Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Side by Side Diff: extensions/browser/api/lock_screen_data/data_item_unittest.cc

Issue 2934293003: The chrome.lockScreen.data API implementation (Closed)
Patch Set: switch to BackendTaskRunner Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "extensions/browser/api/lock_screen_data/data_item.h"
6
7 #include <memory>
8 #include <set>
9 #include <utility>
10
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/callback.h"
14 #include "base/files/scoped_temp_dir.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/run_loop.h"
17 #include "base/values.h"
18 #include "components/keyed_service/content/browser_context_dependency_manager.h"
19 #include "content/public/test/test_browser_context.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "crypto/symmetric_key.h"
22 #include "extensions/browser/api/lock_screen_data/operation_result.h"
23 #include "extensions/browser/api/storage/backend_task_runner.h"
24 #include "extensions/browser/api/storage/local_value_store_cache.h"
25 #include "extensions/browser/extension_registry.h"
26 #include "extensions/browser/test_extensions_browser_client.h"
27 #include "extensions/browser/value_store/test_value_store_factory.h"
28 #include "extensions/browser/value_store/testing_value_store.h"
29 #include "extensions/common/extension_builder.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31
32 namespace extensions {
33 namespace lock_screen_data {
34
35 namespace {
36
37 const char kPrimaryExtensionId[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
38 const char kSecondaryExtensionId[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
39
40 void WriteCallbackNotCalled(const std::string& message,
41 OperationResult result) {
42 ADD_FAILURE() << "Unexpected callback " << message;
43 }
44
45 void ReadCallbackNotCalled(const std::string& message,
46 OperationResult result,
47 std::unique_ptr<std::vector<char>> data) {
48 ADD_FAILURE() << "Unexpected callback " << message;
49 }
50
51 void WriteCallback(const base::Closure& callback,
52 OperationResult* result_out,
53 OperationResult result) {
54 *result_out = result;
55 callback.Run();
56 }
57
58 void ReadCallback(const base::Closure& callback,
59 OperationResult* result_out,
60 std::unique_ptr<std::vector<char>>* content_out,
61 OperationResult result,
62 std::unique_ptr<std::vector<char>> content) {
63 *result_out = result;
64 *content_out = std::move(content);
65 callback.Run();
66 }
67
68 void GetRegisteredItemsCallback(
69 const base::Closure& callback,
70 OperationResult* result_out,
71 std::unique_ptr<base::DictionaryValue>* value_out,
72 OperationResult result,
73 std::unique_ptr<base::DictionaryValue> value) {
74 *result_out = result;
75 *value_out = std::move(value);
76 callback.Run();
77 }
78
79 } // namespace
80
81 class DataItemTest : public testing::Test {
82 public:
83 DataItemTest() {}
84 ~DataItemTest() override = default;
85
86 void SetUp() override {
87 task_runner_ = GetBackendTaskRunner();
88 ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
89
90 context_ = base::MakeUnique<content::TestBrowserContext>();
91 extensions_browser_client_ =
92 base::MakeUnique<TestExtensionsBrowserClient>(context_.get());
93 BrowserContextDependencyManager::GetInstance()->MarkBrowserContextLive(
94 context_.get());
95
96 ExtensionsBrowserClient::Set(extensions_browser_client_.get());
97
98 value_store_factory_ = base::MakeRefCounted<TestValueStoreFactory>();
99 value_store_cache_ =
100 base::MakeUnique<LocalValueStoreCache>(value_store_factory_);
101
102 extension_ = CreateTestExtension(kPrimaryExtensionId);
103 }
104
105 void TearDown() override {
106 TearDownValueStoreCache();
107
108 BrowserContextDependencyManager::GetInstance()
109 ->DestroyBrowserContextServices(context_.get());
110 ExtensionsBrowserClient::Set(nullptr);
111 extensions_browser_client_.reset();
112 context_.reset();
113 }
114
115 std::string GenerateKey(const std::string& password) {
116 std::unique_ptr<crypto::SymmetricKey> key =
117 crypto::SymmetricKey::DeriveKeyFromPassword(
118 crypto::SymmetricKey::AES, password, "salt", 1000, 256);
119 if (!key) {
120 ADD_FAILURE() << "Failed to create symmetric key";
121 return std::string();
122 }
123
124 return key->key();
125 }
126
127 std::unique_ptr<DataItem> CreateDataItem(const std::string& item_id,
128 const std::string& extension_id,
129 const std::string& crypto_key) {
130 return base::MakeUnique<DataItem>(item_id, extension_id, context_.get(),
131 value_store_cache_.get(),
132 task_runner_.get(), crypto_key);
133 }
134
135 std::unique_ptr<DataItem> CreateAndRegisterDataItem(
136 const std::string& item_id,
137 const std::string& extension_id,
138 const std::string& crypto_key) {
139 std::unique_ptr<DataItem> item =
140 CreateDataItem(item_id, extension_id, crypto_key);
141
142 OperationResult result = OperationResult::kFailed;
143 base::RunLoop run_loop;
144 item->Register(base::Bind(&WriteCallback, run_loop.QuitClosure(), &result));
145 run_loop.Run();
146
147 EXPECT_EQ(OperationResult::kSuccess, result);
148 return item;
149 }
150
151 void DrainTaskRunner() {
152 base::RunLoop run_loop;
153 task_runner()->PostTaskAndReply(FROM_HERE, base::Bind(&base::DoNothing),
154 run_loop.QuitClosure());
155 run_loop.Run();
156 }
157
158 const base::FilePath& test_dir() const { return test_dir_.GetPath(); }
159
160 scoped_refptr<base::SequencedTaskRunner> task_runner() {
161 return task_runner_;
162 }
163
164 scoped_refptr<const Extension> CreateTestExtension(
165 const std::string& extension_id) {
166 DictionaryBuilder app_builder;
167 app_builder.Set("background",
168 DictionaryBuilder()
169 .Set("scripts", ListBuilder().Append("script").Build())
170 .Build());
171 ListBuilder app_handlers_builder;
172 app_handlers_builder.Append(DictionaryBuilder()
173 .Set("action", "new_note")
174 .SetBoolean("enabled_on_lock_screen", true)
175 .Build());
176 scoped_refptr<const Extension> extension =
177 ExtensionBuilder()
178 .SetID(extension_id)
179 .SetManifest(
180 DictionaryBuilder()
181 .Set("name", "Test app")
182 .Set("version", "1.0")
183 .Set("manifest_version", 2)
184 .Set("app", app_builder.Build())
185 .Set("action_handlers", app_handlers_builder.Build())
186 .Set("permissions",
187 ListBuilder().Append("lockScreen").Build())
188 .Build())
189 .Build();
190 ExtensionRegistry::Get(context_.get())->AddEnabled(extension);
191 return extension;
192 }
193
194 OperationResult WriteItemAndWaitForResult(DataItem* item,
195 const std::vector<char>& data) {
196 OperationResult result = OperationResult::kFailed;
197 base::RunLoop run_loop;
198 item->Write(data,
199 base::Bind(&WriteCallback, run_loop.QuitClosure(), &result));
200 run_loop.Run();
201 return result;
202 }
203
204 OperationResult ReadItemAndWaitForResult(
205 DataItem* item,
206 std::unique_ptr<std::vector<char>>* data) {
207 OperationResult result = OperationResult::kFailed;
208 std::unique_ptr<std::vector<char>> read_content;
209 base::RunLoop run_loop;
210 item->Read(base::Bind(&ReadCallback, run_loop.QuitClosure(), &result,
211 &read_content));
212 run_loop.Run();
213 if (data)
214 *data = std::move(read_content);
215 return result;
216 }
217
218 OperationResult DeleteItemAndWaitForResult(DataItem* item) {
219 OperationResult result = OperationResult::kFailed;
220 base::RunLoop run_loop;
221 item->Delete(base::Bind(&WriteCallback, run_loop.QuitClosure(), &result));
222 run_loop.Run();
223 return result;
224 }
225
226 OperationResult RegisterItemAndWaitForResult(DataItem* item) {
227 OperationResult result = OperationResult::kFailed;
228 base::RunLoop run_loop;
229 item->Register(base::Bind(&WriteCallback, run_loop.QuitClosure(), &result));
230 run_loop.Run();
231 return result;
232 }
233
234 void SetReturnCodeForValueStoreOperations(const std::string& extension_id,
235 ValueStore::StatusCode code) {
236 TestingValueStore* store = static_cast<TestingValueStore*>(
237 value_store_factory_->GetExisting(extension_id));
238 ASSERT_TRUE(store);
239 store->set_status_code(code);
240 }
241
242 OperationResult GetRegisteredItemIds(const std::string& extension_id,
243 std::set<std::string>* items) {
244 OperationResult result = OperationResult::kFailed;
245 std::unique_ptr<base::DictionaryValue> items_value;
246
247 base::RunLoop run_loop;
248 DataItem::GetRegisteredValuesForExtension(
249 context_.get(), value_store_cache_.get(), task_runner_.get(),
250 extension_id,
251 base::Bind(&GetRegisteredItemsCallback, run_loop.QuitClosure(), &result,
252 &items_value));
253 run_loop.Run();
254
255 if (result != OperationResult::kSuccess)
256 return result;
257
258 items->clear();
259 for (base::DictionaryValue::Iterator iter(*items_value); !iter.IsAtEnd();
260 iter.Advance()) {
261 EXPECT_EQ(0u, items->count(iter.key()));
262 items->insert(iter.key());
263 }
264 return OperationResult::kSuccess;
265 }
266
267 void DeleteAllItems(const std::string& extension_id) {
268 base::RunLoop run_loop;
269 DataItem::DeleteAllItemsForExtension(
270 context_.get(), value_store_cache_.get(), task_runner_.get(),
271 extension_id, run_loop.QuitClosure());
272 run_loop.Run();
273 }
274
275 const Extension* extension() const { return extension_.get(); }
276
277 private:
278 void TearDownValueStoreCache() {
279 base::RunLoop run_loop;
280 task_runner_->PostTaskAndReply(
281 FROM_HERE,
282 base::Bind(&DataItemTest::ReleaseValueStoreCache,
283 base::Unretained(this)),
284 run_loop.QuitClosure());
285 run_loop.Run();
286 }
287
288 void ReleaseValueStoreCache() { value_store_cache_.reset(); }
289
290 base::ScopedTempDir test_dir_;
291
292 std::unique_ptr<content::TestBrowserContext> context_;
293
294 content::TestBrowserThreadBundle thread_bundle_;
295 scoped_refptr<base::SequencedTaskRunner> task_runner_;
296
297 std::unique_ptr<TestExtensionsBrowserClient> extensions_browser_client_;
298
299 scoped_refptr<TestValueStoreFactory> value_store_factory_;
300 std::unique_ptr<ValueStoreCache> value_store_cache_;
301
302 scoped_refptr<const Extension> extension_;
303
304 DISALLOW_COPY_AND_ASSIGN(DataItemTest);
305 };
306
307 TEST_F(DataItemTest, OperationsOnUnregisteredItem) {
308 std::unique_ptr<DataItem> item =
309 CreateDataItem("data_id", extension()->id(), GenerateKey("key_1"));
310
311 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
312 EXPECT_EQ(OperationResult::kNotFound,
313 WriteItemAndWaitForResult(item.get(), content));
314
315 EXPECT_EQ(OperationResult::kNotFound,
316 ReadItemAndWaitForResult(item.get(), nullptr));
317
318 EXPECT_EQ(OperationResult::kNotFound, DeleteItemAndWaitForResult(item.get()));
319
320 EXPECT_EQ(OperationResult::kSuccess,
321 RegisterItemAndWaitForResult(item.get()));
322
323 EXPECT_EQ(OperationResult::kSuccess,
324 WriteItemAndWaitForResult(item.get(), content));
325 }
326
327 TEST_F(DataItemTest, OperationsWithUnknownExtension) {
328 std::unique_ptr<DataItem> item =
329 CreateDataItem("data_id", "unknown", GenerateKey("key_1"));
330
331 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
332 EXPECT_EQ(OperationResult::kUnknownExtension,
333 WriteItemAndWaitForResult(item.get(), content));
334
335 EXPECT_EQ(OperationResult::kUnknownExtension,
336 ReadItemAndWaitForResult(item.get(), nullptr));
337
338 EXPECT_EQ(OperationResult::kUnknownExtension,
339 DeleteItemAndWaitForResult(item.get()));
340
341 EXPECT_EQ(OperationResult::kUnknownExtension,
342 RegisterItemAndWaitForResult(item.get()));
343
344 std::set<std::string> item_ids;
345 EXPECT_EQ(OperationResult::kUnknownExtension,
346 GetRegisteredItemIds("unknown", &item_ids));
347 }
348
349 TEST_F(DataItemTest, ValueStoreErrors) {
350 std::unique_ptr<DataItem> item = CreateAndRegisterDataItem(
351 "data_id", extension()->id(), GenerateKey("key_1"));
352 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
353 EXPECT_EQ(OperationResult::kSuccess,
354 WriteItemAndWaitForResult(item.get(), content));
355
356 SetReturnCodeForValueStoreOperations(extension()->id(),
357 ValueStore::OTHER_ERROR);
358
359 EXPECT_EQ(OperationResult::kNotFound,
360 ReadItemAndWaitForResult(item.get(), nullptr));
361 EXPECT_EQ(OperationResult::kNotFound,
362 WriteItemAndWaitForResult(item.get(), {'x'}));
363 EXPECT_EQ(OperationResult::kFailed, DeleteItemAndWaitForResult(item.get()));
364
365 std::unique_ptr<DataItem> unregistered =
366 CreateDataItem("data_id_1", extension()->id(), GenerateKey("key_1"));
367 EXPECT_EQ(OperationResult::kFailed,
368 RegisterItemAndWaitForResult(unregistered.get()));
369
370 std::set<std::string> item_ids;
371 EXPECT_EQ(OperationResult::kFailed,
372 GetRegisteredItemIds(extension()->id(), &item_ids));
373 }
374
375 TEST_F(DataItemTest, GetRegisteredItems) {
376 std::set<std::string> item_ids;
377 EXPECT_EQ(OperationResult::kSuccess,
378 GetRegisteredItemIds(extension()->id(), &item_ids));
379 EXPECT_TRUE(item_ids.empty());
380
381 std::unique_ptr<DataItem> item_1 =
382 CreateDataItem("data_id_1", extension()->id(), GenerateKey("key_1"));
383
384 EXPECT_EQ(OperationResult::kSuccess,
385 GetRegisteredItemIds(extension()->id(), &item_ids));
386 EXPECT_TRUE(item_ids.empty());
387
388 EXPECT_EQ(OperationResult::kSuccess,
389 RegisterItemAndWaitForResult(item_1.get()));
390
391 EXPECT_EQ(OperationResult::kSuccess,
392 GetRegisteredItemIds(extension()->id(), &item_ids));
393 EXPECT_EQ(std::set<std::string>({"data_id_1"}), item_ids);
394
395 std::unique_ptr<DataItem> item_2 = CreateAndRegisterDataItem(
396 "data_id_2", extension()->id(), GenerateKey("key_1"));
397
398 std::unique_ptr<DataItem> unregistered =
399 CreateDataItem("unregistered", extension()->id(), GenerateKey("key_1"));
400
401 EXPECT_EQ(OperationResult::kSuccess,
402 GetRegisteredItemIds(extension()->id(), &item_ids));
403 EXPECT_EQ(std::set<std::string>({"data_id_1", "data_id_2"}), item_ids);
404
405 scoped_refptr<const Extension> secondary_extension =
406 CreateTestExtension(kSecondaryExtensionId);
407
408 std::unique_ptr<DataItem> secondary_extension_item =
409 CreateAndRegisterDataItem("data_id_2", secondary_extension->id(),
410 GenerateKey("key_1"));
411
412 EXPECT_EQ(OperationResult::kSuccess,
413 GetRegisteredItemIds(extension()->id(), &item_ids));
414 EXPECT_EQ(std::set<std::string>({"data_id_1", "data_id_2"}), item_ids);
415
416 EXPECT_EQ(OperationResult::kSuccess,
417 GetRegisteredItemIds(secondary_extension->id(), &item_ids));
418 EXPECT_EQ(std::set<std::string>({"data_id_2"}), item_ids);
419
420 EXPECT_EQ(OperationResult::kSuccess,
421 DeleteItemAndWaitForResult(item_2.get()));
422
423 EXPECT_EQ(OperationResult::kSuccess,
424 GetRegisteredItemIds(extension()->id(), &item_ids));
425 EXPECT_EQ(std::set<std::string>({"data_id_1"}), item_ids);
426
427 EXPECT_EQ(OperationResult::kSuccess,
428 DeleteItemAndWaitForResult(item_1.get()));
429
430 EXPECT_EQ(OperationResult::kSuccess,
431 GetRegisteredItemIds(extension()->id(), &item_ids));
432 EXPECT_TRUE(item_ids.empty());
433
434 EXPECT_EQ(OperationResult::kSuccess,
435 GetRegisteredItemIds(secondary_extension->id(), &item_ids));
436 EXPECT_EQ(std::set<std::string>({"data_id_2"}), item_ids);
437 }
438
439 TEST_F(DataItemTest, DoubleRegistration) {
440 std::unique_ptr<DataItem> item =
441 CreateDataItem("data_id", extension()->id(), GenerateKey("key_1"));
442
443 EXPECT_EQ(OperationResult::kSuccess,
444 RegisterItemAndWaitForResult(item.get()));
445
446 std::unique_ptr<DataItem> duplicate =
447 CreateDataItem("data_id", extension()->id(), GenerateKey("key_1"));
448
449 EXPECT_EQ(OperationResult::kAlreadyRegistered,
450 RegisterItemAndWaitForResult(duplicate.get()));
451
452 EXPECT_EQ(OperationResult::kSuccess, DeleteItemAndWaitForResult(item.get()));
453
454 EXPECT_EQ(OperationResult::kSuccess,
455 RegisterItemAndWaitForResult(duplicate.get()));
456 }
457
458 TEST_F(DataItemTest, ReadWrite) {
459 std::unique_ptr<DataItem> item = CreateAndRegisterDataItem(
460 "data_id", extension()->id(), GenerateKey("key_1"));
461
462 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
463 EXPECT_EQ(OperationResult::kSuccess,
464 WriteItemAndWaitForResult(item.get(), content));
465
466 std::unique_ptr<std::vector<char>> read_content;
467 ASSERT_EQ(OperationResult::kSuccess,
468 ReadItemAndWaitForResult(item.get(), &read_content));
469 ASSERT_TRUE(read_content);
470 EXPECT_EQ(content, *read_content);
471
472 read_content.reset();
473 std::unique_ptr<DataItem> item_copy =
474 CreateDataItem("data_id", extension()->id(), GenerateKey("key_1"));
475 ASSERT_EQ(OperationResult::kSuccess,
476 ReadItemAndWaitForResult(item_copy.get(), &read_content));
477 ASSERT_TRUE(read_content);
478 EXPECT_EQ(content, *read_content);
479
480 std::unique_ptr<DataItem> different_key =
481 CreateDataItem("data_id", extension()->id(), GenerateKey("key_2"));
482 EXPECT_EQ(OperationResult::kWrongKey,
483 ReadItemAndWaitForResult(different_key.get(), nullptr));
484 }
485
486 TEST_F(DataItemTest, ExtensionsWithConflictingDataItemIds) {
487 std::unique_ptr<DataItem> first = CreateAndRegisterDataItem(
488 "data_id", extension()->id(), GenerateKey("key_1"));
489
490 scoped_refptr<const Extension> second_extension =
491 CreateTestExtension(kSecondaryExtensionId);
492 ASSERT_NE(extension()->id(), second_extension->id());
493 std::unique_ptr<DataItem> second = CreateAndRegisterDataItem(
494 "data_id", second_extension->id(), GenerateKey("key_1"));
495
496 std::vector<char> first_content = {'f', 'i', 'l', 'e', '_', '1'};
497 EXPECT_EQ(OperationResult::kSuccess,
498 WriteItemAndWaitForResult(first.get(), first_content));
499
500 std::vector<char> second_content = {'f', 'i', 'l', 'e', '_', '2'};
501 EXPECT_EQ(OperationResult::kSuccess,
502 WriteItemAndWaitForResult(second.get(), second_content));
503
504 std::unique_ptr<std::vector<char>> first_read;
505 ASSERT_EQ(OperationResult::kSuccess,
506 ReadItemAndWaitForResult(first.get(), &first_read));
507 ASSERT_TRUE(first_read);
508 EXPECT_EQ(first_content, *first_read);
509
510 std::unique_ptr<std::vector<char>> second_read;
511 ASSERT_EQ(OperationResult::kSuccess,
512 ReadItemAndWaitForResult(second.get(), &second_read));
513 ASSERT_TRUE(second_read);
514 EXPECT_EQ(second_content, *second_read);
515
516 EXPECT_EQ(OperationResult::kSuccess, DeleteItemAndWaitForResult(first.get()));
517
518 // The second extension item is still writable after the first extension's one
519 // went away.
520 EXPECT_EQ(OperationResult::kSuccess,
521 WriteItemAndWaitForResult(second.get(), {'x'}));
522 }
523
524 TEST_F(DataItemTest, ReadNonRegisteredItem) {
525 std::unique_ptr<DataItem> item =
526 CreateDataItem("data_id", extension()->id(), GenerateKey("key_1"));
527
528 EXPECT_EQ(OperationResult::kNotFound,
529 ReadItemAndWaitForResult(item.get(), nullptr));
530 }
531
532 TEST_F(DataItemTest, ReadOldFile) {
533 std::unique_ptr<DataItem> writer = CreateAndRegisterDataItem(
534 "data_id", extension()->id(), GenerateKey("key_1"));
535
536 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
537 EXPECT_EQ(OperationResult::kSuccess,
538 WriteItemAndWaitForResult(writer.get(), content));
539 writer.reset();
540
541 std::unique_ptr<DataItem> reader =
542 CreateDataItem("data_id", extension()->id(), GenerateKey("key_1"));
543 std::unique_ptr<std::vector<char>> read_content;
544 ASSERT_EQ(OperationResult::kSuccess,
545 ReadItemAndWaitForResult(reader.get(), &read_content));
546 ASSERT_TRUE(read_content);
547 EXPECT_EQ(content, *read_content);
548 }
549
550 TEST_F(DataItemTest, RepeatedWrite) {
551 std::unique_ptr<DataItem> writer = CreateAndRegisterDataItem(
552 "data_id", extension()->id(), GenerateKey("key_1"));
553
554 OperationResult write_result = OperationResult::kFailed;
555 std::vector<char> first_write = {'f', 'i', 'l', 'e', '_', '1'};
556 std::vector<char> second_write = {'f', 'i', 'l', 'e', '_', '2'};
557
558 writer->Write(
559 first_write,
560 base::Bind(&WriteCallback, base::Bind(&base::DoNothing), &write_result));
561 EXPECT_EQ(OperationResult::kSuccess,
562 WriteItemAndWaitForResult(writer.get(), second_write));
563
564 std::unique_ptr<DataItem> reader =
565 CreateDataItem("data_id", extension()->id(), GenerateKey("key_1"));
566 std::unique_ptr<std::vector<char>> read_content;
567 ASSERT_EQ(OperationResult::kSuccess,
568 ReadItemAndWaitForResult(reader.get(), &read_content));
569 ASSERT_TRUE(read_content);
570 EXPECT_EQ(second_write, *read_content);
571 }
572
573 TEST_F(DataItemTest, ReadDeletedAndReregisteredItem) {
574 std::unique_ptr<DataItem> item = CreateAndRegisterDataItem(
575 "data_id", extension()->id(), GenerateKey("key_1"));
576
577 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
578 EXPECT_EQ(OperationResult::kSuccess,
579 WriteItemAndWaitForResult(item.get(), content));
580
581 EXPECT_EQ(OperationResult::kSuccess, DeleteItemAndWaitForResult(item.get()));
582
583 std::unique_ptr<DataItem> duplicate = CreateAndRegisterDataItem(
584 "data_id", extension()->id(), GenerateKey("key_1"));
585
586 std::unique_ptr<std::vector<char>> read;
587 ASSERT_EQ(OperationResult::kSuccess,
588 ReadItemAndWaitForResult(duplicate.get(), &read));
589 ASSERT_TRUE(read);
590 EXPECT_TRUE(read->empty());
591 }
592
593 TEST_F(DataItemTest, ReadEmpty) {
594 std::unique_ptr<DataItem> item = CreateAndRegisterDataItem(
595 "data_id", extension()->id(), GenerateKey("key_1"));
596
597 std::unique_ptr<std::vector<char>> read_content;
598 ASSERT_EQ(OperationResult::kSuccess,
599 ReadItemAndWaitForResult(item.get(), &read_content));
600 ASSERT_TRUE(read_content);
601 EXPECT_TRUE(read_content->empty());
602
603 ASSERT_EQ(OperationResult::kSuccess, DeleteItemAndWaitForResult(item.get()));
604
605 EXPECT_EQ(OperationResult::kNotFound,
606 ReadItemAndWaitForResult(item.get(), nullptr));
607 }
608
609 TEST_F(DataItemTest, ReadDeletedItem) {
610 std::unique_ptr<DataItem> item = CreateAndRegisterDataItem(
611 "data_id", extension()->id(), GenerateKey("key_1"));
612
613 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
614 EXPECT_EQ(OperationResult::kSuccess,
615 WriteItemAndWaitForResult(item.get(), content));
616
617 ASSERT_EQ(OperationResult::kSuccess, DeleteItemAndWaitForResult(item.get()));
618
619 EXPECT_EQ(OperationResult::kNotFound,
620 ReadItemAndWaitForResult(item.get(), nullptr));
621 }
622
623 TEST_F(DataItemTest, WriteDeletedItem) {
624 std::unique_ptr<DataItem> item = CreateAndRegisterDataItem(
625 "data_id", extension()->id(), GenerateKey("key_1"));
626
627 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
628 EXPECT_EQ(OperationResult::kSuccess,
629 WriteItemAndWaitForResult(item.get(), content));
630
631 ASSERT_EQ(OperationResult::kSuccess, DeleteItemAndWaitForResult(item.get()));
632
633 EXPECT_EQ(OperationResult::kNotFound,
634 WriteItemAndWaitForResult(item.get(), content));
635 }
636
637 TEST_F(DataItemTest, WriteWithInvalidKey) {
638 std::unique_ptr<DataItem> item =
639 CreateAndRegisterDataItem("data_id", extension()->id(), "invalid");
640
641 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
642 EXPECT_EQ(OperationResult::kInvalidKey,
643 WriteItemAndWaitForResult(item.get(), content));
644 }
645
646 TEST_F(DataItemTest, ReadWithInvalidKey) {
647 std::unique_ptr<DataItem> item = CreateAndRegisterDataItem(
648 "data_id", extension()->id(), GenerateKey("key_1"));
649
650 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
651 EXPECT_EQ(OperationResult::kSuccess,
652 WriteItemAndWaitForResult(item.get(), content));
653
654 std::unique_ptr<DataItem> reader =
655 CreateDataItem("data_id", extension()->id(), "invalid");
656 EXPECT_EQ(OperationResult::kInvalidKey,
657 ReadItemAndWaitForResult(reader.get(), nullptr));
658 }
659
660 TEST_F(DataItemTest, ReadWithWrongKey) {
661 std::unique_ptr<DataItem> item = CreateAndRegisterDataItem(
662 "data_id", extension()->id(), GenerateKey("key_1"));
663
664 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
665 EXPECT_EQ(OperationResult::kSuccess,
666 WriteItemAndWaitForResult(item.get(), content));
667
668 std::unique_ptr<DataItem> reader =
669 CreateDataItem("data_id", extension()->id(), GenerateKey("key_2"));
670 EXPECT_EQ(OperationResult::kWrongKey,
671 ReadItemAndWaitForResult(reader.get(), nullptr));
672 }
673
674 TEST_F(DataItemTest, ResetBeforeCallback) {
675 std::unique_ptr<DataItem> writer = CreateAndRegisterDataItem(
676 "data_id", extension()->id(), GenerateKey("key_1"));
677
678 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
679 writer->Write(content, base::Bind(&WriteCallbackNotCalled, "Reset writer"));
680 writer.reset();
681
682 std::unique_ptr<DataItem> reader =
683 CreateDataItem("data_id", extension()->id(), GenerateKey("key_1"));
684 std::unique_ptr<std::vector<char>> read_content;
685 ASSERT_EQ(OperationResult::kSuccess,
686 ReadItemAndWaitForResult(reader.get(), &read_content));
687 ASSERT_TRUE(read_content);
688 EXPECT_EQ(content, *read_content);
689
690 reader->Read(base::Bind(&ReadCallbackNotCalled, "Reset read"));
691 reader.reset();
692
693 std::unique_ptr<DataItem> deleter =
694 CreateDataItem("data_id", extension()->id(), GenerateKey("key_1"));
695 deleter->Delete(base::Bind(&WriteCallbackNotCalled, "Reset deleter"));
696 deleter.reset();
697
698 DrainTaskRunner();
699
700 // Verify item write fails now the item's been deleted.
701 std::unique_ptr<DataItem> second_writer =
702 CreateDataItem("data_id", extension()->id(), GenerateKey("key_1"));
703 EXPECT_EQ(OperationResult::kNotFound,
704 WriteItemAndWaitForResult(second_writer.get(), content));
705 }
706
707 TEST_F(DataItemTest, DeleteAllForExtension) {
708 std::unique_ptr<DataItem> item_1 = CreateAndRegisterDataItem(
709 "data_id_1", extension()->id(), GenerateKey("key_1"));
710 ASSERT_TRUE(item_1);
711
712 std::unique_ptr<DataItem> item_2 = CreateAndRegisterDataItem(
713 "data_id_2", extension()->id(), GenerateKey("key_1"));
714 ASSERT_TRUE(item_2);
715
716 DeleteAllItems(extension()->id());
717
718 std::set<std::string> item_ids;
719 ASSERT_EQ(OperationResult::kSuccess,
720 GetRegisteredItemIds(extension()->id(), &item_ids));
721 EXPECT_TRUE(item_ids.empty());
722
723 std::unique_ptr<DataItem> new_item = CreateAndRegisterDataItem(
724 "data_id_1", extension()->id(), GenerateKey("key_1"));
725 ASSERT_TRUE(item_2);
726
727 ASSERT_EQ(OperationResult::kSuccess,
728 GetRegisteredItemIds(extension()->id(), &item_ids));
729 EXPECT_EQ(std::set<std::string>({"data_id_1"}), item_ids);
730 }
731
732 } // namespace lock_screen_data
733 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/api/lock_screen_data/data_item.cc ('k') | extensions/browser/api/lock_screen_data/lock_screen_data_api.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698