Skip to content

Commit

Permalink
feat: added MATCH_MANIFEST_VERSIONS to extension workspace settings a…
Browse files Browse the repository at this point in the history
…nd to Exhort JS API request (#653)

Signed-off-by: Ilona Shishov <[email protected]>
  • Loading branch information
IlonaShishov authored Oct 25, 2023
1 parent 8faf480 commit 2b35041
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 39 deletions.
41 changes: 37 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@
"description": "Red Hat Dependency Analytics server authentication token for Snyk.",
"scope": "window"
},
"redHatDependencyAnalytics.matchManifestVersions": {
"type": "boolean",
"default": true,
"description": "Restricts RHDA from performing analysis on dependency tags that do not match the tags requested within the manifest files.",
"scope": "window"
},
"redHatDependencyAnalytics.redHatDependencyAnalyticsReportFilePath": {
"type": "string",
"default": "/tmp/redhatDependencyAnalyticsReport.html",
Expand Down Expand Up @@ -278,9 +284,9 @@
"dependencies": {
"@fabric8-analytics/fabric8-analytics-lsp-server": "^0.7.1-ea.13",
"@redhat-developer/vscode-redhat-telemetry": "^0.7.0",
"@RHEcosystemAppEng/exhort-javascript-api": "^0.0.2-ea.32",
"@RHEcosystemAppEng/exhort-javascript-api": "^0.0.2-ea.39",
"fs": "^0.0.1-security",
"path": "^0.12.7",
"vscode-languageclient": "^8.1.0"
}
}
}
1 change: 1 addition & 0 deletions src/authextension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export module authextension {
process.env['PROVIDE_FULLSTACK_ACTION'] = 'true';
process.env['UTM_SOURCE'] = GlobalState.UtmSource;
process.env['SNYK_TOKEN'] = apiConfig.exhortSnykToken;
process.env['MATCH_MANIFEST_VERSIONS'] = apiConfig.matchManifestVersions ? 'true' : 'false';
process.env['MVN_EXECUTABLE'] = Config.getMvnExecutable();
process.env['NPM_EXECUTABLE'] = Config.getNpmExecutable();
process.env['GO_EXECUTABLE'] = Config.getGoExecutable();
Expand Down
38 changes: 25 additions & 13 deletions src/dependencyReportPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,20 @@ export class DependencyReportPanel {
private readonly _panel: vscode.WebviewPanel;
private _disposables: vscode.Disposable[] = [];

public static createOrShow(extensionPath: string, data: any) {
public static createOrShowWebviewPanel() {
const column = vscode.window.activeTextEditor
? vscode.window.activeTextEditor.viewColumn
: undefined;
DependencyReportPanel.data = data;
DependencyReportPanel.data = null;

// If we already have a panel, show it.
if (DependencyReportPanel.currentPanel) {
DependencyReportPanel.currentPanel._panel.reveal(column);
if (DependencyReportPanel.currentPanel._panel.visible) {
DependencyReportPanel.currentPanel._updateWebView();
} else {
DependencyReportPanel.currentPanel._panel.reveal(column);
}
DependencyReportPanel.currentPanel._disposeReport();
return;
}

Expand Down Expand Up @@ -98,6 +104,7 @@ export class DependencyReportPanel {
DependencyReportPanel.data = data;
this._panel.webview.html = data;
} else {
DependencyReportPanel.data = errorTmpl;
this._panel.webview.html = errorTmpl;
}
}
Expand All @@ -107,12 +114,7 @@ export class DependencyReportPanel {

// Clean up our resources
this._panel.dispose();
const apiConfig = Config.getApiConfig();
if (fs.existsSync(apiConfig.redHatDependencyAnalyticsReportFilePath || defaultRedhatDependencyAnalyticsReportFilePath)) {
// Delete temp stackAnalysisReport file
fs.unlinkSync(apiConfig.redHatDependencyAnalyticsReportFilePath || defaultRedhatDependencyAnalyticsReportFilePath);
console.log(`File ${apiConfig.redHatDependencyAnalyticsReportFilePath || defaultRedhatDependencyAnalyticsReportFilePath} has been deleted.`);
}
this._disposeReport();
DependencyReportPanel.data = null;
while (this._disposables.length) {
const x = this._disposables.pop();
Expand All @@ -123,10 +125,20 @@ export class DependencyReportPanel {
}

private _updateWebView() {
this._panel.title = Titles.REPORT_TITLE;
let output = DependencyReportPanel.data;
this._panel.webview.html = output && /<\s*html[^>]*>/i.test(output) ?
output :
loaderTmpl;
if (output && /<\s*html[^>]*>/i.test(output)) {
this._panel.webview.html = output;
} else {
this._panel.webview.html = loaderTmpl;
}
}

private _disposeReport() {
const apiConfig = Config.getApiConfig();
if (fs.existsSync(apiConfig.redHatDependencyAnalyticsReportFilePath || defaultRedhatDependencyAnalyticsReportFilePath)) {
// Delete temp stackAnalysisReport file
fs.unlinkSync(apiConfig.redHatDependencyAnalyticsReportFilePath || defaultRedhatDependencyAnalyticsReportFilePath);
console.log(`File ${apiConfig.redHatDependencyAnalyticsReportFilePath || defaultRedhatDependencyAnalyticsReportFilePath} has been deleted.`);
}
}
}
8 changes: 3 additions & 5 deletions src/multimanifestmodule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,14 @@ export module multimanifestmodule {
};

export const triggerManifestWs = context => {
return new Promise((resolve, reject) => {
return new Promise<void>((resolve, reject) => {
authextension
.authorize_f8_analytics(context)
.then(data => {
if (data) {
DependencyReportPanel.createOrShow(context.extensionPath, null);
resolve(true);
DependencyReportPanel.createOrShowWebviewPanel();
resolve();
}
})
.catch(err => {
reject(`Unable to authenticate.`);
});
});
Expand Down
3 changes: 2 additions & 1 deletion src/stackanalysismodule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export module stackanalysismodule {
'EXHORT_PIP_PATH': Config.getPipExecutable(),
'EXHORT_DEV_MODE': process.env.EXHORT_DEV_MODE,
'RHDA_TOKEN': process.env.TELEMETRY_ID,
'RHDA_SOURCE': process.env.UTM_SOURCE
'RHDA_SOURCE': process.env.UTM_SOURCE,
'MATCH_MANIFEST_VERSIONS': apiConfig.matchManifestVersions
};

if (apiConfig.exhortSnykToken !== '') {
Expand Down
4 changes: 3 additions & 1 deletion test/authextension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ suite('authextension Modules', () => {

test('setContextData should set environment variables', async () => {
const mockApiConfig = {
exhortSnykToken: 'mockToken'
exhortSnykToken: 'mockToken',
matchManifestVersions: true,
};

authextension.setContextData(mockApiConfig);

expect(process.env['PROVIDE_FULLSTACK_ACTION']).equals('true');
expect(process.env['UTM_SOURCE']).equals('vscode');
expect(process.env['SNYK_TOKEN']).equals('mockToken');
expect(process.env['MATCH_MANIFEST_VERSIONS']).equals('true');
expect(process.env['MVN_EXECUTABLE']).equals('mvn');
expect(process.env['NPM_EXECUTABLE']).equals('npm');
expect(process.env['GO_EXECUTABLE']).equals('go');
Expand Down
7 changes: 3 additions & 4 deletions test/dependencyReportPanel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import * as vscode from 'vscode';
import * as fs from 'fs';

import { Config } from '../src/config';
import { context } from './vscontext.mock';
import { DependencyReportPanel } from '../src/dependencyReportPanel';

const expect = chai.expect;
Expand All @@ -25,7 +24,7 @@ suite('DependencyReportPanel Modules', () => {
test('createOrShow should create a new panel', async () => {
const createWebviewPanelSpy = sandbox.spy(vscode.window, 'createWebviewPanel');

DependencyReportPanel.createOrShow(context.extensionPath, null);
DependencyReportPanel.createOrShowWebviewPanel();

expect(createWebviewPanelSpy).to.be.calledOnce;
expect(DependencyReportPanel.currentPanel).to.exist;
Expand All @@ -34,7 +33,7 @@ suite('DependencyReportPanel Modules', () => {
test('doUpdatePanel should render and update data', async () => {
const data = '<html><body>Mock data</body></html>';

DependencyReportPanel.createOrShow(context.extensionPath, null);
DependencyReportPanel.createOrShowWebviewPanel();
DependencyReportPanel.currentPanel.doUpdatePanel(data);

expect(DependencyReportPanel.data).equals(data);
Expand All @@ -48,7 +47,7 @@ suite('DependencyReportPanel Modules', () => {
const existsSyncStub = sandbox.stub(fs, 'existsSync').returns(true);
const unlinkSyncStub = sandbox.stub(fs, 'unlinkSync');

DependencyReportPanel.createOrShow(context.extensionPath, data);
DependencyReportPanel.createOrShowWebviewPanel();
DependencyReportPanel.currentPanel.dispose();

expect(existsSyncStub).to.be.calledWith('mockFilePath');
Expand Down
25 changes: 16 additions & 9 deletions test/multiManifestModule.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,25 @@ suite('multimanifest module', () => {
expect(processStackAnalysisStub.calledOnceWithExactly(context, { uri }, 'maven', uri)).to.be.true;
});

test('triggerManifestWs should resolve with true when authorized and create DependencyReportPanel', async () => {
test('triggerManifestWs should resolve when authorized and create DependencyReportPanel', async () => {
let authorize_f8_analyticsStub = sandbox.stub(authextension, 'authorize_f8_analytics').resolves(true);
const createOrShowStub = sandbox.stub(DependencyReportPanel, 'createOrShow');
const createOrShowWebviewPanelStub = sandbox.stub(DependencyReportPanel, 'createOrShowWebviewPanel');

let result = await multimanifestmodule.triggerManifestWs(context);
try {
await multimanifestmodule.triggerManifestWs(context);
// If triggerManifestWs resolves successfully, the test will pass.
} catch (error) {
// If triggerManifestWs rejects, the test will fail with the error message.
expect.fail('Expected triggerManifestWs to resolve, but it rejected with an error: ' + error);
}

expect(result).equals(true);
expect(createOrShowStub.calledOnceWithExactly(context.extensionPath, null)).to.be.true;
expect(authorize_f8_analyticsStub).to.be.calledOnce;
expect(authorize_f8_analyticsStub.calledOnce).to.be.true;
expect(createOrShowWebviewPanelStub.calledOnce).to.be.true;
});

test('triggerManifestWs should reject with "Unable to authenticate." when authorization fails', async () => {
const authStub = sandbox.stub(authextension, 'authorize_f8_analytics').rejects('Authentication failed');
let authorize_f8_analyticsStub = sandbox.stub(authextension, 'authorize_f8_analytics').resolves(false);
const createOrShowWebviewPanelStub = sandbox.stub(DependencyReportPanel, 'createOrShowWebviewPanel');

try {
await multimanifestmodule.triggerManifestWs(context);
Expand All @@ -56,15 +62,16 @@ suite('multimanifest module', () => {
expect(error).to.equal('Unable to authenticate.');
}

expect(authStub.calledOnceWithExactly(context)).to.be.true;
expect(authorize_f8_analyticsStub.calledOnce).to.be.true;
expect(createOrShowWebviewPanelStub.called).to.be.false;
});

test('triggerTokenValidation should call validateSnykToken when provider is "snyk"', async () => {
const validateSnykTokenStub = sandbox.stub(stackanalysismodule, 'validateSnykToken');

await multimanifestmodule.triggerTokenValidation('snyk');

expect(validateSnykTokenStub).to.be.calledOnce;
expect(validateSnykTokenStub.calledOnce).to.be.true;
});

});

0 comments on commit 2b35041

Please sign in to comment.