OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/ntp_snippets/remote/ntp_snippets_database.h" | 5 #include "components/ntp_snippets/remote/ntp_snippets_database.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/memory/ptr_util.h" |
14 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
15 #include "base/run_loop.h" | 16 #include "base/run_loop.h" |
16 #include "base/threading/thread_task_runner_handle.h" | 17 #include "base/threading/thread_task_runner_handle.h" |
17 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
19 | 20 |
20 using testing::ElementsAre; | 21 using testing::ElementsAre; |
| 22 using testing::Eq; |
21 using testing::IsEmpty; | 23 using testing::IsEmpty; |
22 using testing::Mock; | 24 using testing::Mock; |
23 using testing::_; | 25 using testing::_; |
24 | 26 |
25 namespace ntp_snippets { | 27 namespace ntp_snippets { |
26 | 28 |
27 bool operator==(const SnippetSource& lhs, const SnippetSource& rhs) { | 29 bool operator==(const SnippetSource& lhs, const SnippetSource& rhs) { |
28 return lhs.url == rhs.url && lhs.publisher_name == rhs.publisher_name && | 30 return lhs.url == rhs.url && lhs.publisher_name == rhs.publisher_name && |
29 lhs.amp_url == rhs.amp_url; | 31 lhs.amp_url == rhs.amp_url; |
30 } | 32 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 // Explicitly destroy any existing database first, so it releases the lock | 75 // Explicitly destroy any existing database first, so it releases the lock |
74 // on the file. | 76 // on the file. |
75 db_.reset(); | 77 db_.reset(); |
76 | 78 |
77 db_.reset(new NTPSnippetsDatabase(database_dir_.GetPath(), | 79 db_.reset(new NTPSnippetsDatabase(database_dir_.GetPath(), |
78 base::ThreadTaskRunnerHandle::Get())); | 80 base::ThreadTaskRunnerHandle::Get())); |
79 } | 81 } |
80 | 82 |
81 NTPSnippetsDatabase* db() { return db_.get(); } | 83 NTPSnippetsDatabase* db() { return db_.get(); } |
82 | 84 |
| 85 // TODO(tschumann): MOCK_METHODS on non mock objects are an anti-pattern. |
| 86 // Clean up. |
83 void OnSnippetsLoaded(NTPSnippet::PtrVector snippets) { | 87 void OnSnippetsLoaded(NTPSnippet::PtrVector snippets) { |
84 OnSnippetsLoadedImpl(snippets); | 88 OnSnippetsLoadedImpl(snippets); |
85 } | 89 } |
86 MOCK_METHOD1(OnSnippetsLoadedImpl, | 90 MOCK_METHOD1(OnSnippetsLoadedImpl, |
87 void(const NTPSnippet::PtrVector& snippets)); | 91 void(const NTPSnippet::PtrVector& snippets)); |
88 | 92 |
89 MOCK_METHOD1(OnImageLoaded, void(std::string)); | 93 MOCK_METHOD1(OnImageLoaded, void(std::string)); |
90 | 94 |
91 private: | 95 private: |
92 base::MessageLoop message_loop_; | 96 base::MessageLoop message_loop_; |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 db()->DeleteImage(snippet->id()); | 315 db()->DeleteImage(snippet->id()); |
312 | 316 |
313 // Make sure the image is gone. | 317 // Make sure the image is gone. |
314 EXPECT_CALL(*this, OnImageLoaded(std::string())); | 318 EXPECT_CALL(*this, OnImageLoaded(std::string())); |
315 db()->LoadImage(snippet->id(), | 319 db()->LoadImage(snippet->id(), |
316 base::Bind(&NTPSnippetsDatabaseTest::OnImageLoaded, | 320 base::Bind(&NTPSnippetsDatabaseTest::OnImageLoaded, |
317 base::Unretained(this))); | 321 base::Unretained(this))); |
318 base::RunLoop().RunUntilIdle(); | 322 base::RunLoop().RunUntilIdle(); |
319 } | 323 } |
320 | 324 |
| 325 void LoadExpectedImage(NTPSnippetsDatabase* db, |
| 326 const std::string& id, |
| 327 const std::string& expected_data) { |
| 328 base::RunLoop run_loop; |
| 329 db->LoadImage(id, base::Bind( |
| 330 [](base::Closure signal, std::string expected_data, |
| 331 std::string actual_data) { |
| 332 EXPECT_THAT(actual_data, Eq(expected_data)); |
| 333 signal.Run(); |
| 334 }, |
| 335 run_loop.QuitClosure(), expected_data)); |
| 336 run_loop.Run(); |
| 337 } |
| 338 |
| 339 TEST_F(NTPSnippetsDatabaseTest, ShouldGarbageCollectImages) { |
| 340 CreateDatabase(); |
| 341 base::RunLoop().RunUntilIdle(); |
| 342 ASSERT_TRUE(db()->IsInitialized()); |
| 343 |
| 344 // Store images. |
| 345 db()->SaveImage("snippet-id-1", "pretty-image-1"); |
| 346 db()->SaveImage("snippet-id-2", "pretty-image-2"); |
| 347 db()->SaveImage("snippet-id-3", "pretty-image-3"); |
| 348 base::RunLoop().RunUntilIdle(); |
| 349 |
| 350 // Make sure the to-be-garbage collected images are there. |
| 351 LoadExpectedImage(db(), "snippet-id-1", "pretty-image-1"); |
| 352 LoadExpectedImage(db(), "snippet-id-3", "pretty-image-3"); |
| 353 |
| 354 // Garbage collect all except the second. |
| 355 db()->GarbageCollectImages(base::MakeUnique<std::set<std::string>>( |
| 356 std::set<std::string>({"snippet-id-2"}))); |
| 357 base::RunLoop().RunUntilIdle(); |
| 358 |
| 359 // Make sure the images are gone. |
| 360 LoadExpectedImage(db(), "snippet-id-1", ""); |
| 361 LoadExpectedImage(db(), "snippet-id-3", ""); |
| 362 // Make sure the second still exists. |
| 363 LoadExpectedImage(db(), "snippet-id-2", "pretty-image-2"); |
| 364 } |
| 365 |
321 } // namespace ntp_snippets | 366 } // namespace ntp_snippets |
OLD | NEW |