Skip to content

Commit cc3918a

Browse files
committed
feat: Implement assetFields method across multiple classes for enhanced asset querying
1 parent cf9c3b2 commit cc3918a

File tree

11 files changed

+521
-3
lines changed

11 files changed

+521
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,4 @@ src/main/resources/
274274
/.vscode/
275275
/docs/
276276
INTEGRATION-TESTS-GUIDE.md
277+
src/main/java/com/demo/*

src/main/java/com/contentstack/sdk/Asset.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.contentstack.sdk;
22

33
import org.jetbrains.annotations.NotNull;
4+
import org.json.JSONArray;
45
import org.json.JSONObject;
56
import retrofit2.Retrofit;
67
import lombok.Getter;
@@ -544,6 +545,19 @@ public Asset includeMetadata() {
544545
return this;
545546
}
546547

548+
public Asset assetFields(String... fields) {
549+
if (fields != null && fields.length > 0) {
550+
JSONArray array = new JSONArray();
551+
for (String field : fields) {
552+
array.put(field);
553+
}
554+
if (!array.isEmpty()) {
555+
urlQueries.put("asset_fields[]", array);
556+
}
557+
}
558+
return this;
559+
}
560+
547561
/**
548562
* Fetch.
549563
*

src/main/java/com/contentstack/sdk/AssetLibrary.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.jetbrains.annotations.NotNull;
44
import org.json.JSONObject;
5+
import org.json.JSONArray;
56

67
import java.util.*;
78
import java.util.logging.Logger;
@@ -33,7 +34,8 @@ protected void setStackInstance(@NotNull Stack stack) {
3334

3435
//Sanitization of keys
3536
private boolean isValidKey(String key) {
36-
return key.matches("^[a-zA-Z0-9_.]+$");
37+
// Fixed regex: allow alphanumeric, underscore, dot, and square brackets at the end, escaped properly
38+
return key.matches("^[a-zA-Z0-9_.]+(\\[\\])?$");
3739
}
3840

3941
//Sanitization of values
@@ -265,6 +267,19 @@ public AssetLibrary limit (@NotNull int number) {
265267
return this;
266268
}
267269

270+
public AssetLibrary assetFields(String... fields) {
271+
if (fields != null && fields.length > 0) {
272+
JSONArray array = new JSONArray();
273+
for (String field : fields) {
274+
array.put(field);
275+
}
276+
if (!array.isEmpty()) {
277+
urlQueries.put("asset_fields[]", array);
278+
}
279+
}
280+
return this;
281+
}
282+
268283
/**
269284
* Fetch all.
270285
*

src/main/java/com/contentstack/sdk/CSHttpConnection.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ public String setFormParamsGET(HashMap<String, Object> params) {
102102
if (params != null && params.size() > 0) {
103103
String urlParams = null;
104104
urlParams = info.equalsIgnoreCase(Constants.REQUEST_CONTROLLER.QUERY.name())
105-
|| info.equalsIgnoreCase(Constants.REQUEST_CONTROLLER.ENTRY.name()) ? getParams(params) : null;
105+
|| info.equalsIgnoreCase(Constants.REQUEST_CONTROLLER.ENTRY.name())
106+
|| info.equalsIgnoreCase(Constants.REQUEST_CONTROLLER.ASSET.name())
107+
|| info.equalsIgnoreCase(Constants.REQUEST_CONTROLLER.ASSETLIBRARY.name()) ? getParams(params) : null;
106108
if (urlParams == null) {
107109
for (Map.Entry<String, Object> e : params.entrySet()) {
108110
if (urlParams == null) {
@@ -124,7 +126,7 @@ private String getParams(HashMap<String, Object> params) {
124126
Object value = e.getValue();
125127
try {
126128
if (key.equalsIgnoreCase("include[]") || key.equalsIgnoreCase("only[BASE][]")
127-
|| key.equalsIgnoreCase("except[BASE][]")) {
129+
|| key.equalsIgnoreCase("except[BASE][]") || key.equalsIgnoreCase("asset_fields[]")) {
128130
urlParams = convertUrlParam(urlParams, value, key);
129131
} else if (key.equalsIgnoreCase("only")) {
130132
JSONObject onlyJSON = (JSONObject) value;

src/main/java/com/contentstack/sdk/Entry.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,19 @@ public Entry exceptWithReferenceUid(@NotNull List<String> fieldUid, @NotNull Str
904904
return this;
905905
}
906906

907+
908+
public Entry assetFields(String... fields) {
909+
if (fields != null && fields.length > 0) {
910+
JSONArray array = new JSONArray();
911+
for (String field : fields) {
912+
array.put(field);
913+
}
914+
if (!array.isEmpty()) {
915+
params.put("asset_fields[]", array);
916+
}
917+
}
918+
return this;
919+
}
907920
/**
908921
* Fetches the latest version of the entries from Contentstack.com content stack
909922
*

src/main/java/com/contentstack/sdk/Query.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,19 @@ public Query search(@NotNull String value) {
11461146
return this;
11471147
}
11481148

1149+
public Query assetFields(String... fields) {
1150+
if (fields != null && fields.length > 0) {
1151+
JSONArray array = new JSONArray();
1152+
for (String field : fields) {
1153+
array.put(field);
1154+
}
1155+
if (!array.isEmpty()) {
1156+
urlQueries.put("asset_fields[]", array);
1157+
}
1158+
}
1159+
return this;
1160+
}
1161+
11491162
/**
11501163
* Execute a Query and Caches its result (Optional)
11511164
*

src/test/java/com/contentstack/sdk/TestAsset.java

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,133 @@ void testIncludeMetadata() {
182182
assertEquals(true, asset.urlQueries.get("include_metadata"));
183183
}
184184

185+
// ========== ASSET FIELDS TESTS (CDA asset_fields[] parameter) ==========
186+
187+
@Test
188+
void testAssetFieldsWithSupportedValues() {
189+
Asset result = asset.assetFields("user_defined_fields", "embedded", "ai_suggested", "visual_markups");
190+
assertSame(asset, result);
191+
assertTrue(asset.urlQueries.has("asset_fields[]"));
192+
Object val = asset.urlQueries.get("asset_fields[]");
193+
assertTrue(val instanceof JSONArray);
194+
JSONArray arr = (JSONArray) val;
195+
assertEquals(4, arr.length());
196+
assertEquals("user_defined_fields", arr.get(0));
197+
assertEquals("embedded", arr.get(1));
198+
assertEquals("ai_suggested", arr.get(2));
199+
assertEquals("visual_markups", arr.get(3));
200+
}
201+
202+
@Test
203+
void testAssetFieldsReturnsThis() {
204+
Asset result = asset.assetFields("user_defined_fields");
205+
assertSame(asset, result);
206+
}
207+
208+
@Test
209+
void testAssetFieldsWithNoArgsDoesNotSetParam() {
210+
asset.assetFields();
211+
assertFalse(asset.urlQueries.has("asset_fields[]"));
212+
}
213+
214+
@Test
215+
void testAssetFieldsWithNullDoesNotSetParam() {
216+
asset.assetFields((String[]) null);
217+
assertFalse(asset.urlQueries.has("asset_fields[]"));
218+
}
219+
220+
@Test
221+
void testAssetFieldsChainingWithOtherMethods() {
222+
Asset result = asset.assetFields("embedded", "visual_markups")
223+
.includeMetadata()
224+
.includeDimension();
225+
assertSame(asset, result);
226+
assertTrue(asset.urlQueries.has("asset_fields[]"));
227+
assertTrue(asset.urlQueries.has("include_metadata"));
228+
assertTrue(asset.urlQueries.has("include_dimension"));
229+
JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
230+
assertEquals(2, arr.length());
231+
assertEquals("embedded", arr.get(0));
232+
assertEquals("visual_markups", arr.get(1));
233+
}
234+
235+
/**
236+
* Usage: stack.asset(assetUid).assetFields(...).fetch()
237+
* Verifies the full chain sets asset_fields[] on the asset before fetch.
238+
*/
239+
@Test
240+
void testUsageSingleAssetFetchWithAssetFields() throws IllegalAccessException {
241+
Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
242+
Asset asset = stack.asset("asset_uid_123")
243+
.assetFields("embedded", "visual_markups");
244+
assertTrue(asset.urlQueries.has("asset_fields[]"));
245+
JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
246+
assertEquals(2, arr.length());
247+
assertEquals("embedded", arr.get(0));
248+
assertEquals("visual_markups", arr.get(1));
249+
}
250+
251+
252+
@Test
253+
void testAssetFieldsSingleField() {
254+
asset.assetFields("embedded");
255+
assertTrue(asset.urlQueries.has("asset_fields[]"));
256+
JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
257+
assertEquals(1, arr.length());
258+
assertEquals("embedded", arr.get(0));
259+
}
260+
261+
@Test
262+
void testAssetFieldsEmptyVarargsArrayDoesNotSetParam() {
263+
asset.assetFields(new String[0]);
264+
assertFalse(asset.urlQueries.has("asset_fields[]"));
265+
}
266+
267+
@Test
268+
void testAssetFieldsDuplicateValuesAllowed() {
269+
asset.assetFields("embedded", "embedded");
270+
JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
271+
assertEquals(2, arr.length());
272+
assertEquals("embedded", arr.get(0));
273+
assertEquals("embedded", arr.get(1));
274+
}
275+
276+
@Test
277+
void testAssetFieldsSecondCallOverwrites() {
278+
asset.assetFields("user_defined_fields", "embedded");
279+
asset.assetFields("ai_suggested");
280+
JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
281+
assertEquals(1, arr.length());
282+
assertEquals("ai_suggested", arr.get(0));
283+
}
284+
285+
@Test
286+
void testAssetFieldsWithEmptyStringInArray() {
287+
asset.assetFields("valid", "", "embedded");
288+
JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
289+
assertEquals(3, arr.length());
290+
assertEquals("valid", arr.get(0));
291+
assertEquals("", arr.get(1));
292+
assertEquals("embedded", arr.get(2));
293+
}
294+
295+
@Test
296+
void testAssetFieldsWithNullInArray() {
297+
asset.assetFields("valid", null, "embedded");
298+
JSONArray arr = asset.urlQueries.getJSONArray("asset_fields[]");
299+
assertEquals(3, arr.length());
300+
assertEquals("valid", arr.get(0));
301+
assertEquals("embedded", arr.get(2));
302+
}
303+
304+
@Test
305+
void testAssetFieldsSingleEmptyStringSetsParam() {
306+
asset.assetFields("");
307+
assertTrue(asset.urlQueries.has("asset_fields[]"));
308+
assertEquals(1, asset.urlQueries.getJSONArray("asset_fields[]").length());
309+
assertEquals("", asset.urlQueries.getJSONArray("asset_fields[]").get(0));
310+
}
311+
185312
// ========== CHAINING TESTS ==========
186313

187314
@Test

src/test/java/com/contentstack/sdk/TestAssetLibrary.java

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.contentstack.sdk;
22

3+
import org.json.JSONArray;
34
import org.json.JSONObject;
45
import org.junit.jupiter.api.BeforeEach;
56
import org.junit.jupiter.api.Test;
@@ -135,6 +136,107 @@ void testIncludeMetadata() {
135136
assertEquals(true, assetLibrary.urlQueries.get("include_metadata"));
136137
}
137138

139+
// ========== ASSET FIELDS TESTS (CDA asset_fields[] parameter) ==========
140+
141+
@Test
142+
void testAssetFieldsWithSupportedValues() {
143+
AssetLibrary result = assetLibrary.assetFields("user_defined_fields", "embedded", "ai_suggested", "visual_markups");
144+
assertSame(assetLibrary, result);
145+
assertTrue(assetLibrary.urlQueries.has("asset_fields[]"));
146+
Object val = assetLibrary.urlQueries.get("asset_fields[]");
147+
assertTrue(val instanceof JSONArray);
148+
JSONArray arr = (JSONArray) val;
149+
assertEquals(4, arr.length());
150+
assertEquals("user_defined_fields", arr.get(0));
151+
assertEquals("embedded", arr.get(1));
152+
assertEquals("ai_suggested", arr.get(2));
153+
assertEquals("visual_markups", arr.get(3));
154+
}
155+
156+
@Test
157+
void testAssetFieldsReturnsThis() {
158+
AssetLibrary result = assetLibrary.assetFields("embedded");
159+
assertSame(assetLibrary, result);
160+
}
161+
162+
@Test
163+
void testAssetFieldsWithNoArgsDoesNotSetParam() {
164+
assetLibrary.assetFields();
165+
assertFalse(assetLibrary.urlQueries.has("asset_fields[]"));
166+
}
167+
168+
@Test
169+
void testAssetFieldsWithNullDoesNotSetParam() {
170+
assetLibrary.assetFields((String[]) null);
171+
assertFalse(assetLibrary.urlQueries.has("asset_fields[]"));
172+
}
173+
174+
@Test
175+
void testAssetFieldsChainingWithIncludeMetadata() {
176+
AssetLibrary result = assetLibrary.assetFields("user_defined_fields").includeMetadata().includeCount();
177+
assertSame(assetLibrary, result);
178+
assertTrue(assetLibrary.urlQueries.has("asset_fields[]"));
179+
assertTrue(assetLibrary.urlQueries.has("include_metadata"));
180+
assertTrue(assetLibrary.urlQueries.has("include_count"));
181+
}
182+
183+
/**
184+
* Usage: stack.assetLibrary().assetFields(...).fetchAll()
185+
* (AssetQuery / query assets - in this SDK use assetLibrary(), not asset().find())
186+
* Verifies the full chain sets asset_fields[] on the asset library before fetchAll.
187+
*/
188+
@Test
189+
void testUsageAssetLibraryFetchAllWithAssetFields() throws IllegalAccessException {
190+
Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
191+
AssetLibrary lib = stack.assetLibrary()
192+
.assetFields("user_defined_fields", "embedded");
193+
assertTrue(lib.urlQueries.has("asset_fields[]"));
194+
JSONArray arr = lib.urlQueries.getJSONArray("asset_fields[]");
195+
assertEquals(2, arr.length());
196+
assertEquals("user_defined_fields", arr.get(0));
197+
assertEquals("embedded", arr.get(1));
198+
}
199+
200+
@Test
201+
void testAssetFieldsSingleField() {
202+
assetLibrary.assetFields("visual_markups");
203+
JSONArray arr = assetLibrary.urlQueries.getJSONArray("asset_fields[]");
204+
assertEquals(1, arr.length());
205+
assertEquals("visual_markups", arr.get(0));
206+
}
207+
208+
@Test
209+
void testAssetFieldsEmptyVarargsArrayDoesNotSetParam() {
210+
assetLibrary.assetFields(new String[0]);
211+
assertFalse(assetLibrary.urlQueries.has("asset_fields[]"));
212+
}
213+
214+
@Test
215+
void testAssetFieldsSecondCallOverwrites() {
216+
assetLibrary.assetFields("user_defined_fields", "embedded");
217+
assetLibrary.assetFields("ai_suggested");
218+
JSONArray arr = assetLibrary.urlQueries.getJSONArray("asset_fields[]");
219+
assertEquals(1, arr.length());
220+
assertEquals("ai_suggested", arr.get(0));
221+
}
222+
223+
@Test
224+
void testAssetFieldsDuplicateValuesAllowed() {
225+
assetLibrary.assetFields("embedded", "embedded");
226+
JSONArray arr = assetLibrary.urlQueries.getJSONArray("asset_fields[]");
227+
assertEquals(2, arr.length());
228+
assertEquals("embedded", arr.get(0));
229+
assertEquals("embedded", arr.get(1));
230+
}
231+
232+
@Test
233+
void testAssetFieldsWithEmptyStringInArray() {
234+
assetLibrary.assetFields("valid", "", "visual_markups");
235+
JSONArray arr = assetLibrary.urlQueries.getJSONArray("asset_fields[]");
236+
assertEquals(3, arr.length());
237+
assertEquals("", arr.get(1));
238+
}
239+
138240
@Test
139241
void testMultipleIncludes() {
140242
assetLibrary.includeCount()

0 commit comments

Comments
 (0)