Skip to content

Commit 0f793e6

Browse files
committed
feat: add entry variant tests and configuration updates
1 parent baa3c5e commit 0f793e6

10 files changed

Lines changed: 565 additions & 1 deletion

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@
254254
</includes>
255255
<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
256256
<!-- Skip during default lifecycle (e.g. publish); run tests locally with: mvn test -DskipTests=false -->
257-
<!-- <skipTests>true</skipTests> -->
257+
<skipTests>true</skipTests>
258258
<testFailureIgnore>true</testFailureIgnore>
259259
</configuration>
260260
</plugin>

src/test/java/com/contentstack/cms/TestClient.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,26 @@ public class TestClient {
2525
public final static String DEV_HOST = (env.get("dev_host") != null) ? env.get("dev_host").trim() : "api.contentstack.io";
2626
public final static String VARIANT_GROUP_UID = (env.get("variantGroupUid") != null) ? env.get("variantGroupUid")
2727
: "variantGroupUid99999999";
28+
29+
/** Content type UID for entry-variant tests (default {@code blog}). */
30+
public static final String ENTRY_VARIANT_CONTENT_TYPE_UID =
31+
env.get("entryVariantContentTypeUid") != null ? env.get("entryVariantContentTypeUid") : "blog";
32+
33+
/** Stack branch for entry-variant tests (default {@code develop}). */
34+
public static final String ENTRY_VARIANT_BRANCH =
35+
env.get("entryVariantBranch") != null ? env.get("entryVariantBranch") : "develop";
36+
37+
/** Locale query param for entry-variant tests (default {@code en-us}). */
38+
public static final String ENTRY_VARIANT_LOCALE =
39+
env.get("entryVariantLocale") != null ? env.get("entryVariantLocale") : "en-us";
40+
41+
/**
42+
* {@code true} when {@code apiKey} / {@code managementToken} were not loaded from {@code .env} (defaults apply).
43+
*/
44+
public static boolean isUsingDefaultStackCredentials() {
45+
return env.get("apiKey") == null || env.get("managementToken") == null;
46+
}
47+
2848
private static Contentstack instance;
2949
private static Stack stackInstance;
3050

src/test/java/com/contentstack/cms/UnitTestSuite.java

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

33
import com.contentstack.cms.core.AuthInterceptorTest;
4+
import com.contentstack.cms.stack.EntryVariantUnitTest;
45
import com.contentstack.cms.stack.EnvironmentUnitTest;
56
import com.contentstack.cms.stack.GlobalFieldUnitTests;
67
import com.contentstack.cms.stack.LocaleUnitTest;
@@ -25,6 +26,7 @@
2526
ContentstackUnitTest.class,
2627

2728
// Stack module tests (only public classes)
29+
EntryVariantUnitTest.class,
2830
EnvironmentUnitTest.class,
2931
GlobalFieldUnitTests.class,
3032
LocaleUnitTest.class,

src/test/java/com/contentstack/cms/stack/APISanityTestSuite.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
GlobalFieldAPITest.class,
2323
VariantGroupAPITest.class,
2424
VariantGroupTest.class,
25+
EntryVariantAPITest.class,
2526
ReleaseAPITest.class
2627

2728
})
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
package com.contentstack.cms.stack;
2+
3+
import com.contentstack.cms.TestClient;
4+
import com.contentstack.cms.Utils;
5+
import com.contentstack.cms.core.Util;
6+
7+
import okhttp3.Request;
8+
import org.json.simple.JSONArray;
9+
import org.json.simple.JSONObject;
10+
import org.junit.jupiter.api.Assertions;
11+
import org.junit.jupiter.api.BeforeAll;
12+
import org.junit.jupiter.api.MethodOrderer;
13+
import org.junit.jupiter.api.Order;
14+
import org.junit.jupiter.api.Tag;
15+
import org.junit.jupiter.api.Test;
16+
import org.junit.jupiter.api.TestInstance;
17+
import org.junit.jupiter.api.TestMethodOrder;
18+
19+
/**
20+
* Request-shape checks for entry-variant endpoints (no HTTP — same style as {@link ContentTypeAPITest}).
21+
*/
22+
@Tag("unit")
23+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
24+
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
25+
public class EntryVariantAPITest {
26+
27+
private static final String CREATE_VARIANT_BODY = "entry_variant/create_entry_variant.json";
28+
private static final String UPDATE_VARIANT_BODY = "entry_variant/update_entry_variant.json";
29+
private static final String PUBLISH_VARIANT_BODY = "entry_variant/publish_entry_variant.json";
30+
private static final String UNPUBLISH_VARIANT_BODY = "entry_variant/unpublish_entry_variant.json";
31+
32+
private final String contentTypeUid = TestClient.ENTRY_VARIANT_CONTENT_TYPE_UID;
33+
private final String entryUid = "entry_uid";
34+
private final String variantUid = "variant_uid";
35+
private final String stackBranch = TestClient.ENTRY_VARIANT_BRANCH == null
36+
? "develop"
37+
: TestClient.ENTRY_VARIANT_BRANCH.trim();
38+
39+
private Stack stack;
40+
private int headerCount;
41+
42+
@BeforeAll
43+
void setUp() {
44+
/*
45+
* Fresh Stack from the client — avoids mutating {@link TestClient#getStack()} singleton headers
46+
* (which broke other suites such as {@link ReleaseAPITest} when branch was added globally).
47+
*/
48+
stack = TestClient.getClient().stack(
49+
TestClient.API_KEY,
50+
TestClient.MANAGEMENT_TOKEN,
51+
stackBranch);
52+
headerCount = stack.headers.size();
53+
}
54+
55+
private Entry freshEntry() {
56+
return stack.contentType(contentTypeUid).entry(entryUid);
57+
}
58+
59+
private String variantPathSuffix() {
60+
return "/v3/content_types/" + contentTypeUid + "/entries/" + entryUid + "/variants/" + variantUid;
61+
}
62+
63+
private String variantsCollectionPath() {
64+
return "/v3/content_types/" + contentTypeUid + "/entries/" + entryUid + "/variants";
65+
}
66+
67+
/**
68+
* Publish/unpublish fixtures omit {@code variants[].uid}; inject placeholder for request body construction.
69+
*/
70+
@SuppressWarnings("unchecked")
71+
private static void injectVariantUidIntoVariantsArray(JSONObject body, String uid) {
72+
JSONObject ent = (JSONObject) body.get("entry");
73+
Assertions.assertNotNull(ent, "Body missing entry");
74+
JSONArray variants = (JSONArray) ent.get("variants");
75+
Assertions.assertNotNull(variants, "entry.variants missing");
76+
Assertions.assertFalse(variants.isEmpty(), "entry.variants empty");
77+
JSONObject v0 = (JSONObject) variants.get(0);
78+
v0.put("uid", uid);
79+
}
80+
81+
@Test
82+
@Order(1)
83+
void createEntryVariant_requestShape() {
84+
Entry entry = freshEntry();
85+
entry.clearParams();
86+
entry.addParam("locale", TestClient.ENTRY_VARIANT_LOCALE);
87+
JSONObject body = Utils.readJson(CREATE_VARIANT_BODY);
88+
Assertions.assertNotNull(body);
89+
90+
Request req = entry.createEntryVariant(variantUid, body).request();
91+
Assertions.assertEquals(headerCount, req.headers().names().size());
92+
Assertions.assertEquals("PUT", req.method());
93+
Assertions.assertTrue(req.url().isHttps());
94+
Assertions.assertEquals(variantPathSuffix(), req.url().encodedPath());
95+
Assertions.assertEquals("locale=" + TestClient.ENTRY_VARIANT_LOCALE, req.url().encodedQuery());
96+
Assertions.assertEquals(stackBranch, req.header(Util.BRANCH));
97+
}
98+
99+
@Test
100+
@Order(2)
101+
void updateEntryVariant_sameUrlAndMethodAsCreate() {
102+
Entry entry = freshEntry();
103+
entry.clearParams();
104+
JSONObject createBody = Utils.readJson(CREATE_VARIANT_BODY);
105+
JSONObject updateBody = Utils.readJson(UPDATE_VARIANT_BODY);
106+
Assertions.assertNotNull(createBody);
107+
Assertions.assertNotNull(updateBody);
108+
109+
Request createReq = entry.createEntryVariant(variantUid, createBody).request();
110+
Entry entry2 = freshEntry();
111+
Request updateReq = entry2.updateEntryVariant(variantUid, updateBody).request();
112+
113+
Assertions.assertEquals(createReq.method(), updateReq.method());
114+
Assertions.assertEquals(createReq.url(), updateReq.url());
115+
}
116+
117+
@Test
118+
@Order(3)
119+
void fetchSingleEntryVariant_requestShape() {
120+
Entry entry = freshEntry();
121+
entry.clearParams();
122+
entry.addParam("locale", TestClient.ENTRY_VARIANT_LOCALE);
123+
entry.addParam("include_publish_details", true);
124+
125+
Request req = entry.fetchEntryVariant(variantUid).request();
126+
Assertions.assertEquals(headerCount, req.headers().names().size());
127+
Assertions.assertEquals("GET", req.method());
128+
Assertions.assertTrue(req.url().isHttps());
129+
Assertions.assertEquals(variantPathSuffix(), req.url().encodedPath());
130+
Assertions.assertNotNull(req.url().encodedQuery());
131+
Assertions.assertTrue(req.url().encodedQuery().contains("locale=" + TestClient.ENTRY_VARIANT_LOCALE));
132+
Assertions.assertTrue(req.url().encodedQuery().contains("include_publish_details=true"));
133+
}
134+
135+
@Test
136+
@Order(4)
137+
void fetchAllEntryVariants_requestShape() {
138+
Entry entry = freshEntry();
139+
entry.clearParams();
140+
entry.addParam("locale", TestClient.ENTRY_VARIANT_LOCALE);
141+
142+
Request req = entry.fetchEntryVariants().request();
143+
Assertions.assertEquals(headerCount, req.headers().names().size());
144+
Assertions.assertEquals("GET", req.method());
145+
Assertions.assertEquals(variantsCollectionPath(), req.url().encodedPath());
146+
Assertions.assertEquals("locale=" + TestClient.ENTRY_VARIANT_LOCALE, req.url().encodedQuery());
147+
}
148+
149+
@Test
150+
@Order(5)
151+
void publishEntryVariants_requestShape() {
152+
Entry entry = freshEntry();
153+
entry.clearParams();
154+
entry.addParam("locale", TestClient.ENTRY_VARIANT_LOCALE);
155+
156+
JSONObject publishBody = Utils.readJson(PUBLISH_VARIANT_BODY);
157+
Assertions.assertNotNull(publishBody);
158+
injectVariantUidIntoVariantsArray(publishBody, variantUid);
159+
160+
Request req = entry.publishEntryVariants(publishBody).request();
161+
Assertions.assertEquals("POST", req.method());
162+
Assertions.assertTrue(req.url().isHttps());
163+
Assertions.assertEquals(
164+
"/v3/content_types/" + contentTypeUid + "/entries/" + entryUid + "/publish",
165+
req.url().encodedPath());
166+
Assertions.assertEquals("locale=" + TestClient.ENTRY_VARIANT_LOCALE, req.url().encodedQuery());
167+
Assertions.assertEquals(Util.API_VERSION_ENTRY_VARIANTS_PUBLISH, req.header(Util.API_VERSION));
168+
}
169+
170+
@Test
171+
@Order(6)
172+
void unpublishEntryVariants_requestShape() {
173+
Entry entry = freshEntry();
174+
entry.clearParams();
175+
entry.addParam("locale", TestClient.ENTRY_VARIANT_LOCALE);
176+
177+
JSONObject unpublishBody = Utils.readJson(UNPUBLISH_VARIANT_BODY);
178+
Assertions.assertNotNull(unpublishBody);
179+
injectVariantUidIntoVariantsArray(unpublishBody, variantUid);
180+
181+
Request req = entry.unpublishEntryVariants(unpublishBody).request();
182+
Assertions.assertEquals("POST", req.method());
183+
Assertions.assertEquals(
184+
"/v3/content_types/" + contentTypeUid + "/entries/" + entryUid + "/unpublish",
185+
req.url().encodedPath());
186+
Assertions.assertEquals("locale=" + TestClient.ENTRY_VARIANT_LOCALE, req.url().encodedQuery());
187+
Assertions.assertEquals(Util.API_VERSION_ENTRY_VARIANTS_PUBLISH, req.header(Util.API_VERSION));
188+
}
189+
190+
@Test
191+
@Order(7)
192+
void fetchSingleEntryVariant_implicitVsExplicitBranchHeader() {
193+
Entry plain = freshEntry();
194+
plain.clearParams();
195+
plain.addParam("locale", TestClient.ENTRY_VARIANT_LOCALE);
196+
197+
Request implicit = plain.fetchEntryVariant(variantUid).request();
198+
Assertions.assertEquals(stackBranch, implicit.header(Util.BRANCH));
199+
200+
Entry withPerCall = freshEntry();
201+
withPerCall.clearParams();
202+
withPerCall.addParam("locale", TestClient.ENTRY_VARIANT_LOCALE);
203+
Request explicit = withPerCall.fetchEntryVariant(variantUid, stackBranch).request();
204+
Assertions.assertEquals(stackBranch, explicit.header(Util.BRANCH));
205+
Assertions.assertEquals(implicit.url(), explicit.url());
206+
}
207+
208+
@Test
209+
@Order(8)
210+
void fetchSingleEntryVariant_afterAddBranch() {
211+
Entry entry = freshEntry();
212+
entry.clearParams();
213+
entry.addBranch(stackBranch);
214+
entry.addParam("locale", TestClient.ENTRY_VARIANT_LOCALE);
215+
216+
Request req = entry.fetchEntryVariant(variantUid).request();
217+
Assertions.assertEquals(stackBranch, req.header(Util.BRANCH));
218+
Assertions.assertEquals(variantPathSuffix(), req.url().encodedPath());
219+
}
220+
221+
@Test
222+
@Order(9)
223+
void fetchSingleEntryVariant_withPerCallBranchOverload() {
224+
Entry entry = freshEntry();
225+
entry.clearParams();
226+
entry.addParam("locale", TestClient.ENTRY_VARIANT_LOCALE);
227+
228+
Request req = entry.fetchEntryVariant(variantUid, stackBranch).request();
229+
Assertions.assertEquals(stackBranch, req.header(Util.BRANCH));
230+
Assertions.assertEquals("GET", req.method());
231+
Assertions.assertEquals(variantPathSuffix(), req.url().encodedPath());
232+
}
233+
234+
@Test
235+
@Order(10)
236+
void deleteEntryVariant_requestShape() {
237+
Entry entry = freshEntry();
238+
entry.clearParams();
239+
entry.addParam("locale", TestClient.ENTRY_VARIANT_LOCALE);
240+
241+
Request req = entry.deleteEntryVariant(variantUid).request();
242+
Assertions.assertEquals("DELETE", req.method());
243+
Assertions.assertEquals(variantPathSuffix(), req.url().encodedPath());
244+
Assertions.assertEquals("locale=" + TestClient.ENTRY_VARIANT_LOCALE, req.url().encodedQuery());
245+
}
246+
}

0 commit comments

Comments
 (0)