Skip to content

Commit 20973e9

Browse files
authored
Merge pull request #136 from contentstack/feat/DX-3375-Fetch-Asset-By-Other_Field
Add tests for VersionUtility methods and update copyright year to 2025
2 parents 4d66d8d + 83a6504 commit 20973e9

File tree

5 files changed

+431
-15
lines changed

5 files changed

+431
-15
lines changed

Contentstack.AspNetCore/Contentstack.AspNetCore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<Owners>Contentstack</Owners>
99
<PackageVersion>$(Version)</PackageVersion>
1010
<Description>Main release</Description>
11-
<Copyright>Copyright (c) 2012-2024 Contentstack (http://app.contentstack.com). All Rights Reserved</Copyright>
11+
<Copyright>Copyright (c) 2012-2025 Contentstack (http://app.contentstack.com). All Rights Reserved</Copyright>
1212
<PackageProjectUrl>https://github.com/contentstack/contentstack-dotnet</PackageProjectUrl>
1313
<PackageTags>v$(Version)</PackageTags>
1414
<ReleaseVersion>$(Version)</ReleaseVersion>
Lines changed: 379 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,379 @@
1+
using System;
2+
using System.Reflection;
3+
using Contentstack.Core.Internals;
4+
using Xunit;
5+
6+
namespace Contentstack.Core.Tests
7+
{
8+
public class VersionUtilityTest
9+
{
10+
#region GetSdkVersion Tests
11+
12+
[Fact]
13+
public void GetSdkVersion_ReturnsValidFormat()
14+
{
15+
// Act
16+
var version = VersionUtility.GetSdkVersion();
17+
18+
// Assert
19+
Assert.NotNull(version);
20+
Assert.StartsWith("contentstack-delivery-dotnet/", version);
21+
Assert.True(version.Length > "contentstack-delivery-dotnet/".Length);
22+
}
23+
24+
[Fact]
25+
public void GetSdkVersion_ReturnsConsistentResult()
26+
{
27+
// Act
28+
var version1 = VersionUtility.GetSdkVersion();
29+
var version2 = VersionUtility.GetSdkVersion();
30+
31+
// Assert
32+
Assert.Equal(version1, version2);
33+
}
34+
35+
[Fact]
36+
public void GetSdkVersion_DoesNotReturnNull()
37+
{
38+
// Act
39+
var version = VersionUtility.GetSdkVersion();
40+
41+
// Assert
42+
Assert.NotNull(version);
43+
Assert.NotEmpty(version);
44+
}
45+
46+
[Fact]
47+
public void GetSdkVersion_DoesNotReturnEmptyString()
48+
{
49+
// Act
50+
var version = VersionUtility.GetSdkVersion();
51+
52+
// Assert
53+
Assert.NotEmpty(version);
54+
}
55+
56+
[Fact]
57+
public void GetSdkVersion_ContainsExpectedPrefix()
58+
{
59+
// Act
60+
var version = VersionUtility.GetSdkVersion();
61+
62+
// Assert
63+
Assert.StartsWith("contentstack-delivery-dotnet/", version);
64+
}
65+
66+
[Fact]
67+
public void GetSdkVersion_DoesNotContainSpaces()
68+
{
69+
// Act
70+
var version = VersionUtility.GetSdkVersion();
71+
72+
// Assert
73+
Assert.DoesNotContain(" ", version);
74+
}
75+
76+
[Fact]
77+
public void GetSdkVersion_DoesNotContainNewlines()
78+
{
79+
// Act
80+
var version = VersionUtility.GetSdkVersion();
81+
82+
// Assert
83+
Assert.DoesNotContain("\n", version);
84+
Assert.DoesNotContain("\r", version);
85+
}
86+
87+
#endregion
88+
89+
#region ExtractSemanticVersion Tests (via Reflection)
90+
91+
[Theory]
92+
[InlineData("1.2.3", "1.2.3")]
93+
[InlineData("1.2.3-beta.1", "1.2.3-beta")]
94+
[InlineData("1.2.3+abc123", "1.2.3")]
95+
[InlineData("1.2.3-beta.1+abc123", "1.2.3-beta")]
96+
[InlineData("2.25.0", "2.25.0")]
97+
[InlineData("2.25.0-beta.1", "2.25.0-beta")]
98+
[InlineData("2.25.0+abc123", "2.25.0")]
99+
[InlineData("2.25.0-beta.1+abc123", "2.25.0-beta")]
100+
[InlineData("10.20.30", "10.20.30")]
101+
[InlineData("0.1.0", "0.1.0")]
102+
public void ExtractSemanticVersion_ValidInputs_ReturnsCorrectVersion(string input, string expected)
103+
{
104+
// Arrange
105+
var method = typeof(VersionUtility).GetMethod("ExtractSemanticVersion", BindingFlags.NonPublic | BindingFlags.Static);
106+
107+
// Act
108+
var result = method.Invoke(null, new object[] { input }) as string;
109+
110+
// Assert
111+
Assert.Equal(expected, result);
112+
}
113+
114+
[Theory]
115+
[InlineData("1.2")]
116+
[InlineData("1")]
117+
[InlineData("")]
118+
[InlineData("invalid")]
119+
[InlineData(" ")]
120+
[InlineData("\t")]
121+
[InlineData("\n")]
122+
[InlineData("\r\n")]
123+
public void ExtractSemanticVersion_InvalidInputs_ReturnsNull(string input)
124+
{
125+
// Arrange
126+
var method = typeof(VersionUtility).GetMethod("ExtractSemanticVersion", BindingFlags.NonPublic | BindingFlags.Static);
127+
128+
// Act
129+
var result = method.Invoke(null, new object[] { input }) as string;
130+
131+
// Assert
132+
Assert.Null(result);
133+
}
134+
135+
[Fact]
136+
public void ExtractSemanticVersion_NullInput_ReturnsNull()
137+
{
138+
// Arrange
139+
var method = typeof(VersionUtility).GetMethod("ExtractSemanticVersion", BindingFlags.NonPublic | BindingFlags.Static);
140+
141+
// Act
142+
var result = method.Invoke(null, new object[] { null }) as string;
143+
144+
// Assert
145+
Assert.Null(result);
146+
}
147+
148+
[Theory]
149+
[InlineData("1.2.3+", "1.2.3")] // Should handle trailing + correctly
150+
[InlineData(" 1.2.3 ", "1.2.3")] // Should handle whitespace
151+
[InlineData("1.2.3.4.5", "1.2.3")] // Should handle extra version parts
152+
public void ExtractSemanticVersion_ImprovedHandling_WorksCorrectly(string input, string expected)
153+
{
154+
// Arrange
155+
var method = typeof(VersionUtility).GetMethod("ExtractSemanticVersion", BindingFlags.NonPublic | BindingFlags.Static);
156+
157+
// Act
158+
var result = method.Invoke(null, new object[] { input }) as string;
159+
160+
// Assert
161+
Assert.Equal(expected, result);
162+
}
163+
164+
[Theory]
165+
[InlineData("1.2.3.4", "1.2.3")] // Should take only first 3 parts
166+
[InlineData("1.2.3.4.5.6", "1.2.3")] // Should take only first 3 parts
167+
[InlineData("1.2.3.4.5", "1.2.3")] // Should take only first 3 parts
168+
public void ExtractSemanticVersion_MoreThanThreeParts_TakesFirstThree(string input, string expected)
169+
{
170+
// Arrange
171+
var method = typeof(VersionUtility).GetMethod("ExtractSemanticVersion", BindingFlags.NonPublic | BindingFlags.Static);
172+
173+
// Act
174+
var result = method.Invoke(null, new object[] { input }) as string;
175+
176+
// Assert
177+
Assert.Equal(expected, result);
178+
}
179+
180+
[Theory]
181+
[InlineData("1.2.3+metadata", "1.2.3")]
182+
[InlineData("1.2.3-beta.1+metadata", "1.2.3-beta")]
183+
[InlineData("1.2.3+very-long-metadata-string", "1.2.3")]
184+
[InlineData("1.2.3+", "1.2.3")]
185+
public void ExtractSemanticVersion_WithBuildMetadata_RemovesMetadata(string input, string expected)
186+
{
187+
// Arrange
188+
var method = typeof(VersionUtility).GetMethod("ExtractSemanticVersion", BindingFlags.NonPublic | BindingFlags.Static);
189+
190+
// Act
191+
var result = method.Invoke(null, new object[] { input }) as string;
192+
193+
// Assert
194+
Assert.Equal(expected, result);
195+
}
196+
197+
[Theory]
198+
[InlineData("1.2.3-beta.1", "1.2.3-beta")]
199+
[InlineData("1.2.3-alpha.1", "1.2.3-alpha")]
200+
[InlineData("1.2.3-rc.1", "1.2.3-rc")]
201+
[InlineData("1.2.3-preview.1", "1.2.3-preview")]
202+
public void ExtractSemanticVersion_WithPreReleaseIdentifiers_KeepsPreRelease(string input, string expected)
203+
{
204+
// Arrange
205+
var method = typeof(VersionUtility).GetMethod("ExtractSemanticVersion", BindingFlags.NonPublic | BindingFlags.Static);
206+
207+
// Act
208+
var result = method.Invoke(null, new object[] { input }) as string;
209+
210+
// Assert
211+
Assert.Equal(expected, result);
212+
}
213+
214+
#endregion
215+
216+
#region Edge Cases and Error Scenarios
217+
218+
[Fact]
219+
public void GetSdkVersion_HandlesExceptions_Gracefully()
220+
{
221+
// This test ensures that GetSdkVersion doesn't throw exceptions
222+
// and returns a fallback value when assembly reflection fails
223+
224+
// Act & Assert - should not throw
225+
var version = VersionUtility.GetSdkVersion();
226+
Assert.NotNull(version);
227+
Assert.NotEmpty(version);
228+
}
229+
230+
[Fact]
231+
public void GetSdkVersion_ReturnsFallbackWhenAssemblyVersionIsInvalid()
232+
{
233+
// This test verifies that when assembly version is 0.0.0.0 or invalid,
234+
// the method falls back to other version sources or returns "dev"
235+
236+
// Act
237+
var version = VersionUtility.GetSdkVersion();
238+
239+
// Assert
240+
Assert.NotNull(version);
241+
Assert.True(version == "contentstack-delivery-dotnet/dev" ||
242+
version.StartsWith("contentstack-delivery-dotnet/"));
243+
}
244+
245+
[Theory]
246+
[InlineData("")]
247+
[InlineData(" ")]
248+
[InlineData(" ")]
249+
[InlineData("\t")]
250+
[InlineData("\n")]
251+
[InlineData("\r\n")]
252+
public void ExtractSemanticVersion_WhitespaceInputs_ReturnsNull(string input)
253+
{
254+
// Arrange
255+
var method = typeof(VersionUtility).GetMethod("ExtractSemanticVersion", BindingFlags.NonPublic | BindingFlags.Static);
256+
257+
// Act
258+
var result = method.Invoke(null, new object[] { input }) as string;
259+
260+
// Assert
261+
Assert.Null(result);
262+
}
263+
264+
[Theory]
265+
[InlineData("1.2.3.4.5.6.7.8.9.10")] // Very long version
266+
[InlineData("999999999.999999999.999999999")] // Very large numbers
267+
[InlineData("0.0.0")] // All zeros
268+
public void ExtractSemanticVersion_EdgeCaseInputs_HandlesCorrectly(string input)
269+
{
270+
// Arrange
271+
var method = typeof(VersionUtility).GetMethod("ExtractSemanticVersion", BindingFlags.NonPublic | BindingFlags.Static);
272+
273+
// Act
274+
var result = method.Invoke(null, new object[] { input }) as string;
275+
276+
// Assert
277+
if (input == "0.0.0")
278+
{
279+
Assert.Equal("0.0.0", result);
280+
}
281+
else
282+
{
283+
Assert.NotNull(result);
284+
Assert.True(result.Split('.').Length == 3);
285+
}
286+
}
287+
288+
[Fact]
289+
public void ExtractSemanticVersion_HandlesExceptions_Gracefully()
290+
{
291+
// This test ensures that ExtractSemanticVersion doesn't throw exceptions
292+
// and returns null when parsing fails
293+
294+
// Arrange
295+
var method = typeof(VersionUtility).GetMethod("ExtractSemanticVersion", BindingFlags.NonPublic | BindingFlags.Static);
296+
297+
// Act & Assert - should not throw
298+
var result = method.Invoke(null, new object[] { "invalid-version-string" }) as string;
299+
Assert.Null(result);
300+
}
301+
302+
#endregion
303+
304+
#region Integration Tests
305+
306+
[Fact]
307+
public void GetSdkVersion_Integration_ReturnsValidUserAgentFormat()
308+
{
309+
// Act
310+
var version = VersionUtility.GetSdkVersion();
311+
312+
// Assert
313+
Assert.NotNull(version);
314+
Assert.StartsWith("contentstack-delivery-dotnet/", version);
315+
316+
// Verify it's in a format suitable for User-Agent headers
317+
Assert.DoesNotContain(" ", version);
318+
Assert.DoesNotContain("\n", version);
319+
Assert.DoesNotContain("\r", version);
320+
Assert.DoesNotContain("\t", version);
321+
}
322+
323+
[Fact]
324+
public void GetSdkVersion_Integration_CanBeUsedInHttpHeaders()
325+
{
326+
// Act
327+
var version = VersionUtility.GetSdkVersion();
328+
329+
// Assert
330+
// Verify the version string is suitable for HTTP headers
331+
Assert.NotNull(version);
332+
Assert.NotEmpty(version);
333+
334+
// Should not contain characters that would break HTTP headers
335+
Assert.DoesNotContain("\"", version);
336+
Assert.DoesNotContain("'", version);
337+
Assert.DoesNotContain("\n", version);
338+
Assert.DoesNotContain("\r", version);
339+
}
340+
341+
#endregion
342+
343+
#region Performance Tests
344+
345+
[Fact]
346+
public void GetSdkVersion_Performance_ReturnsQuickly()
347+
{
348+
// Act & Assert
349+
var startTime = DateTime.UtcNow;
350+
var version = VersionUtility.GetSdkVersion();
351+
var endTime = DateTime.UtcNow;
352+
353+
// Should complete quickly (less than 1 second)
354+
var duration = endTime - startTime;
355+
Assert.True(duration.TotalSeconds < 1, $"GetSdkVersion took {duration.TotalSeconds} seconds");
356+
Assert.NotNull(version);
357+
}
358+
359+
[Fact]
360+
public void GetSdkVersion_Performance_MultipleCalls_Consistent()
361+
{
362+
// Act
363+
var versions = new string[100];
364+
for (int i = 0; i < 100; i++)
365+
{
366+
versions[i] = VersionUtility.GetSdkVersion();
367+
}
368+
369+
// Assert
370+
var firstVersion = versions[0];
371+
for (int i = 1; i < versions.Length; i++)
372+
{
373+
Assert.Equal(firstVersion, versions[i]);
374+
}
375+
}
376+
377+
#endregion
378+
}
379+
}

0 commit comments

Comments
 (0)