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.
5 #include "base/callback.h"
6 #include "base/message_loop/message_loop.h"
7 #include "content/browser/geofencing/geofencing_manager.h"
8 #include "content/browser/geofencing/geofencing_service.h"
9 #include "content/browser/service_worker/service_worker_context_wrapper.h"
10 #include "content/public/test/test_browser_thread_bundle.h"
11 #include "content/public/test/test_utils.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"
16 using blink::WebCircularGeofencingRegion
;
17 typedef std::map
<std::string
, WebCircularGeofencingRegion
> RegionMap
;
21 static const char* kTestRegionId
= "region-id";
22 static const int64 kTestServiceWorkerRegistrationId
= 123;
23 static const int64 kTestServiceWorkerRegistrationId2
= 456;
24 static const int64 kTestGeofencingRegistrationId
= 42;
25 static const int64 kTestGeofencingRegistrationId2
= 43;
27 bool RegionsMatch(const WebCircularGeofencingRegion
& expected
,
28 const WebCircularGeofencingRegion
& arg
) {
29 return testing::Matches(expected
.latitude
)(arg
.latitude
) &&
30 testing::Matches(expected
.longitude
)(arg
.longitude
) &&
31 testing::Matches(expected
.radius
)(arg
.radius
);
37 class TestGeofencingService
: public GeofencingService
{
39 MOCK_METHOD0(IsServiceAvailable
, bool());
40 MOCK_METHOD2(RegisterRegion
,
41 int64(const WebCircularGeofencingRegion
& region
,
42 GeofencingRegistrationDelegate
* delegate
));
43 MOCK_METHOD1(UnregisterRegion
, void(int64 geofencing_registration_id
));
46 ACTION_P(SaveDelegate
, delegate
) {
50 ACTION_P(QuitRunner
, runner
) {
54 MATCHER_P(WebCircularGeofencingRegionEq
, expected
, "") {
55 return RegionsMatch(expected
, arg
);
60 StatusCatcher() : was_called_(false), runner_(new MessageLoopRunner()) {}
62 void Done(GeofencingStatus status
) {
69 GeofencingStatus
Wait() {
77 GeofencingStatus result_
;
78 scoped_refptr
<MessageLoopRunner
> runner_
;
81 class GeofencingManagerTest
: public testing::Test
{
83 GeofencingManagerTest() : service_(nullptr) {
84 test_region_
.latitude
= 37.421999;
85 test_region_
.longitude
= -122.084015;
86 test_region_
.radius
= 100;
87 expected_regions_
[kTestRegionId
] = test_region_
;
90 virtual void SetUp() {
91 service_
= new TestGeofencingService();
92 ON_CALL(*service_
, IsServiceAvailable())
93 .WillByDefault(testing::Return(false));
94 manager_
= new GeofencingManager(nullptr /* ServiceWorkerContextWrapper */);
95 manager_
->SetServiceForTesting(service_
);
98 virtual void TearDown() {
104 void SetHasProviderForTests() {
105 ON_CALL(*service_
, IsServiceAvailable())
106 .WillByDefault(testing::Return(true));
109 GeofencingStatus
RegisterRegionSync(
110 int64 service_worker_registration_id
,
111 const std::string
& id
,
112 const WebCircularGeofencingRegion
& region
) {
113 StatusCatcher result
;
114 manager_
->RegisterRegion(
115 service_worker_registration_id
,
118 base::Bind(&StatusCatcher::Done
, base::Unretained(&result
)));
119 return result
.Wait();
122 GeofencingStatus
RegisterRegionSyncWithServiceResult(
123 int64 service_worker_registration_id
,
124 const std::string
& id
,
125 const WebCircularGeofencingRegion
& region
,
126 GeofencingStatus service_status
,
127 int64 geofencing_registration_id
) {
128 StatusCatcher result
;
129 GeofencingRegistrationDelegate
* delegate
= 0;
132 RegisterRegion(WebCircularGeofencingRegionEq(region
), testing::_
))
133 .WillOnce(testing::DoAll(SaveDelegate(&delegate
),
134 testing::Return(geofencing_registration_id
)));
135 manager_
->RegisterRegion(
136 service_worker_registration_id
,
139 base::Bind(&StatusCatcher::Done
, base::Unretained(&result
)));
141 delegate
->RegistrationFinished(geofencing_registration_id
, service_status
);
142 return result
.Wait();
145 GeofencingStatus
UnregisterRegionSync(int64 service_worker_registration_id
,
146 const std::string
& id
,
147 bool should_call_service
,
148 int64 geofencing_registration_id
= 0) {
149 StatusCatcher result
;
150 if (should_call_service
) {
151 EXPECT_CALL(*service_
, UnregisterRegion(geofencing_registration_id
));
153 manager_
->UnregisterRegion(
154 service_worker_registration_id
,
156 base::Bind(&StatusCatcher::Done
, base::Unretained(&result
)));
157 return result
.Wait();
160 void VerifyRegions(int64 service_worker_registration_id
,
161 const RegionMap
& expected_regions
) {
163 EXPECT_EQ(GEOFENCING_STATUS_OK
,
164 manager_
->GetRegisteredRegions(service_worker_registration_id
,
166 EXPECT_EQ(expected_regions
.size(), regions
.size());
167 for (RegionMap::const_iterator it
= expected_regions
.begin();
168 it
!= expected_regions
.end();
170 EXPECT_THAT(regions
[it
->first
],
171 WebCircularGeofencingRegionEq(it
->second
));
176 TestBrowserThreadBundle threads_
;
177 TestGeofencingService
* service_
;
178 scoped_refptr
<GeofencingManager
> manager_
;
180 WebCircularGeofencingRegion test_region_
;
181 RegionMap expected_regions_
;
184 TEST_F(GeofencingManagerTest
, RegisterRegion_NoService
) {
185 EXPECT_EQ(GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE
,
187 kTestServiceWorkerRegistrationId
, kTestRegionId
, test_region_
));
190 TEST_F(GeofencingManagerTest
, UnregisterRegion_NoService
) {
191 EXPECT_EQ(GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE
,
192 UnregisterRegionSync(
193 kTestServiceWorkerRegistrationId
, kTestRegionId
, false));
196 TEST_F(GeofencingManagerTest
, GetRegisteredRegions_NoService
) {
198 EXPECT_EQ(GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE
,
199 manager_
->GetRegisteredRegions(kTestServiceWorkerRegistrationId
,
201 EXPECT_TRUE(regions
.empty());
204 TEST_F(GeofencingManagerTest
, RegisterRegion_FailsInService
) {
205 SetHasProviderForTests();
207 GEOFENCING_STATUS_ERROR
,
208 RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId
,
211 GEOFENCING_STATUS_ERROR
,
215 TEST_F(GeofencingManagerTest
, RegisterRegion_SucceedsInService
) {
216 SetHasProviderForTests();
218 GEOFENCING_STATUS_OK
,
219 RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId
,
222 GEOFENCING_STATUS_OK
,
223 kTestGeofencingRegistrationId
));
224 VerifyRegions(kTestServiceWorkerRegistrationId
, expected_regions_
);
227 TEST_F(GeofencingManagerTest
, RegisterRegion_AlreadyRegistered
) {
228 SetHasProviderForTests();
230 GEOFENCING_STATUS_OK
,
231 RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId
,
234 GEOFENCING_STATUS_OK
,
235 kTestGeofencingRegistrationId
));
236 VerifyRegions(kTestServiceWorkerRegistrationId
, expected_regions_
);
238 WebCircularGeofencingRegion region2
;
239 region2
.latitude
= 43.2;
240 region2
.longitude
= 1.45;
241 region2
.radius
= 8.5;
242 EXPECT_EQ(GEOFENCING_STATUS_ERROR
,
244 kTestServiceWorkerRegistrationId
, kTestRegionId
, region2
));
245 VerifyRegions(kTestServiceWorkerRegistrationId
, expected_regions_
);
248 TEST_F(GeofencingManagerTest
, UnregisterRegion_NotRegistered
) {
249 SetHasProviderForTests();
250 EXPECT_EQ(GEOFENCING_STATUS_UNREGISTRATION_FAILED_NOT_REGISTERED
,
251 UnregisterRegionSync(
252 kTestServiceWorkerRegistrationId
, kTestRegionId
, false));
255 TEST_F(GeofencingManagerTest
, UnregisterRegion_Success
) {
256 SetHasProviderForTests();
259 GEOFENCING_STATUS_OK
,
260 RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId
,
263 GEOFENCING_STATUS_OK
,
264 kTestGeofencingRegistrationId
));
266 EXPECT_EQ(GEOFENCING_STATUS_OK
,
267 UnregisterRegionSync(kTestServiceWorkerRegistrationId
,
270 kTestGeofencingRegistrationId
));
271 VerifyRegions(kTestServiceWorkerRegistrationId
, RegionMap());
274 TEST_F(GeofencingManagerTest
, GetRegisteredRegions_RegistrationInProgress
) {
275 SetHasProviderForTests();
276 StatusCatcher result
;
277 GeofencingRegistrationDelegate
* delegate
= nullptr;
281 RegisterRegion(WebCircularGeofencingRegionEq(test_region_
), testing::_
))
282 .WillOnce(testing::DoAll(SaveDelegate(&delegate
),
283 testing::Return(kTestGeofencingRegistrationId
)));
284 manager_
->RegisterRegion(
285 kTestServiceWorkerRegistrationId
,
288 base::Bind(&StatusCatcher::Done
, base::Unretained(&result
)));
290 // At this point the manager should have tried registering the region with
291 // the service, resulting in |delegate| being set. Until the callback is
292 // called the registration is not complete though.
293 EXPECT_NE(delegate
, nullptr);
294 VerifyRegions(kTestServiceWorkerRegistrationId
, RegionMap());
296 // Now call the callback, and verify the registration completed succesfully.
297 delegate
->RegistrationFinished(kTestGeofencingRegistrationId
,
298 GEOFENCING_STATUS_OK
);
299 EXPECT_EQ(GEOFENCING_STATUS_OK
, result
.Wait());
300 VerifyRegions(kTestServiceWorkerRegistrationId
, expected_regions_
);
303 TEST_F(GeofencingManagerTest
, UnregisterRegion_RegistrationInProgress
) {
304 SetHasProviderForTests();
305 StatusCatcher result
;
306 GeofencingRegistrationDelegate
* delegate
= nullptr;
310 RegisterRegion(WebCircularGeofencingRegionEq(test_region_
), testing::_
))
311 .WillOnce(testing::DoAll(SaveDelegate(&delegate
),
312 testing::Return(kTestGeofencingRegistrationId
)));
313 manager_
->RegisterRegion(
314 kTestServiceWorkerRegistrationId
,
317 base::Bind(&StatusCatcher::Done
, base::Unretained(&result
)));
319 // At this point the manager should have tried registering the region with
320 // the service, resulting in |delegate| being set. Until the callback is
321 // called the registration is not complete though.
322 EXPECT_NE(delegate
, nullptr);
324 EXPECT_EQ(GEOFENCING_STATUS_UNREGISTRATION_FAILED_NOT_REGISTERED
,
325 UnregisterRegionSync(
326 kTestServiceWorkerRegistrationId
, kTestRegionId
, false));
329 TEST_F(GeofencingManagerTest
, GetRegisteredRegions_NoRegions
) {
330 SetHasProviderForTests();
331 VerifyRegions(kTestServiceWorkerRegistrationId
, RegionMap());
334 TEST_F(GeofencingManagerTest
, RegisterRegion_SeparateServiceWorkers
) {
335 SetHasProviderForTests();
338 GEOFENCING_STATUS_OK
,
339 RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId
,
342 GEOFENCING_STATUS_OK
,
343 kTestGeofencingRegistrationId
));
345 VerifyRegions(kTestServiceWorkerRegistrationId
, expected_regions_
);
346 VerifyRegions(kTestServiceWorkerRegistrationId2
, RegionMap());
349 GEOFENCING_STATUS_OK
,
350 RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId2
,
353 GEOFENCING_STATUS_OK
,
354 kTestGeofencingRegistrationId2
));
356 VerifyRegions(kTestServiceWorkerRegistrationId
, expected_regions_
);
357 VerifyRegions(kTestServiceWorkerRegistrationId2
, expected_regions_
);
360 TEST_F(GeofencingManagerTest
, UnregisterRegion_SeparateServiceWorkers
) {
361 SetHasProviderForTests();
364 GEOFENCING_STATUS_OK
,
365 RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId
,
368 GEOFENCING_STATUS_OK
,
369 kTestGeofencingRegistrationId
));
371 GEOFENCING_STATUS_OK
,
372 RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId2
,
375 GEOFENCING_STATUS_OK
,
376 kTestGeofencingRegistrationId2
));
378 EXPECT_EQ(GEOFENCING_STATUS_OK
,
379 UnregisterRegionSync(kTestServiceWorkerRegistrationId
,
382 kTestGeofencingRegistrationId
));
384 VerifyRegions(kTestServiceWorkerRegistrationId
, RegionMap());
385 VerifyRegions(kTestServiceWorkerRegistrationId2
, expected_regions_
);
387 EXPECT_EQ(GEOFENCING_STATUS_OK
,
388 UnregisterRegionSync(kTestServiceWorkerRegistrationId2
,
391 kTestGeofencingRegistrationId2
));
393 VerifyRegions(kTestServiceWorkerRegistrationId
, RegionMap());
394 VerifyRegions(kTestServiceWorkerRegistrationId2
, RegionMap());
397 TEST_F(GeofencingManagerTest
, ShutdownCleansRegistrations
) {
398 SetHasProviderForTests();
399 scoped_refptr
<MessageLoopRunner
> runner(new MessageLoopRunner());
401 GEOFENCING_STATUS_OK
,
402 RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId
,
405 GEOFENCING_STATUS_OK
,
406 kTestGeofencingRegistrationId
));
408 EXPECT_CALL(*service_
, UnregisterRegion(kTestGeofencingRegistrationId
))
409 .WillOnce(QuitRunner(runner
));
410 manager_
->Shutdown();
414 } // namespace content