// Copyright 2015 The Weave 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 "src/device_registration_info.h"

#include <base/json/json_reader.h>
#include <base/json/json_writer.h>
#include <base/values.h>
#include <gtest/gtest.h>
#include <weave/provider/test/fake_task_runner.h>
#include <weave/provider/test/mock_config_store.h>
#include <weave/provider/test/mock_http_client.h>
#include <weave/test/unittest_utils.h>

#include "src/bind_lambda.h"
#include "src/component_manager_impl.h"
#include "src/http_constants.h"
#include "src/privet/auth_manager.h"
#include "src/test/mock_clock.h"

using testing::_;
using testing::AtLeast;
using testing::HasSubstr;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::Mock;
using testing::Return;
using testing::ReturnRef;
using testing::ReturnRefOfCopy;
using testing::SaveArg;
using testing::StrictMock;
using testing::WithArgs;

namespace weave {

using test::CreateDictionaryValue;
using test::CreateValue;
using provider::test::MockHttpClient;
using provider::test::MockHttpClientResponse;
using provider::HttpClient;

namespace {

namespace test_data {

const char kXmppEndpoint[] = "xmpp.server.com:1234";
const char kServiceUrl[] = "http://gcd.server.com/";
const char kOAuthUrl[] = "http://oauth.server.com/";
const char kApiKey[] = "GOadRdTf9FERf0k4w6EFOof56fUJ3kFDdFL3d7f";
const char kClientId[] =
    "123543821385-sfjkjshdkjhfk234sdfsdfkskd"
    "fkjh7f.apps.googleusercontent.com";
const char kClientSecret[] = "5sdGdGlfolGlrFKfdFlgP6FG";
const char kCloudId[] = "4a7ea2d1-b331-1e1f-b206-e863c7635196";
const char kDeviceId[] = "f6885e46-b432-42d7-86a5-d759bfb61f62";
const char kClaimTicketId[] = "RTcUE";
const char kAccessToken[] =
    "ya29.1.AADtN_V-dLUM-sVZ0qVjG9Dxm5NgdS9J"
    "Mx_JLUqhC9bED_YFjzHZtYt65ZzXCS35NMAeaVZ"
    "Dei530-w0yE2urpQ";
const char kRefreshToken[] =
    "1/zQmxR6PKNvhcxf9SjXUrCjcmCrcqRKXctc6cp"
    "1nI-GQ";
const char kRobotAccountAuthCode[] =
    "4/Mf_ujEhPejVhOq-OxW9F5cSOnWzx."
    "YgciVjTYGscRshQV0ieZDAqiTIjMigI";
const char kRobotAccountEmail[] =
    "6ed0b3f54f9bd619b942f4ad2441c252@"
    "clouddevices.gserviceaccount.com";
const char kAuthInfo[] = R"({
  "localAuthInfo": {
    "certFingerprint":
    "FQY6BEINDjw3FgsmYChRWgMzMhc4TC8uG0UUUFhdDz0=",
    "localId": "f6885e46-b432-42d7-86a5-d759bfb61f62"
  }
})";

}  // namespace test_data

std::string GetFormField(const std::string& data, const std::string& name) {
  EXPECT_FALSE(data.empty());
  for (const auto& i : WebParamsDecode(data)) {
    if (i.first == name)
      return i.second;
  }
  return {};
}

std::unique_ptr<HttpClient::Response> ReplyWithJson(int status_code,
                                                    const base::Value& json) {
  std::string text;
  base::JSONWriter::WriteWithOptions(
      json, base::JSONWriter::OPTIONS_PRETTY_PRINT, &text);

  std::unique_ptr<MockHttpClientResponse> response{
      new StrictMock<MockHttpClientResponse>};
  EXPECT_CALL(*response, GetStatusCode())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(status_code));
  EXPECT_CALL(*response, GetContentType())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(http::kJsonUtf8));
  EXPECT_CALL(*response, GetData())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(text));
  return std::move(response);
}

std::pair<std::string, std::string> GetAuthHeader() {
  return {http::kAuthorization,
          std::string("Bearer ") + test_data::kAccessToken};
}

std::pair<std::string, std::string> GetJsonHeader() {
  return {http::kContentType, http::kJsonUtf8};
}

std::pair<std::string, std::string> GetFormHeader() {
  return {http::kContentType, http::kWwwFormUrlEncoded};
}

}  // anonymous namespace

class DeviceRegistrationInfoTest : public ::testing::Test {
 protected:
  void SetUp() override {
    EXPECT_CALL(clock_, Now())
        .WillRepeatedly(Return(base::Time::FromTimeT(1450000000)));
    ReloadDefaults(true);
  }

  void ReloadDefaults(bool allow_endpoints_override) {
    EXPECT_CALL(config_store_, LoadDefaults(_))
        .WillOnce(Invoke([allow_endpoints_override](Settings* settings) {
          settings->client_id = test_data::kClientId;
          settings->client_secret = test_data::kClientSecret;
          settings->api_key = test_data::kApiKey;
          settings->oem_name = "Coffee Pot Maker";
          settings->model_name = "Pot v1";
          settings->name = "Coffee Pot";
          settings->description = "Easy to clean";
          settings->location = "Kitchen";
          settings->local_anonymous_access_role = AuthScope::kViewer;
          settings->model_id = "AAAAA";
          settings->oauth_url = test_data::kOAuthUrl;
          settings->service_url = test_data::kServiceUrl;
          settings->xmpp_endpoint = test_data::kXmppEndpoint;
          settings->allow_endpoints_override = allow_endpoints_override;
          return true;
        }));
    config_.reset(new Config{&config_store_});
    dev_reg_.reset(new DeviceRegistrationInfo{
        config_.get(), &component_manager_, &task_runner_, &http_client_,
        nullptr, &auth_});
    dev_reg_->Start();
  }

  void ReloadSettings(bool registered, bool allow_endpoints_override) {
    base::DictionaryValue dict;
    dict.SetInteger("version", 1);
    if (registered) {
      dict.SetString("refresh_token", test_data::kRefreshToken);
      dict.SetString("cloud_id", test_data::kCloudId);
      dict.SetString("robot_account", test_data::kRobotAccountEmail);
    }
    dict.SetString("device_id", test_data::kDeviceId);
    std::string json_string;
    base::JSONWriter::WriteWithOptions(
        dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_string);
    EXPECT_CALL(config_store_, LoadSettings()).WillOnce(Return(json_string));
    ReloadDefaults(allow_endpoints_override);
  }

  void PublishCommands(const base::ListValue& commands) {
    dev_reg_->PublishCommands(commands, nullptr);
  }

  bool RefreshAccessToken(ErrorPtr* error) const {
    bool succeeded = false;
    auto callback = [&succeeded, &error](ErrorPtr in_error) {
      if (error) {
        *error = std::move(in_error);
        return;
      }
      succeeded = true;
    };
    dev_reg_->RefreshAccessToken(base::Bind(callback));
    return succeeded;
  }

  void SetAccessToken() { dev_reg_->access_token_ = test_data::kAccessToken; }

  GcdState GetGcdState() const { return dev_reg_->GetGcdState(); }

  bool HaveRegistrationCredentials() const {
    return dev_reg_->HaveRegistrationCredentials();
  }

  void RegisterDevice(const RegistrationData registration_data,
                      const RegistrationData& expected_data);

  provider::test::FakeTaskRunner task_runner_;
  provider::test::MockConfigStore config_store_;
  StrictMock<MockHttpClient> http_client_;
  base::DictionaryValue data_;
  std::unique_ptr<Config> config_;
  test::MockClock clock_;
  privet::AuthManager auth_{
      {68, 52, 36, 95, 74, 89, 25, 2,  31, 5,  65, 87, 64, 32, 17, 26,
       8,  73, 57, 16, 33, 82, 71, 10, 72, 62, 45, 1,  77, 97, 70, 24},
      {21, 6,  58, 4,  66, 13, 14, 60, 55, 22, 11, 38, 96, 40, 81, 90,
       3,  51, 50, 23, 56, 76, 47, 46, 27, 69, 20, 80, 88, 93, 15, 61},
      {},
      &clock_};
  std::unique_ptr<DeviceRegistrationInfo> dev_reg_;
  ComponentManagerImpl component_manager_{&task_runner_};
};

TEST_F(DeviceRegistrationInfoTest, GetServiceUrl) {
  EXPECT_EQ(test_data::kServiceUrl, dev_reg_->GetServiceUrl());
  std::string url = test_data::kServiceUrl;
  url += "registrationTickets";
  EXPECT_EQ(url, dev_reg_->GetServiceUrl("registrationTickets"));
  url += "?key=";
  url += test_data::kApiKey;
  EXPECT_EQ(url, dev_reg_->GetServiceUrl("registrationTickets",
                                         {{"key", test_data::kApiKey}}));
  url += "&restart=true";
  EXPECT_EQ(url, dev_reg_->GetServiceUrl(
                     "registrationTickets",
                     {
                         {"key", test_data::kApiKey}, {"restart", "true"},
                     }));
}

TEST_F(DeviceRegistrationInfoTest, GetOAuthUrl) {
  EXPECT_EQ(test_data::kOAuthUrl, dev_reg_->GetOAuthUrl());
  std::string url = test_data::kOAuthUrl;
  url += "auth?redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&";
  url += "response_type=code&";
  url += "client_id=";
  url += test_data::kClientId;
  EXPECT_EQ(url, dev_reg_->GetOAuthUrl(
                     "auth", {{"redirect_uri", "urn:ietf:wg:oauth:2.0:oob"},
                              {"response_type", "code"},
                              {"client_id", test_data::kClientId}}));
}

TEST_F(DeviceRegistrationInfoTest, HaveRegistrationCredentials) {
  EXPECT_FALSE(HaveRegistrationCredentials());
  ReloadSettings(true, false);

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthUrl("token"),
                  HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            EXPECT_EQ("refresh_token", GetFormField(data, "grant_type"));
            EXPECT_EQ(test_data::kRefreshToken,
                      GetFormField(data, "refresh_token"));
            EXPECT_EQ(test_data::kClientId, GetFormField(data, "client_id"));
            EXPECT_EQ(test_data::kClientSecret,
                      GetFormField(data, "client_secret"));

            base::DictionaryValue json;
            json.SetString("access_token", test_data::kAccessToken);
            json.SetInteger("expires_in", 3600);

            callback.Run(ReplyWithJson(200, json), nullptr);
          })));

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost, HasSubstr("upsertLocalAuthInfo"),
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            auto dict = CreateDictionaryValue(data);
            EXPECT_TRUE(dict->Remove("localAuthInfo.clientToken", nullptr));
            EXPECT_JSON_EQ(test_data::kAuthInfo, *dict);
            base::DictionaryValue json;
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));

  EXPECT_TRUE(RefreshAccessToken(nullptr));
  EXPECT_TRUE(HaveRegistrationCredentials());
}

TEST_F(DeviceRegistrationInfoTest, CheckAuthenticationFailure) {
  ReloadSettings(true, false);
  EXPECT_EQ(GcdState::kConnecting, GetGcdState());

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthUrl("token"),
                  HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            EXPECT_EQ("refresh_token", GetFormField(data, "grant_type"));
            EXPECT_EQ(test_data::kRefreshToken,
                      GetFormField(data, "refresh_token"));
            EXPECT_EQ(test_data::kClientId, GetFormField(data, "client_id"));
            EXPECT_EQ(test_data::kClientSecret,
                      GetFormField(data, "client_secret"));

            base::DictionaryValue json;
            json.SetString("error", "unable_to_authenticate");
            callback.Run(ReplyWithJson(400, json), nullptr);
          })));

  ErrorPtr error;
  EXPECT_FALSE(RefreshAccessToken(&error));
  EXPECT_TRUE(error->HasError("unable_to_authenticate"));
  EXPECT_EQ(GcdState::kConnecting, GetGcdState());
}

TEST_F(DeviceRegistrationInfoTest, CheckDeregistration) {
  ReloadSettings(true, false);
  EXPECT_EQ(GcdState::kConnecting, GetGcdState());

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthUrl("token"),
                  HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            EXPECT_EQ("refresh_token", GetFormField(data, "grant_type"));
            EXPECT_EQ(test_data::kRefreshToken,
                      GetFormField(data, "refresh_token"));
            EXPECT_EQ(test_data::kClientId, GetFormField(data, "client_id"));
            EXPECT_EQ(test_data::kClientSecret,
                      GetFormField(data, "client_secret"));

            base::DictionaryValue json;
            json.SetString("error", "invalid_grant");
            callback.Run(ReplyWithJson(400, json), nullptr);
          })));

  ErrorPtr error;
  EXPECT_FALSE(RefreshAccessToken(&error));
  EXPECT_TRUE(error->HasError("invalid_grant"));
  EXPECT_EQ(GcdState::kInvalidCredentials, GetGcdState());
  EXPECT_EQ(test_data::kCloudId, dev_reg_->GetSettings().cloud_id);
}

TEST_F(DeviceRegistrationInfoTest, GetDeviceInfo) {
  ReloadSettings(true, false);
  SetAccessToken();

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kGet, dev_reg_->GetDeviceUrl(),
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            base::DictionaryValue json;
            json.SetString("channel.supportedType", "xmpp");
            json.SetString("deviceKind", "vendor");
            json.SetString("id", test_data::kCloudId);
            json.SetString("kind", "weave#device");
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));

  bool succeeded = false;
  auto callback = [&succeeded, this](const base::DictionaryValue& info,
                                     ErrorPtr error) {
    EXPECT_FALSE(error);
    std::string id;
    EXPECT_TRUE(info.GetString("id", &id));
    EXPECT_EQ(test_data::kCloudId, id);
    succeeded = true;
  };
  dev_reg_->GetDeviceInfo(base::Bind(callback));
  EXPECT_TRUE(succeeded);
}

TEST_F(DeviceRegistrationInfoTest, ReRegisterDevice) {
  ReloadSettings(true, false);

  bool done = false;
  dev_reg_->RegisterDevice(RegistrationData{test_data::kClaimTicketId},
                           base::Bind([this, &done](ErrorPtr error) {
                             EXPECT_TRUE(error->HasError("already_registered"));
                             done = true;
                             task_runner_.Break();
                             EXPECT_EQ(GcdState::kConnecting, GetGcdState());

                             // Validate the device info saved to storage...
                             EXPECT_EQ(test_data::kCloudId,
                                       dev_reg_->GetSettings().cloud_id);
                             EXPECT_EQ(test_data::kRefreshToken,
                                       dev_reg_->GetSettings().refresh_token);
                             EXPECT_EQ(test_data::kRobotAccountEmail,
                                       dev_reg_->GetSettings().robot_account);
                           }));
  task_runner_.Run();
  EXPECT_TRUE(done);
}

void DeviceRegistrationInfoTest::RegisterDevice(
    const RegistrationData registration_data,
    const RegistrationData& expected_data) {
  auto json_traits = CreateDictionaryValue(R"({
    'base': {
      'commands': {
        'reboot': {
          'parameters': {'delay': {'minimum': 10, 'type': 'integer'}},
          'minimalRole': 'user'
        }
      },
      'state': {
        'firmwareVersion': {'type': 'string'}
      }
    },
    'robot': {
      'commands': {
        '_jump': {
          'parameters': {'_height': {'type': 'integer'}},
          'minimalRole': 'user'
        }
      }
    }
  })");
  EXPECT_TRUE(component_manager_.LoadTraits(*json_traits, nullptr));
  EXPECT_TRUE(
      component_manager_.AddComponent("", "comp", {"base", "robot"}, nullptr));
  base::StringValue ver{"1.0"};
  EXPECT_TRUE(component_manager_.SetStateProperty(
      "comp", "base.firmwareVersion", ver, nullptr));

  std::string ticket_url = expected_data.service_url + "registrationTickets/" +
                           expected_data.ticket_id;
  EXPECT_CALL(http_client_,
              SendRequest(HttpClient::Method::kPatch,
                          ticket_url + "?key=" + expected_data.api_key,
                          HttpClient::Headers{GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(Invoke(
          [&expected_data](const std::string& data,
                           const HttpClient::SendRequestCallback& callback) {
            auto json = test::CreateDictionaryValue(data);
            EXPECT_NE(nullptr, json.get());
            std::string value;
            EXPECT_TRUE(json->GetString("id", &value));
            EXPECT_EQ(expected_data.ticket_id, value);
            EXPECT_TRUE(
                json->GetString("deviceDraft.channel.supportedType", &value));
            EXPECT_EQ("pull", value);
            EXPECT_TRUE(json->GetString("oauthClientId", &value));
            EXPECT_EQ(expected_data.client_id, value);
            EXPECT_TRUE(json->GetString("deviceDraft.description", &value));
            EXPECT_EQ("Easy to clean", value);
            EXPECT_TRUE(json->GetString("deviceDraft.location", &value));
            EXPECT_EQ("Kitchen", value);
            EXPECT_TRUE(json->GetString("deviceDraft.modelManifestId", &value));
            EXPECT_EQ("AAAAA", value);
            EXPECT_TRUE(json->GetString("deviceDraft.name", &value));
            EXPECT_EQ("Coffee Pot", value);
            base::DictionaryValue* dict = nullptr;
            EXPECT_FALSE(json->GetDictionary("deviceDraft.commandDefs", &dict));
            EXPECT_FALSE(json->GetDictionary("deviceDraft.state", &dict));
            EXPECT_TRUE(json->GetDictionary("deviceDraft.traits", &dict));
            auto expectedTraits = R"({
              'base': {
                'commands': {
                  'reboot': {
                    'parameters': {'delay': {'minimum': 10, 'type': 'integer'}},
                    'minimalRole': 'user'
                  }
                },
                'state': {
                  'firmwareVersion': {'type': 'string'}
                }
              },
              'robot': {
                'commands': {
                  '_jump': {
                    'parameters': {'_height': {'type': 'integer'}},
                    'minimalRole': 'user'
                  }
                }
              }
            })";
            EXPECT_JSON_EQ(expectedTraits, *dict);

            EXPECT_TRUE(json->GetDictionary("deviceDraft.components", &dict));
            auto expectedComponents = R"({
              'comp': {
                'traits': ['base', 'robot'],
                'state': {
                  'base': { 'firmwareVersion': '1.0' }
                }
              }
            })";
            EXPECT_JSON_EQ(expectedComponents, *dict);

            base::DictionaryValue json_resp;
            json_resp.SetString("id", test_data::kClaimTicketId);
            json_resp.SetString("kind", "weave#registrationTicket");
            json_resp.SetString("oauthClientId", test_data::kClientId);
            base::DictionaryValue* device_draft = nullptr;
            EXPECT_TRUE(json->GetDictionary("deviceDraft", &device_draft));
            device_draft = device_draft->DeepCopy();
            device_draft->SetString("id", test_data::kCloudId);
            device_draft->SetString("kind", "weave#device");
            json_resp.Set("deviceDraft", device_draft);

            callback.Run(ReplyWithJson(200, json_resp), nullptr);
          })));

  EXPECT_CALL(http_client_,
              SendRequest(HttpClient::Method::kPost,
                          ticket_url + "/finalize?key=" + expected_data.api_key,
                          HttpClient::Headers{}, _, _))
      .WillOnce(WithArgs<4>(
          Invoke([](const HttpClient::SendRequestCallback& callback) {
            base::DictionaryValue json;
            json.SetString("id", test_data::kClaimTicketId);
            json.SetString("kind", "weave#registrationTicket");
            json.SetString("oauthClientId", test_data::kClientId);
            json.SetString("userEmail", "user@email.com");
            json.SetString("deviceDraft.id", test_data::kCloudId);
            json.SetString("deviceDraft.kind", "weave#device");
            json.SetString("deviceDraft.channel.supportedType", "xmpp");
            json.SetString("robotAccountEmail", test_data::kRobotAccountEmail);
            json.SetString("robotAccountAuthorizationCode",
                           test_data::kRobotAccountAuthCode);
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost, expected_data.oauth_url + "token",
                  HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(Invoke([&expected_data](
          const std::string& data,
          const HttpClient::SendRequestCallback& callback) {
        EXPECT_EQ("authorization_code", GetFormField(data, "grant_type"));
        EXPECT_EQ(test_data::kRobotAccountAuthCode, GetFormField(data, "code"));
        EXPECT_EQ(expected_data.client_id, GetFormField(data, "client_id"));
        EXPECT_EQ(expected_data.client_secret,
                  GetFormField(data, "client_secret"));
        EXPECT_EQ("oob", GetFormField(data, "redirect_uri"));

        base::DictionaryValue json;
        json.SetString("access_token", test_data::kAccessToken);
        json.SetString("token_type", "Bearer");
        json.SetString("refresh_token", test_data::kRefreshToken);
        json.SetInteger("expires_in", 3600);

        callback.Run(ReplyWithJson(200, json), nullptr);
      })));

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost,
                  expected_data.service_url + "devices/" + test_data::kCloudId +
                      "/upsertLocalAuthInfo",
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            auto dict = CreateDictionaryValue(data);
            EXPECT_TRUE(dict->Remove("localAuthInfo.clientToken", nullptr));
            EXPECT_JSON_EQ(test_data::kAuthInfo, *dict);
            base::DictionaryValue json;
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));

  bool done = false;
  dev_reg_->RegisterDevice(
      registration_data,
      base::Bind([this, &done, &expected_data](ErrorPtr error) {
        done = true;
        task_runner_.Break();

        EXPECT_FALSE(error);
        EXPECT_EQ(GcdState::kConnecting, GetGcdState());

        // Validate the device info saved to storage...
        EXPECT_EQ(test_data::kCloudId, dev_reg_->GetSettings().cloud_id);
        EXPECT_EQ(test_data::kRefreshToken,
                  dev_reg_->GetSettings().refresh_token);
        EXPECT_EQ(test_data::kRobotAccountEmail,
                  dev_reg_->GetSettings().robot_account);
        EXPECT_EQ(expected_data.oauth_url, dev_reg_->GetSettings().oauth_url);
        EXPECT_EQ(expected_data.client_id, dev_reg_->GetSettings().client_id);
        EXPECT_EQ(expected_data.client_secret,
                  dev_reg_->GetSettings().client_secret);
        EXPECT_EQ(expected_data.api_key, dev_reg_->GetSettings().api_key);
        EXPECT_EQ(expected_data.service_url,
                  dev_reg_->GetSettings().service_url);
        EXPECT_EQ(expected_data.xmpp_endpoint,
                  dev_reg_->GetSettings().xmpp_endpoint);
      }));
  task_runner_.Run();
  EXPECT_TRUE(done);
}

TEST_F(DeviceRegistrationInfoTest, RegisterDevice) {
  ReloadSettings(false, true);

  RegistrationData registration_data;
  registration_data.ticket_id = "test_ticked_id";
  registration_data.oauth_url = "https://test.oauth/";
  registration_data.client_id = "test_client_id";
  registration_data.client_secret = "test_client_secret";
  registration_data.api_key = "test_api_key";
  registration_data.service_url = "https://test.service/";
  registration_data.xmpp_endpoint = "test.xmpp:1234";

  RegisterDevice(registration_data, registration_data);
}

TEST_F(DeviceRegistrationInfoTest, RegisterDeviceWithDefaultEndpoints) {
  ReloadSettings(false, true);

  RegistrationData registration_data;
  registration_data.ticket_id = "test_ticked_id";

  RegistrationData expected_data = registration_data;
  expected_data.oauth_url = test_data::kOAuthUrl;
  expected_data.client_id = test_data::kClientId;
  expected_data.client_secret = test_data::kClientSecret;
  expected_data.api_key = test_data::kApiKey;
  expected_data.service_url = test_data::kServiceUrl;
  expected_data.xmpp_endpoint = test_data::kXmppEndpoint;

  RegisterDevice(registration_data, expected_data);
}

TEST_F(DeviceRegistrationInfoTest, RegisterDeviceEndpointsOverrideNotAllowed) {
  ReloadSettings(false, false);

  RegistrationData registration_data;
  registration_data.ticket_id = "test_ticked_id";
  registration_data.service_url = "https://test.service/";

  bool done = false;
  dev_reg_->RegisterDevice(registration_data,
                           base::Bind([this, &done](ErrorPtr error) {
                             done = true;
                             task_runner_.Break();
                             EXPECT_TRUE(error->HasError("invalidParams"));
                           }));
  task_runner_.Run();
  EXPECT_TRUE(done);
}

TEST_F(DeviceRegistrationInfoTest, OOBRegistrationStatus) {
  // After we've been initialized, we should be either offline or
  // unregistered, depending on whether or not we've found credentials.
  EXPECT_EQ(GcdState::kUnconfigured, GetGcdState());
  // Put some credentials into our state, make sure we call that offline.
  ReloadSettings(true, false);
  EXPECT_EQ(GcdState::kConnecting, GetGcdState());
}

class DeviceRegistrationInfoUpdateCommandTest
    : public DeviceRegistrationInfoTest {
 protected:
  void SetUp() override {
    DeviceRegistrationInfoTest::SetUp();

    ReloadSettings(true, false);
    SetAccessToken();

    auto json_traits = CreateDictionaryValue(R"({
      'robot': {
        'commands': {
          '_jump': {
            'parameters': {'_height': 'integer'},
            'progress': {'progress': 'integer'},
            'results': {'status': 'string'},
            'minimalRole': 'user'
          }
        }
      }
    })");
    EXPECT_TRUE(component_manager_.LoadTraits(*json_traits, nullptr));
    EXPECT_TRUE(
        component_manager_.AddComponent("", "comp", {"robot"}, nullptr));

    command_url_ = dev_reg_->GetServiceUrl("commands/1234");

    auto commands_json = CreateValue(R"([{
      'name':'robot._jump',
      'component': 'comp',
      'id':'1234',
      'parameters': {'_height': 100},
      'minimalRole': 'user'
    }])");
    ASSERT_NE(nullptr, commands_json.get());
    const base::ListValue* command_list = nullptr;
    ASSERT_TRUE(commands_json->GetAsList(&command_list));
    PublishCommands(*command_list);
    command_ = component_manager_.FindCommand("1234");
    ASSERT_NE(nullptr, command_);
  }

  void TearDown() override {
    task_runner_.RunOnce();
    DeviceRegistrationInfoTest::TearDown();
  }

  Command* command_{nullptr};
  std::string command_url_;
};

TEST_F(DeviceRegistrationInfoUpdateCommandTest, SetProgress) {
  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPatch, command_url_,
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(Invoke([](
          const std::string& data,
          const HttpClient::SendRequestCallback& callback) {
        EXPECT_JSON_EQ((R"({"state":"inProgress","progress":{"progress":18}})"),
                       *CreateDictionaryValue(data));
        base::DictionaryValue json;
        callback.Run(ReplyWithJson(200, json), nullptr);
      })));
  EXPECT_TRUE(command_->SetProgress(*CreateDictionaryValue("{'progress':18}"),
                                    nullptr));
}

TEST_F(DeviceRegistrationInfoUpdateCommandTest, Complete) {
  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPatch, command_url_,
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            EXPECT_JSON_EQ(R"({"state":"done", "results":{"status":"Ok"}})",
                           *CreateDictionaryValue(data));
            base::DictionaryValue json;
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));
  EXPECT_TRUE(
      command_->Complete(*CreateDictionaryValue("{'status': 'Ok'}"), nullptr));
}

TEST_F(DeviceRegistrationInfoUpdateCommandTest, Cancel) {
  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPatch, command_url_,
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            EXPECT_JSON_EQ(R"({"state":"cancelled"})",
                           *CreateDictionaryValue(data));
            base::DictionaryValue json;
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));
  EXPECT_TRUE(command_->Cancel(nullptr));
}

}  // namespace weave
