1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector>
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/compiler_specific.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/geolocation_override_manager.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/geoposition.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/stub_devtools_client.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct Command {
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Command() {}
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Command(const std::string& method, const base::DictionaryValue& params)
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : method(method) {
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    this->params.MergeDictionary(&params);
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Command(const Command& command) {
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *this = command;
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Command& operator=(const Command& command) {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    method = command.method;
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    params.Clear();
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    params.MergeDictionary(&command.params);
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return *this;
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ~Command() {}
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string method;
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue params;
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class RecorderDevToolsClient : public StubDevToolsClient {
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RecorderDevToolsClient() {}
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~RecorderDevToolsClient() {}
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden from StubDevToolsClient:
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual Status SendCommandAndGetResult(
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& method,
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::DictionaryValue& params,
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_ptr<base::DictionaryValue>* result) OVERRIDE {
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    commands_.push_back(Command(method, params));
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Status(kOk);
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<Command> commands_;
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AssertGeolocationCommand(const Command& command,
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              const Geoposition& geoposition) {
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ("Page.setGeolocationOverride", command.method);
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  double latitude, longitude, accuracy;
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(command.params.GetDouble("latitude", &latitude));
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(command.params.GetDouble("longitude", &longitude));
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(command.params.GetDouble("accuracy", &accuracy));
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(geoposition.latitude, latitude);
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(geoposition.longitude, longitude);
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(geoposition.accuracy, accuracy);
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(GeolocationOverrideManager, OverrideSendsCommand) {
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RecorderDevToolsClient client;
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GeolocationOverrideManager manager(&client);
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Geoposition geoposition = {1, 2, 3};
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manager.OverrideGeolocation(geoposition);
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1u, client.commands_.size());
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     AssertGeolocationCommand(client.commands_[0], geoposition));
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  geoposition.latitude = 5;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manager.OverrideGeolocation(geoposition);
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(2u, client.commands_.size());
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AssertGeolocationCommand(client.commands_[1], geoposition));
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(GeolocationOverrideManager, SendsCommandOnConnect) {
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RecorderDevToolsClient client;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GeolocationOverrideManager manager(&client);
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(0u, client.commands_.size());
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(kOk, manager.OnConnected(&client).code());
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Geoposition geoposition = {1, 2, 3};
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manager.OverrideGeolocation(geoposition);
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1u, client.commands_.size());
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(kOk, manager.OnConnected(&client).code());
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(2u, client.commands_.size());
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AssertGeolocationCommand(client.commands_[1], geoposition));
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(GeolocationOverrideManager, SendsCommandOnNavigation) {
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RecorderDevToolsClient client;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GeolocationOverrideManager manager(&client);
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue main_frame_params;
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(kOk,
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            manager.OnEvent(&client, "Page.frameNavigated", main_frame_params)
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                .code());
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(0u, client.commands_.size());
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Geoposition geoposition = {1, 2, 3};
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manager.OverrideGeolocation(geoposition);
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1u, client.commands_.size());
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(kOk,
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            manager.OnEvent(&client, "Page.frameNavigated", main_frame_params)
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                .code());
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(2u, client.commands_.size());
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AssertGeolocationCommand(client.commands_[1], geoposition));
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue sub_frame_params;
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  sub_frame_params.SetString("frame.parentId", "id");
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk,
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      manager.OnEvent(&client, "Page.frameNavigated", sub_frame_params).code());
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(2u, client.commands_.size());
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
127