Skip to content

Commit 176f6fb

Browse files
authored
(GH-322) Support deleting comments (#323)
1 parent 1537ec3 commit 176f6fb

File tree

8 files changed

+551
-6
lines changed

8 files changed

+551
-6
lines changed

src/Cake.AzureDevOps.Tests/Fakes/FakeAllSetGitClientFactory.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ protected override Mock<GitHttpClient> Setup(Mock<GitHttpClient> m)
161161
},
162162
Comments = new List<Comment>
163163
{
164-
new Comment { Content = "Hello", IsDeleted = false, CommentType = CommentType.CodeChange },
165-
new Comment { Content = "Goodbye", IsDeleted = true, CommentType = CommentType.Text },
164+
new Comment { Content = "Hello", IsDeleted = false, CommentType = CommentType.CodeChange, Id = 1 },
165+
new Comment { Content = "Goodbye", IsDeleted = true, CommentType = CommentType.Text, Id = 2 },
166166
},
167167
Status = CommentThreadStatus.Active,
168168
},
@@ -307,6 +307,21 @@ protected override Mock<GitHttpClient> Setup(Mock<GitHttpClient> m)
307307
return gitPullRequestToCreate;
308308
});
309309

310+
m.Setup(arg => arg.UpdateCommentAsync(
311+
It.IsAny<Comment>(),
312+
It.IsAny<Guid>(),
313+
It.IsAny<int>(),
314+
It.IsAny<int>(),
315+
It.IsAny<int>(),
316+
null,
317+
CancellationToken.None))
318+
.ReturnsAsync((Comment comment, Guid repositoryId, int prId, int threadId, int commentId, object o, CancellationToken c)
319+
=> new Comment
320+
{
321+
Id = comment.Id,
322+
Content = comment.Content,
323+
});
324+
310325
return m;
311326
}
312327
}

src/Cake.AzureDevOps.Tests/Fakes/FakeNullForMethodsGitClientFactory.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ protected override Mock<GitHttpClient> Setup(Mock<GitHttpClient> m)
3535
m.Setup(arg => arg.GetPullRequestIterationChangesAsync(It.IsAny<Guid>(), It.IsAny<int>(), It.IsAny<int>(), null, null, null, null, CancellationToken.None))
3636
.ReturnsAsync(() => null);
3737

38+
m.Setup(arg => arg.UpdateCommentAsync(It.IsAny<Comment>(), It.IsAny<Guid>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>(), null, CancellationToken.None))
39+
.ReturnsAsync(() => null);
40+
3841
return m;
3942
}
4043
}

src/Cake.AzureDevOps.Tests/Repos/PullRequest/AzureDevOpsPullRequestTests.cs

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,12 +750,14 @@ public void Should_Return_Valid_Comment_Threads()
750750
comment11.Content.ShouldBe("Hello");
751751
comment11.IsDeleted.ShouldBe(false);
752752
comment11.CommentType.ShouldBe(AzureDevOpsCommentType.CodeChange);
753+
((int)comment11.Id).ShouldBeGreaterThan(0);
753754

754755
AzureDevOpsComment comment12 = thread1.Comments.Last();
755756
comment12.ShouldNotBeNull();
756757
comment12.Content.ShouldBe("Goodbye");
757758
comment12.IsDeleted.ShouldBe(true);
758759
comment12.CommentType.ShouldBe(AzureDevOpsCommentType.Text);
760+
((int)comment12.Id).ShouldBeGreaterThan(0);
759761

760762
AzureDevOpsPullRequestCommentThread thread2 = threads.Last();
761763
thread2.Id.ShouldBe(22);
@@ -826,6 +828,279 @@ public void Should_Create_Valid_Thread_With_One_Comment()
826828
}
827829
}
828830

831+
public sealed class TheCreateCommentWithFileMethod
832+
{
833+
[Theory]
834+
[InlineData((string)null, typeof(ArgumentNullException))]
835+
[InlineData("", typeof(ArgumentOutOfRangeException))]
836+
[InlineData(" ", typeof(ArgumentOutOfRangeException))]
837+
public void Should_Throw_If_Comment_Is_Null_Or_Empty_Or_Whitespace(string comment, Type expectedExceptionType)
838+
{
839+
// Given
840+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
841+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
842+
843+
// When
844+
var result = Record.Exception(() => pullRequest.CreateComment(comment, new FilePath("text.txt"), 0, 0)) as ArgumentException;
845+
846+
// Then
847+
result.ShouldNotBeNull();
848+
result.IsArgumentException(expectedExceptionType, "comment");
849+
}
850+
851+
[Theory]
852+
[InlineData((string)null, typeof(ArgumentNullException))]
853+
[InlineData("", typeof(ArgumentOutOfRangeException))]
854+
[InlineData(" ", typeof(ArgumentOutOfRangeException))]
855+
public void Should_Throw_If_FilePath_Is_Null_Or_Empty_Or_Whitespace(string filePath, Type expectedExceptionType)
856+
{
857+
// Given
858+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
859+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
860+
861+
// When
862+
var result = Record.Exception(() => pullRequest.CreateComment("test", filePath == null ? null : new FilePath(filePath), 0, 0)) as ArgumentException;
863+
864+
// Then
865+
result.ShouldNotBeNull();
866+
result.IsArgumentException(expectedExceptionType, "filePath");
867+
}
868+
869+
[Theory]
870+
[InlineData(0, typeof(ArgumentOutOfRangeException))]
871+
[InlineData(-1, typeof(ArgumentOutOfRangeException))]
872+
[InlineData(-50, typeof(ArgumentOutOfRangeException))]
873+
public void Should_Throw_If_LineNumber_Is_Negative_Or_Zeror(int lineNumber, Type expectedExceptionType)
874+
{
875+
// Given
876+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
877+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
878+
879+
// When
880+
var result = Record.Exception(() => pullRequest.CreateComment("test", new FilePath("test.txt"), lineNumber, 0)) as ArgumentException;
881+
882+
// Then
883+
result.ShouldNotBeNull();
884+
result.IsArgumentException(expectedExceptionType, "lineNumber");
885+
}
886+
887+
[Theory]
888+
[InlineData(-1, typeof(ArgumentOutOfRangeException))]
889+
[InlineData(-50, typeof(ArgumentOutOfRangeException))]
890+
public void Should_Throw_If_Offset_Is_Negative(int offset, Type expectedExceptionType)
891+
{
892+
// Given
893+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
894+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
895+
896+
// When
897+
var result = Record.Exception(() => pullRequest.CreateComment("test", new FilePath("test.txt"), 1, offset)) as ArgumentException;
898+
899+
// Then
900+
result.ShouldNotBeNull();
901+
result.IsArgumentException(expectedExceptionType, "offset");
902+
}
903+
904+
[Fact]
905+
public void Should_Return_Null_If_Null_Is_Returned_From_Git_Client()
906+
{
907+
// Given
908+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100)
909+
{
910+
GitClientFactory = new FakeNullForMethodsGitClientFactory(),
911+
};
912+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
913+
914+
// When
915+
var thread = pullRequest.CreateComment("Foo", new FilePath("test.txt"), 10, 50);
916+
917+
// Then
918+
thread.ShouldBeNull();
919+
}
920+
921+
[Fact]
922+
public void Should_Create_Valid_Thread_With_One_Comment()
923+
{
924+
// Given
925+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
926+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
927+
928+
// When
929+
var thread = pullRequest.CreateComment("Valid", new FilePath("src/test.txt"), 10, 50);
930+
931+
// Then
932+
thread.ShouldNotBeNull();
933+
thread.Status.ShouldBe(AzureDevOpsCommentThreadStatus.Active);
934+
thread.FilePath.FullPath.ShouldBe("src/test.txt");
935+
thread.LineNumber.ShouldBe(10);
936+
thread.Offset.ShouldBe(50);
937+
938+
thread.Comments.ShouldNotBeNull();
939+
thread.Comments.Count().ShouldBe(1);
940+
941+
var comment = thread.Comments.First();
942+
comment.CommentType.ShouldBe(AzureDevOpsCommentType.System);
943+
comment.IsDeleted.ShouldBeFalse();
944+
comment.Content.ShouldBe("Valid");
945+
}
946+
}
947+
948+
public sealed class TheDeleteCommentMethod
949+
{
950+
[Theory]
951+
[InlineData(0, typeof(ArgumentOutOfRangeException))]
952+
[InlineData(-1, typeof(ArgumentOutOfRangeException))]
953+
[InlineData(-55, typeof(ArgumentOutOfRangeException))]
954+
public void Should_Throw_If_ThreadId_Is_Zero_Or_Below(int threadId, Type expectedExceptionType)
955+
{
956+
// Given
957+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
958+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
959+
960+
// When
961+
var result = Record.Exception(() => pullRequest.DeleteComment(threadId, 5)) as ArgumentException;
962+
963+
// Then
964+
result.ShouldNotBeNull();
965+
result.IsArgumentException(expectedExceptionType, "threadId");
966+
}
967+
968+
[Theory]
969+
[InlineData(0, typeof(ArgumentOutOfRangeException))]
970+
[InlineData(-1, typeof(ArgumentOutOfRangeException))]
971+
[InlineData(-55, typeof(ArgumentOutOfRangeException))]
972+
public void Should_Throw_If_CommentId_Is_Zero_Or_Below(int commentId, Type expectedExceptionType)
973+
{
974+
// Given
975+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
976+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
977+
978+
// When
979+
var result = Record.Exception(() => pullRequest.DeleteComment(5, commentId)) as ArgumentException;
980+
981+
// Then
982+
result.ShouldNotBeNull();
983+
result.IsArgumentException(expectedExceptionType, "commentId");
984+
}
985+
986+
[Fact]
987+
public void Should_Delete_Comment()
988+
{
989+
// Given
990+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
991+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
992+
993+
// When
994+
pullRequest.DeleteComment(5, 1);
995+
996+
// Then
997+
// ?? Nothing to validate here since the method returns void
998+
}
999+
1000+
[Fact]
1001+
public void Should_Throw_If_Comment_Is_Null()
1002+
{
1003+
// Given
1004+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
1005+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
1006+
1007+
// When
1008+
var result = Record.Exception(() => pullRequest.DeleteComment(null)) as ArgumentException;
1009+
1010+
// Then
1011+
result.ShouldNotBeNull();
1012+
result.IsArgumentNullException("comment");
1013+
}
1014+
1015+
[Fact]
1016+
public void Should_Delete_Comment_By_Comment_Properties()
1017+
{
1018+
// Given
1019+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
1020+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
1021+
var inComment = new AzureDevOpsComment(new Microsoft.TeamFoundation.SourceControl.WebApi.Comment { Id = 1 }, 5);
1022+
inComment.Content = "new Content";
1023+
1024+
// When
1025+
pullRequest.DeleteComment(inComment);
1026+
1027+
// Then
1028+
// ?? Nothing to validate here since the method returns void
1029+
}
1030+
}
1031+
1032+
public sealed class TheUpdateCommentMethod
1033+
{
1034+
[Fact]
1035+
public void Should_Throw_If_Comment_Is_Null()
1036+
{
1037+
// Given
1038+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100);
1039+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
1040+
1041+
// When
1042+
var result = Record.Exception(() => pullRequest.UpdateComment(null)) as ArgumentException;
1043+
1044+
// Then
1045+
result.ShouldNotBeNull();
1046+
result.IsArgumentNullException("comment");
1047+
}
1048+
1049+
[Fact]
1050+
public void Should_Return_Null_If_Pull_Request_Is_Invalid()
1051+
{
1052+
// Given
1053+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100)
1054+
{
1055+
GitClientFactory = new FakeNullGitClientFactory(),
1056+
};
1057+
fixture.Settings.ThrowExceptionIfPullRequestCouldNotBeFound = false;
1058+
1059+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
1060+
1061+
// When
1062+
var outThread = pullRequest.UpdateComment(new AzureDevOpsComment());
1063+
1064+
// Then
1065+
outThread.ShouldBeNull();
1066+
}
1067+
1068+
[Fact]
1069+
public void Should_Return_Null_If_Null_Is_Returned_From_Git_Client()
1070+
{
1071+
// Given
1072+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsServerUrl, 100)
1073+
{
1074+
GitClientFactory = new FakeNullForMethodsGitClientFactory(),
1075+
};
1076+
1077+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
1078+
1079+
// When
1080+
var outThread = pullRequest.UpdateComment(new AzureDevOpsComment());
1081+
1082+
// Then
1083+
outThread.ShouldBeNull();
1084+
}
1085+
1086+
[Fact]
1087+
public void Should_Return_Updated_Comment()
1088+
{
1089+
// Given
1090+
var fixture = new PullRequestFixture(BasePullRequestFixture.ValidAzureDevOpsUrl, 200);
1091+
var pullRequest = new AzureDevOpsPullRequest(fixture.Log, fixture.Settings, fixture.GitClientFactory);
1092+
var inComment = new AzureDevOpsComment(new Microsoft.TeamFoundation.SourceControl.WebApi.Comment { Id = 1 }, 5);
1093+
inComment.Content = "new Content";
1094+
1095+
// When
1096+
var outComment = pullRequest.UpdateComment(inComment);
1097+
1098+
// Then
1099+
outComment.Id.ShouldBe(inComment.Id);
1100+
outComment.Content.ShouldBe(inComment.Content);
1101+
}
1102+
}
1103+
8291104
public sealed class TheCreateCommentThreadMethod
8301105
{
8311106
[Fact]

src/Cake.AzureDevOps.Tests/Repos/PullRequest/CommentThread/AzureDevOpsCommentTests.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,22 @@ public sealed class TheCtor
1313
public void Should_Throw_If_Comment_Is_Null()
1414
{
1515
// Given, When
16-
var result = Record.Exception(() => new AzureDevOpsComment(null));
16+
var result = Record.Exception(() => new AzureDevOpsComment(null, 1));
1717

1818
// Then
1919
result.IsArgumentNullException("comment");
2020
}
2121

22+
[Fact]
23+
public void Should_Throw_If_ThreadId_Is_Negative()
24+
{
25+
// Given, When
26+
var result = Record.Exception(() => new AzureDevOpsComment(new Comment(), -1));
27+
28+
// Then
29+
result.IsArgumentOutOfRangeException("threadId");
30+
}
31+
2232
[Fact]
2333
public void Should_Throw_If_Comment_Content_Is_Null()
2434
{
@@ -50,6 +60,7 @@ public void Should_Return_Empty_Comment()
5060
comment.Content.ShouldBe(default(string));
5161
comment.IsDeleted.ShouldBe(default(bool));
5262
comment.CommentType.ShouldBe(default(AzureDevOpsCommentType));
63+
comment.ThreadId.ShouldBe(0);
5364
}
5465

5566
[Fact]
@@ -63,6 +74,7 @@ public void Should_Return_Valid_Comment_With_Default_Comment_Type()
6374
comment.Content.ShouldBe("Hello");
6475
comment.IsDeleted.ShouldBeFalse();
6576
comment.CommentType.ShouldBe(default(AzureDevOpsCommentType));
77+
comment.ThreadId.ShouldBe(0);
6678
}
6779

6880
[Fact]

0 commit comments

Comments
 (0)