Skip to content

Commit c1751e2

Browse files
authored
fix: Respect all comments in lastComment validator and comment action (#755)
1 parent 196099e commit c1751e2

File tree

9 files changed

+65
-16
lines changed

9 files changed

+65
-16
lines changed

__fixtures__/unit/helper.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,10 @@ module.exports = {
207207
resolve({ status: 204 })
208208
})
209209
},
210-
listComments: () => {
211-
return { data: (options.listComments) ? options.listComments : [] }
210+
listComments: {
211+
endpoint: {
212+
merge: () => Promise.resolve({ data: (options.comments) ? options.comments : [] })
213+
}
212214
},
213215
createComment: jest.fn().mockReturnValue(options.createComment || 'createComment call success'),
214216
deleteComment: jest.fn().mockReturnValue(options.deleteComment || 'deleteComment call success'),
@@ -253,5 +255,10 @@ module.exports = {
253255
context.probotContext.config = () => {
254256
return Promise.resolve(yaml.safeLoad(configString))
255257
}
258+
},
259+
260+
flushPromises: () => {
261+
// https://stackoverflow.com/questions/49405338/jest-test-promise-resolution-and-event-loop-tick
262+
return new Promise(resolve => setImmediate(resolve))
256263
}
257264
}

__tests__/unit/actions/comment.test.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ test.each([
3333
}]
3434

3535
await comment.afterValidate(context, settings, '', schedulerResult)
36+
await Helper.flushPromises()
37+
3638
expect(context.octokit.issues.createComment.mock.calls.length).toBe(1)
3739
})
3840

@@ -49,6 +51,8 @@ test('check that comment created when afterValidate is called with proper parame
4951
}
5052

5153
await comment.afterValidate(context, settings, '', result)
54+
await Helper.flushPromises()
55+
5256
expect(context.octokit.issues.createComment.mock.calls.length).toBe(1)
5357
expect(context.octokit.issues.createComment.mock.calls[0][0].body).toBe('Your run has returned the following status: pass')
5458
})
@@ -64,6 +68,8 @@ test('that comment is created three times when result contain three issues found
6468
}
6569
}]
6670
await comment.afterValidate(context, settings, '', schedulerResult)
71+
await Helper.flushPromises()
72+
6773
expect(context.octokit.issues.createComment.mock.calls.length).toBe(3)
6874
})
6975

@@ -93,6 +99,8 @@ test('check that old comments from Mergeable are deleted if they exists', async
9399
}
94100

95101
await comment.afterValidate(context, settings, '', result)
102+
await Helper.flushPromises()
103+
96104
expect(context.octokit.issues.deleteComment.mock.calls.length).toBe(1)
97105
expect(context.octokit.issues.deleteComment.mock.calls[0][0].comment_id).toBe('2')
98106
})
@@ -123,6 +131,8 @@ test('check that old comments checks toLowerCase of the Bot name', async () => {
123131
}
124132

125133
await comment.afterValidate(context, settings, '', result)
134+
await Helper.flushPromises()
135+
126136
expect(context.octokit.issues.deleteComment.mock.calls.length).toBe(1)
127137
expect(context.octokit.issues.deleteComment.mock.calls[0][0].comment_id).toBe('2')
128138
})
@@ -156,6 +166,7 @@ test('error handling includes removing old error comments and creating new error
156166
}
157167

158168
await comment.handleError(context, payload)
169+
159170
expect(context.octokit.issues.deleteComment.mock.calls.length).toBe(1)
160171
expect(context.octokit.issues.deleteComment.mock.calls[0][0].comment_id).toBe('3')
161172
expect(context.octokit.issues.createComment.mock.calls[0][0].body).toBe(payload.body)
@@ -187,6 +198,7 @@ test('remove error comments only remove comments that includes "error" ', async
187198
const context = createMockContext(listComments)
188199

189200
await comment.removeErrorComments(context, comment)
201+
190202
expect(context.octokit.issues.deleteComment.mock.calls.length).toBe(1)
191203
expect(context.octokit.issues.deleteComment.mock.calls[0][0].comment_id).toBe('3')
192204
})
@@ -224,6 +236,7 @@ test('check that leave_old_comment option works', async () => {
224236
}
225237

226238
await comment.afterValidate(context, settings, '', result)
239+
227240
expect(context.octokit.issues.deleteComment.mock.calls.length).toBe(0)
228241
})
229242

@@ -240,6 +253,7 @@ test('remove Error comment fail gracefully if payload does not exists', async ()
240253
}
241254

242255
await comment.removeErrorComments(context)
256+
243257
expect(context.octokit.issues.deleteComment.mock.calls.length).toBe(0)
244258
})
245259

@@ -253,11 +267,13 @@ test('error handling includes removing old error comments and creating new error
253267
}
254268

255269
await comment.afterValidate(context, settings, '', result)
270+
await Helper.flushPromises()
271+
256272
expect(context.octokit.issues.createComment.mock.calls[0][0].body).toBe('creator , do something!')
257273
})
258274

259-
const createMockContext = (listComments, eventName = undefined, event = undefined) => {
260-
const context = Helper.mockContext({ listComments, eventName, event })
275+
const createMockContext = (comments, eventName = undefined, event = undefined) => {
276+
const context = Helper.mockContext({ comments, eventName, event })
261277

262278
context.octokit.issues.createComment = jest.fn()
263279
context.octokit.issues.deleteComment = jest.fn()

__tests__/unit/github/api.test.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ describe('listFiles', () => {
99
expect(res[0]).toEqual({ filename: 'abc.js', additions: 0, deletions: 0, changes: 0, status: 'modified' })
1010
})
1111

12+
test('that pagination is used', async () => {
13+
const context = Helper.mockContext()
14+
await GithubAPI.listFiles(context)
15+
expect(context.octokit.paginate.mock.calls.length).toBe(1)
16+
})
17+
1218
test('that error are re-thrown', async () => {
1319
const context = Helper.mockContext()
1420
context.octokit.pulls.listFiles.endpoint.merge = jest.fn().mockRejectedValue({ status: 402 })
@@ -259,14 +265,20 @@ describe('createComment', () => {
259265

260266
describe('listComments', () => {
261267
test('return correct data if no error', async () => {
262-
const res = await GithubAPI.listComments(Helper.mockContext({ listComments: [{ user: { login: 'mergeable[bot]' } }, { user: { login: 'userA' } }] }))
263-
expect(res.data.length).toEqual(2)
264-
expect(res.data[0].user.login).toEqual('mergeable[bot]')
268+
const res = await GithubAPI.listComments(Helper.mockContext({ comments: [{ user: { login: 'mergeable[bot]' } }, { user: { login: 'userA' } }] }))
269+
expect(res.length).toEqual(2)
270+
expect(res[0].user.login).toEqual('mergeable[bot]')
271+
})
272+
273+
test('that pagination is used', async () => {
274+
const context = Helper.mockContext()
275+
await GithubAPI.listComments(context)
276+
expect(context.octokit.paginate.mock.calls.length).toBe(1)
265277
})
266278

267279
test('that error are re-thrown', async () => {
268280
const context = Helper.mockContext()
269-
context.octokit.issues.listComments = jest.fn().mockRejectedValue({ status: 402 })
281+
context.octokit.issues.listComments.endpoint.merge = jest.fn().mockRejectedValue({ status: 402 })
270282

271283
try {
272284
await GithubAPI.listComments(context)
@@ -680,6 +692,12 @@ describe('listReviews', () => {
680692
expect(res).toEqual(reviews)
681693
})
682694

695+
test('that pagination is used', async () => {
696+
const context = Helper.mockContext()
697+
await GithubAPI.listReviews(context)
698+
expect(context.octokit.paginate.mock.calls.length).toBe(1)
699+
})
700+
683701
test('that error are re-thrown', async () => {
684702
const context = Helper.mockContext()
685703
context.octokit.pulls.listReviews.endpoint.merge = jest.fn().mockRejectedValue({ status: 402 })
@@ -725,6 +743,12 @@ describe('listCommits', () => {
725743
expect(res[0].committer.email).toEqual('[email protected]')
726744
})
727745

746+
test('that pagination is used', async () => {
747+
const context = Helper.mockContext()
748+
await GithubAPI.listCommits(context)
749+
expect(context.octokit.paginate.mock.calls.length).toBe(1)
750+
})
751+
728752
test('that error are NOT re-thrown', async () => {
729753
const context = Helper.mockContext()
730754
context.octokit.pulls.listCommits.endpoint.merge = jest.fn().mockRejectedValue({ status: 402 })

__tests__/unit/validators/approvals.test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,6 @@ test('validate correctly with reviews more than 30.', async () => {
317317
})
318318
expect(validation.validations[0].details.input).toEqual(['user2', 'user1'])
319319
expect(validation.status).toBe('pass')
320-
// ensure paginate was called
321-
expect(context.octokit.paginate.mock.calls.length).toBe(1)
322320
})
323321

324322
test('pr creator is removed from required reviewer list', async () => {

__tests__/unit/validators/lastComment.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,5 +122,5 @@ test('complex Logic test', async () => {
122122
})
123123

124124
function createMockContext (comments) {
125-
return Helper.mockContext({ listComments: Array.isArray(comments) ? comments.map(comment => ({ body: comment })) : [{ body: comments }] })
125+
return Helper.mockContext({ comments: Array.isArray(comments) ? comments.map(comment => ({ body: comment })) : [{ body: comments }] })
126126
}

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
CHANGELOG
22
=====================================
3+
| June 20, 2024: fix: Respect all comments in lastComment validator and comment action `#755 <https://github.com/mergeability/mergeable/pull/755>`_
34
| June 12, 2024: feat: Support `issue_comment` event as trigger for actions `#754 <https://github.com/mergeability/mergeable/pull/754>`_
45
| June 10, 2024: fix: Docker image not working `#753 <https://github.com/mergeability/mergeable/pull/753>`_
56
| June 10, 2024: feat: publish multi arch docker image to dockerhub `#751 <https://github.com/mergeability/mergeable/pull/751>`_

lib/actions/comment.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const fetchCommentsByMergeable = async (context, issueNumber, actionObj) => {
1414
const comments = await actionObj.githubAPI.listComments(context, issueNumber)
1515

1616
const botName = process.env.APP_NAME ? process.env.APP_NAME : 'Mergeable'
17-
return comments.data.filter(comment => comment.user.login.toLowerCase() === `${botName.toLowerCase()}[bot]`)
17+
return comments.filter(comment => comment.user.login.toLowerCase() === `${botName.toLowerCase()}[bot]`)
1818
}
1919

2020
const deleteOldComments = async (context, oldComments, actionObj) => {

lib/github/api.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class GithubAPI {
166166
debugLog(context, callFn)
167167

168168
try {
169-
return context.octokit.issues.createComment(
169+
return await context.octokit.issues.createComment(
170170
context.repo({ issue_number: issueNumber, body })
171171
)
172172
} catch (err) {
@@ -180,8 +180,11 @@ class GithubAPI {
180180
debugLog(context, callFn)
181181

182182
try {
183-
return context.octokit.issues.listComments(
184-
context.repo({ issue_number: issueNumber })
183+
return await context.octokit.paginate(
184+
context.octokit.issues.listComments.endpoint.merge(
185+
context.repo({ issue_number: issueNumber })
186+
),
187+
res => res.data
185188
)
186189
} catch (err) {
187190
return checkCommonError(err, context, callFn)

lib/validators/lastComment.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class LastComment extends Validator {
2424
}
2525

2626
async validate (context, validationSettings) {
27-
const comments = (await this.githubAPI.listComments(context, this.getPayload(context).number)).data
27+
const comments = await this.githubAPI.listComments(context, this.getPayload(context).number)
2828

2929
return this.processOptions(
3030
validationSettings,

0 commit comments

Comments
 (0)