@@ -28,8 +28,6 @@ import { AuthUtil } from '../../../codewhisperer/util/authUtil'
28
28
import { getTestWindow } from '../../shared/vscode/window'
29
29
import { ExtContext } from '../../../shared/extensions'
30
30
import { get , set } from '../../../codewhisperer/util/commonUtil'
31
- import { MockDocument } from '../../fake/fakeDocument'
32
- import { FileSystemCommon } from '../../../srcShared/fs'
33
31
import { getLogger } from '../../../shared/logger/logger'
34
32
import {
35
33
createAutoScans ,
@@ -55,6 +53,9 @@ import { cwQuickPickSource } from '../../../codewhisperer/commands/types'
55
53
import { isTextEditor } from '../../../shared/utilities/editorUtilities'
56
54
import { refreshStatusBar } from '../../../codewhisperer/service/inlineCompletionService'
57
55
import { focusAmazonQPanel } from '../../../codewhispererChat/commands/registerCommands'
56
+ import * as diagnosticsProvider from '../../../codewhisperer/service/diagnosticsProvider'
57
+ import { SecurityIssueHoverProvider } from '../../../codewhisperer/service/securityIssueHoverProvider'
58
+ import { SecurityIssueCodeActionProvider } from '../../../codewhisperer/service/securityIssueCodeActionProvider'
58
59
59
60
describe ( 'CodeWhisperer-basicCommands' , function ( ) {
60
61
let targetCommand : Command < any > & vscode . Disposable
@@ -392,15 +393,19 @@ describe('CodeWhisperer-basicCommands', function () {
392
393
393
394
describe ( 'applySecurityFix' , function ( ) {
394
395
let sandbox : sinon . SinonSandbox
395
- let saveStub : sinon . SinonStub
396
396
let openTextDocumentMock : sinon . SinonStub
397
- let writeFileMock : sinon . SinonStub
397
+ let replaceMock : sinon . SinonStub
398
+ let applyEditMock : sinon . SinonStub
399
+ let removeDiagnosticMock : sinon . SinonStub
400
+ let removeIssueMock : sinon . SinonStub
398
401
399
402
beforeEach ( function ( ) {
400
403
sandbox = sinon . createSandbox ( )
401
- saveStub = sinon . stub ( )
402
404
openTextDocumentMock = sinon . stub ( )
403
- writeFileMock = sinon . stub ( )
405
+ replaceMock = sinon . stub ( )
406
+ applyEditMock = sinon . stub ( )
407
+ removeDiagnosticMock = sinon . stub ( )
408
+ removeIssueMock = sinon . stub ( )
404
409
} )
405
410
406
411
afterEach ( function ( ) {
@@ -409,14 +414,17 @@ describe('CodeWhisperer-basicCommands', function () {
409
414
410
415
it ( 'should call applySecurityFix command successfully' , async function ( ) {
411
416
const fileName = 'sample.py'
412
- saveStub . resolves ( true )
413
- const textDocumentMock = new MockDocument ( 'first line\n second line\n fourth line' , fileName , saveStub )
417
+ const textDocumentMock = createMockDocument ( 'first line\n second line\n fourth line' , fileName )
414
418
415
419
openTextDocumentMock . resolves ( textDocumentMock )
416
420
sandbox . stub ( vscode . workspace , 'openTextDocument' ) . value ( openTextDocumentMock )
417
421
418
- writeFileMock . resolves ( true )
419
- sinon . stub ( FileSystemCommon . prototype , 'writeFile' ) . value ( writeFileMock )
422
+ sandbox . stub ( vscode . WorkspaceEdit . prototype , 'replace' ) . value ( replaceMock )
423
+ applyEditMock . resolves ( true )
424
+ sandbox . stub ( vscode . workspace , 'applyEdit' ) . value ( applyEditMock )
425
+ sandbox . stub ( diagnosticsProvider , 'removeDiagnostic' ) . value ( removeDiagnosticMock )
426
+ sandbox . stub ( SecurityIssueHoverProvider . instance , 'removeIssue' ) . value ( removeIssueMock )
427
+ sandbox . stub ( SecurityIssueCodeActionProvider . instance , 'removeIssue' ) . value ( removeIssueMock )
420
428
421
429
targetCommand = testCommand ( applySecurityFix )
422
430
const codeScanIssue = createCodeScanIssue ( {
@@ -428,8 +436,16 @@ describe('CodeWhisperer-basicCommands', function () {
428
436
] ,
429
437
} )
430
438
await targetCommand . execute ( codeScanIssue , fileName , 'hover' )
431
- assert . ok ( saveStub . calledOnce )
432
- assert . ok ( writeFileMock . calledOnceWith ( fileName , 'first line\n third line\n fourth line' ) )
439
+ assert . ok (
440
+ replaceMock . calledOnceWith (
441
+ textDocumentMock . uri ,
442
+ new vscode . Range ( 0 , 0 , 2 , 12 ) ,
443
+ 'first line\n third line\n fourth line'
444
+ )
445
+ )
446
+ assert . ok ( applyEditMock . calledOnce )
447
+ assert . ok ( removeDiagnosticMock . calledOnceWith ( textDocumentMock . uri , codeScanIssue ) )
448
+ assert . ok ( removeIssueMock . calledTwice )
433
449
434
450
assertTelemetry ( 'codewhisperer_codeScanIssueApplyFix' , {
435
451
detectorId : codeScanIssue . detectorId ,
@@ -439,83 +455,91 @@ describe('CodeWhisperer-basicCommands', function () {
439
455
} )
440
456
} )
441
457
442
- it ( 'handles patch failure' , async function ( ) {
443
- const textDocumentMock = createMockDocument ( )
458
+ it ( 'should call applySecurityFix command successfully but not remove issues if auto-scans is disabled' , async function ( ) {
459
+ const fileName = 'sample.py'
460
+ const textDocumentMock = createMockDocument ( 'first line\n second line\n fourth line' , fileName )
444
461
445
462
openTextDocumentMock . resolves ( textDocumentMock )
446
-
447
463
sandbox . stub ( vscode . workspace , 'openTextDocument' ) . value ( openTextDocumentMock )
448
464
465
+ sandbox . stub ( vscode . WorkspaceEdit . prototype , 'replace' ) . value ( replaceMock )
466
+ applyEditMock . resolves ( true )
467
+ sandbox . stub ( vscode . workspace , 'applyEdit' ) . value ( applyEditMock )
468
+ sandbox . stub ( diagnosticsProvider , 'removeDiagnostic' ) . value ( removeDiagnosticMock )
469
+ sandbox . stub ( SecurityIssueHoverProvider . instance , 'removeIssue' ) . value ( removeIssueMock )
470
+ sandbox . stub ( SecurityIssueCodeActionProvider . instance , 'removeIssue' ) . value ( removeIssueMock )
471
+ await CodeScansState . instance . setScansEnabled ( false )
472
+
449
473
targetCommand = testCommand ( applySecurityFix )
450
474
const codeScanIssue = createCodeScanIssue ( {
451
475
suggestedFixes : [
452
476
{
453
- code : '@@ -1,1 -1,1 @@\n-mock\n+line5 ' ,
454
- description : 'dummy ' ,
477
+ description : 'fix ' ,
478
+ code : '@@ -1,3 +1,3 @@\n first line\n- second line\n+ third line\n fourth line ' ,
455
479
} ,
456
480
] ,
457
481
} )
458
- await targetCommand . execute ( codeScanIssue , 'test.py' , 'webview' )
482
+ await targetCommand . execute ( codeScanIssue , fileName , 'hover' )
483
+ assert . ok (
484
+ replaceMock . calledOnceWith (
485
+ textDocumentMock . uri ,
486
+ new vscode . Range ( 0 , 0 , 2 , 12 ) ,
487
+ 'first line\n third line\n fourth line'
488
+ )
489
+ )
490
+ assert . ok ( applyEditMock . calledOnce )
491
+ assert . ok ( removeDiagnosticMock . notCalled )
492
+ assert . ok ( removeIssueMock . notCalled )
459
493
460
- assert . strictEqual ( getTestWindow ( ) . shownMessages [ 0 ] . message , 'Failed to apply suggested code fix.' )
461
494
assertTelemetry ( 'codewhisperer_codeScanIssueApplyFix' , {
462
495
detectorId : codeScanIssue . detectorId ,
463
496
findingId : codeScanIssue . findingId ,
464
- component : 'webview' ,
465
- result : 'Failed' ,
466
- reason : 'Error: Failed to get updated content from applying diff patch' ,
497
+ component : 'hover' ,
498
+ result : 'Succeeded' ,
467
499
} )
468
500
} )
469
501
470
- it ( 'handles document save failure' , async function ( ) {
471
- const fileName = 'sample.py'
472
- saveStub . resolves ( false )
473
- const textDocumentMock = new MockDocument ( 'first line\n second line\n fourth line' , fileName , saveStub )
502
+ it ( 'handles patch failure' , async function ( ) {
503
+ const textDocumentMock = createMockDocument ( )
474
504
475
505
openTextDocumentMock . resolves ( textDocumentMock )
476
506
477
507
sandbox . stub ( vscode . workspace , 'openTextDocument' ) . value ( openTextDocumentMock )
478
- const loggerStub = sinon . stub ( getLogger ( ) , 'error' )
479
508
480
509
targetCommand = testCommand ( applySecurityFix )
481
510
const codeScanIssue = createCodeScanIssue ( {
482
511
suggestedFixes : [
483
512
{
484
- description : 'fix ' ,
485
- code : '@@ -1,3 +1,3 @@\n first line\n- second line\n+ third line\n fourth line ' ,
513
+ code : '@@ -1,1 -1,1 @@\n-mock\n+line5 ' ,
514
+ description : 'dummy ' ,
486
515
} ,
487
516
] ,
488
517
} )
489
- await targetCommand . execute ( codeScanIssue , fileName , 'quickfix ' )
518
+ await targetCommand . execute ( codeScanIssue , 'test.py' , 'webview ' )
490
519
491
- assert . ok ( saveStub . calledOnce )
492
- assert . ok ( loggerStub . calledOnce )
493
- const actual = loggerStub . getCall ( 0 ) . args [ 0 ]
494
- assert . strictEqual (
495
- actual ,
496
- 'Apply fix command failed. Error: Failed to save editor text changes into the file.'
497
- )
520
+ assert . strictEqual ( getTestWindow ( ) . shownMessages [ 0 ] . message , 'Failed to apply suggested code fix.' )
498
521
assertTelemetry ( 'codewhisperer_codeScanIssueApplyFix' , {
499
522
detectorId : codeScanIssue . detectorId ,
500
523
findingId : codeScanIssue . findingId ,
501
- component : 'quickfix ' ,
524
+ component : 'webview ' ,
502
525
result : 'Failed' ,
503
- reason : 'Error: Failed to save editor text changes into the file. ' ,
526
+ reason : 'Error: Failed to get updated content from applying diff patch ' ,
504
527
} )
505
528
} )
506
529
507
- it ( 'handles document write failure' , async function ( ) {
530
+ it ( 'handles apply edit failure' , async function ( ) {
508
531
const fileName = 'sample.py'
509
- saveStub . resolves ( true )
510
- const textDocumentMock = new MockDocument ( 'first line\n second line\n fourth line' , fileName , saveStub )
532
+ const textDocumentMock = createMockDocument ( 'first line\n second line\n fourth line' , fileName )
511
533
512
534
openTextDocumentMock . resolves ( textDocumentMock )
513
- writeFileMock . rejects ( 'Error: Writing to file failed.' )
514
535
515
536
sandbox . stub ( vscode . workspace , 'openTextDocument' ) . value ( openTextDocumentMock )
516
- sinon . stub ( FileSystemCommon . prototype , 'writeFile' ) . value ( writeFileMock )
517
537
const loggerStub = sinon . stub ( getLogger ( ) , 'error' )
518
538
539
+ sinon . stub ( vscode . WorkspaceEdit . prototype , 'replace' ) . value ( replaceMock )
540
+ applyEditMock . resolves ( false )
541
+ sinon . stub ( vscode . workspace , 'applyEdit' ) . value ( applyEditMock )
542
+
519
543
targetCommand = testCommand ( applySecurityFix )
520
544
const codeScanIssue = createCodeScanIssue ( {
521
545
suggestedFixes : [
@@ -525,18 +549,18 @@ describe('CodeWhisperer-basicCommands', function () {
525
549
} ,
526
550
] ,
527
551
} )
528
- await targetCommand . execute ( codeScanIssue , fileName , 'hover ' )
552
+ await targetCommand . execute ( codeScanIssue , fileName , 'quickfix ' )
529
553
530
- assert . ok ( saveStub . calledOnce )
554
+ assert . ok ( replaceMock . calledOnce )
531
555
assert . ok ( loggerStub . calledOnce )
532
556
const actual = loggerStub . getCall ( 0 ) . args [ 0 ]
533
- assert . strictEqual ( actual , 'Apply fix command failed. Error: Writing to file failed .' )
557
+ assert . strictEqual ( actual , 'Apply fix command failed. Error: Failed to apply edit to the workspace .' )
534
558
assertTelemetry ( 'codewhisperer_codeScanIssueApplyFix' , {
535
559
detectorId : codeScanIssue . detectorId ,
536
560
findingId : codeScanIssue . findingId ,
537
- component : 'hover ' ,
561
+ component : 'quickfix ' ,
538
562
result : 'Failed' ,
539
- reason : 'Error: Writing to file failed .' ,
563
+ reason : 'Error: Failed to apply edit to the workspace .' ,
540
564
} )
541
565
} )
542
566
} )
0 commit comments