diff --git a/src/main/java/com/rultor/agents/github/qtn/QnMerge.java b/src/main/java/com/rultor/agents/github/qtn/QnMerge.java index b8dc8cca6b..29ab0968a8 100644 --- a/src/main/java/com/rultor/agents/github/qtn/QnMerge.java +++ b/src/main/java/com/rultor/agents/github/qtn/QnMerge.java @@ -30,6 +30,7 @@ package com.rultor.agents.github.qtn; import com.jcabi.aspects.Immutable; +import com.jcabi.github.Check; import com.jcabi.github.Comment; import com.jcabi.github.Issue; import com.jcabi.github.Pull; @@ -72,21 +73,29 @@ public Req understand(final Comment.Smart comment, final Issue.Smart issue = new Issue.Smart(comment.issue()); final Req req; if (issue.isPull() && issue.isOpen()) { - new Answer(comment).post( - true, - String.format( - QnMerge.PHRASES.getString("QnMerge.start"), - home.toASCIIString() - ) - ); Logger.info( this, "merge request found in %s#%d, comment #%d", issue.repo().coordinates(), issue.number(), comment.number() ); - req = QnMerge.pack( - comment, - issue.repo().pulls().get(issue.number()) - ); + if (QnMerge.allChecksSuccessful(issue.pull())) { + new Answer(comment).post( + true, + String.format( + QnMerge.PHRASES.getString("QnMerge.start"), + home.toASCIIString() + ) + ); + req = QnMerge.pack( + comment, + issue.repo().pulls().get(issue.number()) + ); + } else { + new Answer(comment).post( + false, + QnMerge.PHRASES.getString("QnMerge.checks-are-failed") + ); + req = Req.EMPTY; + } } else { new Answer(comment).post( false, @@ -164,4 +173,22 @@ private static Req pack(final Comment.Smart comment, return req; } + /** + * Checks if all checks are successful. + * @param pull Pull + * @return True if all checks are successful + * @throws IOException If fails + */ + private static boolean allChecksSuccessful(final Pull pull) + throws IOException { + boolean result = true; + for (final Check check : pull.checks().all()) { + if (!check.successful()) { + result = false; + break; + } + } + return result; + } + } diff --git a/src/test/java/com/rultor/agents/github/qtn/QnMergeTest.java b/src/test/java/com/rultor/agents/github/qtn/QnMergeTest.java index 7fd22f187d..b2fe47c26d 100644 --- a/src/test/java/com/rultor/agents/github/qtn/QnMergeTest.java +++ b/src/test/java/com/rultor/agents/github/qtn/QnMergeTest.java @@ -29,13 +29,15 @@ */ package com.rultor.agents.github.qtn; +import com.jcabi.github.Check; import com.jcabi.github.Comment; import com.jcabi.github.Comments; +import com.jcabi.github.Pull; import com.jcabi.github.Repo; import com.jcabi.github.mock.MkBranches; +import com.jcabi.github.mock.MkChecks; import com.jcabi.github.mock.MkGithub; import com.jcabi.matchers.XhtmlMatchers; -import com.rultor.agents.github.Req; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -43,7 +45,6 @@ import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.xembly.Directives; import org.xembly.Xembler; @@ -75,6 +76,11 @@ final class QnMergeTest { */ private transient Comments comments; + /** + * Pull request. + */ + private transient Pull pull; + /** * Initial phase for all tests. * @throws IOException In case of error. @@ -87,18 +93,20 @@ public void setUp() throws IOException { final String base = "base"; branches.create(head, "abcdef4"); branches.create(base, "abcdef5"); + this.pull = repo.pulls().create("", head, base); this.comments = repo.issues() - .get(repo.pulls().create("", head, base).number()) + .get(this.pull.number()) .comments(); } /** * QnMerge can build a request. - * @throws Exception In case of error. + * + * @throws Exception In case of error */ @Test public void buildsRequest() throws Exception { - final String request = new Xembler(this.requestDirectives()).xml(); + final String request = new Xembler(this.mergeRequest()).xml(); MatcherAssert.assertThat( request, Matchers.allOf( @@ -129,37 +137,62 @@ public void buildsRequest() throws Exception { /** * QnMerge can not build a request because some GitHub checks * were failed. - * @throws Exception In case of error - * @todo #1237:90min We need to implement a verification logic - * for GitHub checks to determine whether they were completed - * correctly or not. If not, Rultor should not create a merge - * request and must display a comment to the user. Once the logic - * is implemented, we can enable that test. + * + * @throws IOException In case of I/O error + * @throws URISyntaxException In case of URI error */ @Test - @Disabled - public void stopsBecauseCiChecksFailed() throws Exception { - final String request = new Xembler(this.requestDirectives()).xml(); + public void stopsBecauseCiChecksFailed() + throws IOException, URISyntaxException { + final MkChecks checks = (MkChecks) this.pull.checks(); + checks.create(Check.Status.IN_PROGRESS, Check.Conclusion.SUCCESS); + this.mergeRequest(); MatcherAssert.assertThat( new Comment.Smart(this.comments.get(1)).body(), Matchers.is(QnMergeTest.COMMAND) ); MatcherAssert.assertThat( new Comment.Smart(this.comments.get(2)).body(), - Matchers.equalTo( + Matchers.containsString( QnMergeTest.PHRASES.getString("QnMerge.checks-are-failed") ) ); - MatcherAssert.assertThat(request, Matchers.equalTo(Req.EMPTY)); } /** - * Request directives. + * QnMerge can build a request because GitHub checks finished successfully. + * + * @throws IOException In case of I/O error + * @throws URISyntaxException In case of URI error + */ + @Test + public void continuesBecauseCiChecksSuccessful() + throws IOException, URISyntaxException { + final MkChecks checks = (MkChecks) this.pull.checks(); + checks.create(Check.Status.COMPLETED, Check.Conclusion.SUCCESS); + this.mergeRequest(); + MatcherAssert.assertThat( + new Comment.Smart(this.comments.get(1)).body(), + Matchers.is(QnMergeTest.COMMAND) + ); + MatcherAssert.assertThat( + new Comment.Smart(this.comments.get(2)).body(), + Matchers.containsString( + String.format( + QnMergeTest.PHRASES.getString("QnMerge.start"), + "#" + ) + ) + ); + } + + /** + * Merge request directives. * @return Directives * @throws IOException In case of error * @throws URISyntaxException In case of error */ - private Directives requestDirectives() throws IOException, + private Directives mergeRequest() throws IOException, URISyntaxException { return new Directives() .add("request")