/* * Copyright (c) 2023 Proton AG * * This file is part of ProtonVPN. * * ProtonVPN is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ProtonVPN is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ProtonVPN. If not, see . */ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json; using NSubstitute; using ProtonVPN.Serialization.Contracts; using ProtonVPN.Serialization.Contracts.Json; using ProtonVPN.Serialization.Tests.Mocks; namespace ProtonVPN.Serialization.Tests; [TestClass] public class JsonSerializerTest { [TestMethod] public void SerializeToString_ShouldSerialize_ToJson() { // Arrange SampleContract value = new() { Number = 34, Name = "ZgD" }; IJsonSerializer serializer = new Json.JsonSerializer(new List()); // Act string result = serializer.SerializeToString(value); // Assert result.Should().Be("{\"Number\":34,\"Name\":\"ZgD\"}"); } [TestMethod] public void DeserializeFromString_ShouldHave_ExpectedPropertyValues() { // Arrange string json = "{\"Number\":199,\"Name\":\"Super Mario\"}"; IJsonSerializer serializer = new Json.JsonSerializer(new List()); // Act SampleContract? result = serializer.DeserializeFromString(json); // Assert result?.Number.Should().Be(199); result?.Name.Should().Be("Super Mario"); } [TestMethod] public void DeserializeFromString_ShouldThrow_ExpectedException_WhenNotCorrectJson() { // Arrange string json = "{Segment"; IJsonSerializer serializer = new Json.JsonSerializer(new List()); // Act Action action = () => serializer.DeserializeFromString(json); // Assert action.Should().Throw(); } [TestMethod] public void DeserializeFromString_ShouldDeserializeExplicitContracts() { // Arrange string json = "{\"Name\":\"Hulk\"}"; List interfaceImplementations = new() { InterfaceImplementation.Create() }; IJsonContractDeserializer jsonContractDeserializer = Substitute.For(); jsonContractDeserializer.Get().Returns(interfaceImplementations); IJsonSerializer serializer = new Json.JsonSerializer(new List() { jsonContractDeserializer }); // Act IUser user = serializer.DeserializeFromString(json)!; // Assert user!.Name.Should().Be("Hulk"); } [TestMethod] public void DeserializeFromString_ShouldNotDeserializeNonExplicitContracts() { // Arrange string json = "{\"Name\":\"Hulk\"}"; IJsonSerializer serializer = new Json.JsonSerializer(new List()); // Act Exception exception = Assert.Throws(() => serializer.DeserializeFromString(json)); Assert.Contains($"Could not create an instance of type {typeof(IUser).FullName}. " + $"Type is an interface or abstract class and cannot be instantiated.", exception.Message); } [TestMethod] public void DeserializeFirstLevel() { // Arrange string json = "{\"User\":{\"Name\":\"Harry Potter\"},\"Device\":{\"Code\":1893}}"; List interfaceImplementations = new() { /*InterfaceImplementation.Create()*/ }; IJsonContractDeserializer jsonContractDeserializer = Substitute.For(); jsonContractDeserializer.Get().Returns(interfaceImplementations); IJsonSerializer serializer = new Json.JsonSerializer(new List() { jsonContractDeserializer }); // Act IDictionary configJsonProperties = serializer.DeserializeFirstLevel(json)!; // Assert Assert.HasCount(2, configJsonProperties); Assert.IsTrue(configJsonProperties.ContainsKey("User")); Assert.AreEqual("{\"Name\":\"Harry Potter\"}", configJsonProperties["User"]); Assert.IsTrue(configJsonProperties.ContainsKey("Device")); Assert.AreEqual("{\"Code\":1893}", configJsonProperties["Device"]); } }