diff --git a/CHANGELOG.md b/CHANGELOG.md index 98931c5..6a2f66e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Changelog of Pull Request Notifier for Stash. ## 1.7 * Not sending authentication headers when user and/or password is not set +* Adding RESCOPED_FROM and RESCOPED_TO event types ## 1.6 * Correcting design with CSS for password field in admin view diff --git a/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestAction.java b/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestAction.java new file mode 100644 index 0000000..8a096dd --- /dev/null +++ b/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestAction.java @@ -0,0 +1,81 @@ +package se.bjurr.prnfs.listener; + +import static com.atlassian.stash.pull.PullRequestAction.APPROVED; +import static com.atlassian.stash.pull.PullRequestAction.COMMENTED; +import static com.atlassian.stash.pull.PullRequestAction.DECLINED; +import static com.atlassian.stash.pull.PullRequestAction.MERGED; +import static com.atlassian.stash.pull.PullRequestAction.OPENED; +import static com.atlassian.stash.pull.PullRequestAction.REOPENED; +import static com.atlassian.stash.pull.PullRequestAction.RESCOPED; +import static com.atlassian.stash.pull.PullRequestAction.UNAPPROVED; +import static com.atlassian.stash.pull.PullRequestAction.UPDATED; +import static com.google.common.collect.Lists.newArrayList; + +import java.util.List; +import java.util.Map; + +import com.atlassian.stash.event.pull.PullRequestEvent; +import com.atlassian.stash.event.pull.PullRequestRescopedEvent; +import com.google.common.collect.ImmutableMap; + +public class PrnfsPullRequestAction { + public static final String RESCOPED_TO = "RESCOPED_TO"; + + public static final String RESCOPED_FROM = "RESCOPED_FROM"; + + private static final Map values = new ImmutableMap.Builder() + .put(APPROVED.name(), new PrnfsPullRequestAction(APPROVED.name())) // + .put(COMMENTED.name(), new PrnfsPullRequestAction(COMMENTED.name())) // + .put(DECLINED.name(), new PrnfsPullRequestAction(DECLINED.name())) // + .put(MERGED.name(), new PrnfsPullRequestAction(MERGED.name())) // + .put(OPENED.name(), new PrnfsPullRequestAction(OPENED.name())) // + .put(REOPENED.name(), new PrnfsPullRequestAction(REOPENED.name())) // + .put(RESCOPED.name(), new PrnfsPullRequestAction(RESCOPED.name())) // + .put(RESCOPED_FROM, new PrnfsPullRequestAction(RESCOPED_FROM)) // + .put(RESCOPED_TO, new PrnfsPullRequestAction(RESCOPED_TO)) // + .put(UNAPPROVED.name(), new PrnfsPullRequestAction(UNAPPROVED.name())) // + .put(UPDATED.name(), new PrnfsPullRequestAction(UPDATED.name())) // + .build(); + + private final String name; + + private PrnfsPullRequestAction() { + name = null; + } + + private PrnfsPullRequestAction(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static PrnfsPullRequestAction valueOf(String string) { + if (values.containsKey(string)) { + return values.get(string); + } + throw new RuntimeException("\"" + string + "\" not found!"); + } + + public static List values() { + return newArrayList(values.values()); + } + + @SuppressWarnings("deprecation") + public static PrnfsPullRequestAction fromPullRequestEvent(PullRequestEvent event) { + if (event instanceof PullRequestRescopedEvent) { + PullRequestRescopedEvent rescopedEvent = (PullRequestRescopedEvent) event; + boolean toChanged = !rescopedEvent.getPreviousToHash().equals( + rescopedEvent.getPullRequest().getToRef().getLatestChangeset()); + boolean fromChanged = !rescopedEvent.getPreviousFromHash().equals( + rescopedEvent.getPullRequest().getFromRef().getLatestChangeset()); + if (fromChanged && !toChanged) { + return PrnfsPullRequestAction.valueOf(RESCOPED_FROM); + } else if (toChanged && !fromChanged) { + return PrnfsPullRequestAction.valueOf(RESCOPED_TO); + } + } + return PrnfsPullRequestAction.valueOf(event.getAction().name()); + } +} diff --git a/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestEventListener.java b/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestEventListener.java index 25c56ef..415aace 100644 --- a/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestEventListener.java +++ b/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestEventListener.java @@ -1,6 +1,7 @@ package se.bjurr.prnfs.listener; import static java.util.regex.Pattern.compile; +import static se.bjurr.prnfs.listener.PrnfsPullRequestAction.fromPullRequestEvent; import static se.bjurr.prnfs.settings.SettingsStorage.getPrnfsSettings; import org.slf4j.Logger; @@ -41,51 +42,51 @@ public void setUrlInvoker(UrlInvoker urlInvoker) { @EventListener public void onEvent(PullRequestApprovedEvent e) { - handleEvent(e); + handleEvent(e, fromPullRequestEvent(e)); } @EventListener public void onEvent(PullRequestCommentAddedEvent e) { - handleEvent(e); + handleEvent(e, fromPullRequestEvent(e)); } @EventListener public void onEvent(PullRequestDeclinedEvent e) { - handleEvent(e); + handleEvent(e, fromPullRequestEvent(e)); } @EventListener public void onEvent(PullRequestMergedEvent e) { - handleEvent(e); + handleEvent(e, fromPullRequestEvent(e)); } @EventListener public void onEvent(PullRequestOpenedEvent e) { - handleEvent(e); + handleEvent(e, fromPullRequestEvent(e)); } @EventListener public void onEvent(PullRequestReopenedEvent e) { - handleEvent(e); + handleEvent(e, fromPullRequestEvent(e)); } @EventListener - public void onEvent(PullRequestRescopedEvent e) { - handleEvent(e); + public void onEvent(final PullRequestRescopedEvent e) { + handleEvent(e, fromPullRequestEvent(e)); } @EventListener public void onEvent(PullRequestUnapprovedEvent e) { - handleEvent(e); + handleEvent(e, fromPullRequestEvent(e)); } @EventListener public void onEvent(PullRequestUpdatedEvent e) { - handleEvent(e); + handleEvent(e, fromPullRequestEvent(e)); } @VisibleForTesting - public void handleEvent(PullRequestEvent o) { + public void handleEvent(PullRequestEvent o, PrnfsPullRequestAction action) { final PrnfsRenderer renderer = new PrnfsRenderer(o); try { final PrnfsSettings settings = getPrnfsSettings(pluginSettingsFactory.createGlobalSettings()); @@ -94,7 +95,7 @@ public void handleEvent(PullRequestEvent o) { && !compile(n.getFilterRegexp().get()).matcher(renderer.render(n.getFilterString().get())).find()) { continue; } - if (n.getTriggers().contains(o.getAction())) { + if (n.getTriggers().contains(action)) { urlInvoker.ivoke(renderer.render(n.getUrl()), n.getUser(), n.getPassword()); } } diff --git a/src/main/java/se/bjurr/prnfs/settings/PrnfsNotification.java b/src/main/java/se/bjurr/prnfs/settings/PrnfsNotification.java index 43abd37..7ff8fc7 100644 --- a/src/main/java/se/bjurr/prnfs/settings/PrnfsNotification.java +++ b/src/main/java/se/bjurr/prnfs/settings/PrnfsNotification.java @@ -10,19 +10,19 @@ import java.util.List; import se.bjurr.prnfs.admin.AdminFormValues; +import se.bjurr.prnfs.listener.PrnfsPullRequestAction; -import com.atlassian.stash.pull.PullRequestAction; import com.google.common.base.Optional; public class PrnfsNotification { private final String filterRegexp; private final String filterString; private final String password; - private final List triggers; + private final List triggers; private final String url; private final String user; - public PrnfsNotification(List triggers, String url, String user, String password, + public PrnfsNotification(List triggers, String url, String user, String password, String filterString, String filterRegexp) throws ValidationException { this.password = emptyToNull(nullToEmpty(password).trim()); if (nullToEmpty(url).trim().isEmpty()) { @@ -64,7 +64,7 @@ public Optional getPassword() { return fromNullable(password); } - public List getTriggers() { + public List getTriggers() { return triggers; } diff --git a/src/main/java/se/bjurr/prnfs/settings/PrnfsNotificationBuilder.java b/src/main/java/se/bjurr/prnfs/settings/PrnfsNotificationBuilder.java index cfff15b..4313f9f 100644 --- a/src/main/java/se/bjurr/prnfs/settings/PrnfsNotificationBuilder.java +++ b/src/main/java/se/bjurr/prnfs/settings/PrnfsNotificationBuilder.java @@ -5,7 +5,7 @@ import java.util.List; -import com.atlassian.stash.pull.PullRequestAction; +import se.bjurr.prnfs.listener.PrnfsPullRequestAction; public class PrnfsNotificationBuilder { public static PrnfsNotificationBuilder prnfsNotificationBuilder() { @@ -13,7 +13,7 @@ public static PrnfsNotificationBuilder prnfsNotificationBuilder() { } private String password; - private final List triggers = newArrayList(); + private final List triggers = newArrayList(); private String url; private String user; private String filterRegexp; @@ -41,7 +41,7 @@ public PrnfsNotificationBuilder withFilterString(String filterString) { return this; } - public PrnfsNotificationBuilder withTrigger(PullRequestAction trigger) { + public PrnfsNotificationBuilder withTrigger(PrnfsPullRequestAction trigger) { this.triggers.add(checkNotNull(trigger)); return this; } diff --git a/src/main/java/se/bjurr/prnfs/settings/SettingsStorage.java b/src/main/java/se/bjurr/prnfs/settings/SettingsStorage.java index f49e14a..a8faba8 100644 --- a/src/main/java/se/bjurr/prnfs/settings/SettingsStorage.java +++ b/src/main/java/se/bjurr/prnfs/settings/SettingsStorage.java @@ -23,9 +23,9 @@ import org.slf4j.LoggerFactory; import se.bjurr.prnfs.admin.AdminFormValues; +import se.bjurr.prnfs.listener.PrnfsPullRequestAction; import com.atlassian.sal.api.pluginsettings.PluginSettings; -import com.atlassian.stash.pull.PullRequestAction; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; @@ -97,7 +97,7 @@ public static PrnfsNotification getPrnfsNotification(AdminFormValues a) throws V final PrnfsNotificationBuilder prnfsNotificationBuilder = prnfsNotificationBuilder().withUrl(urlOpt.get().get(VALUE)); final Iterable> events = filter(a, predicate("events")); for (final Map event : events) { - prnfsNotificationBuilder.withTrigger(PullRequestAction.valueOf(event.get(VALUE))); + prnfsNotificationBuilder.withTrigger(PrnfsPullRequestAction.valueOf(event.get(VALUE))); } if (tryFind(a, predicate(AdminFormValues.FIELDS.user.name())).isPresent()) { prnfsNotificationBuilder.withUser(find(a, predicate(AdminFormValues.FIELDS.user.name())).get(VALUE)); diff --git a/src/main/resources/admin.vm b/src/main/resources/admin.vm index 8d0535f..ad4ae43 100644 --- a/src/main/resources/admin.vm +++ b/src/main/resources/admin.vm @@ -66,12 +66,16 @@

- -

+
+

+ +
+ +

diff --git a/src/test/java/se/bjurr/prnfs/admin/PrnfsPullRequestEventListenerTest.java b/src/test/java/se/bjurr/prnfs/admin/PrnfsPullRequestEventListenerTest.java index d64fcc1..03914ef 100644 --- a/src/test/java/se/bjurr/prnfs/admin/PrnfsPullRequestEventListenerTest.java +++ b/src/test/java/se/bjurr/prnfs/admin/PrnfsPullRequestEventListenerTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import se.bjurr.prnfs.admin.AdminFormValues.FIELDS; +import se.bjurr.prnfs.listener.PrnfsPullRequestAction; import se.bjurr.prnfs.listener.PrnfsRenderer.PrnfsVariable; import com.google.common.io.Resources; @@ -313,4 +314,13 @@ public void testThatVariablesAreMentionedInAdminGUI() throws IOException { assertTrue(prnfsVariable.name() + " in " + resource.toString(), adminVmContent.contains(prnfsVariable.name())); } } + + @Test + public void testThatEventsAreMentionedInAdminGUI() throws IOException { + final URL resource = getResource("admin.vm"); + final String adminVmContent = Resources.toString(resource, UTF_8); + for (final PrnfsPullRequestAction prnfsAction : PrnfsPullRequestAction.values()) { + assertTrue(prnfsAction.getName() + " in " + resource.toString(), adminVmContent.contains(prnfsAction.getName())); + } + } } diff --git a/src/test/java/se/bjurr/prnfs/admin/utils/PrnfsTestBuilder.java b/src/test/java/se/bjurr/prnfs/admin/utils/PrnfsTestBuilder.java index 6ce009e..1e42284 100644 --- a/src/test/java/se/bjurr/prnfs/admin/utils/PrnfsTestBuilder.java +++ b/src/test/java/se/bjurr/prnfs/admin/utils/PrnfsTestBuilder.java @@ -16,6 +16,7 @@ import static org.mockito.Mockito.when; import static se.bjurr.prnfs.admin.AdminFormValues.NAME; import static se.bjurr.prnfs.admin.AdminFormValues.VALUE; +import static se.bjurr.prnfs.listener.PrnfsPullRequestAction.fromPullRequestEvent; import static se.bjurr.prnfs.listener.UrlInvoker.shouldUseBasicAuth; import static se.bjurr.prnfs.settings.PrnfsPredicates.predicate; import static se.bjurr.prnfs.settings.SettingsStorage.FORM_IDENTIFIER_NAME; @@ -254,7 +255,7 @@ public void ivoke(String url, Optional userParam, Optional passw usedPassword.add(passwordParam); } }); - listener.handleEvent(event); + listener.handleEvent(event, fromPullRequestEvent(event)); return this; } diff --git a/src/test/java/se/bjurr/prnfs/listener/PrnfsPullRequestActionTest.java b/src/test/java/se/bjurr/prnfs/listener/PrnfsPullRequestActionTest.java new file mode 100644 index 0000000..85e7e55 --- /dev/null +++ b/src/test/java/se/bjurr/prnfs/listener/PrnfsPullRequestActionTest.java @@ -0,0 +1,84 @@ +package se.bjurr.prnfs.listener; + +import static com.atlassian.stash.pull.PullRequestAction.OPENED; +import static com.atlassian.stash.pull.PullRequestAction.RESCOPED; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static se.bjurr.prnfs.listener.PrnfsPullRequestAction.RESCOPED_FROM; +import static se.bjurr.prnfs.listener.PrnfsPullRequestAction.RESCOPED_TO; +import static se.bjurr.prnfs.listener.PrnfsPullRequestAction.fromPullRequestEvent; + +import org.junit.Before; +import org.junit.Test; + +import com.atlassian.stash.event.pull.PullRequestEvent; +import com.atlassian.stash.event.pull.PullRequestRescopedEvent; +import com.atlassian.stash.pull.PullRequest; +import com.atlassian.stash.pull.PullRequestAction; +import com.atlassian.stash.pull.PullRequestRef; + +public class PrnfsPullRequestActionTest { + private PullRequestRescopedEvent event; + private PullRequest pullRequest; + private PullRequestRef fromRef; + private PullRequestRef toRef; + + @Before + public void before() { + event = mock(PullRequestRescopedEvent.class); + pullRequest = mock(PullRequest.class); + fromRef = mock(PullRequestRef.class); + toRef = mock(PullRequestRef.class); + when(event.getAction()).thenReturn(RESCOPED); + when(event.getPullRequest()).thenReturn(pullRequest); + when(event.getPullRequest().getFromRef()).thenReturn(fromRef); + when(event.getPullRequest().getToRef()).thenReturn(toRef); + } + + @Test + public void testThatAllPullRequestActionEventsAreMapped() { + for (PullRequestAction a : PullRequestAction.values()) { + assertNotNull(a.name(), PrnfsPullRequestAction.valueOf(a.name())); + assertEquals(a.name(), a.name(), PrnfsPullRequestAction.valueOf(a.name()).getName()); + } + } + + @SuppressWarnings("deprecation") + @Test + public void testThatRescopedEventsAreCalculatedCorrectlyWhenFromAndToChanges() { + when(event.getPreviousFromHash()).thenReturn("FROM"); + when(event.getPreviousToHash()).thenReturn("TO"); + when(event.getPullRequest().getFromRef().getLatestChangeset()).thenReturn("FROM2"); + when(event.getPullRequest().getToRef().getLatestChangeset()).thenReturn("TO2"); + assertEquals(RESCOPED.name(), fromPullRequestEvent(event).getName()); + } + + @SuppressWarnings("deprecation") + @Test + public void testThatRescopedEventsAreCalculatedCorrectlyWhenOnlyFromChanges() { + when(event.getPreviousFromHash()).thenReturn("FROM"); + when(event.getPreviousToHash()).thenReturn("TO"); + when(event.getPullRequest().getFromRef().getLatestChangeset()).thenReturn("FROM2"); + when(event.getPullRequest().getToRef().getLatestChangeset()).thenReturn("TO"); + assertEquals(RESCOPED_FROM, fromPullRequestEvent(event).getName()); + } + + @SuppressWarnings("deprecation") + @Test + public void testThatRescopedEventsAreCalculatedCorrectlyWhenOnlyToChanges() { + when(event.getPreviousFromHash()).thenReturn("FROM"); + when(event.getPreviousToHash()).thenReturn("TO"); + when(event.getPullRequest().getFromRef().getLatestChangeset()).thenReturn("FROM"); + when(event.getPullRequest().getToRef().getLatestChangeset()).thenReturn("TO2"); + assertEquals(RESCOPED_TO, fromPullRequestEvent(event).getName()); + } + + @Test + public void testThatNoneRescopedEventsAreCalculatedCorrectly() { + PullRequestEvent superEvent = mock(PullRequestEvent.class); + when(superEvent.getAction()).thenReturn(OPENED); + assertEquals(OPENED.name(), fromPullRequestEvent(superEvent).getName()); + } +}