github.com/vipcoin-gold/reviewdog@v1.0.2/service/bitbucket/annotator_test.go (about) 1 package bitbucket 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/vipcoin-gold/reviewdog/filter" 8 "github.com/vipcoin-gold/reviewdog/proto/rdf" 9 10 "github.com/vipcoin-gold/reviewdog" 11 12 "github.com/stretchr/testify/suite" 13 ) 14 15 type AnnotatorTestSuite struct { 16 suite.Suite 17 cli *MockAPIClient 18 owner string 19 repo string 20 sha string 21 } 22 23 func (s *AnnotatorTestSuite) SetupTest() { 24 s.cli = &MockAPIClient{} 25 s.owner = "test-owner" 26 s.repo = "test-repo" 27 s.sha = "test-commit" 28 } 29 30 // Empty runners list, no comments 31 func (s *AnnotatorTestSuite) TestEmptyRunnersList() { 32 ctx, annotator := s.createAnnotator(nil) 33 34 err := annotator.Flush(ctx) 35 s.Require().NoError(err) 36 s.cli.AssertExpectations(s.T()) 37 } 38 39 // Predefined runners list, and no comments 40 func (s *AnnotatorTestSuite) TestNoComments() { 41 runners := []string{"runner1", "runner2"} 42 ctx, annotator := s.createAnnotator(runners) 43 44 for _, runner := range runners { 45 s.assumeReportCreated(ctx, runner, reportResultPassed) 46 } 47 48 err := annotator.Flush(ctx) 49 50 s.Require().NoError(err) 51 s.cli.AssertExpectations(s.T()) 52 } 53 54 // Predefined runners list, and one comment 55 func (s *AnnotatorTestSuite) TestOneComment() { 56 runners := []string{"runner1", "runner2"} 57 comments := []*reviewdog.Comment{ 58 s.buildComment(runners[1], 1), 59 } 60 61 ctx, annotator := s.createAnnotator(runners) 62 s.setupExpectedAPICalls(ctx, runners, comments) 63 64 for _, comment := range comments { 65 err := annotator.Post(ctx, comment) 66 s.Require().NoError(err) 67 } 68 69 err := annotator.Flush(ctx) 70 71 s.Require().NoError(err) 72 s.cli.AssertExpectations(s.T()) 73 } 74 75 // Predefined runners list, and duplicated comment 76 func (s *AnnotatorTestSuite) TestDuplicateComments() { 77 runners := []string{"runner1", "runner2"} 78 comments := []*reviewdog.Comment{ 79 s.buildComment(runners[1], 1), 80 s.buildComment(runners[1], 1), 81 } 82 83 ctx, annotator := s.createAnnotator(runners) 84 s.setupExpectedAPICalls(ctx, runners, comments) 85 86 for _, comment := range comments { 87 err := annotator.Post(ctx, comment) 88 s.Require().NoError(err) 89 } 90 91 err := annotator.Flush(ctx) 92 93 s.Require().NoError(err) 94 s.cli.AssertExpectations(s.T()) 95 } 96 97 // Predefined runners list, and duplicated comment 98 func (s *AnnotatorTestSuite) TestManyComments() { 99 runners := []string{"runner1", "runner2"} 100 101 comments := make([]*reviewdog.Comment, 333) 102 for idx := 0; idx < 333; idx++ { 103 comments[idx] = s.buildComment(runners[1], int32(idx)) 104 } 105 106 ctx, annotator := s.createAnnotator(runners) 107 s.setupExpectedAPICalls(ctx, runners, comments) 108 109 for _, comment := range comments { 110 err := annotator.Post(ctx, comment) 111 s.Require().NoError(err) 112 } 113 114 err := annotator.Flush(ctx) 115 116 s.Require().NoError(err) 117 s.cli.AssertExpectations(s.T()) 118 } 119 120 func (s *AnnotatorTestSuite) createAnnotator(runners []string) (context.Context, *ReportAnnotator) { 121 ctx := context.Background() 122 123 for _, runner := range runners { 124 s.assumeReportCreated(ctx, runner, reportResultPending) 125 } 126 127 annotator := NewReportAnnotator(s.cli, s.owner, s.repo, s.sha, runners) 128 129 return ctx, annotator 130 } 131 132 func (s *AnnotatorTestSuite) setupExpectedAPICalls( 133 ctx context.Context, 134 runners []string, 135 comments []*reviewdog.Comment, 136 ) { 137 commentsMap := s.splitComments(comments) 138 139 for _, runner := range runners { 140 expResult := reportResultPassed 141 if len(commentsMap[runner]) > 0 { 142 expResult = reportResultFailed 143 } 144 s.assumeReportCreated(ctx, runner, expResult) 145 146 for start, annCount := 0, len(commentsMap[runner]); start < annCount; start += annotationsBatchSize { 147 end := start + annotationsBatchSize 148 149 if end > annCount { 150 end = annCount 151 } 152 153 s.assumeAnnotationsCreated(ctx, runner, commentsMap[runner][start:end]) 154 } 155 } 156 } 157 158 func (s *AnnotatorTestSuite) assumeReportCreated(ctx context.Context, runner string, status string) { 159 s.cli.On("CreateOrUpdateReport", ctx, s.buildReportReq(runner, status)).Return(nil).Once() 160 } 161 162 func (s *AnnotatorTestSuite) assumeAnnotationsCreated( 163 ctx context.Context, 164 runner string, 165 comments []*reviewdog.Comment, 166 ) { 167 s.cli.On("CreateOrUpdateAnnotations", ctx, s.buildAnnotationsRequest(runner, comments)).Return(nil).Once() 168 } 169 170 func (s *AnnotatorTestSuite) buildReportReq(runner string, result string) *ReportRequest { 171 report := &ReportRequest{ 172 ReportID: reportID(runner, reporter), 173 Owner: s.owner, 174 Repository: s.repo, 175 Commit: s.sha, 176 Type: reportTypeBug, 177 Title: reportTitle(runner, reporter), 178 Reporter: reporter, 179 Result: result, 180 LogoURL: logoURL, 181 } 182 183 switch result { 184 case reportResultPassed: 185 report.Details = "Great news! Reviewdog couldn't spot any issues!" 186 case reportResultPending: 187 report.Details = "Please wait for Reviewdog to finish checking your code for issues." 188 default: 189 report.Details = "Woof-Woof! This report generated for you by reviewdog." 190 } 191 192 return report 193 } 194 195 func (s *AnnotatorTestSuite) buildAnnotationsRequest(runner string, comments []*reviewdog.Comment) *AnnotationsRequest { 196 return &AnnotationsRequest{ 197 Owner: s.owner, 198 Repository: s.repo, 199 Commit: s.sha, 200 ReportID: reportID(runner, reporter), 201 Comments: comments, 202 } 203 } 204 205 func (s *AnnotatorTestSuite) buildComment(toolName string, line int32) *reviewdog.Comment { 206 return &reviewdog.Comment{ 207 ToolName: toolName, 208 Result: &filter.FilteredDiagnostic{ 209 Diagnostic: &rdf.Diagnostic{ 210 Location: &rdf.Location{ 211 Path: "main.go", 212 Range: &rdf.Range{Start: &rdf.Position{ 213 Line: line, 214 }}, 215 }, 216 Message: "test message", 217 }, 218 }, 219 } 220 } 221 222 func (s *AnnotatorTestSuite) splitComments(comments []*reviewdog.Comment) map[string][]*reviewdog.Comment { 223 commentsMap := make(map[string][]*reviewdog.Comment) 224 duplicates := make(map[string]struct{}) 225 226 for _, comment := range comments { 227 externalID := externalIDFromDiagnostic(comment.Result.Diagnostic) 228 if _, exist := duplicates[externalID]; !exist { 229 commentsMap[comment.ToolName] = append(commentsMap[comment.ToolName], comment) 230 duplicates[externalID] = struct{}{} 231 } 232 } 233 234 return commentsMap 235 } 236 237 func TestAnnotatorTestSuite(t *testing.T) { 238 suite.Run(t, &AnnotatorTestSuite{}) 239 }