OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 <cstddef> | |
6 #include <set> | |
7 #include <string> | |
8 | |
9 #include "base/compiler_specific.h" | |
10 #include "base/message_loop.h" | |
11 #include "google/cacheinvalidation/include/invalidation-client.h" | |
12 #include "google/cacheinvalidation/include/types.h" | |
13 #include "jingle/notifier/listener/fake_push_client.h" | |
14 #include "sync/internal_api/public/util/weak_handle.h" | |
15 #include "sync/notifier/chrome_invalidation_client.h" | |
16 #include "sync/notifier/fake_invalidation_state_tracker.h" | |
17 #include "sync/notifier/invalidation_util.h" | |
18 #include "testing/gtest/include/gtest/gtest.h" | |
19 | |
20 namespace syncer { | |
21 | |
22 namespace { | |
23 | |
24 using invalidation::AckHandle; | |
25 using invalidation::ObjectId; | |
26 | |
27 const char kClientId[] = "client_id"; | |
28 const char kClientInfo[] = "client_info"; | |
29 | |
30 const char kState[] = "state"; | |
31 const char kNewState[] = "new_state"; | |
32 | |
33 const char kPayload1[] = "payload1"; | |
34 const char kPayload2[] = "payload2"; | |
35 | |
36 const int64 kMinVersion = FakeInvalidationStateTracker::kMinVersion; | |
37 const int64 kVersion1 = 1LL; | |
38 const int64 kVersion2 = 2LL; | |
39 | |
40 const int kChromeSyncSourceId = 1004; | |
41 | |
42 struct AckHandleLessThan { | |
43 bool operator()(const AckHandle& lhs, const AckHandle& rhs) const { | |
44 return lhs.handle_data() < rhs.handle_data(); | |
45 } | |
46 }; | |
47 | |
48 typedef std::set<AckHandle, AckHandleLessThan> AckHandleSet; | |
49 | |
50 // Fake invalidation::InvalidationClient implementation that keeps | |
51 // track of registered IDs and acked handles. | |
52 class FakeInvalidationClient : public invalidation::InvalidationClient { | |
53 public: | |
54 FakeInvalidationClient() : started_(false) {} | |
55 virtual ~FakeInvalidationClient() {} | |
56 | |
57 const ObjectIdSet& GetRegisteredIds() const { | |
58 return registered_ids_; | |
59 } | |
60 | |
61 void ClearAckedHandles() { | |
62 acked_handles_.clear(); | |
63 } | |
64 | |
65 bool IsAckedHandle(const AckHandle& ack_handle) const { | |
66 return (acked_handles_.find(ack_handle) != acked_handles_.end()); | |
67 } | |
68 | |
69 // invalidation::InvalidationClient implementation. | |
70 | |
71 virtual void Start() OVERRIDE { | |
72 started_ = true; | |
73 } | |
74 | |
75 virtual void Stop() OVERRIDE { | |
76 started_ = false; | |
77 } | |
78 | |
79 virtual void Register(const ObjectId& object_id) OVERRIDE { | |
80 if (!started_) { | |
81 ADD_FAILURE(); | |
82 return; | |
83 } | |
84 registered_ids_.insert(object_id); | |
85 } | |
86 | |
87 virtual void Register( | |
88 const invalidation::vector<ObjectId>& object_ids) OVERRIDE { | |
89 if (!started_) { | |
90 ADD_FAILURE(); | |
91 return; | |
92 } | |
93 registered_ids_.insert(object_ids.begin(), object_ids.end()); | |
94 } | |
95 | |
96 virtual void Unregister(const ObjectId& object_id) OVERRIDE { | |
97 if (!started_) { | |
98 ADD_FAILURE(); | |
99 return; | |
100 } | |
101 registered_ids_.erase(object_id); | |
102 } | |
103 | |
104 virtual void Unregister( | |
105 const invalidation::vector<ObjectId>& object_ids) OVERRIDE { | |
106 if (!started_) { | |
107 ADD_FAILURE(); | |
108 return; | |
109 } | |
110 for (invalidation::vector<ObjectId>::const_iterator | |
111 it = object_ids.begin(); it != object_ids.end(); ++it) { | |
112 registered_ids_.erase(*it); | |
113 } | |
114 } | |
115 | |
116 virtual void Acknowledge(const AckHandle& ack_handle) OVERRIDE { | |
117 if (!started_) { | |
118 ADD_FAILURE(); | |
119 return; | |
120 } | |
121 acked_handles_.insert(ack_handle); | |
122 } | |
123 | |
124 private: | |
125 bool started_; | |
126 ObjectIdSet registered_ids_; | |
127 AckHandleSet acked_handles_; | |
128 }; | |
129 | |
130 // Fake listener tkat keeps track of invalidation counts, payloads, | |
131 // and state. | |
132 class FakeListener : public ChromeInvalidationClient::Listener { | |
133 public: | |
134 FakeListener() : reason_(TRANSIENT_NOTIFICATION_ERROR) {} | |
135 virtual ~FakeListener() {} | |
136 | |
137 int GetInvalidationCount(const ObjectId& id) const { | |
138 ObjectIdCountMap::const_iterator it = invalidation_counts_.find(id); | |
139 return (it == invalidation_counts_.end()) ? 0 : it->second; | |
140 } | |
141 | |
142 std::string GetPayload(const ObjectId& id) const { | |
143 ObjectIdStateMap::const_iterator it = states_.find(id); | |
144 return (it == states_.end()) ? "" : it->second.payload; | |
145 } | |
146 | |
147 // NO_NOTIFICATION_ERROR is the enabled state. | |
148 NotificationsDisabledReason GetNotificationsDisabledReason() const { | |
149 return reason_; | |
150 } | |
151 | |
152 // ChromeInvalidationClient::Listener implementation. | |
153 | |
154 virtual void OnInvalidate(const ObjectIdStateMap& id_state_map) OVERRIDE { | |
155 for (ObjectIdStateMap::const_iterator it = id_state_map.begin(); | |
156 it != id_state_map.end(); ++it) { | |
157 ++invalidation_counts_[it->first]; | |
158 states_[it->first] = it->second; | |
159 } | |
160 } | |
161 | |
162 virtual void OnNotificationsEnabled() { | |
163 reason_ = NO_NOTIFICATION_ERROR; | |
164 } | |
165 | |
166 virtual void OnNotificationsDisabled(NotificationsDisabledReason reason) { | |
167 reason_ = reason; | |
168 } | |
169 | |
170 private: | |
171 typedef std::map<ObjectId, int, ObjectIdLessThan> ObjectIdCountMap; | |
172 ObjectIdCountMap invalidation_counts_; | |
173 ObjectIdStateMap states_; | |
174 NotificationsDisabledReason reason_; | |
175 }; | |
176 | |
177 invalidation::InvalidationClient* CreateFakeInvalidationClient( | |
178 FakeInvalidationClient** fake_invalidation_client, | |
179 invalidation::SystemResources* resources, | |
180 int client_type, | |
181 const invalidation::string& client_name, | |
182 const invalidation::string& application_name, | |
183 invalidation::InvalidationListener* listener) { | |
184 *fake_invalidation_client = new FakeInvalidationClient(); | |
185 return *fake_invalidation_client; | |
186 } | |
187 | |
188 class ChromeInvalidationClientTest : public testing::Test { | |
189 protected: | |
190 ChromeInvalidationClientTest() | |
191 : kBookmarksId_(kChromeSyncSourceId, "BOOKMARK"), | |
192 kPreferencesId_(kChromeSyncSourceId, "PREFERENCE"), | |
193 kExtensionsId_(kChromeSyncSourceId, "EXTENSION"), | |
194 kAppsId_(kChromeSyncSourceId, "APP"), | |
195 fake_push_client_(new notifier::FakePushClient()), | |
196 fake_invalidation_client_(NULL), | |
197 client_(scoped_ptr<notifier::PushClient>(fake_push_client_)) {} | |
198 | |
199 virtual void SetUp() { | |
200 StartClient(); | |
201 | |
202 registered_ids_.insert(kBookmarksId_); | |
203 registered_ids_.insert(kPreferencesId_); | |
204 client_.UpdateRegisteredIds(registered_ids_); | |
205 } | |
206 | |
207 virtual void TearDown() { | |
208 StopClient(); | |
209 } | |
210 | |
211 // Restart client without re-registering IDs. | |
212 void RestartClient() { | |
213 StopClient(); | |
214 StartClient(); | |
215 } | |
216 | |
217 int GetInvalidationCount(const ObjectId& id) const { | |
218 return fake_listener_.GetInvalidationCount(id); | |
219 } | |
220 | |
221 std::string GetPayload(const ObjectId& id) const { | |
222 return fake_listener_.GetPayload(id); | |
223 } | |
224 | |
225 NotificationsDisabledReason GetNotificationsDisabledReason() const { | |
226 return fake_listener_.GetNotificationsDisabledReason(); | |
227 } | |
228 | |
229 int64 GetMaxVersion(const ObjectId& id) const { | |
230 return fake_tracker_.GetMaxVersion(id); | |
231 } | |
232 | |
233 std::string GetInvalidationState() const { | |
234 return fake_tracker_.GetInvalidationState(); | |
235 } | |
236 | |
237 ObjectIdSet GetRegisteredIds() const { | |
238 return fake_invalidation_client_->GetRegisteredIds(); | |
239 } | |
240 | |
241 // |payload| can be NULL. | |
242 void FireInvalidate(const ObjectId& object_id, | |
243 int64 version, const char* payload) { | |
244 invalidation::Invalidation inv; | |
245 if (payload) { | |
246 inv = invalidation::Invalidation(object_id, version, payload); | |
247 } else { | |
248 inv = invalidation::Invalidation(object_id, version); | |
249 } | |
250 const AckHandle ack_handle("fakedata"); | |
251 fake_invalidation_client_->ClearAckedHandles(); | |
252 client_.Invalidate(fake_invalidation_client_, inv, ack_handle); | |
253 EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle)); | |
254 // Pump message loop to trigger | |
255 // InvalidationStateTracker::SetMaxVersion(). | |
256 message_loop_.RunAllPending(); | |
257 } | |
258 | |
259 // |payload| can be NULL, but not |type_name|. | |
260 void FireInvalidateUnknownVersion(const ObjectId& object_id) { | |
261 const AckHandle ack_handle("fakedata_unknown"); | |
262 fake_invalidation_client_->ClearAckedHandles(); | |
263 client_.InvalidateUnknownVersion(fake_invalidation_client_, object_id, | |
264 ack_handle); | |
265 EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle)); | |
266 } | |
267 | |
268 void FireInvalidateAll() { | |
269 const AckHandle ack_handle("fakedata_all"); | |
270 fake_invalidation_client_->ClearAckedHandles(); | |
271 client_.InvalidateAll(fake_invalidation_client_, ack_handle); | |
272 EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle)); | |
273 } | |
274 | |
275 void WriteState(const std::string& new_state) { | |
276 client_.WriteState(new_state); | |
277 // Pump message loop to trigger | |
278 // InvalidationStateTracker::WriteState(). | |
279 message_loop_.RunAllPending(); | |
280 } | |
281 | |
282 void EnableNotifications() { | |
283 fake_push_client_->EnableNotifications(); | |
284 } | |
285 | |
286 void DisableNotifications(notifier::NotificationsDisabledReason reason) { | |
287 fake_push_client_->DisableNotifications(reason); | |
288 } | |
289 | |
290 const ObjectId kBookmarksId_; | |
291 const ObjectId kPreferencesId_; | |
292 const ObjectId kExtensionsId_; | |
293 const ObjectId kAppsId_; | |
294 | |
295 ObjectIdSet registered_ids_; | |
296 | |
297 private: | |
298 void StartClient() { | |
299 fake_invalidation_client_ = NULL; | |
300 client_.Start(base::Bind(&CreateFakeInvalidationClient, | |
301 &fake_invalidation_client_), | |
302 kClientId, kClientInfo, kState, | |
303 InvalidationVersionMap(), | |
304 MakeWeakHandle(fake_tracker_.AsWeakPtr()), | |
305 &fake_listener_); | |
306 DCHECK(fake_invalidation_client_); | |
307 } | |
308 | |
309 void StopClient() { | |
310 // client_.StopForTest() stops the invalidation scheduler, which | |
311 // deletes any pending tasks without running them. Some tasks | |
312 // "run and delete" another task, so they must be run in order to | |
313 // avoid leaking the inner task. client_.StopForTest() does not | |
314 // schedule any tasks, so it's both necessary and sufficient to | |
315 // drain the task queue before calling it. | |
316 message_loop_.RunAllPending(); | |
317 fake_invalidation_client_ = NULL; | |
318 client_.StopForTest(); | |
319 } | |
320 | |
321 MessageLoop message_loop_; | |
322 | |
323 FakeListener fake_listener_; | |
324 FakeInvalidationStateTracker fake_tracker_; | |
325 notifier::FakePushClient* const fake_push_client_; | |
326 | |
327 protected: | |
328 // Tests need to access these directly. | |
329 FakeInvalidationClient* fake_invalidation_client_; | |
330 ChromeInvalidationClient client_; | |
331 }; | |
332 | |
333 // Write a new state to the client. It should propagate to the | |
334 // tracker. | |
335 TEST_F(ChromeInvalidationClientTest, WriteState) { | |
336 WriteState(kNewState); | |
337 | |
338 EXPECT_EQ(kNewState, GetInvalidationState()); | |
339 } | |
340 | |
341 // Invalidation tests. | |
342 | |
343 // Fire an invalidation without a payload. It should be processed, | |
344 // the payload should remain empty, and the version should be updated. | |
345 TEST_F(ChromeInvalidationClientTest, InvalidateNoPayload) { | |
346 const ObjectId& id = kBookmarksId_; | |
347 | |
348 FireInvalidate(id, kVersion1, NULL); | |
349 | |
350 EXPECT_EQ(1, GetInvalidationCount(id)); | |
351 EXPECT_EQ("", GetPayload(id)); | |
352 EXPECT_EQ(kVersion1, GetMaxVersion(id)); | |
353 } | |
354 | |
355 // Fire an invalidation with an empty payload. It should be | |
356 // processed, the payload should remain empty, and the version should | |
357 // be updated. | |
358 TEST_F(ChromeInvalidationClientTest, InvalidateEmptyPayload) { | |
359 const ObjectId& id = kBookmarksId_; | |
360 | |
361 FireInvalidate(id, kVersion1, ""); | |
362 | |
363 EXPECT_EQ(1, GetInvalidationCount(id)); | |
364 EXPECT_EQ("", GetPayload(id)); | |
365 EXPECT_EQ(kVersion1, GetMaxVersion(id)); | |
366 } | |
367 | |
368 // Fire an invalidation with a payload. It should be processed, and | |
369 // both the payload and the version should be updated. | |
370 TEST_F(ChromeInvalidationClientTest, InvalidateWithPayload) { | |
371 const ObjectId& id = kPreferencesId_; | |
372 | |
373 FireInvalidate(id, kVersion1, kPayload1); | |
374 | |
375 EXPECT_EQ(1, GetInvalidationCount(id)); | |
376 EXPECT_EQ(kPayload1, GetPayload(id)); | |
377 EXPECT_EQ(kVersion1, GetMaxVersion(id)); | |
378 } | |
379 | |
380 // Fire an invalidation with a payload. It should still be processed, | |
381 // and both the payload and the version should be updated. | |
382 TEST_F(ChromeInvalidationClientTest, InvalidateUnregistered) { | |
383 const ObjectId kUnregisteredId( | |
384 kChromeSyncSourceId, "unregistered"); | |
385 const ObjectId& id = kUnregisteredId; | |
386 | |
387 EXPECT_EQ(0, GetInvalidationCount(id)); | |
388 EXPECT_EQ("", GetPayload(id)); | |
389 EXPECT_EQ(kMinVersion, GetMaxVersion(id)); | |
390 | |
391 FireInvalidate(id, kVersion1, NULL); | |
392 | |
393 EXPECT_EQ(1, GetInvalidationCount(id)); | |
394 EXPECT_EQ("", GetPayload(id)); | |
395 EXPECT_EQ(kVersion1, GetMaxVersion(id)); | |
396 } | |
397 | |
398 // Fire an invalidation, then fire another one with a lower version. | |
399 // The first one should be processed and should update the payload and | |
400 // version, but the second one shouldn't. | |
401 TEST_F(ChromeInvalidationClientTest, InvalidateVersion) { | |
402 const ObjectId& id = kPreferencesId_; | |
403 | |
404 FireInvalidate(id, kVersion2, kPayload2); | |
405 | |
406 EXPECT_EQ(1, GetInvalidationCount(id)); | |
407 EXPECT_EQ(kPayload2, GetPayload(id)); | |
408 EXPECT_EQ(kVersion2, GetMaxVersion(id)); | |
409 | |
410 FireInvalidate(id, kVersion1, kPayload1); | |
411 | |
412 EXPECT_EQ(1, GetInvalidationCount(id)); | |
413 EXPECT_EQ(kPayload2, GetPayload(id)); | |
414 EXPECT_EQ(kVersion2, GetMaxVersion(id)); | |
415 } | |
416 | |
417 // Fire an invalidation with an unknown version twice. It shouldn't | |
418 // update the payload or version either time, but it should still be | |
419 // processed. | |
420 TEST_F(ChromeInvalidationClientTest, InvalidateUnknownVersion) { | |
421 const ObjectId& id = kBookmarksId_; | |
422 | |
423 FireInvalidateUnknownVersion(id); | |
424 | |
425 EXPECT_EQ(1, GetInvalidationCount(id)); | |
426 EXPECT_EQ("", GetPayload(id)); | |
427 EXPECT_EQ(kMinVersion, GetMaxVersion(id)); | |
428 | |
429 FireInvalidateUnknownVersion(id); | |
430 | |
431 EXPECT_EQ(2, GetInvalidationCount(id)); | |
432 EXPECT_EQ("", GetPayload(id)); | |
433 EXPECT_EQ(kMinVersion, GetMaxVersion(id)); | |
434 } | |
435 | |
436 // Fire an invalidation for all enabled IDs. It shouldn't update the | |
437 // payload or version, but it should still invalidate the IDs. | |
438 TEST_F(ChromeInvalidationClientTest, InvalidateAll) { | |
439 FireInvalidateAll(); | |
440 | |
441 for (ObjectIdSet::const_iterator it = registered_ids_.begin(); | |
442 it != registered_ids_.end(); ++it) { | |
443 EXPECT_EQ(1, GetInvalidationCount(*it)); | |
444 EXPECT_EQ("", GetPayload(*it)); | |
445 EXPECT_EQ(kMinVersion, GetMaxVersion(*it)); | |
446 } | |
447 } | |
448 | |
449 // Comprehensive test of various scenarios for multiple IDs. | |
450 TEST_F(ChromeInvalidationClientTest, InvalidateMultipleIds) { | |
451 FireInvalidate(kBookmarksId_, 3, NULL); | |
452 | |
453 EXPECT_EQ(1, GetInvalidationCount(kBookmarksId_)); | |
454 EXPECT_EQ("", GetPayload(kBookmarksId_)); | |
455 EXPECT_EQ(3, GetMaxVersion(kBookmarksId_)); | |
456 | |
457 FireInvalidate(kExtensionsId_, 2, NULL); | |
458 | |
459 EXPECT_EQ(1, GetInvalidationCount(kExtensionsId_)); | |
460 EXPECT_EQ("", GetPayload(kExtensionsId_)); | |
461 EXPECT_EQ(2, GetMaxVersion(kExtensionsId_)); | |
462 | |
463 // Invalidations with lower version numbers should be ignored. | |
464 | |
465 FireInvalidate(kBookmarksId_, 1, NULL); | |
466 | |
467 EXPECT_EQ(1, GetInvalidationCount(kBookmarksId_)); | |
468 EXPECT_EQ("", GetPayload(kBookmarksId_)); | |
469 EXPECT_EQ(3, GetMaxVersion(kBookmarksId_)); | |
470 | |
471 FireInvalidate(kExtensionsId_, 1, NULL); | |
472 | |
473 EXPECT_EQ(1, GetInvalidationCount(kExtensionsId_)); | |
474 EXPECT_EQ("", GetPayload(kExtensionsId_)); | |
475 EXPECT_EQ(2, GetMaxVersion(kExtensionsId_)); | |
476 | |
477 // InvalidateAll shouldn't change any version state. | |
478 | |
479 FireInvalidateAll(); | |
480 | |
481 EXPECT_EQ(2, GetInvalidationCount(kBookmarksId_)); | |
482 EXPECT_EQ("", GetPayload(kBookmarksId_)); | |
483 EXPECT_EQ(3, GetMaxVersion(kBookmarksId_)); | |
484 | |
485 EXPECT_EQ(1, GetInvalidationCount(kPreferencesId_)); | |
486 EXPECT_EQ("", GetPayload(kPreferencesId_)); | |
487 EXPECT_EQ(kMinVersion, GetMaxVersion(kPreferencesId_)); | |
488 | |
489 EXPECT_EQ(1, GetInvalidationCount(kExtensionsId_)); | |
490 EXPECT_EQ("", GetPayload(kExtensionsId_)); | |
491 EXPECT_EQ(2, GetMaxVersion(kExtensionsId_)); | |
492 | |
493 // Invalidations with higher version numbers should be processed. | |
494 | |
495 FireInvalidate(kPreferencesId_, 5, NULL); | |
496 EXPECT_EQ(2, GetInvalidationCount(kPreferencesId_)); | |
497 EXPECT_EQ("", GetPayload(kPreferencesId_)); | |
498 EXPECT_EQ(5, GetMaxVersion(kPreferencesId_)); | |
499 | |
500 FireInvalidate(kExtensionsId_, 3, NULL); | |
501 EXPECT_EQ(2, GetInvalidationCount(kExtensionsId_)); | |
502 EXPECT_EQ("", GetPayload(kExtensionsId_)); | |
503 EXPECT_EQ(3, GetMaxVersion(kExtensionsId_)); | |
504 | |
505 FireInvalidate(kBookmarksId_, 4, NULL); | |
506 EXPECT_EQ(3, GetInvalidationCount(kBookmarksId_)); | |
507 EXPECT_EQ("", GetPayload(kBookmarksId_)); | |
508 EXPECT_EQ(4, GetMaxVersion(kBookmarksId_)); | |
509 } | |
510 | |
511 // Registration tests. | |
512 | |
513 // With IDs already registered, enable notifications then ready the | |
514 // client. The IDs should be registered only after the client is | |
515 // readied. | |
516 TEST_F(ChromeInvalidationClientTest, RegisterEnableReady) { | |
517 EXPECT_TRUE(GetRegisteredIds().empty()); | |
518 | |
519 EnableNotifications(); | |
520 | |
521 EXPECT_TRUE(GetRegisteredIds().empty()); | |
522 | |
523 client_.Ready(fake_invalidation_client_); | |
524 | |
525 EXPECT_EQ(registered_ids_, GetRegisteredIds()); | |
526 } | |
527 | |
528 // With IDs already registered, ready the client then enable | |
529 // notifications. The IDs should be registered after the client is | |
530 // readied. | |
531 TEST_F(ChromeInvalidationClientTest, RegisterReadyEnable) { | |
532 EXPECT_TRUE(GetRegisteredIds().empty()); | |
533 | |
534 client_.Ready(fake_invalidation_client_); | |
535 | |
536 EXPECT_EQ(registered_ids_, GetRegisteredIds()); | |
537 | |
538 EnableNotifications(); | |
539 | |
540 EXPECT_EQ(registered_ids_, GetRegisteredIds()); | |
541 } | |
542 | |
543 // Unregister the IDs, enable notifications, re-register the IDs, then | |
544 // ready the client. The IDs should be registered only after the | |
545 // client is readied. | |
546 TEST_F(ChromeInvalidationClientTest, EnableRegisterReady) { | |
547 client_.UpdateRegisteredIds(ObjectIdSet()); | |
548 | |
549 EXPECT_TRUE(GetRegisteredIds().empty()); | |
550 | |
551 EnableNotifications(); | |
552 | |
553 EXPECT_TRUE(GetRegisteredIds().empty()); | |
554 | |
555 client_.UpdateRegisteredIds(registered_ids_); | |
556 | |
557 EXPECT_TRUE(GetRegisteredIds().empty()); | |
558 | |
559 client_.Ready(fake_invalidation_client_); | |
560 | |
561 EXPECT_EQ(registered_ids_, GetRegisteredIds()); | |
562 } | |
563 | |
564 // Unregister the IDs, enable notifications, ready the client, then | |
565 // re-register the IDs. The IDs should be registered only after the | |
566 // client is readied. | |
567 TEST_F(ChromeInvalidationClientTest, EnableReadyRegister) { | |
568 client_.UpdateRegisteredIds(ObjectIdSet()); | |
569 | |
570 EXPECT_TRUE(GetRegisteredIds().empty()); | |
571 | |
572 EnableNotifications(); | |
573 | |
574 EXPECT_TRUE(GetRegisteredIds().empty()); | |
575 | |
576 client_.Ready(fake_invalidation_client_); | |
577 | |
578 EXPECT_TRUE(GetRegisteredIds().empty()); | |
579 | |
580 client_.UpdateRegisteredIds(registered_ids_); | |
581 | |
582 EXPECT_EQ(registered_ids_, GetRegisteredIds()); | |
583 } | |
584 | |
585 // Unregister the IDs, ready the client, enable notifications, then | |
586 // re-register the IDs. The IDs should be registered only after the | |
587 // client is readied. | |
588 TEST_F(ChromeInvalidationClientTest, ReadyEnableRegister) { | |
589 client_.UpdateRegisteredIds(ObjectIdSet()); | |
590 | |
591 EXPECT_TRUE(GetRegisteredIds().empty()); | |
592 | |
593 EnableNotifications(); | |
594 | |
595 EXPECT_TRUE(GetRegisteredIds().empty()); | |
596 | |
597 client_.Ready(fake_invalidation_client_); | |
598 | |
599 EXPECT_TRUE(GetRegisteredIds().empty()); | |
600 | |
601 client_.UpdateRegisteredIds(registered_ids_); | |
602 | |
603 EXPECT_EQ(registered_ids_, GetRegisteredIds()); | |
604 } | |
605 | |
606 // Unregister the IDs, ready the client, re-register the IDs, then | |
607 // enable notifications. The IDs should be registered only after the | |
608 // client is readied. | |
609 // | |
610 // This test is important: see http://crbug.com/139424. | |
611 TEST_F(ChromeInvalidationClientTest, ReadyRegisterEnable) { | |
612 client_.UpdateRegisteredIds(ObjectIdSet()); | |
613 | |
614 EXPECT_TRUE(GetRegisteredIds().empty()); | |
615 | |
616 client_.Ready(fake_invalidation_client_); | |
617 | |
618 EXPECT_TRUE(GetRegisteredIds().empty()); | |
619 | |
620 client_.UpdateRegisteredIds(registered_ids_); | |
621 | |
622 EXPECT_EQ(registered_ids_, GetRegisteredIds()); | |
623 | |
624 EnableNotifications(); | |
625 | |
626 EXPECT_EQ(registered_ids_, GetRegisteredIds()); | |
627 } | |
628 | |
629 // With IDs already registered, ready the client, restart the client, | |
630 // then re-ready it. The IDs should still be registered. | |
631 TEST_F(ChromeInvalidationClientTest, RegisterTypesPreserved) { | |
632 EXPECT_TRUE(GetRegisteredIds().empty()); | |
633 | |
634 client_.Ready(fake_invalidation_client_); | |
635 | |
636 EXPECT_EQ(registered_ids_, GetRegisteredIds()); | |
637 | |
638 RestartClient(); | |
639 | |
640 EXPECT_TRUE(GetRegisteredIds().empty()); | |
641 | |
642 client_.Ready(fake_invalidation_client_); | |
643 | |
644 EXPECT_EQ(registered_ids_, GetRegisteredIds()); | |
645 } | |
646 | |
647 // Without readying the client, disable notifications, then enable | |
648 // them. The listener should still think notifications are disabled. | |
649 TEST_F(ChromeInvalidationClientTest, EnableNotificationsNotReady) { | |
650 EXPECT_EQ(TRANSIENT_NOTIFICATION_ERROR, | |
651 GetNotificationsDisabledReason()); | |
652 | |
653 DisableNotifications( | |
654 notifier::TRANSIENT_NOTIFICATION_ERROR); | |
655 | |
656 EXPECT_EQ(TRANSIENT_NOTIFICATION_ERROR, | |
657 GetNotificationsDisabledReason()); | |
658 | |
659 DisableNotifications( | |
660 notifier::NOTIFICATION_CREDENTIALS_REJECTED); | |
661 | |
662 EXPECT_EQ(NOTIFICATION_CREDENTIALS_REJECTED, | |
663 GetNotificationsDisabledReason()); | |
664 | |
665 EnableNotifications(); | |
666 | |
667 EXPECT_EQ(TRANSIENT_NOTIFICATION_ERROR, | |
668 GetNotificationsDisabledReason()); | |
669 } | |
670 | |
671 // Enable notifications then Ready the invalidation client. The | |
672 // listener should then be ready. | |
673 TEST_F(ChromeInvalidationClientTest, EnableNotificationsThenReady) { | |
674 EXPECT_EQ(TRANSIENT_NOTIFICATION_ERROR, GetNotificationsDisabledReason()); | |
675 | |
676 EnableNotifications(); | |
677 | |
678 EXPECT_EQ(TRANSIENT_NOTIFICATION_ERROR, GetNotificationsDisabledReason()); | |
679 | |
680 client_.Ready(fake_invalidation_client_); | |
681 | |
682 EXPECT_EQ(NO_NOTIFICATION_ERROR, GetNotificationsDisabledReason()); | |
683 } | |
684 | |
685 // Ready the invalidation client then enable notifications. The | |
686 // listener should then be ready. | |
687 TEST_F(ChromeInvalidationClientTest, ReadyThenEnableNotifications) { | |
688 EXPECT_EQ(TRANSIENT_NOTIFICATION_ERROR, GetNotificationsDisabledReason()); | |
689 | |
690 client_.Ready(fake_invalidation_client_); | |
691 | |
692 EXPECT_EQ(TRANSIENT_NOTIFICATION_ERROR, GetNotificationsDisabledReason()); | |
693 | |
694 EnableNotifications(); | |
695 | |
696 EXPECT_EQ(NO_NOTIFICATION_ERROR, GetNotificationsDisabledReason()); | |
697 } | |
698 | |
699 // Enable notifications and ready the client. Then disable | |
700 // notifications with an auth error and re-enable notifications. The | |
701 // listener should go into an auth error mode and then back out. | |
702 TEST_F(ChromeInvalidationClientTest, PushClientAuthError) { | |
703 EnableNotifications(); | |
704 client_.Ready(fake_invalidation_client_); | |
705 | |
706 EXPECT_EQ(NO_NOTIFICATION_ERROR, GetNotificationsDisabledReason()); | |
707 | |
708 DisableNotifications( | |
709 notifier::NOTIFICATION_CREDENTIALS_REJECTED); | |
710 | |
711 EXPECT_EQ(NOTIFICATION_CREDENTIALS_REJECTED, | |
712 GetNotificationsDisabledReason()); | |
713 | |
714 EnableNotifications(); | |
715 | |
716 EXPECT_EQ(NO_NOTIFICATION_ERROR, GetNotificationsDisabledReason()); | |
717 } | |
718 | |
719 // Enable notifications and ready the client. Then simulate an auth | |
720 // error from the invalidation client. Simulate some notification | |
721 // events, then re-ready the client. The listener should go into an | |
722 // auth error mode and come out of it only after the client is ready. | |
723 TEST_F(ChromeInvalidationClientTest, InvalidationClientAuthError) { | |
724 EnableNotifications(); | |
725 client_.Ready(fake_invalidation_client_); | |
726 | |
727 EXPECT_EQ(NO_NOTIFICATION_ERROR, GetNotificationsDisabledReason()); | |
728 | |
729 client_.InformError( | |
730 fake_invalidation_client_, | |
731 invalidation::ErrorInfo( | |
732 invalidation::ErrorReason::AUTH_FAILURE, | |
733 false /* is_transient */, | |
734 "auth error", | |
735 invalidation::ErrorContext())); | |
736 | |
737 EXPECT_EQ(NOTIFICATION_CREDENTIALS_REJECTED, | |
738 GetNotificationsDisabledReason()); | |
739 | |
740 DisableNotifications( | |
741 notifier::TRANSIENT_NOTIFICATION_ERROR); | |
742 | |
743 EXPECT_EQ(NOTIFICATION_CREDENTIALS_REJECTED, | |
744 GetNotificationsDisabledReason()); | |
745 | |
746 DisableNotifications( | |
747 notifier::TRANSIENT_NOTIFICATION_ERROR); | |
748 | |
749 EXPECT_EQ(NOTIFICATION_CREDENTIALS_REJECTED, | |
750 GetNotificationsDisabledReason()); | |
751 | |
752 EnableNotifications(); | |
753 | |
754 EXPECT_EQ(NOTIFICATION_CREDENTIALS_REJECTED, | |
755 GetNotificationsDisabledReason()); | |
756 | |
757 client_.Ready(fake_invalidation_client_); | |
758 | |
759 EXPECT_EQ(NO_NOTIFICATION_ERROR, GetNotificationsDisabledReason()); | |
760 } | |
761 | |
762 } // namespace | |
763 | |
764 } // namespace syncer | |
OLD | NEW |