Skip to content

Commit b22de66

Browse files
author
Jahed Ahmed
committedMay 5, 2021
test(protect): split unit tests per-module
1 parent 8e4862d commit b22de66

File tree

5 files changed

+269
-268
lines changed

5 files changed

+269
-268
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import * as path from 'path';
2+
import { checkProject } from '../../src/lib/explore-node-modules';
3+
import { PhysicalModuleToPatch } from '../../src/lib/types';
4+
5+
describe(checkProject.name, () => {
6+
it('works with no matching physical modules', () => {
7+
const fixtureFolderRelativePath = '../fixtures/no-matching-paths';
8+
const fixtureFolder = path.join(__dirname, fixtureFolderRelativePath);
9+
10+
const physicalModulesToPatch: PhysicalModuleToPatch[] = []; // this will get populated by checkProject
11+
checkProject(fixtureFolder, ['lodash'], physicalModulesToPatch);
12+
13+
expect(physicalModulesToPatch).toHaveLength(0);
14+
});
15+
16+
it('works with single matching physical module', () => {
17+
const fixtureFolderRelativePath = '../fixtures/single-patchable-module';
18+
const fixtureFolder = path.join(__dirname, fixtureFolderRelativePath);
19+
20+
const physicalModulesToPatch: PhysicalModuleToPatch[] = []; // this will get populated by checkProject
21+
checkProject(fixtureFolder, ['lodash'], physicalModulesToPatch);
22+
23+
expect(physicalModulesToPatch).toHaveLength(1);
24+
const m = physicalModulesToPatch[0];
25+
expect(m.name).toBe('lodash');
26+
expect(m.version).toBe('4.17.15');
27+
expect(m.folderPath).toEqual(
28+
path.join(
29+
__dirname,
30+
fixtureFolderRelativePath,
31+
'/node_modules/nyc/node_modules/lodash',
32+
),
33+
);
34+
});
35+
36+
it('works with multiple matching physical modules', () => {
37+
const fixtureFolderRelativePath = '../fixtures/multiple-matching-paths';
38+
const fixtureFolder = path.join(__dirname, fixtureFolderRelativePath);
39+
40+
const physicalModulesToPatch: PhysicalModuleToPatch[] = []; // this will get populated by checkProject
41+
checkProject(fixtureFolder, ['lodash'], physicalModulesToPatch);
42+
43+
expect(physicalModulesToPatch).toHaveLength(2);
44+
const m0 = physicalModulesToPatch[0];
45+
expect(m0.name).toBe('lodash');
46+
expect(m0.version).toBe('4.17.15');
47+
expect(m0.folderPath).toEqual(
48+
path.join(__dirname, fixtureFolderRelativePath, '/node_modules/lodash'),
49+
);
50+
const m1 = physicalModulesToPatch[1];
51+
expect(m1.name).toBe('lodash');
52+
expect(m1.version).toBe('4.17.15');
53+
expect(m1.folderPath).toEqual(
54+
path.join(
55+
__dirname,
56+
fixtureFolderRelativePath,
57+
'/node_modules/nyc/node_modules/lodash',
58+
),
59+
);
60+
});
61+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { getPatches } from '../../src/lib/get-patches';
2+
import { PackageAndVersion } from '../../src/lib/types';
3+
4+
// TODO: lower it once Protect stops hitting real Snyk API endpoints
5+
const testTimeout = 30000;
6+
7+
// These tests makes a real API calls to Snyk
8+
// TODO: would be better to mock the response
9+
describe(getPatches.name, () => {
10+
it(
11+
'seems to work',
12+
async () => {
13+
const packageAndVersions: PackageAndVersion[] = [
14+
{
15+
name: 'lodash',
16+
version: '4.17.15',
17+
} as PackageAndVersion,
18+
];
19+
const vulnIds = ['SNYK-JS-LODASH-567746'];
20+
const patches = await getPatches(packageAndVersions, vulnIds);
21+
expect(Object.keys(patches)).toEqual(['lodash']);
22+
const lodashPatches = patches['lodash'];
23+
expect(lodashPatches).toHaveLength(1);
24+
const theOnePatch = lodashPatches[0];
25+
expect(theOnePatch.id).toBe('patch:SNYK-JS-LODASH-567746:0');
26+
expect(theOnePatch.diffs).toHaveLength(1);
27+
expect(theOnePatch.diffs[0]).toContain('index 9b95dfef..43e71ffb 100644'); // something from the actual patch
28+
},
29+
testTimeout,
30+
);
31+
32+
it(
33+
'does not download patch for non-applicable version',
34+
async () => {
35+
const packageAndVersions: PackageAndVersion[] = [
36+
{
37+
name: 'lodash',
38+
version: '4.17.20', // this version is not applicable to the patch
39+
} as PackageAndVersion,
40+
];
41+
const vulnIds = ['SNYK-JS-LODASH-567746'];
42+
const patches = await getPatches(packageAndVersions, vulnIds);
43+
expect(patches).toEqual({}); // expect nothing to be returned because SNYK-JS-LODASH-567746 does not apply to 4.17.20 of lodash
44+
},
45+
testTimeout,
46+
);
47+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import * as fs from 'fs';
2+
import * as path from 'path';
3+
import {
4+
extractTargetFilePathFromPatch,
5+
patchString,
6+
} from '../../src/lib/patch';
7+
8+
describe(patchString.name, () => {
9+
it('can apply a patch using string', () => {
10+
const fixtureFolder = path.join(
11+
__dirname,
12+
'../fixtures/patchable-file-lodash',
13+
);
14+
const patchFilePath = path.join(fixtureFolder, 'lodash.patch');
15+
16+
const patchContents = fs.readFileSync(patchFilePath, 'utf-8');
17+
18+
const targetFilePath = path.join(
19+
fixtureFolder,
20+
extractTargetFilePathFromPatch(patchContents),
21+
);
22+
const contentsToPatch = fs.readFileSync(targetFilePath, 'utf-8');
23+
24+
const patchedContents = patchString(patchContents, contentsToPatch);
25+
26+
const expectedPatchedContentsFilePath = path.join(
27+
fixtureFolder,
28+
'lodash-expected-patched.js',
29+
);
30+
const expectedPatchedContents = fs.readFileSync(
31+
expectedPatchedContentsFilePath,
32+
'utf-8',
33+
);
34+
expect(patchedContents).toBe(expectedPatchedContents);
35+
expect(0).toBe(0);
36+
});
37+
38+
// if the patch is not compatible with the target, make sure we throw an Error and do patch
39+
it('will throw if patch does not match target', () => {
40+
const fixtureFolder = path.join(
41+
__dirname,
42+
'../fixtures/non-patchable-file-because-non-matching',
43+
);
44+
const patchFilePath = path.join(fixtureFolder, 'lodash.patch');
45+
const patchContents = fs.readFileSync(patchFilePath, 'utf-8');
46+
const targetFilePath = path.join(
47+
fixtureFolder,
48+
extractTargetFilePathFromPatch(patchContents),
49+
);
50+
const contentsToPatch = fs.readFileSync(targetFilePath, 'utf-8');
51+
expect(() => {
52+
patchString(patchContents, contentsToPatch);
53+
}).toThrow(Error);
54+
});
55+
});

‎packages/snyk-protect/test/unit/protect-unit-tests.spec.ts

-268
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { extractPatchMetadata } from '../../src/lib/snyk-file';
2+
3+
describe(extractPatchMetadata.name, () => {
4+
it('works with a single patch', () => {
5+
const dotSnykFileContents = `
6+
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
7+
version: v1.19.0
8+
ignore: {}
9+
# patches apply the minimum changes required to fix a vulnerability
10+
patch:
11+
SNYK-JS-LODASH-567746:
12+
- tap > nyc > istanbul-lib-instrument > babel-types > lodash:
13+
patched: '2021-02-17T13:43:51.857Z'
14+
`;
15+
const snykFilePatchMetadata = extractPatchMetadata(dotSnykFileContents);
16+
const vulnIds = Object.keys(snykFilePatchMetadata);
17+
18+
// can't use .flat() because it's not supported in Node 10
19+
const packageNames: string[] = [];
20+
for (const nextArrayOfPackageNames of Object.values(
21+
snykFilePatchMetadata,
22+
)) {
23+
packageNames.push(...nextArrayOfPackageNames);
24+
}
25+
26+
expect(vulnIds).toEqual(['SNYK-JS-LODASH-567746']);
27+
expect(packageNames).toEqual(['lodash']);
28+
});
29+
30+
it('works with multiple patches', async () => {
31+
const dotSnykFileContents = `
32+
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
33+
version: v1.19.0
34+
ignore: {}
35+
# patches apply the minimum changes required to fix a vulnerability
36+
patch:
37+
SNYK-JS-LODASH-567746:
38+
- tap > nyc > istanbul-lib-instrument > babel-types > lodash:
39+
patched: '2021-02-17T13:43:51.857Z'
40+
41+
SNYK-FAKE-THEMODULE-000000:
42+
- top-level > some-other > the-module:
43+
patched: '2021-02-17T13:43:51.857Z'
44+
`;
45+
const snykFilePatchMetadata = extractPatchMetadata(dotSnykFileContents);
46+
const vulnIds = Object.keys(snykFilePatchMetadata);
47+
48+
// can't use .flat() because it's not supported in Node 10
49+
const packageNames: string[] = [];
50+
for (const nextArrayOfPackageNames of Object.values(
51+
snykFilePatchMetadata,
52+
)) {
53+
packageNames.push(...nextArrayOfPackageNames);
54+
}
55+
56+
expect(vulnIds).toEqual([
57+
'SNYK-JS-LODASH-567746',
58+
'SNYK-FAKE-THEMODULE-000000',
59+
]);
60+
expect(packageNames).toEqual(['lodash', 'the-module']);
61+
});
62+
63+
it('works with zero patches defined in patch section', async () => {
64+
const dotSnykFileContents = `
65+
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
66+
version: v1.19.0
67+
ignore: {}
68+
# patches apply the minimum changes required to fix a vulnerability
69+
patch:
70+
`;
71+
const snykFilePatchMetadata = extractPatchMetadata(dotSnykFileContents);
72+
const vulnIds = Object.keys(snykFilePatchMetadata);
73+
74+
// can't use .flat() because it's not supported in Node 10
75+
const packageNames: string[] = [];
76+
for (const nextArrayOfPackageNames of Object.values(
77+
snykFilePatchMetadata,
78+
)) {
79+
packageNames.push(...nextArrayOfPackageNames);
80+
}
81+
82+
expect(vulnIds).toHaveLength(0);
83+
expect(packageNames).toHaveLength(0);
84+
});
85+
86+
it('works with no patch section', async () => {
87+
const dotSnykFileContents = `
88+
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
89+
version: v1.19.0
90+
ignore: {}
91+
`;
92+
const snykFilePatchMetadata = extractPatchMetadata(dotSnykFileContents);
93+
const vulnIds = Object.keys(snykFilePatchMetadata);
94+
95+
// can't use .flat() because it's not supported in Node 10
96+
const packageNames: string[] = [];
97+
for (const nextArrayOfPackageNames of Object.values(
98+
snykFilePatchMetadata,
99+
)) {
100+
packageNames.push(...nextArrayOfPackageNames);
101+
}
102+
103+
expect(vulnIds).toHaveLength(0);
104+
expect(packageNames).toHaveLength(0);
105+
});
106+
});

0 commit comments

Comments
 (0)
Please sign in to comment.