Skip to content

Commit af4f464

Browse files
authored
fix(amazonq): avoid apply fix if already applied (#5013)
* fix(amazonq): avoid apply fix if already applied * fix tests
1 parent 4512e20 commit af4f464

File tree

2 files changed

+39
-33
lines changed

2 files changed

+39
-33
lines changed

packages/core/src/codewhisperer/commands/basicCommands.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,17 @@ export const installAmazonQExtension = Commands.declare(
325325
}
326326
)
327327

328+
// Temporary workaround to avoid errors when pressing "Fix" multiple times from hover.
329+
// There doesn't seem to be a way to close the hover or update the hover after interacting inside it.
330+
// Keep track of which findingIds have already been fixed and exit early.
331+
const fixedFindingIds = new Set()
332+
328333
export const applySecurityFix = Commands.declare(
329334
'aws.amazonq.applySecurityFix',
330335
() => async (issue: CodeScanIssue, filePath: string, source: Component) => {
336+
if (fixedFindingIds.has(issue.findingId)) {
337+
return
338+
}
331339
const [suggestedFix] = issue.suggestedFixes
332340
if (!suggestedFix || !filePath) {
333341
return
@@ -371,6 +379,7 @@ export const applySecurityFix = Commands.declare(
371379
}
372380

373381
await closeSecurityIssueWebview(issue.findingId)
382+
fixedFindingIds.add(issue.findingId)
374383
} catch (err) {
375384
getLogger().error(`Apply fix command failed. ${err}`)
376385
applyFixTelemetryEntry.result = 'Failed'

packages/core/src/test/codewhisperer/commands/basicCommands.test.ts

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,14 @@ import {
4949
} from '../../../codewhisperer/ui/codeWhispererNodes'
5050
import { waitUntil } from '../../../shared/utilities/timeoutUtils'
5151
import { listCodeWhispererCommands } from '../../../codewhisperer/ui/statusBarMenu'
52-
import { CodeScansState, CodeSuggestionsState, codeScanState } from '../../../codewhisperer/models/model'
52+
import { CodeScanIssue, CodeScansState, CodeSuggestionsState, codeScanState } from '../../../codewhisperer/models/model'
5353
import { cwQuickPickSource } from '../../../codewhisperer/commands/types'
5454
import { refreshStatusBar } from '../../../codewhisperer/service/inlineCompletionService'
5555
import { focusAmazonQPanel } from '../../../codewhispererChat/commands/registerCommands'
5656
import * as diagnosticsProvider from '../../../codewhisperer/service/diagnosticsProvider'
5757
import { SecurityIssueHoverProvider } from '../../../codewhisperer/service/securityIssueHoverProvider'
5858
import { SecurityIssueCodeActionProvider } from '../../../codewhisperer/service/securityIssueCodeActionProvider'
59+
import { randomUUID } from '../../../common/crypto'
5960

6061
describe('CodeWhisperer-basicCommands', function () {
6162
let targetCommand: Command<any> & vscode.Disposable
@@ -414,6 +415,7 @@ describe('CodeWhisperer-basicCommands', function () {
414415
let applyEditMock: sinon.SinonStub
415416
let removeDiagnosticMock: sinon.SinonStub
416417
let removeIssueMock: sinon.SinonStub
418+
let codeScanIssue: CodeScanIssue
417419

418420
beforeEach(function () {
419421
sandbox = sinon.createSandbox()
@@ -422,6 +424,9 @@ describe('CodeWhisperer-basicCommands', function () {
422424
applyEditMock = sinon.stub()
423425
removeDiagnosticMock = sinon.stub()
424426
removeIssueMock = sinon.stub()
427+
codeScanIssue = createCodeScanIssue({
428+
findingId: randomUUID(),
429+
})
425430
})
426431

427432
afterEach(function () {
@@ -443,14 +448,12 @@ describe('CodeWhisperer-basicCommands', function () {
443448
sandbox.stub(SecurityIssueCodeActionProvider.instance, 'removeIssue').value(removeIssueMock)
444449

445450
targetCommand = testCommand(applySecurityFix)
446-
const codeScanIssue = createCodeScanIssue({
447-
suggestedFixes: [
448-
{
449-
description: 'fix',
450-
code: '@@ -1,3 +1,3 @@\n first line\n- second line\n+ third line\n fourth line',
451-
},
452-
],
453-
})
451+
codeScanIssue.suggestedFixes = [
452+
{
453+
description: 'fix',
454+
code: '@@ -1,3 +1,3 @@\n first line\n- second line\n+ third line\n fourth line',
455+
},
456+
]
454457
await targetCommand.execute(codeScanIssue, fileName, 'hover')
455458
assert.ok(
456459
replaceMock.calledOnceWith(
@@ -487,14 +490,12 @@ describe('CodeWhisperer-basicCommands', function () {
487490
await CodeScansState.instance.setScansEnabled(false)
488491

489492
targetCommand = testCommand(applySecurityFix)
490-
const codeScanIssue = createCodeScanIssue({
491-
suggestedFixes: [
492-
{
493-
description: 'fix',
494-
code: '@@ -1,3 +1,3 @@\n first line\n- second line\n+ third line\n fourth line',
495-
},
496-
],
497-
})
493+
codeScanIssue.suggestedFixes = [
494+
{
495+
description: 'fix',
496+
code: '@@ -1,3 +1,3 @@\n first line\n- second line\n+ third line\n fourth line',
497+
},
498+
]
498499
await targetCommand.execute(codeScanIssue, fileName, 'hover')
499500
assert.ok(
500501
replaceMock.calledOnceWith(
@@ -523,14 +524,12 @@ describe('CodeWhisperer-basicCommands', function () {
523524
sandbox.stub(vscode.workspace, 'openTextDocument').value(openTextDocumentMock)
524525

525526
targetCommand = testCommand(applySecurityFix)
526-
const codeScanIssue = createCodeScanIssue({
527-
suggestedFixes: [
528-
{
529-
code: '@@ -1,1 -1,1 @@\n-mock\n+line5',
530-
description: 'dummy',
531-
},
532-
],
533-
})
527+
codeScanIssue.suggestedFixes = [
528+
{
529+
code: '@@ -1,1 -1,1 @@\n-mock\n+line5',
530+
description: 'dummy',
531+
},
532+
]
534533
await targetCommand.execute(codeScanIssue, 'test.py', 'webview')
535534

536535
assert.strictEqual(getTestWindow().shownMessages[0].message, 'Failed to apply suggested code fix.')
@@ -557,14 +556,12 @@ describe('CodeWhisperer-basicCommands', function () {
557556
sinon.stub(vscode.workspace, 'applyEdit').value(applyEditMock)
558557

559558
targetCommand = testCommand(applySecurityFix)
560-
const codeScanIssue = createCodeScanIssue({
561-
suggestedFixes: [
562-
{
563-
description: 'fix',
564-
code: '@@ -1,3 +1,3 @@\n first line\n- second line\n+ third line\n fourth line',
565-
},
566-
],
567-
})
559+
codeScanIssue.suggestedFixes = [
560+
{
561+
description: 'fix',
562+
code: '@@ -1,3 +1,3 @@\n first line\n- second line\n+ third line\n fourth line',
563+
},
564+
]
568565
await targetCommand.execute(codeScanIssue, fileName, 'quickfix')
569566

570567
assert.ok(replaceMock.calledOnce)

0 commit comments

Comments
 (0)