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

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

Powered by Google App Engine
This is Rietveld 408576698