Package org.jenkinsci.plugins.ghprb

Source Code of org.jenkinsci.plugins.ghprb.GhprbRepositoryTest

package org.jenkinsci.plugins.ghprb;

import hudson.util.CopyOnWriteMap.Hash;

import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.kohsuke.github.GHCommitPointer;
import org.kohsuke.github.GHCommitState;
import org.kohsuke.github.GHIssueComment;
import org.kohsuke.github.GHIssueState;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHPullRequestCommitDetail;
import org.kohsuke.github.GHRateLimit;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GHUser;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.PagedIterable;
import org.kohsuke.github.PagedIterator;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static org.kohsuke.github.GHCommitState.PENDING;
import static org.kohsuke.github.GHIssueState.OPEN;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.doReturn;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.only;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;

/**
* Unit tests for {@link GhprbRepository}.
*/
@RunWith(MockitoJUnitRunner.class)
public class GhprbRepositoryTest {

    private static final String TEST_USER_NAME = "test-user";
    private static final String TEST_REPO_NAME = "test-repo";
    private static final Date UPDATE_DATE = new Date();

    @Mock
    private GitHub gt;
    @Mock
    private GHRepository ghRepository;
    @Mock
    private GhprbGitHub gitHub;
    @Mock
    private Ghprb helper;
    @Mock
    private GHRateLimit ghRateLimit;
    @Mock
    private GHPullRequest ghPullRequest;
    @Mock
    private GHCommitPointer base;
    @Mock
    private GHCommitPointer head;
    @Mock
    private GHUser ghUser;

    private GhprbRepository ghprbRepository;
    private ConcurrentMap<Integer,GhprbPullRequest> pulls;
    private GhprbPullRequest ghprbPullRequest;

    @Before
    public void setUp() throws IOException {
        initGHPRWithTestData();

        // Mock github API
        given(helper.getGitHub()).willReturn(gitHub);
        given(gitHub.get()).willReturn(gt);
        given(gt.getRepository(anyString())).willReturn(ghRepository);

        // Mock rate limit
        given(gt.getRateLimit()).willReturn(ghRateLimit);
        increaseRateLimitToDefaults();
    }

    @Test
    public void testCheckMethodWhenUsingGitHubEnterprise() throws IOException {
        // GIVEN
        given(gt.getRateLimit()).willThrow(new FileNotFoundException());
        List<GHPullRequest> ghPullRequests = createListWithMockPR();
        given(ghRepository.getPullRequests(eq(GHIssueState.OPEN))).willReturn(ghPullRequests);

        mockHeadAndBase();
        mockCommitList();

        given(helper.ifOnlyTriggerPhrase()).willReturn(true);

        pulls.put(1, ghprbPullRequest);

        given(ghPullRequest.getUpdatedAt()).willReturn(UPDATE_DATE);
        given(ghPullRequest.getNumber()).willReturn(1);

        // WHEN
        ghprbRepository.check();

        // THEN
        verifyGetGithub(1);
    }

    @Test
    public void testCheckMethodWithOnlyExistingPRs() throws IOException {
        // GIVEN
        List<GHPullRequest> ghPullRequests = createListWithMockPR();
        given(ghRepository.getPullRequests(eq(GHIssueState.OPEN))).willReturn(ghPullRequests);

        mockHeadAndBase();
        mockCommitList();

        given(helper.ifOnlyTriggerPhrase()).willReturn(true);

        pulls.put(1, ghprbPullRequest);

        given(ghPullRequest.getUpdatedAt()).willReturn(UPDATE_DATE);
        given(ghPullRequest.getNumber()).willReturn(1);

        // WHEN
        ghprbRepository.check();

        // THEN
        verifyGetGithub(1);

        /** GH Repo verifications */
        verify(ghRepository, only()).getPullRequests(OPEN); // Call to Github API
        verifyNoMoreInteractions(ghRepository);

        /** GH PR verifications */
        verify(ghPullRequest, times(3)).getHead();
        verify(ghPullRequest, times(1)).getBase();
        verify(ghPullRequest, times(2)).getNumber();
        verify(ghPullRequest, times(1)).getUpdatedAt();
        verify(ghPullRequest, times(1)).getBody();
        verifyNoMoreInteractions(ghPullRequest);

        verify(helper).ifOnlyTriggerPhrase();
        verify(helper).getWhiteListTargetBranches();
        verifyNoMoreInteractions(helper);
        verifyNoMoreInteractions(gt);

        verifyZeroInteractions(ghUser);
    }

    @Test
    public void testCheckMethodWithNewPR() throws IOException {
        // GIVEN
        List<GHPullRequest> ghPullRequests = createListWithMockPR();
        ghPullRequests.add(ghPullRequest);

        GhprbBuilds builds = mockBuilds();

        mockHeadAndBase();
        mockCommitList();

        given(ghRepository.getPullRequests(eq(GHIssueState.OPEN))).willReturn(ghPullRequests);

        given(ghPullRequest.getUpdatedAt()).willReturn(UPDATE_DATE);
        given(ghPullRequest.getNumber()).willReturn(100);
        given(ghPullRequest.getMergeable()).willReturn(true);
        given(ghPullRequest.getTitle()).willReturn("title");
        given(ghPullRequest.getUser()).willReturn(ghUser);
        given(ghPullRequest.getUrl()).willReturn(new URL("https://github.com/org/repo/pull/100"));
        given(ghPullRequest.getApiURL()).willReturn(new URL("https://github.com/org/repo/pull/100"));

        given(ghUser.getEmail()).willReturn("email");

        given(helper.ifOnlyTriggerPhrase()).willReturn(false);
        given(helper.isWhitelisted(ghUser)).willReturn(true);

        // WHEN
        ghprbRepository.check();

        // THEN

        verifyGetGithub(1);
        verifyNoMoreInteractions(gt);

        /** GH PR verifications */
        verify(builds, times(1)).build(any(GhprbPullRequest.class), any(GHUser.class), any(String.class));
        verify(ghRepository, times(1)).getPullRequests(OPEN); // Call to Github API
        verify(ghRepository, times(1))
                .createCommitStatus(eq("head sha"), eq(PENDING), isNull(String.class), eq("msg")); // Call to Github API
        verifyNoMoreInteractions(ghRepository);

        verify(ghPullRequest, times(1)).getTitle();
        verify(ghPullRequest, times(2)).getUser();
        verify(ghPullRequest, times(1)).getMergeable(); // Call to Github API
        verify(ghPullRequest, times(8)).getHead();
        verify(ghPullRequest, times(3)).getBase();
        verify(ghPullRequest, times(5)).getNumber();
        verify(ghPullRequest, times(3)).getUpdatedAt();
        verify(ghPullRequest, times(1)).getUrl();
        verify(ghPullRequest, times(1)).listCommits();
        verify(ghPullRequest, times(2)).getBody();
        verifyNoMoreInteractions(ghPullRequest);

        verify(helper, times(1)).isWhitelisted(eq(ghUser))// Call to Github API
        verify(helper, times(2)).ifOnlyTriggerPhrase();
        verify(helper, times(1)).getBuilds();
        verify(helper, times(2)).getWhiteListTargetBranches();
        verifyNoMoreInteractions(helper);

        verify(ghUser, times(1)).getEmail();   // Call to Github API
        verify(ghUser, times(1)).getLogin();
        verifyNoMoreInteractions(ghUser);
    }

    private GhprbBuilds mockBuilds() throws IOException {
        GhprbBuilds builds = mock(GhprbBuilds.class);
        given(helper.getBuilds()).willReturn(builds);
        given(builds.build(any(GhprbPullRequest.class), any(GHUser.class), any(String.class))).willReturn("msg");
        given(ghRepository.createCommitStatus(anyString(), any(GHCommitState.class), anyString(), anyString())).willReturn(null);
        return builds;
    }

    @Test
    public void testCheckMethodWhenPrWasUpdatedWithNonKeyPhrase() throws IOException {
        // GIVEN
        List<GHPullRequest> ghPullRequests = createListWithMockPR();

        mockComments("comment body");
        mockHeadAndBase();
        mockCommitList();
        GhprbBuilds builds = mockBuilds();

        given(ghRepository.getPullRequests(eq(GHIssueState.OPEN))).willReturn(ghPullRequests);
        given(ghPullRequest.getUpdatedAt()).willReturn(new Date()).willReturn(new DateTime().plusDays(1).toDate());
        given(ghPullRequest.getNumber()).willReturn(100);
        given(ghPullRequest.getMergeable()).willReturn(true);
        given(ghPullRequest.getTitle()).willReturn("title");
        given(ghPullRequest.getUser()).willReturn(ghUser);
        given(ghPullRequest.getUrl()).willReturn(new URL("https://github.com/org/repo/pull/100"));
        given(ghPullRequest.getApiURL()).willReturn(new URL("https://github.com/org/repo/pull/100"));

        given(ghUser.getEmail()).willReturn("email");
        given(ghUser.getLogin()).willReturn("login");

        given(helper.ifOnlyTriggerPhrase()).willReturn(false);
        given(helper.isWhitelisted(ghUser)).willReturn(true);

        // WHEN
        ghprbRepository.check()// PR was created
        ghprbRepository.check()// PR was updated

        // THEN
        verifyGetGithub(2);
        verifyNoMoreInteractions(gt);

        /** GH PR verifications */
        verify(builds, times(1)).build(any(GhprbPullRequest.class), any(GHUser.class), any(String.class));
        verify(ghRepository, times(2)).getPullRequests(eq(OPEN)); // Call to Github API
        verify(ghRepository, times(1))
                .createCommitStatus(eq("head sha"), eq(PENDING), isNull(String.class), eq("msg")); // Call to Github API
        verifyNoMoreInteractions(ghRepository);

        verify(ghPullRequest, times(2)).getTitle();
        verify(ghPullRequest, times(2)).getUser();
        verify(ghPullRequest, times(1)).getMergeable(); // Call to Github API
        verify(ghPullRequest, times(8)).getHead();
        verify(ghPullRequest, times(3)).getBase();
        verify(ghPullRequest, times(5)).getNumber();
        verify(ghPullRequest, times(1)).getUrl();
        verify(ghPullRequest, times(4)).getUpdatedAt();

        verify(ghPullRequest, times(1)).getComments();
        verify(ghPullRequest, times(1)).listCommits();
        verify(ghPullRequest, times(2)).getBody();
        verifyNoMoreInteractions(ghPullRequest);

        verify(helper, times(1)).isWhitelisted(eq(ghUser))// Call to Github API
        verify(helper, times(2)).ifOnlyTriggerPhrase();
        verify(helper, times(1)).getBuilds();
        verify(helper, times(2)).getWhiteListTargetBranches();

        verify(helper).isBotUser(eq(ghUser));
        verify(helper).isWhitelistPhrase(eq("comment body"));
        verify(helper).isOktotestPhrase(eq("comment body"));
        verify(helper).isRetestPhrase(eq("comment body"));
        verify(helper).isTriggerPhrase(eq("comment body"));
        verifyNoMoreInteractions(helper);

        verify(ghUser, times(1)).getEmail();   // Call to Github API
        verify(ghUser, times(1)).getLogin();
        verifyNoMoreInteractions(ghUser);
    }

    private List<GHPullRequest> createListWithMockPR() {
        List<GHPullRequest> ghPullRequests = new ArrayList<GHPullRequest>();
        ghPullRequests.add(ghPullRequest);
        return ghPullRequests;
    }

    @Test
    public void testCheckMethodWhenPrWasUpdatedWithRetestPhrase() throws IOException {
        // GIVEN
        List<GHPullRequest> ghPullRequests = createListWithMockPR();

        mockComments("test this please");
        mockHeadAndBase();
        mockCommitList();
        GhprbBuilds builds = mockBuilds();

        given(ghRepository.getPullRequests(eq(GHIssueState.OPEN))).willReturn(ghPullRequests);
        given(ghPullRequest.getUpdatedAt()).willReturn(new Date()).willReturn(new Date()).willReturn(new DateTime().plusDays(1).toDate());
        given(ghPullRequest.getNumber()).willReturn(100);
        given(ghPullRequest.getMergeable()).willReturn(true);
        given(ghPullRequest.getTitle()).willReturn("title");
        given(ghPullRequest.getUser()).willReturn(ghUser);
        given(ghPullRequest.getUrl()).willReturn(new URL("https://github.com/org/repo/pull/100"));
        given(ghPullRequest.getApiURL()).willReturn(new URL("https://github.com/org/repo/pull/100"));

        given(ghUser.getEmail()).willReturn("email");
        given(ghUser.getLogin()).willReturn("login");

        given(helper.ifOnlyTriggerPhrase()).willReturn(false);
        given(helper.isRetestPhrase(eq("test this please"))).willReturn(true);
        given(helper.isWhitelisted(ghUser)).willReturn(true);

        // WHEN
        ghprbRepository.check()// PR was created
        ghprbRepository.check()// PR was updated

        // THEN
        verifyGetGithub(2);
        verifyNoMoreInteractions(gt);

        /** GH PR verifications */
        verify(builds, times(2)).build(any(GhprbPullRequest.class), any(GHUser.class), any(String.class));
        verify(ghRepository, times(2)).getPullRequests(eq(OPEN)); // Call to Github API
        verify(ghRepository, times(2))
                .createCommitStatus(eq("head sha"), eq(PENDING), isNull(String.class), eq("msg")); // Call to Github API
        verifyNoMoreInteractions(ghRepository);

        verify(ghPullRequest, times(2)).getTitle();
        verify(ghPullRequest, times(2)).getUser();
        verify(ghPullRequest, times(2)).getMergeable(); // Call to Github API
        verify(ghPullRequest, times(8)).getHead();
        verify(ghPullRequest, times(3)).getBase();
        verify(ghPullRequest, times(5)).getNumber();
        verify(ghPullRequest, times(4)).getUpdatedAt();
        verify(ghPullRequest, times(1)).getUrl();

        verify(ghPullRequest, times(1)).getComments();
        verify(ghPullRequest, times(2)).listCommits();
       
        verify(ghPullRequest, times(2)).getBody();
        verifyNoMoreInteractions(ghPullRequest);

        verify(helper, times(2)).isWhitelisted(eq(ghUser))// Call to Github API
        verify(helper, times(2)).ifOnlyTriggerPhrase();
        verify(helper, times(2)).getBuilds();
        verify(helper, times(2)).getWhiteListTargetBranches();

        verify(helper).isBotUser(eq(ghUser));
        verify(helper).isWhitelistPhrase(eq("test this please"));
        verify(helper).isOktotestPhrase(eq("test this please"));
        verify(helper).isRetestPhrase(eq("test this please"));
        verify(helper).isAdmin(eq(ghUser));
        verifyNoMoreInteractions(helper);

        verify(ghUser, times(1)).getEmail();   // Call to Github API
        verify(ghUser, times(1)).getLogin();
        verifyNoMoreInteractions(ghUser);

        verify(builds, times(2)).build(any(GhprbPullRequest.class), any(GHUser.class), any(String.class));
        verifyNoMoreInteractions(builds);
    }

    private void mockComments(String commentBody) throws IOException {
        GHIssueComment comment = mock(GHIssueComment.class);
        given(comment.getUpdatedAt()).willReturn(new DateTime().plusDays(3).toDate());
        given(comment.getUser()).willReturn(ghUser);
        given(comment.getBody()).willReturn(commentBody);
        List<GHIssueComment> comments = new ArrayList<GHIssueComment>();
        comments.add(comment);
        given(ghPullRequest.getComments()).willReturn(comments);
    }
   

    private void mockHeadAndBase() {
        /** Mock head\base */
        given(ghPullRequest.getHead()).willReturn(head);
        given(base.getSha()).willReturn("base sha");
        given(ghPullRequest.getBase()).willReturn(base);
        given(head.getSha()).willReturn("head sha");
    }
   
    private void mockCommitList() {
      PagedIterator itr = Mockito.mock(PagedIterator.class);
      PagedIterable pagedItr = Mockito.mock(PagedIterable.class);
      Mockito.when(ghPullRequest.listCommits()).thenReturn(pagedItr);
      Mockito.when(pagedItr.iterator()).thenReturn(itr);
      Mockito.when(itr.hasNext()).thenReturn(false);
  }

    @Test
    public void testCheckMethodWithNoPR() throws IOException {
        // GIVEN
        List<GHPullRequest> ghPullRequests = new ArrayList<GHPullRequest>();
        given(ghRepository.getPullRequests(eq(GHIssueState.OPEN))).willReturn(ghPullRequests);

        // WHEN
        ghprbRepository.check();

        // THEN
        verifyGetGithub(1);
        verifyNoMoreInteractions(gt);

        verify(ghRepository, times(1)).getPullRequests(OPEN); // Call to Github API
        verifyNoMoreInteractions(ghRepository);
        verifyZeroInteractions(helper);
    }

    @Test
    public void testExceedRateLimit() throws IOException {
        // GIVEN
        ghRateLimit.remaining = 0;

        // WHEN
        ghprbRepository.check();

        // THEN
        verify(helper, only()).getGitHub();
        verify(gitHub, only()).get();
        verify(gt, only()).getRateLimit();
        verifyZeroInteractions(ghRepository);
        verifyZeroInteractions(gitHub);
        verifyZeroInteractions(gt);
    }

    private void initGHPRWithTestData() throws IOException {
        /** Mock PR data */
        given(ghPullRequest.getUser()).willReturn(ghUser);
        given(ghUser.getEmail()).willReturn("email");
        given(helper.isWhitelisted(ghUser)).willReturn(true);
        given(ghPullRequest.getUpdatedAt()).willReturn(UPDATE_DATE);

        /** Mock head\base */
        given(base.getSha()).willReturn("base sha");
        given(ghPullRequest.getBase()).willReturn(base);

        given(ghPullRequest.getHead()).willReturn(head);
        given(head.getSha()).willReturn("head sha");

        pulls = new ConcurrentHashMap<Integer, GhprbPullRequest>();
        ghprbRepository = new GhprbRepository(TEST_USER_NAME, TEST_REPO_NAME, helper, pulls);
        ghprbPullRequest = new GhprbPullRequest(ghPullRequest, helper, ghprbRepository);

        // Reset mocks not to mix init data invocations with tests
        reset(ghPullRequest, ghUser, helper, head, base);
    }

    private void increaseRateLimitToDefaults() {
        ghRateLimit.remaining = 5000;
    }

    // Verifications
    private void verifyGetGithub(int callsCount) throws IOException {
        verify(helper, times(callsCount)).getGitHub();
        verify(gitHub, times(callsCount)).get(); // Call to Github API (once, than cached)
        verify(gt, times(1)).getRepository(anyString()); // Call to Github API
        verify(gt, times(callsCount)).getRateLimit();
    }
}
TOP

Related Classes of org.jenkinsci.plugins.ghprb.GhprbRepositoryTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.