Skip to content

Commit 5f0828d

Browse files
committed
Feat: variant and branch support in Entry and Query APIs and added integration tests
1 parent 14ea923 commit 5f0828d

7 files changed

Lines changed: 1592 additions & 12 deletions

File tree

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

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,26 +1145,40 @@ public Entry includeMetadata() {
11451145
}
11461146

11471147
/**
1148-
* The variant header will be added to client
1149-
* @return {Entry}
1150-
*
1151-
* import contentstack from '@contentstack/delivery-sdk'
1148+
* Sets a single variant UID for the entry request.
1149+
* Adds the {@code x-cs-variant-uid} header to the request.
1150+
*
1151+
* @param variants single variant UID
1152+
* @return {@link Entry} object, so you can chain this call.
11521153
*
1153-
* Stack stack = contentstack.Stack("apiKey", "deliveryToken",
1154-
* "environment");
1155-
* Entry entry =
1156-
* stack.contentType("user").entry("entry_uid").variant("variant_uid").fetch();
1154+
* <pre class="prettyprint">
1155+
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
1156+
* Entry entry = stack.contentType("abc").entry("entry_uid").variants("xyz");
1157+
* entry.fetch(callback);
1158+
* </pre>
11571159
*/
11581160
public Entry variants(@NotNull String variants) {
1159-
if (variants != null && variants.length() > 0) {
1161+
if (!variants.isEmpty()) {
11601162
this.headers.put("x-cs-variant-uid", variants.trim());
11611163
}
11621164
return this;
1163-
11641165
}
11651166

1167+
/**
1168+
* Sets multiple variant UIDs for the entry request.
1169+
* Adds the {@code x-cs-variant-uid} header with a comma-separated list.
1170+
*
1171+
* @param variants array of variant UIDs
1172+
* @return {@link Entry} object, so you can chain this call.
1173+
*
1174+
* <pre class="prettyprint">
1175+
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
1176+
* Entry entry = stack.contentType("abc").entry("entry_uid").variants(new String[]{"v1","v2"});
1177+
* entry.fetch(callback);
1178+
* </pre>
1179+
*/
11661180
public Entry variants(@NotNull String[] variants) {
1167-
if (variants != null && variants.length > 0) {
1181+
if (variants.length > 0) {
11681182
List<String> variantList = new ArrayList<>();
11691183
for (String variant : variants) {
11701184
if (variant != null && !variant.trim().isEmpty())
@@ -1177,6 +1191,51 @@ public Entry variants(@NotNull String[] variants) {
11771191
return this;
11781192
}
11791193

1194+
/**
1195+
* Sets the variant UID and branch for the entry request.
1196+
* The {@code x-cs-variant-uid} and {@code branch} headers are added to the request.
1197+
*
1198+
* @param variants single variant UID
1199+
* @param branch branch name to scope this request
1200+
* @return {@link Entry} object, so you can chain this call.
1201+
*
1202+
* <pre class="prettyprint">
1203+
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
1204+
* Entry entry = stack.contentType("abc").entry("entry_uid").variants("xyz", "branch_name");
1205+
* entry.fetch(callback);
1206+
* </pre>
1207+
*/
1208+
public Entry variants(@NotNull String variants, @NotNull String branch) {
1209+
variants(variants);
1210+
return applyBranch(branch);
1211+
}
1212+
1213+
/**
1214+
* Sets multiple variant UIDs and a branch for the entry request.
1215+
* The {@code x-cs-variant-uid} and {@code branch} headers are added to the request.
1216+
*
1217+
* @param variants array of variant UIDs
1218+
* @param branch branch name to scope this request
1219+
* @return {@link Entry} object, so you can chain this call.
1220+
*
1221+
* <pre class="prettyprint">
1222+
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
1223+
* Entry entry = stack.contentType("abc").entry("entry_uid").variants(new String[]{"v1","v2"}, "branch_name");
1224+
* entry.fetch(callback);
1225+
* </pre>
1226+
*/
1227+
public Entry variants(@NotNull String[] variants, @NotNull String branch) {
1228+
variants(variants);
1229+
return applyBranch(branch);
1230+
}
1231+
1232+
private Entry applyBranch(String branch) {
1233+
if (branch != null && !branch.isEmpty()) {
1234+
this.headers.put("branch", branch.trim());
1235+
}
1236+
return this;
1237+
}
1238+
11801239
public LinkedHashMap<String, Object> getHeaders() {
11811240
return headers;
11821241
}

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

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,4 +1559,96 @@ public Query includeMetadata() {
15591559
urlQueries.put("include_metadata", true);
15601560
return this;
15611561
}
1562+
1563+
/**
1564+
* Sets a single variant UID for the query request.
1565+
* Adds the {@code x-cs-variant-uid} header to the request.
1566+
*
1567+
* @param variants single variant UID
1568+
* @return {@link Query} object, so you can chain this call.
1569+
*
1570+
* <pre class="prettyprint">
1571+
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
1572+
* Query query = stack.contentType("abc").query().variants("xyz");
1573+
* query.find(callback);
1574+
* </pre>
1575+
*/
1576+
public Query variants(@NotNull String variants) {
1577+
if (!variants.isEmpty()) {
1578+
this.headers.put("x-cs-variant-uid", variants.trim());
1579+
}
1580+
return this;
1581+
}
1582+
1583+
/**
1584+
* Sets multiple variant UIDs for the query request.
1585+
* Adds the {@code x-cs-variant-uid} header with a comma-separated list.
1586+
*
1587+
* @param variants array of variant UIDs
1588+
* @return {@link Query} object, so you can chain this call.
1589+
*
1590+
* <pre class="prettyprint">
1591+
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
1592+
* Query query = stack.contentType("abc").query().variants(new String[]{"v1","v2"});
1593+
* query.find(callback);
1594+
* </pre>
1595+
*/
1596+
public Query variants(@NotNull String[] variants) {
1597+
if (variants.length > 0) {
1598+
List<String> variantList = new ArrayList<>();
1599+
for (String variant : variants) {
1600+
if (variant != null && !variant.trim().isEmpty())
1601+
variantList.add(variant.trim());
1602+
}
1603+
if (!variantList.isEmpty()) {
1604+
this.headers.put("x-cs-variant-uid", String.join(", ", variantList));
1605+
}
1606+
}
1607+
return this;
1608+
}
1609+
1610+
/**
1611+
* Sets a single variant UID and branch for the query request.
1612+
* Adds {@code x-cs-variant-uid} and {@code branch} headers to the request.
1613+
*
1614+
* @param variants single variant UID
1615+
* @param branch branch name to scope this request
1616+
* @return {@link Query} object, so you can chain this call.
1617+
*
1618+
* <pre class="prettyprint">
1619+
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
1620+
* Query query = stack.contentType("abc").query().variants("xyz", "branch_name");
1621+
* query.find(callback);
1622+
* </pre>
1623+
*/
1624+
public Query variants(@NotNull String variants, @NotNull String branch) {
1625+
variants(variants);
1626+
return applyBranch(branch);
1627+
}
1628+
1629+
/**
1630+
* Sets multiple variant UIDs and a branch for the query request.
1631+
* Adds {@code x-cs-variant-uid} and {@code branch} headers to the request.
1632+
*
1633+
* @param variants array of variant UIDs
1634+
* @param branch branch name to scope this request
1635+
* @return {@link Query} object, so you can chain this call.
1636+
*
1637+
* <pre class="prettyprint">
1638+
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
1639+
* Query query = stack.contentType("abc").query().variants(new String[]{"v1","v2"}, "branch_name");
1640+
* query.find(callback);
1641+
* </pre>
1642+
*/
1643+
public Query variants(@NotNull String[] variants, @NotNull String branch) {
1644+
variants(variants);
1645+
return applyBranch(branch);
1646+
}
1647+
1648+
private Query applyBranch(String branch) {
1649+
if (branch != null && !branch.isEmpty()) {
1650+
this.headers.put("branch", branch.trim());
1651+
}
1652+
return this;
1653+
}
15621654
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@ public static boolean hasVariantSupport() {
124124
return VARIANT_UID != null && !VARIANT_UID.isEmpty();
125125
}
126126

127+
/**
128+
* Check if branch support is configured
129+
*/
130+
public static boolean hasBranchSupport() {
131+
return BRANCH_UID != null && !BRANCH_UID.isEmpty();
132+
}
133+
127134
/**
128135
* Check if global field configuration is available
129136
*/

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

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,83 @@ void testVariantsWithNullAndEmptyStrings() throws IllegalAccessException {
11401140
assertFalse(headerValue.contains("null"));
11411141
}
11421142

1143+
// ========== VARIANTS WITH BRANCH TESTS ==========
1144+
1145+
@Test
1146+
void testVariantsWithSingleVariantAndBranch() throws IllegalAccessException {
1147+
Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
1148+
Entry entry = stack.contentType("test").entry();
1149+
1150+
Entry result = entry.variants("variant_uid_123", "staging");
1151+
1152+
assertNotNull(result);
1153+
assertEquals("variant_uid_123", entry.headers.get("x-cs-variant-uid"));
1154+
assertEquals("staging", entry.headers.get("branch"));
1155+
}
1156+
1157+
@Test
1158+
void testVariantsWithMultipleVariantsAndBranch() throws IllegalAccessException {
1159+
Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
1160+
Entry entry = stack.contentType("test").entry();
1161+
1162+
Entry result = entry.variants(new String[]{"variant1", "variant2"}, "feature-branch");
1163+
1164+
assertNotNull(result);
1165+
String variantHeader = (String) entry.headers.get("x-cs-variant-uid");
1166+
assertTrue(variantHeader.contains("variant1"));
1167+
assertTrue(variantHeader.contains("variant2"));
1168+
assertEquals("feature-branch", entry.headers.get("branch"));
1169+
}
1170+
1171+
@Test
1172+
void testVariantsWithEmptyVariantAndBranch() throws IllegalAccessException {
1173+
Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
1174+
Entry entry = stack.contentType("test").entry();
1175+
1176+
entry.variants("", "staging");
1177+
1178+
assertFalse(entry.headers.containsKey("x-cs-variant-uid"));
1179+
assertEquals("staging", entry.headers.get("branch"));
1180+
}
1181+
1182+
@Test
1183+
void testVariantsWithEmptyBranch() throws IllegalAccessException {
1184+
Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
1185+
Entry entry = stack.contentType("test").entry();
1186+
1187+
entry.variants("variant_uid_123", "");
1188+
1189+
assertEquals("variant_uid_123", entry.headers.get("x-cs-variant-uid"));
1190+
assertFalse(entry.headers.containsKey("branch"));
1191+
}
1192+
1193+
@Test
1194+
void testVariantsArrayWithNullAndEmptyStringsAndBranch() throws IllegalAccessException {
1195+
Stack stack = Contentstack.stack("api_key", "delivery_token", "env");
1196+
Entry entry = stack.contentType("test").entry();
1197+
1198+
entry.variants(new String[]{null, "", "valid_variant", " ", "another_valid"}, "main");
1199+
1200+
String variantHeader = (String) entry.headers.get("x-cs-variant-uid");
1201+
assertTrue(variantHeader.contains("valid_variant"));
1202+
assertTrue(variantHeader.contains("another_valid"));
1203+
assertFalse(variantHeader.contains("null"));
1204+
assertEquals("main", entry.headers.get("branch"));
1205+
}
1206+
1207+
@Test
1208+
void testVariantsBranchOverridesStackBranch() throws IllegalAccessException {
1209+
Config config = new Config();
1210+
config.setBranch("main");
1211+
Stack stack = Contentstack.stack("api_key", "delivery_token", "env", config);
1212+
Entry entry = stack.contentType("test").entry();
1213+
1214+
entry.variants("variant_uid_123", "feature-branch");
1215+
1216+
assertEquals("variant_uid_123", entry.headers.get("x-cs-variant-uid"));
1217+
assertEquals("feature-branch", entry.headers.get("branch"));
1218+
}
1219+
11431220
// ========== GET HEADERS METHOD TEST ==========
11441221

11451222
@Test

0 commit comments

Comments
 (0)