package org.zalando.catwatch.backend.github; import com.google.common.collect.Lists; import org.junit.Test; import org.junit.runner.RunWith; import org.kohsuke.github.GHCommit; import org.kohsuke.github.GHRepository; import org.kohsuke.github.GHRepository.Contributor; import org.kohsuke.github.GHTeam; import org.kohsuke.github.GHUser; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; import org.zalando.catwatch.backend.model.Language; import org.zalando.catwatch.backend.model.Project; import org.zalando.catwatch.backend.model.Statistics; import org.zalando.catwatch.backend.model.util.Scorer; import java.io.ByteArrayInputStream; import java.net.URL; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import static java.time.Instant.now; import static java.util.Arrays.asList; import static java.util.Collections.*; import static java.util.Date.from; import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class TakeSnapshotTaskTest { @InjectMocks TakeSnapshotTask task = new TakeSnapshotTask(null, null, null, from(now())); @Mock Scorer scorer; @Mock Date date = new Date(); static final String ORGANIZATION_LOGIN = "myLogin"; static final int ORGANIZATION_ID = 77; @Test public void testCollectContributors() throws Exception { // given RepositoryWrapper repo1 = mock(RepositoryWrapper.class); Contributor c1 = newContributor(11, 22, "http://a.com", 33); when(repo1.listContributors()).thenReturn(asList(c1)); RepositoryWrapper repo2 = mock(RepositoryWrapper.class); Contributor c2 = newContributor(44, 55, "http://b.com", 66); when(repo2.listContributors()).thenReturn(asList(c2)); List<org.zalando.catwatch.backend.model.Contributor> contributors = new ArrayList<>( task.collectContributors(org(asList(repo1, repo2)))); assertThat(contributors, hasSize(2)); org.zalando.catwatch.backend.model.Contributor c1_ = contributors.get(0); assertThat(c1_.getId(), equalTo(11L)); assertThat(c1_.getOrganizationalCommitsCount(), equalTo(22)); assertThat(c1_.getUrl(), equalTo("http://a.com")); org.zalando.catwatch.backend.model.Contributor c2_ = contributors.get(1); assertThat(c2_.getId(), equalTo(44L)); assertThat(c2_.getOrganizationalCommitsCount(), equalTo(55)); assertThat(c2_.getUrl(), equalTo("http://b.com")); } private Contributor newContributor(int id, int contributions, String htmlUrl, int publicRepoCount) throws Exception { Contributor c = mock(Contributor.class); when(c.getId()).thenReturn(id); when(c.getContributions()).thenReturn(contributions); when(c.getHtmlUrl()).thenReturn(new URL(htmlUrl)); when(c.getPublicRepoCount()).thenReturn(publicRepoCount); return c; } @Test public void testCollectStatistics() throws Exception { // given OrganizationWrapper org = mock(OrganizationWrapper.class); when(org.listMembers()).thenReturn(mockList(GHUser.class, 5)); when(org.listTeams()).thenReturn(mockList(GHTeam.class, 4)); when(org.listRepositories()).thenReturn(emptyList()); // TODO add more behavior and more assertions when(org.getLogin()).thenReturn("myLogin"); // when Statistics statistics = task.collectStatistics(org); // then assertThat(statistics.getPublicProjectCount(), equalTo(0)); assertThat(statistics.getMembersCount(), equalTo(5)); assertThat(statistics.getTeamsCount(), equalTo(4)); assertThat(statistics.getOrganizationName(), equalTo("myLogin")); } @Test public void testCollectProjects() throws Exception { // given RepositoryWrapper repo = mock(RepositoryWrapper.class); when(repo.getId()).thenReturn(123); when(repo.getName()).thenReturn("awesome"); when(repo.getUrl()).thenReturn(new URL("http://a.com/b.html")); when(repo.getDescription()).thenReturn("cool"); when(repo.getStarsCount()).thenReturn(11); when(repo.getForksCount()).thenReturn(22); when(repo.getLastPushed()).thenReturn(date); when(repo.getPrimaryLanguage()).thenReturn("Go"); when(repo.listLanguages()).thenReturn(toMap("C", 30, "Go", 15, "Java", 4)); when(repo.listCommits()).thenReturn(mockList(GHCommit.class, 2)); when(repo.listContributors()).thenReturn(mockList(Contributor.class, 2)); when(repo.getFileContent("MAINTAINERS")).thenReturn(new ByteArrayInputStream("foo\nbar".getBytes())); when(repo.getFileContent(".catwatch.yaml")).thenReturn(new ByteArrayInputStream("image: test\n".getBytes())); when(scorer.score(any(Project.class))).thenReturn(55); // when List<Project> projects = new ArrayList<>(task.collectProjects(org(singletonList(repo)))); // then assertThat(projects, hasSize(1)); Project project = projects.get(0); assertThat(project.getGitHubProjectId(), equalTo(123L)); assertThat(project.getSnapshotDate().getTime(), equalTo(((Date)ReflectionTestUtils.getField(task, "snapshotDate")).getTime())); assertThat(project.getName(), equalTo("awesome")); assertThat(project.getUrl(), equalTo("http://a.com/b.html")); assertThat(project.getDescription(), equalTo("cool")); assertThat(project.getStarsCount(), equalTo(11)); assertThat(project.getForksCount(), equalTo(22)); assertThat(project.getLastPushed(), equalTo(date.toString())); assertThat(project.getPrimaryLanguage(), equalTo("Go")); assertThat(project.getLanguageList(), containsInAnyOrder("C", "Go", "Java")); assertThat(project.getCommitsCount(), equalTo(2)); assertThat(project.getContributorsCount(), equalTo(2)); assertThat(project.getScore(), equalTo(55)); assertThat(project.getMaintainers(), containsInAnyOrder("foo", "bar")); assertThat(project.getImage(), equalTo("test")); } @Test public void testCollectLanguages() throws Exception { // given List<RepositoryWrapper> repos = asList( // repo("C", 30, "Go", 15, "Java", 4), // repo("C", 30, "Go", 15, "Java", 4), // repo("Java", 2)); // when List<Language> langs = new ArrayList<>(task.collectLanguages(org(repos))); // then assertThat(langs, hasSize(3)); sort(langs, (p1, p2) -> p1.getName().compareTo(p2.getName())); assertThat(langs.get(0).getName(), equalTo("C")); assertThat(langs.get(0).getProjectsCount(), equalTo(2)); assertThat(langs.get(0).getPercentage(), equalTo(60)); assertThat(langs.get(1).getName(), equalTo("Go")); assertThat(langs.get(1).getProjectsCount(), equalTo(2)); assertThat(langs.get(1).getPercentage(), equalTo(30)); assertThat(langs.get(2).getName(), equalTo("Java")); assertThat(langs.get(2).getProjectsCount(), equalTo(3)); assertThat(langs.get(2).getPercentage(), equalTo(10)); } class TestGHContributor extends GHRepository.Contributor { public TestGHContributor(String login, int id) { super(); this.login = login; this.id = id; } } @Test /** * Tests the counting of external contributors */ public void testCountExternalContributors() throws Exception { GHRepository.Contributor internal1 = new TestGHContributor("internal1", 1); GHRepository.Contributor internal2 = new TestGHContributor("internal2", 2); List<GHUser> members = Lists.newArrayList(internal1, internal2); List<GHRepository.Contributor> contributors = Lists.newArrayList(internal1, internal2, new TestGHContributor("external", 3)); RepositoryWrapper repo = mock(RepositoryWrapper.class); when(repo.listContributors()).thenReturn(contributors); // given OrganizationWrapper org = mock(OrganizationWrapper.class); when(org.listMembers()).thenReturn(members); when(org.listTeams()).thenReturn(mockList(GHTeam.class, 4)); when(org.listRepositories()).thenReturn(Lists.newArrayList(repo)); when(org.contributorIsMember(any(Contributor.class))).thenCallRealMethod(); // when Statistics statistics = task.collectStatistics(org); assertThat(statistics.getExternalContributorsCount(), equalTo(1)); assertThat(statistics.getAllContributorsCount(), equalTo(3)); } private OrganizationWrapper org(List<RepositoryWrapper> repos) { OrganizationWrapper org = mock(OrganizationWrapper.class); when(org.listRepositories()).thenReturn(repos); when(org.getLogin()).thenReturn(ORGANIZATION_LOGIN); when(org.getId()).thenReturn(ORGANIZATION_ID); return org; } private RepositoryWrapper repo(Object... keyAndValuePairs) { RepositoryWrapper repo = mock(RepositoryWrapper.class); when(repo.listLanguages()).thenReturn(toMap(keyAndValuePairs)); return repo; } /** * @param keyAndValuePairs * @return Returns a map with the given keys and values. */ @SuppressWarnings("unchecked") private <T> Map<String, T> toMap(Object... keyAndValuePairs) { Map<String, T> map = new HashMap<>(); for (int index = 0; index < keyAndValuePairs.length; index = index + 2) { String key = (String) keyAndValuePairs[index]; Object value = keyAndValuePairs[index + 1]; map.put(key, (T) value); } return map; } private <T> List<T> mockList(Class<? extends T> clazz, int size) { // does not work on Travis CI (compile error) // return IntStream.generate(() -> 1).limit(size).mapToObj(i -> mock(clazz)).collect(toList()); List<T> result = new ArrayList<>(); for (int index = 0; index < size; index++) { result.add(mock(clazz)); } return result; } }