diff --git a/README.md b/README.md index 1c650890..b3429306 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# tsc +# code-client Typescript consumer of public API @@ -16,17 +16,16 @@ $ npm install --save @snyk/code-client ### Creates and initializes an instance ```javascript -import tsc from '@snyk/code-client'; +import codeClient from '@snyk/code-client'; // An address of server which will be used in order to send code and analyse it. const baseURL = 'https://www.snyk.io'; - ``` ### Requests the creation of a new login session ```javascript -const loginResponse = await tsc.startSession({ +const loginResponse = await codeClient.startSession({ baseURL, // An identificator for the editor using the Snyk APIs source: 'atom', @@ -40,8 +39,9 @@ const { sessionToken, loginURL } = loginResponse.value; ``` ### Checks status of the login process + ```javascript -const sessionResponse = await tsc.checkSession({ baseURL, sessionToken }); +const sessionResponse = await codeClient.checkSession({ baseURL, sessionToken }); if (sessionResponse.type === 'error') { // Handle error and alert user } @@ -53,33 +53,48 @@ const isLoggedIn = sessionResponse.value; // boolean ```javascript /** Building bundle process started with provided data */ -tsc.emitter.on('scanFilesProgress', (processed: number) = { +codeClient.emitter.on('scanFilesProgress', (processed: number) = { console.log(`Indexed ${processed} files`); }); /** Bundle upload process is started with provided data */ -tsc.emitter.on('uploadBundleProgress', (processed: number, total: number) => { +codeClient.emitter.on('uploadBundleProgress', (processed: number, total: number) => { console.log(`Upload bundle progress: ${processed}/${total}`); }); /** Receives an error object and logs an error message */ -tsc.emitter.on('sendError', error => { +codeClient.emitter.on('sendError', error => { console.log(error); }); + +/** Logs HTTP requests sent to the API **/ +codeClient.emitter.on('apiRequestLog', (message) => { + console.log(message); +}); + ``` Complete list of events: - - supportedFilesLoaded: uploading supported file extensions, can be also used for instantiating file watcher - - scanFilesProgress: emits a number of files being found - - createBundleProgress: emits a progress in instantiating packages for analysis - - uploadBundleProgress: emits a progress in uploading files - - analyseProgress: emits a progress in analysis job - - error: emits in case of an error + +- supportedFilesLoaded: uploading supported file extensions, can be also used for instantiating file watcher +- scanFilesProgress: emits a number of files being found +- createBundleProgress: emits a progress in instantiating packages for analysis +- uploadBundleProgress: emits a progress in uploading files +- analyseProgress: emits a progress in analysis job +- error: emits in case of an error ### Run analysis ```javascript -const bundle = await tsc.analyzeFolders(baseURL, sessionToken, false, 1, ['/home/user/repo']); +const bundle = await codeClient.analyzeFolders({ + baseURL, + sessionToken, + includeLint: false, + severity: 1, + paths: ['/home/user/repo'], + sarif, + source, +}); // bundle implements interface IFileBundle: // readonly baseURL: string; @@ -97,7 +112,7 @@ const bundle = await tsc.analyzeFolders(baseURL, sessionToken, false, 1, ['/home ### Creates a new bundle based on a previously uploaded one ```javascript -const result = await tsc.extendBundle({ +const result = await codeClient.extendBundle({ sessionToken, bundleId, files: { @@ -112,8 +127,15 @@ const { bundleId, missingFiles, uploadURL } = result; ### Run analysis of remote git repository ```javascript - -const bundle = await analyzeGit(baseURL, sessionToken, false, 1, 'git@github.com:DeepCodeAI/cli.git@320d98a6896f5376efe6cefefb6e70b46b97d566'); +const bundle = await analyzeGit({ + baseURL, + sessionToken, + includeLint: false, + severity: 1, + gitUri: 'git@github.com:DeepCodeAI/cli.git@320d98a6896f5376efe6cefefb6e70b46b97d566', + sarif: true, + source, +}); // bundle implements interface IGitBundle // readonly baseURL: string; diff --git a/development.md b/development.md index 8d3e7b8e..9d762e68 100644 --- a/development.md +++ b/development.md @@ -1,12 +1,14 @@ # Package development notes To use and debug package locally you don't need publish it to NPM registry: + ```shell script $ cd $ npm install && npm run build && npx yalc publish ``` After that you have to create symlink to your package in your project folder: + ```shell script $ cd $ npx yalc add @snyk/code-client @@ -17,6 +19,7 @@ $ npx yalc add @snyk/code-client ### Before publishing make sure test pass Test variables: + - `SNYK_URL` is the DC server URL (staging deployment if not provided) - `SNYK_API_KEY` is a sessionToken of a user with access to the Snyk - `SNYK_API_KEY_NO_ACCESS` is a sessionToken of a user with no access to the snyk organization (even better if on a different platform than GitHub) diff --git a/src/analysis.ts b/src/analysis.ts index 97feb4d6..20335094 100644 --- a/src/analysis.ts +++ b/src/analysis.ts @@ -31,6 +31,12 @@ import { IFileBundle, IBundleResult, } from './interfaces/analysis-result.interface'; +import { + FolderOptions, + AnalyzeFoldersOptions, + AnalyzeGitOptions, + GitOptions, +} from './interfaces/analysis-options.interface'; const sleep = (duration: number) => new Promise(resolve => setTimeout(resolve, duration)); @@ -43,6 +49,7 @@ async function pollAnalysis({ oAuthToken, username, limitToFiles, + source, }: { baseURL: string; sessionToken: string; @@ -52,6 +59,7 @@ async function pollAnalysis({ oAuthToken?: string; username?: string; limitToFiles?: string[]; + source: string; }): Promise> { let analysisResponse: IResult; let analysisData: GetAnalysisResponseDto; @@ -73,6 +81,7 @@ async function pollAnalysis({ includeLint, severity, limitToFiles, + source, }); if (analysisResponse.type === 'error') { @@ -111,6 +120,7 @@ export async function analyzeBundle({ oAuthToken, username, limitToFiles, + source, }: { baseURL: string; sessionToken: string; @@ -120,6 +130,7 @@ export async function analyzeBundle({ oAuthToken?: string; username?: string; limitToFiles?: string[]; + source: string; }): Promise { // Call remote bundle for analysis results and emit intermediate progress const analysisData = await pollAnalysis({ @@ -131,6 +142,7 @@ export async function analyzeBundle({ includeLint, severity, limitToFiles, + source, }); if (analysisData.type === 'error') { @@ -203,21 +215,35 @@ function mergeBundleResults(bundle: IFileBundle, analysisData: IBundleResult, li analysisResults, }; } +let analyzeFolderDefaults = { + baseURL: defaultBaseURL, + sessionToken: '', + includeLint: false, + severity: AnalysisSeverity.info, + symlinksEnabled: false, + maxPayload: MAX_PAYLOAD, + defaultFileIgnores: IGNORES_DEFAULT, + sarif: false, + source: '', +}; +export async function analyzeFolders(options: FolderOptions): Promise { + const analysisOptions: AnalyzeFoldersOptions = { ...analyzeFolderDefaults, ...options }; + const { + baseURL, + sessionToken, + includeLint, + severity, + paths, + symlinksEnabled, + maxPayload, + defaultFileIgnores, + sarif, + source, + } = analysisOptions; -export async function analyzeFolders( - baseURL = defaultBaseURL, - sessionToken = '', - includeLint = false, - severity = AnalysisSeverity.info, - paths: string[], - symlinksEnabled = false, - maxPayload = MAX_PAYLOAD, - defaultFileIgnores = IGNORES_DEFAULT, - sarif = false, -): Promise { // Get supported filters and test baseURL for correctness and availability emitter.supportedFilesLoaded(null); - const resp = await getFilters(baseURL); + const resp = await getFilters(baseURL, source); if (resp.type === 'error') { throw resp.error; } @@ -249,7 +275,7 @@ export async function analyzeFolders( // Create remote bundle const remoteBundle = bundleFiles.length - ? await remoteBundleFactory(baseURL, sessionToken, bundleFiles, [], baseDir, null, maxPayload) + ? await remoteBundleFactory(baseURL, sessionToken, bundleFiles, [], baseDir, null, maxPayload, source) : null; // Analyze bundle @@ -271,11 +297,12 @@ export async function analyzeFolders( }; } else { analysisData = await analyzeBundle({ - baseURL, - sessionToken, - includeLint, - severity, + baseURL: baseURL, + sessionToken: sessionToken, + includeLint: includeLint!, + severity: severity!, bundleId: remoteBundle.bundleId, + source, }); analysisData.analysisResults.files = normalizeResultFiles(analysisData.analysisResults.files, baseDir); } @@ -303,6 +330,7 @@ export async function extendAnalysis( bundle: IFileBundle, filePaths: string[], maxPayload = MAX_PAYLOAD, + source: string, ): Promise { const { files, removedFiles } = await prepareExtendingBundle( bundle.baseDir, @@ -326,6 +354,7 @@ export async function extendAnalysis( bundle.baseDir, bundle.bundleId, maxPayload, + source, ); if (remoteBundle === null) { @@ -341,6 +370,7 @@ export async function extendAnalysis( severity: bundle.severity, bundleId: remoteBundle.bundleId, limitToFiles: files.map(f => f.bundlePath), + source, }); // Transform relative paths into absolute analysisData.analysisResults.files = normalizeResultFiles(analysisData.analysisResults.files, bundle.baseDir); @@ -353,22 +383,30 @@ export async function extendAnalysis( ); } -export async function analyzeGit( - baseURL = defaultBaseURL, - sessionToken = '', - includeLint = false, - severity = AnalysisSeverity.info, - gitUri: string, - sarif = false, - oAuthToken?: string, - username?: string, -): Promise { - const bundleResponse = await createGitBundle({ baseURL, sessionToken, oAuthToken, username, gitUri }); +const analyzeGitDefaults = { + baseURL: defaultBaseURL, + sessionToken: '', + includeLint: false, + severity: AnalysisSeverity.info, + sarif: false, + source: '', +}; + +export async function analyzeGit(options: GitOptions): Promise { + const analysisOptions: AnalyzeGitOptions = { ...analyzeGitDefaults, ...options }; + const { baseURL, sessionToken, oAuthToken, username, includeLint, severity, gitUri, sarif, source } = analysisOptions; + const bundleResponse = await createGitBundle({ + baseURL, + sessionToken, + oAuthToken, + username, + gitUri, + source, + }); if (bundleResponse.type === 'error') { throw bundleResponse.error; } const { bundleId } = bundleResponse.value; - const analysisData = await analyzeBundle({ baseURL, sessionToken, @@ -377,6 +415,7 @@ export async function analyzeGit( includeLint, severity, bundleId, + source, }); const result = { diff --git a/src/axios.ts b/src/axios.ts index 0ad7ace3..78be97ae 100644 --- a/src/axios.ts +++ b/src/axios.ts @@ -1,5 +1,6 @@ import axios, { AxiosRequestConfig, AxiosError, AxiosResponse } from 'axios'; - +import { LOGGING } from './constants'; +import emitter from './emitter'; const { NODE_ENV } = process.env; const axios_ = axios.create({ @@ -9,31 +10,29 @@ const axios_ = axios.create({ }, }); -if (NODE_ENV !== 'test') { - axios_.interceptors.request.use( - (config: AxiosRequestConfig) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const { method, url, data } = config; - console.log(`=> HTTP ${method?.toUpperCase()} ${url} ${data ? JSON.stringify(data) : ''}`.slice(0, 399)); +axios_.interceptors.request.use( + (config: AxiosRequestConfig) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const { method, url, data } = config; + emitter.apiRequestLog(`=> HTTP ${method?.toUpperCase()} ${url} ${data ? JSON.stringify(data) : ''}`.slice(0, 399)); - return config; - }, - (error: AxiosError) => { - console.error(`Request error --> ${error.message}`); - throw error; - }, - ); + return config; + }, + (error: AxiosError) => { + emitter.apiRequestLog(`Request error --> ${error.message}`); + throw error; + }, +); - axios_.interceptors.response.use( - (response: AxiosResponse) => { - console.log(`<= Response: ${response.status} ${JSON.stringify(response.data)}`.slice(0, 399)); - return response; - }, - (error: AxiosError) => { - console.warn(`Response error --> ${error.message}`); - throw error; - }, - ); -} +axios_.interceptors.response.use( + (response: AxiosResponse) => { + emitter.apiRequestLog(`<= Response: ${response.status} ${JSON.stringify(response.data)}`.slice(0, 399)); + return response; + }, + (error: AxiosError) => { + emitter.apiRequestLog(`Response error --> ${error.message}`); + throw error; + }, +); export default axios_; diff --git a/src/bundles.ts b/src/bundles.ts index 7ad1d98a..de379c24 100644 --- a/src/bundles.ts +++ b/src/bundles.ts @@ -27,6 +27,7 @@ async function* prepareRemoteBundle( removedFiles: string[] = [], existingBundleId: string | null = null, maxPayload = MAX_PAYLOAD, + source: string, ): AsyncGenerator> { let response: IResult; let bundleId = existingBundleId; @@ -42,6 +43,7 @@ async function* prepareRemoteBundle( baseURL, sessionToken, files: paramFiles, + source, }); } else { // eslint-disable-next-line no-await-in-loop @@ -153,8 +155,17 @@ export async function remoteBundleFactory( baseDir: string, existingBundleId: string | null = null, maxPayload = MAX_PAYLOAD, + source: string, ): Promise { - const bundleFactory = prepareRemoteBundle(baseURL, sessionToken, files, removedFiles, existingBundleId, maxPayload); + const bundleFactory = prepareRemoteBundle( + baseURL, + sessionToken, + files, + removedFiles, + existingBundleId, + maxPayload, + source, + ); let remoteBundle: RemoteBundle | null = null; for await (const response of bundleFactory) { diff --git a/src/constants.ts b/src/constants.ts index 1a5c158d..5829c0cd 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -21,6 +21,8 @@ export const DCIGNORE_DRAFTS = { default: DefaultDCIgnore, }; +export let LOGGING = false; + // eslint-disable-next-line no-shadow export enum ErrorCodes { loginInProgress = 304, diff --git a/src/emitter.ts b/src/emitter.ts index 67439a4b..38ab0c5d 100644 --- a/src/emitter.ts +++ b/src/emitter.ts @@ -10,6 +10,7 @@ enum CUSTOM_EVENTS { createBundleProgress = 'createBundleProgress', uploadBundleProgress = 'uploadBundleProgress', analyseProgress = 'analyseProgress', + apiRequestLog = 'apiRequestLog', error = 'error', } @@ -39,6 +40,10 @@ export class EmitterDC extends EventEmitter { sendError(error: Error): void { this.emit(CUSTOM_EVENTS.error, error); } + + apiRequestLog(message: string): void { + this.emit(CUSTOM_EVENTS.apiRequestLog, message); + } } const emitter = new EmitterDC(); diff --git a/src/http.ts b/src/http.ts index b84df719..35a19185 100644 --- a/src/http.ts +++ b/src/http.ts @@ -141,9 +141,13 @@ export async function checkSession(options: { }); } -export async function getFilters(baseURL: string): Promise> { +export async function getFilters( + baseURL: string, + source: string, +): Promise> { const apiName = 'filters'; const config: AxiosRequestConfig = { + headers: { source }, url: `${baseURL}${apiPath}/${apiName}`, method: 'GET', }; @@ -183,10 +187,11 @@ export async function createBundle(options: { readonly baseURL: string; readonly sessionToken: string; readonly files: IFiles; + readonly source: string; }): Promise> { - const { baseURL, sessionToken, files } = options; + const { baseURL, sessionToken, files, source } = options; const config: AxiosRequestConfig = { - headers: { 'Session-Token': sessionToken }, + headers: { 'Session-Token': sessionToken, source }, url: `${baseURL}${apiPath}/bundle`, method: 'POST', data: { @@ -297,9 +302,10 @@ export async function createGitBundle(options: { readonly oAuthToken?: string; readonly username?: string; readonly gitUri: string; + readonly source: string; }): Promise> { - const { baseURL, sessionToken, oAuthToken, username, gitUri } = options; - const headers = { 'Session-Token': sessionToken }; + const { baseURL, sessionToken, oAuthToken, username, gitUri, source } = options; + const headers = { 'Session-Token': sessionToken, source }; if (oAuthToken) { headers['X-OAuthToken'] = oAuthToken; } @@ -410,12 +416,23 @@ export async function getAnalysis(options: { readonly limitToFiles?: string[]; readonly oAuthToken?: string; readonly username?: string; + readonly source: string; }): Promise> { - const { baseURL, sessionToken, oAuthToken, username, bundleId, includeLint, severity, limitToFiles } = options; + const { + baseURL, + sessionToken, + oAuthToken, + username, + bundleId, + includeLint, + severity, + limitToFiles, + source, + } = options; // ?linters=false is still a truthy query value, if(includeLint === false) we have to avoid sending the value altogether const params = { severity, linters: includeLint || undefined }; - const headers = { 'Session-Token': sessionToken }; + const headers = { 'Session-Token': sessionToken, source }; if (oAuthToken) { headers['X-OAuthToken'] = oAuthToken; } diff --git a/src/index.ts b/src/index.ts index cd7f0443..462920fa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,7 @@ import { getGlobPatterns } from './files'; import { ISupportedFiles } from './interfaces/files.interface'; import { + AnalysisSeverity, IFileSuggestion, IFilePath, IMarker, @@ -15,7 +16,6 @@ import { IAnalysisResult, IFileBundle, IGitBundle, - AnalysisSeverity, } from './interfaces/analysis-result.interface'; export { diff --git a/src/interfaces/analysis-options.interface.ts b/src/interfaces/analysis-options.interface.ts new file mode 100644 index 00000000..0f785151 --- /dev/null +++ b/src/interfaces/analysis-options.interface.ts @@ -0,0 +1,44 @@ +import { AnalysisSeverity } from './analysis-result.interface'; + +export interface AnalysisOptions { + baseURL: string; + sessionToken: string; + includeLint: boolean; + severity: AnalysisSeverity; + sarif: boolean; + source: string; +} + +export interface AnalyzeFoldersOptions extends AnalysisOptions { + paths: string[]; + symlinksEnabled: boolean; + maxPayload: number; + defaultFileIgnores: string[]; +} + +export interface AnalyzeGitOptions extends AnalysisOptions { + gitUri: string; + oAuthToken?: string; + username?: string; +} + +export interface Options { + baseURL?: string; + sessionToken: string; + includeLint?: boolean; + severity?: AnalysisSeverity; + sarif?: boolean; + source?: string; +} +export interface FolderOptions extends Options { + paths: string[]; + symlinksEnabled?: boolean; + maxPayload?: number; + defaultFileIgnores?: string[]; +} + +export interface GitOptions extends Options { + gitUri: string; + oAuthToken?: string; + username?: string; +} diff --git a/tests/analysis.spec.ts b/tests/analysis.spec.ts index 27b505a3..dc56150f 100644 --- a/tests/analysis.spec.ts +++ b/tests/analysis.spec.ts @@ -46,7 +46,21 @@ describe('Functional test of analysis', () => { }); emitter.on(emitter.events.analyseProgress, onAnalyseProgress); - const bundle = await analyzeFolders(baseURL, sessionToken, false, 1, [sampleProjectPath], false, 1000); + const onAPIRequestLog = jest.fn((message: string) => { + expect(typeof message).toBe('string'); + }); + emitter.on(emitter.events.apiRequestLog, onAPIRequestLog); + + + const bundle = await analyzeFolders({ + baseURL, + sessionToken, + includeLint: false, + severity: 1, + paths: [sampleProjectPath], + symlinksEnabled: false, + maxPayload: 1000, + }); expect(bundle).toHaveProperty('baseURL'); expect(bundle).toHaveProperty('sessionToken'); expect(bundle).toHaveProperty('supportedFiles'); @@ -87,6 +101,7 @@ describe('Functional test of analysis', () => { expect(onScanFilesProgress).toHaveBeenCalledTimes(8); expect(onCreateBundleProgress).toHaveBeenCalledTimes(4); expect(onAnalyseProgress).toHaveBeenCalled(); + expect(onAPIRequestLog).toHaveBeenCalledTimes(10); // Test uploadRemoteBundle with empty list of files let uploaded = await uploadRemoteBundle(baseURL, sessionToken, bundle.bundleId, []); @@ -107,30 +122,31 @@ describe('Functional test of analysis', () => { expect(uploaded).toEqual(true); expect(onUploadBundleProgress).toHaveBeenCalledTimes(2); + expect(onAPIRequestLog).toHaveBeenCalledTimes(12); }, TEST_TIMEOUT, ); it('analyze folder - with sarif returned', async () => { const includeLint = false; - const severityLevel = AnalysisSeverity.info; + const severity = AnalysisSeverity.info; const paths: string[] = [path.join(sampleProjectPath, 'only_text')]; const symlinksEnabled = false; const maxPayload = 1000; const defaultFileIgnores = undefined; const sarif = true; - const bundle = await analyzeFolders( + const bundle = await analyzeFolders({ baseURL, sessionToken, includeLint, - severityLevel, + severity, paths, symlinksEnabled, maxPayload, defaultFileIgnores, sarif, - ); + }); const validationResult = jsonschema.validate(bundle.sarifResults, sarifSchema); expect(validationResult.errors.length).toEqual(0); @@ -138,20 +154,20 @@ describe('Functional test of analysis', () => { it('analyze empty folder', async () => { const includeLint = false; - const severityLevel = AnalysisSeverity.info; + const severity = AnalysisSeverity.info; const paths: string[] = [path.join(sampleProjectPath, 'only_text')]; const symlinksEnabled = false; const maxPayload = 1000; - const bundle = await analyzeFolders( + const bundle = await analyzeFolders({ baseURL, sessionToken, includeLint, - severityLevel, + severity, paths, symlinksEnabled, maxPayload, - ); + }); expect(bundle.analysisResults.files).toEqual({}); expect(bundle.analysisResults.suggestions).toEqual({}); diff --git a/tests/api.spec.ts b/tests/api.spec.ts index 5f3fe2cd..c35c9f8d 100644 --- a/tests/api.spec.ts +++ b/tests/api.spec.ts @@ -35,11 +35,9 @@ const reportTelemetryRequest = { }, }; - describe('Requests to public API', () => { - it('gets filters successfully', async () => { - const response = await getFilters(baseURL); + const response = await getFilters(baseURL, ''); expect(response.type).toEqual('success'); if (response.type === 'error') return; expect(new Set(response.value.configFiles)).toEqual( @@ -103,9 +101,7 @@ describe('Requests to public API', () => { expect(startSessionResponse.type).toEqual('success'); if (startSessionResponse.type === 'error') return; - expect(startSessionResponse.value.loginURL).toMatch( - /.*\/login-api\?sessionToken=.*&source=atom/, - ); + expect(startSessionResponse.value.loginURL).toMatch(/.*\/login-api\?sessionToken=.*&source=atom/); const draftToken = startSessionResponse.value.sessionToken; // This token is just a draft and not ready to be used permanently @@ -135,451 +131,495 @@ describe('Requests to public API', () => { expect(response.value).toEqual(true); }); - it('creates bundle successfully', async () => { - const files = Object.fromEntries([...(await bundleFiles).entries()].map(([i, d]) => [d.bundlePath, `${i}`])); + it( + 'creates bundle successfully', + async () => { + const files = Object.fromEntries([...(await bundleFiles).entries()].map(([i, d]) => [d.bundlePath, `${i}`])); - const response = await createBundle({ - baseURL, - sessionToken, - files, - }); - expect(response.type).toEqual('success'); - if (response.type === 'error') return; - expect(response.value.bundleId).toContain(fakeBundleId); - fakeBundleIdFull = response.value.bundleId; - expect(response.value.missingFiles).toEqual([ - '/.eslintrc.json', - `/AnnotatorTest.cpp`, - `/GitHubAccessTokenScrambler12.java`, - `/app.js`, - `/db.js`, - `/main.js`, - `/routes/index.js`, - `/routes/sharks.js`, - ]); - }, TEST_TIMEOUT); - - it('checks bundle successfully', async () => { - const response = await checkBundle({ - baseURL, - sessionToken, - bundleId: fakeBundleIdFull, - }); - expect(response.type).toEqual('success'); - if (response.type === 'error') return; - expect(response.value.bundleId).toEqual(fakeBundleIdFull); - expect(response.value.missingFiles).toEqual([ - '/.eslintrc.json', - `/AnnotatorTest.cpp`, - `/GitHubAccessTokenScrambler12.java`, - `/app.js`, - `/db.js`, - `/main.js`, - `/routes/index.js`, - `/routes/sharks.js`, - ]); - }, TEST_TIMEOUT); - - it('checks expired bundle successfully', async () => { - const response = await checkBundle({ - baseURL, - sessionToken, - bundleId: 'mock-expired-bundle-id', - }); - expect(response.type).toEqual('error'); - // dummy to cheat typescript compiler - if (response.type == 'success') return; - expect(response.error.statusCode).toEqual(404); - expect(response.error.statusText).toEqual('Uploaded bundle has expired'); - }, TEST_TIMEOUT); - - it('request analysis with missing files', async () => { - let response; - do { - response = await getAnalysis({ + const response = await createBundle({ baseURL, sessionToken, - bundleId: fakeBundleIdFull, - includeLint: false, - severity: 1, + files, + source: '', }); - } while (response.type === 'success'); - - expect(response.type).toEqual('error'); - expect(response.error).toEqual({ - apiName: 'getAnalysis', - statusCode: 404, - statusText: 'Not found', - }); - - }, TEST_TIMEOUT); - - it('extends bundle successfully', async () => { - const response = await extendBundle({ - baseURL, - sessionToken, - bundleId: fakeBundleIdFull, - files: { - [`/new.js`]: 'new123', - }, - removedFiles: [ + expect(response.type).toEqual('success'); + if (response.type === 'error') return; + expect(response.value.bundleId).toContain(fakeBundleId); + fakeBundleIdFull = response.value.bundleId; + expect(response.value.missingFiles).toEqual([ '/.eslintrc.json', + `/AnnotatorTest.cpp`, + `/GitHubAccessTokenScrambler12.java`, `/app.js`, + `/db.js`, + `/main.js`, + `/routes/index.js`, + `/routes/sharks.js`, + ]); + }, + TEST_TIMEOUT, + ); + + it( + 'checks bundle successfully', + async () => { + const response = await checkBundle({ + baseURL, + sessionToken, + bundleId: fakeBundleIdFull, + }); + expect(response.type).toEqual('success'); + if (response.type === 'error') return; + expect(response.value.bundleId).toEqual(fakeBundleIdFull); + expect(response.value.missingFiles).toEqual([ + '/.eslintrc.json', `/AnnotatorTest.cpp`, `/GitHubAccessTokenScrambler12.java`, + `/app.js`, `/db.js`, `/main.js`, `/routes/index.js`, `/routes/sharks.js`, - ], - }); - expect(response.type).toEqual('success'); - if (response.type === 'error') return; - expect(response.value.bundleId).toContain( - '587a6bcb0095606ad57ccc7bb7ac6401475ce4181c13f7136491a16df06544f1', - ); - expect(response.value.missingFiles).toEqual([`/new.js`]); - }, TEST_TIMEOUT); - - it('extends expired bundle successfully', async () => { - const response = await extendBundle({ - baseURL, - sessionToken, - bundleId: 'wrong-bundle-id', - files: { - [`/new2.js`]: 'new1234', - }, - }); - - expect(response.type).toEqual('error'); - // dummy to cheat typescript compiler - if (response.type == 'success') return; - - expect(response.error.statusCode).toEqual(404); - expect(response.error.statusText).toEqual('Parent bundle has expired'); - }, TEST_TIMEOUT); - - it('uploads fake files to fake bundle', async () => { - const response = await uploadFiles({ - baseURL, - sessionToken, - bundleId: fakeBundleIdFull, - content: [ - { - fileHash: 'df', - fileContent: 'const module = new Module();', + ]); + }, + TEST_TIMEOUT, + ); + + it( + 'checks expired bundle successfully', + async () => { + const response = await checkBundle({ + baseURL, + sessionToken, + bundleId: 'mock-expired-bundle-id', + }); + expect(response.type).toEqual('error'); + // dummy to cheat typescript compiler + if (response.type == 'success') return; + expect(response.error.statusCode).toEqual(404); + expect(response.error.statusText).toEqual('Uploaded bundle has expired'); + }, + TEST_TIMEOUT, + ); + + it( + 'request analysis with missing files', + async () => { + let response; + do { + response = await getAnalysis({ + baseURL, + sessionToken, + bundleId: fakeBundleIdFull, + includeLint: false, + severity: 1, + source: '', + }); + } while (response.type === 'success'); + + expect(response.type).toEqual('error'); + expect(response.error).toEqual({ + apiName: 'getAnalysis', + statusCode: 404, + statusText: 'Not found', + }); + }, + TEST_TIMEOUT, + ); + + it( + 'extends bundle successfully', + async () => { + const response = await extendBundle({ + baseURL, + sessionToken, + bundleId: fakeBundleIdFull, + files: { + [`/new.js`]: 'new123', }, - { - fileHash: 'sdfs', - fileContent: 'const App = new App();', + removedFiles: [ + '/.eslintrc.json', + `/app.js`, + `/AnnotatorTest.cpp`, + `/GitHubAccessTokenScrambler12.java`, + `/db.js`, + `/main.js`, + `/routes/index.js`, + `/routes/sharks.js`, + ], + }); + expect(response.type).toEqual('success'); + if (response.type === 'error') return; + expect(response.value.bundleId).toContain('587a6bcb0095606ad57ccc7bb7ac6401475ce4181c13f7136491a16df06544f1'); + expect(response.value.missingFiles).toEqual([`/new.js`]); + }, + TEST_TIMEOUT, + ); + + it( + 'extends expired bundle successfully', + async () => { + const response = await extendBundle({ + baseURL, + sessionToken, + bundleId: 'wrong-bundle-id', + files: { + [`/new2.js`]: 'new1234', }, - ], - }); - expect(response.type).toEqual('error'); - if (response.type === 'success') return; - expect(response.error).toEqual({ - apiName: 'uploadFiles', - statusCode: 400, - statusText: - 'Invalid request, attempted to extend a git bundle, or ended up with an empty bundle after the extension', - }); - }, TEST_TIMEOUT); - - it('test successful workflow with and without linters', async () => { - // Create a bundle first - const files = Object.fromEntries((await bundleFilesFull).map(d => [d.bundlePath, d.hash])); - - const bundleResponse = await createBundle({ - baseURL, - sessionToken, - files, - }); - expect(bundleResponse.type).toEqual('success'); - if (bundleResponse.type === 'error') return; - expect(bundleResponse.value.bundleId).toContain(realBundleId); - realBundleIdFull = bundleResponse.value.bundleId; - - const content = (await bundleFilesFull).map(d => { - return { - fileHash: d.hash, - fileContent: d.content || '', - }; - }); + }); - // Upload files - const uploadResponse = await uploadFiles({ - baseURL, - sessionToken, - bundleId: realBundleIdFull, - content: content, - }); - expect(uploadResponse.type).toEqual('success'); - if (uploadResponse.type === 'error') return; - expect(uploadResponse.value).toEqual(true); + expect(response.type).toEqual('error'); + // dummy to cheat typescript compiler + if (response.type == 'success') return; - // Check missing files - const checkResponse = await checkBundle({ - baseURL, - sessionToken, - bundleId: realBundleIdFull, - }); - expect(checkResponse.type).toEqual('success'); - if (checkResponse.type === 'error') return; - expect(checkResponse.value.bundleId).toEqual(realBundleIdFull); - expect(checkResponse.value.missingFiles).toEqual([]); + expect(response.error.statusCode).toEqual(404); + expect(response.error.statusText).toEqual('Parent bundle has expired'); + }, + TEST_TIMEOUT, + ); - // Get analysis results without linters - let response = await getAnalysis({ - baseURL, - sessionToken, - bundleId: realBundleIdFull, - includeLint: false, - severity: 1, - }); - expect(response.type).toEqual('success'); - if (response.type === 'error') return; - expect(response.value.status !== AnalysisStatus.failed).toBeTruthy(); - - if (response.value.status === AnalysisStatus.done) { - expect(response.value.analysisURL.includes(realBundleIdFull)).toBeTruthy(); - expect(Object.keys(response.value.analysisResults.suggestions).length).toEqual(8); - const suggestion = response.value.analysisResults.suggestions[0]; - expect(Object.keys(suggestion)).toEqual([ - 'id', - 'rule', - 'message', - 'severity', - 'lead_url', - 'leadURL', - 'categories', - 'tags', - 'title', - 'cwe', - 'text', - 'repoDatasetSize', - 'exampleCommitDescriptions', - 'exampleCommitFixes', - ]); - expect(suggestion.id).toEqual('javascript%2Fdc_interfile_project%2FDisablePoweredBy'); - expect(suggestion.leadURL).toEqual('http://expressjs.com/en/advanced/best-practice-security.html#at-a-minimum-disable-x-powered-by-header'); - expect(suggestion.repoDatasetSize).toEqual(874); - expect(suggestion.exampleCommitDescriptions).toEqual([ - "Test without express", - "/server tests ()", - "secure the api with helmet", - ]); - expect(suggestion.exampleCommitFixes.length).toEqual(3); - expect(suggestion.message).toEqual( - 'Disable X-Powered-By header for your Express app (consider using Helmet middleware), because it exposes information about the used framework to potential attackers.', - ); - expect(suggestion.rule).toEqual('DisablePoweredBy'); - expect(suggestion.severity).toEqual(2); - - expect(suggestion.tags).toEqual([ - "maintenance", - "express", - "server", - "helmet", - ]); - expect(Object.keys(response.value.analysisResults.files).length).toEqual(4); - const filePath = `/AnnotatorTest.cpp`; - expect(response.value.analysisResults.files[filePath]).toEqual({ - '2': [ + it( + 'uploads fake files to fake bundle', + async () => { + const response = await uploadFiles({ + baseURL, + sessionToken, + bundleId: fakeBundleIdFull, + content: [ { - cols: [8, 27], - markers: [], - rows: [5, 5], - fingerprints: [ - { - fingerprint: "f8e3391465a47f6586489cffd1f44ae47a1c4885c722de596d6eb931fe43bb16", - version: 0, - }, - ] + fileHash: 'df', + fileContent: 'const module = new Module();', }, - ], - '3': [ { - cols: [6, 25], - markers: [ - { - msg: [25, 36], - pos: [ - { - cols: [7, 14], - rows: [8, 8], - file: filePath, - }, - ], - }, - { - msg: [45, 57], - pos: [ - { - cols: [6, 25], - rows: [10, 10], - file: filePath, - }, - ], - }, - ], - rows: [10, 10], - fingerprints: [ - { - fingerprint: "3e40a81739245db8fff4903a7e28e08bffa03486a677e7c91594cfdf15fb5a1d", - version: 0, - }, - ] + fileHash: 'sdfs', + fileContent: 'const App = new App();', }, ], }); + expect(response.type).toEqual('error'); + if (response.type === 'success') return; + expect(response.error).toEqual({ + apiName: 'uploadFiles', + statusCode: 400, + statusText: + 'Invalid request, attempted to extend a git bundle, or ended up with an empty bundle after the extension', + }); + }, + TEST_TIMEOUT, + ); - expect(response.value.analysisResults.timing.analysis).toBeGreaterThanOrEqual(response.value.analysisResults.timing.fetchingCode); - expect(response.value.analysisResults.timing.queue).toBeGreaterThanOrEqual(0); - expect(new Set(response.value.analysisResults.coverage)).toEqual(new Set([ - { - "files": 1, - "isSupported": true, - "lang": "C++ (beta)", - }, - { - "files": 1, - "isSupported": false, - "lang": "JSON", - }, - { - "files": 1, - "isSupported": true, - "lang": "Java", - }, - { - "files": 5, - "isSupported": true, - "lang": "JavaScript", - }, - ])); - } + it( + 'test successful workflow with and without linters', + async () => { + // Create a bundle first + const files = Object.fromEntries((await bundleFilesFull).map(d => [d.bundlePath, d.hash])); - // Get analysis results limited to 1 file - do { - response = await getAnalysis({ + const bundleResponse = await createBundle({ baseURL, sessionToken, - bundleId: realBundleIdFull, - includeLint: false, - severity: 1, - limitToFiles: [`/AnnotatorTest.cpp`], + files, + source: '', + }); + expect(bundleResponse.type).toEqual('success'); + if (bundleResponse.type === 'error') return; + expect(bundleResponse.value.bundleId).toContain(realBundleId); + realBundleIdFull = bundleResponse.value.bundleId; + + const content = (await bundleFilesFull).map(d => { + return { + fileHash: d.hash, + fileContent: d.content || '', + }; }); - expect(response.type).toEqual('success'); - if (response.type === 'error') return; - expect(response.value.status !== AnalysisStatus.failed).toBeTruthy(); - - } while (response.value.status !== AnalysisStatus.done); + // Upload files + const uploadResponse = await uploadFiles({ + baseURL, + sessionToken, + bundleId: realBundleIdFull, + content: content, + }); + expect(uploadResponse.type).toEqual('success'); + if (uploadResponse.type === 'error') return; + expect(uploadResponse.value).toEqual(true); - expect(Object.keys(response.value.analysisResults.suggestions).length).toEqual(2); - expect(Object.keys(response.value.analysisResults.files)).toEqual(['/AnnotatorTest.cpp']); + // Check missing files + const checkResponse = await checkBundle({ + baseURL, + sessionToken, + bundleId: realBundleIdFull, + }); + expect(checkResponse.type).toEqual('success'); + if (checkResponse.type === 'error') return; + expect(checkResponse.value.bundleId).toEqual(realBundleIdFull); + expect(checkResponse.value.missingFiles).toEqual([]); - // Get analysis results without linters but with severity 3 - do { - response = await getAnalysis({ + // Get analysis results without linters + let response = await getAnalysis({ baseURL, sessionToken, bundleId: realBundleIdFull, includeLint: false, - severity: 3, + severity: 1, + source: '', }); expect(response.type).toEqual('success'); if (response.type === 'error') return; expect(response.value.status !== AnalysisStatus.failed).toBeTruthy(); - } while (response.value.status !== AnalysisStatus.done); - expect(Object.keys(response.value.analysisResults.suggestions).length).toEqual(2); - expect(Object.keys(response.value.analysisResults.files)).toEqual(['/GitHubAccessTokenScrambler12.java']); - - }, TEST_TIMEOUT); + if (response.value.status === AnalysisStatus.done) { + expect(response.value.analysisURL.includes(realBundleIdFull)).toBeTruthy(); + expect(Object.keys(response.value.analysisResults.suggestions).length).toEqual(8); + const suggestion = response.value.analysisResults.suggestions[0]; + expect(Object.keys(suggestion)).toEqual([ + 'id', + 'rule', + 'message', + 'severity', + 'lead_url', + 'leadURL', + 'categories', + 'tags', + 'title', + 'cwe', + 'text', + 'repoDatasetSize', + 'exampleCommitDescriptions', + 'exampleCommitFixes', + ]); + expect(suggestion.id).toEqual('javascript%2Fdc_interfile_project%2FDisablePoweredBy'); + expect(suggestion.leadURL).toEqual( + 'http://expressjs.com/en/advanced/best-practice-security.html#at-a-minimum-disable-x-powered-by-header', + ); + expect(suggestion.repoDatasetSize).toEqual(874); + expect(suggestion.exampleCommitDescriptions).toEqual([ + 'Test without express', + '/server tests ()', + 'secure the api with helmet', + ]); + expect(suggestion.exampleCommitFixes.length).toEqual(3); + expect(suggestion.message).toEqual( + 'Disable X-Powered-By header for your Express app (consider using Helmet middleware), because it exposes information about the used framework to potential attackers.', + ); + expect(suggestion.rule).toEqual('DisablePoweredBy'); + expect(suggestion.severity).toEqual(2); + + expect(suggestion.tags).toEqual(['maintenance', 'express', 'server', 'helmet']); + expect(Object.keys(response.value.analysisResults.files).length).toEqual(4); + const filePath = `/AnnotatorTest.cpp`; + expect(response.value.analysisResults.files[filePath]).toEqual({ + '2': [ + { + cols: [8, 27], + markers: [], + rows: [5, 5], + fingerprints: [ + { + fingerprint: 'f8e3391465a47f6586489cffd1f44ae47a1c4885c722de596d6eb931fe43bb16', + version: 0, + }, + ], + }, + ], + '3': [ + { + cols: [6, 25], + markers: [ + { + msg: [25, 36], + pos: [ + { + cols: [7, 14], + rows: [8, 8], + file: filePath, + }, + ], + }, + { + msg: [45, 57], + pos: [ + { + cols: [6, 25], + rows: [10, 10], + file: filePath, + }, + ], + }, + ], + rows: [10, 10], + fingerprints: [ + { + fingerprint: '3e40a81739245db8fff4903a7e28e08bffa03486a677e7c91594cfdf15fb5a1d', + version: 0, + }, + ], + }, + ], + }); + + expect(response.value.analysisResults.timing.analysis).toBeGreaterThanOrEqual( + response.value.analysisResults.timing.fetchingCode, + ); + expect(response.value.analysisResults.timing.queue).toBeGreaterThanOrEqual(0); + expect(new Set(response.value.analysisResults.coverage)).toEqual( + new Set([ + { + files: 1, + isSupported: true, + lang: 'C++ (beta)', + }, + { + files: 1, + isSupported: false, + lang: 'JSON', + }, + { + files: 1, + isSupported: true, + lang: 'Java', + }, + { + files: 5, + isSupported: true, + lang: 'JavaScript', + }, + ]), + ); + } + + // Get analysis results limited to 1 file + do { + response = await getAnalysis({ + baseURL, + sessionToken, + bundleId: realBundleIdFull, + includeLint: false, + severity: 1, + limitToFiles: [`/AnnotatorTest.cpp`], + source: '', + }); + + expect(response.type).toEqual('success'); + if (response.type === 'error') return; + expect(response.value.status !== AnalysisStatus.failed).toBeTruthy(); + } while (response.value.status !== AnalysisStatus.done); + + expect(Object.keys(response.value.analysisResults.suggestions).length).toEqual(2); + expect(Object.keys(response.value.analysisResults.files)).toEqual(['/AnnotatorTest.cpp']); + + // Get analysis results without linters but with severity 3 + do { + response = await getAnalysis({ + baseURL, + sessionToken, + bundleId: realBundleIdFull, + includeLint: false, + severity: 3, + source: '', + }); + expect(response.type).toEqual('success'); + if (response.type === 'error') return; + expect(response.value.status !== AnalysisStatus.failed).toBeTruthy(); + } while (response.value.status !== AnalysisStatus.done); + + expect(Object.keys(response.value.analysisResults.suggestions).length).toEqual(2); + expect(Object.keys(response.value.analysisResults.files)).toEqual(['/GitHubAccessTokenScrambler12.java']); + }, + TEST_TIMEOUT, + ); it('create git bundle', async () => { const bundleResponse = await createGitBundle({ baseURL, sessionToken, gitUri: 'git@github.com:DeepCodeAI/cli.git', + source: '', }); expect(bundleResponse.type).toEqual('success'); if (bundleResponse.type === 'error') return; expect(bundleResponse.value.bundleId).toBeTruthy(); }); - it('git analysis', async () => { - const bundleId = 'gh/DeepcodeAI/cli/320d98a6896f5376efe6cefefb6e70b46b97d566'; + it( + 'git analysis', + async () => { + const bundleId = 'gh/DeepcodeAI/cli/320d98a6896f5376efe6cefefb6e70b46b97d566'; - // Get analysis results - const response = await getAnalysis({ - baseURL, - sessionToken, - bundleId, - includeLint: false, - severity: 1, - }); - expect(response.type).toEqual('success'); - if (response.type === 'error') return; - expect(response.value.status !== AnalysisStatus.failed).toBeTruthy(); - - if (response.value.status === AnalysisStatus.done) { - expect(response.value.analysisURL.includes(bundleId)).toBeTruthy(); - expect(response.value.analysisResults.suggestions).toBeTruthy(); - - const suggestion = response.value.analysisResults.suggestions[0]; - expect(suggestion.categories).toEqual(['Security', 'InTest']); - expect(suggestion).toHaveProperty('exampleCommitDescriptions'); - expect(suggestion).toHaveProperty('exampleCommitFixes'); - expect(suggestion.leadURL).toEqual(''); - expect(suggestion.id).toEqual('python%2Fdc%2FHardcodedNonCryptoSecret%2Ftest'); - expect(suggestion.message).toContain( - 'Avoid hardcoding values that are meant to be secret. Found a hardcoded string used in here.', - ); - expect(suggestion.rule).toEqual('HardcodedNonCryptoSecret/test'); - expect(suggestion.severity).toEqual(1); - expect(suggestion.tags).toEqual(['maintenance', 'bug', 'key', 'secret', 'credentials']); - expect(Object.keys(response.value.analysisResults.files).length).toEqual(1); - } - }, TEST_TIMEOUT); - - it('git analysis with empty results', async () => { - const bundleId = 'gh/DeepcodeAI/test-bigfiles/e7633ef98fba3ddc24e5bea27ae58d5b08b2f949'; - - let response; - - do { // Get analysis results - response = await getAnalysis({ + const response = await getAnalysis({ baseURL, sessionToken, bundleId, includeLint: false, severity: 1, + source: '', }); - expect(response.type).toEqual('success'); if (response.type === 'error') return; expect(response.value.status !== AnalysisStatus.failed).toBeTruthy(); - } while (response.value.status !== AnalysisStatus.done) - - expect(response.value.analysisURL.includes(bundleId)).toBeTruthy(); - expect(response.value.analysisResults.suggestions).toEqual({}); - expect(response.value.analysisResults.files).toEqual({}); - - expect(response.value.analysisResults.coverage).toEqual([ - { - files: 3, - isSupported: false, - lang: 'Text', - }, - { - files: 1, - isSupported: false, - lang: 'Markdown', - }, - ]); - - }, TEST_TIMEOUT); + + if (response.value.status === AnalysisStatus.done) { + expect(response.value.analysisURL.includes(bundleId)).toBeTruthy(); + expect(response.value.analysisResults.suggestions).toBeTruthy(); + + const suggestion = response.value.analysisResults.suggestions[0]; + expect(suggestion.categories).toEqual(['Security', 'InTest']); + expect(suggestion).toHaveProperty('exampleCommitDescriptions'); + expect(suggestion).toHaveProperty('exampleCommitFixes'); + expect(suggestion.leadURL).toEqual(''); + expect(suggestion.id).toEqual('python%2Fdc%2FHardcodedNonCryptoSecret%2Ftest'); + expect(suggestion.message).toContain( + 'Avoid hardcoding values that are meant to be secret. Found a hardcoded string used in here.', + ); + expect(suggestion.rule).toEqual('HardcodedNonCryptoSecret/test'); + expect(suggestion.severity).toEqual(1); + expect(suggestion.tags).toEqual(['maintenance', 'bug', 'key', 'secret', 'credentials']); + expect(Object.keys(response.value.analysisResults.files).length).toEqual(1); + } + }, + TEST_TIMEOUT, + ); + + it( + 'git analysis with empty results', + async () => { + const bundleId = 'gh/DeepcodeAI/test-bigfiles/e7633ef98fba3ddc24e5bea27ae58d5b08b2f949'; + + let response; + + do { + // Get analysis results + response = await getAnalysis({ + baseURL, + sessionToken, + bundleId, + includeLint: false, + severity: 1, + source: '', + }); + + expect(response.type).toEqual('success'); + if (response.type === 'error') return; + expect(response.value.status !== AnalysisStatus.failed).toBeTruthy(); + } while (response.value.status !== AnalysisStatus.done); + + expect(response.value.analysisURL.includes(bundleId)).toBeTruthy(); + expect(response.value.analysisResults.suggestions).toEqual({}); + expect(response.value.analysisResults.files).toEqual({}); + + expect(response.value.analysisResults.coverage).toEqual([ + { + files: 3, + isSupported: false, + lang: 'Text', + }, + { + files: 1, + isSupported: false, + lang: 'Markdown', + }, + ]); + }, + TEST_TIMEOUT, + ); }); diff --git a/tests/git.analysis.spec.ts b/tests/git.analysis.spec.ts index 0345e5f7..ec6cc84a 100644 --- a/tests/git.analysis.spec.ts +++ b/tests/git.analysis.spec.ts @@ -18,7 +18,13 @@ describe('Functional test of analysis', () => { it( 'analyze remote git without oid', async () => { - const bundle = await analyzeGit(baseURL, sessionToken, false, 1, 'git@github.com:DeepCodeAI/cli.git'); + const bundle = await analyzeGit({ + baseURL, + sessionToken, + includeLint: false, + severity: 1, + gitUri: 'git@github.com:DeepCodeAI/cli.git', + }); expect(bundle.analysisResults.files).toBeTruthy(); expect(bundle.analysisResults.suggestions).toBeTruthy(); }, @@ -28,13 +34,13 @@ describe('Functional test of analysis', () => { itif(!!oAuthToken)( 'analyze remote git with oid', async () => { - const bundle = await analyzeGit( + const bundle = await analyzeGit({ baseURL, sessionToken, - false, - 1, - 'git@github.com:DeepCodeAI/cli.git@320d98a6896f5376efe6cefefb6e70b46b97d566', - ); + includeLint: false, + severity: 1, + gitUri: 'git@github.com:DeepCodeAI/cli.git@320d98a6896f5376efe6cefefb6e70b46b97d566', + }); expect(bundle.analysisResults.files).toBeTruthy(); expect(Object.keys(bundle.analysisResults.files).length).toEqual(1); expect(bundle.analysisResults.suggestions).toBeTruthy(); @@ -48,27 +54,27 @@ describe('Functional test of analysis', () => { async () => { let failedGit: IGitBundle | undefined; try { - failedGit = await analyzeGit( + failedGit = await analyzeGit({ baseURL, - sessionTokenNoRepoAccess, - false, - 1, - 'git@github.com:DeepCodeAI/testcrepo.git', - ); + sessionToken: sessionTokenNoRepoAccess, + includeLint: false, + severity: 1, + gitUri: 'git@github.com:DeepCodeAI/testcrepo.git', + }); } catch (failed) { expect(failed.statusCode).toEqual(ErrorCodes.unauthorizedBundleAccess); } expect(failedGit).toBe(undefined); - const bundle = await analyzeGit( + const bundle = await analyzeGit({ baseURL, - sessionTokenNoRepoAccess, - false, - 1, - 'git@github.com:DeepCodeAI/testcrepo.git', - false, + sessionToken: sessionTokenNoRepoAccess, + includeLint: false, + severity: 1, + gitUri: 'git@github.com:DeepCodeAI/testcrepo.git', + sarif: false, oAuthToken, - ); + }); expect(bundle.analysisResults.files).toBeTruthy(); expect(bundle.analysisResults.suggestions).toBeTruthy(); }, @@ -78,14 +84,14 @@ describe('Functional test of analysis', () => { it( 'CWE fields in analysis results', async () => { - const bundle = await analyzeGit( + const bundle = await analyzeGit({ baseURL, sessionToken, - false, - 1, - 'git@github.com:eclipse/che.git@75889e8c33601e8986e75bad74456cff39e511c0', - true, - ); + includeLint: false, + severity: 1, + gitUri: 'git@github.com:eclipse/che.git@75889e8c33601e8986e75bad74456cff39e511c0', + sarif: true, + }); // Test DC JSON format first expect(Object.keys(bundle.analysisResults.suggestions).length).toEqual(119); @@ -113,14 +119,14 @@ describe('Functional test of analysis', () => { it( 'analyze remote git with oid and return sarif', async () => { - const bundle = await analyzeGit( + const bundle = await analyzeGit({ baseURL, sessionToken, - false, - 1, - 'git@github.com:DeepCodeAI/cli.git@320d98a6896f5376efe6cefefb6e70b46b97d566', - true, - ); + includeLint: false, + severity: 1, + gitUri: 'git@github.com:DeepCodeAI/cli.git@320d98a6896f5376efe6cefefb6e70b46b97d566', + sarif: true, + }); sarifResults = bundle.sarifResults; expect(!!bundle.sarifResults).toEqual(true); }, @@ -130,14 +136,14 @@ describe('Functional test of analysis', () => { it( 'analyze remote git and formatter sarif with zero supported files', async () => { - const bundle = await analyzeGit( + const bundle = await analyzeGit({ baseURL, sessionToken, - false, - 1, - 'git@github.com:DeepCodeAI/test-bigfiles.git@e7633ef98fba3ddc24e5bea27ae58d5b08b2f949', - true, - ); + includeLint: false, + severity: 1, + gitUri: 'git@github.com:DeepCodeAI/test-bigfiles.git@e7633ef98fba3ddc24e5bea27ae58d5b08b2f949', + sarif: true, + }); expect(bundle.sarifResults?.runs[0].properties?.coverage).toEqual([ { files: 3,