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 "content/browser/geofencing/geofencing_provider.h"
6 #include "content/browser/geofencing/geofencing_registration_delegate.h"
7 #include "content/browser/geofencing/geofencing_service.h"
8 #include "content/public/test/test_browser_thread_bundle.h"
9 #include "content/public/test/test_utils.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"
14 using blink::WebCircularGeofencingRegion
;
18 bool RegionsMatch(const WebCircularGeofencingRegion
& expected
,
19 const WebCircularGeofencingRegion
& arg
) {
20 return testing::Matches(expected
.latitude
)(arg
.latitude
) &&
21 testing::Matches(expected
.longitude
)(arg
.longitude
) &&
22 testing::Matches(expected
.radius
)(arg
.radius
);
29 class MockGeofencingRegistrationDelegate
30 : public GeofencingRegistrationDelegate
{
32 MOCK_METHOD2(RegistrationFinished
,
33 void(int64 geofencing_registration_id
, GeofencingStatus status
));
36 class MockGeofencingProvider
: public GeofencingProvider
{
38 MOCK_METHOD3(RegisterRegion
,
39 void(int64 geofencing_registration_id
,
40 const blink::WebCircularGeofencingRegion
& region
,
41 const StatusCallback
& callback
));
42 MOCK_METHOD1(UnregisterRegion
, void(int64 geofencing_registration_id
));
45 ACTION_P(QuitRunner
, runner
) {
49 ACTION_P(SaveRegistrationId
, geofencing_registration_id
) {
50 *geofencing_registration_id
= arg0
;
53 ACTION_P(SaveStatusCallback
, callback
) {
57 MATCHER_P(WebCircularGeofencingRegionEq
, expected
, "") {
58 return RegionsMatch(expected
, arg
);
61 class GeofencingServiceTest
: public testing::Test
{
63 GeofencingServiceTest() : service_(nullptr) {
64 test_region_
.latitude
= 37.421999;
65 test_region_
.longitude
= -122.084015;
66 test_region_
.radius
= 100;
69 virtual void SetUp() { service_
= new GeofencingServiceImpl(); }
71 virtual void TearDown() { delete service_
; }
73 void SetProviderForTests() {
74 provider_
= new MockGeofencingProvider();
75 service_
->SetProviderForTesting(make_scoped_ptr(provider_
));
78 int RegistrationCount() { return service_
->RegistrationCountForTesting(); }
80 int64
RegisterRegionSync(const WebCircularGeofencingRegion
& region
,
81 GeofencingStatus provider_status
) {
82 scoped_refptr
<MessageLoopRunner
> runner(new MessageLoopRunner());
84 // The registration ID that is passed to the provider.
85 int64 provider_registration_id
= -1;
86 // The callback that is passed to the provider.
87 GeofencingProvider::StatusCallback callback
;
92 testing::_
, WebCircularGeofencingRegionEq(region
), testing::_
))
93 .WillOnce(testing::DoAll(SaveRegistrationId(&provider_registration_id
),
94 SaveStatusCallback(&callback
)));
96 int64 geofencing_registration_id
=
97 service_
->RegisterRegion(region
, &delegate_
);
99 // Service should have synchronously called the provider.
100 CHECK(!callback
.is_null());
101 CHECK(provider_registration_id
== geofencing_registration_id
);
103 // Finish up registration by calling the callback and waiting for the
104 // delegate to be called.
107 RegistrationFinished(geofencing_registration_id
, provider_status
))
108 .WillOnce(QuitRunner(runner
));
109 callback
.Run(provider_status
);
111 return geofencing_registration_id
;
115 TestBrowserThreadBundle threads_
;
116 GeofencingServiceImpl
* service_
;
117 MockGeofencingProvider
* provider_
;
118 MockGeofencingRegistrationDelegate delegate_
;
120 WebCircularGeofencingRegion test_region_
;
123 TEST_F(GeofencingServiceTest
, RegisterRegion_NoProvider
) {
124 scoped_refptr
<MessageLoopRunner
> runner(new MessageLoopRunner());
125 int64 geofencing_registration_id
=
126 service_
->RegisterRegion(test_region_
, &delegate_
);
127 EXPECT_CALL(delegate_
,
128 RegistrationFinished(
129 geofencing_registration_id
,
130 GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE
))
131 .WillOnce(QuitRunner(runner
));
133 EXPECT_EQ(0, RegistrationCount());
136 TEST_F(GeofencingServiceTest
, RegisterRegion_FailsInProvider
) {
137 SetProviderForTests();
138 RegisterRegionSync(test_region_
, GEOFENCING_STATUS_ERROR
);
139 EXPECT_EQ(0, RegistrationCount());
142 TEST_F(GeofencingServiceTest
, RegisterRegion_SucceedsInProvider
) {
143 SetProviderForTests();
144 RegisterRegionSync(test_region_
, GEOFENCING_STATUS_OK
);
145 EXPECT_EQ(1, RegistrationCount());
148 TEST_F(GeofencingServiceTest
, UnregisterRegion_AfterRegistration
) {
149 SetProviderForTests();
150 int geofencing_registration_id
=
151 RegisterRegionSync(test_region_
, GEOFENCING_STATUS_OK
);
152 EXPECT_EQ(1, RegistrationCount());
154 EXPECT_CALL(*provider_
, UnregisterRegion(geofencing_registration_id
));
155 service_
->UnregisterRegion(geofencing_registration_id
);
156 EXPECT_EQ(0, RegistrationCount());
159 TEST_F(GeofencingServiceTest
, UnregisterRegion_DuringSuccesfullRegistration
) {
160 SetProviderForTests();
161 scoped_refptr
<MessageLoopRunner
> runner(new MessageLoopRunner());
163 // The callback that is passed to the provider.
164 GeofencingProvider::StatusCallback callback
;
169 testing::_
, WebCircularGeofencingRegionEq(test_region_
), testing::_
))
170 .WillOnce(SaveStatusCallback(&callback
));
172 int64 geofencing_registration_id
=
173 service_
->RegisterRegion(test_region_
, &delegate_
);
175 // Service should have synchronously called the provider.
176 CHECK(!callback
.is_null());
178 // Call unregister before registration is finished.
179 service_
->UnregisterRegion(geofencing_registration_id
);
181 // Finish up registration by calling the callback and waiting for the
182 // provider to be called. The delegate should not be called in this case.
183 EXPECT_CALL(delegate_
, RegistrationFinished(testing::_
, testing::_
)).Times(0);
184 EXPECT_CALL(*provider_
, UnregisterRegion(geofencing_registration_id
))
185 .WillOnce(QuitRunner(runner
));
186 callback
.Run(GEOFENCING_STATUS_OK
);
188 EXPECT_EQ(0, RegistrationCount());
191 } // namespace content