Skip to content

Commit 8147ddd

Browse files
committed
Reduce duplication
1 parent 818c3e6 commit 8147ddd

File tree

4 files changed

+281
-82
lines changed

4 files changed

+281
-82
lines changed

src/dms/tests/EdFi.DataManagementService.Tests.E2E/Features/General/KafkaMessaging.feature

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,15 @@ Feature: Kafka Messaging
2222
"lastSurname": "Student"
2323
}
2424
"""
25-
Then it should respond with status 201
25+
Then it should respond with 201
2626
And a Kafka message received on topic "edfi.dms.document" should contain in the edfidoc field
2727
"""
28-
"studentUniqueId": "KAFKA_TEST_001"
28+
{
29+
"id": "{id}",
30+
"studentUniqueId": "KAFKA_TEST_001",
31+
"birthDate": "2009-01-01",
32+
"firstName": "KafkaTest",
33+
"lastSurname": "Student"
34+
}
2935
"""
3036

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Licensed to the Ed-Fi Alliance under one or more agreements.
3+
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
4+
// See the LICENSE and NOTICES files in the project root for more information.
5+
6+
using System.Text.Json;
7+
using System.Text.Json.Nodes;
8+
using System.Text.RegularExpressions;
9+
using EdFi.DataManagementService.Tests.E2E.Extensions;
10+
using FluentAssertions;
11+
using static EdFi.DataManagementService.Tests.E2E.Management.JsonComparer;
12+
13+
namespace EdFi.DataManagementService.Tests.E2E.Management;
14+
15+
public static partial class JsonTestUtilities
16+
{
17+
private static readonly Regex _findIds = IdRegex();
18+
19+
public static bool CompareJsonWithPlaceholderReplacement(
20+
string expectedBody,
21+
JsonNode actualJson,
22+
string id = "",
23+
string dependentId = "",
24+
string etag = "",
25+
IReadOnlyDictionary<string, string>? variableReplacements = null,
26+
string baseUrl = "",
27+
string oauthUrl = "",
28+
bool removeMetadataFromActual = true,
29+
bool removeEtagFromActual = true
30+
)
31+
{
32+
// Process the actual JSON
33+
JsonNode processedActualJson = actualJson.DeepClone()!;
34+
35+
if (removeMetadataFromActual)
36+
{
37+
CheckAndRemoveMetadata(processedActualJson, removeEtagFromActual);
38+
}
39+
40+
// Replace placeholders in expected body
41+
string processedExpectedBody = ReplacePlaceholders(
42+
expectedBody,
43+
actualJson,
44+
id,
45+
dependentId,
46+
etag,
47+
variableReplacements,
48+
baseUrl,
49+
oauthUrl
50+
);
51+
52+
JsonNode expectedJson = JsonNode.Parse(processedExpectedBody)!;
53+
54+
// Remove correlationId from both if present (as it's dynamic)
55+
(processedActualJson as JsonObject)?.Remove("correlationId");
56+
(expectedJson as JsonObject)?.Remove("correlationId");
57+
58+
return AreEqual(expectedJson, processedActualJson);
59+
}
60+
61+
public static string ReplacePlaceholders(
62+
string body,
63+
JsonNode responseJson,
64+
string id = "",
65+
string dependentId = "",
66+
string etag = "",
67+
IReadOnlyDictionary<string, string>? variableReplacements = null,
68+
string baseUrl = "",
69+
string oauthUrl = ""
70+
)
71+
{
72+
string replacedBody = "";
73+
if (body.TrimStart().StartsWith('['))
74+
{
75+
var responseAsArray = responseJson.AsArray();
76+
if (responseAsArray == null || responseAsArray.Count == 0)
77+
{
78+
return body;
79+
}
80+
81+
int index = 0;
82+
replacedBody = _findIds.Replace(
83+
body,
84+
match =>
85+
{
86+
var idValue = responseJson[index]?["id"]?.ToString();
87+
index++;
88+
return idValue ?? match.ToString();
89+
}
90+
);
91+
}
92+
else
93+
{
94+
replacedBody = _findIds.Replace(
95+
body,
96+
match =>
97+
{
98+
var idValue = responseJson["id"]?.ToString();
99+
return idValue ?? match.ToString();
100+
}
101+
);
102+
}
103+
104+
// Replace other placeholders
105+
replacedBody = replacedBody
106+
.Replace("{id}", id)
107+
.Replace("{dependentId}", dependentId)
108+
.Replace("{etag}", etag);
109+
110+
if (!string.IsNullOrEmpty(baseUrl))
111+
{
112+
replacedBody = replacedBody.Replace("{BASE_URL}/", baseUrl);
113+
}
114+
115+
if (!string.IsNullOrEmpty(oauthUrl))
116+
{
117+
replacedBody = replacedBody.Replace("{OAUTH_URL}", oauthUrl);
118+
}
119+
120+
if (variableReplacements != null)
121+
{
122+
replacedBody = replacedBody.ReplacePlaceholdersWithDictionaryValues(variableReplacements);
123+
}
124+
125+
return replacedBody;
126+
}
127+
128+
private static bool AreEqual(JsonNode expectedBodyJson, JsonNode responseJson)
129+
{
130+
JsonNode orderedResponseJson = OrderJsonProperties(responseJson);
131+
JsonNode orderedExpectedJson = OrderJsonProperties(expectedBodyJson);
132+
133+
JsonElement expectedElement = JsonDocument.Parse(orderedExpectedJson.ToJsonString()).RootElement;
134+
JsonElement responseElement = JsonDocument.Parse(orderedResponseJson.ToJsonString()).RootElement;
135+
136+
return JsonElementEqualityComparer.Instance.Equals(expectedElement, responseElement);
137+
}
138+
139+
private static void CheckAndRemoveMetadata(JsonNode responseJson, bool removeEtag)
140+
{
141+
if (responseJson is JsonArray jsonArray && jsonArray.Count > 0)
142+
{
143+
foreach (JsonObject? item in jsonArray.Cast<JsonObject?>())
144+
{
145+
if (item != null)
146+
{
147+
var lastModifiedDate = LastModifiedDate(item);
148+
lastModifiedDate.Should().NotBeNull();
149+
item.Remove("_lastModifiedDate");
150+
151+
var eTag = Etag(item);
152+
eTag.Should().NotBeNull();
153+
if (removeEtag)
154+
{
155+
item.Remove("_etag");
156+
}
157+
}
158+
}
159+
}
160+
else if (responseJson is JsonObject jsonObject && jsonObject.Count > 0)
161+
{
162+
var lastModifiedDate = LastModifiedDate(responseJson);
163+
lastModifiedDate.Should().NotBeNull();
164+
(responseJson as JsonObject)?.Remove("_lastModifiedDate");
165+
166+
var eTag = Etag(responseJson);
167+
eTag.Should().NotBeNull();
168+
if (removeEtag)
169+
{
170+
(responseJson as JsonObject)?.Remove("_etag");
171+
}
172+
}
173+
}
174+
175+
private static string? LastModifiedDate(JsonNode response)
176+
{
177+
if (
178+
response is JsonObject jsonObject
179+
&& jsonObject.TryGetPropertyValue("_lastModifiedDate", out JsonNode? lastModifiedDate)
180+
&& lastModifiedDate != null
181+
)
182+
{
183+
return lastModifiedDate.GetValue<string?>();
184+
}
185+
return null;
186+
}
187+
188+
private static string? Etag(JsonNode response)
189+
{
190+
if (
191+
response is JsonObject jsonObject
192+
&& jsonObject.TryGetPropertyValue("_etag", out JsonNode? etag)
193+
&& etag != null
194+
)
195+
{
196+
return etag.GetValue<string?>();
197+
}
198+
return null;
199+
}
200+
201+
[GeneratedRegex(@"\{id\}", RegexOptions.Compiled)]
202+
private static partial Regex IdRegex();
203+
}

0 commit comments

Comments
 (0)