diff --git a/src/main/java/jenkins/plugins/slack/ActiveNotifier.java b/src/main/java/jenkins/plugins/slack/ActiveNotifier.java
index 03ab2ecd..ba77a8f6 100755
--- a/src/main/java/jenkins/plugins/slack/ActiveNotifier.java
+++ b/src/main/java/jenkins/plugins/slack/ActiveNotifier.java
@@ -19,11 +19,15 @@
import org.apache.commons.lang.StringUtils;
import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.SEVERE;
@@ -216,6 +220,8 @@ String getBuildStatusMessage(AbstractBuild r, boolean includeTestSummary, boolea
public static class MessageBuilder {
+ private static final Pattern aTag = Pattern.compile("(?i)]+)>(.+?)");
+ private static final Pattern href = Pattern.compile("\\s*(?i)href\\s*=\\s*(\"([^\"]*\")|'[^']*'|([^'\">\\s]+))");
private static final String STARTING_STATUS_MESSAGE = "Starting...",
BACK_TO_NORMAL_STATUS_MESSAGE = "Back to normal",
STILL_FAILING_STATUS_MESSAGE = "Still Failing",
@@ -383,7 +389,7 @@ private String createBackToNormalDurationString(){
return Util.getTimeSpanString(backToNormalDuration);
}
- public String escape(String string) {
+ private String escapeCharacters(String string) {
string = string.replace("&", "&");
string = string.replace("<", "<");
string = string.replace(">", ">");
@@ -391,6 +397,26 @@ public String escape(String string) {
return string;
}
+ private String[] extractReplaceLinks(Matcher aTag, StringBuffer sb) {
+ int size = 0;
+ List links = new ArrayList();
+ while (aTag.find()) {
+ Matcher url = href.matcher(aTag.group(1));
+ if (url.find()) {
+ aTag.appendReplacement(sb,String.format("{%s}", size++));
+ links.add(String.format("<%s|%s>", url.group(1).replaceAll("\"", ""), aTag.group(2)));
+ }
+ }
+ aTag.appendTail(sb);
+ return links.toArray(new String[size]);
+ }
+
+ public String escape(String string) {
+ StringBuffer pattern = new StringBuffer();
+ String[] links = extractReplaceLinks(aTag.matcher(string), pattern);
+ return MessageFormat.format(escapeCharacters(pattern.toString()), links);
+ }
+
public String toString() {
return message.toString();
}
diff --git a/src/test/java/jenkins/plugins/slack/workflow/MessageBuilderTest.java b/src/test/java/jenkins/plugins/slack/workflow/MessageBuilderTest.java
new file mode 100644
index 00000000..1fa93cd7
--- /dev/null
+++ b/src/test/java/jenkins/plugins/slack/workflow/MessageBuilderTest.java
@@ -0,0 +1,66 @@
+package jenkins.plugins.slack.workflow;
+
+import hudson.model.FreeStyleBuild;
+import hudson.model.FreeStyleProject;
+import hudson.model.ItemGroup;
+import jenkins.plugins.slack.ActiveNotifier;
+import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mockito;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.ExecutionException;
+
+@RunWith(Parameterized.class)
+public class MessageBuilderTest extends TestCase {
+
+ private ActiveNotifier.MessageBuilder messageBuilder;
+ private String expectedResult;
+ private FreeStyleBuild build;
+
+
+ @Before
+ @Override
+ public void setUp() throws IOException, ExecutionException, InterruptedException {
+ messageBuilder = new ActiveNotifier.MessageBuilder(null, build);
+ }
+
+ public MessageBuilderTest(String projectDisplayName, String buildDisplayName, String expectedResult) {
+ this.build = Mockito.mock(FreeStyleBuild.class);
+ FreeStyleProject project = Mockito.mock(FreeStyleProject.class);
+
+ Mockito.when(build.getProject()).thenReturn(project);
+ Mockito.when(build.getDisplayName()).thenReturn(buildDisplayName);
+
+ ItemGroup ig = Mockito.mock(ItemGroup.class);
+ Mockito.when(ig.getFullDisplayName()).thenReturn("");
+ Mockito.when(project.getParent()).thenReturn(ig);
+ Mockito.when(project.getDisplayName()).thenReturn(projectDisplayName);
+
+ this.expectedResult = expectedResult;
+
+ }
+
+ @Parameterized.Parameters
+ public static Collection businessTypeKeys() {
+ return Arrays.asList(new Object[][]{
+ {"", "", " - "},
+ {"project", "#43 Started by changes from Bob", "project - #43 Started by changes from Bob "},
+ {"project", "#541 #125 Bug",
+ "project - #541 "},
+ {"project", "#541 Bold Project", "project - #541 <b>Bold Project</b> "},
+ {"project", "#541 bob", "project - #541 <a no-url>bob</a> "}
+ });
+ }
+
+ @Test
+ public void testStartMessage() {
+ assertEquals(expectedResult, messageBuilder.toString());
+ }
+
+}