diff --git a/CHANGELOG.md b/CHANGELOG.md index 776e063..c6aef4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +### Version: 2.26.0 +#### Date: Feb-10-2026 + +##### Feat: +- CDA / DAM 2.0 – AssetFields support + - Added `AssetFields(params string[] fields)` to request specific asset-related metadata via the CDA `asset_fields[]` query parameter + - Implemented on: Entry (single entry fetch), Query (entries find), Asset (single asset fetch), AssetLibrary (assets find) + - Valid parameters: `user_defined_fields`, `embedded_metadata`, `ai_generated_metadata`, `visual_markups` + - Method is chainable; when called with no arguments, the query parameter is not set + ### Version: 2.25.2 #### Date: Nov-13-2025 diff --git a/Contentstack.Core.Tests/AssetTest.cs b/Contentstack.Core.Tests/AssetTest.cs index 6f779da..37818ef 100644 --- a/Contentstack.Core.Tests/AssetTest.cs +++ b/Contentstack.Core.Tests/AssetTest.cs @@ -1,4 +1,4 @@ -using System; +using System; using Xunit; using Contentstack.Core.Models; using System.Threading.Tasks; @@ -951,5 +951,187 @@ public void Where_WithSpecialCharacters_ShouldHandleCorrectly_Test() Assert.NotNull(result); Assert.IsType(result); } + + [Fact] + public async Task AssetFields_SingleAsset_RequestSucceeds() + { + string uid = await FetchAssetUID(); + Asset asset = client.Asset(uid); + + asset.AssetFields("user_defined_fields", "embedded_metadata", "ai_generated_metadata", "visual_markups"); + Asset result = await asset.Fetch(); + + if (result == null) + Assert.Fail("Asset.Fetch with AssetFields did not return a result."); + Assert.NotNull(result.Uid); + Assert.NotEmpty(result.FileName); + } + + [Fact] + public async Task AssetFields_AssetLibrary_RequestSucceeds() + { + AssetLibrary assetLibrary = client.AssetLibrary(); + assetLibrary.AssetFields("user_defined_fields", "ai_generated_metadata"); + ContentstackCollection assets = await assetLibrary.FetchAll(); + + if (assets == null) + Assert.Fail("AssetLibrary.FetchAll with AssetFields did not return a result."); + Assert.NotNull(assets.Items); + } + + [Fact] + public async Task AssetFields_ChainedWithIncludeMetadata_RequestSucceeds() + { + string uid = await FetchAssetUID(); + Asset result = await client.Asset(uid) + .AssetFields("user_defined_fields") + .IncludeMetadata() + .Fetch(); + + if (result == null) + Assert.Fail("Asset.Fetch with AssetFields and IncludeMetadata did not return a result."); + Assert.NotNull(result.Uid); + Assert.NotEmpty(result.FileName); + } + + [Fact] + public async Task AssetFields_AssetLibrary_ChainedWithIncludeMetadata_RequestSucceeds() + { + ContentstackCollection assets = await client.AssetLibrary() + .AssetFields("user_defined_fields") + .IncludeMetadata() + .FetchAll(); + + if (assets == null) + Assert.Fail("AssetLibrary.FetchAll with AssetFields and IncludeMetadata did not return a result."); + Assert.NotNull(assets.Items); + } + + [Fact] + public async Task AssetFields_SingleField_RequestSucceeds() + { + string uid = await FetchAssetUID(); + Asset asset = client.Asset(uid); + asset.AssetFields("user_defined_fields"); + Asset result = await asset.Fetch(); + + if (result == null) + Assert.Fail("Asset.Fetch with AssetFields single field did not return a result."); + Assert.NotNull(result.Uid); + Assert.NotEmpty(result.FileName); + } + + [Fact] + public async Task AssetFields_WithMultipleFields_RequestSucceeds() + { + string uid = await FetchAssetUID(); + Asset asset = client.Asset(uid); + asset.AssetFields("user_defined_fields", "embedded_metadata", "visual_markups"); + Asset result = await asset.Fetch(); + + if (result == null) + Assert.Fail("Asset.Fetch with AssetFields multiple fields did not return a result."); + Assert.NotNull(result.Uid); + Assert.NotEmpty(result.FileName); + } + + [Fact] + public async Task AssetFields_AssetLibrary_SingleField_RequestSucceeds() + { + AssetLibrary assetLibrary = client.AssetLibrary(); + assetLibrary.AssetFields("user_defined_fields"); + ContentstackCollection assets = await assetLibrary.FetchAll(); + + if (assets == null) + Assert.Fail("AssetLibrary.FetchAll with AssetFields single field did not return a result."); + Assert.NotNull(assets.Items); + } + + [Fact] + public async Task AssetFields_AssetLibrary_WithMultipleFields_RequestSucceeds() + { + AssetLibrary assetLibrary = client.AssetLibrary(); + assetLibrary.AssetFields("user_defined_fields", "embedded_metadata", "ai_generated_metadata", "visual_markups"); + ContentstackCollection assets = await assetLibrary.FetchAll(); + + if (assets == null) + Assert.Fail("AssetLibrary.FetchAll with AssetFields multiple fields did not return a result."); + Assert.NotNull(assets.Items); + } + + [Fact] + public async Task AssetFields_WithNoArguments_RequestSucceeds() + { + string uid = await FetchAssetUID(); + Asset asset = client.Asset(uid); + asset.AssetFields(); + Asset result = await asset.Fetch(); + + if (result == null) + Assert.Fail("Asset.Fetch with AssetFields() no arguments did not return a result."); + Assert.NotNull(result.Uid); + } + + [Fact] + public async Task AssetFields_AssetLibrary_WithNoArguments_RequestSucceeds() + { + AssetLibrary assetLibrary = client.AssetLibrary(); + assetLibrary.AssetFields(); + ContentstackCollection assets = await assetLibrary.FetchAll(); + + if (assets == null) + Assert.Fail("AssetLibrary.FetchAll with AssetFields() no arguments did not return a result."); + Assert.NotNull(assets.Items); + } + + [Fact] + public async Task AssetFields_WithNull_RequestSucceeds() + { + string uid = await FetchAssetUID(); + Asset asset = client.Asset(uid); + asset.AssetFields(null); + Asset result = await asset.Fetch(); + + if (result == null) + Assert.Fail("Asset.Fetch with AssetFields(null) did not return a result."); + Assert.NotNull(result.Uid); + } + + [Fact] + public async Task AssetFields_WithEmptyArray_RequestSucceeds() + { + string uid = await FetchAssetUID(); + Asset asset = client.Asset(uid); + asset.AssetFields(new string[0]); + Asset result = await asset.Fetch(); + + if (result == null) + Assert.Fail("Asset.Fetch with AssetFields(empty array) did not return a result."); + Assert.NotNull(result.Uid); + } + + [Fact] + public async Task AssetFields_AssetLibrary_WithNull_RequestSucceeds() + { + AssetLibrary assetLibrary = client.AssetLibrary(); + assetLibrary.AssetFields(null); + ContentstackCollection assets = await assetLibrary.FetchAll(); + + if (assets == null) + Assert.Fail("AssetLibrary.FetchAll with AssetFields(null) did not return a result."); + Assert.NotNull(assets.Items); + } + + [Fact] + public async Task AssetFields_AssetLibrary_WithEmptyArray_RequestSucceeds() + { + AssetLibrary assetLibrary = client.AssetLibrary(); + assetLibrary.AssetFields(new string[0]); + ContentstackCollection assets = await assetLibrary.FetchAll(); + + if (assets == null) + Assert.Fail("AssetLibrary.FetchAll with AssetFields(empty array) did not return a result."); + Assert.NotNull(assets.Items); + } } } \ No newline at end of file diff --git a/Contentstack.Core.Tests/Contentstack.Core.Tests.csproj b/Contentstack.Core.Tests/Contentstack.Core.Tests.csproj index c40482e..1a3233c 100644 --- a/Contentstack.Core.Tests/Contentstack.Core.Tests.csproj +++ b/Contentstack.Core.Tests/Contentstack.Core.Tests.csproj @@ -28,6 +28,7 @@ + diff --git a/Contentstack.Core.Tests/EntryTest.cs b/Contentstack.Core.Tests/EntryTest.cs index 73fc79a..16e14c5 100644 --- a/Contentstack.Core.Tests/EntryTest.cs +++ b/Contentstack.Core.Tests/EntryTest.cs @@ -1,4 +1,4 @@ -using System; +using System; using Xunit; using Contentstack.Core.Models; using System.Threading.Tasks; @@ -457,5 +457,112 @@ public async Task GetMetadata() Assert.True(true, "GetMetadata() returns a valid dictionary (may be empty)"); } } + + [Fact] + public async Task AssetFields_SingleEntry_RequestSucceeds() + { + ContentType contenttype = client.ContentType(source); + string uid = await GetUID("source1"); + Entry sourceEntry = contenttype.Entry(uid); + + sourceEntry.AssetFields("user_defined_fields", "embedded_metadata", "ai_generated_metadata", "visual_markups"); + var result = await sourceEntry.Fetch(); + + if (result == null) + Assert.Fail("Entry.Fetch with AssetFields did not return a result."); + Assert.NotNull(result.Uid); + } + + [Fact] + public async Task AssetFields_ChainedWithIncludeMetadata_RequestSucceeds() + { + ContentType contenttype = client.ContentType(source); + string uid = await GetUID("source1"); + Entry sourceEntry = contenttype.Entry(uid); + + var result = await sourceEntry + .AssetFields("user_defined_fields") + .IncludeMetadata() + .Fetch(); + + if (result == null) + Assert.Fail("Entry.Fetch with AssetFields and IncludeMetadata did not return a result."); + Assert.NotNull(result.Uid); + } + + [Fact] + public async Task AssetFields_SingleField_RequestSucceeds() + { + ContentType contenttype = client.ContentType(source); + string uid = await GetUID("source1"); + Entry sourceEntry = contenttype.Entry(uid); + + sourceEntry.AssetFields("user_defined_fields"); + var result = await sourceEntry.Fetch(); + + if (result == null) + Assert.Fail("Entry.Fetch with AssetFields single field did not return a result."); + Assert.NotNull(result.Uid); + } + + [Fact] + public async Task AssetFields_WithMultipleFields_RequestSucceeds() + { + ContentType contenttype = client.ContentType(source); + string uid = await GetUID("source1"); + Entry sourceEntry = contenttype.Entry(uid); + + sourceEntry.AssetFields("user_defined_fields", "embedded_metadata", "visual_markups"); + var result = await sourceEntry.Fetch(); + + if (result == null) + Assert.Fail("Entry.Fetch with AssetFields multiple fields did not return a result."); + Assert.NotNull(result.Uid); + } + + [Fact] + public async Task AssetFields_WithNoArguments_RequestSucceeds() + { + ContentType contenttype = client.ContentType(source); + string uid = await GetUID("source1"); + Entry sourceEntry = contenttype.Entry(uid); + + sourceEntry.AssetFields(); + var result = await sourceEntry.Fetch(); + + if (result == null) + Assert.Fail("Entry.Fetch with AssetFields() no arguments did not return a result."); + Assert.NotNull(result.Uid); + } + + [Fact] + public async Task AssetFields_WithNull_RequestSucceeds() + { + ContentType contenttype = client.ContentType(source); + string uid = await GetUID("source1"); + Entry sourceEntry = contenttype.Entry(uid); + + sourceEntry.AssetFields(null); + var result = await sourceEntry.Fetch(); + + if (result == null) + Assert.Fail("Entry.Fetch with AssetFields(null) did not return a result."); + Assert.NotNull(result.Uid); + } + + [Fact] + public async Task AssetFields_WithEmptyArray_RequestSucceeds() + { + ContentType contenttype = client.ContentType(source); + string uid = await GetUID("source1"); + Entry sourceEntry = contenttype.Entry(uid); + + sourceEntry.AssetFields(new string[0]); + var result = await sourceEntry.Fetch(); + + if (result == null) + Assert.Fail("Entry.Fetch with AssetFields(empty array) did not return a result."); + Assert.NotNull(result.Uid); + } } } diff --git a/Contentstack.Core.Tests/QueryTest.cs b/Contentstack.Core.Tests/QueryTest.cs index b677546..5c367c2 100644 --- a/Contentstack.Core.Tests/QueryTest.cs +++ b/Contentstack.Core.Tests/QueryTest.cs @@ -1619,6 +1619,91 @@ public async Task IncludeSchema() // The exact assertion depends on your data structure } } + + [Fact] + public async Task AssetFieldsQueryEntriesRequestSucceeds() + { + Query query = client.ContentType(source).Query(); + query.AssetFields("user_defined_fields", "embedded_metadata", "ai_generated_metadata", "visual_markups"); + var result = await query.Find(); + + if (result == null) + Assert.Fail("Query.Find with AssetFields did not return a result."); + Assert.NotNull(result.Items); + } + + [Fact] + public async Task AssetFields_ChainedWithIncludeMetadata_RequestSucceeds() + { + var result = await client.ContentType(source).Query() + .AssetFields("user_defined_fields") + .IncludeMetadata() + .Find(); + + if (result == null) + Assert.Fail("Query.Find with AssetFields and IncludeMetadata did not return a result."); + Assert.NotNull(result.Items); + } + + [Fact] + public async Task AssetFields_SingleField_RequestSucceeds() + { + Query query = client.ContentType(source).Query(); + query.AssetFields("user_defined_fields"); + var result = await query.Find(); + + if (result == null) + Assert.Fail("Query.Find with AssetFields single field did not return a result."); + Assert.NotNull(result.Items); + } + + [Fact] + public async Task AssetFields_WithMultipleFields_RequestSucceeds() + { + Query query = client.ContentType(source).Query(); + query.AssetFields("user_defined_fields", "embedded_metadata", "visual_markups"); + var result = await query.Find(); + + if (result == null) + Assert.Fail("Query.Find with AssetFields multiple fields did not return a result."); + Assert.NotNull(result.Items); + } + + [Fact] + public async Task AssetFields_WithNoArguments_RequestSucceeds() + { + Query query = client.ContentType(source).Query(); + query.AssetFields(); + var result = await query.Find(); + + if (result == null) + Assert.Fail("Query.Find with AssetFields() no arguments did not return a result."); + Assert.NotNull(result.Items); + } + + [Fact] + public async Task AssetFields_WithNull_RequestSucceeds() + { + Query query = client.ContentType(source).Query(); + query.AssetFields(null); + var result = await query.Find(); + + if (result == null) + Assert.Fail("Query.Find with AssetFields(null) did not return a result."); + Assert.NotNull(result.Items); + } + + [Fact] + public async Task AssetFields_WithEmptyArray_RequestSucceeds() + { + Query query = client.ContentType(source).Query(); + query.AssetFields(new string[0]); + var result = await query.Find(); + + if (result == null) + Assert.Fail("Query.Find with AssetFields(empty array) did not return a result."); + Assert.NotNull(result.Items); + } } } diff --git a/Contentstack.Core.Unit.Tests/AssetLibraryUnitTests.cs b/Contentstack.Core.Unit.Tests/AssetLibraryUnitTests.cs index 1797d2b..73b457b 100644 --- a/Contentstack.Core.Unit.Tests/AssetLibraryUnitTests.cs +++ b/Contentstack.Core.Unit.Tests/AssetLibraryUnitTests.cs @@ -171,6 +171,119 @@ public void IncludeMetadata_AddsQueryParameter() #endregion + #region AssetFields Tests + + [Fact] + public void AssetFields_WithSingleField_AddsQueryParameter() + { + // Arrange + var assetLibrary = CreateAssetLibrary(); + var field = "user_defined_fields"; + + // Act + AssetLibrary result = assetLibrary.AssetFields(field); + + // Assert + Assert.NotNull(result); + Assert.Equal(assetLibrary, result); + + var urlQueriesField = typeof(AssetLibrary).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(assetLibrary); + + Assert.True(urlQueries?.ContainsKey("asset_fields[]") ?? false); + var fields = urlQueries?["asset_fields[]"] as string[]; + Assert.NotNull(fields); + Assert.Single(fields); + Assert.Equal("user_defined_fields", fields[0]); + } + + [Fact] + public void AssetFields_WithMultipleFields_AddsQueryParameter() + { + // Arrange + var assetLibrary = CreateAssetLibrary(); + var fields = new[] { "user_defined_fields", "embedded_metadata", "ai_generated_metadata" }; + + // Act + AssetLibrary result = assetLibrary.AssetFields(fields); + + // Assert + Assert.NotNull(result); + Assert.Equal(assetLibrary, result); + + var urlQueriesField = typeof(AssetLibrary).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(assetLibrary); + + Assert.True(urlQueries?.ContainsKey("asset_fields[]") ?? false); + Assert.Equal(fields, urlQueries?["asset_fields[]"]); + } + + [Fact] + public void AssetFields_ReturnsSameInstance_ForChaining() + { + // Arrange + var assetLibrary = CreateAssetLibrary(); + + // Act + AssetLibrary result = assetLibrary.AssetFields("embedded_metadata"); + + // Assert + Assert.NotNull(result); + Assert.Same(assetLibrary, result); + } + + [Fact] + public void AssetFields_WithNoArguments_DoesNotAddParameter() + { + // Arrange + var assetLibrary = CreateAssetLibrary(); + + // Act + AssetLibrary result = assetLibrary.AssetFields(); + + // Assert + var urlQueriesField = typeof(AssetLibrary).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(assetLibrary); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + [Fact] + public void AssetFields_WithNull_DoesNotAddParameter() + { + // Arrange + var assetLibrary = CreateAssetLibrary(); + + // Act + AssetLibrary result = assetLibrary.AssetFields(null); + + // Assert + var urlQueriesField = typeof(AssetLibrary).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(assetLibrary); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + [Fact] + public void AssetFields_WithEmptyArray_DoesNotAddParameter() + { + // Arrange + var assetLibrary = CreateAssetLibrary(); + + // Act + AssetLibrary result = assetLibrary.AssetFields(new string[0]); + + // Assert + var urlQueriesField = typeof(AssetLibrary).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(assetLibrary); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + #endregion + #region IncludeBranch Tests [Fact] diff --git a/Contentstack.Core.Unit.Tests/AssetUnitTests.cs b/Contentstack.Core.Unit.Tests/AssetUnitTests.cs index f560c83..8baa357 100644 --- a/Contentstack.Core.Unit.Tests/AssetUnitTests.cs +++ b/Contentstack.Core.Unit.Tests/AssetUnitTests.cs @@ -368,6 +368,119 @@ public void IncludeMetadata_AddsQueryParameter() #endregion + #region AssetFields Tests + + [Fact] + public void AssetFields_WithSingleField_AddsQueryParameter() + { + // Arrange + var asset = CreateAsset(); + var field = "user_defined_fields"; + + // Act + Asset result = asset.AssetFields(field); + + // Assert + Assert.NotNull(result); + Assert.Equal(asset, result); + + var urlQueriesField = typeof(Asset).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(asset); + + Assert.True(urlQueries?.ContainsKey("asset_fields[]") ?? false); + var fields = urlQueries?["asset_fields[]"] as string[]; + Assert.NotNull(fields); + Assert.Single(fields); + Assert.Equal("user_defined_fields", fields[0]); + } + + [Fact] + public void AssetFields_WithMultipleFields_AddsQueryParameter() + { + // Arrange + var asset = CreateAsset(); + var fields = new[] { "embedded_metadata", "visual_markups" }; + + // Act + Asset result = asset.AssetFields(fields); + + // Assert + Assert.NotNull(result); + Assert.Equal(asset, result); + + var urlQueriesField = typeof(Asset).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(asset); + + Assert.True(urlQueries?.ContainsKey("asset_fields[]") ?? false); + Assert.Equal(fields, urlQueries?["asset_fields[]"]); + } + + [Fact] + public void AssetFields_ReturnsSameInstance_ForChaining() + { + // Arrange + var asset = CreateAsset(); + + // Act + Asset result = asset.AssetFields("ai_generated_metadata"); + + // Assert + Assert.NotNull(result); + Assert.Same(asset, result); + } + + [Fact] + public void AssetFields_WithNoArguments_DoesNotAddParameter() + { + // Arrange + var asset = CreateAsset(); + + // Act + Asset result = asset.AssetFields(); + + // Assert + var urlQueriesField = typeof(Asset).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(asset); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + [Fact] + public void AssetFields_WithNull_DoesNotAddParameter() + { + // Arrange + var asset = CreateAsset(); + + // Act + Asset result = asset.AssetFields(null); + + // Assert + var urlQueriesField = typeof(Asset).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(asset); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + [Fact] + public void AssetFields_WithEmptyArray_DoesNotAddParameter() + { + // Arrange + var asset = CreateAsset(); + + // Act + Asset result = asset.AssetFields(new string[0]); + + // Assert + var urlQueriesField = typeof(Asset).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(asset); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + #endregion + #region IncludeBranch Tests [Fact] diff --git a/Contentstack.Core.Unit.Tests/Contentstack.Core.Unit.Tests.csproj b/Contentstack.Core.Unit.Tests/Contentstack.Core.Unit.Tests.csproj index 5284303..bb1056f 100644 --- a/Contentstack.Core.Unit.Tests/Contentstack.Core.Unit.Tests.csproj +++ b/Contentstack.Core.Unit.Tests/Contentstack.Core.Unit.Tests.csproj @@ -21,6 +21,7 @@ + diff --git a/Contentstack.Core.Unit.Tests/EntryUnitTests.cs b/Contentstack.Core.Unit.Tests/EntryUnitTests.cs index 15813c2..859cd06 100644 --- a/Contentstack.Core.Unit.Tests/EntryUnitTests.cs +++ b/Contentstack.Core.Unit.Tests/EntryUnitTests.cs @@ -1338,6 +1338,122 @@ public void IncludeReference_WithEmptyArray_DoesNotAddParameter() #endregion + #region AssetFields Tests + + [Fact] + public void AssetFields_WithSingleField_AddsQueryParameter() + { + // Arrange + var entry = CreateEntry(); + var field = "user_defined_fields"; + + // Act + Entry result = entry.AssetFields(field); + + // Assert + Assert.NotNull(result); + Assert.Equal(entry, result); + + var urlQueriesField = typeof(Entry).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(entry); + + Assert.True(urlQueries?.ContainsKey("asset_fields[]") ?? false); + var fields = urlQueries?["asset_fields[]"] as string[]; + Assert.NotNull(fields); + Assert.Single(fields); + Assert.Equal("user_defined_fields", fields[0]); + } + + [Fact] + public void AssetFields_WithMultipleFields_AddsQueryParameter() + { + // Arrange + var entry = CreateEntry(); + var fields = new[] { "user_defined_fields", "embedded_metadata", "ai_generated_metadata" }; + + // Act + Entry result = entry.AssetFields(fields); + + // Assert + Assert.NotNull(result); + Assert.Equal(entry, result); + + var urlQueriesField = typeof(Entry).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(entry); + + Assert.True(urlQueries?.ContainsKey("asset_fields[]") ?? false); + Assert.Equal(fields, urlQueries?["asset_fields[]"]); + } + + [Fact] + public void AssetFields_ReturnsSameInstance_ForChaining() + { + // Arrange + var entry = CreateEntry(); + + // Act + Entry result = entry.AssetFields("embedded_metadata"); + + // Assert + Assert.NotNull(result); + Assert.Same(entry, result); + } + + [Fact] + public void AssetFields_WithNoArguments_DoesNotAddParameter() + { + // Arrange + var entry = CreateEntry(); + + // Act + Entry result = entry.AssetFields(); + + // Assert + Assert.NotNull(result); + var urlQueriesField = typeof(Entry).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(entry); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + [Fact] + public void AssetFields_WithNull_DoesNotAddParameter() + { + // Arrange + var entry = CreateEntry(); + + // Act + Entry result = entry.AssetFields(null); + + // Assert + Assert.NotNull(result); + var urlQueriesField = typeof(Entry).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(entry); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + [Fact] + public void AssetFields_WithEmptyArray_DoesNotAddParameter() + { + // Arrange + var entry = CreateEntry(); + + // Act + Entry result = entry.AssetFields(new string[0]); + + // Assert + Assert.NotNull(result); + var urlQueriesField = typeof(Entry).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(entry); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + #endregion + #region IncludeFallback Tests [Fact] diff --git a/Contentstack.Core.Unit.Tests/QueryUnitTests.cs b/Contentstack.Core.Unit.Tests/QueryUnitTests.cs index 316f19f..4e1c4ff 100644 --- a/Contentstack.Core.Unit.Tests/QueryUnitTests.cs +++ b/Contentstack.Core.Unit.Tests/QueryUnitTests.cs @@ -754,6 +754,119 @@ public void IncludeReference_WithArray_AddsQueryParameter() #endregion + #region AssetFields Tests + + [Fact] + public void AssetFields_WithSingleField_AddsQueryParameter() + { + // Arrange + var query = CreateQuery(); + var field = "user_defined_fields"; + + // Act + Query result = query.AssetFields(field); + + // Assert + Assert.NotNull(result); + Assert.Equal(query, result); + + var urlQueriesField = typeof(Query).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(query); + + Assert.True(urlQueries?.ContainsKey("asset_fields[]") ?? false); + var fields = urlQueries?["asset_fields[]"] as string[]; + Assert.NotNull(fields); + Assert.Single(fields); + Assert.Equal("user_defined_fields", fields[0]); + } + + [Fact] + public void AssetFields_WithMultipleFields_AddsQueryParameter() + { + // Arrange + var query = CreateQuery(); + var fields = new[] { "user_defined_fields", "embedded_metadata" }; + + // Act + Query result = query.AssetFields(fields); + + // Assert + Assert.NotNull(result); + Assert.Equal(query, result); + + var urlQueriesField = typeof(Query).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(query); + + Assert.True(urlQueries?.ContainsKey("asset_fields[]") ?? false); + Assert.Equal(fields, urlQueries?["asset_fields[]"]); + } + + [Fact] + public void AssetFields_ReturnsSameInstance_ForChaining() + { + // Arrange + var query = CreateQuery(); + + // Act + Query result = query.AssetFields("embedded_metadata"); + + // Assert + Assert.NotNull(result); + Assert.Same(query, result); + } + + [Fact] + public void AssetFields_WithNoArguments_DoesNotAddParameter() + { + // Arrange + var query = CreateQuery(); + + // Act + Query result = query.AssetFields(); + + // Assert + var urlQueriesField = typeof(Query).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(query); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + [Fact] + public void AssetFields_WithNull_DoesNotAddParameter() + { + // Arrange + var query = CreateQuery(); + + // Act + Query result = query.AssetFields(null); + + // Assert + var urlQueriesField = typeof(Query).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(query); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + [Fact] + public void AssetFields_WithEmptyArray_DoesNotAddParameter() + { + // Arrange + var query = CreateQuery(); + + // Act + Query result = query.AssetFields(new string[0]); + + // Assert + var urlQueriesField = typeof(Query).GetField("UrlQueries", + BindingFlags.NonPublic | BindingFlags.Instance); + var urlQueries = (Dictionary)urlQueriesField?.GetValue(query); + Assert.False(urlQueries?.ContainsKey("asset_fields[]") ?? false); + } + + #endregion + #region AddParam Tests [Fact] diff --git a/Contentstack.Core/Contentstack.Core.csproj b/Contentstack.Core/Contentstack.Core.csproj index 1d39949..d9b55f2 100644 --- a/Contentstack.Core/Contentstack.Core.csproj +++ b/Contentstack.Core/Contentstack.Core.csproj @@ -28,7 +28,7 @@ - + diff --git a/Contentstack.Core/Models/Asset.cs b/Contentstack.Core/Models/Asset.cs index 26a674b..4174ec5 100644 --- a/Contentstack.Core/Models/Asset.cs +++ b/Contentstack.Core/Models/Asset.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -299,6 +299,27 @@ public Asset AddParam(string key, string value) return this; } + /// + /// Request specific asset-related metadata in the response (CDA asset_fields[]). + /// Valid parameters: user_defined_fields, embedded_metadata, ai_generated_metadata, visual_markups. + /// + /// Asset field names to include. + /// Current instance of Asset for chaining. + /// + /// + /// stack.Asset(uid).AssetFields("user_defined_fields", "embedded_metadata").Fetch() + /// + /// + public Asset AssetFields(params string[] fields) + { + if (fields != null && fields.Length > 0) + { + this.UrlQueries.Add("asset_fields[]", fields); + } + return this; + } + + public void RemoveHeader(string key) { if (this._Headers.ContainsKey(key)) diff --git a/Contentstack.Core/Models/AssetLibrary.cs b/Contentstack.Core/Models/AssetLibrary.cs index 24c33f2..6a51f74 100644 --- a/Contentstack.Core/Models/AssetLibrary.cs +++ b/Contentstack.Core/Models/AssetLibrary.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -245,6 +245,26 @@ public AssetLibrary AddParam(string key, string value) return this; } + /// + /// Request specific asset-related metadata in the response (CDA asset_fields[]). + /// Valid parameters: user_defined_fields, embedded_metadata, ai_generated_metadata, visual_markups. + /// + /// Asset field names to include. + /// Current instance of AssetLibrary for chaining. + /// + /// + /// stack.Asset().AssetFields("user_defined_fields").Find() + /// + /// + public AssetLibrary AssetFields(params string[] fields) + { + if (fields != null && fields.Length > 0) + { + UrlQueries.Add("asset_fields[]", fields); + } + return this; + } + /// /// Sets the locale. /// diff --git a/Contentstack.Core/Models/Entry.cs b/Contentstack.Core/Models/Entry.cs index 882a54c..d683ecd 100644 --- a/Contentstack.Core/Models/Entry.cs +++ b/Contentstack.Core/Models/Entry.cs @@ -1,4 +1,4 @@ -using Markdig; +using Markdig; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; @@ -1181,6 +1181,26 @@ public Entry AddParam(string key, string value) return this; } + /// + /// Request specific asset-related metadata in the response (CDA asset_fields[]). + /// Valid parameters: user_defined_fields, embedded_metadata, ai_generated_metadata, visual_markups. + /// + /// Asset field names to include (e.g. "user_defined_fields", "embedded_metadata"). + /// Current instance of Entry for chaining. + /// + /// + /// stack.ContentType(uid).Entry(uid).AssetFields("user_defined_fields", "embedded_metadata").Fetch() + /// + /// + public Entry AssetFields(params string[] fields) + { + if (fields != null && fields.Length > 0) + { + UrlQueries.Add("asset_fields[]", fields); + } + return this; + } + /// /// Include branch for publish content. /// diff --git a/Contentstack.Core/Models/Query.cs b/Contentstack.Core/Models/Query.cs index ea92342..c0d6ead 100644 --- a/Contentstack.Core/Models/Query.cs +++ b/Contentstack.Core/Models/Query.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; @@ -1019,6 +1019,27 @@ public Query IncludeReference(String[] filed_uids) } + /// + /// Request specific asset-related metadata in the response (CDA asset_fields[]). + /// Valid parameters: user_defined_fields, embedded_metadata, ai_generated_metadata, visual_markups. + /// + /// Asset field names to include. + /// Current instance of Query for chaining. + /// + /// + /// stack.ContentType(uid).Entry().AssetFields("user_defined_fields").Find() + /// + /// + public Query AssetFields(params string[] fields) + { + if (fields != null && fields.Length > 0) + { + UrlQueries.Add("asset_fields[]", fields); + } + return this; + } + + /// /// Include tags with which to search entries. /// diff --git a/Directory.Build.props b/Directory.Build.props index 0e81c8f..0780fae 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 2.25.2 + 2.26.0