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

Side by Side Diff: components/suggestions/suggestions_service_impl_unittest.cc

Issue 2869013004: Test SuggestionsServiceImpl without friending anything (Closed)
Patch Set: Rebase (to HEAD) 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/suggestions/suggestions_service_impl.h" 5 #include "components/suggestions/suggestions_service_impl.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
(...skipping 28 matching lines...) Expand all
39 using testing::AnyNumber; 39 using testing::AnyNumber;
40 using testing::DoAll; 40 using testing::DoAll;
41 using testing::Eq; 41 using testing::Eq;
42 using testing::Return; 42 using testing::Return;
43 using testing::SetArgPointee; 43 using testing::SetArgPointee;
44 using testing::StrictMock; 44 using testing::StrictMock;
45 45
46 namespace { 46 namespace {
47 47
48 const char kAccountId[] = "account"; 48 const char kAccountId[] = "account";
49 const char kSuggestionsUrlPath[] = "/chromesuggestions";
50 const char kBlacklistUrlPath[] = "/chromesuggestions/blacklist";
51 const char kBlacklistClearUrlPath[] = "/chromesuggestions/blacklist/clear";
49 const char kTestTitle[] = "a title"; 52 const char kTestTitle[] = "a title";
50 const char kTestUrl[] = "http://go.com"; 53 const char kTestUrl[] = "http://go.com";
51 const char kTestFaviconUrl[] = 54 const char kTestFaviconUrl[] =
52 "https://s2.googleusercontent.com/s2/favicons?domain_url=" 55 "https://s2.googleusercontent.com/s2/favicons?domain_url="
53 "http://go.com&alt=s&sz=32"; 56 "http://go.com&alt=s&sz=32";
54 const char kBlacklistedUrl[] = "http://blacklist.com"; 57 const char kBlacklistedUrl[] = "http://blacklist.com";
55 const char kBlacklistedUrlAlt[] = "http://blacklist-atl.com"; 58 const int64_t kTestSetExpiry = 12121212; // This timestamp lies in the past.
56 const int64_t kTestDefaultExpiry = 1402200000000000;
57 const int64_t kTestSetExpiry = 1404792000000000;
58
59 std::unique_ptr<net::FakeURLFetcher> CreateURLFetcher(
60 const GURL& url,
61 net::URLFetcherDelegate* delegate,
62 const std::string& response_data,
63 net::HttpStatusCode response_code,
64 net::URLRequestStatus::Status status) {
65 std::unique_ptr<net::FakeURLFetcher> fetcher(new net::FakeURLFetcher(
66 url, delegate, response_data, response_code, status));
67
68 if (response_code == net::HTTP_OK) {
69 scoped_refptr<net::HttpResponseHeaders> download_headers(
70 new net::HttpResponseHeaders(""));
71 download_headers->AddHeader("Content-Type: text/html");
72 fetcher->set_response_headers(download_headers);
73 }
74 return fetcher;
75 }
76 59
77 // GMock matcher for protobuf equality. 60 // GMock matcher for protobuf equality.
78 MATCHER_P(EqualsProto, message, "") { 61 MATCHER_P(EqualsProto, message, "") {
79 // This implementation assumes protobuf serialization is deterministic, which 62 // This implementation assumes protobuf serialization is deterministic, which
80 // is true in practice but technically not something that code is supposed 63 // is true in practice but technically not something that code is supposed
81 // to rely on. However, it vastly simplifies the implementation. 64 // to rely on. However, it vastly simplifies the implementation.
82 std::string expected_serialized, actual_serialized; 65 std::string expected_serialized, actual_serialized;
83 message.SerializeToString(&expected_serialized); 66 message.SerializeToString(&expected_serialized);
84 arg.SerializeToString(&actual_serialized); 67 arg.SerializeToString(&actual_serialized);
85 return expected_serialized == actual_serialized; 68 return expected_serialized == actual_serialized;
86 } 69 }
87 70
88 } // namespace 71 } // namespace
89 72
90 namespace suggestions { 73 namespace suggestions {
91 74
92 SuggestionsProfile CreateSuggestionsProfile() { 75 SuggestionsProfile CreateSuggestionsProfile() {
93 SuggestionsProfile profile; 76 SuggestionsProfile profile;
94 profile.set_timestamp(123); 77 profile.set_timestamp(123);
95 ChromeSuggestion* suggestion = profile.add_suggestions(); 78 ChromeSuggestion* suggestion = profile.add_suggestions();
96 suggestion->set_title(kTestTitle); 79 suggestion->set_title(kTestTitle);
97 suggestion->set_url(kTestUrl); 80 suggestion->set_url(kTestUrl);
98 suggestion->set_expiry_ts(kTestSetExpiry);
99 return profile; 81 return profile;
100 } 82 }
101 83
102 // Creates one suggestion with expiry timestamp and one without.
103 SuggestionsProfile CreateSuggestionsProfileWithExpiryTimestamps() {
104 SuggestionsProfile profile;
105 profile.set_timestamp(123);
106 ChromeSuggestion* suggestion = profile.add_suggestions();
107 suggestion->set_title(kTestTitle);
108 suggestion->set_url(kTestUrl);
109 suggestion->set_expiry_ts(kTestSetExpiry);
110
111 suggestion = profile.add_suggestions();
112 suggestion->set_title(kTestTitle);
113 suggestion->set_url(kTestUrl);
114
115 return profile;
116 }
117
118 class MockSyncService : public syncer::FakeSyncService { 84 class MockSyncService : public syncer::FakeSyncService {
119 public: 85 public:
120 MockSyncService() {} 86 MockSyncService() {}
121 virtual ~MockSyncService() {} 87 virtual ~MockSyncService() {}
122 MOCK_CONST_METHOD0(CanSyncStart, bool()); 88 MOCK_CONST_METHOD0(CanSyncStart, bool());
123 MOCK_CONST_METHOD0(IsSyncActive, bool()); 89 MOCK_CONST_METHOD0(IsSyncActive, bool());
124 MOCK_CONST_METHOD0(ConfigurationDone, bool()); 90 MOCK_CONST_METHOD0(ConfigurationDone, bool());
125 MOCK_CONST_METHOD0(GetActiveDataTypes, syncer::ModelTypeSet()); 91 MOCK_CONST_METHOD0(GetActiveDataTypes, syncer::ModelTypeSet());
126 }; 92 };
127 93
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 MOCK_METHOD1(GetCandidateForUpload, bool(GURL*)); 130 MOCK_METHOD1(GetCandidateForUpload, bool(GURL*));
165 MOCK_METHOD1(RemoveUrl, bool(const GURL&)); 131 MOCK_METHOD1(RemoveUrl, bool(const GURL&));
166 MOCK_METHOD1(FilterSuggestions, void(SuggestionsProfile*)); 132 MOCK_METHOD1(FilterSuggestions, void(SuggestionsProfile*));
167 }; 133 };
168 134
169 class SuggestionsServiceTest : public testing::Test { 135 class SuggestionsServiceTest : public testing::Test {
170 protected: 136 protected:
171 SuggestionsServiceTest() 137 SuggestionsServiceTest()
172 : signin_client_(&pref_service_), 138 : signin_client_(&pref_service_),
173 signin_manager_(&signin_client_, &account_tracker_), 139 signin_manager_(&signin_client_, &account_tracker_),
174 factory_(nullptr, base::Bind(&CreateURLFetcher)), 140 request_context_(new net::TestURLRequestContextGetter(
141 io_message_loop_.task_runner())),
175 mock_thumbnail_manager_(nullptr), 142 mock_thumbnail_manager_(nullptr),
176 mock_blacklist_store_(nullptr), 143 mock_blacklist_store_(nullptr),
177 test_suggestions_store_(nullptr) { 144 test_suggestions_store_(nullptr) {
178 SigninManagerBase::RegisterProfilePrefs(pref_service_.registry()); 145 SigninManagerBase::RegisterProfilePrefs(pref_service_.registry());
179 SigninManagerBase::RegisterPrefs(pref_service_.registry()); 146 SigninManagerBase::RegisterPrefs(pref_service_.registry());
180 147
181 signin_manager_.SignIn(kAccountId); 148 signin_manager_.SignIn(kAccountId);
182 token_service_.UpdateCredentials(kAccountId, "refresh_token"); 149 token_service_.UpdateCredentials(kAccountId, "refresh_token");
183 token_service_.set_auto_post_fetch_response_on_message_loop(true); 150 token_service_.set_auto_post_fetch_response_on_message_loop(true);
184 } 151 }
185 152
186 ~SuggestionsServiceTest() override {} 153 ~SuggestionsServiceTest() override {}
187 154
188 void SetUp() override { 155 void SetUp() override {
189 request_context_ = 156 IgnoreRepeatedMockCalls();
190 new net::TestURLRequestContextGetter(io_message_loop_.task_runner()); 157 CreateSuggestionsServiceWithMocks();
158 }
191 159
192 EXPECT_CALL(mock_sync_service_, CanSyncStart()) 160 void TearDown() override {
161 testing::Mock::VerifyAndClearExpectations(thumbnail_manager());
162 testing::Mock::VerifyAndClearExpectations(blacklist_store());
163 testing::Mock::VerifyAndClearExpectations(sync_service());
Marc Treib 2017/05/10 09:53:44 I don't think this is necessary. Doesn't that happ
fhorschig 2017/05/10 11:54:45 Gone.
164 }
165
166 GURL CurrentlyQueriedUrl() {
Marc Treib 2017/05/10 09:53:45 GetCurrentlyQueriedUrl?
fhorschig 2017/05/10 11:54:45 Done.
167 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
168 if (!fetcher) {
169 return GURL();
170 }
171 return fetcher->GetOriginalURL();
172 }
173
174 void RespondToFetch(const std::string& response_body,
175 net::HttpStatusCode response_code,
176 net::URLRequestStatus status) {
177 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
178 ASSERT_TRUE(fetcher) << "Tried to respond to fetch that is not ongoing!";
179 fetcher->SetResponseString(response_body);
180 fetcher->set_response_code(response_code);
181 fetcher->set_status(status);
182 fetcher->delegate()->OnURLFetchComplete(fetcher);
183 }
184
185 void RespondToFetchWithProfile(const SuggestionsProfile& profile) {
Marc Treib 2017/05/10 09:53:44 nit: RespondToFetchWithSuggestions? I find the "pr
fhorschig 2017/05/10 11:54:45 Done.
186 RespondToFetch(
187 profile.SerializeAsString(), net::HTTP_OK,
188 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
189 }
190
191 void NotifySuggestionsService() {
Marc Treib 2017/05/10 09:53:45 Notify of what? TBH, I'd leave this inlined into a
fhorschig 2017/05/10 11:54:45 Inlined with cast. (I am a little bit split here.
Marc Treib 2017/05/10 12:16:24 We had that discussion before. I prefer keeping it
fhorschig 2017/05/10 12:38:15 It's not a big deal. (My reasoning was: we don't a
192 // The implementation of |OnStateChanged| is private in the
193 // SuggestionsService, but public for every SyncServiceObserver.
194 syncer::SyncServiceObserver* observer = suggestions_service();
195 observer->OnStateChanged(sync_service());
196 }
197
198 void IgnoreRepeatedMockCalls() {
Marc Treib 2017/05/10 09:53:45 The point isn't to ignore the calls, but to return
fhorschig 2017/05/10 11:54:46 Inlined.
199 EXPECT_CALL(*sync_service(), CanSyncStart())
193 .Times(AnyNumber()) 200 .Times(AnyNumber())
194 .WillRepeatedly(Return(true)); 201 .WillRepeatedly(Return(true));
195 EXPECT_CALL(mock_sync_service_, IsSyncActive()) 202 EXPECT_CALL(*sync_service(), IsSyncActive())
196 .Times(AnyNumber()) 203 .Times(AnyNumber())
197 .WillRepeatedly(Return(true)); 204 .WillRepeatedly(Return(true));
198 EXPECT_CALL(mock_sync_service_, ConfigurationDone()) 205 EXPECT_CALL(*sync_service(), ConfigurationDone())
199 .Times(AnyNumber()) 206 .Times(AnyNumber())
200 .WillRepeatedly(Return(true)); 207 .WillRepeatedly(Return(true));
201 EXPECT_CALL(mock_sync_service_, GetActiveDataTypes()) 208 EXPECT_CALL(*sync_service(), GetActiveDataTypes())
202 .Times(AnyNumber()) 209 .Times(AnyNumber())
203 .WillRepeatedly( 210 .WillRepeatedly(
204 Return(syncer::ModelTypeSet(syncer::HISTORY_DELETE_DIRECTIVES))); 211 Return(syncer::ModelTypeSet(syncer::HISTORY_DELETE_DIRECTIVES)));
212 }
205 213
214 MockBlacklistStore* blacklist_store() { return mock_blacklist_store_; }
215
216 SuggestionsServiceImpl* suggestions_service() {
217 return suggestions_service_.get();
218 }
219
220 TestSuggestionsStore* suggestions_store() { return test_suggestions_store_; }
221
222 MockSyncService* sync_service() { return &mock_sync_service_; }
223
224 MockImageManager* thumbnail_manager() { return mock_thumbnail_manager_; }
225
226 FakeProfileOAuth2TokenService* token_service() { return &token_service_; }
Marc Treib 2017/05/10 09:53:45 nit: The order of the accessors seems a bit arbitr
fhorschig 2017/05/10 11:54:45 I don't consider alphabetic ordering very arbitrar
Marc Treib 2017/05/10 12:16:24 Hah, I didn't notice it was alphabetical :) Still,
fhorschig 2017/05/10 12:38:15 Agreed.
227
228 private:
229 void CreateSuggestionsServiceWithMocks() {
Marc Treib 2017/05/10 09:53:44 Any reason this is a separate method?
fhorschig 2017/05/10 11:54:45 Only Historic reasons. Inlined into setup.
206 // These objects are owned by the SuggestionsService, but we keep the 230 // These objects are owned by the SuggestionsService, but we keep the
207 // pointers around for testing. 231 // pointers around for testing.
208 test_suggestions_store_ = new TestSuggestionsStore(); 232 test_suggestions_store_ = new TestSuggestionsStore();
209 mock_thumbnail_manager_ = new StrictMock<MockImageManager>(); 233 mock_thumbnail_manager_ = new StrictMock<MockImageManager>();
210 mock_blacklist_store_ = new StrictMock<MockBlacklistStore>(); 234 mock_blacklist_store_ = new StrictMock<MockBlacklistStore>();
211 suggestions_service_ = base::MakeUnique<SuggestionsServiceImpl>( 235 suggestions_service_ = base::MakeUnique<SuggestionsServiceImpl>(
212 &signin_manager_, &token_service_, &mock_sync_service_, 236 &signin_manager_, &token_service_, &mock_sync_service_,
213 request_context_.get(), base::WrapUnique(test_suggestions_store_), 237 request_context_.get(), base::WrapUnique(test_suggestions_store_),
214 base::WrapUnique(mock_thumbnail_manager_), 238 base::WrapUnique(mock_thumbnail_manager_),
215 base::WrapUnique(mock_blacklist_store_)); 239 base::WrapUnique(mock_blacklist_store_));
216 } 240 }
217 241
218 bool HasPendingSuggestionsRequest() const {
219 return !!suggestions_service_->pending_request_.get();
220 }
221
222 protected:
223 base::MessageLoopForIO io_message_loop_; 242 base::MessageLoopForIO io_message_loop_;
224 TestingPrefServiceSyncable pref_service_; 243 TestingPrefServiceSyncable pref_service_;
225 AccountTrackerService account_tracker_; 244 AccountTrackerService account_tracker_;
226 TestSigninClient signin_client_; 245 TestSigninClient signin_client_;
227 FakeSigninManagerBase signin_manager_; 246 FakeSigninManagerBase signin_manager_;
228 net::FakeURLFetcherFactory factory_; 247 net::TestURLFetcherFactory factory_;
229 FakeProfileOAuth2TokenService token_service_; 248 FakeProfileOAuth2TokenService token_service_;
230 MockSyncService mock_sync_service_; 249 MockSyncService mock_sync_service_;
231 scoped_refptr<net::TestURLRequestContextGetter> request_context_; 250 scoped_refptr<net::TestURLRequestContextGetter> request_context_;
232 // Owned by the SuggestionsService. 251 // Owned by the SuggestionsService.
233 MockImageManager* mock_thumbnail_manager_; 252 MockImageManager* mock_thumbnail_manager_;
234 MockBlacklistStore* mock_blacklist_store_; 253 MockBlacklistStore* mock_blacklist_store_;
235 TestSuggestionsStore* test_suggestions_store_; 254 TestSuggestionsStore* test_suggestions_store_;
236 255
237 std::unique_ptr<SuggestionsServiceImpl> suggestions_service_; 256 std::unique_ptr<SuggestionsServiceImpl> suggestions_service_;
238 257
239 private:
240 DISALLOW_COPY_AND_ASSIGN(SuggestionsServiceTest); 258 DISALLOW_COPY_AND_ASSIGN(SuggestionsServiceTest);
241 }; 259 };
242 260
243 TEST_F(SuggestionsServiceTest, FetchSuggestionsData) { 261 TEST_F(SuggestionsServiceTest, FetchSuggestionsData) {
244 base::MockCallback<SuggestionsService::ResponseCallback> callback; 262 base::MockCallback<SuggestionsService::ResponseCallback> callback;
245 auto subscription = suggestions_service_->AddCallback(callback.Get()); 263 auto subscription = suggestions_service()->AddCallback(callback.Get());
246 264
247 // Set up net::FakeURLFetcherFactory. 265 EXPECT_CALL(*thumbnail_manager(), Initialize(_));
248 factory_.SetFakeResponse(SuggestionsServiceImpl::BuildSuggestionsURL(), 266 EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
249 CreateSuggestionsProfile().SerializeAsString(), 267 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
250 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
251
252 EXPECT_CALL(*mock_thumbnail_manager_, Initialize(_));
253 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_));
254 EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
255 .WillOnce(Return(false)); 268 .WillOnce(Return(false));
256 269
257 // Send the request. The data should be returned to the callback. 270 // Send the request. The data should be returned to the callback.
258 suggestions_service_->FetchSuggestionsData(); 271 suggestions_service()->FetchSuggestionsData();
259 272
260 EXPECT_CALL(callback, Run(_)); 273 EXPECT_CALL(callback, Run(_));
261 274
262 // Let the network request run.
263 base::RunLoop().RunUntilIdle(); 275 base::RunLoop().RunUntilIdle();
Marc Treib 2017/05/10 09:53:45 Is the RunLoop still needed? (Lots more instances
fhorschig 2017/05/10 11:54:45 Sadly yes. The request is preceeded by a task from
276 EXPECT_FALSE(CurrentlyQueriedUrl().is_empty());
277 EXPECT_TRUE(CurrentlyQueriedUrl().is_valid());
Marc Treib 2017/05/10 09:53:45 Valid implies not empty, so the above check is red
fhorschig 2017/05/10 11:54:45 Absolutely.
278 EXPECT_EQ(CurrentlyQueriedUrl().path(), kSuggestionsUrlPath);
279 RespondToFetchWithProfile(CreateSuggestionsProfile());
264 280
265 SuggestionsProfile suggestions; 281 SuggestionsProfile suggestions_profile;
Marc Treib 2017/05/10 09:53:44 nit: Any reason for putting the "profile" back? (m
fhorschig 2017/05/10 11:54:45 Rerenamed all instances. (Technically, it _is_ a p
Marc Treib 2017/05/10 12:16:24 Some places called this "suggestions_profile", som
fhorschig 2017/05/10 12:38:15 Acknowledged.
266 test_suggestions_store_->LoadSuggestions(&suggestions); 282 suggestions_store()->LoadSuggestions(&suggestions_profile);
267 ASSERT_EQ(1, suggestions.suggestions_size()); 283 ASSERT_EQ(1, suggestions_profile.suggestions_size());
268 EXPECT_EQ(kTestTitle, suggestions.suggestions(0).title()); 284 EXPECT_EQ(kTestTitle, suggestions_profile.suggestions(0).title());
269 EXPECT_EQ(kTestUrl, suggestions.suggestions(0).url()); 285 EXPECT_EQ(kTestUrl, suggestions_profile.suggestions(0).url());
270 EXPECT_EQ(kTestFaviconUrl, suggestions.suggestions(0).favicon_url()); 286 EXPECT_EQ(kTestFaviconUrl, suggestions_profile.suggestions(0).favicon_url());
271 } 287 }
272 288
273 TEST_F(SuggestionsServiceTest, IgnoresNoopSyncChange) { 289 TEST_F(SuggestionsServiceTest, IgnoresNoopSyncChange) {
274 base::MockCallback<SuggestionsService::ResponseCallback> callback; 290 base::MockCallback<SuggestionsService::ResponseCallback> callback;
275 EXPECT_CALL(callback, Run(_)).Times(0); 291 EXPECT_CALL(callback, Run(_)).Times(0);
276 auto subscription = suggestions_service_->AddCallback(callback.Get()); 292 auto subscription = suggestions_service()->AddCallback(callback.Get());
277
278 factory_.SetFakeResponse(SuggestionsServiceImpl::BuildSuggestionsURL(),
279 CreateSuggestionsProfile().SerializeAsString(),
280 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
281 293
282 // An no-op change should not result in a suggestions refresh. 294 // An no-op change should not result in a suggestions refresh.
283 suggestions_service_->OnStateChanged(&mock_sync_service_); 295 NotifySuggestionsService();
284 296
285 // Let any network request run (there shouldn't be one). 297 // Let any network request run (there shouldn't be one).
Marc Treib 2017/05/10 09:53:44 If the RunLoop is still needed, this comment needs
fhorschig 2017/05/10 11:54:45 Done.
286 base::RunLoop().RunUntilIdle(); 298 base::RunLoop().RunUntilIdle();
299 EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
287 } 300 }
288 301
289 TEST_F(SuggestionsServiceTest, IgnoresUninterestingSyncChange) { 302 TEST_F(SuggestionsServiceTest, IgnoresUninterestingSyncChange) {
290 base::MockCallback<SuggestionsService::ResponseCallback> callback; 303 base::MockCallback<SuggestionsService::ResponseCallback> callback;
291 EXPECT_CALL(callback, Run(_)).Times(0); 304 EXPECT_CALL(callback, Run(_)).Times(0);
292 auto subscription = suggestions_service_->AddCallback(callback.Get()); 305 auto subscription = suggestions_service()->AddCallback(callback.Get());
293
294 factory_.SetFakeResponse(SuggestionsServiceImpl::BuildSuggestionsURL(),
295 CreateSuggestionsProfile().SerializeAsString(),
296 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
297 306
298 // An uninteresting change should not result in a network request (the 307 // An uninteresting change should not result in a network request (the
299 // SyncState is INITIALIZED_ENABLED_HISTORY before and after). 308 // SyncState is INITIALIZED_ENABLED_HISTORY before and after).
300 EXPECT_CALL(mock_sync_service_, GetActiveDataTypes()) 309 EXPECT_CALL(*sync_service(), GetActiveDataTypes())
301 .Times(AnyNumber()) 310 .Times(AnyNumber())
302 .WillRepeatedly(Return(syncer::ModelTypeSet( 311 .WillRepeatedly(Return(syncer::ModelTypeSet(
303 syncer::HISTORY_DELETE_DIRECTIVES, syncer::BOOKMARKS))); 312 syncer::HISTORY_DELETE_DIRECTIVES, syncer::BOOKMARKS)));
304 suggestions_service_->OnStateChanged(&mock_sync_service_); 313 NotifySuggestionsService();
305 314
306 // Let any network request run (there shouldn't be one). 315 // Let any network request run (there shouldn't be one).
307 base::RunLoop().RunUntilIdle(); 316 base::RunLoop().RunUntilIdle();
317 EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
308 } 318 }
309 319
310 // During startup, the state changes from NOT_INITIALIZED_ENABLED to 320 // During startup, the state changes from NOT_INITIALIZED_ENABLED to
311 // INITIALIZED_ENABLED_HISTORY (for a signed-in user with history sync enabled). 321 // INITIALIZED_ENABLED_HISTORY (for a signed-in user with history sync enabled).
312 // This should *not* result in an automatic fetch. 322 // This should *not* result in an automatic fetch.
313 TEST_F(SuggestionsServiceTest, DoesNotFetchOnStartup) { 323 TEST_F(SuggestionsServiceTest, DoesNotFetchOnStartup) {
314 // The sync service starts out inactive. 324 // The sync service starts out inactive.
315 EXPECT_CALL(mock_sync_service_, IsSyncActive()).WillRepeatedly(Return(false)); 325 EXPECT_CALL(*sync_service(), IsSyncActive()).WillRepeatedly(Return(false));
316 suggestions_service_->OnStateChanged(&mock_sync_service_); 326 NotifySuggestionsService();
317 327
318 ASSERT_EQ(SuggestionsServiceImpl::NOT_INITIALIZED_ENABLED, 328 base::RunLoop().RunUntilIdle();
319 suggestions_service_->ComputeSyncState()); 329 ASSERT_FALSE(suggestions_service()->has_pending_request_for_testing());
330
331 // Sync getting enabled should not result in a fetch.
332 EXPECT_CALL(*sync_service(), IsSyncActive()).WillRepeatedly(Return(true));
333 NotifySuggestionsService();
334
335 // Let any network request run (there shouldn't be one).
336 base::RunLoop().RunUntilIdle();
337 EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
338 }
339
340 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataSyncNotInitializedEnabled) {
341 EXPECT_CALL(*sync_service(), IsSyncActive()).WillRepeatedly(Return(false));
342 NotifySuggestionsService();
320 343
321 base::MockCallback<SuggestionsService::ResponseCallback> callback; 344 base::MockCallback<SuggestionsService::ResponseCallback> callback;
322 EXPECT_CALL(callback, Run(_)).Times(0); 345 EXPECT_CALL(callback, Run(_)).Times(0);
323 auto subscription = suggestions_service_->AddCallback(callback.Get()); 346 auto subscription = suggestions_service()->AddCallback(callback.Get());
324
325 factory_.SetFakeResponse(SuggestionsServiceImpl::BuildSuggestionsURL(),
326 CreateSuggestionsProfile().SerializeAsString(),
327 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
328
329 // Sync getting enabled should not result in a fetch.
330 EXPECT_CALL(mock_sync_service_, IsSyncActive()).WillRepeatedly(Return(true));
331 suggestions_service_->OnStateChanged(&mock_sync_service_);
332
333 ASSERT_EQ(SuggestionsServiceImpl::INITIALIZED_ENABLED_HISTORY,
334 suggestions_service_->ComputeSyncState());
335
336 // Let any network request run (there shouldn't be one).
337 base::RunLoop().RunUntilIdle();
338 }
339
340 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataSyncNotInitializedEnabled) {
341 EXPECT_CALL(mock_sync_service_, IsSyncActive()).WillRepeatedly(Return(false));
342 suggestions_service_->OnStateChanged(&mock_sync_service_);
343
344 base::MockCallback<SuggestionsService::ResponseCallback> callback;
345 EXPECT_CALL(callback, Run(_)).Times(0);
346 auto subscription = suggestions_service_->AddCallback(callback.Get());
347 347
348 // Try to fetch suggestions. Since sync is not active, no network request 348 // Try to fetch suggestions. Since sync is not active, no network request
349 // should be sent. 349 // should be sent.
350 suggestions_service_->FetchSuggestionsData(); 350 suggestions_service()->FetchSuggestionsData();
351 351
352 // Let any network request run (there shouldn't be one). 352 // Let any network request run (there shouldn't be one).
353 base::RunLoop().RunUntilIdle(); 353 base::RunLoop().RunUntilIdle();
354 354 EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
355 // |test_suggestions_store_| should still contain the default values. 355
356 // |suggestions_store()| should still contain the default values.
356 SuggestionsProfile suggestions; 357 SuggestionsProfile suggestions;
357 test_suggestions_store_->LoadSuggestions(&suggestions); 358 suggestions_store()->LoadSuggestions(&suggestions);
358 EXPECT_THAT(suggestions, EqualsProto(CreateSuggestionsProfile())); 359 EXPECT_THAT(suggestions, EqualsProto(CreateSuggestionsProfile()));
359 } 360 }
360 361
361 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataSyncDisabled) { 362 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataSyncDisabled) {
362 EXPECT_CALL(mock_sync_service_, CanSyncStart()).WillRepeatedly(Return(false)); 363 EXPECT_CALL(*sync_service(), CanSyncStart()).WillRepeatedly(Return(false));
363 364
364 base::MockCallback<SuggestionsService::ResponseCallback> callback; 365 base::MockCallback<SuggestionsService::ResponseCallback> callback;
365 auto subscription = suggestions_service_->AddCallback(callback.Get()); 366 auto subscription = suggestions_service()->AddCallback(callback.Get());
366 367
367 // Tell SuggestionsService that the sync state changed. The cache should be 368 // Tell SuggestionsService that the sync state changed. The cache should be
368 // cleared and empty data returned to the callback. 369 // cleared and empty data returned to the callback.
369 EXPECT_CALL(callback, Run(EqualsProto(SuggestionsProfile()))); 370 EXPECT_CALL(callback, Run(EqualsProto(SuggestionsProfile())));
370 suggestions_service_->OnStateChanged(&mock_sync_service_); 371 NotifySuggestionsService();
371 372
372 // Try to fetch suggestions. Since sync is not active, no network request 373 // Try to fetch suggestions. Since sync is not active, no network request
373 // should be sent. 374 // should be sent.
374 suggestions_service_->FetchSuggestionsData(); 375 suggestions_service()->FetchSuggestionsData();
375 376
376 // Let any network request run. 377 // Let any network request run.
377 base::RunLoop().RunUntilIdle(); 378 base::RunLoop().RunUntilIdle();
379 EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
378 } 380 }
379 381
380 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataNoAccessToken) { 382 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataNoAccessToken) {
381 token_service_.set_auto_post_fetch_response_on_message_loop(false); 383 token_service()->set_auto_post_fetch_response_on_message_loop(false);
382 384
383 base::MockCallback<SuggestionsService::ResponseCallback> callback; 385 base::MockCallback<SuggestionsService::ResponseCallback> callback;
384 EXPECT_CALL(callback, Run(_)).Times(0); 386 EXPECT_CALL(callback, Run(_)).Times(0);
385 auto subscription = suggestions_service_->AddCallback(callback.Get()); 387 auto subscription = suggestions_service()->AddCallback(callback.Get());
386 388
387 EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_)) 389 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
388 .WillOnce(Return(false)); 390 .WillOnce(Return(false));
389 391
390 suggestions_service_->FetchSuggestionsData(); 392 suggestions_service()->FetchSuggestionsData();
391 393
392 token_service_.IssueErrorForAllPendingRequests(GoogleServiceAuthError( 394 token_service()->IssueErrorForAllPendingRequests(GoogleServiceAuthError(
393 GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS)); 395 GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));
394 396
395 // No network request should be sent. 397 // No network request should be sent.
396 base::RunLoop().RunUntilIdle(); 398 base::RunLoop().RunUntilIdle();
397 EXPECT_FALSE(HasPendingSuggestionsRequest()); 399 EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
398 } 400 }
399 401
400 TEST_F(SuggestionsServiceTest, IssueRequestIfNoneOngoingError) { 402 TEST_F(SuggestionsServiceTest, FetchingSuggestionsIgnoresRequestFailure) {
401 // Fake a request error. 403 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
402 factory_.SetFakeResponse(SuggestionsServiceImpl::BuildSuggestionsURL(), 404 .WillOnce(Return(false));
403 "irrelevant", net::HTTP_OK, 405
404 net::URLRequestStatus::FAILED); 406 suggestions_service()->FetchSuggestionsData();
405 407
406 EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_)) 408 base::RunLoop().RunUntilIdle();
409 RespondToFetch("irrelevant", net::HTTP_OK,
410 net::URLRequestStatus(net::URLRequestStatus::FAILED,
411 net::ERR_INVALID_RESPONSE));
Marc Treib 2017/05/10 09:53:45 What exactly does this test?
fhorschig 2017/05/10 11:54:45 The original idea was probably to just have the co
Marc Treib 2017/05/10 12:16:24 Acknowledged.
fhorschig 2017/05/10 12:38:15 Acknowledged.
412 }
413
414 TEST_F(SuggestionsServiceTest, FetchingSuggestionsClearsStoreIfResponseNotOK) {
415 suggestions_store()->StoreSuggestions(CreateSuggestionsProfile());
416
417 // Expect that an upload to the blacklist is scheduled.
418 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
407 .WillOnce(Return(false)); 419 .WillOnce(Return(false));
408 420
409 // Send the request. Empty data will be returned to the callback. 421 // Send the request. Empty data will be returned to the callback.
410 suggestions_service_->IssueRequestIfNoneOngoing( 422 suggestions_service()->FetchSuggestionsData();
411 SuggestionsServiceImpl::BuildSuggestionsURL()); 423
412 424 base::RunLoop().RunUntilIdle();
413 // (Testing only) wait until suggestion fetch is complete. 425 RespondToFetch(
414 base::RunLoop().RunUntilIdle(); 426 "irrelevant", net::HTTP_BAD_REQUEST,
415 } 427 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
416 428
417 TEST_F(SuggestionsServiceTest, IssueRequestIfNoneOngoingResponseNotOK) {
418 // Fake a non-200 response code.
419 factory_.SetFakeResponse(SuggestionsServiceImpl::BuildSuggestionsURL(),
420 "irrelevant", net::HTTP_BAD_REQUEST,
421 net::URLRequestStatus::SUCCESS);
422
423 // Expect that an upload to the blacklist is scheduled.
424 EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
425 .WillOnce(Return(false));
426
427 // Send the request. Empty data will be returned to the callback.
428 suggestions_service_->IssueRequestIfNoneOngoing(
429 SuggestionsServiceImpl::BuildSuggestionsURL());
430
431 // (Testing only) wait until suggestion fetch is complete.
432 base::RunLoop().RunUntilIdle();
433
434 // Expect no suggestions in the cache.
435 SuggestionsProfile empty_suggestions; 429 SuggestionsProfile empty_suggestions;
436 EXPECT_FALSE(test_suggestions_store_->LoadSuggestions(&empty_suggestions)); 430 EXPECT_FALSE(suggestions_store()->LoadSuggestions(&empty_suggestions));
437 } 431 }
438 432
439 TEST_F(SuggestionsServiceTest, BlacklistURL) { 433 TEST_F(SuggestionsServiceTest, BlacklistURL) {
434 // Calling RunUntilIdle on the MessageLoop only works when the task is not
Marc Treib 2017/05/10 09:53:45 nit: It's a RunLoop, not a MessageLoop.
fhorschig 2017/05/10 11:54:45 Thanks! I mindlessly copied that comment.
435 // posted for the future.
440 const base::TimeDelta no_delay = base::TimeDelta::FromSeconds(0); 436 const base::TimeDelta no_delay = base::TimeDelta::FromSeconds(0);
441 suggestions_service_->set_blacklist_delay(no_delay); 437 suggestions_service()->set_blacklist_delay_for_testing(no_delay);
442 438
443 base::MockCallback<SuggestionsService::ResponseCallback> callback; 439 base::MockCallback<SuggestionsService::ResponseCallback> callback;
444 auto subscription = suggestions_service_->AddCallback(callback.Get()); 440 auto subscription = suggestions_service()->AddCallback(callback.Get());
445 441
446 const GURL blacklisted_url(kBlacklistedUrl); 442 EXPECT_CALL(*thumbnail_manager(), Initialize(_)).Times(2);
447 const GURL request_url( 443 EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
448 SuggestionsServiceImpl::BuildSuggestionsBlacklistURL(blacklisted_url)); 444 .WillOnce(Return(true));
449 factory_.SetFakeResponse(request_url, 445 EXPECT_CALL(*blacklist_store(), FilterSuggestions(_)).Times(2);
450 CreateSuggestionsProfile().SerializeAsString(), 446 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
451 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
452 EXPECT_CALL(*mock_thumbnail_manager_, Initialize(_)).Times(2);
453
454 // Expected calls to the blacklist store.
455 EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url)))
456 .WillOnce(Return(true));
457 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)).Times(2);
458 EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
459 .WillOnce(DoAll(SetArgPointee<0>(no_delay), Return(true))) 447 .WillOnce(DoAll(SetArgPointee<0>(no_delay), Return(true)))
460 .WillOnce(Return(false)); 448 .WillOnce(Return(false));
461 EXPECT_CALL(*mock_blacklist_store_, GetCandidateForUpload(_)) 449 EXPECT_CALL(*blacklist_store(), GetCandidateForUpload(_))
462 .WillOnce(DoAll(SetArgPointee<0>(blacklisted_url), Return(true))); 450 .WillOnce(DoAll(SetArgPointee<0>(GURL(kBlacklistedUrl)), Return(true)));
463 EXPECT_CALL(*mock_blacklist_store_, RemoveUrl(Eq(blacklisted_url))) 451 EXPECT_CALL(*blacklist_store(), RemoveUrl(Eq(GURL(kBlacklistedUrl))))
464 .WillOnce(Return(true)); 452 .WillOnce(Return(true));
465 453
466 EXPECT_CALL(callback, Run(_)).Times(2); 454 EXPECT_CALL(callback, Run(_)).Times(2);
467 455
468 EXPECT_TRUE(suggestions_service_->BlacklistURL(blacklisted_url)); 456 EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
469 457
470 // Wait on the upload task, the blacklist request and the next blacklist 458 // Wait on the upload task, the blacklist request and the next blacklist
471 // scheduling task. This only works when the scheduling task is not for future 459 // scheduling task.
472 // execution (note how both the SuggestionsService's scheduling delay and the 460 base::RunLoop().RunUntilIdle();
473 // BlacklistStore's candidacy delay are zero). 461
Marc Treib 2017/05/10 09:53:45 I'd leave the explanation here.
fhorschig 2017/05/10 11:54:46 Reverted.
474 base::RunLoop().RunUntilIdle(); 462 EXPECT_EQ(CurrentlyQueriedUrl().path(), kBlacklistUrlPath);
475 463 RespondToFetchWithProfile(CreateSuggestionsProfile());
476 SuggestionsProfile suggestions; 464
477 test_suggestions_store_->LoadSuggestions(&suggestions); 465 SuggestionsProfile suggestions_profile;
478 ASSERT_EQ(1, suggestions.suggestions_size()); 466 suggestions_store()->LoadSuggestions(&suggestions_profile);
479 EXPECT_EQ(kTestTitle, suggestions.suggestions(0).title()); 467 ASSERT_EQ(1, suggestions_profile.suggestions_size());
480 EXPECT_EQ(kTestUrl, suggestions.suggestions(0).url()); 468 EXPECT_EQ(kTestTitle, suggestions_profile.suggestions(0).title());
481 EXPECT_EQ(kTestFaviconUrl, suggestions.suggestions(0).favicon_url()); 469 EXPECT_EQ(kTestUrl, suggestions_profile.suggestions(0).url());
470 EXPECT_EQ(kTestFaviconUrl, suggestions_profile.suggestions(0).favicon_url());
482 } 471 }
483 472
484 TEST_F(SuggestionsServiceTest, BlacklistURLFails) { 473 TEST_F(SuggestionsServiceTest, BlacklistURLFails) {
485 base::MockCallback<SuggestionsService::ResponseCallback> callback; 474 base::MockCallback<SuggestionsService::ResponseCallback> callback;
486 EXPECT_CALL(callback, Run(_)).Times(0); 475 EXPECT_CALL(callback, Run(_)).Times(0);
487 auto subscription = suggestions_service_->AddCallback(callback.Get()); 476 auto subscription = suggestions_service()->AddCallback(callback.Get());
488 477
489 const GURL blacklisted_url(kBlacklistedUrl); 478 EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
490 EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url))) 479 .WillOnce(Return(false));
491 .WillOnce(Return(false)); 480
492 EXPECT_FALSE(suggestions_service_->BlacklistURL(blacklisted_url)); 481 EXPECT_FALSE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
493 } 482 }
494 483
495 // Initial blacklist request fails, triggering a second which succeeds. 484 TEST_F(SuggestionsServiceTest, RetryBlacklistURLRequestAfterFailure) {
496 TEST_F(SuggestionsServiceTest, BlacklistURLRequestFails) { 485 // Calling RunUntilIdle on the MessageLoop only works when the task is not
486 // posted for the future.
497 const base::TimeDelta no_delay = base::TimeDelta::FromSeconds(0); 487 const base::TimeDelta no_delay = base::TimeDelta::FromSeconds(0);
498 suggestions_service_->set_blacklist_delay(no_delay); 488 suggestions_service()->set_blacklist_delay_for_testing(no_delay);
499 489
500 base::MockCallback<SuggestionsService::ResponseCallback> callback; 490 base::MockCallback<SuggestionsService::ResponseCallback> callback;
501 auto subscription = suggestions_service_->AddCallback(callback.Get()); 491 auto subscription = suggestions_service()->AddCallback(callback.Get());
502 492
503 const GURL blacklisted_url(kBlacklistedUrl); 493 EXPECT_CALL(*thumbnail_manager(), Initialize(_)).Times(2);
504 const GURL request_url( 494 EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
505 SuggestionsServiceImpl::BuildSuggestionsBlacklistURL(blacklisted_url)); 495 .WillOnce(Return(true));
506 const GURL blacklisted_url_alt(kBlacklistedUrlAlt); 496 EXPECT_CALL(*blacklist_store(), FilterSuggestions(_)).Times(2);
507 const GURL request_url_alt( 497 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
Marc Treib 2017/05/10 09:53:45 I think the stuff below might be worth a comment (
fhorschig 2017/05/10 11:54:45 Done and split the expectations to see the the cor
508 SuggestionsServiceImpl::BuildSuggestionsBlacklistURL(
509 blacklisted_url_alt));
510
511 // Note: we want to set the response for the blacklist URL to first
512 // succeed, then fail. This doesn't seem possible. For simplicity of testing,
513 // we'll pretend the URL changed in the BlacklistStore between the first and
514 // the second request, and adjust expectations accordingly.
515 factory_.SetFakeResponse(request_url, "irrelevant", net::HTTP_OK,
516 net::URLRequestStatus::FAILED);
517 factory_.SetFakeResponse(request_url_alt,
518 CreateSuggestionsProfile().SerializeAsString(),
519 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
520
521 // Expectations.
522 EXPECT_CALL(*mock_thumbnail_manager_, Initialize(_)).Times(2);
523 EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url)))
524 .WillOnce(Return(true));
525 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)).Times(2);
526 EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
527 .WillOnce(DoAll(SetArgPointee<0>(no_delay), Return(true))) 498 .WillOnce(DoAll(SetArgPointee<0>(no_delay), Return(true)))
528 .WillOnce(DoAll(SetArgPointee<0>(no_delay), Return(true))) 499 .WillOnce(DoAll(SetArgPointee<0>(no_delay), Return(true)))
529 .WillOnce(Return(false)); 500 .WillOnce(Return(false));
530 EXPECT_CALL(*mock_blacklist_store_, GetCandidateForUpload(_)) 501 EXPECT_CALL(*blacklist_store(), GetCandidateForUpload(_))
531 .WillOnce(DoAll(SetArgPointee<0>(blacklisted_url), Return(true))) 502 .WillOnce(DoAll(SetArgPointee<0>(GURL(kBlacklistedUrl)), Return(true)))
532 .WillOnce(DoAll(SetArgPointee<0>(blacklisted_url_alt), Return(true))); 503 .WillOnce(DoAll(SetArgPointee<0>(GURL(kBlacklistedUrl)), Return(true)));
533 EXPECT_CALL(*mock_blacklist_store_, RemoveUrl(Eq(blacklisted_url_alt))) 504 EXPECT_CALL(*blacklist_store(), RemoveUrl(Eq(GURL(kBlacklistedUrl))))
534 .WillOnce(Return(true)); 505 .WillOnce(Return(true));
535 506
536 EXPECT_CALL(callback, Run(_)).Times(2); 507 EXPECT_CALL(callback, Run(_)).Times(2);
537 508
538 // Blacklist call, first request attempt. 509 // Blacklist call, first request attempt.
539 EXPECT_TRUE(suggestions_service_->BlacklistURL(blacklisted_url)); 510 EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
540 511
541 // Wait for the first scheduling, the first request, the second scheduling, 512 // Wait for the first scheduling receiving a failing response.
542 // second request and the third scheduling. Again, note that calling 513 base::RunLoop().RunUntilIdle();
543 // RunUntilIdle on the MessageLoop only works when the task is not posted for 514 EXPECT_EQ(CurrentlyQueriedUrl().path(), kBlacklistUrlPath);
544 // the future. 515 RespondToFetch("irrelevant", net::HTTP_OK,
545 base::RunLoop().RunUntilIdle(); 516 net::URLRequestStatus(net::URLRequestStatus::FAILED,
546 517 net::ERR_INVALID_RESPONSE));
547 SuggestionsProfile suggestions; 518
548 test_suggestions_store_->LoadSuggestions(&suggestions); 519 // Wait for the second scheduling followed by a successful response.
549 ASSERT_EQ(1, suggestions.suggestions_size()); 520 base::RunLoop().RunUntilIdle();
550 EXPECT_EQ(kTestTitle, suggestions.suggestions(0).title()); 521 ASSERT_TRUE(CurrentlyQueriedUrl().is_valid());
Marc Treib 2017/05/10 09:53:44 nit: Why? There isn't a similar assert above.
fhorschig 2017/05/10 11:54:45 But there should be. Fixed.
551 EXPECT_EQ(kTestUrl, suggestions.suggestions(0).url()); 522 EXPECT_EQ(CurrentlyQueriedUrl().path(), kBlacklistUrlPath);
552 EXPECT_EQ(kTestFaviconUrl, suggestions.suggestions(0).favicon_url()); 523 RespondToFetchWithProfile(CreateSuggestionsProfile());
524
525 SuggestionsProfile suggestions_profile;
526 suggestions_store()->LoadSuggestions(&suggestions_profile);
527 ASSERT_EQ(1, suggestions_profile.suggestions_size());
528 EXPECT_EQ(kTestTitle, suggestions_profile.suggestions(0).title());
529 EXPECT_EQ(kTestUrl, suggestions_profile.suggestions(0).url());
530 EXPECT_EQ(kTestFaviconUrl, suggestions_profile.suggestions(0).favicon_url());
553 } 531 }
554 532
555 TEST_F(SuggestionsServiceTest, UndoBlacklistURL) { 533 TEST_F(SuggestionsServiceTest, UndoBlacklistURL) {
556 // Ensure scheduling the request doesn't happen before undo. 534 // Ensure scheduling the request doesn't happen before undo.
557 const base::TimeDelta delay = base::TimeDelta::FromHours(1); 535 const base::TimeDelta delay = base::TimeDelta::FromHours(1);
558 suggestions_service_->set_blacklist_delay(delay); 536 suggestions_service()->set_blacklist_delay_for_testing(delay);
559 537
560 base::MockCallback<SuggestionsService::ResponseCallback> callback; 538 base::MockCallback<SuggestionsService::ResponseCallback> callback;
561 auto subscription = suggestions_service_->AddCallback(callback.Get()); 539 auto subscription = suggestions_service()->AddCallback(callback.Get());
562
563 const GURL blacklisted_url(kBlacklistedUrl);
564 540
565 // Blacklist expectations. 541 // Blacklist expectations.
566 EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url))) 542 EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
567 .WillOnce(Return(true)); 543 .WillOnce(Return(true));
568 EXPECT_CALL(*mock_thumbnail_manager_, 544 EXPECT_CALL(*thumbnail_manager(),
569 Initialize(EqualsProto(CreateSuggestionsProfile()))) 545 Initialize(EqualsProto(CreateSuggestionsProfile())))
570 .Times(AnyNumber()); 546 .Times(AnyNumber());
571 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)).Times(AnyNumber()); 547 EXPECT_CALL(*blacklist_store(), FilterSuggestions(_)).Times(AnyNumber());
572 EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_)) 548 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
573 .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true))); 549 .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true)));
574 // Undo expectations. 550 // Undo expectations.
575 EXPECT_CALL(*mock_blacklist_store_, 551 EXPECT_CALL(*blacklist_store(),
576 GetTimeUntilURLReadyForUpload(Eq(blacklisted_url), _)) 552 GetTimeUntilURLReadyForUpload(Eq(GURL(kBlacklistedUrl)), _))
577 .WillOnce(DoAll(SetArgPointee<1>(delay), Return(true))); 553 .WillOnce(DoAll(SetArgPointee<1>(delay), Return(true)));
578 EXPECT_CALL(*mock_blacklist_store_, RemoveUrl(Eq(blacklisted_url))) 554 EXPECT_CALL(*blacklist_store(), RemoveUrl(Eq(GURL(kBlacklistedUrl))))
579 .WillOnce(Return(true)); 555 .WillOnce(Return(true));
580 556
581 EXPECT_CALL(callback, Run(_)).Times(2); 557 EXPECT_CALL(callback, Run(_)).Times(2);
582 EXPECT_TRUE(suggestions_service_->BlacklistURL(blacklisted_url)); 558 EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
583 EXPECT_TRUE(suggestions_service_->UndoBlacklistURL(blacklisted_url)); 559 EXPECT_TRUE(suggestions_service()->UndoBlacklistURL(GURL(kBlacklistedUrl)));
584 } 560 }
585 561
586 TEST_F(SuggestionsServiceTest, ClearBlacklist) { 562 TEST_F(SuggestionsServiceTest, ClearBlacklist) {
587 // Ensure scheduling the request doesn't happen before undo. 563 // Ensure scheduling the request doesn't happen before undo.
Marc Treib 2017/05/10 09:53:45 Pre-existing problem, but this comment seems out o
fhorschig 2017/05/10 11:54:46 Gone.
588 const base::TimeDelta delay = base::TimeDelta::FromHours(1); 564 const base::TimeDelta delay = base::TimeDelta::FromHours(1);
589 suggestions_service_->set_blacklist_delay(delay); 565 suggestions_service()->set_blacklist_delay_for_testing(delay);
590 566 base::MockCallback<SuggestionsService::ResponseCallback> callback;
Marc Treib 2017/05/10 09:53:44 nit: Keep the newline above
fhorschig 2017/05/10 11:54:45 Done.
591 base::MockCallback<SuggestionsService::ResponseCallback> callback; 567 auto subscription = suggestions_service()->AddCallback(callback.Get());
592 auto subscription = suggestions_service_->AddCallback(callback.Get());
593
594 const SuggestionsProfile suggestions_profile = CreateSuggestionsProfile();
595 const GURL blacklisted_url(kBlacklistedUrl);
596
597 factory_.SetFakeResponse(
598 SuggestionsServiceImpl::BuildSuggestionsBlacklistClearURL(),
599 suggestions_profile.SerializeAsString(), net::HTTP_OK,
600 net::URLRequestStatus::SUCCESS);
601 568
602 // Blacklist expectations. 569 // Blacklist expectations.
603 EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url))) 570 EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
604 .WillOnce(Return(true)); 571 .WillOnce(Return(true));
605 EXPECT_CALL(*mock_thumbnail_manager_, 572 EXPECT_CALL(*thumbnail_manager(),
606 Initialize(EqualsProto(suggestions_profile))) 573 Initialize(EqualsProto(CreateSuggestionsProfile())))
607 .Times(AnyNumber()); 574 .Times(AnyNumber());
608 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)).Times(AnyNumber()); 575 EXPECT_CALL(*blacklist_store(), FilterSuggestions(_)).Times(AnyNumber());
609 EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_)) 576 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
610 .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true))); 577 .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true)));
611 EXPECT_CALL(*mock_blacklist_store_, ClearBlacklist()); 578 EXPECT_CALL(*blacklist_store(), ClearBlacklist());
612 579
613 EXPECT_CALL(callback, Run(_)).Times(2); 580 EXPECT_CALL(callback, Run(_)).Times(2);
614 EXPECT_TRUE(suggestions_service_->BlacklistURL(blacklisted_url)); 581 EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
615 suggestions_service_->ClearBlacklist(); 582 suggestions_service()->ClearBlacklist();
583
584 base::RunLoop().RunUntilIdle();
585 EXPECT_EQ(CurrentlyQueriedUrl().path(), kBlacklistClearUrlPath);
616 } 586 }
617 587
618 TEST_F(SuggestionsServiceTest, UndoBlacklistURLFailsIfNotInBlacklist) { 588 TEST_F(SuggestionsServiceTest, UndoBlacklistURLFailsIfNotInBlacklist) {
619 // Ensure scheduling the request doesn't happen before undo. 589 // Ensure scheduling the request doesn't happen before undo.
620 const base::TimeDelta delay = base::TimeDelta::FromHours(1); 590 const base::TimeDelta delay = base::TimeDelta::FromHours(1);
621 suggestions_service_->set_blacklist_delay(delay); 591 suggestions_service()->set_blacklist_delay_for_testing(delay);
622 592 base::MockCallback<SuggestionsService::ResponseCallback> callback;
Marc Treib 2017/05/10 09:53:45 Also here: newline above
fhorschig 2017/05/10 11:54:45 Also done.
623 base::MockCallback<SuggestionsService::ResponseCallback> callback; 593 auto subscription = suggestions_service()->AddCallback(callback.Get());
624 auto subscription = suggestions_service_->AddCallback(callback.Get());
625
626 const GURL blacklisted_url(kBlacklistedUrl);
627 594
628 // Blacklist expectations. 595 // Blacklist expectations.
629 EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url))) 596 EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
630 .WillOnce(Return(true)); 597 .WillOnce(Return(true));
631 EXPECT_CALL(*mock_thumbnail_manager_, 598 EXPECT_CALL(*thumbnail_manager(),
632 Initialize(EqualsProto(CreateSuggestionsProfile()))); 599 Initialize(EqualsProto(CreateSuggestionsProfile())));
633 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)); 600 EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
634 EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_)) 601 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
635 .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true))); 602 .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true)));
636 603 // Undo expectations.
637 // URL is not in local blacklist. 604 // URL is not in local blacklist.
638 EXPECT_CALL(*mock_blacklist_store_, 605 EXPECT_CALL(*blacklist_store(),
639 GetTimeUntilURLReadyForUpload(Eq(blacklisted_url), _)) 606 GetTimeUntilURLReadyForUpload(Eq(GURL(kBlacklistedUrl)), _))
640 .WillOnce(Return(false)); 607 .WillOnce(Return(false));
641 608
642 EXPECT_CALL(callback, Run(_)); 609 EXPECT_CALL(callback, Run(_));
643 EXPECT_TRUE(suggestions_service_->BlacklistURL(blacklisted_url)); 610 EXPECT_TRUE(suggestions_service_->BlacklistURL(blacklisted_url));
644 EXPECT_FALSE(suggestions_service_->UndoBlacklistURL(blacklisted_url)); 611 EXPECT_FALSE(suggestions_service_->UndoBlacklistURL(blacklisted_url));
Marc Treib 2017/05/10 09:53:44 These two lines were replaced by the two below I t
fhorschig 2017/05/10 11:54:45 Gone. (Yes, they even broke compilation)
612
613 EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
614 EXPECT_FALSE(suggestions_service()->UndoBlacklistURL(GURL(kBlacklistedUrl)));
645 } 615 }
646 616
647 TEST_F(SuggestionsServiceTest, UndoBlacklistURLFailsIfAlreadyCandidate) { 617 TEST_F(SuggestionsServiceTest, UndoBlacklistURLFailsIfAlreadyCandidate) {
648 // Ensure scheduling the request doesn't happen before undo. 618 // Ensure scheduling the request doesn't happen before undo.
649 const base::TimeDelta delay = base::TimeDelta::FromHours(1); 619 const base::TimeDelta delay = base::TimeDelta::FromHours(1);
650 suggestions_service_->set_blacklist_delay(delay); 620 suggestions_service()->set_blacklist_delay_for_testing(delay);
651 621
652 base::MockCallback<SuggestionsService::ResponseCallback> callback; 622 base::MockCallback<SuggestionsService::ResponseCallback> callback;
653 auto subscription = suggestions_service_->AddCallback(callback.Get()); 623 auto subscription = suggestions_service()->AddCallback(callback.Get());
654
655 const GURL blacklisted_url(kBlacklistedUrl);
656 624
657 // Blacklist expectations. 625 // Blacklist expectations.
658 EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url))) 626 EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
659 .WillOnce(Return(true)); 627 .WillOnce(Return(true));
660 EXPECT_CALL(*mock_thumbnail_manager_, 628 EXPECT_CALL(*thumbnail_manager(),
661 Initialize(EqualsProto(CreateSuggestionsProfile()))); 629 Initialize(EqualsProto(CreateSuggestionsProfile())));
662 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)); 630 EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
663 EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_)) 631 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
664 .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true))); 632 .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true)));
665 633
634 // Undo expectations.
666 // URL is not yet candidate for upload. 635 // URL is not yet candidate for upload.
667 base::TimeDelta negative_delay = base::TimeDelta::FromHours(-1); 636 const base::TimeDelta negative_delay = base::TimeDelta::FromHours(-1);
668 EXPECT_CALL(*mock_blacklist_store_, 637 EXPECT_CALL(*blacklist_store(),
669 GetTimeUntilURLReadyForUpload(Eq(blacklisted_url), _)) 638 GetTimeUntilURLReadyForUpload(Eq(GURL(kBlacklistedUrl)), _))
670 .WillOnce(DoAll(SetArgPointee<1>(negative_delay), Return(true))); 639 .WillOnce(DoAll(SetArgPointee<1>(negative_delay), Return(true)));
671 640
672 EXPECT_CALL(callback, Run(_)); 641 EXPECT_CALL(callback, Run(_));
673 EXPECT_TRUE(suggestions_service_->BlacklistURL(blacklisted_url)); 642
674 EXPECT_FALSE(suggestions_service_->UndoBlacklistURL(blacklisted_url)); 643 EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
675 } 644 EXPECT_FALSE(suggestions_service()->UndoBlacklistURL(GURL(kBlacklistedUrl)));
676 645 }
677 TEST_F(SuggestionsServiceTest, GetBlacklistedUrlNotBlacklistRequest) { 646
678 // Not a blacklist request. 647 TEST_F(SuggestionsServiceTest, TemporaryIncreasesBlacklistDelayOnFailure) {
Marc Treib 2017/05/10 09:53:45 s/Temporary/Temporarily/
fhorschig 2017/05/10 11:54:46 Done.
679 std::unique_ptr<net::FakeURLFetcher> fetcher( 648 EXPECT_CALL(*thumbnail_manager(), Initialize(_)).Times(AnyNumber());
680 CreateURLFetcher(GURL("http://not-blacklisting.com/a?b=c"), nullptr, "", 649 EXPECT_CALL(*blacklist_store(), FilterSuggestions(_)).Times(AnyNumber());
681 net::HTTP_OK, net::URLRequestStatus::SUCCESS)); 650 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
682 GURL retrieved_url; 651 .Times(AnyNumber())
683 EXPECT_FALSE( 652 .WillRepeatedly(Return(false));
684 SuggestionsServiceImpl::GetBlacklistedUrl(*fetcher, &retrieved_url)); 653 const base::TimeDelta initial_delay =
685 } 654 suggestions_service()->blacklist_delay_for_testing();
686
687 TEST_F(SuggestionsServiceTest, GetBlacklistedUrlBlacklistRequest) {
688 // An actual blacklist request.
689 const GURL blacklisted_url("http://blacklisted.com/a?b=c&d=e");
690 const std::string encoded_blacklisted_url =
691 "http%3A%2F%2Fblacklisted.com%2Fa%3Fb%3Dc%26d%3De";
692 const std::string blacklist_request_prefix(
693 SuggestionsServiceImpl::BuildSuggestionsBlacklistURLPrefix());
694 std::unique_ptr<net::FakeURLFetcher> fetcher(CreateURLFetcher(
695 GURL(blacklist_request_prefix + encoded_blacklisted_url), nullptr, "",
696 net::HTTP_OK, net::URLRequestStatus::SUCCESS));
697 GURL retrieved_url;
698 EXPECT_TRUE(
699 SuggestionsServiceImpl::GetBlacklistedUrl(*fetcher, &retrieved_url));
700 EXPECT_EQ(blacklisted_url, retrieved_url);
701 }
702
703 TEST_F(SuggestionsServiceTest, UpdateBlacklistDelay) {
704 const base::TimeDelta initial_delay = suggestions_service_->blacklist_delay();
705 655
706 // Delay unchanged on success. 656 // Delay unchanged on success.
707 suggestions_service_->UpdateBlacklistDelay(true); 657 suggestions_service()->FetchSuggestionsData();
708 EXPECT_EQ(initial_delay, suggestions_service_->blacklist_delay()); 658 base::RunLoop().RunUntilIdle();
659 RespondToFetchWithProfile(CreateSuggestionsProfile());
660 EXPECT_EQ(initial_delay,
661 suggestions_service()->blacklist_delay_for_testing());
709 662
710 // Delay increases on failure. 663 // Delay increases on failure.
711 suggestions_service_->UpdateBlacklistDelay(false); 664 suggestions_service()->FetchSuggestionsData();
712 EXPECT_GT(suggestions_service_->blacklist_delay(), initial_delay); 665 base::RunLoop().RunUntilIdle();
666 RespondToFetch(
667 "irrelevant", net::HTTP_BAD_REQUEST,
668 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
669 EXPECT_GT(suggestions_service()->blacklist_delay_for_testing(),
670 initial_delay);
713 671
714 // Delay resets on success. 672 // Delay resets on success.
715 suggestions_service_->UpdateBlacklistDelay(true); 673 suggestions_service()->FetchSuggestionsData();
716 EXPECT_EQ(initial_delay, suggestions_service_->blacklist_delay()); 674 base::RunLoop().RunUntilIdle();
717 } 675 RespondToFetchWithProfile(CreateSuggestionsProfile());
718 676 EXPECT_EQ(initial_delay,
719 TEST_F(SuggestionsServiceTest, CheckDefaultTimeStamps) { 677 suggestions_service()->blacklist_delay_for_testing());
720 SuggestionsProfile suggestions = 678 }
721 CreateSuggestionsProfileWithExpiryTimestamps(); 679
722 suggestions_service_->SetDefaultExpiryTimestamp(&suggestions, 680 TEST_F(SuggestionsServiceTest, DoesNotOverrideDefaultExpiryTime) {
723 kTestDefaultExpiry); 681 EXPECT_CALL(*thumbnail_manager(), Initialize(_));
724 EXPECT_EQ(kTestSetExpiry, suggestions.suggestions(0).expiry_ts()); 682 EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
725 EXPECT_EQ(kTestDefaultExpiry, suggestions.suggestions(1).expiry_ts()); 683 EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
684 .WillOnce(Return(false));
685
686 suggestions_service()->FetchSuggestionsData();
687
688 base::RunLoop().RunUntilIdle();
689 // Creates one suggestion without timestamp and adds a second with timestamp.
690 SuggestionsProfile profile = CreateSuggestionsProfile();
691 ChromeSuggestion* suggestion = profile.add_suggestions();
692 suggestion->set_title(kTestTitle);
693 suggestion->set_url(kTestUrl);
694 suggestion->set_expiry_ts(kTestSetExpiry);
695 RespondToFetchWithProfile(profile);
696
697 SuggestionsProfile suggestions_profile;
698 suggestions_store()->LoadSuggestions(&suggestions_profile);
699 ASSERT_EQ(2, suggestions_profile.suggestions_size());
700 // Suggestion[1] had a very old time stamp but should not be updated.
701 EXPECT_EQ(kTestSetExpiry, suggestions_profile.suggestions(1).expiry_ts());
702 // Suggestion[0] had no time stamp and should be ahead of the old suggestion.
703 EXPECT_LT(kTestSetExpiry, suggestions_profile.suggestions(0).expiry_ts());
Marc Treib 2017/05/10 09:53:45 nit: Check suggestions(0) first?
fhorschig 2017/05/10 11:54:45 Done.
726 } 704 }
727 705
728 TEST_F(SuggestionsServiceTest, GetPageThumbnail) { 706 TEST_F(SuggestionsServiceTest, GetPageThumbnail) {
729 const GURL test_url(kTestUrl); 707 const GURL test_url(kTestUrl);
730 const GURL thumbnail_url("https://www.thumbnails.com/thumb.jpg"); 708 const GURL thumbnail_url("https://www.thumbnails.com/thumb.jpg");
731 base::Callback<void(const GURL&, const gfx::Image&)> dummy_callback; 709 base::Callback<void(const GURL&, const gfx::Image&)> dummy_callback;
732 710
733 EXPECT_CALL(*mock_thumbnail_manager_, GetImageForURL(test_url, _)); 711 EXPECT_CALL(*thumbnail_manager(), GetImageForURL(test_url, _));
734 suggestions_service_->GetPageThumbnail(test_url, dummy_callback); 712 suggestions_service()->GetPageThumbnail(test_url, dummy_callback);
735 713
736 EXPECT_CALL(*mock_thumbnail_manager_, AddImageURL(test_url, thumbnail_url)); 714 EXPECT_CALL(*thumbnail_manager(), AddImageURL(test_url, thumbnail_url));
737 EXPECT_CALL(*mock_thumbnail_manager_, GetImageForURL(test_url, _)); 715 EXPECT_CALL(*thumbnail_manager(), GetImageForURL(test_url, _));
738 suggestions_service_->GetPageThumbnailWithURL(test_url, thumbnail_url, 716 suggestions_service()->GetPageThumbnailWithURL(test_url, thumbnail_url,
739 dummy_callback); 717 dummy_callback);
740 } 718 }
741 719
742 } // namespace suggestions 720 } // namespace suggestions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698