1 // Copyright 2015 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.
5 #include "components/gcm_driver/instance_id/instance_id_driver.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/strings/string_util.h"
12 #include "components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h"
13 #include "components/gcm_driver/instance_id/instance_id.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace instance_id
{
20 const char kTestAppID1
[] = "TestApp1";
21 const char kTestAppID2
[] = "TestApp2";
22 const char kAuthorizedEntity1
[] = "Sender 1";
23 const char kAuthorizedEntity2
[] = "Sender 2";
24 const char kScope1
[] = "GCM1";
25 const char kScope2
[] = "FooBar";
27 bool VerifyInstanceID(const std::string
& str
) {
29 if (str
.length() != static_cast<size_t>(
30 std::ceil(InstanceID::kInstanceIDByteLength
* 8 / 6.0)))
33 // Checks if it is URL-safe base64 encoded.
35 if (!base::IsAsciiAlpha(ch
) && !base::IsAsciiDigit(ch
) &&
36 ch
!= '_' && ch
!= '-')
44 class InstanceIDDriverTest
: public testing::Test
{
46 InstanceIDDriverTest();
47 ~InstanceIDDriverTest() override
;
50 void SetUp() override
;
52 void WaitForAsyncOperation();
54 // Recreates InstanceIDDriver to simulate restart.
55 void RecreateInstanceIDDriver();
57 // Sync wrappers for async version.
58 std::string
GetID(InstanceID
* instance_id
);
59 base::Time
GetCreationTime(InstanceID
* instance_id
);
60 InstanceID::Result
DeleteID(InstanceID
* instance_id
);
62 InstanceID
* instance_id
,
63 const std::string
& authorized_entity
,
64 const std::string
& scope
,
65 const std::map
<std::string
, std::string
>& options
);
66 InstanceID::Result
DeleteToken(
67 InstanceID
* instance_id
,
68 const std::string
& authorized_entity
,
69 const std::string
& scope
);
71 InstanceIDDriver
* driver() const { return driver_
.get(); }
74 void GetIDCompleted(const std::string
& id
);
75 void GetCreationTimeCompleted(const base::Time
& creation_time
);
76 void DeleteIDCompleted(InstanceID::Result result
);
77 void GetTokenCompleted(const std::string
& token
, InstanceID::Result result
);
78 void DeleteTokenCompleted(InstanceID::Result result
);
80 base::MessageLoopForUI message_loop_
;
81 scoped_ptr
<FakeGCMDriverForInstanceID
> gcm_driver_
;
82 scoped_ptr
<InstanceIDDriver
> driver_
;
85 base::Time creation_time_
;
87 InstanceID::Result result_
;
89 bool async_operation_completed_
;
90 base::Closure async_operation_completed_callback_
;
92 DISALLOW_COPY_AND_ASSIGN(InstanceIDDriverTest
);
95 InstanceIDDriverTest::InstanceIDDriverTest()
96 : result_(InstanceID::UNKNOWN_ERROR
),
97 async_operation_completed_(false) {
100 InstanceIDDriverTest::~InstanceIDDriverTest() {
103 void InstanceIDDriverTest::SetUp() {
104 gcm_driver_
.reset(new FakeGCMDriverForInstanceID
);
105 RecreateInstanceIDDriver();
108 void InstanceIDDriverTest::RecreateInstanceIDDriver() {
109 driver_
.reset(new InstanceIDDriver(gcm_driver_
.get()));
112 void InstanceIDDriverTest::WaitForAsyncOperation() {
113 // No need to wait if async operation is not needed.
114 if (async_operation_completed_
)
116 base::RunLoop run_loop
;
117 async_operation_completed_callback_
= run_loop
.QuitClosure();
121 std::string
InstanceIDDriverTest::GetID(InstanceID
* instance_id
) {
122 async_operation_completed_
= false;
124 instance_id
->GetID(base::Bind(&InstanceIDDriverTest::GetIDCompleted
,
125 base::Unretained(this)));
126 WaitForAsyncOperation();
130 base::Time
InstanceIDDriverTest::GetCreationTime(InstanceID
* instance_id
) {
131 async_operation_completed_
= false;
132 creation_time_
= base::Time();
133 instance_id
->GetCreationTime(
134 base::Bind(&InstanceIDDriverTest::GetCreationTimeCompleted
,
135 base::Unretained(this)));
136 WaitForAsyncOperation();
137 return creation_time_
;
140 InstanceID::Result
InstanceIDDriverTest::DeleteID(InstanceID
* instance_id
) {
141 async_operation_completed_
= false;
142 result_
= InstanceID::UNKNOWN_ERROR
;;
143 instance_id
->DeleteID(base::Bind(&InstanceIDDriverTest::DeleteIDCompleted
,
144 base::Unretained(this)));
145 WaitForAsyncOperation();
149 std::string
InstanceIDDriverTest::GetToken(
150 InstanceID
* instance_id
,
151 const std::string
& authorized_entity
,
152 const std::string
& scope
,
153 const std::map
<std::string
, std::string
>& options
) {
154 async_operation_completed_
= false;
156 result_
= InstanceID::UNKNOWN_ERROR
;;
157 instance_id
->GetToken(
161 base::Bind(&InstanceIDDriverTest::GetTokenCompleted
,
162 base::Unretained(this)));
163 WaitForAsyncOperation();
167 InstanceID::Result
InstanceIDDriverTest::DeleteToken(
168 InstanceID
* instance_id
,
169 const std::string
& authorized_entity
,
170 const std::string
& scope
) {
171 async_operation_completed_
= false;
172 result_
= InstanceID::UNKNOWN_ERROR
;;
173 instance_id
->DeleteToken(
176 base::Bind(&InstanceIDDriverTest::DeleteTokenCompleted
,
177 base::Unretained(this)));
178 WaitForAsyncOperation();
182 void InstanceIDDriverTest::GetIDCompleted(const std::string
& id
) {
183 DCHECK(!async_operation_completed_
);
184 async_operation_completed_
= true;
186 if (!async_operation_completed_callback_
.is_null())
187 async_operation_completed_callback_
.Run();
190 void InstanceIDDriverTest::GetCreationTimeCompleted(
191 const base::Time
& creation_time
) {
192 DCHECK(!async_operation_completed_
);
193 async_operation_completed_
= true;
194 creation_time_
= creation_time
;
195 if (!async_operation_completed_callback_
.is_null())
196 async_operation_completed_callback_
.Run();
199 void InstanceIDDriverTest::DeleteIDCompleted(InstanceID::Result result
) {
200 DCHECK(!async_operation_completed_
);
201 async_operation_completed_
= true;
203 if (!async_operation_completed_callback_
.is_null())
204 async_operation_completed_callback_
.Run();
207 void InstanceIDDriverTest::GetTokenCompleted(
208 const std::string
& token
, InstanceID::Result result
){
209 DCHECK(!async_operation_completed_
);
210 async_operation_completed_
= true;
213 if (!async_operation_completed_callback_
.is_null())
214 async_operation_completed_callback_
.Run();
217 void InstanceIDDriverTest::DeleteTokenCompleted(InstanceID::Result result
) {
218 DCHECK(!async_operation_completed_
);
219 async_operation_completed_
= true;
221 if (!async_operation_completed_callback_
.is_null())
222 async_operation_completed_callback_
.Run();
225 TEST_F(InstanceIDDriverTest
, GetAndRemoveInstanceID
) {
226 EXPECT_FALSE(driver()->ExistsInstanceID(kTestAppID1
));
228 InstanceID
* instance_id
= driver()->GetInstanceID(kTestAppID1
);
229 EXPECT_TRUE(instance_id
);
230 EXPECT_TRUE(driver()->ExistsInstanceID(kTestAppID1
));
232 driver()->RemoveInstanceID(kTestAppID1
);
233 EXPECT_FALSE(driver()->ExistsInstanceID(kTestAppID1
));
236 TEST_F(InstanceIDDriverTest
, NewID
) {
237 // Creation time should not be set when the ID is not created.
238 InstanceID
* instance_id1
= driver()->GetInstanceID(kTestAppID1
);
239 EXPECT_TRUE(GetCreationTime(instance_id1
).is_null());
241 // New ID is generated for the first time.
242 std::string id1
= GetID(instance_id1
);
243 EXPECT_TRUE(VerifyInstanceID(id1
));
244 base::Time creation_time
= GetCreationTime(instance_id1
);
245 EXPECT_FALSE(creation_time
.is_null());
247 // Same ID is returned for the same app.
248 EXPECT_EQ(id1
, GetID(instance_id1
));
249 EXPECT_EQ(creation_time
, GetCreationTime(instance_id1
));
251 // New ID is generated for another app.
252 InstanceID
* instance_id2
= driver()->GetInstanceID(kTestAppID2
);
253 std::string id2
= GetID(instance_id2
);
254 EXPECT_TRUE(VerifyInstanceID(id2
));
256 EXPECT_FALSE(GetCreationTime(instance_id2
).is_null());
259 TEST_F(InstanceIDDriverTest
, PersistID
) {
260 InstanceID
* instance_id
= driver()->GetInstanceID(kTestAppID1
);
262 // Create the ID for the first time. The ID and creation time should be saved
264 std::string id
= GetID(instance_id
);
265 EXPECT_FALSE(id
.empty());
266 base::Time creation_time
= GetCreationTime(instance_id
);
267 EXPECT_FALSE(creation_time
.is_null());
269 // Simulate restart by recreating InstanceIDDriver. Same ID and creation time
270 // should be expected.
271 RecreateInstanceIDDriver();
272 instance_id
= driver()->GetInstanceID(kTestAppID1
);
273 EXPECT_EQ(creation_time
, GetCreationTime(instance_id
));
274 EXPECT_EQ(id
, GetID(instance_id
));
276 // Delete the ID. The ID and creation time should be removed from the store.
277 EXPECT_EQ(InstanceID::SUCCESS
, DeleteID(instance_id
));
278 EXPECT_TRUE(GetCreationTime(instance_id
).is_null());
280 // Simulate restart by recreating InstanceIDDriver. Different ID should be
282 // Note that we do not check for different creation time since the test might
283 // be run at a very fast server.
284 RecreateInstanceIDDriver();
285 instance_id
= driver()->GetInstanceID(kTestAppID1
);
286 EXPECT_NE(id
, GetID(instance_id
));
289 TEST_F(InstanceIDDriverTest
, DeleteID
) {
290 InstanceID
* instance_id
= driver()->GetInstanceID(kTestAppID1
);
291 std::string id1
= GetID(instance_id
);
292 EXPECT_FALSE(id1
.empty());
293 EXPECT_FALSE(GetCreationTime(instance_id
).is_null());
295 // New ID will be generated from GetID after calling DeleteID.
296 EXPECT_EQ(InstanceID::SUCCESS
, DeleteID(instance_id
));
297 EXPECT_TRUE(GetCreationTime(instance_id
).is_null());
299 std::string id2
= GetID(instance_id
);
300 EXPECT_FALSE(id2
.empty());
302 EXPECT_FALSE(GetCreationTime(instance_id
).is_null());
305 TEST_F(InstanceIDDriverTest
, GetToken
) {
306 InstanceID
* instance_id
= driver()->GetInstanceID(kTestAppID1
);
307 std::map
<std::string
, std::string
> options
;
309 GetToken(instance_id
, kAuthorizedEntity1
, kScope1
, options
);
310 EXPECT_FALSE(token1
.empty());
312 // Same token is returned for same authorized entity and scope.
314 GetToken(instance_id
, kAuthorizedEntity1
, kScope1
, options
));
316 // Different token is returned for different authorized entity or scope.
318 GetToken(instance_id
, kAuthorizedEntity1
, kScope2
, options
);
319 EXPECT_FALSE(token2
.empty());
320 EXPECT_NE(token1
, token2
);
323 GetToken(instance_id
, kAuthorizedEntity2
, kScope1
, options
);
324 EXPECT_FALSE(token3
.empty());
325 EXPECT_NE(token1
, token3
);
326 EXPECT_NE(token2
, token3
);
329 TEST_F(InstanceIDDriverTest
, DeleteToken
) {
330 InstanceID
* instance_id
= driver()->GetInstanceID(kTestAppID1
);
331 std::map
<std::string
, std::string
> options
;
335 GetToken(instance_id
, kAuthorizedEntity1
, kScope1
, options
);
336 EXPECT_FALSE(token1
.empty());
338 GetToken(instance_id
, kAuthorizedEntity2
, kScope1
, options
);
339 EXPECT_FALSE(token1
.empty());
340 EXPECT_NE(token1
, token2
);
342 // Different token is returned for same authorized entity and scope after
344 EXPECT_EQ(InstanceID::SUCCESS
,
345 DeleteToken(instance_id
, kAuthorizedEntity1
, kScope1
));
346 std::string new_token1
=
347 GetToken(instance_id
, kAuthorizedEntity1
, kScope2
, options
);
348 EXPECT_FALSE(new_token1
.empty());
349 EXPECT_NE(token1
, new_token1
);
351 // The other token is not affected by the deletion.
353 GetToken(instance_id
, kAuthorizedEntity2
, kScope1
, options
));