Skip to content

Commit e89b2a8

Browse files
committed
fix(EditableTags): ensure correct variant resolution for array fields and improve tag generation
1 parent 9b98701 commit e89b2a8

File tree

2 files changed

+69
-7
lines changed

2 files changed

+69
-7
lines changed

src/main/java/com/contentstack/utils/EditableTags.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ private static void handleKey(JSONObject tags, String key, Object value, String
167167
if (!metaUid.isEmpty() && !updatedMetakey.isEmpty()) {
168168
updatedMetakey = updatedMetakey + "." + metaUid;
169169
}
170+
// For array fields, per-element processing below must not overwrite this — line 220's field tag uses it.
171+
String fieldMetakey = updatedMetakey;
170172

171173
if (value instanceof JSONArray) {
172174
JSONArray arr = (JSONArray) value;
@@ -178,13 +180,13 @@ private static void handleKey(JSONObject tags, String key, Object value, String
178180
String childKey = key + "__" + index;
179181
String parentKey = key + "__parent";
180182
metaUid = metaUidFromValue(obj);
181-
updatedMetakey = shouldApplyVariant ? metaKeyPrefix + key : "";
182-
if (!metaUid.isEmpty() && !updatedMetakey.isEmpty()) {
183-
updatedMetakey = updatedMetakey + "." + metaUid;
183+
String elementMetakey = shouldApplyVariant ? metaKeyPrefix + key : "";
184+
if (!metaUid.isEmpty() && !elementMetakey.isEmpty()) {
185+
elementMetakey = elementMetakey + "." + metaUid;
184186
}
185187
String indexPath = prefix + "." + key + "." + index;
186188
String fieldPath = prefix + "." + key;
187-
putTag(tags, childKey, indexPath, tagsAsObject, applied, shouldApplyVariant, updatedMetakey);
189+
putTag(tags, childKey, indexPath, tagsAsObject, applied, shouldApplyVariant, elementMetakey);
188190
putParentTag(tags, parentKey, fieldPath, tagsAsObject);
189191
if (obj instanceof JSONObject) {
190192
JSONObject jobj = (JSONObject) obj;
@@ -202,11 +204,11 @@ private static void handleKey(JSONObject tags, String key, Object value, String
202204
: locale;
203205
String refPrefix = jobj.optString("_content_type_uid") + "." + jobj.optString("uid") + "."
204206
+ refLocale;
205-
jobj.put("$", getTag(jobj, refPrefix, tagsAsObject, locale,
207+
jobj.put("$", getTag(jobj, refPrefix, tagsAsObject, refLocale,
206208
new AppliedVariantsState(newApplied, newShould, "")));
207209
} else {
208210
jobj.put("$", getTag(jobj, indexPath, tagsAsObject, locale,
209-
new AppliedVariantsState(applied, shouldApplyVariant, updatedMetakey)));
211+
new AppliedVariantsState(applied, shouldApplyVariant, elementMetakey)));
210212
}
211213
}
212214
}
@@ -217,7 +219,7 @@ private static void handleKey(JSONObject tags, String key, Object value, String
217219
}
218220

219221
String fieldTagPath = prefix + "." + key;
220-
putTag(tags, key, fieldTagPath, tagsAsObject, applied, shouldApplyVariant, updatedMetakey);
222+
putTag(tags, key, fieldTagPath, tagsAsObject, applied, shouldApplyVariant, fieldMetakey);
221223
}
222224

223225
private static String metaUidFromValue(Object value) {

src/test/java/com/contentstack/utils/EditableTagsTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,39 @@ public void arrayFieldIndexAndParentTags() {
8585
Assert.assertEquals("data-cslp=ct.e1.en-us.items", dollar.getString("items"));
8686
}
8787

88+
/**
89+
* Parent field tag for an array must use the field-level metakey (for variant resolution), not the last
90+
* element's {@code _metadata.uid} suffix — otherwise a per-element variant key (e.g. {@code items.uidB})
91+
* would incorrectly win for the parent {@code items} tag.
92+
*/
93+
@Test
94+
public void arrayFieldParentTagUsesFieldMetakeyNotLastElementMetadata() {
95+
JSONObject applied = new JSONObject();
96+
applied.put("items", "fieldVar");
97+
applied.put("items.uidB", "wrongVar");
98+
JSONObject metaA = new JSONObject();
99+
metaA.put("uid", "uidA");
100+
JSONObject metaB = new JSONObject();
101+
metaB.put("uid", "uidB");
102+
JSONObject el0 = new JSONObject();
103+
el0.put("_metadata", metaA);
104+
el0.put("x", "a");
105+
JSONObject el1 = new JSONObject();
106+
el1.put("_metadata", metaB);
107+
el1.put("x", "b");
108+
JSONArray arr = new JSONArray().put(el0).put(el1);
109+
JSONObject entry = new JSONObject();
110+
entry.put("uid", "e1");
111+
entry.put("_applied_variants", applied);
112+
entry.put("items", arr);
113+
Utils.addEditableTags(entry, "ct", false, "en-us", null);
114+
String parentItemsTag = entry.getJSONObject("$").getString("items");
115+
Assert.assertTrue("parent field should resolve variant via key \"items\"",
116+
parentItemsTag.contains("ct.e1_fieldVar.en-us.items"));
117+
Assert.assertFalse("parent field must not apply last element's variant (items.uidB -> wrongVar)",
118+
parentItemsTag.contains("e1_wrongVar"));
119+
}
120+
88121
@Test
89122
public void referenceInArrayUsesRefPrefix() {
90123
JSONObject ref = new JSONObject();
@@ -99,6 +132,33 @@ public void referenceInArrayUsesRefPrefix() {
99132
Assert.assertEquals("data-cslp=author_ct.refuid.en-us.title", refDollar.getString("title"));
100133
}
101134

135+
/**
136+
* Referenced entry may declare its own {@code locale}; recursive {@code getTag} must receive {@code refLocale}
137+
* (not the parent entry locale) so nested plain objects use the correct path segment, and nested refs in arrays
138+
* without {@code locale} fall back to that reference locale (not the top-level entry locale).
139+
*/
140+
@Test
141+
public void referenceInArrayPassesRefLocaleToNestedGetTag() {
142+
JSONObject nested = new JSONObject();
143+
nested.put("name", "Nested");
144+
JSONObject subRef = new JSONObject();
145+
subRef.put("_content_type_uid", "child_ct");
146+
subRef.put("uid", "c1");
147+
subRef.put("x", "v");
148+
JSONObject ref = new JSONObject();
149+
ref.put("_content_type_uid", "author_ct");
150+
ref.put("uid", "refuid");
151+
ref.put("locale", "fr-fr");
152+
ref.put("profile", nested);
153+
ref.put("nested_refs", new JSONArray().put(subRef));
154+
JSONObject entry = new JSONObject();
155+
entry.put("uid", "e1");
156+
entry.put("authors", new JSONArray().put(ref));
157+
Utils.addEditableTags(entry, "post", false, "en-us", null);
158+
Assert.assertEquals("data-cslp=author_ct.refuid.fr-fr.profile.name", nested.getJSONObject("$").getString("name"));
159+
Assert.assertEquals("data-cslp=child_ct.c1.fr-fr.x", subRef.getJSONObject("$").getString("x"));
160+
}
161+
102162
@Test
103163
public void variantDirectFieldAppendsVariantToUidSegment() {
104164
JSONObject applied = new JSONObject();

0 commit comments

Comments
 (0)