Don't allow registration of registered device

Device first needs to be factory reset.

BUG: 26427523

Change-Id: I82102fccaaad87f125ae4d124b1c17f984b39b46
Reviewed-on: https://weave-review.googlesource.com/2169
Reviewed-by: Vitaly Buka <vitalybuka@google.com>
diff --git a/src/device_registration_info.cc b/src/device_registration_info.cc
index a91ae6f..c374527 100644
--- a/src/device_registration_info.cc
+++ b/src/device_registration_info.cc
@@ -36,6 +36,7 @@
 const char kErrorDomainOAuth2[] = "oauth2";
 const char kErrorDomainGCD[] = "gcd";
 const char kErrorDomainGCDServer[] = "gcd_server";
+const char kErrorAlreayRegistered[] = "already_registered";
 
 namespace {
 
@@ -523,6 +524,14 @@
 
 void DeviceRegistrationInfo::RegisterDevice(const std::string& ticket_id,
                                             const DoneCallback& callback) {
+  if (HaveRegistrationCredentials()) {
+    ErrorPtr error;
+    Error::AddTo(&error, FROM_HERE, errors::kErrorDomain,
+                 kErrorAlreayRegistered,
+                 "Unable to register already registered device");
+    return RegisterDeviceError(callback, std::move(error));
+  }
+
   std::unique_ptr<base::DictionaryValue> device_draft = BuildDeviceResource();
   CHECK(device_draft);
 
@@ -835,7 +844,7 @@
     const std::string& service_url,
     ErrorPtr* error) {
   if (HaveRegistrationCredentials()) {
-    Error::AddTo(error, FROM_HERE, errors::kErrorDomain, "already_registered",
+    Error::AddTo(error, FROM_HERE, errors::kErrorDomain, kErrorAlreayRegistered,
                  "Unable to change config for registered device");
     return false;
   }
diff --git a/src/device_registration_info_unittest.cc b/src/device_registration_info_unittest.cc
index ea81057..595d749 100644
--- a/src/device_registration_info_unittest.cc
+++ b/src/device_registration_info_unittest.cc
@@ -153,11 +153,14 @@
     dev_reg_->Start();
   }
 
-  void ReloadSettings() {
+  void ReloadSettings(bool registered = true) {
     base::DictionaryValue dict;
-    dict.SetString("refresh_token", test_data::kRefreshToken);
-    dict.SetString("cloud_id", test_data::kCloudId);
-    dict.SetString("robot_account", test_data::kRobotAccountEmail);
+    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(
@@ -373,7 +376,7 @@
 }
 
 TEST_F(DeviceRegistrationInfoTest, RegisterDevice) {
-  ReloadSettings();
+  ReloadSettings(false);
 
   auto json_traits = CreateDictionaryValue(R"({
     'base': {
@@ -558,6 +561,28 @@
   EXPECT_TRUE(done);
 }
 
+TEST_F(DeviceRegistrationInfoTest, ReRegisterDevice) {
+  ReloadSettings();
+
+  bool done = false;
+  dev_reg_->RegisterDevice(
+      test_data::kClaimTicketId, base::Bind([this, &done](ErrorPtr error) {
+        EXPECT_TRUE(error->HasError("weave", "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);
+}
+
 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.
diff --git a/src/weave_unittest.cc b/src/weave_unittest.cc
index 987b0c4..b106aab 100644
--- a/src/weave_unittest.cc
+++ b/src/weave_unittest.cc
@@ -433,6 +433,17 @@
                     }));
   task_runner_.Run();
   EXPECT_TRUE(done);
+
+  done = false;
+  device_->Register(
+      "TICKET_ID2", base::Bind([this, &done](ErrorPtr error) {
+        EXPECT_TRUE(error->HasError("weave", "already_registered"));
+        done = true;
+        task_runner_.Break();
+        EXPECT_EQ("CLOUD_ID", device_->GetSettings().cloud_id);
+      }));
+  task_runner_.Run();
+  EXPECT_TRUE(done);
 }
 
 class WeaveWiFiSetupTest : public WeaveTest {