OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/services/gcm/gcm_service.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "base/files/scoped_temp_dir.h" | |
10 #include "base/location.h" | |
11 #include "base/run_loop.h" | |
12 #include "base/strings/string_util.h" | |
13 #include "chrome/browser/services/gcm/fake_gcm_client_factory.h" | |
14 #include "chrome/browser/services/gcm/gcm_app_handler.h" | |
15 #include "chrome/browser/services/gcm/gcm_client_factory.h" | |
16 #include "chrome/browser/services/gcm/gcm_client_mock.h" | |
17 #include "content/public/browser/browser_thread.h" | |
18 #include "content/public/test/test_browser_thread_bundle.h" | |
19 #include "google_apis/gaia/fake_identity_provider.h" | |
20 #include "google_apis/gaia/fake_oauth2_token_service.h" | |
21 #include "net/url_request/url_request_context_getter.h" | |
22 #include "net/url_request/url_request_test_util.h" | |
23 #include "testing/gtest/include/gtest/gtest.h" | |
24 | |
25 namespace gcm { | |
26 | |
27 namespace { | |
28 | |
29 const char kTestAccountID1[] = "user1@example.com"; | |
30 const char kTestAccountID2[] = "user2@example.com"; | |
31 const char kTestAccountID3[] = "user3@example.com"; | |
32 const char kTestAppID1[] = "TestApp1"; | |
33 const char kTestAppID2[] = "TestApp2"; | |
34 const char kUserID1[] = "user1"; | |
35 const char kUserID2[] = "user2"; | |
36 | |
37 void PumpUILoop() { | |
38 base::RunLoop().RunUntilIdle(); | |
39 } | |
40 | |
41 void PumpIOLoop() { | |
42 base::RunLoop run_loop; | |
43 content::BrowserThread::PostTaskAndReply(content::BrowserThread::IO, | |
44 FROM_HERE, | |
45 base::Bind(&base::DoNothing), | |
46 run_loop.QuitClosure()); | |
47 run_loop.Run(); | |
48 } | |
49 | |
50 std::vector<std::string> ToSenderList(const std::string& sender_ids) { | |
51 std::vector<std::string> senders; | |
52 Tokenize(sender_ids, ",", &senders); | |
53 return senders; | |
54 } | |
55 | |
56 class FakeGCMAppHandler : public GCMAppHandler { | |
57 public: | |
58 enum Event { | |
59 NO_EVENT, | |
60 MESSAGE_EVENT, | |
61 MESSAGES_DELETED_EVENT, | |
62 SEND_ERROR_EVENT | |
63 }; | |
64 | |
65 FakeGCMAppHandler(); | |
66 virtual ~FakeGCMAppHandler(); | |
67 | |
68 const Event& received_event() const { return received_event_; } | |
69 const std::string& app_id() const { return app_id_; } | |
70 const GCMClient::IncomingMessage& message() const { return message_; } | |
71 const GCMClient::SendErrorDetails& send_error_details() const { | |
72 return send_error_details_; | |
73 } | |
74 | |
75 void WaitForNotification(); | |
76 | |
77 // GCMAppHandler: | |
78 virtual void ShutdownHandler() OVERRIDE; | |
79 virtual void OnMessage(const std::string& app_id, | |
80 const GCMClient::IncomingMessage& message) OVERRIDE; | |
81 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE; | |
82 virtual void OnSendError( | |
83 const std::string& app_id, | |
84 const GCMClient::SendErrorDetails& send_error_details) OVERRIDE; | |
85 | |
86 private: | |
87 void ClearResults(); | |
88 | |
89 scoped_ptr<base::RunLoop> run_loop_; | |
90 | |
91 Event received_event_; | |
92 std::string app_id_; | |
93 GCMClient::IncomingMessage message_; | |
94 GCMClient::SendErrorDetails send_error_details_; | |
95 | |
96 DISALLOW_COPY_AND_ASSIGN(FakeGCMAppHandler); | |
97 }; | |
98 | |
99 class TestGCMService : public GCMService { | |
100 public: | |
101 TestGCMService( | |
102 bool start_automatically, | |
103 scoped_ptr<IdentityProvider> identity_provider, | |
104 const scoped_refptr<net::URLRequestContextGetter>& request_context); | |
105 virtual ~TestGCMService(); | |
106 | |
107 protected: | |
108 // GCMService: | |
109 virtual bool ShouldStartAutomatically() const OVERRIDE; | |
110 virtual base::FilePath GetStorePath() const OVERRIDE; | |
111 virtual scoped_refptr<net::URLRequestContextGetter> | |
112 GetURLRequestContextGetter() const OVERRIDE; | |
113 | |
114 private: | |
115 base::ScopedTempDir temp_dir_; | |
116 scoped_refptr<net::URLRequestContextGetter> request_context_; | |
117 const bool start_automatically_; | |
118 | |
119 DISALLOW_COPY_AND_ASSIGN(TestGCMService); | |
120 }; | |
121 | |
122 FakeGCMAppHandler::FakeGCMAppHandler() : received_event_(NO_EVENT) { | |
123 } | |
124 | |
125 FakeGCMAppHandler::~FakeGCMAppHandler() { | |
126 } | |
127 | |
128 void FakeGCMAppHandler::WaitForNotification() { | |
129 run_loop_.reset(new base::RunLoop); | |
130 run_loop_->Run(); | |
131 run_loop_.reset(); | |
132 } | |
133 | |
134 void FakeGCMAppHandler::ShutdownHandler() { | |
135 } | |
136 | |
137 void FakeGCMAppHandler::OnMessage(const std::string& app_id, | |
138 const GCMClient::IncomingMessage& message) { | |
139 ClearResults(); | |
140 received_event_ = MESSAGE_EVENT; | |
141 app_id_ = app_id; | |
142 message_ = message; | |
143 if (run_loop_) | |
144 run_loop_->Quit(); | |
145 } | |
146 | |
147 void FakeGCMAppHandler::OnMessagesDeleted(const std::string& app_id) { | |
148 ClearResults(); | |
149 received_event_ = MESSAGES_DELETED_EVENT; | |
150 app_id_ = app_id; | |
151 if (run_loop_) | |
152 run_loop_->Quit(); | |
153 } | |
154 | |
155 void FakeGCMAppHandler::OnSendError( | |
156 const std::string& app_id, | |
157 const GCMClient::SendErrorDetails& send_error_details) { | |
158 ClearResults(); | |
159 received_event_ = SEND_ERROR_EVENT; | |
160 app_id_ = app_id; | |
161 send_error_details_ = send_error_details; | |
162 if (run_loop_) | |
163 run_loop_->Quit(); | |
164 } | |
165 | |
166 void FakeGCMAppHandler::ClearResults() { | |
167 received_event_ = NO_EVENT; | |
168 app_id_.clear(); | |
169 message_ = GCMClient::IncomingMessage(); | |
170 send_error_details_ = GCMClient::SendErrorDetails(); | |
171 } | |
172 | |
173 TestGCMService::TestGCMService( | |
174 bool start_automatically, | |
175 scoped_ptr<IdentityProvider> identity_provider, | |
176 const scoped_refptr<net::URLRequestContextGetter>& request_context) | |
177 : GCMService(identity_provider.Pass()), | |
178 request_context_(request_context), | |
179 start_automatically_(start_automatically) { | |
180 if (!temp_dir_.CreateUniqueTempDir()) | |
181 ADD_FAILURE(); | |
182 } | |
183 | |
184 TestGCMService::~TestGCMService() { | |
185 } | |
186 | |
187 bool TestGCMService::ShouldStartAutomatically() const { | |
188 return start_automatically_; | |
189 } | |
190 | |
191 base::FilePath TestGCMService::GetStorePath() const { | |
192 return temp_dir_.path(); | |
193 } | |
194 | |
195 scoped_refptr<net::URLRequestContextGetter> | |
196 TestGCMService::GetURLRequestContextGetter() const { | |
197 return request_context_; | |
198 } | |
199 | |
200 } // namespace | |
201 | |
202 class TestGCMServiceWrapper { | |
203 public: | |
204 enum AsyncBehavior { | |
jianli
2014/04/23 00:42:32
nit: the name sounds more like asynchronous execut
bartfab (slow)
2014/04/23 11:33:07
Well, it is async execution on another thread. But
| |
205 DO_NOT_WAIT, | |
206 WAIT | |
207 }; | |
208 | |
209 explicit TestGCMServiceWrapper( | |
210 const scoped_refptr<net::URLRequestContextGetter>& request_context); | |
211 ~TestGCMServiceWrapper(); | |
212 | |
213 TestGCMService* service() { return service_.get(); } | |
214 FakeGCMAppHandler* gcm_app_handler() { return gcm_app_handler_.get(); } | |
215 const std::string& registration_id() const { return registration_id_; } | |
216 GCMClient::Result registration_result() const { return registration_result_; } | |
217 const std::string& send_message_id() const { return send_message_id_; } | |
218 GCMClient::Result send_result() const { return send_result_; } | |
219 GCMClient::Result unregistration_result() const { | |
220 return unregistration_result_; | |
221 } | |
222 | |
223 void ClearRegistrationResult(); | |
224 void ClearUnregistrationResult(); | |
225 | |
226 bool ServiceHasAppHandlers() const; | |
227 GCMClientMock* GetGCMClient(); | |
228 | |
229 void CreateService(bool start_automatically, | |
230 GCMClientMock::LoadingDelay gcm_client_loading_delay); | |
231 | |
232 void SignIn(const std::string& account_id); | |
233 void SignOut(); | |
234 | |
235 void Register(const std::string& app_id, | |
236 const std::vector<std::string>& sender_ids, | |
237 AsyncBehavior async_behavior); | |
238 void Send(const std::string& app_id, | |
239 const std::string& receiver_id, | |
240 const GCMClient::OutgoingMessage& message, | |
241 AsyncBehavior async_behavior); | |
242 void Unregister(const std::string& app_id, AsyncBehavior async_behavior); | |
243 | |
244 void WaitForAsyncOperation(); | |
245 | |
246 private: | |
247 void RegisterCompleted(const std::string& registration_id, | |
248 GCMClient::Result result); | |
249 void SendCompleted(const std::string& message_id, GCMClient::Result result); | |
250 void UnregisterCompleted(GCMClient::Result result); | |
251 | |
252 scoped_refptr<net::URLRequestContextGetter> request_context_; | |
253 FakeOAuth2TokenService token_service_; | |
254 scoped_ptr<FakeIdentityProvider> identity_provider_owner_; | |
255 FakeIdentityProvider* identity_provider_; | |
256 scoped_ptr<TestGCMService> service_; | |
257 scoped_ptr<FakeGCMAppHandler> gcm_app_handler_; | |
258 | |
259 base::Closure async_operation_completed_callback_; | |
260 | |
261 std::string registration_id_; | |
262 GCMClient::Result registration_result_; | |
263 std::string send_message_id_; | |
264 GCMClient::Result send_result_; | |
265 GCMClient::Result unregistration_result_; | |
266 | |
267 DISALLOW_COPY_AND_ASSIGN(TestGCMServiceWrapper); | |
268 }; | |
269 | |
270 TestGCMServiceWrapper::TestGCMServiceWrapper( | |
271 const scoped_refptr<net::URLRequestContextGetter>& request_context) | |
272 : request_context_(request_context), | |
273 identity_provider_(NULL), | |
274 registration_result_(GCMClient::UNKNOWN_ERROR), | |
275 send_result_(GCMClient::UNKNOWN_ERROR), | |
276 unregistration_result_(GCMClient::UNKNOWN_ERROR) { | |
277 identity_provider_owner_.reset(new FakeIdentityProvider(&token_service_)); | |
278 identity_provider_ = identity_provider_owner_.get(); | |
279 } | |
280 | |
281 TestGCMServiceWrapper::~TestGCMServiceWrapper() { | |
282 if (!service_) | |
283 return; | |
284 | |
285 service_->ShutdownService(); | |
286 service_.reset(); | |
287 PumpIOLoop(); | |
288 } | |
289 | |
290 void TestGCMServiceWrapper::ClearRegistrationResult() { | |
291 registration_id_.clear(); | |
292 registration_result_ = GCMClient::UNKNOWN_ERROR; | |
293 } | |
294 | |
295 void TestGCMServiceWrapper::ClearUnregistrationResult() { | |
296 unregistration_result_ = GCMClient::UNKNOWN_ERROR; | |
297 } | |
298 | |
299 bool TestGCMServiceWrapper::ServiceHasAppHandlers() const { | |
300 return !service_->app_handlers_.empty(); | |
301 } | |
302 | |
303 GCMClientMock* TestGCMServiceWrapper::GetGCMClient() { | |
304 return static_cast<GCMClientMock*>(service_->GetGCMClientForTesting()); | |
305 } | |
306 | |
307 void TestGCMServiceWrapper::CreateService( | |
308 bool start_automatically, | |
309 GCMClientMock::LoadingDelay gcm_client_loading_delay) { | |
310 service_.reset(new TestGCMService( | |
311 start_automatically, | |
312 identity_provider_owner_.PassAs<IdentityProvider>(), | |
313 request_context_)); | |
314 service_->Initialize(scoped_ptr<GCMClientFactory>( | |
315 new FakeGCMClientFactory(gcm_client_loading_delay))); | |
316 | |
317 gcm_app_handler_.reset(new FakeGCMAppHandler); | |
318 service_->AddAppHandler(kTestAppID1, gcm_app_handler_.get()); | |
319 service_->AddAppHandler(kTestAppID2, gcm_app_handler_.get()); | |
320 } | |
321 | |
322 void TestGCMServiceWrapper::SignIn(const std::string& account_id) { | |
323 token_service_.AddAccount(account_id); | |
324 identity_provider_->LogIn(account_id); | |
325 PumpIOLoop(); | |
326 PumpUILoop(); | |
327 } | |
328 | |
329 void TestGCMServiceWrapper::SignOut() { | |
330 identity_provider_->LogOut(); | |
331 PumpIOLoop(); | |
332 PumpUILoop(); | |
333 } | |
334 | |
335 void TestGCMServiceWrapper::Register(const std::string& app_id, | |
336 const std::vector<std::string>& sender_ids, | |
337 AsyncBehavior async_behavior) { | |
338 base::RunLoop run_loop; | |
339 async_operation_completed_callback_ = run_loop.QuitClosure(); | |
340 service_->Register(app_id, | |
341 sender_ids, | |
342 base::Bind(&TestGCMServiceWrapper::RegisterCompleted, | |
343 base::Unretained(this))); | |
344 if (async_behavior == WAIT) | |
345 run_loop.Run(); | |
346 } | |
347 | |
348 void TestGCMServiceWrapper::Send(const std::string& app_id, | |
349 const std::string& receiver_id, | |
350 const GCMClient::OutgoingMessage& message, | |
351 AsyncBehavior async_behavior) { | |
352 base::RunLoop run_loop; | |
353 async_operation_completed_callback_ = run_loop.QuitClosure(); | |
354 service_->Send(app_id, | |
355 receiver_id, | |
356 message, | |
357 base::Bind(&TestGCMServiceWrapper::SendCompleted, | |
358 base::Unretained(this))); | |
359 if (async_behavior == WAIT) | |
360 run_loop.Run(); | |
361 } | |
362 | |
363 void TestGCMServiceWrapper::Unregister(const std::string& app_id, | |
364 AsyncBehavior async_behavior) { | |
365 base::RunLoop run_loop; | |
366 async_operation_completed_callback_ = run_loop.QuitClosure(); | |
367 service_->Unregister(app_id, | |
368 base::Bind(&TestGCMServiceWrapper::UnregisterCompleted, | |
369 base::Unretained(this))); | |
370 if (async_behavior == WAIT) | |
371 run_loop.Run(); | |
372 } | |
373 | |
374 void TestGCMServiceWrapper::WaitForAsyncOperation() { | |
375 base::RunLoop run_loop; | |
376 async_operation_completed_callback_ = run_loop.QuitClosure(); | |
377 run_loop.Run(); | |
378 } | |
379 | |
380 void TestGCMServiceWrapper::RegisterCompleted( | |
381 const std::string& registration_id, | |
382 GCMClient::Result result) { | |
383 registration_id_ = registration_id; | |
384 registration_result_ = result; | |
385 if (!async_operation_completed_callback_.is_null()) | |
386 async_operation_completed_callback_.Run(); | |
387 } | |
388 | |
389 void TestGCMServiceWrapper::SendCompleted(const std::string& message_id, | |
390 GCMClient::Result result) { | |
391 send_message_id_ = message_id; | |
392 send_result_ = result; | |
393 if (!async_operation_completed_callback_.is_null()) | |
394 async_operation_completed_callback_.Run(); | |
395 } | |
396 | |
397 void TestGCMServiceWrapper::UnregisterCompleted(GCMClient::Result result) { | |
398 unregistration_result_ = result; | |
399 if (!async_operation_completed_callback_.is_null()) | |
400 async_operation_completed_callback_.Run(); | |
401 } | |
402 | |
403 class GCMServiceTest : public testing::Test { | |
404 protected: | |
405 GCMServiceTest(); | |
406 virtual ~GCMServiceTest(); | |
407 | |
408 // testing::Test: | |
409 void SetUp() OVERRIDE; | |
410 void TearDown() OVERRIDE; | |
411 | |
412 scoped_ptr<content::TestBrowserThreadBundle> thread_bundle_; | |
413 scoped_refptr<net::URLRequestContextGetter> request_context_; | |
414 scoped_ptr<TestGCMServiceWrapper> wrapper_; | |
415 | |
416 private: | |
417 DISALLOW_COPY_AND_ASSIGN(GCMServiceTest); | |
418 }; | |
419 | |
420 GCMServiceTest::GCMServiceTest() { | |
421 } | |
422 | |
423 GCMServiceTest::~GCMServiceTest() { | |
424 } | |
425 | |
426 void GCMServiceTest::SetUp() { | |
427 thread_bundle_.reset(new content::TestBrowserThreadBundle( | |
428 content::TestBrowserThreadBundle::REAL_IO_THREAD)); | |
429 request_context_ = new net::TestURLRequestContextGetter( | |
430 content::BrowserThread::GetMessageLoopProxyForThread( | |
431 content::BrowserThread::IO)); | |
432 wrapper_.reset(new TestGCMServiceWrapper(request_context_)); | |
433 } | |
434 | |
435 void GCMServiceTest::TearDown() { | |
436 wrapper_.reset(); | |
437 } | |
438 | |
439 TEST_F(GCMServiceTest, CreateGCMServiceBeforeSignIn) { | |
440 // Create CreateGMCService first. | |
441 wrapper_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
442 EXPECT_FALSE(wrapper_->service()->IsStarted()); | |
443 | |
444 // Sign in. This will kick off the check-in. | |
445 wrapper_->SignIn(kTestAccountID1); | |
446 EXPECT_TRUE(wrapper_->service()->IsStarted()); | |
447 } | |
448 | |
449 TEST_F(GCMServiceTest, CreateGCMServiceAfterSignIn) { | |
450 // Sign in. This will not initiate the check-in. | |
451 wrapper_->SignIn(kTestAccountID1); | |
452 | |
453 // Create GCMeService after sign-in. | |
454 wrapper_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
455 EXPECT_TRUE(wrapper_->service()->IsStarted()); | |
456 } | |
457 | |
458 TEST_F(GCMServiceTest, Shutdown) { | |
459 wrapper_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
460 EXPECT_TRUE(wrapper_->ServiceHasAppHandlers()); | |
461 | |
462 wrapper_->service()->ShutdownService(); | |
463 EXPECT_FALSE(wrapper_->ServiceHasAppHandlers()); | |
464 } | |
465 | |
466 TEST_F(GCMServiceTest, SignInAndSignOutUnderPositiveChannelSignal) { | |
467 wrapper_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
468 wrapper_->SignIn(kTestAccountID1); | |
469 | |
470 // GCMClient should be loaded. | |
471 EXPECT_TRUE(wrapper_->service()->IsGCMClientReady()); | |
472 EXPECT_EQ(GCMClientMock::LOADED, wrapper_->GetGCMClient()->status()); | |
473 | |
474 wrapper_->SignOut(); | |
475 | |
476 // GCMClient should be checked out. | |
477 EXPECT_FALSE(wrapper_->service()->IsGCMClientReady()); | |
478 EXPECT_EQ(GCMClientMock::CHECKED_OUT, wrapper_->GetGCMClient()->status()); | |
479 } | |
480 | |
481 TEST_F(GCMServiceTest, SignInAndSignOutUnderNonPositiveChannelSignal) { | |
482 // Non-positive channel signal will prevent GCMClient from checking in during | |
483 // sign-in. | |
484 wrapper_->CreateService(false, GCMClientMock::NO_DELAY_LOADING); | |
485 wrapper_->SignIn(kTestAccountID1); | |
486 | |
487 // GCMClient should not be loaded. | |
488 EXPECT_FALSE(wrapper_->service()->IsGCMClientReady()); | |
489 EXPECT_EQ(GCMClientMock::UNINITIALIZED, wrapper_->GetGCMClient()->status()); | |
490 | |
491 wrapper_->SignOut(); | |
492 | |
493 // Check-out should still be performed. | |
494 EXPECT_FALSE(wrapper_->service()->IsGCMClientReady()); | |
495 EXPECT_EQ(GCMClientMock::CHECKED_OUT, wrapper_->GetGCMClient()->status()); | |
496 } | |
497 | |
498 TEST_F(GCMServiceTest, SignOutAndThenSignIn) { | |
499 wrapper_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
500 wrapper_->SignIn(kTestAccountID1); | |
501 | |
502 // GCMClient should be loaded. | |
503 EXPECT_TRUE(wrapper_->service()->IsGCMClientReady()); | |
504 EXPECT_EQ(GCMClientMock::LOADED, wrapper_->GetGCMClient()->status()); | |
505 | |
506 wrapper_->SignOut(); | |
507 | |
508 // GCMClient should be checked out. | |
509 EXPECT_FALSE(wrapper_->service()->IsGCMClientReady()); | |
510 EXPECT_EQ(GCMClientMock::CHECKED_OUT, wrapper_->GetGCMClient()->status()); | |
511 | |
512 // Sign-in with a different account. | |
513 wrapper_->SignIn(kTestAccountID2); | |
514 | |
515 // GCMClient should be loaded again. | |
516 EXPECT_TRUE(wrapper_->service()->IsGCMClientReady()); | |
517 EXPECT_EQ(GCMClientMock::LOADED, wrapper_->GetGCMClient()->status()); | |
518 } | |
519 | |
520 TEST_F(GCMServiceTest, StopAndRestartGCM) { | |
521 wrapper_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
522 wrapper_->SignIn(kTestAccountID1); | |
523 | |
524 // GCMClient should be loaded. | |
525 EXPECT_TRUE(wrapper_->service()->IsGCMClientReady()); | |
526 EXPECT_EQ(GCMClientMock::LOADED, wrapper_->GetGCMClient()->status()); | |
527 | |
528 // Stops the GCM. | |
529 wrapper_->service()->Stop(); | |
530 PumpIOLoop(); | |
531 PumpUILoop(); | |
532 | |
533 // GCMClient should be stopped. | |
534 EXPECT_FALSE(wrapper_->service()->IsGCMClientReady()); | |
535 EXPECT_EQ(GCMClientMock::STOPPED, wrapper_->GetGCMClient()->status()); | |
536 | |
537 // Restarts the GCM. | |
538 wrapper_->service()->Start(); | |
539 PumpIOLoop(); | |
540 PumpUILoop(); | |
541 | |
542 // GCMClient should be loaded. | |
543 EXPECT_TRUE(wrapper_->service()->IsGCMClientReady()); | |
544 EXPECT_EQ(GCMClientMock::LOADED, wrapper_->GetGCMClient()->status()); | |
545 | |
546 // Stops the GCM. | |
547 wrapper_->service()->Stop(); | |
548 PumpIOLoop(); | |
549 PumpUILoop(); | |
550 | |
551 // GCMClient should be stopped. | |
552 EXPECT_FALSE(wrapper_->service()->IsGCMClientReady()); | |
553 EXPECT_EQ(GCMClientMock::STOPPED, wrapper_->GetGCMClient()->status()); | |
554 | |
555 // Sign out. | |
556 wrapper_->SignOut(); | |
557 | |
558 // GCMClient should be checked out. | |
559 EXPECT_FALSE(wrapper_->service()->IsGCMClientReady()); | |
560 EXPECT_EQ(GCMClientMock::CHECKED_OUT, wrapper_->GetGCMClient()->status()); | |
561 } | |
562 | |
563 TEST_F(GCMServiceTest, RegisterWhenNotSignedIn) { | |
564 wrapper_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
565 | |
566 std::vector<std::string> sender_ids; | |
567 sender_ids.push_back("sender1"); | |
568 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
569 | |
570 EXPECT_TRUE(wrapper_->registration_id().empty()); | |
571 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, wrapper_->registration_result()); | |
572 } | |
573 | |
574 TEST_F(GCMServiceTest, RegisterUnderNonPositiveChannelSignal) { | |
575 // Non-positive channel signal will prevent GCMClient from checking in during | |
576 // sign-in. | |
577 wrapper_->CreateService(false, GCMClientMock::NO_DELAY_LOADING); | |
578 wrapper_->SignIn(kTestAccountID1); | |
579 | |
580 // GCMClient should not be checked in. | |
581 EXPECT_FALSE(wrapper_->service()->IsGCMClientReady()); | |
582 EXPECT_EQ(GCMClientMock::UNINITIALIZED, wrapper_->GetGCMClient()->status()); | |
583 | |
584 // Invoking register will make GCMClient checked in. | |
585 std::vector<std::string> sender_ids; | |
586 sender_ids.push_back("sender1"); | |
587 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
588 | |
589 // GCMClient should be checked in. | |
590 EXPECT_TRUE(wrapper_->service()->IsGCMClientReady()); | |
591 EXPECT_EQ(GCMClientMock::LOADED, wrapper_->GetGCMClient()->status()); | |
592 | |
593 // Registration should succeed. | |
594 const std::string expected_registration_id = | |
595 GCMClientMock::GetRegistrationIdFromSenderIds(sender_ids); | |
596 EXPECT_EQ(expected_registration_id, wrapper_->registration_id()); | |
597 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
598 } | |
599 | |
600 TEST_F(GCMServiceTest, SendWhenNotSignedIn) { | |
601 wrapper_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
602 | |
603 GCMClient::OutgoingMessage message; | |
604 message.id = "1"; | |
605 message.data["key1"] = "value1"; | |
606 wrapper_->Send(kTestAppID1, kUserID1, message, TestGCMServiceWrapper::WAIT); | |
607 | |
608 EXPECT_TRUE(wrapper_->send_message_id().empty()); | |
609 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, wrapper_->send_result()); | |
610 } | |
611 | |
612 TEST_F(GCMServiceTest, SendUnderNonPositiveChannelSignal) { | |
613 // Non-positive channel signal will prevent GCMClient from checking in during | |
614 // sign-in. | |
615 wrapper_->CreateService(false, GCMClientMock::NO_DELAY_LOADING); | |
616 wrapper_->SignIn(kTestAccountID1); | |
617 | |
618 // GCMClient should not be checked in. | |
619 EXPECT_FALSE(wrapper_->service()->IsGCMClientReady()); | |
620 EXPECT_EQ(GCMClientMock::UNINITIALIZED, wrapper_->GetGCMClient()->status()); | |
621 | |
622 // Invoking send will make GCMClient checked in. | |
623 GCMClient::OutgoingMessage message; | |
624 message.id = "1"; | |
625 message.data["key1"] = "value1"; | |
626 wrapper_->Send(kTestAppID1, kUserID1, message, TestGCMServiceWrapper::WAIT); | |
627 | |
628 // GCMClient should be checked in. | |
629 EXPECT_TRUE(wrapper_->service()->IsGCMClientReady()); | |
630 EXPECT_EQ(GCMClientMock::LOADED, wrapper_->GetGCMClient()->status()); | |
631 | |
632 // Sending should succeed. | |
633 EXPECT_EQ(message.id, wrapper_->send_message_id()); | |
634 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->send_result()); | |
635 } | |
636 | |
637 // Tests a single instance of GCMService. | |
638 class GCMServiceSingleInstanceTest : public GCMServiceTest { | |
639 public: | |
640 GCMServiceSingleInstanceTest(); | |
641 virtual ~GCMServiceSingleInstanceTest(); | |
642 | |
643 // GCMServiceTest: | |
644 virtual void SetUp() OVERRIDE; | |
645 | |
646 private: | |
647 DISALLOW_COPY_AND_ASSIGN(GCMServiceSingleInstanceTest); | |
648 }; | |
649 | |
650 GCMServiceSingleInstanceTest::GCMServiceSingleInstanceTest() { | |
651 } | |
652 | |
653 GCMServiceSingleInstanceTest::~GCMServiceSingleInstanceTest() { | |
654 } | |
655 | |
656 void GCMServiceSingleInstanceTest::SetUp() { | |
657 GCMServiceTest::SetUp(); | |
658 | |
659 wrapper_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
660 wrapper_->SignIn(kTestAccountID1); | |
661 } | |
662 | |
663 TEST_F(GCMServiceSingleInstanceTest, Register) { | |
664 std::vector<std::string> sender_ids; | |
665 sender_ids.push_back("sender1"); | |
666 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
667 const std::string expected_registration_id = | |
668 GCMClientMock::GetRegistrationIdFromSenderIds(sender_ids); | |
669 | |
670 EXPECT_EQ(expected_registration_id, wrapper_->registration_id()); | |
671 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
672 } | |
673 | |
674 TEST_F(GCMServiceSingleInstanceTest, RegisterError) { | |
675 std::vector<std::string> sender_ids; | |
676 sender_ids.push_back("sender1@error"); | |
677 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
678 | |
679 EXPECT_TRUE(wrapper_->registration_id().empty()); | |
680 EXPECT_NE(GCMClient::SUCCESS, wrapper_->registration_result()); | |
681 } | |
682 | |
683 TEST_F(GCMServiceSingleInstanceTest, RegisterAgainWithSameSenderIDs) { | |
684 std::vector<std::string> sender_ids; | |
685 sender_ids.push_back("sender1"); | |
686 sender_ids.push_back("sender2"); | |
687 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
688 const std::string expected_registration_id = | |
689 GCMClientMock::GetRegistrationIdFromSenderIds(sender_ids); | |
690 | |
691 EXPECT_EQ(expected_registration_id, wrapper_->registration_id()); | |
692 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
693 | |
694 // Clears the results the would be set by the Register callback in preparation | |
695 // to call register 2nd time. | |
696 wrapper_->ClearRegistrationResult(); | |
697 | |
698 // Calling register 2nd time with the same set of sender IDs but different | |
699 // ordering will get back the same registration ID. | |
700 std::vector<std::string> another_sender_ids; | |
701 another_sender_ids.push_back("sender2"); | |
702 another_sender_ids.push_back("sender1"); | |
703 wrapper_->Register(kTestAppID1, | |
704 another_sender_ids, | |
705 TestGCMServiceWrapper::WAIT); | |
706 | |
707 EXPECT_EQ(expected_registration_id, wrapper_->registration_id()); | |
708 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
709 } | |
710 | |
711 TEST_F(GCMServiceSingleInstanceTest, RegisterAgainWithDifferentSenderIDs) { | |
712 std::vector<std::string> sender_ids; | |
713 sender_ids.push_back("sender1"); | |
714 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
715 const std::string expected_registration_id = | |
716 GCMClientMock::GetRegistrationIdFromSenderIds(sender_ids); | |
717 | |
718 EXPECT_EQ(expected_registration_id, wrapper_->registration_id()); | |
719 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
720 | |
721 // Make sender IDs different. | |
722 sender_ids.push_back("sender2"); | |
723 const std::string expected_registration_id2 = | |
724 GCMClientMock::GetRegistrationIdFromSenderIds(sender_ids); | |
725 | |
726 // Calling register 2nd time with the different sender IDs will get back a new | |
727 // registration ID. | |
728 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
729 EXPECT_EQ(expected_registration_id2, wrapper_->registration_id()); | |
730 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
731 } | |
732 | |
733 TEST_F(GCMServiceSingleInstanceTest, GCMClientNotReadyBeforeRegistration) { | |
734 // Make GCMClient not ready initially. | |
735 wrapper_.reset(new TestGCMServiceWrapper(request_context_)); | |
736 wrapper_->CreateService(true, GCMClientMock::DELAY_LOADING); | |
737 wrapper_->SignIn(kTestAccountID1); | |
738 | |
739 // The registration is on hold until GCMClient is ready. | |
740 std::vector<std::string> sender_ids; | |
741 sender_ids.push_back("sender1"); | |
742 wrapper_->Register(kTestAppID1, | |
743 sender_ids, | |
744 TestGCMServiceWrapper::DO_NOT_WAIT); | |
745 PumpIOLoop(); | |
746 PumpUILoop(); | |
747 EXPECT_TRUE(wrapper_->registration_id().empty()); | |
748 EXPECT_EQ(GCMClient::UNKNOWN_ERROR, wrapper_->registration_result()); | |
749 | |
750 // Register operation will be invoked after GCMClient becomes ready. | |
751 wrapper_->GetGCMClient()->PerformDelayedLoading(); | |
752 wrapper_->WaitForAsyncOperation(); | |
753 EXPECT_FALSE(wrapper_->registration_id().empty()); | |
754 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
755 } | |
756 | |
757 TEST_F(GCMServiceSingleInstanceTest, RegisterAfterSignOut) { | |
758 // This will trigger check-out. | |
759 wrapper_->SignOut(); | |
760 | |
761 std::vector<std::string> sender_ids; | |
762 sender_ids.push_back("sender1"); | |
763 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
764 | |
765 EXPECT_TRUE(wrapper_->registration_id().empty()); | |
766 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, wrapper_->registration_result()); | |
767 } | |
768 | |
769 TEST_F(GCMServiceSingleInstanceTest, UnregisterExplicitly) { | |
770 std::vector<std::string> sender_ids; | |
771 sender_ids.push_back("sender1"); | |
772 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
773 | |
774 EXPECT_FALSE(wrapper_->registration_id().empty()); | |
775 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
776 | |
777 wrapper_->Unregister(kTestAppID1, TestGCMServiceWrapper::WAIT); | |
778 | |
779 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->unregistration_result()); | |
780 } | |
781 | |
782 TEST_F(GCMServiceSingleInstanceTest, UnregisterWhenAsyncOperationPending) { | |
783 std::vector<std::string> sender_ids; | |
784 sender_ids.push_back("sender1"); | |
785 // First start registration without waiting for it to complete. | |
786 wrapper_->Register(kTestAppID1, | |
787 sender_ids, | |
788 TestGCMServiceWrapper::DO_NOT_WAIT); | |
789 | |
790 // Test that unregistration fails with async operation pending when there is a | |
791 // registration already in progress. | |
792 wrapper_->Unregister(kTestAppID1, TestGCMServiceWrapper::WAIT); | |
793 EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING, | |
794 wrapper_->unregistration_result()); | |
795 | |
796 // Complete the unregistration. | |
797 PumpIOLoop(); | |
798 PumpUILoop(); | |
799 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
800 | |
801 // Start unregistration without waiting for it to complete. This time no async | |
802 // operation is pending. | |
803 wrapper_->Unregister(kTestAppID1, TestGCMServiceWrapper::DO_NOT_WAIT); | |
804 | |
805 // Test that unregistration fails with async operation pending when there is | |
806 // an unregistration already in progress. | |
807 wrapper_->Unregister(kTestAppID1, TestGCMServiceWrapper::WAIT); | |
808 EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING, | |
809 wrapper_->unregistration_result()); | |
810 wrapper_->ClearUnregistrationResult(); | |
811 | |
812 // Complete unregistration. | |
813 PumpIOLoop(); | |
814 PumpUILoop(); | |
815 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->unregistration_result()); | |
816 } | |
817 | |
818 TEST_F(GCMServiceSingleInstanceTest, RegisterWhenAsyncOperationPending) { | |
819 std::vector<std::string> sender_ids; | |
820 sender_ids.push_back("sender1"); | |
821 // First start registration without waiting for it to complete. | |
822 wrapper_->Register(kTestAppID1, | |
823 sender_ids, | |
824 TestGCMServiceWrapper::DO_NOT_WAIT); | |
825 | |
826 // Test that registration fails with async operation pending when there is a | |
827 // registration already in progress. | |
828 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
829 EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING, | |
830 wrapper_->registration_result()); | |
831 wrapper_->ClearRegistrationResult(); | |
832 | |
833 // Complete the registration. | |
834 PumpIOLoop(); | |
835 PumpUILoop(); | |
836 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
837 | |
838 // Start unregistration without waiting for it to complete. This time no async | |
839 // operation is pending. | |
840 wrapper_->Unregister(kTestAppID1, TestGCMServiceWrapper::DO_NOT_WAIT); | |
841 | |
842 // Test that registration fails with async operation pending when there is an | |
843 // unregistration already in progress. | |
844 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
845 EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING, | |
846 wrapper_->registration_result()); | |
847 | |
848 // Complete the first unregistration expecting success. | |
849 PumpIOLoop(); | |
850 PumpUILoop(); | |
851 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->unregistration_result()); | |
852 | |
853 // Test that it is ok to register again after unregistration. | |
854 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
855 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
856 } | |
857 | |
858 TEST_F(GCMServiceSingleInstanceTest, Send) { | |
859 GCMClient::OutgoingMessage message; | |
860 message.id = "1"; | |
861 message.data["key1"] = "value1"; | |
862 message.data["key2"] = "value2"; | |
863 wrapper_->Send(kTestAppID1, kUserID1, message, TestGCMServiceWrapper::WAIT); | |
864 | |
865 EXPECT_EQ(message.id, wrapper_->send_message_id()); | |
866 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->send_result()); | |
867 } | |
868 | |
869 TEST_F(GCMServiceSingleInstanceTest, GCMClientNotReadyBeforeSending) { | |
870 // Make GCMClient not ready initially. | |
871 wrapper_.reset(new TestGCMServiceWrapper(request_context_)); | |
872 wrapper_->CreateService(true, GCMClientMock::DELAY_LOADING); | |
873 wrapper_->SignIn(kTestAccountID1); | |
874 | |
875 // The sending is on hold until GCMClient is ready. | |
876 GCMClient::OutgoingMessage message; | |
877 message.id = "1"; | |
878 message.data["key1"] = "value1"; | |
879 message.data["key2"] = "value2"; | |
880 wrapper_->Send(kTestAppID1, | |
881 kUserID1, | |
882 message, | |
883 TestGCMServiceWrapper::DO_NOT_WAIT); | |
884 PumpIOLoop(); | |
885 PumpUILoop(); | |
886 | |
887 EXPECT_TRUE(wrapper_->send_message_id().empty()); | |
888 EXPECT_EQ(GCMClient::UNKNOWN_ERROR, wrapper_->send_result()); | |
889 | |
890 // Send operation will be invoked after GCMClient becomes ready. | |
891 wrapper_->GetGCMClient()->PerformDelayedLoading(); | |
892 wrapper_->WaitForAsyncOperation(); | |
893 EXPECT_EQ(message.id, wrapper_->send_message_id()); | |
894 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->send_result()); | |
895 } | |
896 | |
897 TEST_F(GCMServiceSingleInstanceTest, SendAfterSignOut) { | |
898 // This will trigger check-out. | |
899 wrapper_->SignOut(); | |
900 | |
901 GCMClient::OutgoingMessage message; | |
902 message.id = "1"; | |
903 message.data["key1"] = "value1"; | |
904 message.data["key2"] = "value2"; | |
905 wrapper_->Send(kTestAppID1, kUserID1, message, TestGCMServiceWrapper::WAIT); | |
906 | |
907 EXPECT_TRUE(wrapper_->send_message_id().empty()); | |
908 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, wrapper_->send_result()); | |
909 } | |
910 | |
911 TEST_F(GCMServiceSingleInstanceTest, SendError) { | |
912 GCMClient::OutgoingMessage message; | |
913 // Embedding error in id will tell the mock to simulate the send error. | |
914 message.id = "1@error"; | |
915 message.data["key1"] = "value1"; | |
916 message.data["key2"] = "value2"; | |
917 wrapper_->Send(kTestAppID1, kUserID1, message, TestGCMServiceWrapper::WAIT); | |
918 | |
919 EXPECT_EQ(message.id, wrapper_->send_message_id()); | |
920 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->send_result()); | |
921 | |
922 // Wait for the send error. | |
923 wrapper_->gcm_app_handler()->WaitForNotification(); | |
924 EXPECT_EQ(FakeGCMAppHandler::SEND_ERROR_EVENT, | |
925 wrapper_->gcm_app_handler()->received_event()); | |
926 EXPECT_EQ(kTestAppID1, wrapper_->gcm_app_handler()->app_id()); | |
927 EXPECT_EQ(message.id, | |
928 wrapper_->gcm_app_handler()->send_error_details().message_id); | |
929 EXPECT_NE(GCMClient::SUCCESS, | |
930 wrapper_->gcm_app_handler()->send_error_details().result); | |
931 EXPECT_EQ(message.data, | |
932 wrapper_->gcm_app_handler()->send_error_details().additional_data); | |
933 } | |
934 | |
935 TEST_F(GCMServiceSingleInstanceTest, MessageReceived) { | |
936 wrapper_->Register(kTestAppID1, | |
937 ToSenderList("sender"), | |
938 TestGCMServiceWrapper::WAIT); | |
939 GCMClient::IncomingMessage message; | |
940 message.data["key1"] = "value1"; | |
941 message.data["key2"] = "value2"; | |
942 message.sender_id = "sender"; | |
943 wrapper_->GetGCMClient()->ReceiveMessage(kTestAppID1, message); | |
944 wrapper_->gcm_app_handler()->WaitForNotification(); | |
945 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT, | |
946 wrapper_->gcm_app_handler()->received_event()); | |
947 EXPECT_EQ(kTestAppID1, wrapper_->gcm_app_handler()->app_id()); | |
948 EXPECT_EQ(message.data, wrapper_->gcm_app_handler()->message().data); | |
949 EXPECT_TRUE(wrapper_->gcm_app_handler()->message().collapse_key.empty()); | |
950 EXPECT_EQ(message.sender_id, | |
951 wrapper_->gcm_app_handler()->message().sender_id); | |
952 } | |
953 | |
954 TEST_F(GCMServiceSingleInstanceTest, MessageWithCollapseKeyReceived) { | |
955 wrapper_->Register(kTestAppID1, | |
956 ToSenderList("sender"), | |
957 TestGCMServiceWrapper::WAIT); | |
958 GCMClient::IncomingMessage message; | |
959 message.data["key1"] = "value1"; | |
960 message.collapse_key = "collapse_key_value"; | |
961 message.sender_id = "sender"; | |
962 wrapper_->GetGCMClient()->ReceiveMessage(kTestAppID1, message); | |
963 wrapper_->gcm_app_handler()->WaitForNotification(); | |
964 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT, | |
965 wrapper_->gcm_app_handler()->received_event()); | |
966 EXPECT_EQ(kTestAppID1, wrapper_->gcm_app_handler()->app_id()); | |
967 EXPECT_EQ(message.data, wrapper_->gcm_app_handler()->message().data); | |
968 EXPECT_EQ(message.collapse_key, | |
969 wrapper_->gcm_app_handler()->message().collapse_key); | |
970 } | |
971 | |
972 TEST_F(GCMServiceSingleInstanceTest, MessagesDeleted) { | |
973 wrapper_->GetGCMClient()->DeleteMessages(kTestAppID1); | |
974 wrapper_->gcm_app_handler()->WaitForNotification(); | |
975 EXPECT_EQ(FakeGCMAppHandler::MESSAGES_DELETED_EVENT, | |
976 wrapper_->gcm_app_handler()->received_event()); | |
977 EXPECT_EQ(kTestAppID1, wrapper_->gcm_app_handler()->app_id()); | |
978 } | |
979 | |
980 // Tests to make sure that concurrent GCMService instances work correctly | |
981 // regardless how GCMClient is created. | |
982 class GCMServiceMultipleInstanceTest : public GCMServiceTest { | |
983 protected: | |
984 GCMServiceMultipleInstanceTest(); | |
985 virtual ~GCMServiceMultipleInstanceTest(); | |
986 | |
987 // GCMServiceTest: | |
988 virtual void SetUp() OVERRIDE; | |
989 virtual void TearDown() OVERRIDE; | |
990 | |
991 scoped_ptr<TestGCMServiceWrapper> wrapper2_; | |
992 | |
993 private: | |
994 DISALLOW_COPY_AND_ASSIGN(GCMServiceMultipleInstanceTest); | |
995 }; | |
996 | |
997 GCMServiceMultipleInstanceTest::GCMServiceMultipleInstanceTest() { | |
998 } | |
999 | |
1000 GCMServiceMultipleInstanceTest::~GCMServiceMultipleInstanceTest() { | |
1001 } | |
1002 | |
1003 void GCMServiceMultipleInstanceTest::SetUp() { | |
1004 GCMServiceTest::SetUp(); | |
1005 | |
1006 wrapper2_.reset(new TestGCMServiceWrapper(request_context_)); | |
1007 | |
1008 wrapper_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
1009 wrapper2_->CreateService(true, GCMClientMock::NO_DELAY_LOADING); | |
1010 | |
1011 // Initiate check-in for each instance. | |
1012 wrapper_->SignIn(kTestAccountID1); | |
1013 wrapper2_->SignIn(kTestAccountID2); | |
1014 } | |
1015 | |
1016 void GCMServiceMultipleInstanceTest::TearDown() { | |
1017 wrapper2_.reset(); | |
1018 } | |
1019 | |
1020 TEST_F(GCMServiceMultipleInstanceTest, Register) { | |
1021 // Register an app. | |
1022 std::vector<std::string> sender_ids; | |
1023 sender_ids.push_back("sender1"); | |
1024 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
1025 | |
1026 // Register the same app in a different instance. | |
1027 std::vector<std::string> sender_ids2; | |
1028 sender_ids2.push_back("foo"); | |
1029 sender_ids2.push_back("bar"); | |
1030 wrapper2_->Register(kTestAppID1, sender_ids2, TestGCMServiceWrapper::WAIT); | |
1031 | |
1032 EXPECT_EQ(GCMClientMock::GetRegistrationIdFromSenderIds(sender_ids), | |
1033 wrapper_->registration_id()); | |
1034 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
1035 | |
1036 EXPECT_EQ(GCMClientMock::GetRegistrationIdFromSenderIds(sender_ids2), | |
1037 wrapper2_->registration_id()); | |
1038 EXPECT_EQ(GCMClient::SUCCESS, wrapper2_->registration_result()); | |
1039 | |
1040 // Register a different app in a different instance. | |
1041 std::vector<std::string> sender_ids3; | |
1042 sender_ids3.push_back("sender1"); | |
1043 sender_ids3.push_back("sender2"); | |
1044 sender_ids3.push_back("sender3"); | |
1045 wrapper2_->Register(kTestAppID2, sender_ids3, TestGCMServiceWrapper::WAIT); | |
1046 | |
1047 EXPECT_EQ(GCMClientMock::GetRegistrationIdFromSenderIds(sender_ids3), | |
1048 wrapper2_->registration_id()); | |
1049 EXPECT_EQ(GCMClient::SUCCESS, wrapper2_->registration_result()); | |
1050 } | |
1051 | |
1052 TEST_F(GCMServiceMultipleInstanceTest, Send) { | |
1053 // Send a message from one app in one instance. | |
1054 GCMClient::OutgoingMessage message; | |
1055 message.id = "1"; | |
1056 message.data["key1"] = "value1"; | |
1057 message.data["key2"] = "value2"; | |
1058 wrapper_->Send(kTestAppID1, kUserID1, message, TestGCMServiceWrapper::WAIT); | |
1059 | |
1060 // Send a message from same app in another instance. | |
1061 GCMClient::OutgoingMessage message2; | |
1062 message2.id = "2"; | |
1063 message2.data["foo"] = "bar"; | |
1064 wrapper2_->Send(kTestAppID1, kUserID2, message2, TestGCMServiceWrapper::WAIT); | |
1065 | |
1066 EXPECT_EQ(message.id, wrapper_->send_message_id()); | |
1067 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->send_result()); | |
1068 | |
1069 EXPECT_EQ(message2.id, wrapper2_->send_message_id()); | |
1070 EXPECT_EQ(GCMClient::SUCCESS, wrapper2_->send_result()); | |
1071 | |
1072 // Send another message from different app in another instance. | |
1073 GCMClient::OutgoingMessage message3; | |
1074 message3.id = "3"; | |
1075 message3.data["hello"] = "world"; | |
1076 wrapper2_->Send(kTestAppID2, kUserID1, message3, TestGCMServiceWrapper::WAIT); | |
1077 | |
1078 EXPECT_EQ(message3.id, wrapper2_->send_message_id()); | |
1079 EXPECT_EQ(GCMClient::SUCCESS, wrapper2_->send_result()); | |
1080 } | |
1081 | |
1082 TEST_F(GCMServiceMultipleInstanceTest, MessageReceived) { | |
1083 wrapper_->Register(kTestAppID1, | |
1084 ToSenderList("sender"), | |
1085 TestGCMServiceWrapper::WAIT); | |
1086 wrapper2_->Register(kTestAppID1, | |
1087 ToSenderList("sender"), | |
1088 TestGCMServiceWrapper::WAIT); | |
1089 wrapper2_->Register(kTestAppID2, | |
1090 ToSenderList("sender2"), | |
1091 TestGCMServiceWrapper::WAIT); | |
1092 | |
1093 // Trigger an incoming message for an app in one instance. | |
1094 GCMClient::IncomingMessage message; | |
1095 message.data["key1"] = "value1"; | |
1096 message.data["key2"] = "value2"; | |
1097 message.sender_id = "sender"; | |
1098 wrapper_->GetGCMClient()->ReceiveMessage(kTestAppID1, message); | |
1099 wrapper_->gcm_app_handler()->WaitForNotification(); | |
1100 | |
1101 // Trigger an incoming message for the same app in another instance. | |
1102 GCMClient::IncomingMessage message2; | |
1103 message2.data["foo"] = "bar"; | |
1104 message2.sender_id = "sender"; | |
1105 wrapper2_->GetGCMClient()->ReceiveMessage(kTestAppID1, message2); | |
1106 wrapper2_->gcm_app_handler()->WaitForNotification(); | |
1107 | |
1108 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT, | |
1109 wrapper_->gcm_app_handler()->received_event()); | |
1110 EXPECT_EQ(kTestAppID1, wrapper_->gcm_app_handler()->app_id()); | |
1111 EXPECT_EQ(message.data, wrapper_->gcm_app_handler()->message().data); | |
1112 EXPECT_EQ("sender", wrapper_->gcm_app_handler()->message().sender_id); | |
1113 | |
1114 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT, | |
1115 wrapper2_->gcm_app_handler()->received_event()); | |
1116 EXPECT_EQ(kTestAppID1, wrapper2_->gcm_app_handler()->app_id()); | |
1117 EXPECT_EQ(message2.data, wrapper2_->gcm_app_handler()->message().data); | |
1118 EXPECT_EQ("sender", wrapper2_->gcm_app_handler()->message().sender_id); | |
1119 | |
1120 // Trigger another incoming message for a different app in another instance. | |
1121 GCMClient::IncomingMessage message3; | |
1122 message3.data["bar1"] = "foo1"; | |
1123 message3.data["bar2"] = "foo2"; | |
1124 message3.sender_id = "sender2"; | |
1125 wrapper2_->GetGCMClient()->ReceiveMessage(kTestAppID2, message3); | |
1126 wrapper2_->gcm_app_handler()->WaitForNotification(); | |
1127 | |
1128 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT, | |
1129 wrapper2_->gcm_app_handler()->received_event()); | |
1130 EXPECT_EQ(kTestAppID2, wrapper2_->gcm_app_handler()->app_id()); | |
1131 EXPECT_EQ(message3.data, wrapper2_->gcm_app_handler()->message().data); | |
1132 EXPECT_EQ("sender2", wrapper2_->gcm_app_handler()->message().sender_id); | |
1133 } | |
1134 | |
1135 // Test a set of GCM operations on multiple instances. | |
1136 // 1) Register 1 app in instance 1 and register 2 apps in instance 2; | |
1137 // 2) Send a message from instance 1; | |
1138 // 3) Receive a message to an app in instance 1 and receive a message for each | |
1139 // of the two apps in instance 2; | |
1140 // 4) Send a message for each of the two apps in instance 2; | |
1141 // 5) Sign out of instance 1. | |
1142 // 6) Register/send stops working for instance 1; | |
1143 // 7) The app in instance 2 can still receive these events; | |
1144 // 8) Sign into instance 1 with a different account. | |
1145 // 9) The message to the newly signed-in account will be routed. | |
1146 TEST_F(GCMServiceMultipleInstanceTest, Combined) { | |
1147 // Register an app. | |
1148 std::vector<std::string> sender_ids; | |
1149 sender_ids.push_back("sender1"); | |
1150 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
1151 | |
1152 // Register the same app in a different instance. | |
1153 std::vector<std::string> sender_ids2; | |
1154 sender_ids2.push_back("foo"); | |
1155 sender_ids2.push_back("bar"); | |
1156 wrapper2_->Register(kTestAppID1, sender_ids2, TestGCMServiceWrapper::WAIT); | |
1157 | |
1158 // Register a different app in a different instance. | |
1159 std::vector<std::string> sender_ids3; | |
1160 sender_ids3.push_back("sender1"); | |
1161 sender_ids3.push_back("sender2"); | |
1162 sender_ids3.push_back("sender3"); | |
1163 wrapper2_->Register(kTestAppID2, sender_ids3, TestGCMServiceWrapper::WAIT); | |
1164 | |
1165 EXPECT_EQ(GCMClientMock::GetRegistrationIdFromSenderIds(sender_ids), | |
1166 wrapper_->registration_id()); | |
1167 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->registration_result()); | |
1168 | |
1169 EXPECT_EQ(GCMClientMock::GetRegistrationIdFromSenderIds(sender_ids3), | |
1170 wrapper2_->registration_id()); | |
1171 EXPECT_EQ(GCMClient::SUCCESS, wrapper2_->registration_result()); | |
1172 | |
1173 // Send a message from one instance. | |
1174 GCMClient::OutgoingMessage out_message; | |
1175 out_message.id = "1"; | |
1176 out_message.data["out1"] = "out_data1"; | |
1177 out_message.data["out1_2"] = "out_data1_2"; | |
1178 wrapper_->Send(kTestAppID1, | |
1179 kUserID1, | |
1180 out_message, | |
1181 TestGCMServiceWrapper::WAIT); | |
1182 | |
1183 EXPECT_EQ(out_message.id, wrapper_->send_message_id()); | |
1184 EXPECT_EQ(GCMClient::SUCCESS, wrapper_->send_result()); | |
1185 | |
1186 // Trigger an incoming message for an app in one instance. | |
1187 GCMClient::IncomingMessage in_message; | |
1188 in_message.data["in1"] = "in_data1"; | |
1189 in_message.data["in1_2"] = "in_data1_2"; | |
1190 in_message.sender_id = "sender1"; | |
1191 wrapper_->GetGCMClient()->ReceiveMessage(kTestAppID1, in_message); | |
1192 wrapper_->gcm_app_handler()->WaitForNotification(); | |
1193 | |
1194 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT, | |
1195 wrapper_->gcm_app_handler()->received_event()); | |
1196 EXPECT_EQ(kTestAppID1, wrapper_->gcm_app_handler()->app_id()); | |
1197 EXPECT_EQ(in_message.data, wrapper_->gcm_app_handler()->message().data); | |
1198 | |
1199 // Trigger 2 incoming messages, one for each app respectively, in another | |
1200 // instance. | |
1201 GCMClient::IncomingMessage in_message2; | |
1202 in_message2.data["in2"] = "in_data2"; | |
1203 in_message2.sender_id = "sender3"; | |
1204 wrapper2_->GetGCMClient()->ReceiveMessage(kTestAppID2, in_message2); | |
1205 | |
1206 GCMClient::IncomingMessage in_message3; | |
1207 in_message3.data["in3"] = "in_data3"; | |
1208 in_message3.data["in3_2"] = "in_data3_2"; | |
1209 in_message3.sender_id = "foo"; | |
1210 wrapper2_->GetGCMClient()->ReceiveMessage(kTestAppID1, in_message3); | |
1211 | |
1212 wrapper2_->gcm_app_handler()->WaitForNotification(); | |
1213 | |
1214 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT, | |
1215 wrapper2_->gcm_app_handler()->received_event()); | |
1216 EXPECT_EQ(kTestAppID2, wrapper2_->gcm_app_handler()->app_id()); | |
1217 EXPECT_EQ(in_message2.data, wrapper2_->gcm_app_handler()->message().data); | |
1218 | |
1219 wrapper2_->gcm_app_handler()->WaitForNotification(); | |
1220 | |
1221 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT, | |
1222 wrapper2_->gcm_app_handler()->received_event()); | |
1223 EXPECT_EQ(kTestAppID1, wrapper2_->gcm_app_handler()->app_id()); | |
1224 EXPECT_EQ(in_message3.data, wrapper2_->gcm_app_handler()->message().data); | |
1225 | |
1226 // Send two messages, one for each app respectively, from another instance. | |
1227 GCMClient::OutgoingMessage out_message2; | |
1228 out_message2.id = "2"; | |
1229 out_message2.data["out2"] = "out_data2"; | |
1230 wrapper2_->Send(kTestAppID1, | |
1231 kUserID2, | |
1232 out_message2, | |
1233 TestGCMServiceWrapper::WAIT); | |
1234 | |
1235 GCMClient::OutgoingMessage out_message3; | |
1236 out_message3.id = "3"; | |
1237 out_message3.data["out3"] = "out_data3"; | |
1238 wrapper2_->Send(kTestAppID2, | |
1239 kUserID2, | |
1240 out_message3, | |
1241 TestGCMServiceWrapper::DO_NOT_WAIT); | |
1242 | |
1243 EXPECT_EQ(out_message2.id, wrapper2_->send_message_id()); | |
1244 EXPECT_EQ(GCMClient::SUCCESS, wrapper2_->send_result()); | |
1245 | |
1246 PumpIOLoop(); | |
1247 PumpUILoop(); | |
1248 | |
1249 EXPECT_EQ(out_message3.id, wrapper2_->send_message_id()); | |
1250 EXPECT_EQ(GCMClient::SUCCESS, wrapper2_->send_result()); | |
1251 | |
1252 // Sign out of one instance. | |
1253 wrapper_->SignOut(); | |
1254 | |
1255 // Register/send stops working for signed-out instance. | |
1256 wrapper_->Register(kTestAppID1, sender_ids, TestGCMServiceWrapper::WAIT); | |
1257 EXPECT_TRUE(wrapper_->registration_id().empty()); | |
1258 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, wrapper_->registration_result()); | |
1259 | |
1260 wrapper_->Send(kTestAppID2, | |
1261 kUserID2, | |
1262 out_message3, | |
1263 TestGCMServiceWrapper::WAIT); | |
1264 EXPECT_TRUE(wrapper_->send_message_id().empty()); | |
1265 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, wrapper_->send_result()); | |
1266 | |
1267 // Deleted messages event will go through for another signed-in instance. | |
1268 wrapper2_->GetGCMClient()->DeleteMessages(kTestAppID2); | |
1269 wrapper2_->gcm_app_handler()->WaitForNotification(); | |
1270 | |
1271 EXPECT_EQ(FakeGCMAppHandler::MESSAGES_DELETED_EVENT, | |
1272 wrapper2_->gcm_app_handler()->received_event()); | |
1273 EXPECT_EQ(kTestAppID2, wrapper2_->gcm_app_handler()->app_id()); | |
1274 | |
1275 // Send error event will go through for another signed-in instance. | |
1276 GCMClient::OutgoingMessage out_message4; | |
1277 out_message4.id = "1@error"; | |
1278 out_message4.data["out4"] = "out_data4"; | |
1279 wrapper2_->Send(kTestAppID1, | |
1280 kUserID1, | |
1281 out_message4, | |
1282 TestGCMServiceWrapper::WAIT); | |
1283 | |
1284 EXPECT_EQ(out_message4.id, wrapper2_->send_message_id()); | |
1285 EXPECT_EQ(GCMClient::SUCCESS, wrapper2_->send_result()); | |
1286 | |
1287 wrapper2_->gcm_app_handler()->WaitForNotification(); | |
1288 EXPECT_EQ(FakeGCMAppHandler::SEND_ERROR_EVENT, | |
1289 wrapper2_->gcm_app_handler()->received_event()); | |
1290 EXPECT_EQ(kTestAppID1, wrapper2_->gcm_app_handler()->app_id()); | |
1291 EXPECT_EQ(out_message4.id, | |
1292 wrapper2_->gcm_app_handler()->send_error_details().message_id); | |
1293 EXPECT_NE(GCMClient::SUCCESS, | |
1294 wrapper2_->gcm_app_handler()->send_error_details().result); | |
1295 EXPECT_EQ(out_message4.data, | |
1296 wrapper2_->gcm_app_handler()->send_error_details().additional_data); | |
1297 | |
1298 // Sign in with a different account. | |
1299 wrapper_->SignIn(kTestAccountID3); | |
1300 | |
1301 // Signing out cleared all registrations, so we need to register again. | |
1302 wrapper_->Register(kTestAppID1, | |
1303 ToSenderList("sender1"), | |
1304 TestGCMServiceWrapper::WAIT); | |
1305 | |
1306 // Incoming message will go through for the new signed-in account. | |
1307 GCMClient::IncomingMessage in_message5; | |
1308 in_message5.data["in5"] = "in_data5"; | |
1309 in_message5.sender_id = "sender1"; | |
1310 wrapper_->GetGCMClient()->ReceiveMessage(kTestAppID1, in_message5); | |
1311 | |
1312 wrapper_->gcm_app_handler()->WaitForNotification(); | |
1313 | |
1314 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT, | |
1315 wrapper_->gcm_app_handler()->received_event()); | |
1316 EXPECT_EQ(in_message5.data, wrapper_->gcm_app_handler()->message().data); | |
1317 } | |
1318 | |
1319 } // namespace gcm | |
OLD | NEW |