Skip to content

Commit 1a7ddcf

Browse files
committed
Make download method handle zip files
This will: - download a zip file as an ArrayBuffer - save the file as `results.zip` - unzip the contents into a `results/` folder For the tests: - In order to check whether we're saving the correct files in the tests, we've had to make the `getRepoStorageDirectory` method public. Unfortunately the temporary file path generated for tests is random so we're not able to hardcode it. - Now that we have a real zip file to use in our tests, we're first converting this file into an ArrayBuffer, then stubbing the API to return it. We then check that it's saved and unzipped correctly.
1 parent 7cef45c commit 1a7ddcf

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

extensions/ql-vscode/src/remote-queries/variant-analysis-results-manager.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { DisposableObject, DisposeHandler } from '../pure/disposable-object';
1414
import { VariantAnalysisRepoTask } from './gh-api/variant-analysis';
1515
import * as ghApiClient from './gh-api/gh-api-client';
1616
import { EventEmitter } from 'vscode';
17+
import { unzipFile } from '../pure/zip';
1718

1819
type CacheKey = `${number}/${string}`;
1920

@@ -58,8 +59,15 @@ export class VariantAnalysisResultsManager extends DisposableObject {
5859
repoTask.artifact_url
5960
);
6061

61-
fs.mkdirSync(resultDirectory, { recursive: true });
62-
await fs.writeFile(path.join(resultDirectory, 'results.zip'), JSON.stringify(result, null, 2), 'utf8');
62+
if (!(await fs.pathExists(resultDirectory))) {
63+
await fs.mkdir(resultDirectory, { recursive: true });
64+
}
65+
66+
const zipFilePath = path.join(resultDirectory, 'results.zip');
67+
const unzippedFilesDirectory = path.join(resultDirectory, 'results');
68+
69+
fs.writeFileSync(zipFilePath, Buffer.from(result));
70+
await unzipFile(zipFilePath, unzippedFilesDirectory);
6371

6472
this._onResultDownloaded.fire({
6573
variantAnalysisId,
@@ -156,7 +164,7 @@ export class VariantAnalysisResultsManager extends DisposableObject {
156164
);
157165
}
158166

159-
private getRepoStorageDirectory(variantAnalysisId: number, fullName: string): string {
167+
public getRepoStorageDirectory(variantAnalysisId: number, fullName: string): string {
160168
return path.join(
161169
this.getStorageDirectory(variantAnalysisId),
162170
fullName

extensions/ql-vscode/src/vscode-tests/cli-integration/remote-queries/variant-analysis-results-manager.test.ts

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ import { CodeQLExtensionInterface } from '../../../extension';
55
import { logger } from '../../../logging';
66
import { Credentials } from '../../../authentication';
77
import * as fs from 'fs-extra';
8+
import * as path from 'path';
89

910
import { VariantAnalysisResultsManager } from '../../../remote-queries/variant-analysis-results-manager';
1011
import { createMockVariantAnalysisRepoTask } from '../../factories/remote-queries/gh-api/variant-analysis-repo-task';
1112
import { CodeQLCliServer } from '../../../cli';
1213
import { storagePath } from '../global.helper';
1314
import { faker } from '@faker-js/faker';
1415
import * as ghApiClient from '../../../remote-queries/gh-api/gh-api-client';
16+
import { VariantAnalysisRepoTask } from '../../../remote-queries/gh-api/variant-analysis';
1517

1618
describe(VariantAnalysisResultsManager.name, () => {
1719
let sandbox: sinon.SinonSandbox;
@@ -69,12 +71,29 @@ describe(VariantAnalysisResultsManager.name, () => {
6971
});
7072

7173
describe('when the artifact_url is present', async () => {
72-
it('should save the result to disk', async () => {
73-
const dummyRepoTask = createMockVariantAnalysisRepoTask();
74+
let dummyRepoTask: VariantAnalysisRepoTask;
75+
let storageDirectory: string;
76+
let arrayBuffer: ArrayBuffer;
77+
78+
beforeEach(async () => {
79+
dummyRepoTask = createMockVariantAnalysisRepoTask();
80+
81+
storageDirectory = variantAnalysisResultsManager.getRepoStorageDirectory(variantAnalysisId, dummyRepoTask.repository.full_name);
82+
const sourceFilePath = path.join(__dirname, '../../../../src/vscode-tests/cli-integration/data/variant-analysis-results.zip');
83+
arrayBuffer = fs.readFileSync(sourceFilePath).buffer;
7484

75-
const dummyResult = 'this-is-a-repo-result';
76-
getVariantAnalysisRepoResultStub = sandbox.stub(ghApiClient, 'getVariantAnalysisRepoResult').withArgs(mockCredentials, dummyRepoTask.artifact_url as string).resolves(dummyResult);
85+
getVariantAnalysisRepoResultStub = sandbox
86+
.stub(ghApiClient, 'getVariantAnalysisRepoResult')
87+
.withArgs(mockCredentials, dummyRepoTask.artifact_url as string)
88+
.resolves(arrayBuffer);
89+
});
90+
91+
afterEach(async () => {
92+
fs.removeSync(`${storageDirectory}/results.zip`);
93+
fs.removeSync(`${storageDirectory}/results`);
94+
});
7795

96+
it('should call the API to download the results', async () => {
7897
await variantAnalysisResultsManager.download(
7998
mockCredentials,
8099
variantAnalysisId,
@@ -83,6 +102,26 @@ describe(VariantAnalysisResultsManager.name, () => {
83102

84103
expect(getVariantAnalysisRepoResultStub.calledOnce).to.be.true;
85104
});
105+
106+
it('should save the results zip file to disk', async () => {
107+
await variantAnalysisResultsManager.download(
108+
mockCredentials,
109+
variantAnalysisId,
110+
dummyRepoTask
111+
);
112+
113+
expect(fs.existsSync(`${storageDirectory}/results.zip`)).to.be.true;
114+
});
115+
116+
it('should unzip the results in a `results/` folder', async () => {
117+
await variantAnalysisResultsManager.download(
118+
mockCredentials,
119+
variantAnalysisId,
120+
dummyRepoTask
121+
);
122+
123+
expect(fs.existsSync(`${storageDirectory}/results/results.sarif`)).to.be.true;
124+
});
86125
});
87126
});
88127
});

0 commit comments

Comments
 (0)