Skip to content

Commit

Permalink
feat(scan): cover runScan handler by tests
Browse files Browse the repository at this point in the history
  • Loading branch information
artur committed May 13, 2024
1 parent 740a27c commit 1cf888a
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 24 deletions.
152 changes: 135 additions & 17 deletions src/Commands/RunScan.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
import 'reflect-metadata';
import { Logger, logger } from '../Utils';
import { RunScan } from './RunScan';
import { anything, reset, spy, verify, when } from 'ts-mockito';
import {
AttackParamLocation,
Exclusions,
Module,
RestScans,
Scans,
ScanWarning,
TestType
} from '../Scan';
import {
anything,
instance,
mock,
objectContaining,
reset,
resetCalls,
spy,
verify,
when
} from 'ts-mockito';
import { container } from 'tsyringe';
import { Arguments } from 'yargs';

describe('RunScan', () => {
let processSpy!: NodeJS.Process;
Expand Down Expand Up @@ -68,25 +89,122 @@ describe('RunScan', () => {
});
});

describe('serializeWarnings', () => {
it('should print warnings correctly', () => {
// arrange
const input = [
{
message: 'Notice: Warning 1',
code: '1'
},
{
message: 'Notice: Warning 2',
code: '2'
}
describe('handler', () => {
let runScan: RunScan;
let mockedRestScans: RestScans;

beforeEach(() => {
mockedRestScans = mock(RestScans);
container.registerInstance(Scans, instance(mockedRestScans));
resetCalls(mockedRestScans);
runScan = new RunScan();
});

afterEach(() => {
container.clearInstances();
reset(mockedRestScans);
});

it('should correctly pass scan config from args', async () => {
const args = {
test: ['test1', 'test2'],
name: 'test-scan',
module: 'test-module',
auth: 'test-auth',
project: 'test-project',
template: 'test-template',
bucket: ['test-bucket'],
hostFilter: ['test-host'],
header: ['header1', 'header2'],
crawler: ['test-crawler'],
archive: 'test-archive',
repeater: ['test-repeater'],
smart: true,
param: ['param1', 'param2'],
excludeEntryPoint: ['exclude-entry-point'],
excludeParam: ['exclude-param'],
_: [],
$0: ''
} as Arguments;

when(processSpy.exit(anything())).thenReturn(undefined);
when(
mockedRestScans.create(
objectContaining({
tests: args.test as TestType[],
name: args.name as string,
module: args.module as Module,
authObjectId: args.auth as string,
projectId: args.project as string,
templateId: args.template as string,
buckets: args.bucket as string[],
hostsFilter: args.hostFilter as string[],
crawlerUrls: args.crawler as string[],
fileId: args.archive as string,
repeaters: args.repeater as string[],
smart: args.smart as boolean,
attackParamLocations: args.param as AttackParamLocation[],
exclusions: {
requests: args.excludeEntryPoint,
params: args.excludeParam
} as Exclusions
})
)
).thenResolve({ id: 'test-scan-id', warnings: [] });

await runScan.handler(args);

verify(processSpy.exit(0)).once();
verify(loggerSpy.error(anything())).never();
verify(loggerSpy.warn(anything())).never();
});

it('should throw an error on create request fall', async () => {
const args = {
name: 'test-scan',
_: [],
$0: ''
} as Arguments;

when(processSpy.exit(anything())).thenReturn(undefined);
when(
mockedRestScans.create(
objectContaining({
name: args.name as string
})
)
).thenReject(new Error('request error'));

await runScan.handler(args);

verify(processSpy.exit(1)).once();
verify(
loggerSpy.error(objectContaining('Error during "scan:run": '))
).once();
});

it('should display warnings when present', async () => {
const args = {
name: 'test-scan',
_: [],
$0: ''
} as Arguments;

const warnings: ScanWarning[] = [
{ message: 'Warning message 1', code: '123' },
{ message: 'Warning message 2', code: '124' }
];

// act
const result = RunScan.serializeWarnings(input);
when(processSpy.exit(anything())).thenReturn(undefined);
when(mockedRestScans.create(anything())).thenResolve({
id: 'test-scan-id',
warnings
});

// assert
expect(result).toEqual('Notice: Warning 1\nNotice: Warning 2');
await runScan.handler(args);

verify(processSpy.exit(0)).once();
verify(loggerSpy.warn('Warning message 1\nWarning message 2\n')).once();
});
});
});
11 changes: 4 additions & 7 deletions src/Commands/RunScan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import {
ScanConfig,
Scans,
TestType,
ATTACK_PARAM_LOCATIONS_DEFAULT,
ScanWarning
ATTACK_PARAM_LOCATIONS_DEFAULT
} from '../Scan';
import { Helpers, logger } from '../Utils';
import { Arguments, Argv, CommandModule } from 'yargs';
Expand Down Expand Up @@ -38,10 +37,6 @@ export class RunScan implements CommandModule {
});
}

public static serializeWarnings(warnings: ScanWarning[]): string {
return `${warnings.map((warning) => warning.message).join('\n')}`;
}

public builder(argv: Argv): Argv {
return argv
.option('token', {
Expand Down Expand Up @@ -204,7 +199,9 @@ export class RunScan implements CommandModule {
console.log(scanId);

if (warnings.length) {
logger.warn(RunScan.serializeWarnings(warnings));
logger.warn(
`${warnings.map((warning) => warning.message).join('\n')}\n`
);
}

process.exit(0);
Expand Down

0 comments on commit 1cf888a

Please sign in to comment.