Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Unit Test
on:
pull_request:
push:

jobs:
unit-test:
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4.2.2
- name: Setup .NET Core @ Latest
uses: actions/setup-dotnet@v4.3.0
- name: Build solution and run unit tests
run: sh ./Scripts/run-unit-test-case.sh
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### Version: 1.2.0
#### Date: March-31-2026
- Added `GetVariantMetadataTags(JObject, string)` and `GetVariantMetadataTags(JArray, string)` as the canonical API for building the `data-csvariants` payload (same behavior as the previous helpers).
- `GetDataCsvariantsAttribute` is now obsolete and delegates to `GetVariantMetadataTags`; it will be removed in a future major release. Existing callers remain binary-compatible.

### Version: 1.1.0
#### Date: March-24-2026
- Added `GetVariantAliases` and `GetDataCsvariantsAttribute` for variant alias extraction and `data-csvariants` serialization; Invalid arguments throw `ArgumentException`.
Expand Down
11 changes: 3 additions & 8 deletions Contentstack.Utils.Tests/Contentstack.Utils.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="coverlet.collector" Version="6.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand All @@ -21,11 +21,6 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Reference Include="Contentstack.Utils">
<HintPath>..\Contentstack.Utils\bin\Debug\netstandard2.0\Contentstack.Utils.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contentstack.Utils\Contentstack.Utils.csproj" />
</ItemGroup>
Expand Down
52 changes: 40 additions & 12 deletions Contentstack.Utils.Tests/VariantAliasesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ public void GetVariantAliases_SingleEntry_ReturnsAliases()
}

[Fact]
public void GetDataCsvariantsAttribute_SingleEntry_ReturnsJsonArrayString()
public void GetVariantMetadataTags_SingleEntry_ReturnsJsonArrayString()
{
JObject full = ReadJsonRoot("variantsSingleEntry.json");
JObject entry = (JObject)full["entry"];
const string contentTypeUid = "movie";

JObject result = Utils.GetDataCsvariantsAttribute(entry, contentTypeUid);
JObject result = Utils.GetVariantMetadataTags(entry, contentTypeUid);

Assert.True(result["data-csvariants"] != null);
string dataCsvariantsStr = result["data-csvariants"].ToString();
Expand Down Expand Up @@ -96,13 +96,13 @@ public void GetVariantAliases_MultipleEntries_ReturnsOneResultPerEntryWithUid()
}

[Fact]
public void GetDataCsvariantsAttribute_MultipleEntries_ReturnsJsonArrayString()
public void GetVariantMetadataTags_MultipleEntries_ReturnsJsonArrayString()
{
JObject full = ReadJsonRoot("variantsEntries.json");
JArray entries = (JArray)full["entries"];
const string contentTypeUid = "movie";

JObject result = Utils.GetDataCsvariantsAttribute(entries, contentTypeUid);
JObject result = Utils.GetVariantMetadataTags(entries, contentTypeUid);

Assert.True(result["data-csvariants"] != null);
string dataCsvariantsStr = result["data-csvariants"].ToString();
Expand Down Expand Up @@ -139,9 +139,9 @@ public void GetVariantAliases_ThrowsWhenContentTypeUidEmpty()
}

[Fact]
public void GetDataCsvariantsAttribute_WhenEntryNull_ReturnsEmptyArrayString()
public void GetVariantMetadataTags_WhenEntryNull_ReturnsEmptyArrayString()
{
JObject result = Utils.GetDataCsvariantsAttribute((JObject)null, "landing_page");
JObject result = Utils.GetVariantMetadataTags((JObject)null, "landing_page");
Assert.True(result["data-csvariants"] != null);
Assert.Equal("[]", result["data-csvariants"].ToString());
}
Expand Down Expand Up @@ -175,24 +175,52 @@ public void GetVariantAliases_Batch_ThrowsWhenContentTypeUidEmpty()
}

[Fact]
public void GetDataCsvariantsAttribute_WhenEntriesArrayNull_ReturnsEmptyArrayString()
public void GetVariantMetadataTags_WhenEntriesArrayNull_ReturnsEmptyArrayString()
{
JObject result = Utils.GetDataCsvariantsAttribute((JArray)null, "movie");
JObject result = Utils.GetVariantMetadataTags((JArray)null, "movie");
Assert.Equal("[]", result["data-csvariants"].ToString());
}

[Fact]
public void GetDataCsvariantsAttribute_Batch_ThrowsWhenContentTypeUidNull()
public void GetVariantMetadataTags_Batch_ThrowsWhenContentTypeUidNull()
{
var entries = new JArray { new JObject { ["uid"] = "a" } };
Assert.Throws<ArgumentException>(() => Utils.GetDataCsvariantsAttribute(entries, null));
Assert.Throws<ArgumentException>(() => Utils.GetVariantMetadataTags(entries, null));
}

[Fact]
public void GetDataCsvariantsAttribute_Batch_ThrowsWhenContentTypeUidEmpty()
public void GetVariantMetadataTags_Batch_ThrowsWhenContentTypeUidEmpty()
{
var entries = new JArray { new JObject { ["uid"] = "a" } };
Assert.Throws<ArgumentException>(() => Utils.GetDataCsvariantsAttribute(entries, ""));
Assert.Throws<ArgumentException>(() => Utils.GetVariantMetadataTags(entries, ""));
}

[Fact]
public void GetDataCsvariantsAttribute_DelegatesToGetVariantMetadataTags()
{
#pragma warning disable CS0618 // Type or member is obsolete — intentional coverage of backward-compatible alias
JObject full = ReadJsonRoot("variantsSingleEntry.json");
JObject entry = (JObject)full["entry"];
const string contentTypeUid = "movie";

JObject canonical = Utils.GetVariantMetadataTags(entry, contentTypeUid);
JObject legacy = Utils.GetDataCsvariantsAttribute(entry, contentTypeUid);
Assert.True(JToken.DeepEquals(canonical, legacy));

JObject fullMulti = ReadJsonRoot("variantsEntries.json");
JArray entries = (JArray)fullMulti["entries"];
JObject canonicalBatch = Utils.GetVariantMetadataTags(entries, contentTypeUid);
JObject legacyBatch = Utils.GetDataCsvariantsAttribute(entries, contentTypeUid);
Assert.True(JToken.DeepEquals(canonicalBatch, legacyBatch));

JObject nullEntryLegacy = Utils.GetDataCsvariantsAttribute((JObject)null, "x");
JObject nullEntryCanonical = Utils.GetVariantMetadataTags((JObject)null, "x");
Assert.True(JToken.DeepEquals(nullEntryCanonical, nullEntryLegacy));

JObject nullArrLegacy = Utils.GetDataCsvariantsAttribute((JArray)null, "x");
JObject nullArrCanonical = Utils.GetVariantMetadataTags((JArray)null, "x");
Assert.True(JToken.DeepEquals(nullArrCanonical, nullArrLegacy));
#pragma warning restore CS0618
}

[Fact]
Expand Down
36 changes: 33 additions & 3 deletions Contentstack.Utils/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,13 @@ public static JArray GetVariantAliases(JArray entries, string contentTypeUid)
return variantResults;
}

public static JObject GetDataCsvariantsAttribute(JObject entry, string contentTypeUid)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change

/// <summary>
/// Builds the JSON object used for the <c>data-csvariants</c> HTML attribute payload from a single entry.
/// </summary>
/// <param name="entry">Entry JSON (e.g. from the Delivery API), or <c>null</c> to produce an empty payload.</param>
/// <param name="contentTypeUid">Content type UID for the entry.</param>
/// <returns>A <see cref="JObject"/> with a <c>data-csvariants</c> key whose value is a compact JSON array string.</returns>
public static JObject GetVariantMetadataTags(JObject entry, string contentTypeUid)
{
if (entry == null)
{
Expand All @@ -347,10 +353,16 @@ public static JObject GetDataCsvariantsAttribute(JObject entry, string contentTy
}
JArray entries = new JArray();
entries.Add(entry);
return GetDataCsvariantsAttribute(entries, contentTypeUid);
return GetVariantMetadataTags(entries, contentTypeUid);
Comment on lines -350 to +356
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check with @reeshika-h whether to remove the method or not

}

public static JObject GetDataCsvariantsAttribute(JArray entries, string contentTypeUid)
/// <summary>
/// Builds the JSON object used for the <c>data-csvariants</c> HTML attribute payload from multiple entries.
/// </summary>
/// <param name="entries">Array of entry JSON objects, or <c>null</c> to produce an empty payload.</param>
/// <param name="contentTypeUid">Content type UID shared by these entries.</param>
/// <returns>A <see cref="JObject"/> with a <c>data-csvariants</c> key whose value is a compact JSON array string.</returns>
public static JObject GetVariantMetadataTags(JArray entries, string contentTypeUid)
{
JObject result = new JObject();
if (entries == null)
Expand All @@ -368,6 +380,24 @@ public static JObject GetDataCsvariantsAttribute(JArray entries, string contentT
return result;
}

/// <summary>
/// Prefer <see cref="GetVariantMetadataTags(JObject, string)"/>. This alias exists for backward compatibility and will be removed in a future major release.
/// </summary>
[Obsolete("Use GetVariantMetadataTags instead. This method will be removed in a future major release.")]
public static JObject GetDataCsvariantsAttribute(JObject entry, string contentTypeUid)
{
return GetVariantMetadataTags(entry, contentTypeUid);
}

/// <summary>
/// Prefer <see cref="GetVariantMetadataTags(JArray, string)"/>. This alias exists for backward compatibility and will be removed in a future major release.
/// </summary>
[Obsolete("Use GetVariantMetadataTags instead. This method will be removed in a future major release.")]
public static JObject GetDataCsvariantsAttribute(JArray entries, string contentTypeUid)
{
return GetVariantMetadataTags(entries, contentTypeUid);
}

private static JArray ExtractVariantAliasesFromEntry(JObject entry)
{
JArray variantArray = new JArray();
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>
<PropertyGroup>
<Version>1.1.0</Version>
<Version>1.2.0</Version>
</PropertyGroup>
</Project>
Loading
Loading