Skip to content

Commit

Permalink
Merge pull request #155 from yrodiere/multi-repo
Browse files Browse the repository at this point in the history
Fix GitHubService when two history issues exist and one is the prefix of the other
  • Loading branch information
yrodiere authored Apr 29, 2024
2 parents ac9cb4d + 7f799a8 commit 3b00dfe
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package io.quarkus.github.lottery.github;

public class GitHubDedicatedIssue {
}
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,17 @@ private Optional<GHIssue> getDedicatedIssue(String assignee, String topic) throw
builder.assignee(assignee);
}
builder.state(GHIssueState.ALL);
// Try exact match first to avoid confusion if there are two issues and one is
// the exact topic while the other just starts with the topic.
// Example:
// topic = Lottery history for quarkusio/quarkus
// issue1.title = Lottery history for quarkusio/quarkusio.github.io
// issue2.title = Lottery history for quarkusio/quarkus
for (var issue : builder.list()) {
if (issue.getTitle().equals(topic)) {
return Optional.of(issue);
}
}
for (var issue : builder.list()) {
if (issue.getTitle().startsWith(topic)) {
return Optional.of(issue);
Expand Down
128 changes: 128 additions & 0 deletions src/test/java/io/quarkus/github/lottery/GitHubServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,60 @@ void extractCommentsFromDedicatedIssue_dedicatedIssueExists_appCommentsExist() t
});
}

@Test
void extractCommentsFromDedicatedIssue_dedicatedIssueExists_appCommentsExist_withConfusingOther() throws Exception {
var repoRef = new GitHubRepositoryRef(installationRef, "quarkusio/quarkus-lottery-reports");
var since = LocalDateTime.of(2017, 11, 6, 19, 0).toInstant(ZoneOffset.UTC);

var queryIssuesBuilderMock = Mockito.mock(GHIssueQueryBuilder.ForRepository.class,
withSettings().defaultAnswer(Answers.RETURNS_SELF));
var queryCommentsBuilderMock = Mockito.mock(GHIssueCommentQueryBuilder.class,
withSettings().defaultAnswer(Answers.RETURNS_SELF));

given()
.github(mocks -> {
var repositoryMock = mocks.repository(repoRef.repositoryName());

when(repositoryMock.queryIssues()).thenReturn(queryIssuesBuilderMock);
var issue1Mock = mockIssueForNotification(mocks, 1, "Lottery history for quarkusio/quarkusio.github.io");
var issue2Mock = mockIssueForNotification(mocks, 2, "Lottery history for quarkusio/quarkus");
var issuesMocks = mockPagedIterable(issue1Mock, issue2Mock);
when(queryIssuesBuilderMock.list()).thenReturn(issuesMocks);

var mySelfMock = mocks.ghObject(GHUser.class, 1L);
when(mySelfMock.getLogin()).thenReturn(installationRef.appLogin());
var someoneElseMock = mocks.ghObject(GHUser.class, 2L);
when(someoneElseMock.getLogin()).thenReturn("yrodiere");

when(issue2Mock.queryComments()).thenReturn(queryCommentsBuilderMock);
var issue2Comment1Mock = mocks.issueComment(202);
when(issue2Comment1Mock.getUser()).thenReturn(mySelfMock);
when(issue2Comment1Mock.getBody()).thenReturn("issue2Comment1Mock#body");
var issue2Comment2Mock = mocks.issueComment(203);
when(issue2Comment2Mock.getUser()).thenReturn(mySelfMock);
when(issue2Comment2Mock.getBody()).thenReturn("issue2Comment2Mock#body");
var issue2Comment3Mock = mocks.issueComment(204);
when(issue2Comment3Mock.getUser()).thenReturn(someoneElseMock);
var issue2CommentMocks = mockPagedIterable(issue2Comment1Mock, issue2Comment2Mock, issue2Comment3Mock);
when(queryCommentsBuilderMock.list()).thenReturn(issue2CommentMocks);
})
.when(() -> {
var repo = gitHubService.repository(repoRef);

assertThat(repo.extractCommentsFromDedicatedIssue(null,
"Lottery history for quarkusio/quarkus", since))
.containsExactly("issue2Comment1Mock#body", "issue2Comment2Mock#body");
})
.then().github(mocks -> {
verify(queryIssuesBuilderMock).creator(installationRef.appLogin());
verify(queryIssuesBuilderMock).state(GHIssueState.ALL);
verify(queryCommentsBuilderMock).since(Date.from(since));

verifyNoMoreInteractions(queryIssuesBuilderMock, queryCommentsBuilderMock);
verifyNoMoreInteractions(mocks.ghObjects());
});
}

@SuppressWarnings("unchecked")
@Test
void commentOnDedicatedIssue_dedicatedIssueExists_open() throws Exception {
Expand Down Expand Up @@ -965,6 +1019,80 @@ void commentOnDedicatedIssue_dedicatedIssueExists_noTopicSuffix() throws Excepti
});
}

@SuppressWarnings("unchecked")
@Test
void commentOnDedicatedIssue_dedicatedIssueExists_withConfusingOther() throws Exception {
var repoRef = new GitHubRepositoryRef(installationRef, "quarkusio/quarkus-lottery-reports");
var commentToMinimizeNodeId = "MDM6Qm90NzUwNjg0Mzg=";

Instant now = LocalDateTime.of(2017, 11, 6, 6, 0).toInstant(ZoneOffset.UTC);
var clockMock = Clock.fixed(now, ZoneOffset.UTC);
QuarkusMock.installMockForType(clockMock, Clock.class);

var queryIssuesBuilderMock = Mockito.mock(GHIssueQueryBuilder.ForRepository.class,
withSettings().defaultAnswer(Answers.RETURNS_SELF));
var queryCommentsBuilderMock = Mockito.mock(GHIssueCommentQueryBuilder.class,
withSettings().defaultAnswer(Answers.RETURNS_SELF));

given()
.github(mocks -> {
var repositoryMock = mocks.repository(repoRef.repositoryName());

when(repositoryMock.queryIssues()).thenReturn(queryIssuesBuilderMock);
var issue1Mock = mockIssueForNotification(mocks, 1, "Lottery history for quarkusio/quarkusio.github.io");
var issue2Mock = mockIssueForNotification(mocks, 2, "Lottery history for quarkusio/quarkus");
var issuesMocks = mockPagedIterable(issue1Mock, issue2Mock);
when(queryIssuesBuilderMock.list()).thenReturn(issuesMocks);

when(issue2Mock.getState()).thenReturn(GHIssueState.OPEN);

var mySelfMock = mocks.ghObject(GHUser.class, 1L);
when(mySelfMock.getLogin()).thenReturn(installationRef.appLogin());
var someoneElseMock = mocks.ghObject(GHUser.class, 2L);
when(someoneElseMock.getLogin()).thenReturn("yrodiere");

when(issue2Mock.queryComments()).thenReturn(queryCommentsBuilderMock);
var issue2Comment1Mock = mocks.issueComment(201);
when(issue2Comment1Mock.getUser()).thenReturn(mySelfMock);
var issue2Comment2Mock = mocks.issueComment(202);
when(issue2Comment2Mock.getUser()).thenReturn(mySelfMock);
var issue2Comment3Mock = mocks.issueComment(203);
when(issue2Comment3Mock.getUser()).thenReturn(someoneElseMock);
var issue2CommentMocks = mockPagedIterable(issue2Comment1Mock, issue2Comment2Mock, issue2Comment3Mock);
when(queryCommentsBuilderMock.list()).thenReturn(issue2CommentMocks);

when(issue2Comment2Mock.getNodeId()).thenReturn(commentToMinimizeNodeId);

when(messageFormatterMock.formatDedicatedIssueBodyMarkdown("Lottery history for quarkusio/quarkus",
"Some content"))
.thenReturn("Dedicated issue body");
})
.when(() -> {
var repo = gitHubService.repository(repoRef);

repo.commentOnDedicatedIssue("quarkus-github-lottery[bot]",
"Lottery history for quarkusio/quarkus", "", "Some content");
})
.then().github(mocks -> {
verify(queryIssuesBuilderMock).creator(installationRef.appLogin());
verify(queryIssuesBuilderMock).assignee("quarkus-github-lottery[bot]");
verify(queryIssuesBuilderMock).state(GHIssueState.ALL);

verify(queryCommentsBuilderMock).since(Date.from(now.minus(21, ChronoUnit.DAYS)));
var mapCaptor = ArgumentCaptor.forClass(Map.class);
verify(mocks.installationGraphQLClient(installationRef.installationId()))
.executeSync(anyString(), mapCaptor.capture());

verify(mocks.issue(2)).setBody("Dedicated issue body");
verify(mocks.issue(2)).comment("Some content");

verifyNoMoreInteractions(messageFormatterMock, queryIssuesBuilderMock);
verifyNoMoreInteractions(mocks.ghObjects());

assertThat(mapCaptor.getValue()).containsValue(commentToMinimizeNodeId);
});
}

@SuppressWarnings("unchecked")
@Test
void commentOnDedicatedIssue_dedicatedIssueExists_closed() throws Exception {
Expand Down

0 comments on commit 3b00dfe

Please sign in to comment.