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