package se.bjurr.prnfb.service;
import static com.atlassian.bitbucket.pull.PullRequestState.DECLINED;
import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import static se.bjurr.prnfb.listener.PrnfbPullRequestAction.BUTTON_TRIGGER;
import static se.bjurr.prnfb.listener.PrnfbPullRequestAction.MERGED;
import static se.bjurr.prnfb.test.Podam.populatedInstanceOf;
import static se.bjurr.prnfb.transformer.ButtonTransformer.toPrnfbButton;
import static se.bjurr.prnfb.transformer.NotificationTransformer.toPrnfbNotification;
import java.util.List;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import com.atlassian.bitbucket.auth.AuthenticationContext;
import com.atlassian.bitbucket.project.Project;
import com.atlassian.bitbucket.pull.PullRequest;
import com.atlassian.bitbucket.pull.PullRequestRef;
import com.atlassian.bitbucket.pull.PullRequestService;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.repository.RepositoryService;
import com.atlassian.bitbucket.server.ApplicationPropertiesService;
import com.google.common.collect.Lists;
import se.bjurr.prnfb.http.ClientKeyStore;
import se.bjurr.prnfb.listener.PrnfbPullRequestAction;
import se.bjurr.prnfb.listener.PrnfbPullRequestEventListener;
import se.bjurr.prnfb.presentation.dto.ButtonDTO;
import se.bjurr.prnfb.presentation.dto.NotificationDTO;
import se.bjurr.prnfb.presentation.dto.ON_OR_OFF;
import se.bjurr.prnfb.settings.PrnfbButton;
import se.bjurr.prnfb.settings.PrnfbNotification;
import se.bjurr.prnfb.settings.USER_LEVEL;
import se.bjurr.prnfb.settings.ValidationException;
public class ButtonsServiceTest {
@Mock private AuthenticationContext authenticationContext;
private PrnfbButton button1;
private PrnfbButton button2;
private PrnfbButton button3;
private ButtonDTO buttonDto1;
private ButtonDTO buttonDto2;
private ButtonDTO buttonDto3;
@Mock private ClientKeyStore clientKeyStore;
private final ON_OR_OFF confirmation = ON_OR_OFF.on;
private final String name = "name";
private PrnfbNotification notification1;
private PrnfbNotification notification2;
private NotificationDTO notificationDto1;
private NotificationDTO notificationDto2;
private List<PrnfbNotification> notifications;
@Mock private Repository originRepo;
@Mock private PrnfbPullRequestEventListener prnfbPullRequestEventListener;
@Mock private PrnfbRendererFactory prnfbRendererFactory;
@Mock private Project project;
@Mock private ApplicationPropertiesService propertiesService;
@Mock private PullRequestRef prRef;
@Mock private PullRequest pullRequest;
private final PrnfbPullRequestAction pullRequestAction = BUTTON_TRIGGER;
@Mock private PullRequestService pullRequestService;
@Mock private PrnfbRenderer renderer;
@Mock private Repository repository;
@Mock private RepositoryService repositoryService;
@Mock private SettingsService settingsService;
private final Boolean shouldAcceptAnyCertificate = true;
private ButtonsService sut;
@Mock private UserCheckService userCheckService;
private final USER_LEVEL userLevel = USER_LEVEL.ADMIN;
private final UUID uuid = UUID.randomUUID();
@SuppressWarnings("unchecked")
@Before
public void before() throws ValidationException {
initMocks(this);
this.sut =
new ButtonsService(
this.pullRequestService,
this.prnfbPullRequestEventListener,
this.prnfbRendererFactory,
this.settingsService,
this.userCheckService);
when(this.prnfbRendererFactory.create(
any(PullRequest.class),
any(PrnfbPullRequestAction.class),
any(PrnfbNotification.class),
any(VariablesContext.class))) //
.thenReturn(this.renderer);
this.buttonDto1 = populatedInstanceOf(ButtonDTO.class);
this.buttonDto1.setProjectKey(null);
this.buttonDto1.setRepositorySlug(null);
this.buttonDto1.setUserLevel(null);
this.button1 = toPrnfbButton(this.buttonDto1);
this.buttonDto2 = populatedInstanceOf(ButtonDTO.class);
this.buttonDto2.setProjectKey(null);
this.buttonDto2.setRepositorySlug(null);
this.buttonDto2.setUserLevel(null);
this.button2 = toPrnfbButton(this.buttonDto2);
this.buttonDto3 = populatedInstanceOf(ButtonDTO.class);
this.buttonDto3.setUserLevel(null);
this.button3 = toPrnfbButton(this.buttonDto3);
when(this.settingsService.getButton(this.button1.getUuid())) //
.thenReturn(this.button1);
when(this.settingsService.getButton(this.button2.getUuid())) //
.thenReturn(this.button2);
when(this.settingsService.getButton(this.button3.getUuid())) //
.thenReturn(this.button3);
this.notificationDto1 = populatedInstanceOf(NotificationDTO.class);
this.notificationDto1.setUrl("http://hej.com");
this.notificationDto1.setTriggerIgnoreStateList(Lists.newArrayList(DECLINED.name()));
this.notificationDto1.setTriggers(newArrayList(MERGED.name()));
this.notification1 = toPrnfbNotification(this.notificationDto1);
this.notificationDto2 = populatedInstanceOf(NotificationDTO.class);
this.notificationDto2.setUrl("http://hej.com");
this.notificationDto2.setTriggerIgnoreStateList(Lists.newArrayList(DECLINED.name()));
this.notificationDto2.setTriggers(newArrayList(MERGED.name()));
this.notification2 = toPrnfbNotification(this.notificationDto2);
this.notifications = newArrayList(this.notification1, this.notification2);
when(this.settingsService.getNotifications()) //
.thenReturn(this.notifications);
when(this.pullRequest.getToRef()).thenReturn(this.prRef);
when(this.prRef.getRepository()).thenReturn(this.repository);
when(this.repository.getSlug()).thenReturn(this.button3.getRepositorySlug().get());
when(this.repository.getProject()).thenReturn(this.project);
when(this.project.getKey()).thenReturn(this.button3.getProjectKey().get());
}
@Test
public void testThatButtonsCanBeRetrievedWhenAllAllowed() {
List<PrnfbButton> candidates = newArrayList(this.button1, this.button2, this.button3);
when(this.settingsService.getButtons()) //
.thenReturn(candidates);
String projectKey = prRef.getRepository().getProject().getKey();
String repoSlug = prRef.getRepository().getSlug();
when(this.userCheckService.isAllowed(this.button1.getUserLevel(), projectKey, repoSlug)) //
.thenReturn(true);
when(this.userCheckService.isAllowed(this.button2.getUserLevel(), projectKey, repoSlug)) //
.thenReturn(true);
when(this.userCheckService.isAllowed(this.button3.getUserLevel(), projectKey, repoSlug)) //
.thenReturn(true);
when(this.userCheckService.isAllowed(
this.button1.getUserLevel(), projectKey, "otherrepository")) //
.thenReturn(true);
when(this.userCheckService.isAllowed(
this.button2.getUserLevel(), projectKey, "otherrepository")) //
.thenReturn(true);
when(this.userCheckService.isAllowed(
this.button3.getUserLevel(), projectKey, "otherrepository")) //
.thenReturn(true);
when(this.prnfbPullRequestEventListener.isNotificationTriggeredByAction(
this.notification1,
this.pullRequestAction,
this.renderer,
this.pullRequest,
this.clientKeyStore,
this.shouldAcceptAnyCertificate)) //
.thenReturn(true);
when(this.prnfbPullRequestEventListener.isNotificationTriggeredByAction(
this.notification2,
this.pullRequestAction,
this.renderer,
this.pullRequest,
this.clientKeyStore,
this.shouldAcceptAnyCertificate)) //
.thenReturn(true);
List<PrnfbButton> actual =
this.sut.doGetButtons(
this.notifications,
this.clientKeyStore,
this.pullRequest,
this.shouldAcceptAnyCertificate);
assertThat(actual) //
.containsOnly(this.button1, this.button2, this.button3);
// Now do the same with another repository - button3 should disappear
when(this.repository.getSlug()).thenReturn("otherrepository");
actual =
this.sut.doGetButtons(
this.notifications,
this.clientKeyStore,
this.pullRequest,
this.shouldAcceptAnyCertificate);
assertThat(actual) //
.containsOnly(this.button1, this.button2);
// Now check if the button is inherited from the origin repo
when(this.repository.getOrigin()).thenReturn(this.originRepo);
when(this.originRepo.getSlug()).thenReturn(this.button3.getRepositorySlug().get());
when(this.originRepo.getProject()).thenReturn(this.project);
actual =
this.sut.doGetButtons(
this.notifications,
this.clientKeyStore,
this.pullRequest,
this.shouldAcceptAnyCertificate);
assertThat(actual) //
.containsOnly(this.button1, this.button2, this.button3);
}
@Test
public void testThatButtonsCanBeRetrievedWhenNoneAllowed() {
List<PrnfbButton> candidates = newArrayList(this.button1, this.button2);
when(this.settingsService.getButtons()) //
.thenReturn(candidates);
String projectKey = prRef.getRepository().getProject().getKey();
String repoSlug = prRef.getRepository().getSlug();
when(this.userCheckService.isAllowed(this.button1.getUserLevel(), projectKey, repoSlug)) //
.thenReturn(false);
when(this.userCheckService.isAllowed(this.button2.getUserLevel(), projectKey, repoSlug)) //
.thenReturn(false);
List<PrnfbButton> actual =
this.sut.doGetButtons(
this.notifications,
this.clientKeyStore,
this.pullRequest,
this.shouldAcceptAnyCertificate);
assertThat(actual) //
.isEmpty();
}
@Test
public void testThatPressedButtonDoesNotDoAnythingIfNoMatchingNotification() {
UUID buttonUuid = this.button1.getUuid();
this.sut.doHandlePressed(
buttonUuid, this.clientKeyStore, this.shouldAcceptAnyCertificate, this.pullRequest, "");
verify(this.prnfbPullRequestEventListener, times(0)) //
.notify(any(), any(), any(), any(), any(), any());
}
@Test
public void testThatPressedButtonDoesTriggerIfMatchingNotification() {
UUID buttonUuid = this.button1.getUuid();
when(this.prnfbPullRequestEventListener.isNotificationTriggeredByAction(
any(), any(), any(), any(), any(), any())) //
.thenReturn(true);
this.sut.doHandlePressed(
buttonUuid, this.clientKeyStore, this.shouldAcceptAnyCertificate, this.pullRequest, "");
verify(this.prnfbPullRequestEventListener, times(2)) //
.notify(any(), any(), any(), any(), any(), any());
}
@Test
public void testVisibilityOnPullRequest() {
String buttonProjectKey = "proj";
String buttonRepositorySlug = "repo";
String repoProjectKey = "proj";
String repoRepositorySlug = "repo";
testVisibilityOnRepository(
buttonProjectKey, buttonRepositorySlug, repoProjectKey, repoRepositorySlug, true);
buttonProjectKey = "proj";
buttonRepositorySlug = "repo";
repoProjectKey = "proj2";
repoRepositorySlug = "repo";
testVisibilityOnRepository(
buttonProjectKey, buttonRepositorySlug, repoProjectKey, repoRepositorySlug, false);
buttonProjectKey = "proj";
buttonRepositorySlug = null;
repoProjectKey = "proj";
repoRepositorySlug = "repo";
testVisibilityOnRepository(
buttonProjectKey, buttonRepositorySlug, repoProjectKey, repoRepositorySlug, true);
buttonProjectKey = "proj";
buttonRepositorySlug = null;
repoProjectKey = "proj2";
repoRepositorySlug = "repo";
testVisibilityOnRepository(
buttonProjectKey, buttonRepositorySlug, repoProjectKey, repoRepositorySlug, false);
buttonProjectKey = "proj";
buttonRepositorySlug = "repo";
repoProjectKey = "proj";
repoRepositorySlug = "repo2";
testVisibilityOnRepository(
buttonProjectKey, buttonRepositorySlug, repoProjectKey, repoRepositorySlug, false);
buttonProjectKey = "proj";
buttonRepositorySlug = "repo";
repoProjectKey = "proj2";
repoRepositorySlug = "repo2";
testVisibilityOnRepository(
buttonProjectKey, buttonRepositorySlug, repoProjectKey, repoRepositorySlug, false);
}
private void testVisibilityOnRepository(
String buttonProjectKey,
String buttonRepositorySlug,
String repoProjectKey,
String repoRepoSlug,
boolean expected) {
PrnfbButton button =
new PrnfbButton(
this.uuid,
this.name,
this.userLevel,
this.confirmation,
buttonProjectKey,
buttonRepositorySlug,
"confirmationText",
null);
when(this.repository.getProject()).thenReturn(this.project);
when(this.repository.getProject().getKey()) //
.thenReturn(repoProjectKey);
when(this.repository.getSlug()) //
.thenReturn(repoRepoSlug);
assertThat(this.sut.isVisibleOnRepository(button, this.repository)) //
.isEqualTo(expected);
}
}