diff --git a/.gitignore b/.gitignore
index 80376521..a043cab6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -274,3 +274,4 @@ src/main/resources/
/.vscode/
/docs/
INTEGRATION-TESTS-GUIDE.md
+src/main/java/com/demo/*
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 001a9d56..d2fa8498 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# CHANGELOG
+## v2.5.0
+
+### Feb 12, 2026
+- Enhancement: assetFields method added
+
## v2.4.0
### Feb 02, 2026
diff --git a/pom.xml b/pom.xml
index 41ea6079..d8aa684b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
4.0.0
com.contentstack.sdk
java
- 2.4.0
+ 2.5.0
jar
contentstack-java
Java SDK for Contentstack Content Delivery API
diff --git a/src/main/java/com/contentstack/sdk/Asset.java b/src/main/java/com/contentstack/sdk/Asset.java
index e281f53c..9f498245 100644
--- a/src/main/java/com/contentstack/sdk/Asset.java
+++ b/src/main/java/com/contentstack/sdk/Asset.java
@@ -1,6 +1,7 @@
package com.contentstack.sdk;
import org.jetbrains.annotations.NotNull;
+import org.json.JSONArray;
import org.json.JSONObject;
import retrofit2.Retrofit;
import lombok.Getter;
@@ -544,6 +545,19 @@ public Asset includeMetadata() {
return this;
}
+ public Asset assetFields(String... fields) {
+ if (fields != null && fields.length > 0) {
+ JSONArray array = new JSONArray();
+ for (String field : fields) {
+ array.put(field);
+ }
+ if (!array.isEmpty()) {
+ urlQueries.put("asset_fields[]", array);
+ }
+ }
+ return this;
+ }
+
/**
* Fetch.
*
diff --git a/src/main/java/com/contentstack/sdk/AssetLibrary.java b/src/main/java/com/contentstack/sdk/AssetLibrary.java
index e005955f..29fd0c4b 100644
--- a/src/main/java/com/contentstack/sdk/AssetLibrary.java
+++ b/src/main/java/com/contentstack/sdk/AssetLibrary.java
@@ -2,6 +2,7 @@
import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;
+import org.json.JSONArray;
import java.util.*;
import java.util.logging.Logger;
@@ -33,7 +34,8 @@ protected void setStackInstance(@NotNull Stack stack) {
//Sanitization of keys
private boolean isValidKey(String key) {
- return key.matches("^[a-zA-Z0-9_.]+$");
+ // Fixed regex: allow alphanumeric, underscore, dot, and square brackets at the end, escaped properly
+ return key.matches("^[a-zA-Z0-9_.]+(\\[\\])?$");
}
//Sanitization of values
@@ -265,6 +267,19 @@ public AssetLibrary limit (@NotNull int number) {
return this;
}
+ public AssetLibrary assetFields(String... fields) {
+ if (fields != null && fields.length > 0) {
+ JSONArray array = new JSONArray();
+ for (String field : fields) {
+ array.put(field);
+ }
+ if (!array.isEmpty()) {
+ urlQueries.put("asset_fields[]", array);
+ }
+ }
+ return this;
+ }
+
/**
* Fetch all.
*
diff --git a/src/main/java/com/contentstack/sdk/CSHttpConnection.java b/src/main/java/com/contentstack/sdk/CSHttpConnection.java
index 9635dbf5..b60532db 100644
--- a/src/main/java/com/contentstack/sdk/CSHttpConnection.java
+++ b/src/main/java/com/contentstack/sdk/CSHttpConnection.java
@@ -102,7 +102,9 @@ public String setFormParamsGET(HashMap params) {
if (params != null && params.size() > 0) {
String urlParams = null;
urlParams = info.equalsIgnoreCase(Constants.REQUEST_CONTROLLER.QUERY.name())
- || info.equalsIgnoreCase(Constants.REQUEST_CONTROLLER.ENTRY.name()) ? getParams(params) : null;
+ || info.equalsIgnoreCase(Constants.REQUEST_CONTROLLER.ENTRY.name())
+ || info.equalsIgnoreCase(Constants.REQUEST_CONTROLLER.ASSET.name())
+ || info.equalsIgnoreCase(Constants.REQUEST_CONTROLLER.ASSETLIBRARY.name()) ? getParams(params) : null;
if (urlParams == null) {
for (Map.Entry e : params.entrySet()) {
if (urlParams == null) {
@@ -124,7 +126,7 @@ private String getParams(HashMap params) {
Object value = e.getValue();
try {
if (key.equalsIgnoreCase("include[]") || key.equalsIgnoreCase("only[BASE][]")
- || key.equalsIgnoreCase("except[BASE][]")) {
+ || key.equalsIgnoreCase("except[BASE][]") || key.equalsIgnoreCase("asset_fields[]")) {
urlParams = convertUrlParam(urlParams, value, key);
} else if (key.equalsIgnoreCase("only")) {
JSONObject onlyJSON = (JSONObject) value;
diff --git a/src/main/java/com/contentstack/sdk/Entry.java b/src/main/java/com/contentstack/sdk/Entry.java
index ab24592e..14cb47eb 100644
--- a/src/main/java/com/contentstack/sdk/Entry.java
+++ b/src/main/java/com/contentstack/sdk/Entry.java
@@ -904,6 +904,19 @@ public Entry exceptWithReferenceUid(@NotNull List fieldUid, @NotNull Str
return this;
}
+
+ public Entry assetFields(String... fields) {
+ if (fields != null && fields.length > 0) {
+ JSONArray array = new JSONArray();
+ for (String field : fields) {
+ array.put(field);
+ }
+ if (!array.isEmpty()) {
+ params.put("asset_fields[]", array);
+ }
+ }
+ return this;
+ }
/**
* Fetches the latest version of the entries from Contentstack.com content stack
*
diff --git a/src/main/java/com/contentstack/sdk/Query.java b/src/main/java/com/contentstack/sdk/Query.java
index fdc1f521..52b6851c 100644
--- a/src/main/java/com/contentstack/sdk/Query.java
+++ b/src/main/java/com/contentstack/sdk/Query.java
@@ -1146,6 +1146,19 @@ public Query search(@NotNull String value) {
return this;
}
+ public Query assetFields(String... fields) {
+ if (fields != null && fields.length > 0) {
+ JSONArray array = new JSONArray();
+ for (String field : fields) {
+ array.put(field);
+ }
+ if (!array.isEmpty()) {
+ urlQueries.put("asset_fields[]", array);
+ }
+ }
+ return this;
+ }
+
/**
* Execute a Query and Caches its result (Optional)
*
diff --git a/src/test/java/com/contentstack/sdk/TestAsset.java b/src/test/java/com/contentstack/sdk/TestAsset.java
index ac460463..715c3777 100644
--- a/src/test/java/com/contentstack/sdk/TestAsset.java
+++ b/src/test/java/com/contentstack/sdk/TestAsset.java
@@ -182,6 +182,133 @@ void testIncludeMetadata() {
assertEquals(true, asset.urlQueries.get("include_metadata"));
}
+ // ========== ASSET FIELDS TESTS (CDA asset_fields[] parameter) ==========
+
+ @Test
+ void testAssetFieldsWithSupportedValues() {
+ Asset result = asset.assetFields("user_defined_fields", "embedded", "ai_suggested", "visual_markups");
+ assertSame(asset, result);
+ assertTrue(asset.urlQueries.has("asset_fields[]"));
+ Object val = asset.urlQueries.get("asset_fields[]");
+ assertTrue(val instanceof JSONArray);
+ JSONArray arr = (JSONArray) val;
+ assertEquals(4, arr.length());
+ assertEquals("user_defined_fields", arr.get(0));
+ assertEquals("embedded", arr.get(1));
+ assertEquals("ai_suggested", arr.get(2));
+ assertEquals("visual_markups", arr.get(3));
+ }
+
+ @Test
+ void testAssetFieldsReturnsThis() {
+ Asset result = asset.assetFields("user_defined_fields");
+ assertSame(asset, result);
+ }
+
+ @Test
+ void testAssetFieldsWithNoArgsDoesNotSetParam() {
+ asset.assetFields();
+ assertFalse(asset.urlQueries.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsWithNullDoesNotSetParam() {
+ asset.assetFields((String[]) null);
+ assertFalse(asset.urlQueries.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsChainingWithOtherMethods() {
+ Asset result = asset.assetFields("embedded", "visual_markups")
+ .includeMetadata()
+ .includeDimension();
+ assertSame(asset, result);
+ assertTrue(asset.urlQueries.has("asset_fields[]"));
+ assertTrue(asset.urlQueries.has("include_metadata"));
+ assertTrue(asset.urlQueries.has("include_dimension"));
+ JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(2, arr.length());
+ assertEquals("embedded", arr.get(0));
+ assertEquals("visual_markups", arr.get(1));
+ }
+
+ /**
+ * Usage: stack.asset(assetUid).assetFields(...).fetch()
+ * Verifies the full chain sets asset_fields[] on the asset before fetch.
+ */
+ @Test
+ void testUsageSingleAssetFetchWithAssetFields() throws IllegalAccessException {
+ Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
+ Asset asset = stack.asset("asset_uid_123")
+ .assetFields("embedded", "visual_markups");
+ assertTrue(asset.urlQueries.has("asset_fields[]"));
+ JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(2, arr.length());
+ assertEquals("embedded", arr.get(0));
+ assertEquals("visual_markups", arr.get(1));
+ }
+
+
+ @Test
+ void testAssetFieldsSingleField() {
+ asset.assetFields("embedded");
+ assertTrue(asset.urlQueries.has("asset_fields[]"));
+ JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(1, arr.length());
+ assertEquals("embedded", arr.get(0));
+ }
+
+ @Test
+ void testAssetFieldsEmptyVarargsArrayDoesNotSetParam() {
+ asset.assetFields(new String[0]);
+ assertFalse(asset.urlQueries.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsDuplicateValuesAllowed() {
+ asset.assetFields("embedded", "embedded");
+ JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(2, arr.length());
+ assertEquals("embedded", arr.get(0));
+ assertEquals("embedded", arr.get(1));
+ }
+
+ @Test
+ void testAssetFieldsSecondCallOverwrites() {
+ asset.assetFields("user_defined_fields", "embedded");
+ asset.assetFields("ai_suggested");
+ JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(1, arr.length());
+ assertEquals("ai_suggested", arr.get(0));
+ }
+
+ @Test
+ void testAssetFieldsWithEmptyStringInArray() {
+ asset.assetFields("valid", "", "embedded");
+ JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(3, arr.length());
+ assertEquals("valid", arr.get(0));
+ assertEquals("", arr.get(1));
+ assertEquals("embedded", arr.get(2));
+ }
+
+ @Test
+ void testAssetFieldsWithNullInArray() {
+ asset.assetFields("valid", null, "embedded");
+ JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(3, arr.length());
+ assertEquals("valid", arr.get(0));
+ assertEquals("embedded", arr.get(2));
+ }
+
+ @Test
+ void testAssetFieldsSingleEmptyStringSetsParam() {
+ asset.assetFields("");
+ assertTrue(asset.urlQueries.has("asset_fields[]"));
+ assertEquals(1, asset.urlQueries.getJSONArray("asset_fields[]").length());
+ assertEquals("", asset.urlQueries.getJSONArray("asset_fields[]").get(0));
+ }
+
// ========== CHAINING TESTS ==========
@Test
diff --git a/src/test/java/com/contentstack/sdk/TestAssetLibrary.java b/src/test/java/com/contentstack/sdk/TestAssetLibrary.java
index c9e5348e..9092c4f1 100644
--- a/src/test/java/com/contentstack/sdk/TestAssetLibrary.java
+++ b/src/test/java/com/contentstack/sdk/TestAssetLibrary.java
@@ -1,5 +1,6 @@
package com.contentstack.sdk;
+import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -135,6 +136,107 @@ void testIncludeMetadata() {
assertEquals(true, assetLibrary.urlQueries.get("include_metadata"));
}
+ // ========== ASSET FIELDS TESTS (CDA asset_fields[] parameter) ==========
+
+ @Test
+ void testAssetFieldsWithSupportedValues() {
+ AssetLibrary result = assetLibrary.assetFields("user_defined_fields", "embedded", "ai_suggested", "visual_markups");
+ assertSame(assetLibrary, result);
+ assertTrue(assetLibrary.urlQueries.has("asset_fields[]"));
+ Object val = assetLibrary.urlQueries.get("asset_fields[]");
+ assertTrue(val instanceof JSONArray);
+ JSONArray arr = (JSONArray) val;
+ assertEquals(4, arr.length());
+ assertEquals("user_defined_fields", arr.get(0));
+ assertEquals("embedded", arr.get(1));
+ assertEquals("ai_suggested", arr.get(2));
+ assertEquals("visual_markups", arr.get(3));
+ }
+
+ @Test
+ void testAssetFieldsReturnsThis() {
+ AssetLibrary result = assetLibrary.assetFields("embedded");
+ assertSame(assetLibrary, result);
+ }
+
+ @Test
+ void testAssetFieldsWithNoArgsDoesNotSetParam() {
+ assetLibrary.assetFields();
+ assertFalse(assetLibrary.urlQueries.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsWithNullDoesNotSetParam() {
+ assetLibrary.assetFields((String[]) null);
+ assertFalse(assetLibrary.urlQueries.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsChainingWithIncludeMetadata() {
+ AssetLibrary result = assetLibrary.assetFields("user_defined_fields").includeMetadata().includeCount();
+ assertSame(assetLibrary, result);
+ assertTrue(assetLibrary.urlQueries.has("asset_fields[]"));
+ assertTrue(assetLibrary.urlQueries.has("include_metadata"));
+ assertTrue(assetLibrary.urlQueries.has("include_count"));
+ }
+
+ /**
+ * Usage: stack.assetLibrary().assetFields(...).fetchAll()
+ * (AssetQuery / query assets - in this SDK use assetLibrary(), not asset().find())
+ * Verifies the full chain sets asset_fields[] on the asset library before fetchAll.
+ */
+ @Test
+ void testUsageAssetLibraryFetchAllWithAssetFields() throws IllegalAccessException {
+ Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
+ AssetLibrary lib = stack.assetLibrary()
+ .assetFields("user_defined_fields", "embedded");
+ assertTrue(lib.urlQueries.has("asset_fields[]"));
+ JSONArray arr = lib.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(2, arr.length());
+ assertEquals("user_defined_fields", arr.get(0));
+ assertEquals("embedded", arr.get(1));
+ }
+
+ @Test
+ void testAssetFieldsSingleField() {
+ assetLibrary.assetFields("visual_markups");
+ JSONArray arr = assetLibrary.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(1, arr.length());
+ assertEquals("visual_markups", arr.get(0));
+ }
+
+ @Test
+ void testAssetFieldsEmptyVarargsArrayDoesNotSetParam() {
+ assetLibrary.assetFields(new String[0]);
+ assertFalse(assetLibrary.urlQueries.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsSecondCallOverwrites() {
+ assetLibrary.assetFields("user_defined_fields", "embedded");
+ assetLibrary.assetFields("ai_suggested");
+ JSONArray arr = assetLibrary.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(1, arr.length());
+ assertEquals("ai_suggested", arr.get(0));
+ }
+
+ @Test
+ void testAssetFieldsDuplicateValuesAllowed() {
+ assetLibrary.assetFields("embedded", "embedded");
+ JSONArray arr = assetLibrary.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(2, arr.length());
+ assertEquals("embedded", arr.get(0));
+ assertEquals("embedded", arr.get(1));
+ }
+
+ @Test
+ void testAssetFieldsWithEmptyStringInArray() {
+ assetLibrary.assetFields("valid", "", "visual_markups");
+ JSONArray arr = assetLibrary.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(3, arr.length());
+ assertEquals("", arr.get(1));
+ }
+
@Test
void testMultipleIncludes() {
assetLibrary.includeCount()
diff --git a/src/test/java/com/contentstack/sdk/TestCSHttpConnection.java b/src/test/java/com/contentstack/sdk/TestCSHttpConnection.java
index 754e96f6..bf2a097e 100644
--- a/src/test/java/com/contentstack/sdk/TestCSHttpConnection.java
+++ b/src/test/java/com/contentstack/sdk/TestCSHttpConnection.java
@@ -399,6 +399,33 @@ void testGetParamsWithMultipleTypes() throws Exception {
assertTrue(result.contains("environment=staging"));
}
+ @Test
+ void testGetParamsWithAssetFieldsArray() throws Exception {
+ connection.setInfo("ENTRY");
+
+ HashMap params = new HashMap<>();
+ params.put("environment", "production");
+
+ JSONArray assetFieldsArray = new JSONArray();
+ assetFieldsArray.put("user_defined_fields");
+ assetFieldsArray.put("embedded");
+ assetFieldsArray.put("ai_suggested");
+ assetFieldsArray.put("visual_markups");
+ params.put("asset_fields[]", assetFieldsArray);
+
+ Method getParamsMethod = CSHttpConnection.class.getDeclaredMethod("getParams", HashMap.class);
+ getParamsMethod.setAccessible(true);
+
+ String result = (String) getParamsMethod.invoke(connection, params);
+
+ assertNotNull(result);
+ assertTrue(result.contains("environment=production"));
+ assertTrue(result.contains("user_defined_fields"));
+ assertTrue(result.contains("embedded"));
+ assertTrue(result.contains("ai_suggested"));
+ assertTrue(result.contains("visual_markups"));
+ }
+
// ========== CONVERT URL PARAM TESTS ==========
@Test
diff --git a/src/test/java/com/contentstack/sdk/TestEntry.java b/src/test/java/com/contentstack/sdk/TestEntry.java
index 4cf7ac2d..827cfabc 100644
--- a/src/test/java/com/contentstack/sdk/TestEntry.java
+++ b/src/test/java/com/contentstack/sdk/TestEntry.java
@@ -1,5 +1,6 @@
package com.contentstack.sdk;
+import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -251,6 +252,106 @@ void testIncludeMetadata() {
assertEquals(true, entry.params.get("include_metadata"));
}
+ // ========== ASSET FIELDS TESTS (CDA asset_fields[] parameter) ==========
+
+ @Test
+ void testAssetFieldsWithSupportedValues() {
+ Entry result = entry.assetFields("user_defined_fields", "embedded", "ai_suggested", "visual_markups");
+ assertSame(entry, result);
+ assertTrue(entry.params.has("asset_fields[]"));
+ Object val = entry.params.get("asset_fields[]");
+ assertTrue(val instanceof JSONArray);
+ JSONArray arr = (JSONArray) val;
+ assertEquals(4, arr.length());
+ assertEquals("user_defined_fields", arr.get(0));
+ assertEquals("embedded", arr.get(1));
+ assertEquals("ai_suggested", arr.get(2));
+ assertEquals("visual_markups", arr.get(3));
+ }
+
+ @Test
+ void testAssetFieldsReturnsThis() {
+ Entry result = entry.assetFields("embedded");
+ assertSame(entry, result);
+ }
+
+ @Test
+ void testAssetFieldsWithNoArgsDoesNotSetParam() {
+ entry.assetFields();
+ assertFalse(entry.params.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsWithNullDoesNotSetParam() {
+ entry.assetFields((String[]) null);
+ assertFalse(entry.params.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsChainingWithIncludeMetadata() {
+ Entry result = entry.assetFields("user_defined_fields", "visual_markups").includeMetadata().setLocale("en-us");
+ assertSame(entry, result);
+ assertTrue(entry.params.has("asset_fields[]"));
+ assertTrue(entry.params.has("include_metadata"));
+ assertTrue(entry.params.has("locale"));
+ }
+
+ /**
+ * Usage: stack.contentType(ctUid).entry(entryUid).assetFields(...).fetch()
+ * Verifies the full chain sets asset_fields[] on the entry before fetch.
+ */
+ @Test
+ void testUsageSingleEntryFetchWithAssetFields() throws IllegalAccessException {
+ Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
+ Entry entry = stack.contentType("blog").entry("entry_123")
+ .assetFields("user_defined_fields", "embedded");
+ assertTrue(entry.params.has("asset_fields[]"));
+ JSONArray arr = entry.params.getJSONArray("asset_fields[]");
+ assertEquals(2, arr.length());
+ assertEquals("user_defined_fields", arr.get(0));
+ assertEquals("embedded", arr.get(1));
+ }
+
+ @Test
+ void testAssetFieldsSingleField() {
+ entry.assetFields("embedded");
+ JSONArray arr = entry.params.getJSONArray("asset_fields[]");
+ assertEquals(1, arr.length());
+ assertEquals("embedded", arr.get(0));
+ }
+
+ @Test
+ void testAssetFieldsEmptyVarargsArrayDoesNotSetParam() {
+ entry.assetFields(new String[0]);
+ assertFalse(entry.params.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsSecondCallOverwrites() {
+ entry.assetFields("user_defined_fields", "embedded");
+ entry.assetFields("ai_suggested");
+ JSONArray arr = entry.params.getJSONArray("asset_fields[]");
+ assertEquals(1, arr.length());
+ assertEquals("ai_suggested", arr.get(0));
+ }
+
+ @Test
+ void testAssetFieldsDuplicateValuesAllowed() {
+ entry.assetFields("embedded", "embedded");
+ JSONArray arr = entry.params.getJSONArray("asset_fields[]");
+ assertEquals(2, arr.length());
+ assertEquals("embedded", arr.get(0));
+ assertEquals("embedded", arr.get(1));
+ }
+
+ @Test
+ void testAssetFieldsWithEmptyStringInArray() {
+ entry.assetFields("valid", "", "visual_markups");
+ JSONArray arr = entry.params.getJSONArray("asset_fields[]");
+ assertEquals(3, arr.length());
+ assertEquals("", arr.get(1));
+ }
+
// ========== ONLY/EXCEPT FIELD TESTS ==========
@Test
diff --git a/src/test/java/com/contentstack/sdk/TestQuery.java b/src/test/java/com/contentstack/sdk/TestQuery.java
index 065ef3d1..667fdf1b 100644
--- a/src/test/java/com/contentstack/sdk/TestQuery.java
+++ b/src/test/java/com/contentstack/sdk/TestQuery.java
@@ -550,6 +550,109 @@ void testIncludeMetadata() {
assertNotNull(query.urlQueries);
}
+ // ========== ASSET FIELDS TESTS (CDA asset_fields[] parameter) ==========
+
+ @Test
+ void testAssetFieldsWithSupportedValues() {
+ Query result = query.assetFields("user_defined_fields", "embedded", "ai_suggested", "visual_markups");
+ assertSame(query, result);
+ assertTrue(query.urlQueries.has("asset_fields[]"));
+ Object val = query.urlQueries.get("asset_fields[]");
+ assertTrue(val instanceof JSONArray);
+ JSONArray arr = (JSONArray) val;
+ assertEquals(4, arr.length());
+ assertEquals("user_defined_fields", arr.get(0));
+ assertEquals("embedded", arr.get(1));
+ assertEquals("ai_suggested", arr.get(2));
+ assertEquals("visual_markups", arr.get(3));
+ }
+
+ @Test
+ void testAssetFieldsReturnsThis() {
+ Query result = query.assetFields("embedded");
+ assertSame(query, result);
+ }
+
+ @Test
+ void testAssetFieldsWithNoArgsDoesNotSetParam() {
+ query.assetFields();
+ assertFalse(query.urlQueries.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsWithNullDoesNotSetParam() {
+ query.assetFields((String[]) null);
+ assertFalse(query.urlQueries.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsChainingWithIncludeMetadata() {
+ Query result = query.assetFields("ai_suggested", "visual_markups").includeMetadata().includeCount();
+ assertSame(query, result);
+ assertTrue(query.urlQueries.has("asset_fields[]"));
+ assertTrue(query.urlQueries.has("include_count"));
+ JSONArray arr = query.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(2, arr.length());
+ assertEquals("ai_suggested", arr.get(0));
+ assertEquals("visual_markups", arr.get(1));
+ }
+
+ /**
+ * Usage: stack.contentType(ctUid).query().assetFields(...).find()
+ * Verifies the full chain sets asset_fields[] on the query before find.
+ */
+ @Test
+ void testUsageQueryEntriesFindWithAssetFields() throws IllegalAccessException {
+ Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
+ Query query = stack.contentType("blog").query()
+ .assetFields("ai_suggested", "visual_markups");
+ assertTrue(query.urlQueries.has("asset_fields[]"));
+ JSONArray arr = query.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(2, arr.length());
+ assertEquals("ai_suggested", arr.get(0));
+ assertEquals("visual_markups", arr.get(1));
+ }
+
+ @Test
+ void testAssetFieldsSingleField() {
+ query.assetFields("user_defined_fields");
+ JSONArray arr = query.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(1, arr.length());
+ assertEquals("user_defined_fields", arr.get(0));
+ }
+
+ @Test
+ void testAssetFieldsEmptyVarargsArrayDoesNotSetParam() {
+ query.assetFields(new String[0]);
+ assertFalse(query.urlQueries.has("asset_fields[]"));
+ }
+
+ @Test
+ void testAssetFieldsSecondCallOverwrites() {
+ query.assetFields("user_defined_fields", "embedded");
+ query.assetFields("visual_markups");
+ JSONArray arr = query.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(1, arr.length());
+ assertEquals("visual_markups", arr.get(0));
+ }
+
+ @Test
+ void testAssetFieldsDuplicateValuesAllowed() {
+ query.assetFields("ai_suggested", "ai_suggested");
+ JSONArray arr = query.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(2, arr.length());
+ assertEquals("ai_suggested", arr.get(0));
+ assertEquals("ai_suggested", arr.get(1));
+ }
+
+ @Test
+ void testAssetFieldsWithEmptyStringInArray() {
+ query.assetFields("valid", "", "embedded");
+ JSONArray arr = query.urlQueries.getJSONArray("asset_fields[]");
+ assertEquals(3, arr.length());
+ assertEquals("", arr.get(1));
+ }
+
@Test
void testMultipleIncludeMethods() {
query.includeFallback()