buffet: Add CommandInstance::ToJson

Method is needed to implement commands status requests from
privetd. Current implementation generates JSON on request.

BUG=brillo:430
TEST=unittest

Change-Id: Iee4a788792a33278c997ad535abe11f26fa7f422
Reviewed-on: https://chromium-review.googlesource.com/262215
Reviewed-by: Vitaly Buka <vitalybuka@chromium.org>
Tested-by: Vitaly Buka <vitalybuka@chromium.org>
Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/buffet/commands/command_instance_unittest.cc b/buffet/commands/command_instance_unittest.cc
index 98c23e5..48d54b9 100644
--- a/buffet/commands/command_instance_unittest.cc
+++ b/buffet/commands/command_instance_unittest.cc
@@ -189,3 +189,33 @@
   EXPECT_EQ("command_failed", error->GetCode());
   EXPECT_EQ("Failed to validate command 'robot.speak'", error->GetMessage());
 }
+
+TEST_F(CommandInstanceTest, ToJson) {
+  auto json = CreateDictionaryValue(R"({
+    'name': 'robot.jump',
+    'parameters': {
+      'height': 53,
+      '_jumpType': '_withKick'
+    },
+    'results': {}
+  })");
+  auto instance = buffet::CommandInstance::FromJson(json.get(), dict_, nullptr);
+  instance->SetProgress(15);
+  instance->SetID("testId");
+  buffet::native_types::Object results;
+  buffet::IntPropType int_prop;
+  results["testResult"] = int_prop.CreateValue(17, nullptr);
+  instance->SetResults(results);
+
+  json->MergeDictionary(CreateDictionaryValue(R"({
+    'id': 'testId',
+    'progress': 15,
+    'state': 'inProgress',
+    'results': {'testResult': 17}
+  })").get());
+
+  auto converted = instance->ToJson();
+  EXPECT_PRED2([](const base::Value& val1, const base::Value& val2) {
+    return val1.Equals(&val2);
+  }, *json, *converted);
+}