Skip to content

Commit 96f67ac

Browse files
authored
Merge pull request #117 from contentstack/staging
DX | 03-02-2025 | Hotfix Release
2 parents db249d5 + 842affe commit 96f67ac

File tree

9 files changed

+321
-20
lines changed

9 files changed

+321
-20
lines changed

.github/workflows/coverage.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
run: mvn jacoco:prepare-agent jacoco:report
2323

2424
- name: Upload Code Coverage Report
25-
uses: actions/upload-artifact@v3
25+
uses: actions/upload-artifact@v4
2626
with:
2727
name: code-coverage-report
2828
path: target/site/jacoco

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ if(response.isSuccessful()){
137137

138138
### The MIT License (MIT)
139139

140-
Copyright © 2012-2024 [Contentstack](https://www.contentstack.com/). All Rights Reserved
140+
Copyright © 2012-2025 [Contentstack](https://www.contentstack.com/). All Rights Reserved
141141

142142
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
143143
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the

changelog.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## v1.5.2
4+
5+
### Feb 03, 2025
6+
7+
- Feature added related to entry workflow methods
8+
39
## v1.5.1
410

511
### Jan 20, 2025

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<artifactId>cms</artifactId>
88
<packaging>jar</packaging>
99
<name>contentstack-management-java</name>
10-
<version>1.5.1</version>
10+
<version>1.5.2</version>
1111
<description>Contentstack Java Management SDK for Content Management API, Contentstack is a headless CMS with an
1212
API-first approach
1313
</description>

src/main/java/com/contentstack/cms/stack/Entry.java

+36
Original file line numberDiff line numberDiff line change
@@ -825,4 +825,40 @@ public Call<ResponseBody> query(@NotNull JSONObject query) {
825825
return this.service.filterTaxonomy(this.headers, this.contentTypeUid, query);
826826
}
827827

828+
829+
/**
830+
* The Set Entry Workflow Stage request allows you to either set a particular workflow stage of an entry or update the workflow stage details of an entry.
831+
* To configure the permissions for your application via OAuth,
832+
* please include the cm.entry.workflow:write scope.
833+
* In the 'Body' section, you need to provide the details of the workflow stage.
834+
* Enter a comment for the assigned user, if needed; provide the due date;
835+
* set notification settings to ‘true’, so that the specified user will be notified of it;
836+
* enter the UID of the workflow stage; and finally, enter the user details, such as UID, name, and email address of the user.
837+
* param query the request body of type {@link JSONObject}
838+
*/
839+
840+
public Call<ResponseBody> setWorkflowStage(@NotNull JSONObject workflow) {
841+
validateCT();
842+
validateEntry();
843+
return this.service.setWorkflowStage(this.headers, this.contentTypeUid, this.entryUid, this.params, workflow);
844+
}
845+
846+
847+
/**
848+
* This multipurpose request allows you to either send a publish request or accept/reject a received publish request.
849+
* When executing the API request, in the 'Header' section,
850+
* you need to provide the API Key of your stack and the authtoken that you receive after logging into your account.
851+
* In the 'Body' section, you need to provide the details of the publish rule,
852+
* such as its UID, action (‘publish’, ‘unpublish’, or ’both’),
853+
* status (this could be ‘0’ for Approval Requested, ‘1’ for ‘Approval Accepted’, and ‘-1’ for ‘Approval Rejected’),
854+
* notification setting, and comment for the approver.
855+
* param query the request body of type {@link JSONObject}
856+
*/
857+
858+
public Call<ResponseBody> publishRequest(@NotNull JSONObject publishing_rule) {
859+
validateCT();
860+
validateEntry();
861+
return this.service.publishRequestApproval(this.headers, this.contentTypeUid, this.entryUid, this.params, publishing_rule);
862+
}
863+
828864
}

src/main/java/com/contentstack/cms/stack/EntryService.java

+15
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,19 @@ Call<ResponseBody> filterTaxonomy(
154154
@Path("content_type_uid") String contentTypeUid,
155155
@Query("query") JSONObject queryObject);
156156

157+
@POST("content_types/{content_type_uid}/entries/{entry_uid}/workflow")
158+
Call<ResponseBody> setWorkflowStage(
159+
@HeaderMap Map<String, Object> headers,
160+
@Path("content_type_uid") String contentTypeUid,
161+
@Path("entry_uid") String entryUid,
162+
@QueryMap Map<String, Object> params,
163+
@Body JSONObject body);
164+
165+
@POST("content_types/{content_type_uid}/entries/{entry_uid}/workflow")
166+
Call<ResponseBody> publishRequestApproval(
167+
@HeaderMap Map<String, Object> headers,
168+
@Path("content_type_uid") String contentTypeUid,
169+
@Path("entry_uid") String entryUid,
170+
@QueryMap Map<String, Object> params,
171+
@Body JSONObject body);
157172
}

src/main/java/com/contentstack/cms/stack/WorkflowService.java

-16
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,6 @@ Call<ResponseBody> delete(
4545
@HeaderMap Map<String, Object> headers,
4646
@Path("workflow_uid") String workflowUid);
4747

48-
@POST("content_types/{content_type_uid}/entries/{entry_uid}/workflow")
49-
Call<ResponseBody> updateWorkflowStage(
50-
@HeaderMap Map<String, Object> headers,
51-
@Path("content_type_uid") String contentTypeUid,
52-
@Path("entry_uid") String entryUid,
53-
@QueryMap Map<String, Object> params,
54-
@Body JSONObject body);
55-
5648
@POST("workflows/publishing_rules")
5749
Call<ResponseBody> createPublishRules(
5850
@HeaderMap Map<String, Object> headers,
@@ -85,14 +77,6 @@ Call<ResponseBody> fetchPublishRuleContentType(
8577
@Path("content_type_uid") String contentTypeUid,
8678
@QueryMap Map<String, Object> params);
8779

88-
@POST("content_types/{content_type_uid}/entries/{entry_uid}/workflow")
89-
Call<ResponseBody> publishRequestApproval(
90-
@HeaderMap Map<String, Object> headers,
91-
@Path("content_type_uid") String contentTypeUid,
92-
@Path("entry_uid") String entryUid,
93-
@QueryMap Map<String, Object> params,
94-
@Body JSONObject body);
95-
9680
@GET("workflows/content_type/{content_type_uid}")
9781
Call<ResponseBody> fetchTasks(
9882
@HeaderMap Map<String, Object> headers,

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

+94
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
import org.json.simple.JSONArray;
1313
import org.json.simple.JSONObject;
14+
import org.json.simple.parser.JSONParser;
15+
import org.json.simple.parser.ParseException;
1416
import org.junit.jupiter.api.*;
1517

1618
import java.io.IOException;
@@ -818,4 +820,96 @@ void queryFiltersOnTaxonomy() {
818820

819821
}
820822

823+
@Test
824+
void testSetWorkflowStage() throws ParseException, IOException {
825+
String workflowStagePayload = "{\n" +
826+
" \"workflow\": {\n" +
827+
" \"workflow_stage\": {\n" +
828+
" \"uid\": \"uid\",\n" +
829+
" \"assigned_by_roles\": [{ \"uid\": \"uid\", \"name\": \"Content Manager\" }],\n" +
830+
" \"due_date\": \"Thu Feb 06 2025\",\n" +
831+
" \"comment\": \"Review the entry\",\n" +
832+
" \"notify\": true,\n" +
833+
" \"assigned_to\": [{ \"uid\": \"user_uid\", \"name\": \"name\", \"email\": \"mail.com\" }]\n" +
834+
" }\n" +
835+
" }\n" +
836+
"}";
837+
JSONParser parser = new JSONParser();
838+
JSONObject body = (JSONObject) parser.parse(workflowStagePayload);
839+
Entry entry1 = TestClient.getClient().stack(API_KEY,MANAGEMENT_TOKEN).contentType("author").entry("entry_uid");
840+
Request request = entry1.setWorkflowStage(body).request();
841+
Assertions.assertNotNull(request);
842+
Assertions.assertTrue(request.url().isHttps());
843+
Assertions.assertEquals("api.contentstack.io", request.url().host());
844+
Assertions.assertEquals(6, request.url().pathSegments().size());
845+
Assertions.assertEquals("v3", request.url().pathSegments().get(0));
846+
Assertions.assertEquals("content_types", request.url().pathSegments().get(1));
847+
Assertions.assertEquals("author", request.url().pathSegments().get(2));
848+
Assertions.assertEquals("entries", request.url().pathSegments().get(3));
849+
Assertions.assertEquals("entry_uid", request.url().pathSegments().get(4));
850+
Assertions.assertEquals("workflow", request.url().pathSegments().get(5));
851+
Assertions.assertEquals("https://api.contentstack.io/v3/content_types/author/entries/entry_uid/workflow", request.url().toString());
852+
}
853+
854+
@Test
855+
void setWorkflowStage_VerifyQueryParams() throws ParseException {
856+
String payload = "{ \"workflow\": { \"workflow_stage\": { \"uid\": \"stage_uid\" } } }";
857+
JSONParser parser = new JSONParser();
858+
JSONObject body = (JSONObject) parser.parse(payload);
859+
Entry entry = TestClient.getClient().stack(API_KEY, MANAGEMENT_TOKEN).contentType("author").entry("entry_uid");
860+
entry.addParam("locale", "en-us");
861+
Request request = entry.setWorkflowStage(body).request();
862+
Assertions.assertNotNull(request.url().encodedQuery());
863+
Assertions.assertEquals("locale=en-us", request.url().encodedQuery());
864+
Assertions.assertEquals("https://api.contentstack.io/v3/content_types/author/entries/entry_uid/workflow?locale=en-us", request.url().toString());
865+
}
866+
867+
@Test
868+
void testPublishRequest_ValidRequest() throws ParseException {
869+
Contentstack contentstack = new Contentstack.Builder().setAuthtoken(TestClient.AUTHTOKEN).build();
870+
Stack stack = contentstack.stack(TestClient.API_KEY, TestClient.MANAGEMENT_TOKEN);
871+
String publishRequestPayload = "{\n" +
872+
" \"workflow\": {\n" +
873+
" \"publishing_rule\": {\n" +
874+
" \"uid\": \"rule_uid\",\n" +
875+
" \"action\": \"publish\",\n" +
876+
" \"status\": 1,\n" +
877+
" \"notify\": true,\n" +
878+
" \"comment\": \"Approve this entry.\"\n" +
879+
" }\n" +
880+
" }\n" +
881+
"}";
882+
JSONParser parser = new JSONParser();
883+
JSONObject body = (JSONObject) parser.parse(publishRequestPayload);
884+
Request request = stack.contentType("author").entry("entry_uid").publishRequest(body).request();
885+
886+
Assertions.assertEquals("POST", request.method());
887+
Assertions.assertEquals("https", request.url().scheme());
888+
Assertions.assertEquals("api.contentstack.io", request.url().host());
889+
Assertions.assertEquals("v3", request.url().pathSegments().get(0));
890+
Assertions.assertEquals("content_types", request.url().pathSegments().get(1));
891+
Assertions.assertEquals("author", request.url().pathSegments().get(2));
892+
Assertions.assertEquals("entries", request.url().pathSegments().get(3));
893+
Assertions.assertEquals("entry_uid", request.url().pathSegments().get(4));
894+
Assertions.assertEquals("workflow", request.url().pathSegments().get(5));
895+
Assertions.assertTrue(request.headers().names().contains("authorization"));
896+
Assertions.assertTrue(request.headers().names().contains("api_key"));
897+
}
898+
899+
@Test
900+
void testPublishRequest_InvalidRequestBody() throws ParseException, IOException {
901+
Contentstack contentstack = new Contentstack.Builder().setAuthtoken(TestClient.AUTHTOKEN).build();
902+
Stack stack = contentstack.stack(TestClient.API_KEY, TestClient.MANAGEMENT_TOKEN);
903+
String invalidPayload = "{ \"invalid_field\": \"invalid_value\" }";
904+
JSONParser parser = new JSONParser();
905+
JSONObject body = (JSONObject) parser.parse(invalidPayload);
906+
Request request = stack.contentType("author").entry("entry_uid").publishRequest(body).request();
907+
Assertions.assertEquals("POST", request.method());
908+
Assertions.assertTrue(request.headers().names().contains("authorization"));
909+
Assertions.assertTrue(request.headers().names().contains("api_key"));
910+
Assertions.assertEquals("https", request.url().scheme());
911+
Assertions.assertEquals("api.contentstack.io", request.url().host());
912+
Assertions.assertEquals("v3", request.url().pathSegments().get(0));
913+
}
914+
821915
}

0 commit comments

Comments
 (0)