Skip to content

Commit b36fec8

Browse files
committed
EPMRPP-97593 update dependencies. add unit test
1 parent 6d1f45e commit b36fec8

File tree

8 files changed

+414
-19
lines changed

8 files changed

+414
-19
lines changed

build.gradle

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ dependencyManagement {
3838
}
3939
}
4040

41+
ext['junit-jupiter.version'] = "${junitVersion}"
42+
4143
dependencies {
4244
if (releaseMode) {
4345
implementation 'com.epam.reportportal:commons-dao'
@@ -49,12 +51,20 @@ dependencies {
4951
annotationProcessor 'com.github.reportportal:plugin-api:develop-SNAPSHOT'
5052
}
5153

52-
implementation("com.slack.api:slack-api-client:1.27.1") {
53-
exclude group: "org.slf4j"
54-
}
54+
compileOnly "org.projectlombok:lombok:${lombokVersion}"
55+
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
56+
testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
57+
testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}"
58+
5559
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2'
56-
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
5760
implementation 'org.hibernate:hibernate-core:5.6.15.Final'
61+
testImplementation 'org.mockito:mockito-core:5.14.2'
62+
testImplementation 'org.mockito:mockito-junit-jupiter:5.14.2'
63+
testImplementation "org.junit.jupiter:junit-jupiter"
64+
testImplementation "org.junit.jupiter:junit-jupiter-api"
65+
testImplementation "org.junit.jupiter:junit-jupiter-engine"
66+
testImplementation 'net.bytebuddy:byte-buddy:1.14.9'
67+
//testImplementation "org.junit.jupiter:mockito-junit-jupiter:${junitVersion}"
5868
}
5969

6070
test {
@@ -115,6 +125,7 @@ shadowJar {
115125
configurations = [project.configurations.compileClasspath]
116126
zip64 true
117127
dependencies {
128+
include(dependency('commons-io:commons-io:2.15.1'))
118129
}
119130
}
120131

gradle.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
version=1.0.0
22
description=EPAM Report Portal. Slack plugin.
33
pluginId = slack
4+
lombokVersion=1.18.36
5+
junitVersion=5.11.0

src/main/java/com/epam/reportportal/extension/slack/SlackPluginExtension.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.springframework.context.support.AbstractApplicationContext;
4848
import org.springframework.core.io.FileSystemResource;
4949
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
50+
import org.springframework.web.client.RestTemplate;
5051

5152
/**
5253
* @author Andrei Piankouski
@@ -100,6 +101,9 @@ public class SlackPluginExtension implements ReportPortalExtensionPoint, Disposa
100101
@Autowired
101102
private ProjectRepository projectRepository;
102103

104+
@Autowired
105+
private RestTemplate restTemplate;
106+
103107
@Autowired
104108
private ApplicationContext applicationContext;
105109

@@ -131,7 +135,7 @@ public SlackPluginExtension(Map<String, Object> initParams) {
131135

132136
launchFinishEventListenerSupplier = new MemoizingSupplier<>(
133137
() -> new SlackLaunchFinishEventListener(projectRepository,
134-
launchRepository, senderCaseMatcher.get(), attachmentResolverSupplier.get()));
138+
launchRepository, senderCaseMatcher.get(), attachmentResolverSupplier.get(), restTemplate));
135139
}
136140

137141
@PostConstruct

src/main/java/com/epam/reportportal/extension/slack/event/launch/SlackLaunchFinishEventListener.java

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,23 @@
2727
import com.epam.ta.reportportal.entity.project.Project;
2828
import com.epam.ta.reportportal.entity.project.ProjectUtils;
2929
import com.epam.ta.reportportal.entity.project.email.SenderCase;
30-
import com.slack.api.Slack;
3130
import java.util.Map;
3231
import java.util.Optional;
3332
import org.apache.commons.lang3.BooleanUtils;
3433
import org.springframework.context.ApplicationListener;
34+
import org.springframework.web.client.RestTemplate;
3535

3636
/**
3737
* @author <a href="mailto:andrei_piankouski@epam.com">Andrei Piankouski</a>
3838
*/
3939
public class SlackLaunchFinishEventListener implements
4040
ApplicationListener<LaunchFinishedPluginEvent> {
4141

42-
private final static String SLACK_NOTIFICATION_ATTRIBUTE = "notifications.slack.enabled";
42+
public final static String SLACK_NOTIFICATION_ATTRIBUTE = "notifications.slack.enabled";
4343

44-
private final static String WEBHOOK_DETAILS = "webhookURL";
44+
public final static String WEBHOOK_DETAILS = "webhookURL";
4545

46-
private final static String PLUGIN_NOTIFICATION_TYPE = "slack";
46+
public final static String PLUGIN_NOTIFICATION_TYPE = "slack";
4747

4848
private final ProjectRepository projectRepository;
4949

@@ -52,15 +52,18 @@ public class SlackLaunchFinishEventListener implements
5252
private final SenderCaseMatcher senderCaseMatcher;
5353

5454
private final AttachmentResolver attachmentResolver;
55+
private final RestTemplate restTemplate;
5556

5657

5758
public SlackLaunchFinishEventListener(
5859
ProjectRepository projectRepository, LaunchRepository launchRepository,
59-
SenderCaseMatcher senderCaseMatcher, AttachmentResolver attachmentResolver) {
60+
SenderCaseMatcher senderCaseMatcher, AttachmentResolver attachmentResolver,
61+
RestTemplate restTemplate) {
6062
this.projectRepository = projectRepository;
6163
this.launchRepository = launchRepository;
6264
this.senderCaseMatcher = senderCaseMatcher;
6365
this.attachmentResolver = attachmentResolver;
66+
this.restTemplate = restTemplate;
6467
}
6568

6669
@Override
@@ -103,7 +106,7 @@ private void sendNotification(SenderCase senderCase, Launch launch, String launc
103106
Optional<String> webhookUrl = getWebhookUrl(senderCase);
104107
Optional<String> attachment = resolveAttachment(launch, launchLink);
105108
if (webhookUrl.isPresent() && attachment.isPresent()) {
106-
sendSlackNotification(webhookUrl.get(), attachment.get());
109+
restTemplate.postForLocation(webhookUrl.get(), attachment.get());
107110
}
108111
}
109112

@@ -116,13 +119,6 @@ private Optional<String> resolveAttachment(Launch launch, String launchLink) {
116119
return attachmentResolver.resolve(launch, launchLink);
117120
}
118121

119-
private void sendSlackNotification(String webhookUrl, String attachment) {
120-
try (Slack slack = Slack.getInstance()) {
121-
slack.send(webhookUrl, attachment);
122-
} catch (Exception e) {
123-
throw new ReportPortalException("Failed to send Slack notification", e);
124-
}
125-
}
126122

127123
private boolean isNotificationsEnabled(Project project) {
128124
Map<String, String> projectConfig = ProjectUtils.getConfigParameters(

src/main/resources/message-template/finish-launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,4 @@
204204
]
205205
}
206206
]
207-
}
207+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.epam.reportportal.extension.slack.event.launch;
2+
3+
import static com.epam.reportportal.extension.slack.utils.SampleAttachment.SAMPLE_ATTACHMENT;
4+
import static org.mockito.ArgumentMatchers.any;
5+
import static org.mockito.ArgumentMatchers.anyLong;
6+
import static org.mockito.ArgumentMatchers.anyString;
7+
import static org.mockito.Mockito.times;
8+
import static org.mockito.Mockito.verify;
9+
import static org.mockito.Mockito.when;
10+
11+
import com.epam.reportportal.extension.event.LaunchFinishedPluginEvent;
12+
import com.epam.reportportal.extension.slack.event.launch.resolver.AttachmentResolver;
13+
import com.epam.reportportal.extension.slack.event.launch.resolver.SenderCaseMatcher;
14+
import com.epam.reportportal.extension.slack.utils.MockData;
15+
import com.epam.ta.reportportal.dao.LaunchRepository;
16+
import com.epam.ta.reportportal.dao.ProjectRepository;
17+
import com.epam.ta.reportportal.entity.launch.Launch;
18+
import java.net.URI;
19+
import java.net.URISyntaxException;
20+
import java.util.Optional;
21+
import org.junit.jupiter.api.Test;
22+
import org.junit.jupiter.api.extension.ExtendWith;
23+
import org.mockito.Answers;
24+
import org.mockito.Mock;
25+
import org.mockito.junit.jupiter.MockitoExtension;
26+
import org.springframework.web.client.RestTemplate;
27+
28+
@ExtendWith(MockitoExtension.class)
29+
class SlackLaunchFinishEventListenerTest {
30+
31+
private static final String LAUNCH_LINK = "http://localhost:8080/ui/#admin123/launches/all/55";
32+
33+
@Mock
34+
RestTemplate restTemplate;// = new RestTemplate();
35+
@Mock
36+
ProjectRepository projectRepository;
37+
@Mock
38+
LaunchRepository launchRepository;
39+
@Mock(answer = Answers.CALLS_REAL_METHODS)
40+
SenderCaseMatcher senderCaseMatcher;
41+
@Mock
42+
AttachmentResolver attachmentResolver;
43+
44+
@Test
45+
void sendNotificationPositive() throws URISyntaxException {
46+
var slackLaunchFinishEventListener = new SlackLaunchFinishEventListener(projectRepository,
47+
launchRepository, senderCaseMatcher, attachmentResolver, restTemplate);
48+
49+
when(projectRepository.findById(anyLong()))
50+
.thenReturn(Optional.of(MockData.getProjectSample()));
51+
when(launchRepository.findById(anyLong()))
52+
.thenReturn(Optional.of(MockData.getLaunch()));
53+
when(attachmentResolver.resolve(any(Launch.class), anyString()))
54+
.thenReturn(Optional.of(SAMPLE_ATTACHMENT));
55+
when(restTemplate.postForLocation(anyString(), anyString()))
56+
.thenReturn(new URI("http://localhost:8080"));
57+
58+
slackLaunchFinishEventListener.onApplicationEvent(
59+
new LaunchFinishedPluginEvent(1L, 10L, LAUNCH_LINK));
60+
61+
verify(restTemplate, times(1)).postForLocation(anyString(), anyString());
62+
63+
}
64+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package com.epam.reportportal.extension.slack.utils;
2+
3+
import static com.epam.reportportal.extension.slack.event.launch.SlackLaunchFinishEventListener.PLUGIN_NOTIFICATION_TYPE;
4+
import static com.epam.reportportal.extension.slack.event.launch.SlackLaunchFinishEventListener.SLACK_NOTIFICATION_ATTRIBUTE;
5+
import static com.epam.reportportal.extension.slack.event.launch.SlackLaunchFinishEventListener.WEBHOOK_DETAILS;
6+
import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.NOTIFICATIONS_ENABLED;
7+
8+
import com.epam.ta.reportportal.entity.attribute.Attribute;
9+
import com.epam.ta.reportportal.entity.enums.SendCase;
10+
import com.epam.ta.reportportal.entity.launch.Launch;
11+
import com.epam.ta.reportportal.entity.project.Project;
12+
import com.epam.ta.reportportal.entity.project.ProjectAttribute;
13+
import com.epam.ta.reportportal.entity.project.email.SenderCase;
14+
import com.epam.ta.reportportal.entity.project.email.SenderCaseOptions;
15+
import java.io.IOException;
16+
import java.io.InputStream;
17+
import java.nio.charset.StandardCharsets;
18+
import java.nio.file.Files;
19+
import java.nio.file.Paths;
20+
import java.util.Collections;
21+
import java.util.Map;
22+
import java.util.Set;
23+
import java.util.stream.Stream;
24+
import org.apache.commons.io.IOUtils;
25+
26+
public class MockData {
27+
28+
private static final String LAUNCH_NAME_1 = "Launch name 1";
29+
30+
public static Project getProjectSample() {
31+
var project = new Project();
32+
33+
project.setId(1L);
34+
project.setSenderCases(Collections.singleton(getSenderCase()));
35+
project.setProjectAttributes(getProjectAttributes());
36+
return project;
37+
}
38+
39+
private static Set<ProjectAttribute> getProjectAttributes() {
40+
var attribute1 = new Attribute();
41+
attribute1.setId(13L);
42+
attribute1.setName(NOTIFICATIONS_ENABLED.getAttribute());
43+
44+
var attribute2 = new Attribute();
45+
attribute2.setId(21L);
46+
attribute2.setName(SLACK_NOTIFICATION_ATTRIBUTE);
47+
48+
ProjectAttribute projectAttribute1 = new ProjectAttribute()
49+
.withAttribute(attribute1)
50+
.withProject(new Project())
51+
.withValue("true");
52+
53+
ProjectAttribute projectAttribute2 = new ProjectAttribute()
54+
.withAttribute(attribute2)
55+
.withProject(new Project())
56+
.withValue("true");
57+
58+
return Set.of(projectAttribute1, projectAttribute2);
59+
60+
}
61+
62+
63+
public static SenderCase getSenderCase() {
64+
var senderCase = new SenderCase();
65+
senderCase.setEnabled(true);
66+
senderCase.setType(PLUGIN_NOTIFICATION_TYPE);
67+
senderCase.setSendCase(SendCase.ALWAYS);
68+
senderCase.setLaunchNames(Set.of(LAUNCH_NAME_1));
69+
senderCase.setRuleDetails(getSenderCaseOptions());
70+
return senderCase;
71+
}
72+
73+
public static Launch getLaunch() {
74+
var launch = new Launch();
75+
launch.setId(20L);
76+
launch.setName(LAUNCH_NAME_1);
77+
return launch;
78+
}
79+
80+
public static SenderCaseOptions getSenderCaseOptions() {
81+
SenderCaseOptions senderCaseOptions = new SenderCaseOptions();
82+
senderCaseOptions.setOptions(
83+
Map.of(WEBHOOK_DETAILS,
84+
"https://hooks.slack.com/services/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"));
85+
return senderCaseOptions;
86+
}
87+
88+
public static String readFileToString(String path) throws IOException {
89+
90+
try (InputStream resourceAsStream = MockData.class.getClassLoader().getResourceAsStream(path)) {
91+
if (resourceAsStream != null) {
92+
return IOUtils.toString(resourceAsStream, StandardCharsets.UTF_8);
93+
} else {
94+
StringBuilder sb = new StringBuilder();
95+
try (Stream<String> lines = Files.lines(Paths.get(path))) {
96+
lines.forEach(sb::append);
97+
}
98+
return sb.toString();
99+
}
100+
}
101+
}
102+
}
103+

0 commit comments

Comments
 (0)