< prev index next >

bots/mlbridge/src/test/java/org/openjdk/skara/bots/mlbridge/MailingListBridgeBotTests.java

Print this page

  94     void simpleArchive(TestInfo testInfo) throws IOException {
  95         try (var credentials = new HostCredentials(testInfo);
  96              var tempFolder = new TemporaryDirectory();
  97              var archiveFolder = new TemporaryDirectory();
  98              var webrevFolder = new TemporaryDirectory();
  99              var listServer = new TestMailmanServer()) {
 100             var author = credentials.getHostedRepository();
 101             var archive = credentials.getHostedRepository();
 102             var ignored = credentials.getHostedRepository();
 103             var listAddress = EmailAddress.parse(listServer.createList("test"));
 104             var censusBuilder = credentials.getCensusBuilder()
 105                                            .addAuthor(author.host().getCurrentUserDetails().id());
 106             var from = EmailAddress.from("test", "test@test.mail");
 107             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master", listAddress,
 108                                                  Set.of(ignored.host().getCurrentUserDetails().userName()),
 109                                                  Set.of(),
 110                                                  listServer.getArchive(), listServer.getSMTP(),
 111                                                  archive, "webrev", Path.of("test"),
 112                                                  URIBuilder.base("http://www.test.test/").build(),
 113                                                  Set.of("rfr"), Map.of(ignored.host().getCurrentUserDetails().userName(),
 114                                                                        Pattern.compile("ready")));

 115 
 116             // Populate the projects repository
 117             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType());
 118             var masterHash = localRepo.resolve("master").orElseThrow();
 119             localRepo.push(masterHash, author.getUrl(), "master", true);
 120             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 121 
 122             // Make a change with a corresponding PR
 123             var editHash = CheckableRepository.appendAndCommit(localRepo, "A simple change",
 124                                                                "Change msg\n\nWith several lines");
 125             localRepo.push(editHash, author.getUrl(), "edit", true);
 126             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 127             pr.setBody("This should not be ready");
 128 
 129             // Run an archive pass
 130             TestBotRunner.runPeriodicItems(mlBot);
 131 
 132             // A PR that isn't ready for review should not be archived
 133             Repository.materialize(archiveFolder.path(), archive.getUrl(), "master");
 134             assertFalse(archiveContains(archiveFolder.path(), "This is a pull request"));
 135 
 136             // Flag it as ready for review
 137             pr.setBody("This should now be ready");
 138             pr.addLabel("rfr");
 139 
 140             // Run another archive pass
 141             TestBotRunner.runPeriodicItems(mlBot);
 142 
 143             // But it should still not be archived
 144             Repository.materialize(archiveFolder.path(), archive.getUrl(), "master");
 145             assertFalse(archiveContains(archiveFolder.path(), "This is a pull request"));
 146 

 153 
 154             // It should still not be archived
 155             Repository.materialize(archiveFolder.path(), archive.getUrl(), "master");
 156             assertFalse(archiveContains(archiveFolder.path(), "This is a pull request"));
 157 
 158             // Now post a ready comment
 159             ignoredPr.addComment("ready");
 160 
 161             // Run another archive pass
 162             TestBotRunner.runPeriodicItems(mlBot);
 163 
 164             // The archive should now contain an entry
 165             Repository.materialize(archiveFolder.path(), archive.getUrl(), "master");
 166             assertTrue(archiveContains(archiveFolder.path(), "This is a pull request"));
 167             assertTrue(archiveContains(archiveFolder.path(), "This should now be ready"));
 168             assertTrue(archiveContains(archiveFolder.path(), "Patch:"));
 169             assertTrue(archiveContains(archiveFolder.path(), "Changes:"));
 170             assertTrue(archiveContains(archiveFolder.path(), "Webrev:"));
 171             assertTrue(archiveContains(archiveFolder.path(), "http://www.test.test/"));
 172             assertTrue(archiveContains(archiveFolder.path(), "webrev.00"));


 173             assertTrue(archiveContains(archiveFolder.path(), "Fetch:"));
 174             assertTrue(archiveContains(archiveFolder.path(), "^ - " + editHash.abbreviate() + ": Change msg"));
 175             assertFalse(archiveContains(archiveFolder.path(), "With several lines"));
 176 
 177             // The mailing list as well
 178             listServer.processIncoming();
 179             var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP());
 180             var mailmanList = mailmanServer.getList(listAddress.address());
 181             var conversations = mailmanList.conversations(Duration.ofDays(1));
 182             assertEquals(1, conversations.size());
 183             var mail = conversations.get(0).first();
 184             assertEquals("RFR: This is a pull request", mail.subject());
 185             assertEquals(pr.getAuthor().fullName(), mail.author().fullName().orElseThrow());
 186             assertEquals(noreplyAddress(archive), mail.author().address());
 187             assertEquals(from, mail.sender());
 188 
 189             // And there should be a webrev
 190             Repository.materialize(webrevFolder.path(), archive.getUrl(), "webrev");
 191             assertTrue(webrevContains(webrevFolder.path(), "1 lines changed"));
 192             var comments = pr.getComments();
 193             var webrevComments = comments.stream()
 194                                          .filter(comment -> comment.author().equals(author.host().getCurrentUserDetails()))
 195                                          .filter(comment -> comment.body().contains("webrev"))
 196                                          .filter(comment -> comment.body().contains(editHash.hex()))
 197                                          .collect(Collectors.toList());
 198             assertEquals(1, webrevComments.size());
 199 
 200             // Add a comment
 201             pr.addComment("This is a comment :smile:");
 202 
 203             // Add a comment from an ignored user as well
 204             ignoredPr.addComment("Don't mind me");

 243 
 244     @Test
 245     void reviewComment(TestInfo testInfo) throws IOException {
 246         try (var credentials = new HostCredentials(testInfo);
 247              var tempFolder = new TemporaryDirectory();
 248              var archiveFolder = new TemporaryDirectory();
 249              var listServer = new TestMailmanServer()) {
 250             var author = credentials.getHostedRepository();
 251             var archive = credentials.getHostedRepository();
 252             var ignored = credentials.getHostedRepository();
 253             var listAddress = EmailAddress.parse(listServer.createList("test"));
 254             var censusBuilder = credentials.getCensusBuilder()
 255                                            .addAuthor(author.host().getCurrentUserDetails().id());
 256             var from = EmailAddress.from("test", "test@test.mail");
 257             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master", listAddress,
 258                                                  Set.of(ignored.host().getCurrentUserDetails().userName()),
 259                                                  Set.of(),
 260                                                  listServer.getArchive(), listServer.getSMTP(),
 261                                                  archive, "webrev", Path.of("test"),
 262                                                  URIBuilder.base("http://www.test.test/").build(),
 263                                                  Set.of(), Map.of());

 264 
 265             // Populate the projects repository
 266             var reviewFile = Path.of("reviewfile.txt");
 267             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 268             var masterHash = localRepo.resolve("master").orElseThrow();
 269             localRepo.push(masterHash, author.getUrl(), "master", true);
 270             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 271 
 272             // Make a change with a corresponding PR
 273             var editHash = CheckableRepository.appendAndCommit(localRepo);
 274             localRepo.push(editHash, author.getUrl(), "edit", true);
 275             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 276             pr.setBody("This is now ready");
 277             TestBotRunner.runPeriodicItems(mlBot);
 278             listServer.processIncoming();
 279 
 280             // And make a file specific comment
 281             var currentMaster = localRepo.resolve("master").orElseThrow();
 282             var comment = pr.addReviewComment(masterHash, editHash, reviewFile.toString(), 2, "Review comment");
 283 

 329     }
 330 
 331     @Test
 332     void combineComments(TestInfo testInfo) throws IOException {
 333         try (var credentials = new HostCredentials(testInfo);
 334              var tempFolder = new TemporaryDirectory();
 335              var archiveFolder = new TemporaryDirectory();
 336              var listServer = new TestMailmanServer()) {
 337             var author = credentials.getHostedRepository();
 338             var archive = credentials.getHostedRepository();
 339             var listAddress = EmailAddress.parse(listServer.createList("test"));
 340             var censusBuilder = credentials.getCensusBuilder()
 341                                            .addAuthor(author.host().getCurrentUserDetails().id());
 342             var from = EmailAddress.from("test", "test@test.mail");
 343             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 344                                                  listAddress, Set.of(), Set.of(),
 345                                                  listServer.getArchive(),
 346                                                  listServer.getSMTP(),
 347                                                  archive, "webrev", Path.of("test"),
 348                                                  URIBuilder.base("http://www.test.test/").build(),
 349                                                  Set.of(), Map.of());

 350 
 351             // Populate the projects repository
 352             var reviewFile = Path.of("reviewfile.txt");
 353             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 354             var masterHash = localRepo.resolve("master").orElseThrow();
 355             localRepo.push(masterHash, author.getUrl(), "master", true);
 356             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 357 
 358             // Make a change with a corresponding PR
 359             var editHash = CheckableRepository.appendAndCommit(localRepo);
 360             localRepo.push(editHash, author.getUrl(), "edit", true);
 361             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 362             pr.setBody("This is now ready");
 363             pr.addComment("Avoid combining");
 364 
 365             TestBotRunner.runPeriodicItems(mlBot);
 366             listServer.processIncoming();
 367             listServer.processIncoming();
 368 
 369             // Make two file specific comments

 401     @Test
 402     void commentThreading(TestInfo testInfo) throws IOException {
 403         try (var credentials = new HostCredentials(testInfo);
 404              var tempFolder = new TemporaryDirectory();
 405              var archiveFolder = new TemporaryDirectory();
 406              var listServer = new TestMailmanServer()) {
 407             var author = credentials.getHostedRepository();
 408             var reviewer = credentials.getHostedRepository();
 409             var archive = credentials.getHostedRepository();
 410             var listAddress = EmailAddress.parse(listServer.createList("test"));
 411             var censusBuilder = credentials.getCensusBuilder()
 412                                            .addReviewer(reviewer.host().getCurrentUserDetails().id())
 413                                            .addAuthor(author.host().getCurrentUserDetails().id());
 414             var from = EmailAddress.from("test", "test@test.mail");
 415             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 416                                                  listAddress, Set.of(), Set.of(),
 417                                                  listServer.getArchive(),
 418                                                  listServer.getSMTP(),
 419                                                  archive, "webrev", Path.of("test"),
 420                                                  URIBuilder.base("http://www.test.test/").build(),
 421                                                  Set.of(), Map.of());

 422 
 423             // Populate the projects repository
 424             var reviewFile = Path.of("reviewfile.txt");
 425             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 426             var masterHash = localRepo.resolve("master").orElseThrow();
 427             localRepo.push(masterHash, author.getUrl(), "master", true);
 428             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 429 
 430             // Make a change with a corresponding PR
 431             var editHash = CheckableRepository.appendAndCommit(localRepo);
 432             localRepo.push(editHash, author.getUrl(), "edit", true);
 433             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 434             pr.setBody("This is now ready");
 435             TestBotRunner.runPeriodicItems(mlBot);
 436             listServer.processIncoming();
 437 
 438             // Make a file specific comment
 439             var reviewPr = reviewer.getPullRequest(pr.getId());
 440             var comment1 = reviewPr.addReviewComment(masterHash, editHash, reviewFile.toString(), 2, "Review comment");
 441             pr.addReviewCommentReply(comment1, "I agree");

 509     }
 510 
 511     @Test
 512     void reviewContext(TestInfo testInfo) throws IOException {
 513         try (var credentials = new HostCredentials(testInfo);
 514              var tempFolder = new TemporaryDirectory();
 515              var archiveFolder = new TemporaryDirectory();
 516              var listServer = new TestMailmanServer()) {
 517             var author = credentials.getHostedRepository();
 518             var archive = credentials.getHostedRepository();
 519             var listAddress = EmailAddress.parse(listServer.createList("test"));
 520             var censusBuilder = credentials.getCensusBuilder()
 521                                            .addAuthor(author.host().getCurrentUserDetails().id());
 522             var from = EmailAddress.from("test", "test@test.mail");
 523             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 524                                                  listAddress, Set.of(), Set.of(),
 525                                                  listServer.getArchive(),
 526                                                  listServer.getSMTP(),
 527                                                  archive, "webrev", Path.of("test"),
 528                                                  URIBuilder.base("http://www.test.test/").build(),
 529                                                  Set.of(), Map.of());

 530 
 531             // Populate the projects repository
 532             var reviewFile = Path.of("reviewfile.txt");
 533             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 534             var masterHash = localRepo.resolve("master").orElseThrow();
 535             localRepo.push(masterHash, author.getUrl(), "master", true);
 536             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 537 
 538             // Make a change with a corresponding PR
 539             var editHash = CheckableRepository.appendAndCommit(localRepo, "Line 1\nLine 2\nLine 3\nLine 4");
 540             localRepo.push(editHash, author.getUrl(), "edit", true);
 541             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 542             pr.setBody("This is now ready");
 543             TestBotRunner.runPeriodicItems(mlBot);
 544             listServer.processIncoming();
 545 
 546             // Make a file specific comment
 547             pr.addReviewComment(masterHash, editHash, reviewFile.toString(), 2, "Review comment");
 548 
 549             TestBotRunner.runPeriodicItems(mlBot);

 558     }
 559 
 560     @Test
 561     void multipleReviewContexts(TestInfo testInfo) throws IOException {
 562         try (var credentials = new HostCredentials(testInfo);
 563              var tempFolder = new TemporaryDirectory();
 564              var archiveFolder = new TemporaryDirectory();
 565              var listServer = new TestMailmanServer()) {
 566             var author = credentials.getHostedRepository();
 567             var archive = credentials.getHostedRepository();
 568             var listAddress = EmailAddress.parse(listServer.createList("test"));
 569             var censusBuilder = credentials.getCensusBuilder()
 570                                            .addAuthor(author.host().getCurrentUserDetails().id());
 571             var from = EmailAddress.from("test", "test@test.mail");
 572             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 573                                                  listAddress, Set.of(), Set.of(),
 574                                                  listServer.getArchive(),
 575                                                  listServer.getSMTP(),
 576                                                  archive, "webrev", Path.of("test"),
 577                                                  URIBuilder.base("http://www.test.test/").build(),
 578                                                  Set.of(), Map.of());

 579 
 580             // Populate the projects repository
 581             var reviewFile = Path.of("reviewfile.txt");
 582             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 583             var masterHash = localRepo.resolve("master").orElseThrow();
 584             localRepo.push(masterHash, author.getUrl(), "master", true);
 585             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 586             var initialHash = CheckableRepository.appendAndCommit(localRepo,
 587                                                                   "Line 0.1\nLine 0.2\nLine 0.3\nLine 0.4\n" +
 588                                                                           "Line 1\nLine 2\nLine 3\nLine 4\n" +
 589                                                                           "Line 5\nLine 6\nLine 7\nLine 8\n" +
 590                                                                           "Line 8.1\nLine 8.2\nLine 8.3\nLine 8.4\n" +
 591                                                                           "Line 9\nLine 10\nLine 11\nLine 12\n" +
 592                                                                           "Line 13\nLine 14\nLine 15\nLine 16\n");
 593             localRepo.push(initialHash, author.getUrl(), "master");
 594 
 595             // Make a change with a corresponding PR
 596             var current = Files.readString(localRepo.root().resolve(reviewFile), StandardCharsets.UTF_8);
 597             var updated = current.replaceAll("Line 2", "Line 2 edit\nLine 2.5");
 598             updated = updated.replaceAll("Line 13", "Line 12.5\nLine 13 edit");

 625         }
 626     }
 627 
 628     @Test
 629     void filterComments(TestInfo testInfo) throws IOException {
 630         try (var credentials = new HostCredentials(testInfo);
 631              var tempFolder = new TemporaryDirectory();
 632              var archiveFolder = new TemporaryDirectory();
 633              var listServer = new TestMailmanServer()) {
 634             var author = credentials.getHostedRepository();
 635             var archive = credentials.getHostedRepository();
 636             var listAddress = EmailAddress.parse(listServer.createList("test"));
 637             var censusBuilder = credentials.getCensusBuilder()
 638                                            .addAuthor(author.host().getCurrentUserDetails().id());
 639             var from = EmailAddress.from("test", "test@test.mail");
 640             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 641                                                  listAddress, Set.of(), Set.of(),
 642                                                  listServer.getArchive(), listServer.getSMTP(),
 643                                                  archive, "webrev", Path.of("test"),
 644                                                  URIBuilder.base("http://www.test.test/").build(),
 645                                                  Set.of(), Map.of());

 646 
 647             // Populate the projects repository
 648             var reviewFile = Path.of("reviewfile.txt");
 649             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 650             var masterHash = localRepo.resolve("master").orElseThrow();
 651             localRepo.push(masterHash, author.getUrl(), "master", true);
 652             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 653 
 654             // Make a change with a corresponding PR
 655             var editHash = CheckableRepository.appendAndCommit(localRepo);
 656             localRepo.push(editHash, author.getUrl(), "edit", true);
 657             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 658             pr.setBody("This is now ready\n<!-- this is a comment -->\nAnd this is not\n" +
 659                                "<!-- Anything below this marker will be hidden -->\nStatus stuff");
 660 
 661             // Make a bunch of comments
 662             pr.addComment("Plain comment\n<!-- this is a comment -->");
 663             pr.addReviewComment(masterHash, editHash, reviewFile.toString(), 2, "Review comment <!-- this is a comment -->\n");
 664             pr.addComment("/integrate stuff");
 665             TestBotRunner.runPeriodicItems(mlBot);

 682     }
 683 
 684     @Test
 685     void incrementalChanges(TestInfo testInfo) throws IOException {
 686         try (var credentials = new HostCredentials(testInfo);
 687              var tempFolder = new TemporaryDirectory();
 688              var archiveFolder = new TemporaryDirectory();
 689              var listServer = new TestMailmanServer()) {
 690             var author = credentials.getHostedRepository();
 691             var archive = credentials.getHostedRepository();
 692             var commenter = credentials.getHostedRepository();
 693             var listAddress = EmailAddress.parse(listServer.createList("test"));
 694             var censusBuilder = credentials.getCensusBuilder()
 695                                            .addAuthor(author.host().getCurrentUserDetails().id());
 696             var from = EmailAddress.from("test", "test@test.mail");
 697             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 698                                                  listAddress, Set.of(), Set.of(),
 699                                                  listServer.getArchive(), listServer.getSMTP(),
 700                                                  archive, "webrev", Path.of("test"),
 701                                                  URIBuilder.base("http://www.test.test/").build(),
 702                                                  Set.of(), Map.of());

 703 
 704             // Populate the projects repository
 705             var reviewFile = Path.of("reviewfile.txt");
 706             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 707             var masterHash = localRepo.resolve("master").orElseThrow();
 708             localRepo.push(masterHash, author.getUrl(), "master", true);
 709             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 710 
 711             // Make a change with a corresponding PR
 712             var editHash = CheckableRepository.appendAndCommit(localRepo);
 713             localRepo.push(editHash, author.getUrl(), "edit", true);
 714             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 715             pr.setBody("This is now ready");
 716 
 717             // Run an archive pass
 718             TestBotRunner.runPeriodicItems(mlBot);
 719             listServer.processIncoming();
 720 
 721             var nextHash = CheckableRepository.appendAndCommit(localRepo, "Yet one more line", "Fixing");
 722             localRepo.push(nextHash, author.getUrl(), "edit");

 801         }
 802     }
 803 
 804     @Test
 805     void rebased(TestInfo testInfo) throws IOException {
 806         try (var credentials = new HostCredentials(testInfo);
 807              var tempFolder = new TemporaryDirectory();
 808              var archiveFolder = new TemporaryDirectory();
 809              var listServer = new TestMailmanServer()) {
 810             var author = credentials.getHostedRepository();
 811             var archive = credentials.getHostedRepository();
 812             var listAddress = EmailAddress.parse(listServer.createList("test"));
 813             var censusBuilder = credentials.getCensusBuilder()
 814                                            .addAuthor(author.host().getCurrentUserDetails().id());
 815             var sender = EmailAddress.from("test", "test@test.mail");
 816             var mlBot = new MailingListBridgeBot(sender, author, archive, censusBuilder.build(), "master",
 817                                                  listAddress, Set.of(), Set.of(),
 818                                                  listServer.getArchive(), listServer.getSMTP(),
 819                                                  archive, "webrev", Path.of("test"),
 820                                                  URIBuilder.base("http://www.test.test/").build(),
 821                                                  Set.of(), Map.of());

 822 
 823             // Populate the projects repository
 824             var reviewFile = Path.of("reviewfile.txt");
 825             var localRepo = CheckableRepository.init(tempFolder.path().resolve("first"), author.getRepositoryType(), reviewFile);
 826             var masterHash = localRepo.resolve("master").orElseThrow();
 827             localRepo.push(masterHash, author.getUrl(), "master", true);
 828             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 829 
 830             // Make a change with a corresponding PR
 831             var editHash = CheckableRepository.appendAndCommit(localRepo, "A line", "Original msg");
 832             localRepo.push(editHash, author.getUrl(), "edit", true);
 833             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 834             pr.setBody("This is now ready");
 835 
 836             // Run an archive pass
 837             TestBotRunner.runPeriodicItems(mlBot);
 838             listServer.processIncoming();
 839 
 840             var newLocalRepo = Repository.materialize(tempFolder.path().resolve("second"), author.getUrl(), "master");
 841             var newEditHash = CheckableRepository.appendAndCommit(newLocalRepo, "Another line", "Replaced msg");

 892     void skipAddingExistingWebrev(TestInfo testInfo) throws IOException {
 893         try (var credentials = new HostCredentials(testInfo);
 894              var tempFolder = new TemporaryDirectory();
 895              var archiveFolder = new TemporaryDirectory();
 896              var webrevFolder = new TemporaryDirectory();
 897              var listServer = new TestMailmanServer()) {
 898             var author = credentials.getHostedRepository();
 899             var archive = credentials.getHostedRepository();
 900             var ignored = credentials.getHostedRepository();
 901             var listAddress = EmailAddress.parse(listServer.createList("test"));
 902             var censusBuilder = credentials.getCensusBuilder()
 903                                            .addAuthor(author.host().getCurrentUserDetails().id());
 904             var from = EmailAddress.from("test", "test@test.mail");
 905             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 906                                                  listAddress,
 907                                                  Set.of(ignored.host().getCurrentUserDetails().userName()),
 908                                                  Set.of(),
 909                                                  listServer.getArchive(), listServer.getSMTP(),
 910                                                  archive, "webrev", Path.of("test"),
 911                                                  URIBuilder.base("http://www.test.test/").build(),
 912                                                  Set.of(), Map.of());

 913 
 914             // Populate the projects repository
 915             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType());
 916             var masterHash = localRepo.resolve("master").orElseThrow();
 917             localRepo.push(masterHash, author.getUrl(), "master", true);
 918             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 919 
 920             // Make a change with a corresponding PR
 921             var editHash = CheckableRepository.appendAndCommit(localRepo, "A simple change",
 922                                                                "Change msg\n\nWith several lines");
 923             localRepo.push(editHash, author.getUrl(), "edit", true);
 924             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 925 
 926             // Flag it as ready for review
 927             pr.setBody("This should now be ready");
 928 
 929             // Run an archive pass
 930             TestBotRunner.runPeriodicItems(mlBot);
 931 
 932             // The archive should now contain an entry

 963 
 964     @Test
 965     void notifyReviewVerdicts(TestInfo testInfo) throws IOException {
 966         try (var credentials = new HostCredentials(testInfo);
 967              var tempFolder = new TemporaryDirectory();
 968              var archiveFolder = new TemporaryDirectory();
 969              var listServer = new TestMailmanServer()) {
 970             var author = credentials.getHostedRepository();
 971             var archive = credentials.getHostedRepository();
 972             var reviewer = credentials.getHostedRepository();
 973             var listAddress = EmailAddress.parse(listServer.createList("test"));
 974             var from = EmailAddress.from("test", "test@test.mail");
 975             var censusBuilder = credentials.getCensusBuilder()
 976                                            .addReviewer(reviewer.host().getCurrentUserDetails().id())
 977                                            .addAuthor(author.host().getCurrentUserDetails().id());
 978             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 979                                                  listAddress, Set.of(), Set.of(),
 980                                                  listServer.getArchive(), listServer.getSMTP(),
 981                                                  archive, "webrev", Path.of("test"),
 982                                                  URIBuilder.base("http://www.test.test/").build(),
 983                                                  Set.of(), Map.of());

 984 
 985             // Populate the projects repository
 986             var reviewFile = Path.of("reviewfile.txt");
 987             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 988             var masterHash = localRepo.resolve("master").orElseThrow();
 989             localRepo.push(masterHash, author.getUrl(), "master", true);
 990             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 991 
 992             // Make a change with a corresponding PR
 993             var editHash = CheckableRepository.appendAndCommit(localRepo);
 994             localRepo.push(editHash, author.getUrl(), "edit", true);
 995             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 996             pr.setBody("This is now ready");
 997 
 998             // Run an archive pass
 999             TestBotRunner.runPeriodicItems(mlBot);
1000 
1001             // First unapprove it
1002             var reviewedPr = reviewer.getPullRequest(pr.getId());
1003             reviewedPr.addReview(Review.Verdict.DISAPPROVED, "Reason 1");

1045     @Test
1046     void ignoreComments(TestInfo testInfo) throws IOException {
1047         try (var credentials = new HostCredentials(testInfo);
1048              var tempFolder = new TemporaryDirectory();
1049              var archiveFolder = new TemporaryDirectory();
1050              var listServer = new TestMailmanServer()) {
1051             var author = credentials.getHostedRepository();
1052             var ignored = credentials.getHostedRepository();
1053             var archive = credentials.getHostedRepository();
1054             var listAddress = EmailAddress.parse(listServer.createList("test"));
1055             var censusBuilder = credentials.getCensusBuilder()
1056                                            .addAuthor(author.host().getCurrentUserDetails().id());
1057             var from = EmailAddress.from("test", "test@test.mail");
1058             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
1059                                                  listAddress,
1060                                                  Set.of(ignored.host().getCurrentUserDetails().userName()),
1061                                                  Set.of(Pattern.compile("ignore this comment", Pattern.MULTILINE | Pattern.DOTALL)),
1062                                                  listServer.getArchive(), listServer.getSMTP(),
1063                                                  archive, "webrev", Path.of("test"),
1064                                                  URIBuilder.base("http://www.test.test/").build(),
1065                                                  Set.of(), Map.of());

1066 
1067             // Populate the projects repository
1068             var reviewFile = Path.of("reviewfile.txt");
1069             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
1070             var masterHash = localRepo.resolve("master").orElseThrow();
1071             localRepo.push(masterHash, author.getUrl(), "master", true);
1072             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
1073 
1074             // Make a change with a corresponding PR
1075             var editHash = CheckableRepository.appendAndCommit(localRepo);
1076             localRepo.push(editHash, author.getUrl(), "edit", true);
1077             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
1078             pr.setBody("This is now ready");
1079 
1080             // Make a bunch of comments
1081             pr.addComment("Plain comment");
1082             pr.addComment("ignore this comment");
1083             pr.addComment("I think it is time to\nignore this comment!");
1084             pr.addReviewComment(masterHash, editHash, reviewFile.toString(), 2, "Review ignore this comment");
1085 

  94     void simpleArchive(TestInfo testInfo) throws IOException {
  95         try (var credentials = new HostCredentials(testInfo);
  96              var tempFolder = new TemporaryDirectory();
  97              var archiveFolder = new TemporaryDirectory();
  98              var webrevFolder = new TemporaryDirectory();
  99              var listServer = new TestMailmanServer()) {
 100             var author = credentials.getHostedRepository();
 101             var archive = credentials.getHostedRepository();
 102             var ignored = credentials.getHostedRepository();
 103             var listAddress = EmailAddress.parse(listServer.createList("test"));
 104             var censusBuilder = credentials.getCensusBuilder()
 105                                            .addAuthor(author.host().getCurrentUserDetails().id());
 106             var from = EmailAddress.from("test", "test@test.mail");
 107             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master", listAddress,
 108                                                  Set.of(ignored.host().getCurrentUserDetails().userName()),
 109                                                  Set.of(),
 110                                                  listServer.getArchive(), listServer.getSMTP(),
 111                                                  archive, "webrev", Path.of("test"),
 112                                                  URIBuilder.base("http://www.test.test/").build(),
 113                                                  Set.of("rfr"), Map.of(ignored.host().getCurrentUserDetails().userName(),
 114                                                                        Pattern.compile("ready")),
 115                                                  URIBuilder.base("http://issues.test/browse/").build());
 116 
 117             // Populate the projects repository
 118             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType());
 119             var masterHash = localRepo.resolve("master").orElseThrow();
 120             localRepo.push(masterHash, author.getUrl(), "master", true);
 121             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 122 
 123             // Make a change with a corresponding PR
 124             var editHash = CheckableRepository.appendAndCommit(localRepo, "A simple change",
 125                                                                "Change msg\n\nWith several lines");
 126             localRepo.push(editHash, author.getUrl(), "edit", true);
 127             var pr = credentials.createPullRequest(archive, "master", "edit", "1234: This is a pull request");
 128             pr.setBody("This should not be ready");
 129 
 130             // Run an archive pass
 131             TestBotRunner.runPeriodicItems(mlBot);
 132 
 133             // A PR that isn't ready for review should not be archived
 134             Repository.materialize(archiveFolder.path(), archive.getUrl(), "master");
 135             assertFalse(archiveContains(archiveFolder.path(), "This is a pull request"));
 136 
 137             // Flag it as ready for review
 138             pr.setBody("This should now be ready");
 139             pr.addLabel("rfr");
 140 
 141             // Run another archive pass
 142             TestBotRunner.runPeriodicItems(mlBot);
 143 
 144             // But it should still not be archived
 145             Repository.materialize(archiveFolder.path(), archive.getUrl(), "master");
 146             assertFalse(archiveContains(archiveFolder.path(), "This is a pull request"));
 147 

 154 
 155             // It should still not be archived
 156             Repository.materialize(archiveFolder.path(), archive.getUrl(), "master");
 157             assertFalse(archiveContains(archiveFolder.path(), "This is a pull request"));
 158 
 159             // Now post a ready comment
 160             ignoredPr.addComment("ready");
 161 
 162             // Run another archive pass
 163             TestBotRunner.runPeriodicItems(mlBot);
 164 
 165             // The archive should now contain an entry
 166             Repository.materialize(archiveFolder.path(), archive.getUrl(), "master");
 167             assertTrue(archiveContains(archiveFolder.path(), "This is a pull request"));
 168             assertTrue(archiveContains(archiveFolder.path(), "This should now be ready"));
 169             assertTrue(archiveContains(archiveFolder.path(), "Patch:"));
 170             assertTrue(archiveContains(archiveFolder.path(), "Changes:"));
 171             assertTrue(archiveContains(archiveFolder.path(), "Webrev:"));
 172             assertTrue(archiveContains(archiveFolder.path(), "http://www.test.test/"));
 173             assertTrue(archiveContains(archiveFolder.path(), "webrev.00"));
 174             assertTrue(archiveContains(archiveFolder.path(), "Issue:"));
 175             assertTrue(archiveContains(archiveFolder.path(), "http://issues.test/browse/TSTPRJ-1234"));
 176             assertTrue(archiveContains(archiveFolder.path(), "Fetch:"));
 177             assertTrue(archiveContains(archiveFolder.path(), "^ - " + editHash.abbreviate() + ": Change msg"));
 178             assertFalse(archiveContains(archiveFolder.path(), "With several lines"));
 179 
 180             // The mailing list as well
 181             listServer.processIncoming();
 182             var mailmanServer = MailingListServerFactory.createMailmanServer(listServer.getArchive(), listServer.getSMTP());
 183             var mailmanList = mailmanServer.getList(listAddress.address());
 184             var conversations = mailmanList.conversations(Duration.ofDays(1));
 185             assertEquals(1, conversations.size());
 186             var mail = conversations.get(0).first();
 187             assertEquals("RFR: 1234: This is a pull request", mail.subject());
 188             assertEquals(pr.getAuthor().fullName(), mail.author().fullName().orElseThrow());
 189             assertEquals(noreplyAddress(archive), mail.author().address());
 190             assertEquals(from, mail.sender());
 191 
 192             // And there should be a webrev
 193             Repository.materialize(webrevFolder.path(), archive.getUrl(), "webrev");
 194             assertTrue(webrevContains(webrevFolder.path(), "1 lines changed"));
 195             var comments = pr.getComments();
 196             var webrevComments = comments.stream()
 197                                          .filter(comment -> comment.author().equals(author.host().getCurrentUserDetails()))
 198                                          .filter(comment -> comment.body().contains("webrev"))
 199                                          .filter(comment -> comment.body().contains(editHash.hex()))
 200                                          .collect(Collectors.toList());
 201             assertEquals(1, webrevComments.size());
 202 
 203             // Add a comment
 204             pr.addComment("This is a comment :smile:");
 205 
 206             // Add a comment from an ignored user as well
 207             ignoredPr.addComment("Don't mind me");

 246 
 247     @Test
 248     void reviewComment(TestInfo testInfo) throws IOException {
 249         try (var credentials = new HostCredentials(testInfo);
 250              var tempFolder = new TemporaryDirectory();
 251              var archiveFolder = new TemporaryDirectory();
 252              var listServer = new TestMailmanServer()) {
 253             var author = credentials.getHostedRepository();
 254             var archive = credentials.getHostedRepository();
 255             var ignored = credentials.getHostedRepository();
 256             var listAddress = EmailAddress.parse(listServer.createList("test"));
 257             var censusBuilder = credentials.getCensusBuilder()
 258                                            .addAuthor(author.host().getCurrentUserDetails().id());
 259             var from = EmailAddress.from("test", "test@test.mail");
 260             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master", listAddress,
 261                                                  Set.of(ignored.host().getCurrentUserDetails().userName()),
 262                                                  Set.of(),
 263                                                  listServer.getArchive(), listServer.getSMTP(),
 264                                                  archive, "webrev", Path.of("test"),
 265                                                  URIBuilder.base("http://www.test.test/").build(),
 266                                                  Set.of(), Map.of(),
 267                                                  URIBuilder.base("http://issues.test/browse/").build());
 268 
 269             // Populate the projects repository
 270             var reviewFile = Path.of("reviewfile.txt");
 271             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 272             var masterHash = localRepo.resolve("master").orElseThrow();
 273             localRepo.push(masterHash, author.getUrl(), "master", true);
 274             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 275 
 276             // Make a change with a corresponding PR
 277             var editHash = CheckableRepository.appendAndCommit(localRepo);
 278             localRepo.push(editHash, author.getUrl(), "edit", true);
 279             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 280             pr.setBody("This is now ready");
 281             TestBotRunner.runPeriodicItems(mlBot);
 282             listServer.processIncoming();
 283 
 284             // And make a file specific comment
 285             var currentMaster = localRepo.resolve("master").orElseThrow();
 286             var comment = pr.addReviewComment(masterHash, editHash, reviewFile.toString(), 2, "Review comment");
 287 

 333     }
 334 
 335     @Test
 336     void combineComments(TestInfo testInfo) throws IOException {
 337         try (var credentials = new HostCredentials(testInfo);
 338              var tempFolder = new TemporaryDirectory();
 339              var archiveFolder = new TemporaryDirectory();
 340              var listServer = new TestMailmanServer()) {
 341             var author = credentials.getHostedRepository();
 342             var archive = credentials.getHostedRepository();
 343             var listAddress = EmailAddress.parse(listServer.createList("test"));
 344             var censusBuilder = credentials.getCensusBuilder()
 345                                            .addAuthor(author.host().getCurrentUserDetails().id());
 346             var from = EmailAddress.from("test", "test@test.mail");
 347             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 348                                                  listAddress, Set.of(), Set.of(),
 349                                                  listServer.getArchive(),
 350                                                  listServer.getSMTP(),
 351                                                  archive, "webrev", Path.of("test"),
 352                                                  URIBuilder.base("http://www.test.test/").build(),
 353                                                  Set.of(), Map.of(),
 354                                                  URIBuilder.base("http://issues.test/browse/").build());
 355 
 356             // Populate the projects repository
 357             var reviewFile = Path.of("reviewfile.txt");
 358             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 359             var masterHash = localRepo.resolve("master").orElseThrow();
 360             localRepo.push(masterHash, author.getUrl(), "master", true);
 361             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 362 
 363             // Make a change with a corresponding PR
 364             var editHash = CheckableRepository.appendAndCommit(localRepo);
 365             localRepo.push(editHash, author.getUrl(), "edit", true);
 366             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 367             pr.setBody("This is now ready");
 368             pr.addComment("Avoid combining");
 369 
 370             TestBotRunner.runPeriodicItems(mlBot);
 371             listServer.processIncoming();
 372             listServer.processIncoming();
 373 
 374             // Make two file specific comments

 406     @Test
 407     void commentThreading(TestInfo testInfo) throws IOException {
 408         try (var credentials = new HostCredentials(testInfo);
 409              var tempFolder = new TemporaryDirectory();
 410              var archiveFolder = new TemporaryDirectory();
 411              var listServer = new TestMailmanServer()) {
 412             var author = credentials.getHostedRepository();
 413             var reviewer = credentials.getHostedRepository();
 414             var archive = credentials.getHostedRepository();
 415             var listAddress = EmailAddress.parse(listServer.createList("test"));
 416             var censusBuilder = credentials.getCensusBuilder()
 417                                            .addReviewer(reviewer.host().getCurrentUserDetails().id())
 418                                            .addAuthor(author.host().getCurrentUserDetails().id());
 419             var from = EmailAddress.from("test", "test@test.mail");
 420             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 421                                                  listAddress, Set.of(), Set.of(),
 422                                                  listServer.getArchive(),
 423                                                  listServer.getSMTP(),
 424                                                  archive, "webrev", Path.of("test"),
 425                                                  URIBuilder.base("http://www.test.test/").build(),
 426                                                  Set.of(), Map.of(),
 427                                                  URIBuilder.base("http://issues.test/browse/").build());
 428 
 429             // Populate the projects repository
 430             var reviewFile = Path.of("reviewfile.txt");
 431             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 432             var masterHash = localRepo.resolve("master").orElseThrow();
 433             localRepo.push(masterHash, author.getUrl(), "master", true);
 434             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 435 
 436             // Make a change with a corresponding PR
 437             var editHash = CheckableRepository.appendAndCommit(localRepo);
 438             localRepo.push(editHash, author.getUrl(), "edit", true);
 439             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 440             pr.setBody("This is now ready");
 441             TestBotRunner.runPeriodicItems(mlBot);
 442             listServer.processIncoming();
 443 
 444             // Make a file specific comment
 445             var reviewPr = reviewer.getPullRequest(pr.getId());
 446             var comment1 = reviewPr.addReviewComment(masterHash, editHash, reviewFile.toString(), 2, "Review comment");
 447             pr.addReviewCommentReply(comment1, "I agree");

 515     }
 516 
 517     @Test
 518     void reviewContext(TestInfo testInfo) throws IOException {
 519         try (var credentials = new HostCredentials(testInfo);
 520              var tempFolder = new TemporaryDirectory();
 521              var archiveFolder = new TemporaryDirectory();
 522              var listServer = new TestMailmanServer()) {
 523             var author = credentials.getHostedRepository();
 524             var archive = credentials.getHostedRepository();
 525             var listAddress = EmailAddress.parse(listServer.createList("test"));
 526             var censusBuilder = credentials.getCensusBuilder()
 527                                            .addAuthor(author.host().getCurrentUserDetails().id());
 528             var from = EmailAddress.from("test", "test@test.mail");
 529             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 530                                                  listAddress, Set.of(), Set.of(),
 531                                                  listServer.getArchive(),
 532                                                  listServer.getSMTP(),
 533                                                  archive, "webrev", Path.of("test"),
 534                                                  URIBuilder.base("http://www.test.test/").build(),
 535                                                  Set.of(), Map.of(),
 536                                                  URIBuilder.base("http://issues.test/browse/").build());
 537 
 538             // Populate the projects repository
 539             var reviewFile = Path.of("reviewfile.txt");
 540             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 541             var masterHash = localRepo.resolve("master").orElseThrow();
 542             localRepo.push(masterHash, author.getUrl(), "master", true);
 543             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 544 
 545             // Make a change with a corresponding PR
 546             var editHash = CheckableRepository.appendAndCommit(localRepo, "Line 1\nLine 2\nLine 3\nLine 4");
 547             localRepo.push(editHash, author.getUrl(), "edit", true);
 548             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 549             pr.setBody("This is now ready");
 550             TestBotRunner.runPeriodicItems(mlBot);
 551             listServer.processIncoming();
 552 
 553             // Make a file specific comment
 554             pr.addReviewComment(masterHash, editHash, reviewFile.toString(), 2, "Review comment");
 555 
 556             TestBotRunner.runPeriodicItems(mlBot);

 565     }
 566 
 567     @Test
 568     void multipleReviewContexts(TestInfo testInfo) throws IOException {
 569         try (var credentials = new HostCredentials(testInfo);
 570              var tempFolder = new TemporaryDirectory();
 571              var archiveFolder = new TemporaryDirectory();
 572              var listServer = new TestMailmanServer()) {
 573             var author = credentials.getHostedRepository();
 574             var archive = credentials.getHostedRepository();
 575             var listAddress = EmailAddress.parse(listServer.createList("test"));
 576             var censusBuilder = credentials.getCensusBuilder()
 577                                            .addAuthor(author.host().getCurrentUserDetails().id());
 578             var from = EmailAddress.from("test", "test@test.mail");
 579             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 580                                                  listAddress, Set.of(), Set.of(),
 581                                                  listServer.getArchive(),
 582                                                  listServer.getSMTP(),
 583                                                  archive, "webrev", Path.of("test"),
 584                                                  URIBuilder.base("http://www.test.test/").build(),
 585                                                  Set.of(), Map.of(),
 586                                                  URIBuilder.base("http://issues.test/browse/").build());
 587 
 588             // Populate the projects repository
 589             var reviewFile = Path.of("reviewfile.txt");
 590             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 591             var masterHash = localRepo.resolve("master").orElseThrow();
 592             localRepo.push(masterHash, author.getUrl(), "master", true);
 593             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 594             var initialHash = CheckableRepository.appendAndCommit(localRepo,
 595                                                                   "Line 0.1\nLine 0.2\nLine 0.3\nLine 0.4\n" +
 596                                                                           "Line 1\nLine 2\nLine 3\nLine 4\n" +
 597                                                                           "Line 5\nLine 6\nLine 7\nLine 8\n" +
 598                                                                           "Line 8.1\nLine 8.2\nLine 8.3\nLine 8.4\n" +
 599                                                                           "Line 9\nLine 10\nLine 11\nLine 12\n" +
 600                                                                           "Line 13\nLine 14\nLine 15\nLine 16\n");
 601             localRepo.push(initialHash, author.getUrl(), "master");
 602 
 603             // Make a change with a corresponding PR
 604             var current = Files.readString(localRepo.root().resolve(reviewFile), StandardCharsets.UTF_8);
 605             var updated = current.replaceAll("Line 2", "Line 2 edit\nLine 2.5");
 606             updated = updated.replaceAll("Line 13", "Line 12.5\nLine 13 edit");

 633         }
 634     }
 635 
 636     @Test
 637     void filterComments(TestInfo testInfo) throws IOException {
 638         try (var credentials = new HostCredentials(testInfo);
 639              var tempFolder = new TemporaryDirectory();
 640              var archiveFolder = new TemporaryDirectory();
 641              var listServer = new TestMailmanServer()) {
 642             var author = credentials.getHostedRepository();
 643             var archive = credentials.getHostedRepository();
 644             var listAddress = EmailAddress.parse(listServer.createList("test"));
 645             var censusBuilder = credentials.getCensusBuilder()
 646                                            .addAuthor(author.host().getCurrentUserDetails().id());
 647             var from = EmailAddress.from("test", "test@test.mail");
 648             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 649                                                  listAddress, Set.of(), Set.of(),
 650                                                  listServer.getArchive(), listServer.getSMTP(),
 651                                                  archive, "webrev", Path.of("test"),
 652                                                  URIBuilder.base("http://www.test.test/").build(),
 653                                                  Set.of(), Map.of(),
 654                                                  URIBuilder.base("http://issues.test/browse/").build());
 655 
 656             // Populate the projects repository
 657             var reviewFile = Path.of("reviewfile.txt");
 658             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 659             var masterHash = localRepo.resolve("master").orElseThrow();
 660             localRepo.push(masterHash, author.getUrl(), "master", true);
 661             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 662 
 663             // Make a change with a corresponding PR
 664             var editHash = CheckableRepository.appendAndCommit(localRepo);
 665             localRepo.push(editHash, author.getUrl(), "edit", true);
 666             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 667             pr.setBody("This is now ready\n<!-- this is a comment -->\nAnd this is not\n" +
 668                                "<!-- Anything below this marker will be hidden -->\nStatus stuff");
 669 
 670             // Make a bunch of comments
 671             pr.addComment("Plain comment\n<!-- this is a comment -->");
 672             pr.addReviewComment(masterHash, editHash, reviewFile.toString(), 2, "Review comment <!-- this is a comment -->\n");
 673             pr.addComment("/integrate stuff");
 674             TestBotRunner.runPeriodicItems(mlBot);

 691     }
 692 
 693     @Test
 694     void incrementalChanges(TestInfo testInfo) throws IOException {
 695         try (var credentials = new HostCredentials(testInfo);
 696              var tempFolder = new TemporaryDirectory();
 697              var archiveFolder = new TemporaryDirectory();
 698              var listServer = new TestMailmanServer()) {
 699             var author = credentials.getHostedRepository();
 700             var archive = credentials.getHostedRepository();
 701             var commenter = credentials.getHostedRepository();
 702             var listAddress = EmailAddress.parse(listServer.createList("test"));
 703             var censusBuilder = credentials.getCensusBuilder()
 704                                            .addAuthor(author.host().getCurrentUserDetails().id());
 705             var from = EmailAddress.from("test", "test@test.mail");
 706             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 707                                                  listAddress, Set.of(), Set.of(),
 708                                                  listServer.getArchive(), listServer.getSMTP(),
 709                                                  archive, "webrev", Path.of("test"),
 710                                                  URIBuilder.base("http://www.test.test/").build(),
 711                                                  Set.of(), Map.of(),
 712                                                  URIBuilder.base("http://issues.test/browse/").build());
 713 
 714             // Populate the projects repository
 715             var reviewFile = Path.of("reviewfile.txt");
 716             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
 717             var masterHash = localRepo.resolve("master").orElseThrow();
 718             localRepo.push(masterHash, author.getUrl(), "master", true);
 719             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 720 
 721             // Make a change with a corresponding PR
 722             var editHash = CheckableRepository.appendAndCommit(localRepo);
 723             localRepo.push(editHash, author.getUrl(), "edit", true);
 724             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 725             pr.setBody("This is now ready");
 726 
 727             // Run an archive pass
 728             TestBotRunner.runPeriodicItems(mlBot);
 729             listServer.processIncoming();
 730 
 731             var nextHash = CheckableRepository.appendAndCommit(localRepo, "Yet one more line", "Fixing");
 732             localRepo.push(nextHash, author.getUrl(), "edit");

 811         }
 812     }
 813 
 814     @Test
 815     void rebased(TestInfo testInfo) throws IOException {
 816         try (var credentials = new HostCredentials(testInfo);
 817              var tempFolder = new TemporaryDirectory();
 818              var archiveFolder = new TemporaryDirectory();
 819              var listServer = new TestMailmanServer()) {
 820             var author = credentials.getHostedRepository();
 821             var archive = credentials.getHostedRepository();
 822             var listAddress = EmailAddress.parse(listServer.createList("test"));
 823             var censusBuilder = credentials.getCensusBuilder()
 824                                            .addAuthor(author.host().getCurrentUserDetails().id());
 825             var sender = EmailAddress.from("test", "test@test.mail");
 826             var mlBot = new MailingListBridgeBot(sender, author, archive, censusBuilder.build(), "master",
 827                                                  listAddress, Set.of(), Set.of(),
 828                                                  listServer.getArchive(), listServer.getSMTP(),
 829                                                  archive, "webrev", Path.of("test"),
 830                                                  URIBuilder.base("http://www.test.test/").build(),
 831                                                  Set.of(), Map.of(),
 832                                                  URIBuilder.base("http://issues.test/browse/").build());
 833 
 834             // Populate the projects repository
 835             var reviewFile = Path.of("reviewfile.txt");
 836             var localRepo = CheckableRepository.init(tempFolder.path().resolve("first"), author.getRepositoryType(), reviewFile);
 837             var masterHash = localRepo.resolve("master").orElseThrow();
 838             localRepo.push(masterHash, author.getUrl(), "master", true);
 839             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 840 
 841             // Make a change with a corresponding PR
 842             var editHash = CheckableRepository.appendAndCommit(localRepo, "A line", "Original msg");
 843             localRepo.push(editHash, author.getUrl(), "edit", true);
 844             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 845             pr.setBody("This is now ready");
 846 
 847             // Run an archive pass
 848             TestBotRunner.runPeriodicItems(mlBot);
 849             listServer.processIncoming();
 850 
 851             var newLocalRepo = Repository.materialize(tempFolder.path().resolve("second"), author.getUrl(), "master");
 852             var newEditHash = CheckableRepository.appendAndCommit(newLocalRepo, "Another line", "Replaced msg");

 903     void skipAddingExistingWebrev(TestInfo testInfo) throws IOException {
 904         try (var credentials = new HostCredentials(testInfo);
 905              var tempFolder = new TemporaryDirectory();
 906              var archiveFolder = new TemporaryDirectory();
 907              var webrevFolder = new TemporaryDirectory();
 908              var listServer = new TestMailmanServer()) {
 909             var author = credentials.getHostedRepository();
 910             var archive = credentials.getHostedRepository();
 911             var ignored = credentials.getHostedRepository();
 912             var listAddress = EmailAddress.parse(listServer.createList("test"));
 913             var censusBuilder = credentials.getCensusBuilder()
 914                                            .addAuthor(author.host().getCurrentUserDetails().id());
 915             var from = EmailAddress.from("test", "test@test.mail");
 916             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 917                                                  listAddress,
 918                                                  Set.of(ignored.host().getCurrentUserDetails().userName()),
 919                                                  Set.of(),
 920                                                  listServer.getArchive(), listServer.getSMTP(),
 921                                                  archive, "webrev", Path.of("test"),
 922                                                  URIBuilder.base("http://www.test.test/").build(),
 923                                                  Set.of(), Map.of(),
 924                                                  URIBuilder.base("http://issues.test/browse/").build());
 925 
 926             // Populate the projects repository
 927             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType());
 928             var masterHash = localRepo.resolve("master").orElseThrow();
 929             localRepo.push(masterHash, author.getUrl(), "master", true);
 930             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
 931 
 932             // Make a change with a corresponding PR
 933             var editHash = CheckableRepository.appendAndCommit(localRepo, "A simple change",
 934                                                                "Change msg\n\nWith several lines");
 935             localRepo.push(editHash, author.getUrl(), "edit", true);
 936             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
 937 
 938             // Flag it as ready for review
 939             pr.setBody("This should now be ready");
 940 
 941             // Run an archive pass
 942             TestBotRunner.runPeriodicItems(mlBot);
 943 
 944             // The archive should now contain an entry

 975 
 976     @Test
 977     void notifyReviewVerdicts(TestInfo testInfo) throws IOException {
 978         try (var credentials = new HostCredentials(testInfo);
 979              var tempFolder = new TemporaryDirectory();
 980              var archiveFolder = new TemporaryDirectory();
 981              var listServer = new TestMailmanServer()) {
 982             var author = credentials.getHostedRepository();
 983             var archive = credentials.getHostedRepository();
 984             var reviewer = credentials.getHostedRepository();
 985             var listAddress = EmailAddress.parse(listServer.createList("test"));
 986             var from = EmailAddress.from("test", "test@test.mail");
 987             var censusBuilder = credentials.getCensusBuilder()
 988                                            .addReviewer(reviewer.host().getCurrentUserDetails().id())
 989                                            .addAuthor(author.host().getCurrentUserDetails().id());
 990             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
 991                                                  listAddress, Set.of(), Set.of(),
 992                                                  listServer.getArchive(), listServer.getSMTP(),
 993                                                  archive, "webrev", Path.of("test"),
 994                                                  URIBuilder.base("http://www.test.test/").build(),
 995                                                  Set.of(), Map.of(),
 996                                                  URIBuilder.base("http://issues.test/browse/").build());
 997 
 998             // Populate the projects repository
 999             var reviewFile = Path.of("reviewfile.txt");
1000             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
1001             var masterHash = localRepo.resolve("master").orElseThrow();
1002             localRepo.push(masterHash, author.getUrl(), "master", true);
1003             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
1004 
1005             // Make a change with a corresponding PR
1006             var editHash = CheckableRepository.appendAndCommit(localRepo);
1007             localRepo.push(editHash, author.getUrl(), "edit", true);
1008             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
1009             pr.setBody("This is now ready");
1010 
1011             // Run an archive pass
1012             TestBotRunner.runPeriodicItems(mlBot);
1013 
1014             // First unapprove it
1015             var reviewedPr = reviewer.getPullRequest(pr.getId());
1016             reviewedPr.addReview(Review.Verdict.DISAPPROVED, "Reason 1");

1058     @Test
1059     void ignoreComments(TestInfo testInfo) throws IOException {
1060         try (var credentials = new HostCredentials(testInfo);
1061              var tempFolder = new TemporaryDirectory();
1062              var archiveFolder = new TemporaryDirectory();
1063              var listServer = new TestMailmanServer()) {
1064             var author = credentials.getHostedRepository();
1065             var ignored = credentials.getHostedRepository();
1066             var archive = credentials.getHostedRepository();
1067             var listAddress = EmailAddress.parse(listServer.createList("test"));
1068             var censusBuilder = credentials.getCensusBuilder()
1069                                            .addAuthor(author.host().getCurrentUserDetails().id());
1070             var from = EmailAddress.from("test", "test@test.mail");
1071             var mlBot = new MailingListBridgeBot(from, author, archive, censusBuilder.build(), "master",
1072                                                  listAddress,
1073                                                  Set.of(ignored.host().getCurrentUserDetails().userName()),
1074                                                  Set.of(Pattern.compile("ignore this comment", Pattern.MULTILINE | Pattern.DOTALL)),
1075                                                  listServer.getArchive(), listServer.getSMTP(),
1076                                                  archive, "webrev", Path.of("test"),
1077                                                  URIBuilder.base("http://www.test.test/").build(),
1078                                                  Set.of(), Map.of(),
1079                                                  URIBuilder.base("http://issues.test/browse/").build());
1080 
1081             // Populate the projects repository
1082             var reviewFile = Path.of("reviewfile.txt");
1083             var localRepo = CheckableRepository.init(tempFolder.path(), author.getRepositoryType(), reviewFile);
1084             var masterHash = localRepo.resolve("master").orElseThrow();
1085             localRepo.push(masterHash, author.getUrl(), "master", true);
1086             localRepo.push(masterHash, archive.getUrl(), "webrev", true);
1087 
1088             // Make a change with a corresponding PR
1089             var editHash = CheckableRepository.appendAndCommit(localRepo);
1090             localRepo.push(editHash, author.getUrl(), "edit", true);
1091             var pr = credentials.createPullRequest(archive, "master", "edit", "This is a pull request");
1092             pr.setBody("This is now ready");
1093 
1094             // Make a bunch of comments
1095             pr.addComment("Plain comment");
1096             pr.addComment("ignore this comment");
1097             pr.addComment("I think it is time to\nignore this comment!");
1098             pr.addReviewComment(masterHash, editHash, reviewFile.toString(), 2, "Review ignore this comment");
1099 
< prev index next >