Skip to content

Commit

Permalink
Replace <a> tags with Slack <link|name>
Browse files Browse the repository at this point in the history
Replace <a href...>text</a> with <url|text> before
escaping the remaining parts of the message

fixes #126
fixes nishio-dens/bitbucket-pullrequest-builder-plugin#59
  • Loading branch information
frodeaa committed May 27, 2016
1 parent 06f41c3 commit 82d7103
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/main/java/jenkins/plugins/slack/ActiveNotifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -216,6 +220,8 @@ String getBuildStatusMessage(AbstractBuild r, boolean includeTestSummary, boolea

public static class MessageBuilder {

private static final Pattern aTag = Pattern.compile("(?i)<a([^>]+)>(.+?)</a>");
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",
Expand Down Expand Up @@ -383,14 +389,34 @@ private String createBackToNormalDurationString(){
return Util.getTimeSpanString(backToNormalDuration);
}

public String escape(String string) {
private String escapeCharacters(String string) {
string = string.replace("&", "&amp;");
string = string.replace("<", "&lt;");
string = string.replace(">", "&gt;");

return string;
}

private String[] extractReplaceLinks(Matcher aTag, StringBuffer sb) {
int size = 0;
List<String> links = new ArrayList<String>();
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();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <a href=\"https://bitbucket.org/org/project/pull-request/125\">#125 Bug</a>",
"project - #541 <https://bitbucket.org/org/project/pull-request/125|#125 Bug> "},
{"project", "#541 <b>Bold Project</b>", "project - #541 &lt;b&gt;Bold Project&lt;/b&gt; "},
{"project", "#541 <a no-url>bob</a>", "project - #541 &lt;a no-url&gt;bob&lt;/a&gt; "}
});
}

@Test
public void testStartMessage() {
assertEquals(expectedResult, messageBuilder.toString());
}

}

0 comments on commit 82d7103

Please sign in to comment.