Skip to content

Commit

Permalink
Move delete serialization to dedicated class
Browse files Browse the repository at this point in the history
  • Loading branch information
simpat-adam committed Dec 6, 2023
1 parent 6cc6435 commit bb1b996
Show file tree
Hide file tree
Showing 13 changed files with 131 additions and 79 deletions.
2 changes: 1 addition & 1 deletion DataImport.Models.Tests/DataMapExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void SetUp()
};

var dataMapSerializer = new DataMapSerializer(_dataMap);
_dataMap.Map = dataMapSerializer.Serialize(mappings, false);
_dataMap.Map = dataMapSerializer.Serialize(mappings);
}

[Test]
Expand Down
26 changes: 13 additions & 13 deletions DataImport.Models.Tests/DataMapSerializerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public void ShouldSerializeAndDeserializeJsonMapRepresentationOfDeleteByIdMappin
}
}";

SerializeDeleteByIdMap(_resourceMetadata, mappings).ShouldMatch(jsonMap);
SerializeDeleteByIdMap(mappings).ShouldMatch(jsonMap);
DeserializeDeleteByIdMap(_resourceMetadata, jsonMap).Single().SourceColumn.ShouldMatch(mappings.Single().SourceColumn);
}

Expand Down Expand Up @@ -464,7 +464,7 @@ public void ShouldDeserializeFromPreviouslyParsedDeleteByIdJObject()
}
}";

DeserializeDeleteByIdMap(_resourceMetadata, JObject.Parse(jsonMap)).Single().SourceColumn.ShouldMatch(mappings.Single().SourceColumn);
DeserializeDeleteByIdMap(JObject.Parse(jsonMap)).Single().SourceColumn.ShouldMatch(mappings.Single().SourceColumn);
}

[Test]
Expand Down Expand Up @@ -1037,42 +1037,42 @@ private static JToken SerializeNormalMap(ResourceMetadata[] resourceMetadata, Da
{
var dataMapSerializer = new DataMapSerializer("/testResource", resourceMetadata);

return JToken.Parse(dataMapSerializer.Serialize(mappings, false));
return JToken.Parse(dataMapSerializer.Serialize(mappings));
}

private static JToken SerializeDeleteByIdMap(ResourceMetadata[] resourceMetadata, DataMapper[] mappings)
private static JToken SerializeDeleteByIdMap(DataMapper[] mappings)
{
var dataMapSerializer = new DataMapSerializer("/testResource", resourceMetadata);
var dataMapDeleteSerializer = new DeleteDataMapSerializer();

return JToken.Parse(dataMapSerializer.Serialize(mappings, true));
return JToken.Parse(dataMapDeleteSerializer.Serialize(mappings));
}

private static DataMapper[] DeserializeNormalMap(ResourceMetadata[] resourceMetadata, string jsonMap)
{
var dataMapSerializer = new DataMapSerializer("/testResource", resourceMetadata);

return dataMapSerializer.Deserialize(jsonMap, false);
return dataMapSerializer.Deserialize(jsonMap);
}

private static DataMapper[] DeserializeDeleteByIdMap(ResourceMetadata[] resourceMetadata, string jsonMap)
{
var dataMapSerializer = new DataMapSerializer("/testResource", resourceMetadata);
var dataMapSerializer = new DeleteDataMapSerializer();

return dataMapSerializer.Deserialize(jsonMap, true);
return dataMapSerializer.Deserialize(jsonMap);
}

private static DataMapper[] DeserializeNormalMap(ResourceMetadata[] resourceMetadata, JObject jsonMap)
{
var dataMapSerializer = new DataMapSerializer("/testResource", resourceMetadata);

return dataMapSerializer.Deserialize(jsonMap, false);
return dataMapSerializer.Deserialize(jsonMap);
}

private static DataMapper[] DeserializeDeleteByIdMap(ResourceMetadata[] resourceMetadata, JObject jsonMap)
private static DataMapper[] DeserializeDeleteByIdMap(JObject jsonMap)
{
var dataMapSerializer = new DataMapSerializer("/testResource", resourceMetadata);
var dataMapSerializer = new DeleteDataMapSerializer();

return dataMapSerializer.Deserialize(jsonMap, true);
return dataMapSerializer.Deserialize(jsonMap);
}
}
}
2 changes: 1 addition & 1 deletion DataImport.Models/DataMapExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static string[] ReferencedColumns(this DataMapper[] mappings)
private static DataMapper[] Mappings(DataMap dataMap)
{
var dataMapSerializer = new DataMapSerializer(dataMap);
return dataMapSerializer.Deserialize(dataMap.Map, false);
return dataMapSerializer.Deserialize(dataMap.Map);
}

private static IEnumerable<string> Yield(this IEnumerable<DataMapper> mappings, Func<DataMapper, string> propertyAccessor)
Expand Down
47 changes: 6 additions & 41 deletions DataImport.Models/DataMapSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,12 @@ public DataMapSerializer(string resourcePath, ResourceMetadata[] resourceMetadat
_resourceMetadatas = resourceMetadatas;
}

public string Serialize(DataMapper[] mappings, bool isDeleteByIdOperation)
public string Serialize(DataMapper[] mappings)
{
return isDeleteByIdOperation
? SerializeObjectForDeleteById(mappings.Single()).ToString(Formatting.Indented)
: SerializeObject(_resourceMetadatas, mappings).ToString(Formatting.Indented);
return SerializeObject(_resourceMetadatas, mappings).ToString(Formatting.Indented);
}

public DataMapper[] Deserialize(string jsonMap, bool isDeleteByIdOperation)
public DataMapper[] Deserialize(string jsonMap)
{
JObject jobject;
try
Expand All @@ -62,14 +60,12 @@ public DataMapper[] Deserialize(string jsonMap, bool isDeleteByIdOperation)
, exception);
}

return Deserialize(jobject, isDeleteByIdOperation);
return Deserialize(jobject);
}

public DataMapper[] Deserialize(JObject jsonMap, bool isDeleteByIdOperation)
public DataMapper[] Deserialize(JObject jsonMap)
{
return isDeleteByIdOperation
? DeserializeObjectForDeleteById(jsonMap).ToArray()
: DeserializeObject(_resourceMetadatas, jsonMap).ToArray();
return DeserializeObject(_resourceMetadatas, jsonMap).ToArray();
}

private JObject SerializeObject(IReadOnlyList<ResourceMetadata> nodeMetadatas, IReadOnlyList<DataMapper> nodes)
Expand Down Expand Up @@ -129,12 +125,6 @@ private JObject SerializeObject(IReadOnlyList<ResourceMetadata> nodeMetadatas, I
return result;
}

private JObject SerializeObjectForDeleteById(DataMapper node)
{
var result = new JObject { new JProperty("Id", new JObject { new JProperty("Column", node.SourceColumn) }) };
return result;
}

private JArray SerializeArray(ResourceMetadata arrayItemMetadata, IReadOnlyList<DataMapper> nodes)
{
var result = new JArray();
Expand Down Expand Up @@ -223,31 +213,6 @@ private List<DataMapper> DeserializeObject(IReadOnlyList<ResourceMetadata> nodeM
return result;
}

private List<DataMapper> DeserializeObjectForDeleteById(JToken objectToken)
{
var jobject = objectToken as JObject;

if (jobject == null)
throw new InvalidOperationException(
"Cannot deserialize mappings from JSON, because an object literal was expected. " +
"Instead, found: " +
$"{objectToken.ToString(Formatting.Indented)}");

var result = new List<DataMapper>();

var nodes = jobject.Children().Cast<JProperty>().ToArray();

var node = nodes.Single(n => n.Name == "Id");

var propertyValue = node.Children().Single();

var sourceColumn = ((JObject) propertyValue).Children().Cast<JProperty>().Single().Value;

result.Add(new DataMapper() { Name = "Id", SourceColumn = DeserializeRawValue(sourceColumn) });

return result;
}

private List<DataMapper> DeserializeArray(ResourceMetadata arrayItemMetadata, JToken arrayToken)
{
var array = arrayToken as JArray;
Expand Down
86 changes: 86 additions & 0 deletions DataImport.Models/DeleteDataMapSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: Apache-2.0
// Licensed to the Ed-Fi Alliance under one or more agreements.
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
// See the LICENSE and NOTICES files in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace DataImport.Models
{
public class DeleteDataMapSerializer
{
public string Serialize(DataMapper[] mappings)
{
return SerializeObjectForDeleteById(mappings.Single()).ToString(Formatting.Indented);
}

public DataMapper[] Deserialize(string jsonMap)
{
JObject jobject;
try
{
jobject = JObject.Parse(jsonMap);
}
catch (Exception exception)
{
throw new ArgumentException(
"Cannot deserialize mappings from JSON, because the map text is not a valid JSON object. " +
"Check the inner exception for details. Invalid JSON Map text:" +
$"{Environment.NewLine}{Environment.NewLine}{jsonMap}"
, exception);
}

return Deserialize(jobject);
}
public DataMapper[] Deserialize(JObject jsonMap)
{
return DeserializeObjectForDeleteById(jsonMap).ToArray();
}

private JObject SerializeObjectForDeleteById(DataMapper node)
{
var result = new JObject { new JProperty("Id", new JObject { new JProperty("Column", node.SourceColumn) }) };
return result;
}

private List<DataMapper> DeserializeObjectForDeleteById(JToken objectToken)
{
var jobject = objectToken as JObject;

if (jobject == null)
throw new InvalidOperationException(
"Cannot deserialize mappings from JSON, because an object literal was expected. " +
"Instead, found: " +
$"{objectToken.ToString(Formatting.Indented)}");

var result = new List<DataMapper>();

var nodes = jobject.Children().Cast<JProperty>().ToArray();

var node = nodes.Single(n => n.Name == "Id");

var propertyValue = node.Children().Single();

var sourceColumn = ((JObject) propertyValue).Children().Cast<JProperty>().Single().Value;

result.Add(new DataMapper() { Name = "Id", SourceColumn = DeserializeRawValue(sourceColumn) });

return result;
}

private static string DeserializeRawValue(object rawValue)
{
if (rawValue == null)
return null;

if (rawValue is bool)
return rawValue.ToString().ToLower();

return rawValue.ToString();
}
}
}
4 changes: 2 additions & 2 deletions DataImport.Models/MetadataValidationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ private static bool IsObjectCompatibleWithResource(this JObject jsonMap, Resourc
try
{
var serializer = new DataMapSerializer(resource);
var deserialized = serializer.Deserialize(jsonMap, false);
var deserialized = serializer.Deserialize(jsonMap);

if (level == MetadataCompatibilityLevel.Bootstrap && deserialized.ReferencedColumns().Any())
throw new Exception("Bootstrap JSON cannot include column references.");

serializer.Serialize(deserialized, false);
serializer.Serialize(deserialized);
exceptionMessage = null;
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ public ResourceMapper(ILogger logger, DataMap dataMap, LookupCollection mappingL
{
_logger = logger;

var dataMapSerializer = new DataMapSerializer(dataMap);
_mappings = dataMapSerializer.Deserialize(dataMap.Map, dataMap.IsDeleteOperation);
_mappings = dataMap.IsDeleteOperation
? new DeleteDataMapSerializer().Deserialize(dataMap.Map)
: new DataMapSerializer(dataMap).Deserialize(dataMap.Map);
_resourceMetadata = ResourceMetadata.DeserializeFrom(dataMap);
_mappingLookups = mappingLookups;
}
Expand Down
14 changes: 7 additions & 7 deletions DataImport.Web.Tests/Features/DataMaps/AddEditDataMapsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public async Task ShouldSuccessfullyAddDataMap()
var apiVersion = Query(d => d.ApiVersions.Single(x => x.Id == resource.ApiVersionId));

var dataMapSerializer = new DataMapSerializer(resource);
var expectedJsonMap = dataMapSerializer.Serialize(mappings, false);
var expectedJsonMap = dataMapSerializer.Serialize(mappings);
var sourceCsvHeaders = new[] { "ColA", "ColB", "ColC" };

var addForm = await Send(new AddDataMap.Query { SourceCsvHeaders = sourceCsvHeaders });
Expand Down Expand Up @@ -183,8 +183,8 @@ public async Task ShouldSuccessfullyAddDeleteByIdDataMap()
var mappings = (await TrivialMappings(resource)).Take(1).ToArray();
var apiVersion = Query(d => d.ApiVersions.Single(x => x.Id == resource.ApiVersionId));

var dataMapSerializer = new DataMapSerializer(resource);
var expectedJsonMap = dataMapSerializer.Serialize(mappings, true);
var dataMapSerializer = new DeleteDataMapSerializer();
var expectedJsonMap = dataMapSerializer.Serialize(mappings);
var sourceCsvHeaders = new[] { "ColA", "ColB", "ColC" };

var addForm = await Send(new AddDataMap.Query { SourceCsvHeaders = sourceCsvHeaders });
Expand Down Expand Up @@ -274,7 +274,7 @@ public async Task ShouldSuccessfullyEditDataMap()
var columnHeaders = new[] { "ColA", "ColB", "ColC" };

var dataMapSerializer = new DataMapSerializer(resource);
var expectedJsonMap = dataMapSerializer.Serialize(updatedMappings, false);
var expectedJsonMap = dataMapSerializer.Serialize(updatedMappings);

var response = await Send(new AddDataMap.Command
{
Expand Down Expand Up @@ -352,11 +352,11 @@ public async Task ShouldSuccessfullyEditDeleteByIdDataMap()
var updatedMapName = SampleString();
var initialMappings = (await TrivialMappings(resource)).Take(1).ToArray();
var updatedMappings = (await TrivialMappings(resource)).Take(1).ToArray();

var columnHeaders = new[] { "ColA", "ColB", "ColC" };

var dataMapSerializer = new DataMapSerializer(resource);
var expectedJsonMap = dataMapSerializer.Serialize(updatedMappings, true);
var dataMapSerializer = new DeleteDataMapSerializer();
var expectedJsonMap = dataMapSerializer.Serialize(updatedMappings);

var response = await Send(new AddDataMap.Command
{
Expand Down
4 changes: 2 additions & 2 deletions DataImport.Web.Tests/Features/Shared/JsonMapFormatTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ private static void AllResourcesCanSerializeAndDeserializeWithoutDataLoss()

var dataMapSerializer = new DataMapSerializer(resource);

var serializedToJsonMap = dataMapSerializer.Serialize(originalMappings, false);
var deserializedFromJsonMap = dataMapSerializer.Deserialize(serializedToJsonMap, false);
var serializedToJsonMap = dataMapSerializer.Serialize(originalMappings);
var deserializedFromJsonMap = dataMapSerializer.Deserialize(serializedToJsonMap);

// Serializing and deserializing should be an identity operation.
deserializedFromJsonMap.ShouldMatch(originalMappings);
Expand Down
2 changes: 0 additions & 2 deletions DataImport.Web.Tests/SetUpFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
// See the LICENSE and NOTICES files in the project root for more information.

using System;
using DataImport.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Serilog;
using static DataImport.Web.Tests.Testing;

Expand Down
4 changes: 3 additions & 1 deletion DataImport.Web/Features/DataMaps/AddDataMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ protected override Response Handle(Command request)
{
Name = request.MapName,
ResourcePath = resource.Path,
Map = dataMapSerializer.Serialize(request.Mappings, request.IsDeleteOperation),
Map = request.IsDeleteOperation
? new DeleteDataMapSerializer().Serialize(request.Mappings)
: new DataMapSerializer(resource).Serialize(request.Mappings),
Metadata = resource.Metadata,
CreateDate = DateTimeOffset.Now,
UpdateDate = DateTimeOffset.Now,
Expand Down
12 changes: 6 additions & 6 deletions DataImport.Web/Features/DataMaps/EditDataMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ protected override AddEditDataMapViewModel Handle(Query request)

var resourceMetadata = ResourceMetadata.DeserializeFrom(dataMap);

var dataMapSerializer = new DataMapSerializer(dataMap);

return new AddEditDataMapViewModel
{
DataMapId = mapId,
Expand All @@ -61,7 +59,9 @@ protected override AddEditDataMapViewModel Handle(Query request)
SourceTables = DataMapperFields.MapLookupTablesToViewModel(_database),
SourceColumns = DataMapperFields.MapCsvHeadersToSourceColumns(columnHeaders),
ResourceMetadata = resourceMetadata,
Mappings = dataMapSerializer.Deserialize(dataMap.Map, dataMap.IsDeleteOperation)
Mappings = dataMap.IsDeleteOperation
? new DeleteDataMapSerializer().Deserialize(dataMap.Map)
: new DataMapSerializer(dataMap).Deserialize(dataMap.Map),
},

MapName = dataMap.Name,
Expand Down Expand Up @@ -135,10 +135,10 @@ protected override ToastResponse Handle(Command request)
{
var map = _dataImportDbContext.DataMaps.FirstOrDefault(x => x.Id == request.DataMapId) ?? new DataMap();

var dataMapSerializer = new DataMapSerializer(map);

map.Name = request.MapName;
map.Map = dataMapSerializer.Serialize(request.Mappings, request.IsDeleteOperation);
map.Map = request.IsDeleteOperation
? new DeleteDataMapSerializer().Serialize(request.Mappings)
: new DataMapSerializer(map).Serialize(request.Mappings);
map.ColumnHeaders = JsonConvert.SerializeObject(request.ColumnHeaders);
map.UpdateDate = DateTimeOffset.Now;
map.FileProcessorScriptId = request.PreprocessorId;
Expand Down
Loading

0 comments on commit bb1b996

Please sign in to comment.