1 // Copyright (c) 2012 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.
10 #include "base/compiler_specific.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop.h"
14 #include "base/time.h"
15 #include "content/browser/geolocation/win7_location_api_win.h"
16 #include "content/public/common/geoposition.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
21 using testing::AtLeast
;
22 using testing::DoDefault
;
23 using testing::Invoke
;
24 using testing::NiceMock
;
25 using testing::Return
;
29 class MockLatLongReport
: public ILatLongReport
{
31 MockLatLongReport() : ref_count_(1) {
32 ON_CALL(*this, GetAltitude(_
))
33 .WillByDefault(Invoke(this, &MockLatLongReport::GetAltitudeValid
));
34 ON_CALL(*this, GetAltitudeError(_
))
35 .WillByDefault(Invoke(this,
36 &MockLatLongReport::GetAltitudeErrorValid
));
37 ON_CALL(*this, GetErrorRadius(_
))
38 .WillByDefault(Invoke(this, &MockLatLongReport::GetErrorRadiusValid
));
39 ON_CALL(*this, GetLatitude(_
))
40 .WillByDefault(Invoke(this, &MockLatLongReport::GetLatitudeValid
));
41 ON_CALL(*this, GetLongitude(_
))
42 .WillByDefault(Invoke(this, &MockLatLongReport::GetLongitudeValid
));
43 ON_CALL(*this, GetValue(_
, _
))
44 .WillByDefault(Invoke(this, &MockLatLongReport::GetValueValid
));
45 ON_CALL(*this, Release())
46 .WillByDefault(Invoke(this, &MockLatLongReport::ReleaseInternal
));
47 ON_CALL(*this, AddRef())
48 .WillByDefault(Invoke(this, &MockLatLongReport::AddRefInternal
));
52 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
55 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
58 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
61 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
64 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
68 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
71 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
73 HRESULT(SYSTEMTIME
*));
74 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
76 HRESULT(REFPROPERTYKEY
, PROPVARIANT
*));
78 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
80 HRESULT(REFIID
, void**));
81 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
84 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
88 HRESULT
GetAltitudeValid(DOUBLE
* altitude
) {
92 HRESULT
GetAltitudeErrorValid(DOUBLE
* altitude_error
) {
93 *altitude_error
= 10.0;
96 HRESULT
GetErrorRadiusValid(DOUBLE
* error
) {
100 HRESULT
GetLatitudeValid(DOUBLE
* latitude
) {
104 HRESULT
GetLongitudeValid(DOUBLE
* longitude
) {
108 HRESULT
GetValueValid(REFPROPERTYKEY prop_key
, PROPVARIANT
* prop
) {
114 ~MockLatLongReport() {}
116 ULONG
AddRefInternal() {
117 return InterlockedIncrement(&ref_count_
);
119 ULONG
ReleaseInternal() {
120 LONG new_ref_count
= InterlockedDecrement(&ref_count_
);
121 if (0 == new_ref_count
)
123 return new_ref_count
;
129 class MockReport
: public ILocationReport
{
131 MockReport() : ref_count_(1) {
132 mock_lat_long_report_
=
133 new MockLatLongReport();
134 ON_CALL(*this, QueryInterface(_
, _
))
135 .WillByDefault(Invoke(this, &MockReport::QueryInterfaceValid
));
136 ON_CALL(*this, Release())
137 .WillByDefault(Invoke(this, &MockReport::ReleaseInternal
));
138 ON_CALL(*this, AddRef())
139 .WillByDefault(Invoke(this, &MockReport::AddRefInternal
));
143 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
145 HRESULT(SENSOR_ID
*));
146 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
148 HRESULT(SYSTEMTIME
*));
149 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
151 HRESULT(REFPROPERTYKEY
, PROPVARIANT
*));
153 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
155 HRESULT(REFIID
, void**));
156 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
159 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
163 MockLatLongReport
* mock_lat_long_report_
;
167 mock_lat_long_report_
->Release();
170 ULONG
AddRefInternal() {
171 return InterlockedIncrement(&ref_count_
);
173 ULONG
ReleaseInternal() {
174 LONG new_ref_count
= InterlockedDecrement(&ref_count_
);
175 if (0 == new_ref_count
)
177 return new_ref_count
;
179 HRESULT
QueryInterfaceValid(REFIID id
, void** report
) {
180 EXPECT_TRUE(id
== IID_ILatLongReport
);
181 *report
= reinterpret_cast<ILatLongReport
*>(mock_lat_long_report_
);
182 mock_lat_long_report_
->AddRef();
189 class MockLocation
: public ILocation
{
191 MockLocation() : ref_count_(1) {
192 mock_report_
= new MockReport();
193 ON_CALL(*this, SetDesiredAccuracy(_
, _
))
194 .WillByDefault(Return(S_OK
));
195 ON_CALL(*this, GetReport(_
, _
))
196 .WillByDefault(Invoke(this, &MockLocation::GetReportValid
));
197 ON_CALL(*this, RequestPermissions(_
, _
, _
, _
))
198 .WillByDefault(Return(S_OK
));
199 ON_CALL(*this, AddRef())
200 .WillByDefault(Invoke(this, &MockLocation::AddRefInternal
));
201 ON_CALL(*this, Release())
202 .WillByDefault(Invoke(this, &MockLocation::ReleaseInternal
));
206 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
208 HRESULT(REFIID
, LOCATION_DESIRED_ACCURACY
*));
209 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
211 HRESULT(REFIID
, ILocationReport
**));
212 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
214 HRESULT(REFIID
, DWORD
*));
215 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
217 HRESULT(REFIID
, LOCATION_REPORT_STATUS
*));
218 MOCK_METHOD4_WITH_CALLTYPE(STDMETHODCALLTYPE
,
220 HRESULT(HWND
, IID
*, ULONG
, BOOL
));
221 MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE
,
223 HRESULT(ILocationEvents
*, REFIID
, DWORD
));
224 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
226 HRESULT(REFIID
, LOCATION_DESIRED_ACCURACY
));
227 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
229 HRESULT(REFIID
, DWORD
));
230 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE
,
234 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE
,
236 HRESULT(REFIID
, void**));
237 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
240 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE
,
244 MockReport
* mock_report_
;
248 mock_report_
->Release();
252 HRESULT
GetReportValid(REFIID report_type
,
253 ILocationReport
** location_report
) {
254 *location_report
= reinterpret_cast<ILocationReport
*>(mock_report_
);
255 mock_report_
->AddRef();
258 ULONG
AddRefInternal() {
259 return InterlockedIncrement(&ref_count_
);
261 ULONG
ReleaseInternal() {
262 LONG new_ref_count
= InterlockedDecrement(&ref_count_
);
263 if (0 == new_ref_count
)
265 return new_ref_count
;
272 HRESULT __stdcall
MockPropVariantToDoubleFunction(REFPROPVARIANT propvarIn
,
274 CHECK_EQ(10.0, propvarIn
.dblVal
);
279 // TODO(allanwoj): Either make mock classes into NiceMock classes
280 // or check every mock method call.
281 class GeolocationApiWin7Tests
: public testing::Test
{
283 GeolocationApiWin7Tests() {
285 virtual void SetUp() {
286 api_
.reset(CreateMock());
287 report_
= locator_
->mock_report_
;
288 lat_long_report_
= report_
->mock_lat_long_report_
;
290 virtual void TearDown() {
294 ~GeolocationApiWin7Tests() {
297 Win7LocationApi
* CreateMock() {
298 NiceMock
<MockLocation
>* locator
= new NiceMock
<MockLocation
>();
300 return Win7LocationApi::CreateForTesting(&MockPropVariantToDoubleFunction
,
304 scoped_ptr
<Win7LocationApi
> api_
;
305 MockLatLongReport
* lat_long_report_
;
306 NiceMock
<MockLocation
>* locator_
;
310 TEST_F(GeolocationApiWin7Tests
, PermissionDenied
) {
311 EXPECT_CALL(*locator_
, GetReport(_
, _
))
313 .WillRepeatedly(Return(E_ACCESSDENIED
));
314 Geoposition position
;
315 api_
->GetPosition(&position
);
316 EXPECT_EQ(Geoposition::ERROR_CODE_PERMISSION_DENIED
,
317 position
.error_code
);
320 TEST_F(GeolocationApiWin7Tests
, GetValidPosition
) {
321 EXPECT_CALL(*locator_
, GetReport(_
, _
))
323 Geoposition position
;
324 api_
->GetPosition(&position
);
325 EXPECT_TRUE(position
.Validate());
328 TEST_F(GeolocationApiWin7Tests
, GetInvalidPosition
) {
329 EXPECT_CALL(*lat_long_report_
, GetLatitude(_
))
331 .WillRepeatedly(Return(HRESULT_FROM_WIN32(ERROR_NO_DATA
)));
332 EXPECT_CALL(*locator_
, GetReport(_
, _
))
334 Geoposition position
;
335 api_
->GetPosition(&position
);
336 EXPECT_FALSE(position
.Validate());
339 } // namespace content