list) {
+ return list.stream().mapToInt(String::length).reduce(0, Integer::sum) + list.size();
+ }
+
+ private static String truncateToLimit(TaskListener listener, String fieldName, String value, int limit) {
+ if (value == null)
+ return null;
+
+ if (value.length() > limit) {
+ listener.getLogger().printf("Warning: '%s' field has more than %d characters (%d). It will be truncated.%n",
+ fieldName,
+ limit,
+ value.length());
+ return value.substring(0, limit);
+ }
+
+ return value;
+ }
+
+ private static InputStream getFileInputStream(StepContext context, String file) throws IOException, InterruptedException {
+ FilePath ws = context.get(FilePath.class);
+ if (ws == null)
+ return null;
+
+ FilePath fp = ws.child(file);
+ if (fp.exists()) {
+ try {
+ return fp.read();
+ } catch (InvalidPathException var3) {
+ throw new IOException(var3);
+ }
+ } else {
+ String message = "No such file: " + file;
+ return new ByteArrayInputStream(message.getBytes(Charset.defaultCharset()));
+ }
+ }
+}
diff --git a/src/main/java/nz/co/jammehcow/jenkinsdiscord/util/MarkdownUtil.java b/src/main/java/nz/co/jammehcow/jenkinsdiscord/util/MarkdownUtil.java
new file mode 100644
index 0000000..bba98fb
--- /dev/null
+++ b/src/main/java/nz/co/jammehcow/jenkinsdiscord/util/MarkdownUtil.java
@@ -0,0 +1,99 @@
+package nz.co.jammehcow.jenkinsdiscord.util;
+
+import java.util.Objects;
+
+public final class MarkdownUtil {
+ private MarkdownUtil() {
+ }
+
+ /**
+ * From JDA's MarkdownSanitizer
+ *
+ * Escapes every single markdown formatting token found in the provided string.
+ *
Example: {@code escape("**Hello _World_", true)}
+ *
+ * This code is licensed under the Apache-2.0 license:
+ *
+ * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ * @param sequence The string to sanitize
+ * @return The string with escaped markdown
+ * @throws NullPointerException If provided with a null sequence
+ */
+ public static String escape(String sequence) {
+ Objects.requireNonNull(sequence);
+ StringBuilder builder = new StringBuilder();
+ boolean escaped = false;
+ boolean newline = true;
+ for (int i = 0; i < sequence.length(); i++) {
+ char current = sequence.charAt(i);
+ if (newline) {
+ newline = Character.isWhitespace(current); // might still be a quote if prefixed by whitespace
+ if (current == '>') {
+ // Check for quote if line starts with angle bracket
+ if (i + 1 < sequence.length() && Character.isWhitespace(sequence.charAt(i + 1))) {
+ builder.append("\\>"); // simple quote
+ } else if (i + 3 < sequence.length() && sequence.startsWith(">>>", i) &&
+ Character.isWhitespace(sequence.charAt(i + 3))) {
+ builder.append("\\>\\>\\>").append(sequence.charAt(i + 3)); // block quote
+ i += 3; // since we include 3 angle brackets AND whitespace
+ } else {
+ builder.append(current); // just a normal angle bracket
+ }
+ continue;
+ }
+ }
+
+ if (escaped) {
+ builder.append(current);
+ escaped = false;
+ continue;
+ }
+ // Handle average case
+ switch (current) {
+ case '*': // simple markdown escapes for single characters
+ case '_':
+ case '`':
+ builder.append('\\').append(current);
+ break;
+ case '|': // cases that require at least 2 characters in sequence
+ case '~':
+ if (i + 1 < sequence.length() && sequence.charAt(i + 1) == current) {
+ builder.append('\\').append(current)
+ .append('\\').append(current);
+ i++;
+ } else
+ builder.append(current);
+ break;
+ case '\\': // escape character
+ builder.append(current);
+ escaped = true;
+ break;
+ case '\n': // linefeed is a special case for quotes
+ builder.append(current);
+ newline = true;
+ break;
+ default:
+ builder.append(current);
+ }
+ }
+ return builder.toString();
+ }
+
+ public static String formatMarkdownUrl(String text, String url) {
+ return String.format("[%s](%s)", text, url.replaceAll("\\)", "\\\\\\)"));
+ }
+}
diff --git a/src/test/java/nz/co/jammehcow/jenkinsdiscord/BasicTest.java b/src/test/java/nz/co/jammehcow/jenkinsdiscord/BasicTest.java
index 446e7c9..e85ae6e 100644
--- a/src/test/java/nz/co/jammehcow/jenkinsdiscord/BasicTest.java
+++ b/src/test/java/nz/co/jammehcow/jenkinsdiscord/BasicTest.java
@@ -1,35 +1,24 @@
package nz.co.jammehcow.jenkinsdiscord;
+import org.jenkinsci.plugins.workflow.steps.StepConfigTester;
+import org.junit.Rule;
import org.junit.Test;
-
-import static org.junit.Assert.fail;
+import org.jvnet.hudson.test.JenkinsRule;
public class BasicTest {
- @Test
- public void webhookClassDoesntThrow() {
- try {
- DiscordWebhook wh = new DiscordWebhook("http://exampl.e");
- wh.setContent("content");
- wh.setDescription("desc");
- wh.setStatus(DiscordWebhook.StatusColor.GREEN);
- wh.send();
- } catch (Exception e) {
- fail();
- }
- }
+ @Rule
+ public JenkinsRule j = new JenkinsRule();
@Test
- public void pipelineDoesntThrow() {
+ public void configRoundTrip() {
try {
DiscordPipelineStep step = new DiscordPipelineStep("http://exampl.e");
step.setTitle("Test title");
- DiscordPipelineStep.DiscordPipelineStepExecution execution =
- new DiscordPipelineStep.DiscordPipelineStepExecution();
- execution.step = step;
- execution.listener = () -> System.out;
- execution.run();
+
+ DiscordPipelineStep roundtrippedStep = new StepConfigTester(this.j).configRoundTrip(step);
+ this.j.assertEqualDataBoundBeans(step, roundtrippedStep);
} catch (Exception e) {
- fail();
+ throw new RuntimeException(e);
}
}
}