From b82c1695133d363a0eb00b3c438b497966837188 Mon Sep 17 00:00:00 2001 From: Denis-Cosmin Nutiu Date: Sun, 16 Feb 2020 13:55:29 +0200 Subject: [PATCH] NUC-31: Implement FireStore rest translator --- .../Utilities/FirebaseRestTranslator.cs | 115 ++++++++++++++++++ .../Utilities/FirebaseRestTranslatorTests.cs | 79 ++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 NucuCar.Domain/Utilities/FirebaseRestTranslator.cs create mode 100644 NucuCar.UnitTests/NucuCar.Domain.Tests/Utilities/FirebaseRestTranslatorTests.cs diff --git a/NucuCar.Domain/Utilities/FirebaseRestTranslator.cs b/NucuCar.Domain/Utilities/FirebaseRestTranslator.cs new file mode 100644 index 0000000..30ec6cd --- /dev/null +++ b/NucuCar.Domain/Utilities/FirebaseRestTranslator.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; + +namespace NucuCar.Domain.Utilities +{ + /// + /// This class is used to translate C# dictionaries into firebase json format. + /// + public static class FirebaseRestTranslator + { + public static Dictionary Translate(string name, Dictionary dict) + { + return BuildRoot(name, dict); + } + + private static Dictionary BuildRoot(string name, Dictionary dict) + { + var root = new Dictionary(); + root["name"] = name; + root["fields"] = new Dictionary(); + // iterate through fields and build leaf + foreach (var entry in dict) + { + var fields = (Dictionary) root["fields"]; + fields[entry.Key] = BuildNode(entry.Value); + } + return root; + } + + private static Dictionary BuildNode(object value) + { + switch (value) + { + case string v: + { + if (DateTime.TryParse(v, out _)) + { + return BuildTimestamp(v); + } + return BuildString(v); + } + case int v: + { + return BuildInteger(v); + } + case double v: + { + return BuildDouble(v); + } + case List> v: + { + return BuildArray(v); + } + case Dictionary v: + { + return BuildMap(v); + } + } + + throw new ArgumentException($"Can't build leaf! Unknown type for: {value}"); + } + + private static Dictionary BuildSimpleValue(string type, object value) + { + return new Dictionary() + { + [type] = value + }; + } + private static Dictionary BuildString(string value) + { + return BuildSimpleValue("stringValue", value); + } + private static Dictionary BuildInteger(int value) + { + return BuildSimpleValue("integerValue", value); + } + private static Dictionary BuildTimestamp(string value) + { + return BuildSimpleValue("timestampValue", value); + } + private static Dictionary BuildDouble(double value) + { + return BuildSimpleValue("doubleValue", value); + } + private static Dictionary BuildArray(List> array) + { + var root = new Dictionary(); + var values = new List>(); + foreach (var entry in array) + { + values.Add(BuildNode(entry)); + } + root["values"] = values; + return root; + } + + private static Dictionary BuildMap(Dictionary map) + { + var fields = new Dictionary(); + var root = new Dictionary + { + ["mapValue"] = new Dictionary + { + ["fields"] = fields + } + }; + foreach (var entry in map) + { + fields[entry.Key] = BuildNode(entry.Value); + } + return root; + } + } +} \ No newline at end of file diff --git a/NucuCar.UnitTests/NucuCar.Domain.Tests/Utilities/FirebaseRestTranslatorTests.cs b/NucuCar.UnitTests/NucuCar.Domain.Tests/Utilities/FirebaseRestTranslatorTests.cs new file mode 100644 index 0000000..e08372e --- /dev/null +++ b/NucuCar.UnitTests/NucuCar.Domain.Tests/Utilities/FirebaseRestTranslatorTests.cs @@ -0,0 +1,79 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using NucuCar.Domain.Utilities; +using Xunit; +using Xunit.Abstractions; + +namespace NucuCar.UnitTests.NucuCar.Domain.Tests.Utilities +{ + /* + { + "source":"NucuCar.Sensors", + "timestamp":"2019-12-01T23:26:13.5537227+02:00", + "data":[ + { + "sensor_state":2, + "temperature":32.65558333857916, + "humidity":100.0, + "pressure":62228.49565168124, + "voc":0.0, + "_id":"Bme680-Sensor" + }, + { + "sensor_state":2, + "cpu_temperature":48.849998474121094, + "_id":"CpuTemperature" + } + ] + } + */ + public class FirebaseRestTranslatorTests + { + private readonly ITestOutputHelper _testOutputHelper; + + public FirebaseRestTranslatorTests(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + } + + private Dictionary getBasicTelemetryData() + { + var basicTelemetryDict = new Dictionary + { + ["source"] = "NucuCar.Sensors", + ["timestamp"] = "2019-12-01T23:26:13.5537227+02:00" + }; + var data = new List> + { + new Dictionary() + { + ["sensor_state"] = 2, + ["cpu_temperature"] = 48.849998474121094, + ["_id"] = "CpuTemperature", + }, + new Dictionary() + { + ["sensor_state"] = 2, + ["temperature"] = 32.65, + ["humidity"] = 100.0, + ["pressure"] = 62228.49, + ["voc"] = 0.0, + ["_id"] = "Bme680-Sensor" + } + }; + basicTelemetryDict["data"] = data; + return basicTelemetryDict; + } + + [Fact] + public void Test_FireBaseTranslator_Parse() + { + var expectedJson = + "{\"name\":\"Test\",\"fields\":{\"source\":{\"stringValue\":\"NucuCar.Sensors\"},\"timestamp\":{\"timestampValue\":\"2019-12-01T23:26:13.5537227+02:00\"},\"data\":{\"values\":[{\"mapValue\":{\"fields\":{\"sensor_state\":{\"integerValue\":2},\"cpu_temperature\":{\"doubleValue\":48.849998474121094},\"_id\":{\"stringValue\":\"CpuTemperature\"}}}},{\"mapValue\":{\"fields\":{\"sensor_state\":{\"integerValue\":2},\"temperature\":{\"doubleValue\":32.65},\"humidity\":{\"doubleValue\":100.0},\"pressure\":{\"doubleValue\":62228.49},\"voc\":{\"doubleValue\":0.0},\"_id\":{\"stringValue\":\"Bme680-Sensor\"}}}}]}}}"; + var basicTelemetryData = getBasicTelemetryData(); + var result = FirebaseRestTranslator.Translate("Test", basicTelemetryData); + var json = JsonConvert.SerializeObject(result); + Assert.Equal(expectedJson, json); + } + } +} \ No newline at end of file