Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add fallback audit to tests #4770

Merged
merged 1 commit into from
Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions tap-snapshots/test/lib/commands/audit.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/lib/commands/audit.js TAP audit fix > lockfile has test-dep-a@1.0.1 1`] = `
exports[`test/lib/commands/audit.js TAP audit fix - bulk endpoint > lockfile has test-dep-a@1.0.1 1`] = `
{
"name": "test-dep",
"version": "1.0.0",
Expand Down Expand Up @@ -34,13 +34,28 @@ exports[`test/lib/commands/audit.js TAP audit fix > lockfile has test-dep-a@1.0.

`

exports[`test/lib/commands/audit.js TAP audit fix > must match snapshot 1`] = `
exports[`test/lib/commands/audit.js TAP audit fix - bulk endpoint > must match snapshot 1`] = `

added 1 package, and audited 2 packages in xxx

found 0 vulnerabilities
`

exports[`test/lib/commands/audit.js TAP fallback audit > must match snapshot 1`] = `
# npm audit report

test-dep-a 1.0.0
Severity: high
Test advisory 100 - https://github.com/advisories/GHSA-100
fix available via \`npm audit fix\`
node_modules/test-dep-a

1 high severity vulnerability

To address all issues, run:
npm audit fix
`

exports[`test/lib/commands/audit.js TAP json audit > must match snapshot 1`] = `
{
"auditReportVersion": 2,
Expand Down Expand Up @@ -98,14 +113,14 @@ exports[`test/lib/commands/audit.js TAP json audit > must match snapshot 1`] = `
exports[`test/lib/commands/audit.js TAP normal audit > must match snapshot 1`] = `
# npm audit report

test-dep-a *
test-dep-a 1.0.0
Severity: high
Test advisory 100 - https://github.com/advisories/GHSA-100
No fix available
fix available via \`npm audit fix\`
node_modules/test-dep-a

1 high severity vulnerability

Some issues need review, and may require choosing
a different dependency.
To address all issues, run:
npm audit fix
`
90 changes: 76 additions & 14 deletions test/lib/commands/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ const t = require('tap')

const { load: loadMockNpm } = require('../../fixtures/mock-npm')
const MockRegistry = require('../../fixtures/mock-registry.js')
const util = require('util')
const zlib = require('zlib')
const gzip = util.promisify(zlib.gzip)
const gzip = zlib.gzipSync
const gunzip = zlib.gunzipSync
const path = require('path')
const fs = require('fs')

Expand Down Expand Up @@ -43,7 +43,14 @@ const tree = {
},
},
}),
'test-dep-a': {
'test-dep-a-vuln': {
'package.json': JSON.stringify({
name: 'test-dep-a',
version: '1.0.0',
}),
'vulnerable.txt': 'vulnerable test-dep-a',
},
'test-dep-a-fixed': {
'package.json': JSON.stringify({
name: 'test-dep-a',
version: '1.0.1',
Expand All @@ -66,8 +73,11 @@ t.test('normal audit', async t => {
packuments: [{ version: '1.0.0' }, { version: '1.0.1' }],
})
await registry.package({ manifest })
const advisory = registry.advisory({ id: 100 })
const bulkBody = await gzip(JSON.stringify({ 'test-dep-a': ['1.0.0'] }))
const advisory = registry.advisory({
id: 100,
vulnerable_versions: '<1.0.1',
})
const bulkBody = gzip(JSON.stringify({ 'test-dep-a': ['1.0.0'] }))
registry.nock.post('/-/npm/v1/security/advisories/bulk', bulkBody)
.reply(200, {
'test-dep-a': [advisory],
Expand All @@ -79,6 +89,55 @@ t.test('normal audit', async t => {
t.matchSnapshot(joinedOutput())
})

t.test('fallback audit ', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: tree,
})
const registry = new MockRegistry({
tap: t,
registry: npm.config.get('registry'),
})
const manifest = registry.manifest({
name: 'test-dep-a',
packuments: [{ version: '1.0.0' }, { version: '1.0.1' }],
})
await registry.package({ manifest })
const advisory = registry.advisory({
id: 100,
module_name: 'test-dep-a',
vulnerable_versions: '<1.0.1',
findings: [{ version: '1.0.0', paths: ['test-dep-a'] }],
})
registry.nock
.post('/-/npm/v1/security/advisories/bulk').reply(404)
.post('/-/npm/v1/security/audits/quick', body => {
const unzipped = JSON.parse(gunzip(Buffer.from(body, 'hex')))
return t.match(unzipped, {
name: 'test-dep',
version: '1.0.0',
requires: { 'test-dep-a': '*' },
dependencies: { 'test-dep-a': { version: '1.0.0' } },
})
}).reply(200, {
actions: [],
muted: [],
advisories: {
100: advisory,
},
metadata: {
vulnerabilities: { info: 0, low: 0, moderate: 0, high: 1, critical: 0 },
dependencies: 1,
devDependencies: 0,
optionalDependencies: 0,
totalDependencies: 1,
},
})
await npm.exec('audit', [])
t.ok(process.exitCode, 'would have exited uncleanly')
process.exitCode = 0
t.matchSnapshot(joinedOutput())
})

t.test('json audit', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: tree,
Expand All @@ -97,7 +156,7 @@ t.test('json audit', async t => {
})
await registry.package({ manifest })
const advisory = registry.advisory({ id: 100 })
const bulkBody = await gzip(JSON.stringify({ 'test-dep-a': ['1.0.0'] }))
const bulkBody = gzip(JSON.stringify({ 'test-dep-a': ['1.0.0'] }))
registry.nock.post('/-/npm/v1/security/advisories/bulk', bulkBody)
.reply(200, {
'test-dep-a': [advisory],
Expand All @@ -109,7 +168,7 @@ t.test('json audit', async t => {
t.matchSnapshot(joinedOutput())
})

t.test('audit fix', async t => {
t.test('audit fix - bulk endpoint', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: tree,
})
Expand All @@ -124,20 +183,23 @@ t.test('audit fix', async t => {
await registry.package({
manifest,
tarballs: {
'1.0.1': path.join(npm.prefix, 'test-dep-a'),
'1.0.1': path.join(npm.prefix, 'test-dep-a-fixed'),
},
})
const advisory = registry.advisory({ id: 100, vulnerable_versions: '1.0.0' })
// Can't validate this request body because it changes with each node
// version/npm version and nock's body validation is not async, while
// zlib.gunzip is
registry.nock.post('/-/npm/v1/security/advisories/bulk')
registry.nock.post('/-/npm/v1/security/advisories/bulk', body => {
const unzipped = JSON.parse(gunzip(Buffer.from(body, 'hex')))
return t.same(unzipped, { 'test-dep-a': ['1.0.0'] })
})
.reply(200, { // first audit
'test-dep-a': [advisory],
})
.post('/-/npm/v1/security/advisories/bulk')
.post('/-/npm/v1/security/advisories/bulk', body => {
const unzipped = JSON.parse(gunzip(Buffer.from(body, 'hex')))
return t.same(unzipped, { 'test-dep-a': ['1.0.1'] })
})
.reply(200, { // after fix
'test-dep-a': [advisory],
'test-dep-a': [],
})
await npm.exec('audit', ['fix'])
t.matchSnapshot(joinedOutput())
Expand Down