| Index: blimp/engine/feature/geolocation/engine_geolocation_feature_unittest.cc | 
| diff --git a/blimp/engine/feature/geolocation/engine_geolocation_feature_unittest.cc b/blimp/engine/feature/geolocation/engine_geolocation_feature_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..eb679fe891d39705ce3a12e143b4ced50c720596 | 
| --- /dev/null | 
| +++ b/blimp/engine/feature/geolocation/engine_geolocation_feature_unittest.cc | 
| @@ -0,0 +1,149 @@ | 
| +// Copyright 2016 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "blimp/engine/feature/geolocation/engine_geolocation_feature.h" | 
| + | 
| +#include "base/memory/ptr_util.h" | 
| +#include "blimp/common/create_blimp_message.h" | 
| +#include "blimp/common/proto/blimp_message.pb.h" | 
| +#include "blimp/common/proto/geolocation.pb.h" | 
| +#include "blimp/net/test_common.h" | 
| +#include "content/public/browser/location_provider.h" | 
| +#include "content/public/common/geoposition.h" | 
| +#include "net/base/test_completion_callback.h" | 
| +#include "testing/gmock/include/gmock/gmock.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| + | 
| +using testing::_; | 
| + | 
| +namespace blimp { | 
| +namespace engine { | 
| + | 
| +void SendMockLocationMessage(BlimpMessageProcessor* processor, | 
| +                             ErrorMessage::ErrorCode error) { | 
| +  GeolocationMessage* geolocation_message; | 
| +  std::unique_ptr<BlimpMessage> message = | 
| +      CreateBlimpMessage(&geolocation_message); | 
| +  if (error == ErrorMessage::ERROR_CODE_NONE) { | 
| +    LocationMessage* location_message = geolocation_message->mutable_location(); | 
| +    location_message->set_latitude(-42.0); | 
| +    location_message->set_longitude(17.3); | 
| +    location_message->set_altitude(123.4); | 
| +    location_message->set_accuracy(73.7); | 
| +    location_message->set_timestamp_millis(87); | 
| +  } else { | 
| +    ErrorMessage* error_message = geolocation_message->mutable_error(); | 
| +    error_message->set_error_code(error); | 
| +    error_message->set_error_message("AN ERROR HAS OCCURRED."); | 
| +  } | 
| +  net::TestCompletionCallback cb; | 
| +  processor->ProcessMessage(std::move(message), cb.callback()); | 
| +  EXPECT_EQ(net::OK, cb.WaitForResult()); | 
| +} | 
| + | 
| +MATCHER_P(EqualsUpdatedListenState, accuracy, "") { | 
| +  return arg.feature_case() == BlimpMessage::kGeolocation && | 
| +         arg.geolocation().type_case() == | 
| +             GeolocationMessage::kUpdateListenState && | 
| +         arg.geolocation().update_listen_state().listen_state() == accuracy; | 
| +} | 
| + | 
| +MATCHER(EqualsStoppedListenState, "") { | 
| +  return arg.feature_case() == BlimpMessage::kGeolocation && | 
| +         arg.geolocation().type_case() == | 
| +             GeolocationMessage::kUpdateListenState && | 
| +         arg.geolocation().update_listen_state().listen_state() == | 
| +             UpdateListenStateMessage::STOPPED; | 
| +} | 
| + | 
| +MATCHER(EqualsRequestRefresh, "") { | 
| +  return arg.feature_case() == BlimpMessage::kGeolocation && | 
| +         arg.geolocation().type_case() == GeolocationMessage::kRequestRefresh; | 
| +} | 
| + | 
| +class EngineGeolocationFeatureTest : public testing::Test { | 
| + public: | 
| +  EngineGeolocationFeatureTest() | 
| +      : out_processor_(nullptr), | 
| +        mock_callback_( | 
| +            base::Bind(&EngineGeolocationFeatureTest::OnLocationUpdate, | 
| +                       base::Unretained(this))) {} | 
| + | 
| +  void SetUp() override { | 
| +    out_processor_ = new MockBlimpMessageProcessor(); | 
| +    feature_.set_outgoing_message_processor(base::WrapUnique(out_processor_)); | 
| +    feature_.SetUpdateCallback(mock_callback_); | 
| +    received_position = nullptr; | 
| +  } | 
| + | 
| +  void OnLocationUpdate(const content::Geoposition& geoposition) { | 
| +    received_position = &geoposition; | 
| +  } | 
| + | 
| + protected: | 
| +  // This is a raw pointer to a class that is owned by the NavigationFeature. | 
| +  MockBlimpMessageProcessor* out_processor_; | 
| + | 
| +  EngineGeolocationFeature feature_; | 
| +  base::Callback<void(const content::Geoposition&)> mock_callback_; | 
| +  const content::Geoposition* received_position; | 
| +}; | 
| + | 
| +TEST_F(EngineGeolocationFeatureTest, TestLocationRecieved) { | 
| +  SendMockLocationMessage(&feature_, ErrorMessage::ERROR_CODE_NONE); | 
| +  ASSERT_NE(nullptr, received_position); | 
| +  EXPECT_EQ(content::Geoposition::ERROR_CODE_NONE, | 
| +            received_position->error_code); | 
| +  EXPECT_EQ(-42.0, received_position->latitude); | 
| +  EXPECT_EQ(17.3, received_position->longitude); | 
| +  EXPECT_EQ(123.4, received_position->altitude); | 
| +  EXPECT_EQ(73.7, received_position->accuracy); | 
| +  EXPECT_EQ(base::Time::FromJsTime(87), received_position->timestamp); | 
| +} | 
| + | 
| +TEST_F(EngineGeolocationFeatureTest, TestErrorRecieved) { | 
| +  SendMockLocationMessage(&feature_, | 
| +                          ErrorMessage::ERROR_CODE_PERMISSION_DENIED); | 
| +  ASSERT_NE(nullptr, received_position); | 
| +  EXPECT_EQ(content::Geoposition::ERROR_CODE_PERMISSION_DENIED, | 
| +            received_position->error_code); | 
| +  EXPECT_EQ("AN ERROR HAS OCCURRED.", received_position->error_message); | 
| + | 
| +  SendMockLocationMessage(&feature_, | 
| +                          ErrorMessage::ERROR_CODE_POSITION_UNAVAILABLE); | 
| +  EXPECT_EQ(content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE, | 
| +            received_position->error_code); | 
| +} | 
| + | 
| +TEST_F(EngineGeolocationFeatureTest, TestSendUpdateListenStateMessage) { | 
| +  EXPECT_CALL( | 
| +      *out_processor_, | 
| +      MockableProcessMessage( | 
| +          EqualsUpdatedListenState(UpdateListenStateMessage::ACCURACY_HIGH), _)) | 
| +      .Times(1); | 
| +  EXPECT_CALL( | 
| +      *out_processor_, | 
| +      MockableProcessMessage( | 
| +          EqualsUpdatedListenState(UpdateListenStateMessage::ACCURACY_LOW), _)) | 
| +      .Times(1); | 
| +  feature_.UpdateListenState(true); | 
| +  feature_.UpdateListenState(false); | 
| +} | 
| + | 
| +TEST_F(EngineGeolocationFeatureTest, TestSendStopUpdateListenStateMessage) { | 
| +  EXPECT_CALL(*out_processor_, | 
| +              MockableProcessMessage(EqualsStoppedListenState(), _)) | 
| +      .Times(1); | 
| +  feature_.StopListenState(); | 
| +} | 
| + | 
| +TEST_F(EngineGeolocationFeatureTest, TestSendRequestRefreshMessage) { | 
| +  EXPECT_CALL(*out_processor_, | 
| +              MockableProcessMessage(EqualsRequestRefresh(), _)) | 
| +      .Times(1); | 
| +  feature_.RequestRefresh(); | 
| +} | 
| + | 
| +}  // namespace engine | 
| +}  // namespace blimp | 
|  |