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

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: remove FilePath*UTF8Unsafe methods Created 3 years, 6 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 <utility>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/memory/ptr_util.h"
17 #include "base/run_loop.h"
18 #include "base/task_scheduler/post_task.h"
19 #include "base/test/scoped_task_environment.h"
20 #include "base/values.h"
21 #include "crypto/symmetric_key.h"
22 #include "extensions/browser/api/lock_screen_data/operation_result.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 namespace extensions {
26 namespace lock_screen_data {
27
28 namespace {
29
30 void WriteCallback(const base::Closure& callback,
31 OperationResult* result_out,
32 OperationResult result) {
33 *result_out = result;
34 callback.Run();
35 }
36
37 void DeleteCallback(const base::Closure& callback,
38 OperationResult* result_out,
39 OperationResult result) {
40 *result_out = result;
41 callback.Run();
42 }
43
44 void ReadCallback(const base::Closure& callback,
45 OperationResult* result_out,
46 std::unique_ptr<std::vector<char>>* content_out,
47 OperationResult result,
48 std::unique_ptr<std::vector<char>> content) {
49 *result_out = result;
50 *content_out = std::move(content);
51 callback.Run();
52 }
53
54 void NotCalled(const std::string& message) {
55 ADD_FAILURE() << "Not expected to be called: " << message;
56 }
57
58 } // namespace
59
60 class DataItemTest : public testing::Test {
61 public:
62 DataItemTest() = default;
63 ~DataItemTest() override = default;
64
65 void SetUp() override {
66 task_runner_ =
67 base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()});
68 ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
69 }
70
71 std::string GenerateKey(const std::string& password) {
72 std::unique_ptr<crypto::SymmetricKey> key =
73 crypto::SymmetricKey::DeriveKeyFromPassword(
74 crypto::SymmetricKey::AES, password, "salt", 1000, 256);
75 if (!key) {
76 ADD_FAILURE() << "Failed to create symmetric key";
77 return std::string();
78 }
79
80 return key->key();
81 }
82
83 void DrainTaskRunner() {
84 base::RunLoop run_loop;
85 task_runner()->PostTaskAndReply(FROM_HERE, base::Bind(&base::DoNothing),
86 run_loop.QuitClosure());
87 run_loop.Run();
88 }
89
90 const base::FilePath& test_dir() const { return test_dir_.GetPath(); }
91
92 scoped_refptr<base::SequencedTaskRunner> task_runner() {
93 return task_runner_;
94 }
95
96 private:
97 base::ScopedTempDir test_dir_;
98
99 base::test::ScopedTaskEnvironment scoped_task_environment_;
100 scoped_refptr<base::SequencedTaskRunner> task_runner_;
101
102 DISALLOW_COPY_AND_ASSIGN(DataItemTest);
103 };
104
105 TEST_F(DataItemTest, ValueConversion) {
106 DataItem item("data_id");
107
108 std::unique_ptr<base::DictionaryValue> value = item.ToValue();
109 ASSERT_TRUE(value);
110
111 {
112 DataItem converted("data_id");
113 EXPECT_TRUE(converted.InitFromValue(*value));
114
115 EXPECT_EQ("data_id", converted.id());
116 EXPECT_TRUE(converted.backing_file().empty());
117 }
118
119 item.set_backing_file(test_dir().AppendASCII("test_file"));
120
121 value = item.ToValue();
122 {
123 DataItem converted("data_id");
124 EXPECT_TRUE(converted.InitFromValue(*value));
125
126 EXPECT_EQ("data_id", converted.id());
127 EXPECT_EQ(test_dir().AppendASCII("test_file"), converted.backing_file());
128 }
129
130 {
131 DataItem converted("different_id");
132 EXPECT_FALSE(converted.InitFromValue(*value));
133
134 EXPECT_EQ("different_id", converted.id());
135 EXPECT_TRUE(converted.backing_file().empty());
136 }
137 }
138
139 TEST_F(DataItemTest, WriteLocation) {
140 DataItem item("data_id");
141
142 std::string key = GenerateKey("key_1");
143 ASSERT_FALSE(key.empty());
144
145 OperationResult write_result = OperationResult::kFailed;
146 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
147
148 item.set_backing_file(test_dir().AppendASCII("app").AppendASCII("test_file"));
149
150 {
151 base::RunLoop run_loop;
152 ASSERT_EQ(OperationResult::kPending,
153 item.Write(content, key, task_runner(),
154 base::Bind(&WriteCallback, run_loop.QuitClosure(),
155 &write_result)));
156 run_loop.Run();
157 }
158
159 EXPECT_EQ(OperationResult::kSuccess, write_result);
160
161 EXPECT_TRUE(
162 base::PathExists(test_dir().AppendASCII("app").AppendASCII("test_file")));
163
164 OperationResult delete_result = OperationResult::kFailed;
165 {
166 base::RunLoop run_loop;
167 item.Delete(
168 task_runner(),
169 base::Bind(&DeleteCallback, run_loop.QuitClosure(), &delete_result));
170 run_loop.Run();
171 }
172
173 EXPECT_EQ(OperationResult::kSuccess, delete_result);
174 EXPECT_FALSE(
175 base::PathExists(test_dir().AppendASCII("app").AppendASCII("test_file")));
176 }
177
178 TEST_F(DataItemTest, ReadWrite) {
179 DataItem item("data_id");
180
181 std::string key = GenerateKey("key_1");
182 ASSERT_FALSE(key.empty());
183
184 OperationResult write_result = OperationResult::kFailed;
185 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
186
187 EXPECT_EQ(
188 OperationResult::kNoBackingFile,
189 item.Write(content, key, task_runner(),
190 base::Bind(&WriteCallback,
191 base::Bind(&NotCalled,
192 "Writing item with no backing file"),
193 &write_result)));
194
195 item.set_backing_file(test_dir().AppendASCII("app").AppendASCII("test_file"));
196
197 {
198 base::RunLoop run_loop;
199 ASSERT_EQ(OperationResult::kPending,
200 item.Write(content, key, task_runner(),
201 base::Bind(&WriteCallback, run_loop.QuitClosure(),
202 &write_result)));
203 run_loop.Run();
204 }
205
206 EXPECT_EQ(OperationResult::kSuccess, write_result);
207
208 OperationResult read_result = OperationResult::kFailed;
209 std::unique_ptr<std::vector<char>> read_content;
210
211 {
212 base::RunLoop run_loop;
213 ASSERT_EQ(OperationResult::kPending,
214 item.Read(key, task_runner(),
215 base::Bind(&ReadCallback, run_loop.QuitClosure(),
216 &read_result, &read_content)));
217 run_loop.Run();
218 }
219
220 ASSERT_EQ(OperationResult::kSuccess, read_result);
221 ASSERT_TRUE(read_content);
222 EXPECT_EQ(content, *read_content);
223
224 std::string different_key = GenerateKey("key_2");
225 ASSERT_FALSE(different_key.empty());
226
227 {
228 base::RunLoop run_loop;
229 ASSERT_EQ(OperationResult::kPending,
230 item.Read(different_key, task_runner(),
231 base::Bind(&ReadCallback, run_loop.QuitClosure(),
232 &read_result, &read_content)));
233 run_loop.Run();
234 }
235
236 ASSERT_EQ(OperationResult::kWrongKey, read_result);
237 ASSERT_TRUE(read_content);
238 EXPECT_TRUE(read_content->empty());
239 }
240
241 TEST_F(DataItemTest, ReadFromNonexistentSource) {
242 DataItem item("data_id");
243
244 std::string key = GenerateKey("key_1");
245 ASSERT_FALSE(key.empty());
246
247 OperationResult read_result = OperationResult::kFailed;
248 std::unique_ptr<std::vector<char>> read_content;
249
250 EXPECT_EQ(
251 OperationResult::kNoBackingFile,
252 item.Read(key, task_runner(),
253 base::Bind(
254 &ReadCallback,
255 base::Bind(&NotCalled, "Reading item with no backing file"),
256 &read_result, &read_content)));
257
258 item.set_backing_file(test_dir().AppendASCII("nonexistent"));
259
260 {
261 base::RunLoop run_loop;
262 ASSERT_EQ(OperationResult::kPending,
263 item.Read(key, task_runner(),
264 base::Bind(&ReadCallback, run_loop.QuitClosure(),
265 &read_result, &read_content)));
266 run_loop.Run();
267 }
268
269 EXPECT_EQ(OperationResult::kNotFound, read_result);
270 ASSERT_TRUE(read_content);
271 EXPECT_TRUE(read_content->empty());
272 }
273
274 TEST_F(DataItemTest, ReadOldFile) {
275 std::unique_ptr<DataItem> writer = base::MakeUnique<DataItem>("data_id");
276 writer->set_backing_file(
277 test_dir().AppendASCII("app").AppendASCII("test_file"));
278
279 std::string key = GenerateKey("key_1");
280 ASSERT_FALSE(key.empty());
281
282 OperationResult write_result = OperationResult::kFailed;
283 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
284
285 {
286 base::RunLoop run_loop;
287 ASSERT_EQ(OperationResult::kPending,
288 writer->Write(content, key, task_runner(),
289 base::Bind(&WriteCallback, run_loop.QuitClosure(),
290 &write_result)));
291 run_loop.Run();
292 }
293
294 writer.reset();
295
296 OperationResult read_result = OperationResult::kFailed;
297 std::unique_ptr<std::vector<char>> read_content;
298
299 std::unique_ptr<DataItem> reader = base::MakeUnique<DataItem>("data_id");
300 reader->set_backing_file(
301 test_dir().AppendASCII("app").AppendASCII("test_file"));
302
303 {
304 base::RunLoop run_loop;
305 ASSERT_EQ(OperationResult::kPending,
306 reader->Read(key, task_runner(),
307 base::Bind(&ReadCallback, run_loop.QuitClosure(),
308 &read_result, &read_content)));
309 run_loop.Run();
310 }
311
312 EXPECT_EQ(OperationResult::kSuccess, read_result);
313 ASSERT_TRUE(read_content);
314 EXPECT_EQ(content, *read_content);
315 }
316
317 TEST_F(DataItemTest, RepeatedWrite) {
318 DataItem item("data_id");
319 item.set_backing_file(test_dir().AppendASCII("app").AppendASCII("test_file"));
320
321 std::string key = GenerateKey("key_1");
322 ASSERT_FALSE(key.empty());
323
324 OperationResult write_result = OperationResult::kFailed;
325 std::vector<char> first_write = {'f', 'i', 'l', 'e', '_', '1'};
326 std::vector<char> second_write = {'f', 'i', 'l', 'e', '_', '2'};
327
328 {
329 base::RunLoop run_loop;
330 ASSERT_EQ(
331 OperationResult::kPending,
332 item.Write(first_write, key, task_runner(),
333 base::Bind(&WriteCallback, base::Bind(&base::DoNothing),
334 &write_result)));
335 ASSERT_EQ(OperationResult::kPending,
336 item.Write(second_write, key, task_runner(),
337 base::Bind(&WriteCallback, run_loop.QuitClosure(),
338 &write_result)));
339 run_loop.Run();
340 }
341
342 DataItem reader("data_id");
343 reader.set_backing_file(
344 test_dir().AppendASCII("app").AppendASCII("test_file"));
345 OperationResult read_result = OperationResult::kFailed;
346 std::unique_ptr<std::vector<char>> read_content;
347
348 {
349 base::RunLoop run_loop;
350 ASSERT_EQ(OperationResult::kPending,
351 reader.Read(key, task_runner(),
352 base::Bind(&ReadCallback, run_loop.QuitClosure(),
353 &read_result, &read_content)));
354 run_loop.Run();
355 }
356
357 EXPECT_EQ(OperationResult::kSuccess, read_result);
358 ASSERT_TRUE(read_content);
359 EXPECT_EQ(second_write, *read_content);
360 }
361
362 TEST_F(DataItemTest, DeleteWithNoBackingFile) {
363 DataItem item("data_id");
364
365 OperationResult delete_result = OperationResult::kFailed;
366 EXPECT_EQ(OperationResult::kNoBackingFile,
367 item.Delete(task_runner(),
368 base::Bind(&DeleteCallback,
369 base::Bind(&NotCalled,
370 "Delete with no backing file"),
371 &delete_result)));
372
373 DrainTaskRunner();
374 }
375
376 TEST_F(DataItemTest, ReadDeletedItem) {
377 DataItem item("data_id");
378 item.set_backing_file(test_dir().AppendASCII("app").AppendASCII("test_file"));
379
380 std::string key = GenerateKey("key_1");
381 ASSERT_FALSE(key.empty());
382
383 OperationResult write_result = OperationResult::kFailed;
384 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
385
386 {
387 base::RunLoop run_loop;
388 ASSERT_EQ(OperationResult::kPending,
389 item.Write(content, key, task_runner(),
390 base::Bind(&WriteCallback, run_loop.QuitClosure(),
391 &write_result)));
392 run_loop.Run();
393 }
394
395 EXPECT_EQ(OperationResult::kSuccess, write_result);
396
397 OperationResult delete_result = OperationResult::kFailed;
398 {
399 base::RunLoop run_loop;
400 item.Delete(
401 task_runner(),
402 base::Bind(&DeleteCallback, run_loop.QuitClosure(), &delete_result));
403 run_loop.Run();
404 }
405
406 EXPECT_EQ(OperationResult::kSuccess, delete_result);
407
408 OperationResult read_result = OperationResult::kFailed;
409 std::unique_ptr<std::vector<char>> read_content;
410 EXPECT_EQ(
411 OperationResult::kNoBackingFile,
412 item.Read(key, task_runner(),
413 base::Bind(&ReadCallback,
414 base::Bind(&NotCalled, "Read deleted item callback"),
415 &read_result, &read_content)));
416
417 DrainTaskRunner();
418 }
419
420 TEST_F(DataItemTest, WriteDeletedItem) {
421 DataItem item("data_id");
422 item.set_backing_file(test_dir().AppendASCII("app").AppendASCII("test_file"));
423
424 std::string key = GenerateKey("key_1");
425 ASSERT_FALSE(key.empty());
426
427 OperationResult write_result = OperationResult::kFailed;
428 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
429
430 {
431 base::RunLoop run_loop;
432 ASSERT_EQ(OperationResult::kPending,
433 item.Write(content, key, task_runner(),
434 base::Bind(&WriteCallback, run_loop.QuitClosure(),
435 &write_result)));
436 run_loop.Run();
437 }
438
439 EXPECT_EQ(OperationResult::kSuccess, write_result);
440
441 OperationResult delete_result = OperationResult::kFailed;
442 {
443 base::RunLoop run_loop;
444 item.Delete(
445 task_runner(),
446 base::Bind(&DeleteCallback, run_loop.QuitClosure(), &delete_result));
447 run_loop.Run();
448 }
449
450 EXPECT_EQ(OperationResult::kSuccess, delete_result);
451
452 EXPECT_EQ(OperationResult::kNoBackingFile,
453 item.Write(content, key, task_runner(),
454 base::Bind(&WriteCallback,
455 base::Bind(&NotCalled,
456 "Write deleted item callback"),
457 &write_result)));
458
459 DrainTaskRunner();
460 }
461
462 TEST_F(DataItemTest, WriteWithInvalidKey) {
463 DataItem item("data_id");
464 item.set_backing_file(test_dir().AppendASCII("app").AppendASCII("test_file"));
465
466 std::string key = GenerateKey("key_1");
467 ASSERT_FALSE(key.empty());
468
469 OperationResult write_result = OperationResult::kFailed;
470 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
471
472 {
473 base::RunLoop run_loop;
474 ASSERT_EQ(OperationResult::kPending,
475 item.Write(content, key, task_runner(),
476 base::Bind(&WriteCallback, run_loop.QuitClosure(),
477 &write_result)));
478 run_loop.Run();
479 }
480
481 EXPECT_EQ(OperationResult::kSuccess, write_result);
482
483 OperationResult read_result = OperationResult::kFailed;
484 std::unique_ptr<std::vector<char>> read_content;
485 {
486 base::RunLoop run_loop;
487 ASSERT_EQ(OperationResult::kPending,
488 item.Read("invalid", task_runner(),
489 base::Bind(&ReadCallback, run_loop.QuitClosure(),
490 &read_result, &read_content)));
491 run_loop.Run();
492 }
493
494 EXPECT_EQ(OperationResult::kInvalidKey, read_result);
495 }
496
497 TEST_F(DataItemTest, ReadWithInvalidKey) {
498 DataItem item("data_id");
499 item.set_backing_file(test_dir().AppendASCII("app").AppendASCII("test_file"));
500
501 OperationResult write_result = OperationResult::kFailed;
502 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
503
504 {
505 base::RunLoop run_loop;
506 ASSERT_EQ(OperationResult::kPending,
507 item.Write(content, "invalid", task_runner(),
508 base::Bind(&WriteCallback, run_loop.QuitClosure(),
509 &write_result)));
510 run_loop.Run();
511 }
512
513 EXPECT_EQ(OperationResult::kInvalidKey, write_result);
514 }
515
516 TEST_F(DataItemTest, ResetBeforeCallback) {
517 std::unique_ptr<DataItem> writer = base::MakeUnique<DataItem>("data_id");
518 writer->set_backing_file(
519 test_dir().AppendASCII("app").AppendASCII("test_file"));
520
521 std::string key = GenerateKey("key_1");
522 ASSERT_FALSE(key.empty());
523
524 OperationResult write_result = OperationResult::kFailed;
525 std::vector<char> content = {'f', 'i', 'l', 'e', '_', '1'};
526
527 ASSERT_EQ(
528 OperationResult::kPending,
529 writer->Write(content, key, task_runner(),
530 base::Bind(&WriteCallback,
531 base::Bind(&NotCalled, "Reset writer callback"),
532 &write_result)));
533 writer.reset();
534
535 std::unique_ptr<DataItem> reader = base::MakeUnique<DataItem>("data_id");
536 reader->set_backing_file(
537 test_dir().AppendASCII("app").AppendASCII("test_file"));
538 OperationResult read_result = OperationResult::kFailed;
539 std::unique_ptr<std::vector<char>> read_content;
540
541 {
542 base::RunLoop run_loop;
543 ASSERT_EQ(OperationResult::kPending,
544 reader->Read(key, task_runner(),
545 base::Bind(&ReadCallback, run_loop.QuitClosure(),
546 &read_result, &read_content)));
547 run_loop.Run();
548 }
549
550 EXPECT_EQ(OperationResult::kSuccess, read_result);
551 ASSERT_TRUE(read_content);
552 EXPECT_EQ(content, *read_content);
553
554 ASSERT_EQ(
555 OperationResult::kPending,
556 reader->Read(key, task_runner(),
557 base::Bind(&ReadCallback,
558 base::Bind(&NotCalled, "Reset reader calblack"),
559 &read_result, &read_content)));
560 reader.reset();
561
562 std::unique_ptr<DataItem> deleter = base::MakeUnique<DataItem>("data_id");
563 deleter->set_backing_file(
564 test_dir().AppendASCII("app").AppendASCII("test_file"));
565
566 OperationResult delete_result = OperationResult::kFailed;
567 ASSERT_EQ(OperationResult::kPending,
568 deleter->Delete(
569 task_runner(),
570 base::Bind(&DeleteCallback,
571 base::Bind(&NotCalled, "Reset delete callback"),
572 &delete_result)));
573 deleter.reset();
574
575 DrainTaskRunner();
576
577 EXPECT_FALSE(
578 base::PathExists(test_dir().AppendASCII("app").AppendASCII("test_file")));
579 }
580
581 } // namespace lock_screen_data
582 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698