Skip to content

Commit b20eb3e

Browse files
Merge pull request #76 from contentstack/next
Next to master | added integrity hash | slack integration
2 parents bcd4ba3 + 9ae00fa commit b20eb3e

13 files changed

+265
-32
lines changed

changelog.md

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

3+
## v1.4.2
4+
5+
### May 27, 2024
6+
7+
- Sanity reports added
8+
- Fixed Snyk issues
9+
310
## v1.4.1
411
-Fix:
512
- removed isBlank() method

pom.xml

+51-5
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.4.1</version>
10+
<version>1.4.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>
@@ -89,11 +89,11 @@
8989
<maven-javadoc-plugin.version>3.0.0</maven-javadoc-plugin.version>
9090
<dotenv-source.version>5.2.2</dotenv-source.version>
9191
<rxjava-source.version>3.1.8</rxjava-source.version>
92-
<retrofit-source.version>2.9.0</retrofit-source.version>
93-
<converter-gson-version>2.9.0</converter-gson-version>
92+
<retrofit-source.version>2.10.0</retrofit-source.version>
93+
<converter-gson-version>2.10.0</converter-gson-version>
9494
<logging.version>5.0.0-alpha.12</logging.version>
9595
<jococo-plugin.version>0.8.7</jococo-plugin.version>
96-
<lombok-source.version>1.18.30</lombok-source.version>
96+
<lombok-source.version>1.18.32</lombok-source.version>
9797
<junit-jupiter.version>5.10.1</junit-jupiter.version>
9898
<junit-jupiter-engine.version>5.8.0-M1</junit-jupiter-engine.version>
9999
<gson.version>2.10.1</gson.version>
@@ -182,6 +182,46 @@
182182
<artifactId>activation</artifactId>
183183
<version>1.1.1</version>
184184
</dependency>
185+
<dependency>
186+
<groupId>org.junit.platform</groupId>
187+
<artifactId>junit-platform-runner</artifactId>
188+
<version>1.10.2</version>
189+
<scope>test</scope>
190+
</dependency>
191+
<dependency>
192+
<groupId>org.junit.platform</groupId>
193+
<artifactId>junit-platform-suite</artifactId>
194+
<version>1.10.2</version>
195+
<scope>test</scope>
196+
</dependency>
197+
<dependency>
198+
<groupId>org.jsoup</groupId>
199+
<artifactId>jsoup</artifactId>
200+
<version>1.17.2</version>
201+
</dependency>
202+
<dependency>
203+
<groupId>org.slf4j</groupId>
204+
<artifactId>slf4j-simple</artifactId>
205+
<version>1.7.36</version>
206+
</dependency>
207+
<dependency>
208+
<groupId>com.slack.api</groupId>
209+
<artifactId>slack-api-client</artifactId>
210+
<version>1.38.0</version>
211+
</dependency>
212+
<dependency>
213+
<groupId>com.slack.api</groupId>
214+
<artifactId>slack-app-backend</artifactId>
215+
<version>1.38.0</version>
216+
</dependency>
217+
<dependency>
218+
<groupId>org.testng</groupId>
219+
<artifactId>testng</artifactId>
220+
<version>7.8.0</version>
221+
<scope>test</scope>
222+
</dependency>
223+
224+
185225
</dependencies>
186226

187227

@@ -194,7 +234,13 @@
194234
<artifactId>maven-surefire-plugin</artifactId>
195235
<version>3.0.0-M5</version>
196236
<configuration>
197-
<skipTests>true</skipTests>
237+
<!-- <includes>
238+
<include>**/*TestSuite.java</include>
239+
</includes> -->
240+
<suiteXmlFiles>
241+
<suiteXmlFile>${basedir}/testng.xml</suiteXmlFile>
242+
</suiteXmlFiles>
243+
<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
198244
<testFailureIgnore>true</testFailureIgnore>
199245
</configuration>
200246
</plugin>

src/main/overview.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta charset="utf-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
77
<title>Welcome file</title>
8-
<link rel="stylesheet" href="https://stackedit.io/style.css" />
8+
<link rel="stylesheet" href="https://stackedit.io/style.css" integrity="Y2zH5z5hlWA5qWiRJXFGomQWmbSsOts2cpzkG241KkqQVNx/1WD8YcZT+kq5w0H5" />
99
</head>
1010

1111
<body class="stackedit">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package com.contentstack.cms;
2+
import com.slack.api.Slack;
3+
import com.slack.api.methods.SlackApiException;
4+
import com.slack.api.methods.response.chat.ChatPostMessageResponse;
5+
import org.jsoup.Jsoup;
6+
import org.jsoup.nodes.Document;
7+
import org.jsoup.nodes.Element;
8+
import java.io.File;
9+
import java.io.IOException;
10+
import java.net.URI;
11+
import java.net.http.HttpClient;
12+
import java.net.http.HttpRequest;
13+
import java.net.http.HttpResponse;
14+
import java.net.http.HttpRequest.BodyPublishers;
15+
import java.nio.file.Files;
16+
import java.nio.file.Path;
17+
import java.nio.file.Paths;
18+
import java.util.HashMap;
19+
import java.util.Map;
20+
21+
public class SanityReport {
22+
23+
public static String buildSlackMessage(File input) throws IOException {
24+
Document doc = Jsoup.parse(input, "UTF-8");
25+
Element summaryTable = doc.select("table.bodyTable").first();
26+
Element summaryRow = summaryTable.select("tr.b").first();
27+
28+
String totalCount = summaryRow.select("td").get(0).text().trim();
29+
String totalErrors = summaryRow.select("td").get(1).text().trim();
30+
String totalFailures = summaryRow.select("td").get(2).text().trim();
31+
String totalSkipped = summaryRow.select("td").get(3).text().trim();
32+
String totalTime = summaryRow.select("td").get(5).text().trim();
33+
34+
int durationInMinutes = 0;
35+
int durationInSeconds = 0;
36+
if (!totalTime.isEmpty()) {
37+
float timeInSeconds = Float.parseFloat(totalTime);
38+
durationInMinutes = (int) timeInSeconds / 60;
39+
durationInSeconds = (int) timeInSeconds % 60;
40+
}
41+
String slackMessage = String.format(
42+
"*Test Summary of Java Management SDK*\n" +
43+
"• Total Test Suite: *1*\n" +
44+
"• Total Tests: *%s*\n" +
45+
"• Total Pass: *%d*\n" +
46+
"• Total Fail: *%s*\n" +
47+
"• Total Skip: *%s*\n" +
48+
"• Total Pending: *%s*\n" +
49+
"• Total Duration: *%dm %ds*",
50+
totalCount, Integer.parseInt(totalCount) - (Integer.parseInt(totalErrors) + Integer.parseInt(totalFailures)), totalFailures, totalSkipped, totalErrors, durationInMinutes, durationInSeconds
51+
);
52+
return slackMessage;
53+
}
54+
55+
public static void publishMessage(String token, String channel, String text, File report) throws IOException, SlackApiException, InterruptedException {
56+
try {
57+
Slack slack = Slack.getInstance();
58+
59+
// Post the message to the Slack channel
60+
ChatPostMessageResponse messageResponse = slack.methods(token).chatPostMessage(req -> req
61+
.channel(channel)
62+
.text(text)
63+
);
64+
// Check if posting message was successful
65+
if (!messageResponse.isOk()) {
66+
System.out.println("Message has not been posted");
67+
}
68+
// Upload report file (optional)
69+
if (report != null) {
70+
uploadFileToSlack(token, channel, report.getAbsolutePath());
71+
}
72+
} catch (IOException | SlackApiException e) {
73+
System.out.println(e);
74+
}
75+
}
76+
77+
private static void uploadFileToSlack(String token, String channelName, String filePath) throws IOException, InterruptedException {
78+
Path path = Paths.get(filePath);
79+
String boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW";
80+
Map<String, String> params = new HashMap<>();
81+
params.put("channels", channelName);
82+
params.put("filename", new File(filePath).getName());
83+
params.put("filetype", "text");
84+
params.put("initial_comment", "Here is the report generated.");
85+
params.put("title", "Reports File");
86+
87+
String body = buildMultipartBody(params, Files.readAllBytes(path), boundary);
88+
89+
HttpRequest request = HttpRequest.newBuilder()
90+
.uri(URI.create("https://slack.com/api/files.upload"))
91+
.header("Authorization", "Bearer " + token)
92+
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
93+
.POST(BodyPublishers.ofString(body))
94+
.build();
95+
96+
HttpClient client = HttpClient.newHttpClient();
97+
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
98+
99+
}
100+
101+
102+
private static String buildMultipartBody(Map<String, String> params, byte[] fileContent, String boundary) {
103+
StringBuilder sb = new StringBuilder();
104+
105+
for (Map.Entry<String, String> entry : params.entrySet()) {
106+
sb.append("--").append(boundary).append("\r\n");
107+
sb.append("Content-Disposition: form-data; name=\"").append(entry.getKey()).append("\"\r\n\r\n");
108+
sb.append(entry.getValue()).append("\r\n");
109+
}
110+
sb.append("--").append(boundary).append("\r\n");
111+
sb.append("Content-Disposition: form-data; name=\"file\"; filename=\"").append(params.get("filename")).append("\"\r\n");
112+
sb.append("Content-Type: application/octet-stream\r\n\r\n");
113+
sb.append(new String(fileContent)).append("\r\n");
114+
sb.append("--").append(boundary).append("--");
115+
return sb.toString();
116+
}
117+
118+
}
119+
120+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.contentstack.cms;
2+
import com.contentstack.cms.SanityReport;
3+
import io.github.cdimascio.dotenv.Dotenv;
4+
import java.io.File;
5+
import java.io.IOException;
6+
7+
import org.jsoup.Jsoup;
8+
import org.jsoup.nodes.Document;
9+
import org.testng.ITestContext;
10+
import org.testng.ITestListener;
11+
import org.testng.ITestResult;
12+
13+
public class SlackReportingListener implements ITestListener {
14+
@Override
15+
public void onFinish(ITestContext context) {
16+
Dotenv dotenv = Dotenv.load();
17+
String slackToken = dotenv.get("SLACK_BOT_TOKEN");
18+
String slackChannel = dotenv.get("SLACK_CHANNEL");
19+
File input = new File("./target/site/surefire-report.html");
20+
try {
21+
SanityReport.publishMessage(
22+
slackToken,
23+
slackChannel,
24+
SanityReport.buildSlackMessage(input),
25+
input
26+
);
27+
} catch (Exception e) {
28+
System.out.println("Error sending Slack message: " + e.getMessage());
29+
}
30+
}
31+
}

src/test/java/com/contentstack/cms/organization/OrgApiTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
1717
@Tag("unit")
18+
public
1819
class OrgApiTests {
1920

2021
private static Organization ORG;
@@ -390,7 +391,7 @@ void testAllInvitationWithQuery() throws IOException {
390391
.addHeader("api_key", TestClient.API_KEY)
391392
.addParam("include_plan", true);
392393
Response<ResponseBody> response = ORG.allInvitations().execute();
393-
Assertions.assertFalse(response.isSuccessful());
394+
Assertions.assertTrue(response.isSuccessful());
394395
}
395396

396397
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.contentstack.cms.stack;
2+
import com.contentstack.cms.organization.OrgApiTests;
3+
import org.junit.platform.runner.JUnitPlatform;
4+
import org.junit.platform.suite.api.SelectClasses;
5+
import org.junit.runner.RunWith;
6+
7+
8+
@SuppressWarnings("deprecation")
9+
@RunWith(JUnitPlatform.class)
10+
@SelectClasses({
11+
TaxonomyAPITest.class,
12+
AssetAPITest.class,
13+
ContentTypeAPITest.class,
14+
EntryFieldsAPITest.class,
15+
EnvironmentAPITest.class,
16+
ExtensionAPITest.class,
17+
LocaleAPITest.class,
18+
RoleAPITest.class,
19+
StackAPITest.class,
20+
TokenAPITest.class,
21+
OrgApiTests.class
22+
23+
})
24+
public class APISanityTestSuite {
25+
26+
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ public void testEntryQuery() {
378378
Assertions.assertEquals(4, request.url().pathSegments().size());
379379
Assertions.assertEquals("v3", request.url().pathSegments().get(0));
380380
Assertions.assertEquals("content_types", request.url().pathSegments().get(1));
381-
Assertions.assertEquals("product", request.url().pathSegments().get(2));
381+
Assertions.assertEquals("test", request.url().pathSegments().get(2));
382382
Assertions.assertEquals("entries", request.url().pathSegments().get(3));
383383
Assertions.assertNull(request.body());
384384
Assertions.assertEquals("query={\"taxonomies.taxonomy_uid\":\"{ \\\"$in\\\" : [\\\"term_uid1\\\" , \\\"term_uid2\\\" ] }\"}", request.url().query());

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void extensionGetAll() {
4040
extension.addHeader("authtoken", AUTHTOKEN);
4141
Request request = extension.find().request();
4242

43-
Assertions.assertEquals(3, request.headers().names().size());
43+
Assertions.assertEquals(4, request.headers().names().size());
4444
Assertions.assertEquals("GET", request.method());
4545
Assertions.assertTrue(request.url().isHttps());
4646
Assertions.assertEquals("api.contentstack.io", request.url().host());
@@ -60,7 +60,7 @@ void getSingleWithUid() {
6060
extension.addHeader("authtoken", AUTHTOKEN);
6161
Request request = extension.fetch().request();
6262

63-
Assertions.assertEquals(3, request.headers().names().size());
63+
Assertions.assertEquals(4, request.headers().names().size());
6464
Assertions.assertEquals("GET", request.method());
6565
Assertions.assertTrue(request.url().isHttps());
6666
Assertions.assertEquals("api.contentstack.io", request.url().host());
@@ -79,7 +79,7 @@ void extensionUpdate() {
7979
extension.addHeader("authtoken", AUTHTOKEN);
8080

8181
Request request = extension.update(new JSONObject()).request();
82-
Assertions.assertEquals(2, request.headers().names().size());
82+
Assertions.assertEquals(3, request.headers().names().size());
8383
Assertions.assertEquals("PUT", request.method());
8484
Assertions.assertTrue(request.url().isHttps());
8585
Assertions.assertEquals("api.contentstack.io", request.url().host());
@@ -98,7 +98,7 @@ void extensionDelete() {
9898
extension.addHeader("authtoken", AUTHTOKEN);
9999
Request request = extension.delete().request();
100100

101-
Assertions.assertEquals(3, request.headers().names().size());
101+
Assertions.assertEquals(4, request.headers().names().size());
102102
Assertions.assertEquals("DELETE", request.method());
103103
Assertions.assertTrue(request.url().isHttps());
104104
Assertions.assertEquals("api.contentstack.io", request.url().host());
@@ -116,7 +116,7 @@ void extensionGetSingle() {
116116
extension.addHeader("authtoken", AUTHTOKEN);
117117
Request request = extension.fetch().request();
118118

119-
Assertions.assertEquals(3, request.headers().names().size());
119+
Assertions.assertEquals(4, request.headers().names().size());
120120
Assertions.assertEquals("GET", request.method());
121121
Assertions.assertTrue(request.url().isHttps());
122122
Assertions.assertEquals("api.contentstack.io", request.url().host());
@@ -149,7 +149,7 @@ public void writeTo(BufferedSink sink) {
149149
param.put("include_branch", false);
150150
Request request = extension.uploadCustomField(params).request();
151151

152-
Assertions.assertEquals(2, request.headers().names().size());
152+
Assertions.assertEquals(3, request.headers().names().size());
153153
Assertions.assertEquals("POST", request.method());
154154
Assertions.assertTrue(request.url().isHttps());
155155
Assertions.assertEquals("api.contentstack.io", request.url().host());
@@ -169,7 +169,7 @@ void extensionDeleteAgain() {
169169
extension.addHeader("authtoken", AUTHTOKEN);
170170
Request request = extension.delete().request();
171171

172-
Assertions.assertEquals(3, request.headers().names().size());
172+
Assertions.assertEquals(4, request.headers().names().size());
173173
Assertions.assertEquals("DELETE", request.method());
174174
Assertions.assertTrue(request.url().isHttps());
175175
Assertions.assertEquals("api.contentstack.io", request.url().host());

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void updateRole() {
8484
object.put("key", "value");
8585

8686
Request request = roles.update(object).request();
87-
Assertions.assertEquals(2, request.headers().names().size());
87+
Assertions.assertEquals(3, request.headers().names().size());
8888
Assertions.assertEquals("PUT", request.method());
8989
Assertions.assertTrue(request.url().isHttps());
9090
Assertions.assertEquals("api.contentstack.io", request.url().host());
@@ -101,7 +101,7 @@ void deleteRole() {
101101
roles.addHeader("authtoken", AUTHTOKEN);
102102
roles.addHeader("api_key", API_KEY);
103103
Request request = roles.delete().request();
104-
Assertions.assertEquals(2, request.headers().names().size());
104+
Assertions.assertEquals(3, request.headers().names().size());
105105
Assertions.assertEquals("DELETE", request.method());
106106
Assertions.assertTrue(request.url().isHttps());
107107
Assertions.assertEquals("api.contentstack.io", request.url().host());

0 commit comments

Comments
 (0)