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

Side by Side Diff: components/doodle/doodle_service_unittest.cc

Issue 2886443002: [Doodle] Move image fetching from LogoBridge to DoodleService (Closed)
Patch Set: comment Created 3 years, 7 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
« no previous file with comments | « components/doodle/doodle_service.cc ('k') | components/image_fetcher/core/image_fetcher_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 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 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/doodle/doodle_service.h" 5 #include "components/doodle/doodle_service.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
14 #include "base/test/histogram_tester.h" 14 #include "base/test/histogram_tester.h"
15 #include "base/test/mock_callback.h"
15 #include "base/test/simple_test_tick_clock.h" 16 #include "base/test/simple_test_tick_clock.h"
16 #include "base/test/test_mock_time_task_runner.h" 17 #include "base/test/test_mock_time_task_runner.h"
17 #include "base/threading/thread_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
18 #include "base/time/time.h" 19 #include "base/time/time.h"
20 #include "components/image_fetcher/core/image_fetcher.h"
21 #include "components/image_fetcher/core/request_metadata.h"
19 #include "components/prefs/testing_pref_service.h" 22 #include "components/prefs/testing_pref_service.h"
20 #include "testing/gmock/include/gmock/gmock.h" 23 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/gfx/geometry/size.h"
26 #include "ui/gfx/image/image.h"
27 #include "ui/gfx/image/image_unittest_util.h"
22 28
29 using image_fetcher::ImageFetcher;
30 using image_fetcher::RequestMetadata;
31 using testing::_;
23 using testing::Eq; 32 using testing::Eq;
24 using testing::StrictMock; 33 using testing::StrictMock;
34 using testing::Not;
25 35
26 namespace doodle { 36 namespace doodle {
27 37
28 namespace { 38 namespace {
29 39
30 class FakeDoodleFetcher : public DoodleFetcher { 40 class FakeDoodleFetcher : public DoodleFetcher {
31 public: 41 public:
32 FakeDoodleFetcher() = default; 42 FakeDoodleFetcher() = default;
33 ~FakeDoodleFetcher() override = default; 43 ~FakeDoodleFetcher() override = default;
34 44
(...skipping 18 matching lines...) Expand all
53 std::vector<FinishedCallback> callbacks_; 63 std::vector<FinishedCallback> callbacks_;
54 }; 64 };
55 65
56 class MockDoodleObserver : public DoodleService::Observer { 66 class MockDoodleObserver : public DoodleService::Observer {
57 public: 67 public:
58 MOCK_METHOD1(OnDoodleConfigUpdated, 68 MOCK_METHOD1(OnDoodleConfigUpdated,
59 void(const base::Optional<DoodleConfig>&)); 69 void(const base::Optional<DoodleConfig>&));
60 MOCK_METHOD1(OnDoodleConfigRevalidated, void(bool)); 70 MOCK_METHOD1(OnDoodleConfigRevalidated, void(bool));
61 }; 71 };
62 72
73 class FakeImageFetcher : public ImageFetcher {
74 public:
75 FakeImageFetcher() = default;
76 ~FakeImageFetcher() override = default;
77
78 void SetImageFetcherDelegate(image_fetcher::ImageFetcherDelegate*) override {
79 NOTREACHED();
80 }
81
82 void SetDataUseServiceName(DataUseServiceName) override {
83 // Ignored.
84 }
85
86 void SetImageDownloadLimit(base::Optional<int64_t>) override {
87 // Ignored.
88 }
89
90 void SetDesiredImageFrameSize(const gfx::Size&) override {
91 // Ignored.
92 }
93
94 void StartOrQueueNetworkRequest(
95 const std::string& id,
96 const GURL& url,
97 const ImageFetcherCallback& callback) override {
98 // For simplicity, the fake doesn't support multiple concurrent requests.
99 DCHECK(!HasPendingRequest());
100
101 pending_id_ = id;
102 pending_url_ = url;
103 pending_callback_ = callback;
104 }
105
106 image_fetcher::ImageDecoder* GetImageDecoder() override {
107 NOTREACHED();
108 return nullptr;
109 }
110
111 bool HasPendingRequest() const { return !pending_callback_.is_null(); }
112
113 const GURL& pending_url() const { return pending_url_; }
114
115 void RespondToPendingRequest(const gfx::Image& image) {
116 DCHECK(HasPendingRequest());
117
118 RequestMetadata metadata;
119 metadata.http_response_code = 200;
120 pending_callback_.Run(pending_id_, image, metadata);
121
122 pending_id_.clear();
123 pending_url_ = GURL();
124 pending_callback_.Reset();
125 }
126
127 private:
128 std::string pending_id_;
129 GURL pending_url_;
130 ImageFetcherCallback pending_callback_;
131 };
132
63 DoodleConfig CreateConfig(DoodleType type) { 133 DoodleConfig CreateConfig(DoodleType type) {
64 return DoodleConfig(type, DoodleImage(GURL("https://doodle.com/image.jpg"))); 134 return DoodleConfig(type, DoodleImage(GURL("https://doodle.com/image.jpg")));
65 } 135 }
66 136
137 MATCHER(IsEmptyImage, "") {
138 return arg.IsEmpty();
139 }
140
67 } // namespace 141 } // namespace
68 142
69 class DoodleServiceTest : public testing::Test { 143 class DoodleServiceTest : public testing::Test {
70 public: 144 public:
71 DoodleServiceTest() 145 DoodleServiceTest()
72 : task_runner_(new base::TestMockTimeTaskRunner()), 146 : task_runner_(new base::TestMockTimeTaskRunner()),
73 task_runner_handle_(task_runner_), 147 task_runner_handle_(task_runner_),
74 tick_clock_(task_runner_->GetMockTickClock()), 148 tick_clock_(task_runner_->GetMockTickClock()),
75 fetcher_(nullptr), 149 fetcher_(nullptr),
76 expiry_timer_(nullptr) { 150 expiry_timer_(nullptr) {
77 DoodleService::RegisterProfilePrefs(pref_service_.registry()); 151 DoodleService::RegisterProfilePrefs(pref_service_.registry());
78 152
79 task_runner_->FastForwardBy(base::TimeDelta::FromHours(12345)); 153 task_runner_->FastForwardBy(base::TimeDelta::FromHours(12345));
80 154
81 // Set the minimum refresh interval to 0 by default, so tests don't have to 155 // Set the minimum refresh interval to 0 by default, so tests don't have to
82 // worry about it. The tests that care set it explicitly. 156 // worry about it. The tests that care set it explicitly.
83 RecreateServiceWithZeroRefreshInterval(); 157 RecreateServiceWithZeroRefreshInterval();
84 } 158 }
85 159
86 void DestroyService() { service_ = nullptr; } 160 void TearDown() override { DestroyService(); }
161
162 void DestroyService() {
163 if (image_fetcher_) {
164 // Make sure we didn't receive an unexpected image request.
165 ASSERT_FALSE(image_fetcher_->HasPendingRequest());
166 }
167
168 fetcher_ = nullptr;
169 expiry_timer_ = nullptr;
170 image_fetcher_ = nullptr;
171
172 service_ = nullptr;
173 }
87 174
88 void RecreateServiceWithZeroRefreshInterval() { 175 void RecreateServiceWithZeroRefreshInterval() {
89 RecreateService(/*min_refresh_interval=*/base::TimeDelta()); 176 RecreateService(/*min_refresh_interval=*/base::TimeDelta());
90 } 177 }
91 178
92 void RecreateService(base::Optional<base::TimeDelta> refresh_interval) { 179 void RecreateService(base::Optional<base::TimeDelta> refresh_interval) {
93 auto expiry_timer = base::MakeUnique<base::OneShotTimer>(tick_clock_.get()); 180 auto expiry_timer = base::MakeUnique<base::OneShotTimer>(tick_clock_.get());
94 expiry_timer->SetTaskRunner(task_runner_); 181 expiry_timer->SetTaskRunner(task_runner_);
95 expiry_timer_ = expiry_timer.get(); 182 expiry_timer_ = expiry_timer.get();
96 183
97 auto fetcher = base::MakeUnique<FakeDoodleFetcher>(); 184 auto fetcher = base::MakeUnique<FakeDoodleFetcher>();
98 fetcher_ = fetcher.get(); 185 fetcher_ = fetcher.get();
99 186
187 auto image_fetcher = base::MakeUnique<FakeImageFetcher>();
188 image_fetcher_ = image_fetcher.get();
189
100 service_ = base::MakeUnique<DoodleService>( 190 service_ = base::MakeUnique<DoodleService>(
101 &pref_service_, std::move(fetcher), std::move(expiry_timer), 191 &pref_service_, std::move(fetcher), std::move(expiry_timer),
102 task_runner_->GetMockClock(), task_runner_->GetMockTickClock(), 192 task_runner_->GetMockClock(), task_runner_->GetMockTickClock(),
103 refresh_interval); 193 refresh_interval, std::move(image_fetcher));
104 } 194 }
105 195
106 DoodleService* service() { return service_.get(); } 196 DoodleService* service() { return service_.get(); }
107 FakeDoodleFetcher* fetcher() { return fetcher_; } 197 FakeDoodleFetcher* fetcher() { return fetcher_; }
198 FakeImageFetcher* image_fetcher() { return image_fetcher_; }
108 199
109 base::TestMockTimeTaskRunner* task_runner() { return task_runner_.get(); } 200 base::TestMockTimeTaskRunner* task_runner() { return task_runner_.get(); }
110 201
111 private: 202 private:
112 TestingPrefServiceSimple pref_service_; 203 TestingPrefServiceSimple pref_service_;
113 204
114 scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; 205 scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
115 base::ThreadTaskRunnerHandle task_runner_handle_; 206 base::ThreadTaskRunnerHandle task_runner_handle_;
116 std::unique_ptr<base::TickClock> tick_clock_; 207 std::unique_ptr<base::TickClock> tick_clock_;
117 208
118 std::unique_ptr<DoodleService> service_; 209 std::unique_ptr<DoodleService> service_;
119 210
120 // Weak, owned by the service. 211 // Weak, owned by the service.
121 FakeDoodleFetcher* fetcher_; 212 FakeDoodleFetcher* fetcher_;
122 base::OneShotTimer* expiry_timer_; 213 base::OneShotTimer* expiry_timer_;
214 FakeImageFetcher* image_fetcher_;
123 }; 215 };
124 216
125 TEST_F(DoodleServiceTest, FetchesConfigOnRefresh) { 217 TEST_F(DoodleServiceTest, FetchesConfigOnRefresh) {
126 ASSERT_THAT(service()->config(), Eq(base::nullopt)); 218 ASSERT_THAT(service()->config(), Eq(base::nullopt));
127 219
128 // Request a refresh of the doodle config. 220 // Request a refresh of the doodle config.
129 service()->Refresh(); 221 service()->Refresh();
130 // The request should have arrived at the fetcher. 222 // The request should have arrived at the fetcher.
131 EXPECT_THAT(fetcher()->num_pending_callbacks(), Eq(1u)); 223 EXPECT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
132 224
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 682
591 // Fast-forward time so that the config expires. 683 // Fast-forward time so that the config expires.
592 task_runner()->FastForwardBy(base::TimeDelta::FromHours(1)); 684 task_runner()->FastForwardBy(base::TimeDelta::FromHours(1));
593 ASSERT_THAT(service()->config(), Eq(base::nullopt)); 685 ASSERT_THAT(service()->config(), Eq(base::nullopt));
594 686
595 // This should not have resulted in any metrics being emitted. 687 // This should not have resulted in any metrics being emitted.
596 histograms.ExpectTotalCount("Doodle.ConfigDownloadOutcome", 0); 688 histograms.ExpectTotalCount("Doodle.ConfigDownloadOutcome", 0);
597 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0); 689 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0);
598 } 690 }
599 691
692 TEST_F(DoodleServiceTest, GetImageWithEmptyConfigReturnsImmediately) {
693 ASSERT_THAT(service()->config(), Eq(base::nullopt));
694
695 base::MockCallback<DoodleService::ImageCallback> callback;
696 EXPECT_CALL(callback, Run(IsEmptyImage()));
697
698 service()->GetImage(callback.Get());
699 }
700
701 TEST_F(DoodleServiceTest, GetImageFetchesLargeImage) {
702 service()->Refresh();
703 DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
704 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
705 base::TimeDelta::FromHours(1), config);
706 ASSERT_THAT(service()->config(), Eq(config));
707
708 base::MockCallback<DoodleService::ImageCallback> callback;
709 service()->GetImage(callback.Get());
710
711 EXPECT_EQ(config.large_image.url, image_fetcher()->pending_url());
712
713 EXPECT_CALL(callback, Run(Not(IsEmptyImage())));
714 gfx::Image image = gfx::test::CreateImage(1, 1);
715 ASSERT_TRUE(image_fetcher()->HasPendingRequest());
716 image_fetcher()->RespondToPendingRequest(image);
717 }
718
719 TEST_F(DoodleServiceTest, GetImageFetchesCTAImage) {
720 service()->Refresh();
721 DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
722 // Set a CTA image, which should take precedence over the regular image.
723 config.large_image.is_animated_gif = true;
724 config.large_cta_image = DoodleImage(GURL("https://doodle.com/cta.jpg"));
725 config.large_cta_image->is_cta = true;
726 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
727 base::TimeDelta::FromHours(1), config);
728 ASSERT_THAT(service()->config(), Eq(config));
729
730 base::MockCallback<DoodleService::ImageCallback> callback;
731 service()->GetImage(callback.Get());
732
733 // If the doodle has a CTA image, that should loaded instead of the regular
734 // large image.
735 EXPECT_EQ(config.large_cta_image->url, image_fetcher()->pending_url());
736
737 EXPECT_CALL(callback, Run(Not(IsEmptyImage())));
738 gfx::Image image = gfx::test::CreateImage(1, 1);
739 ASSERT_TRUE(image_fetcher()->HasPendingRequest());
740 image_fetcher()->RespondToPendingRequest(image);
741 }
742
600 } // namespace doodle 743 } // namespace doodle
OLDNEW
« no previous file with comments | « components/doodle/doodle_service.cc ('k') | components/image_fetcher/core/image_fetcher_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698