diff --git a/github/pom.xml b/github/pom.xml
index d52b92f5d..7348901ee 100644
--- a/github/pom.xml
+++ b/github/pom.xml
@@ -79,6 +79,21 @@
spring-boot-starter-test
test
+
+ org.junit.platform
+ junit-platform-launcher
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ test
+
\ No newline at end of file
diff --git a/github/src/main/java/io/fundrequest/platform/github/parser/GithubResult.java b/github/src/main/java/io/fundrequest/platform/github/parser/GithubResult.java
index c41d35eec..c40ee94c2 100644
--- a/github/src/main/java/io/fundrequest/platform/github/parser/GithubResult.java
+++ b/github/src/main/java/io/fundrequest/platform/github/parser/GithubResult.java
@@ -15,7 +15,8 @@ public class GithubResult {
private String number;
private String title;
private String state;
- @JsonProperty("body_html")
private String body;
+ @JsonProperty("body_html")
+ private String bodyHtml;
private GithubUser user;
}
diff --git a/github/src/main/java/io/fundrequest/platform/github/scraper/GithubScraper.java b/github/src/main/java/io/fundrequest/platform/github/scraper/GithubScraper.java
index cd3a2f411..5f20cb402 100644
--- a/github/src/main/java/io/fundrequest/platform/github/scraper/GithubScraper.java
+++ b/github/src/main/java/io/fundrequest/platform/github/scraper/GithubScraper.java
@@ -1,6 +1,7 @@
package io.fundrequest.platform.github.scraper;
import io.fundrequest.common.infrastructure.JsoupSpringWrapper;
+import io.fundrequest.platform.github.scraper.model.GithubId;
import io.fundrequest.platform.github.scraper.model.GithubIssue;
import org.jsoup.nodes.Document;
import org.springframework.stereotype.Component;
@@ -29,7 +30,7 @@ public GithubIssue fetchGithubIssue(final String owner, final String repo, final
}
return GithubIssue.builder()
.number(number)
- .solver(solverResolver.resolve(document, owner, repo))
+ .solver(solverResolver.resolve(document, GithubId.builder().owner(owner).repo(repo).number(number).build()).orElse(null))
.status(statusResolver.resolve(document))
.build();
}
diff --git a/github/src/main/java/io/fundrequest/platform/github/scraper/GithubSolverResolver.java b/github/src/main/java/io/fundrequest/platform/github/scraper/GithubSolverResolver.java
index 0ddbed2d6..6d216701e 100644
--- a/github/src/main/java/io/fundrequest/platform/github/scraper/GithubSolverResolver.java
+++ b/github/src/main/java/io/fundrequest/platform/github/scraper/GithubSolverResolver.java
@@ -2,54 +2,75 @@
import io.fundrequest.platform.github.GithubGateway;
import io.fundrequest.platform.github.parser.GithubResult;
+import io.fundrequest.platform.github.scraper.model.GithubId;
import org.apache.commons.lang.StringUtils;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.regex.Pattern;
+
@Component
public class GithubSolverResolver {
+ private static final List CLOSING_KEYWORDS = Arrays.asList("close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved");
+
private final GithubGateway githubGateway;
public GithubSolverResolver(final GithubGateway githubGateway) {
this.githubGateway = githubGateway;
}
- public String resolve(final Document document, final String owner, final String repo) {
+ public Optional resolve(final Document document, final GithubId issueGithubId) {
return document.select(".discussion-item")
.stream()
.filter(this::isPullRequest)
.filter(this::isMerged)
- .map(this::resolvePullRequestNumber)
- .map(pullRequestNumber -> fetchAuthorFromPullRequest(pullRequestNumber, owner, repo))
+ .map(this::resolvePullRequestGithubId)
+ .map(pullRequestGithubId -> fetchAuthorFromPullRequest(pullRequestGithubId, issueGithubId))
+ .filter(Optional::isPresent)
+ .map(Optional::get)
.filter(StringUtils::isNotEmpty)
- .findFirst()
- .orElse(null);
+ .findFirst();
}
- private String resolvePullRequestNumber(final Element discussionItem) {
- final String pullRequestNumber;
+ private GithubId resolvePullRequestGithubId(final Element discussionItem) {
if (isPullRequestInSingleDiscussionItem(discussionItem)) {
- pullRequestNumber = getPullRequestNumberFromSingleDiscussionItem(discussionItem);
+ return getPullRequestGithubIdFromSingleDiscussionItem(discussionItem);
} else {
- pullRequestNumber = getPullRequestNumberFromInlineDiscussionItem(discussionItem);
+ return getPullRequestGithubIdFromInlineDiscussionItem(discussionItem);
}
- return pullRequestNumber.replace("#", "");
}
- private String getPullRequestNumberFromSingleDiscussionItem(final Element discussionItem) {
- return discussionItem.select(".discussion-item [id^=ref-pullrequest-] ~ .discussion-item-ref-title span.issue-num").text();
+ private GithubId getPullRequestGithubIdFromSingleDiscussionItem(final Element discussionItem) {
+ return GithubId.fromString(discussionItem.select(".discussion-item [id^=ref-pullrequest-] ~ .discussion-item-ref-title a").attr("href"))
+ .orElseThrow(() -> new RuntimeException("No pullrequest identifier is found"));
+ }
+
+ private GithubId getPullRequestGithubIdFromInlineDiscussionItem(final Element discussionItem) {
+ return GithubId.fromString(discussionItem.select(".discussion-item [id^=ref-pullrequest-] a").attr("href"))
+ .orElseThrow(() -> new RuntimeException("No pullrequest identifier is found"));
}
- private String getPullRequestNumberFromInlineDiscussionItem(final Element discussionItem) {
- return discussionItem.select(".discussion-item [id^=ref-pullrequest-] span.issue-num").text();
+ private Optional fetchAuthorFromPullRequest(final GithubId pullRequestGithubId, final GithubId issueGithubId) {
+ final GithubResult pullRequest = githubGateway.getPullrequest(pullRequestGithubId.getOwner(), pullRequestGithubId.getRepo(), pullRequestGithubId.getNumber());
+ if (pullRequest != null && pullRequestFixesIssue(pullRequest, issueGithubId)) {
+ return Optional.of(pullRequest.getUser().getLogin());
+ }
+ return Optional.empty();
}
- private String fetchAuthorFromPullRequest(final String pullRequestNumber, final String owner, final String repo) {
- final GithubResult pullRequest = githubGateway.getPullrequest(owner, repo, pullRequestNumber);
- return pullRequest.getUser().getLogin();
+ private boolean pullRequestFixesIssue(final GithubResult pullRequest, final GithubId issueGithubId) {
+ final String pullRequestBody = pullRequest.getBody();
+
+ return pullRequestBody != null && CLOSING_KEYWORDS.stream()
+ .anyMatch(keyword -> Pattern.compile("\\b" + keyword.toLowerCase() + "\\b:?\\s*#" + issueGithubId.getNumber())
+ .matcher(pullRequestBody.toLowerCase())
+ .find());
}
private boolean isPullRequestInSingleDiscussionItem(final Element discussionItem) {
diff --git a/github/src/main/java/io/fundrequest/platform/github/scraper/model/GithubId.java b/github/src/main/java/io/fundrequest/platform/github/scraper/model/GithubId.java
new file mode 100644
index 000000000..0c6c920ef
--- /dev/null
+++ b/github/src/main/java/io/fundrequest/platform/github/scraper/model/GithubId.java
@@ -0,0 +1,32 @@
+package io.fundrequest.platform.github.scraper.model;
+
+import lombok.Builder;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+
+import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Getter
+@Builder
+@EqualsAndHashCode
+public class GithubId {
+
+ private final String owner;
+ private final String repo;
+ private final String number;
+
+ public static Optional fromString(final String githubIdAsString) {
+ final Pattern pattern = Pattern.compile("^.*?/?(?.+)/(?.+)/.+/(?\\d+)$");
+ final Matcher matcher = pattern.matcher(githubIdAsString);
+ if (matcher.matches()) {
+ return Optional.of(GithubId.builder()
+ .owner(matcher.group("owner"))
+ .repo(matcher.group("repo"))
+ .number(matcher.group("number"))
+ .build());
+ }
+ return Optional.empty();
+ }
+}
diff --git a/github/src/test/java/io/fundrequest/platform/github/scraper/DocumentMockBuilder.java b/github/src/test/java/io/fundrequest/platform/github/scraper/DocumentMockBuilder.java
index ac6777594..0ab515560 100644
--- a/github/src/test/java/io/fundrequest/platform/github/scraper/DocumentMockBuilder.java
+++ b/github/src/test/java/io/fundrequest/platform/github/scraper/DocumentMockBuilder.java
@@ -1,5 +1,6 @@
package io.fundrequest.platform.github.scraper;
+import io.fundrequest.platform.github.scraper.model.GithubId;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
@@ -7,6 +8,7 @@
import java.util.ArrayList;
import java.util.List;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -41,7 +43,7 @@ public static class DiscussionItemBuilder {
private final Element element;
private DiscussionItemBuilder() {
- this.element = mock(Element.class);
+ this.element = mock(Element.class, RETURNS_DEEP_STUBS);
}
public static DiscussionItemBuilder builder() {
@@ -69,19 +71,17 @@ public DiscussionItemBuilder withAuthor(final String author) {
return this;
}
- public DiscussionItemBuilder withIssueNum(final int issueNum, final boolean isInlinePullRequest) {
+ public DiscussionItemBuilder withPullrequestReference(final GithubId githubId, final boolean isInlinePullRequest) {
final Elements pullRequestElements = mock(Elements.class);
- final Elements pullRequestIssueNumElements = mock(Elements.class);
when(pullRequestElements.isEmpty()).thenReturn(!isInlinePullRequest);
when(element.select(".discussion-item .discussion-item-rollup-ref [id^=ref-pullrequest-]")).thenReturn(pullRequestElements);
+ final String githubIssueId = String.format("/%s/%s/pulls/%s", githubId.getOwner(), githubId.getRepo(), githubId.getNumber());
if (isInlinePullRequest) {
- when(pullRequestIssueNumElements.text()).thenReturn("#" + String.valueOf(issueNum));
- when(element.select(".discussion-item [id^=ref-pullrequest-] span.issue-num")).thenReturn(pullRequestIssueNumElements);
+ when(element.select(".discussion-item [id^=ref-pullrequest-] a").attr("href")).thenReturn(githubIssueId);
} else {
- when(pullRequestIssueNumElements.text()).thenReturn("#" + String.valueOf(issueNum));
- when(element.select(".discussion-item [id^=ref-pullrequest-] ~ .discussion-item-ref-title span.issue-num")).thenReturn(pullRequestIssueNumElements);
+ when(element.select(".discussion-item [id^=ref-pullrequest-] ~ .discussion-item-ref-title a").attr("href")).thenReturn(githubIssueId);
}
return this;
}
diff --git a/github/src/test/java/io/fundrequest/platform/github/scraper/GithubScraperIntegrationTest.java b/github/src/test/java/io/fundrequest/platform/github/scraper/GithubScraperIntegrationTest.java
index 5765c8b47..ad8d1aee6 100644
--- a/github/src/test/java/io/fundrequest/platform/github/scraper/GithubScraperIntegrationTest.java
+++ b/github/src/test/java/io/fundrequest/platform/github/scraper/GithubScraperIntegrationTest.java
@@ -54,8 +54,7 @@ public void fetch_parsesCorrectSolver_whenReferencerInIssueIsNotOwnerPullRequest
assertThat(githubIssue.getNumber()).isEqualTo("48");
assertThat(githubIssue.getSolver()).isEqualTo("pauliax");
- //TODO Uncomment when issue https://github.com/FundRequest/contracts/issues/48 is closed.
- // assertThat(githubIssue.getStatus()).isEqualTo("Closed");
+ assertThat(githubIssue.getStatus()).isEqualTo("Closed");
}
@Test
@@ -70,4 +69,43 @@ public void fetch_whenNoSolver() {
assertThat(githubIssue.getSolver()).isNull();
assertThat(githubIssue.getStatus()).isEqualTo("Closed");
}
+
+ @Test
+ public void fetch_issueRandomlyReferencedInPullRequestFromSameRepo() {
+ final String owner = "aragon";
+ final String repo = "aragonOS";
+ final String number = "280";
+
+ final GithubIssue githubIssue = scraper.fetchGithubIssue(owner, repo, number);
+
+ assertThat(githubIssue.getNumber()).isEqualTo("280");
+ assertThat(githubIssue.getSolver()).isNull();
+ assertThat(githubIssue.getStatus()).isEqualTo("Open");
+ }
+
+ @Test
+ public void fetch_issueRandomlyReferencedInPullRequestFromOtherRepo() {
+ final String owner = "trufflesuite";
+ final String repo = "truffle";
+ final String number = "501";
+
+ final GithubIssue githubIssue = scraper.fetchGithubIssue(owner, repo, number);
+
+ assertThat(githubIssue.getNumber()).isEqualTo("501");
+ assertThat(githubIssue.getSolver()).isNull();
+ assertThat(githubIssue.getStatus()).isEqualTo("Open");
+ }
+
+ @Test
+ public void fetch_() {
+ final String owner = "FundRequest";
+ final String repo = "contracts";
+ final String number = "50";
+
+ final GithubIssue githubIssue = scraper.fetchGithubIssue(owner, repo, number);
+
+ assertThat(githubIssue.getNumber()).isEqualTo("50");
+ assertThat(githubIssue.getSolver()).isEqualTo("thomasvds");
+ assertThat(githubIssue.getStatus()).isEqualTo("Closed");
+ }
}
diff --git a/github/src/test/java/io/fundrequest/platform/github/scraper/GithubScraperTest.java b/github/src/test/java/io/fundrequest/platform/github/scraper/GithubScraperTest.java
index ce63c688d..bbe89d15f 100644
--- a/github/src/test/java/io/fundrequest/platform/github/scraper/GithubScraperTest.java
+++ b/github/src/test/java/io/fundrequest/platform/github/scraper/GithubScraperTest.java
@@ -2,12 +2,14 @@
import io.fundrequest.common.infrastructure.JsoupSpringWrapper;
+import io.fundrequest.platform.github.scraper.model.GithubId;
import io.fundrequest.platform.github.scraper.model.GithubIssue;
import org.jsoup.nodes.Document;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
+import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -39,7 +41,7 @@ public void fetchGithubIssue() throws IOException {
final Document document = mock(Document.class);
when(jsoup.connect("https://github.com/" + owner + "/" + repo + "/issues/" + number).get()).thenReturn(document);
- when(solverParser.resolve(document, owner, repo)).thenReturn(expectedSolver);
+ when(solverParser.resolve(document, GithubId.builder().owner(owner).repo(repo).number(number).build())).thenReturn(Optional.of(expectedSolver));
when(statusParser.resolve(document)).thenReturn(expectedStatus);
final GithubIssue returnedIssue = scraper.fetchGithubIssue(owner, repo, number);
diff --git a/github/src/test/java/io/fundrequest/platform/github/scraper/GithubSolverResolverTest.java b/github/src/test/java/io/fundrequest/platform/github/scraper/GithubSolverResolverTest.java
index 7688caac6..c595d7322 100644
--- a/github/src/test/java/io/fundrequest/platform/github/scraper/GithubSolverResolverTest.java
+++ b/github/src/test/java/io/fundrequest/platform/github/scraper/GithubSolverResolverTest.java
@@ -3,31 +3,36 @@
import io.fundrequest.platform.github.GithubGateway;
import io.fundrequest.platform.github.parser.GithubResult;
import io.fundrequest.platform.github.parser.GithubUser;
+import io.fundrequest.platform.github.scraper.model.GithubId;
import org.jsoup.nodes.Document;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-public class GithubSolverResolverTest {
+class GithubSolverResolverTest {
private GithubSolverResolver parser;
private GithubGateway githubGateway;
- @Before
- public void setUp() {
+ @BeforeEach
+ void setUp() {
githubGateway = mock(GithubGateway.class);
parser = new GithubSolverResolver(githubGateway);
}
@Test
- public void parse() {
- final String owner = "tfjgk";
- final String repo = "hfcjgv";
+ void parse() {
final String solver = "dfgh";
- final int pullrequestNumber = 765;
+ final GithubUser solverUser = GithubUser.builder().login(solver).build();
+ final GithubId issueGithubId = GithubId.builder().owner("tfjgk").repo("hfcjgv").number("435").build();
+ final GithubId pullrequestGithubId = GithubId.builder().owner("gb").repo("awerg").number("765").build();
final Document doc = DocumentMockBuilder.documentBuilder()
.addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
.isPullRequest(false)
@@ -36,31 +41,36 @@ public void parse() {
.isPullRequest(true)
.isMerged(false)
.withAuthor("hgfcjgv")
- .withIssueNum(53, false)
+ .withPullrequestReference(GithubId.builder().owner("xnbf").repo("afds").number("53").build(), false)
.build())
.addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
.isPullRequest(true)
.isMerged(true)
.withAuthor("gdhfh")
- .withIssueNum(pullrequestNumber, false)
+ .withPullrequestReference(pullrequestGithubId, false)
.build())
.build();
- when(githubGateway.getPullrequest(owner, repo, String.valueOf(pullrequestNumber))).thenReturn(GithubResult.builder()
- .user(GithubUser.builder().login(solver).build())
- .build());
+ when(githubGateway.getPullrequest("xnbf", "afds", "53")).thenReturn(GithubResult.builder()
+ .user(GithubUser.builder().login("hgfcjgv").build())
+ .body("fixes #" + issueGithubId.getNumber())
+ .build());
+ when(githubGateway.getPullrequest(pullrequestGithubId.getOwner(), pullrequestGithubId.getRepo(), pullrequestGithubId.getNumber())).thenReturn(GithubResult.builder()
+ .user(solverUser)
+ .body("Fixes #" + issueGithubId.getNumber())
+ .build());
- final String returnedSolver = parser.resolve(doc, owner, repo);
+ final Optional result = parser.resolve(doc, issueGithubId);
- assertThat(returnedSolver).isEqualTo(solver);
+ assertThat(result).contains(solver);
}
@Test
- public void parse_pullRequestMerged_noSolverOnPage() {
- final String owner = "tfjgk";
- final String repo = "hfcjgv";
+ void parse_pullRequestMerged_noSolverOnPage() {
final String solver = "dfgh";
- final int pullrequestNumber = 765;
+ final GithubUser solverUser = GithubUser.builder().login(solver).build();
+ final GithubId issueGithubId = GithubId.builder().owner("tfjgk").repo("hfcjgv").number("435").build();
+ final GithubId pullrequestGithubId = GithubId.builder().owner("gb").repo("awerg").number("765").build();
final Document doc = DocumentMockBuilder.documentBuilder()
.addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
.isPullRequest(false)
@@ -69,39 +79,41 @@ public void parse_pullRequestMerged_noSolverOnPage() {
.isPullRequest(true)
.isMerged(false)
.withAuthor("hgfcjgv")
- .withIssueNum(53, false)
+ .withPullrequestReference(GithubId.builder().owner("xnbf").repo("afds").number("53").build(), false)
.build())
.addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
.isPullRequest(true)
.isMerged(true)
.withAuthor("")
- .withIssueNum(pullrequestNumber, true)
+ .withPullrequestReference(pullrequestGithubId, false)
.build())
.build();
- when(githubGateway.getPullrequest(owner, repo, String.valueOf(pullrequestNumber))).thenReturn(GithubResult.builder()
- .user(GithubUser.builder().login(solver).build())
- .build());
-
- final String returnedSolver = parser.resolve(doc, owner, repo);
+ when(githubGateway.getPullrequest("xnbf", "afds", "53")).thenReturn(GithubResult.builder()
+ .user(GithubUser.builder().login("hgfcjgv").build())
+ .body("fixes #" + issueGithubId.getNumber())
+ .build());
+ when(githubGateway.getPullrequest(pullrequestGithubId.getOwner(), pullrequestGithubId.getRepo(), pullrequestGithubId.getNumber())).thenReturn(GithubResult.builder()
+ .user(solverUser)
+ .body("fixes #" + issueGithubId.getNumber())
+ .build());
+ final Optional result = parser.resolve(doc, issueGithubId);
- assertThat(returnedSolver).isEqualTo(solver);
+ assertThat(result).contains(solver);
}
@Test
- public void parse_noDiscussionItems() {
- final String owner = "tfjgk";
- final String repo = "hfcjgv";
+ void parse_noDiscussionItems() {
+ final GithubId issueGithubId = GithubId.builder().owner("tfjgk").repo("hfcjgv").number("35").build();
final Document doc = DocumentMockBuilder.documentBuilder().build();
- final String returnedSolver = parser.resolve(doc, owner, repo);
+ final Optional result = parser.resolve(doc, issueGithubId);
- assertThat(returnedSolver).isNull();
+ assertThat(result).isEmpty();
}
@Test
- public void parse_noPullRequest() {
- final String owner = "tfjgk";
- final String repo = "hfcjgv";
+ void parse_noPullRequest() {
+ final GithubId issueGithubId = GithubId.builder().owner("tfjgk").repo("hfcjgv").number("35").build();
final Document doc = DocumentMockBuilder.documentBuilder()
.addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
.isPullRequest(false)
@@ -111,34 +123,33 @@ public void parse_noPullRequest() {
.build())
.build();
- final String returnedSolver = parser.resolve(doc, owner, repo);
+ final Optional result = parser.resolve(doc, issueGithubId);
- assertThat(returnedSolver).isNull();;
+ assertThat(result).isEmpty();
}
@Test
- public void parse_noMergedPullRequest() {
- final String owner = "tfjgk";
- final String repo = "hfcjgv";
+ void parse_noMergedPullRequest() {
+ final GithubId issueGithubId = GithubId.builder().owner("tfjgk").repo("hfcjgv").number("35").build();
+ final GithubId pullrequestGithubId = GithubId.builder().owner("gb").repo("awerg").number("765").build();
final Document doc = DocumentMockBuilder.documentBuilder()
.addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
.isPullRequest(true)
- .withIssueNum(53, false)
+ .withPullrequestReference(pullrequestGithubId, false)
.isMerged(false)
.withAuthor("hgfcjgv")
.build())
.build();
- final String returnedSolver = parser.resolve(doc, owner, repo);
+ final Optional result = parser.resolve(doc, issueGithubId);
- assertThat(returnedSolver).isNull();
+ assertThat(result).isEmpty();
}
@Test
- public void parse_noSolver() {
- final String owner = "tfjgk";
- final String repo = "hfcjgv";
- final int pullrequestNumber = 43;
+ void parse_noSolver() {
+ final GithubId issueGithubId = GithubId.builder().owner("tfjgk").repo("hfcjgv").number("35").build();
+ final GithubId pullrequestGithubId = GithubId.builder().owner("gb").repo("awerg").number("765").build();
final Document doc = DocumentMockBuilder.documentBuilder()
.addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
.isPullRequest(false)
@@ -146,22 +157,142 @@ public void parse_noSolver() {
.addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
.isPullRequest(true)
.isMerged(false)
- .withIssueNum(31, false)
+ .withPullrequestReference(GithubId.builder().owner("xnbf").repo("afds").number("53").build(), false)
.withAuthor("ljhkgfdy")
.build())
.addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
.isPullRequest(true)
.isMerged(true)
.withAuthor("")
- .withIssueNum(pullrequestNumber, true)
+ .withPullrequestReference(pullrequestGithubId, true)
+ .build())
+ .build();
+ when(githubGateway.getPullrequest(pullrequestGithubId.getOwner(), pullrequestGithubId.getRepo(), pullrequestGithubId.getNumber())).thenReturn(GithubResult.builder()
+ .user(GithubUser.builder().login("").build())
+ .body("fixes #" + issueGithubId.getNumber())
+ .build());
+
+ final Optional result = parser.resolve(doc, issueGithubId);
+
+ assertThat(result).isEmpty();
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"close ", "closes ", "closed ", "fix ", "fixes ", "fixed ", "resolve ", "resolves ", "resolved ", "close: ", "closes: ", "closed: ", "fix: ", "fixes: ", "fixed: ", "resolve: ",
+ "resolves: ", "resolved: ", "close:", "closes:", "closed:", "fix:", "fixes:", "fixed:", "resolve:",
+ "resolves:", "resolved:", "Close ", "Closes ", "Closed ", "Fix ", "Fixes ", "Fixed ", "Resolve ", "Resolves ", "Resolved", "close: ", "closes: "})
+ void parse_withClosingKeywords(final String keyword) {
+ final String solver = "dfgh";
+ final GithubUser solverUser = GithubUser.builder().login(solver).build();
+ final GithubId issueGithubId = GithubId.builder().owner("tfjgk").repo("hfcjgv").number("435").build();
+ final GithubId pullrequestGithubId = GithubId.builder().owner("gb").repo("awerg").number("765").build();
+ final Document doc = DocumentMockBuilder.documentBuilder()
+ .addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
+ .isPullRequest(false)
+ .build())
+ .addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
+ .isPullRequest(true)
+ .isMerged(false)
+ .withAuthor("hgfcjgv")
+ .withPullrequestReference(GithubId.builder().owner("xnbf").repo("afds").number("53").build(), false)
+ .build())
+ .addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
+ .isPullRequest(true)
+ .isMerged(true)
+ .withAuthor("gdhfh")
+ .withPullrequestReference(pullrequestGithubId, false)
.build())
.build();
- when(githubGateway.getPullrequest(owner, repo, String.valueOf(pullrequestNumber))).thenReturn(GithubResult.builder()
- .user(GithubUser.builder().login("").build())
- .build());
- final String returnedSolver = parser.resolve(doc, owner, repo);
+ when(githubGateway.getPullrequest("xnbf", "afds", "53")).thenReturn(GithubResult.builder()
+ .user(GithubUser.builder().login("hgfcjgv").build())
+ .body("fixes #" + issueGithubId.getNumber())
+ .build());
+ when(githubGateway.getPullrequest(pullrequestGithubId.getOwner(), pullrequestGithubId.getRepo(), pullrequestGithubId.getNumber())).thenReturn(GithubResult.builder()
+ .user(solverUser)
+ .body(String.format("%s#%s",
+ keyword,
+ issueGithubId.getNumber()))
+ .build());
+
+ final Optional result = parser.resolve(doc, issueGithubId);
+
+ assertThat(result).contains(solver);
+ }
+
+ @Test
+ void parse_noClosingKeyword() {
+ final String solver = "dfgh";
+ final GithubUser solverUser = GithubUser.builder().login(solver).build();
+ final GithubId issueGithubId = GithubId.builder().owner("tfjgk").repo("hfcjgv").number("435").build();
+ final GithubId pullrequestGithubId = GithubId.builder().owner("gb").repo("awerg").number("765").build();
+ final Document doc = DocumentMockBuilder.documentBuilder()
+ .addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
+ .isPullRequest(false)
+ .build())
+ .addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
+ .isPullRequest(true)
+ .isMerged(false)
+ .withAuthor("hgfcjgv")
+ .withPullrequestReference(GithubId.builder().owner("xnbf").repo("afds").number("53").build(), false)
+ .build())
+ .addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
+ .isPullRequest(true)
+ .isMerged(true)
+ .withAuthor("gdhfh")
+ .withPullrequestReference(pullrequestGithubId, false)
+ .build())
+ .build();
+
+ when(githubGateway.getPullrequest("xnbf", "afds", "53")).thenReturn(GithubResult.builder()
+ .user(GithubUser.builder().login("hgfcjgv").build())
+ .body("fixes #" + issueGithubId.getNumber())
+ .build());
+ when(githubGateway.getPullrequest(pullrequestGithubId.getOwner(), pullrequestGithubId.getRepo(), pullrequestGithubId.getNumber())).thenReturn(GithubResult.builder()
+ .user(solverUser)
+ .body("")
+ .build());
+
+ final Optional result = parser.resolve(doc, issueGithubId);
+
+ assertThat(result).isEmpty();
+ }
+
+ @Test
+ void parse_noClosingKeywordReferenceToIssue() {
+ final String solver = "dfgh";
+ final GithubUser solverUser = GithubUser.builder().login(solver).build();
+ final GithubId issueGithubId = GithubId.builder().owner("tfjgk").repo("hfcjgv").number("435").build();
+ final GithubId pullrequestGithubId = GithubId.builder().owner("gb").repo("awerg").number("765").build();
+ final Document doc = DocumentMockBuilder.documentBuilder()
+ .addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
+ .isPullRequest(false)
+ .build())
+ .addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
+ .isPullRequest(true)
+ .isMerged(false)
+ .withAuthor("hgfcjgv")
+ .withPullrequestReference(GithubId.builder().owner("xnbf").repo("afds").number("53").build(), false)
+ .build())
+ .addDiscussionItem(DocumentMockBuilder.discussionItemBuilder()
+ .isPullRequest(true)
+ .isMerged(true)
+ .withAuthor("gdhfh")
+ .withPullrequestReference(pullrequestGithubId, false)
+ .build())
+ .build();
+
+ when(githubGateway.getPullrequest("xnbf", "afds", "53")).thenReturn(GithubResult.builder()
+ .user(GithubUser.builder().login("hgfcjgv").build())
+ .body("fixes #" + issueGithubId.getNumber())
+ .build());
+ when(githubGateway.getPullrequest(pullrequestGithubId.getOwner(), pullrequestGithubId.getRepo(), pullrequestGithubId.getNumber())).thenReturn(GithubResult.builder()
+ .user(solverUser)
+ .body("#" + issueGithubId.getNumber())
+ .build());
+
+ final Optional result = parser.resolve(doc, issueGithubId);
- assertThat(returnedSolver).isNull();
+ assertThat(result).isEmpty();
}
}
diff --git a/github/src/test/java/io/fundrequest/platform/github/scraper/model/GithubIdTest.java b/github/src/test/java/io/fundrequest/platform/github/scraper/model/GithubIdTest.java
new file mode 100644
index 000000000..c53d307a9
--- /dev/null
+++ b/github/src/test/java/io/fundrequest/platform/github/scraper/model/GithubIdTest.java
@@ -0,0 +1,67 @@
+package io.fundrequest.platform.github.scraper.model;
+
+
+import org.junit.Test;
+
+import java.util.Optional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class GithubIdTest {
+
+ @Test
+ public void fromString_issue() {
+
+ final Optional resultOptional = GithubId.fromString("/FundRequest/area51/issues/38");
+
+ assertThat(resultOptional).isPresent();
+ final GithubId result = resultOptional.get();
+ assertThat(result.getOwner()).isEqualTo("FundRequest");
+ assertThat(result.getRepo()).isEqualTo("area51");
+ assertThat(result.getNumber()).isEqualTo("38");
+ }
+
+ @Test
+ public void fromString_issueFullURL() {
+
+ final Optional resultOptional = GithubId.fromString("https://github.com/trufflesuite/truffle/issues/501");
+
+ assertThat(resultOptional).isPresent();
+ final GithubId result = resultOptional.get();
+ assertThat(result.getOwner()).isEqualTo("trufflesuite");
+ assertThat(result.getRepo()).isEqualTo("truffle");
+ assertThat(result.getNumber()).isEqualTo("501");
+ }
+
+ @Test
+ public void fromString_pullrequest() {
+
+ final Optional resultOptional = GithubId.fromString("/smartcontractkit/chainlink/pull/276");
+
+ assertThat(resultOptional).isPresent();
+ final GithubId result = resultOptional.get();
+ assertThat(result.getOwner()).isEqualTo("smartcontractkit");
+ assertThat(result.getRepo()).isEqualTo("chainlink");
+ assertThat(result.getNumber()).isEqualTo("276");
+ }
+
+ @Test
+ public void fromString_pullrequestFullURL() {
+
+ final Optional resultOptional = GithubId.fromString("https://github.com/aragon/aragonOS/pull/204");
+
+ assertThat(resultOptional).isPresent();
+ final GithubId result = resultOptional.get();
+ assertThat(result.getOwner()).isEqualTo("aragon");
+ assertThat(result.getRepo()).isEqualTo("aragonOS");
+ assertThat(result.getNumber()).isEqualTo("204");
+ }
+
+ @Test
+ public void noMatchEmtpy() {
+
+ final Optional resultOptional = GithubId.fromString("/hfgdjfgk");
+
+ assertThat(resultOptional).isEmpty();
+ }
+}