@@ -13,12 +13,24 @@ import { GitLabAdapter } from './GitLabAdapter';
1313import { AnalyzerBot } from '../../AnalyzerBot/AnalyzerBot' ;
1414
1515const mockCurrentUserId = 123456 ;
16- const mockNoteIdToBeDeleted = 6544321 ;
16+
17+ // Create helper function to generate consistent comment keys
18+ const generateCommentKey = ( file : string , line : number | undefined , text : string ) =>
19+ `${ file } :${ line } :${ text } ` ;
1720
1821const mockNotes = [
19- { id : 1 , author : { id : mockCurrentUserId } , system : true } ,
20- { id : mockNoteIdToBeDeleted , author : { id : mockCurrentUserId } , system : false } , // only one to be deleted
21- { id : 3 , author : { id : 99 } , system : false } ,
22+ {
23+ id : 1 ,
24+ author : { id : mockCurrentUserId } ,
25+ system : true ,
26+ body : 'system message' ,
27+ } ,
28+ {
29+ id : 2 ,
30+ author : { id : mockCurrentUserId } ,
31+ system : false ,
32+ body : 'existing comment' ,
33+ } ,
2234] as MergeRequestNoteSchema [ ] ;
2335
2436const mockVersionId = 3425234 ;
@@ -47,7 +59,11 @@ function createGitLab(service: IGitLabMRService, configs: ConfigArgument) {
4759}
4860
4961describe ( 'VCS: GitLab' , ( ) => {
50- it ( 'should returns true when there is no error' , async ( ) => {
62+ beforeEach ( ( ) => {
63+ jest . clearAllMocks ( ) ;
64+ } ) ;
65+
66+ it ( 'should return true when there is no error' , async ( ) => {
5167 const service = new MrServiceMock ( ) ;
5268 const gitLab = createGitLab ( service , configs ) ;
5369
@@ -60,7 +76,7 @@ describe('VCS: GitLab', () => {
6076 expect ( result ) . toBe ( true ) ;
6177 } ) ;
6278
63- it ( 'should returns false when there is some error' , async ( ) => {
79+ it ( 'should return false when there is some error' , async ( ) => {
6480 const service = new MrServiceMock ( ) ;
6581 const gitLab = createGitLab ( service , configs ) ;
6682
@@ -74,40 +90,32 @@ describe('VCS: GitLab', () => {
7490 expect ( result ) . toBe ( false ) ;
7591 } ) ;
7692
77- it ( 'should remove old self comments and reviews and post new ones ' , async ( ) => {
93+ it ( 'should not create duplicate comments and should create new unique comments ' , async ( ) => {
7894 const service = new MrServiceMock ( ) ;
79- const gitLab = createGitLab ( service , { ...configs , removeOldComment : true } ) ;
8095
81- await gitLab . report ( [
82- touchFileError ,
83- touchFileWarning ,
84- untouchedError ,
85- untouchedWarning ,
96+ // Pre-populate with an existing comment for the error
97+ const existingErrorText = `${ touchFileError . source } :${ touchFileError . line } ::rotating_light: ${ touchFileError . msg } \n` ;
98+
99+ service . listAllNotes . mockResolvedValue ( [
100+ ...mockNotes ,
101+ {
102+ id : 4 ,
103+ author : { id : mockCurrentUserId } ,
104+ system : false ,
105+ body : existingErrorText ,
106+ } ,
86107 ] ) ;
87108
88- expect ( service . listAllNotes ) . toHaveBeenCalledTimes ( 1 ) ;
89- expect ( service . getCurrentUserId ) . toHaveBeenCalledTimes ( 1 ) ;
90-
91- expect ( service . deleteNote ) . toHaveBeenCalledTimes ( 1 ) ;
92- expect ( service . deleteNote ) . toHaveBeenCalledWith ( mockNoteIdToBeDeleted ) ;
93-
94- expect ( service . createMRDiscussion ) . toHaveBeenNthCalledWith (
95- 1 ,
96- mockVersion ,
97- touchFileError . source ,
98- touchFileError . line ,
99- expect . any ( String ) ,
100- ) ;
109+ const gitLab = createGitLab ( service , configs ) ;
110+ await gitLab . report ( [ touchFileError , touchFileWarning ] ) ;
101111
102- expect ( service . createMRDiscussion ) . toHaveBeenNthCalledWith (
103- 2 ,
112+ expect ( service . createMRDiscussion ) . toHaveBeenCalledTimes ( 1 ) ;
113+ expect ( service . createMRDiscussion ) . toHaveBeenCalledWith (
104114 mockVersion ,
105115 touchFileWarning . source ,
106116 touchFileWarning . line ,
107117 expect . any ( String ) ,
108118 ) ;
109-
110- expect ( service . createNote ) . toHaveBeenCalledTimes ( 1 ) ;
111119 } ) ;
112120
113121 it ( 'should not comment if there is no relevant lint issue' , async ( ) => {
@@ -120,39 +128,58 @@ describe('VCS: GitLab', () => {
120128 expect ( service . createNote ) . not . toHaveBeenCalled ( ) ;
121129 } ) ;
122130
131+ it ( 'should not create comments that already exist' , async ( ) => {
132+ const service = new MrServiceMock ( ) ;
133+ const gitLab = createGitLab ( service , configs ) ;
134+
135+ // Set up mock with existing summary comment
136+ const existingSummaryComment =
137+ '## CodeCoach reports 1 issue\n:rotating_light: 0 error\n:warning: 1 warning' ;
138+ service . listAllNotes . mockResolvedValue ( [
139+ {
140+ id : 1 ,
141+ author : { id : mockCurrentUserId } ,
142+ system : false ,
143+ body : existingSummaryComment ,
144+ } ,
145+ ] ) ;
146+
147+ await gitLab . report ( [ touchFileWarning ] ) ;
148+ expect ( service . createNote ) . not . toHaveBeenCalled ( ) ;
149+ } ) ;
150+
123151 describe ( 'when failOnWarnings is true' , ( ) => {
124- it ( 'should returns true when there is no error or warning' , async ( ) => {
152+ const warningConfigs = { ...configs , failOnWarnings : true } ;
153+
154+ it ( 'should return true when there is no error or warning' , async ( ) => {
125155 const service = new MrServiceMock ( ) ;
126- const gitLab = createGitLab ( service , { ... configs , failOnWarnings : true } ) ;
156+ const gitLab = createGitLab ( service , warningConfigs ) ;
127157
128158 const result = await gitLab . report ( [ untouchedError , untouchedWarning ] ) ;
129-
130159 expect ( result ) . toBe ( true ) ;
131160 } ) ;
132161
133- it ( 'should returns false when there is some error' , async ( ) => {
162+ it ( 'should return false when there is some error' , async ( ) => {
134163 const service = new MrServiceMock ( ) ;
135- const gitLab = createGitLab ( service , { ... configs , failOnWarnings : true } ) ;
164+ const gitLab = createGitLab ( service , warningConfigs ) ;
136165
137166 const result = await gitLab . report ( [
138167 touchFileError ,
139168 untouchedError ,
140169 untouchedWarning ,
141170 ] ) ;
142-
143171 expect ( result ) . toBe ( false ) ;
144172 } ) ;
145173
146- it ( 'should returns false when there is some warnings' , async ( ) => {
174+ it ( 'should return false when there is some warnings' , async ( ) => {
147175 const service = new MrServiceMock ( ) ;
148- const gitLab = createGitLab ( service , { ... configs , failOnWarnings : true } ) ;
176+ const gitLab = createGitLab ( service , warningConfigs ) ;
149177
150178 const result = await gitLab . report ( [
151179 touchFileWarning ,
152180 untouchedError ,
153181 untouchedWarning ,
154182 ] ) ;
155-
156183 expect ( result ) . toBe ( false ) ;
157184 } ) ;
158185 } ) ;
0 commit comments