Files

254 lines
7.8 KiB
TypeScript
Raw Permalink Normal View History

2022-06-14 13:00:18 +02:00
import {expect, test, beforeEach} from '@jest/globals'
2022-11-08 09:53:36 +00:00
import {readConfig} from '../src/config'
import {getRefs} from '../src/git-refs'
2022-10-21 13:51:02 +00:00
import * as Utils from '../src/utils'
2022-06-14 13:00:18 +02:00
// GitHub Action inputs come in the form of environment variables
// with an INPUT prefix (e.g. INPUT_FAIL-ON-SEVERITY)
function setInput(input: string, value: string) {
process.env[`INPUT_${input.toUpperCase()}`] = value
}
// We want a clean ENV before each test. We use `delete`
// since we want `undefined` values and not empty strings.
function clearInputs() {
2022-08-18 15:03:11 +02:00
const allowedOptions = [
'FAIL-ON-SEVERITY',
2022-09-15 18:48:58 +00:00
'FAIL-ON-SCOPES',
2022-08-18 15:03:11 +02:00
'ALLOW-LICENSES',
'DENY-LICENSES',
2022-09-22 21:34:18 +00:00
'ALLOW-GHSAS',
'LICENSE-CHECK',
'VULNERABILITY-CHECK',
2022-09-19 17:29:25 +02:00
'CONFIG-FILE',
2022-08-18 15:03:11 +02:00
'BASE-REF',
'HEAD-REF'
]
allowedOptions.forEach(option => {
delete process.env[`INPUT_${option.toUpperCase()}`]
})
2022-06-14 13:00:18 +02:00
}
2022-10-21 13:51:02 +00:00
beforeAll(() => {
jest.spyOn(Utils, 'isSPDXValid').mockReturnValue(true)
})
2022-06-14 13:00:18 +02:00
beforeEach(() => {
clearInputs()
2022-06-13 19:55:08 +02:00
})
test('it defaults to low severity', async () => {
2022-11-08 10:52:30 +00:00
const config = await readConfig()
expect(config.fail_on_severity).toEqual('low')
2022-06-13 19:55:08 +02:00
})
test('it reads custom configs', async () => {
2022-06-14 13:00:18 +02:00
setInput('fail-on-severity', 'critical')
setInput('allow-licenses', ' BSD, GPL 2')
2022-06-13 19:55:08 +02:00
2022-11-08 10:52:30 +00:00
const config = await readConfig()
expect(config.fail_on_severity).toEqual('critical')
expect(config.allow_licenses).toEqual(['BSD', 'GPL 2'])
})
2022-06-13 19:55:08 +02:00
test('it defaults to empty allow/deny lists ', async () => {
2022-11-08 10:52:30 +00:00
const config = await readConfig()
2022-11-08 10:52:30 +00:00
expect(config.allow_licenses).toEqual(undefined)
expect(config.deny_licenses).toEqual(undefined)
2022-06-06 17:07:26 +02:00
})
test('it raises an error if both an allow and denylist are specified', async () => {
2022-06-14 13:00:18 +02:00
setInput('allow-licenses', 'MIT')
setInput('deny-licenses', 'BSD')
await expect(readConfig()).rejects.toThrow(
'You cannot specify both allow-licenses and deny-licenses'
)
2022-06-06 17:07:26 +02:00
})
2022-11-08 11:15:36 +00:00
test('it raises an error if an empty allow list is specified', async () => {
setInput('config-file', './__tests__/fixtures/config-empty-allow-sample.yml')
await expect(readConfig()).rejects.toThrow(
'You should provide at least one license in allow-licenses'
)
})
2022-06-13 19:55:08 +02:00
2022-06-14 07:42:51 +02:00
test('it raises an error when given an unknown severity', async () => {
2022-06-14 13:00:18 +02:00
setInput('fail-on-severity', 'zombies')
await expect(readConfig()).rejects.toThrow(/received 'zombies'/)
2022-06-14 07:42:51 +02:00
})
test('it uses the given refs when the event is not a pull request', async () => {
setInput('base-ref', 'a-custom-base-ref')
setInput('head-ref', 'a-custom-head-ref')
const refs = getRefs(await readConfig(), {
payload: {},
eventName: 'workflow_dispatch'
})
expect(refs.base).toEqual('a-custom-base-ref')
expect(refs.head).toEqual('a-custom-head-ref')
})
test('it raises an error when no refs are provided and the event is not a pull request', async () => {
2022-11-08 10:52:30 +00:00
const config = await readConfig()
expect(() =>
2022-11-08 10:52:30 +00:00
getRefs(config, {
payload: {},
eventName: 'workflow_dispatch'
})
).toThrow()
})
2022-09-16 14:31:06 +02:00
2022-11-08 09:53:36 +00:00
test('it reads an external config file', async () => {
setInput('config-file', './__tests__/fixtures/config-allow-sample.yml')
const config = await readConfig()
expect(config.fail_on_severity).toEqual('critical')
expect(config.allow_licenses).toEqual(['BSD', 'GPL 2'])
2022-09-16 14:31:06 +02:00
})
2022-11-08 09:53:36 +00:00
test('raises an error when the the config file was not found', async () => {
setInput('config-file', 'fixtures/i-dont-exist')
await expect(readConfig()).rejects.toThrow(/Unable to fetch config file/)
2022-09-16 14:31:06 +02:00
})
2022-09-19 17:29:25 +02:00
2022-11-04 16:12:05 +00:00
test('it parses options from both sources', async () => {
setInput('config-file', './__tests__/fixtures/config-allow-sample.yml')
2022-11-08 10:52:30 +00:00
let config = await readConfig()
expect(config.fail_on_severity).toEqual('critical')
setInput('base-ref', 'a-custom-base-ref')
2022-11-08 10:52:30 +00:00
config = await readConfig()
expect(config.base_ref).toEqual('a-custom-base-ref')
})
2022-11-08 10:52:30 +00:00
test('in case of conflicts, the inline config is the source of truth', async () => {
setInput('fail-on-severity', 'low')
setInput('config-file', './__tests__/fixtures/config-allow-sample.yml') // this will set fail-on-severity to 'critical'
2022-09-19 17:29:25 +02:00
2022-11-08 10:52:30 +00:00
const config = await readConfig()
expect(config.fail_on_severity).toEqual('low')
2022-09-19 17:29:25 +02:00
})
2022-09-19 17:34:12 +02:00
2022-11-04 16:12:05 +00:00
test('it uses the default values when loading external files', async () => {
setInput('config-file', './__tests__/fixtures/no-licenses-config.yml')
2022-11-08 10:52:30 +00:00
let config = await readConfig()
expect(config.allow_licenses).toEqual(undefined)
expect(config.deny_licenses).toEqual(undefined)
setInput('config-file', './__tests__/fixtures/license-config-sample.yml')
2022-11-08 10:52:30 +00:00
config = await readConfig()
expect(config.fail_on_severity).toEqual('low')
})
2022-09-19 17:34:12 +02:00
test('it accepts an external configuration filename', async () => {
setInput('config-file', './__tests__/fixtures/no-licenses-config.yml')
2022-11-08 10:52:30 +00:00
const config = await readConfig()
expect(config.fail_on_severity).toEqual('critical')
2022-09-19 17:34:12 +02:00
})
test('it raises an error when given an unknown severity in an external config file', async () => {
setInput('config-file', './__tests__/fixtures/invalid-severity-config.yml')
await expect(readConfig()).rejects.toThrow()
})
2022-09-21 16:50:02 +02:00
2022-09-15 18:48:58 +00:00
test('it defaults to runtime scope', async () => {
2022-11-08 10:52:30 +00:00
const config = await readConfig()
expect(config.fail_on_scopes).toEqual(['runtime'])
2022-09-15 18:48:58 +00:00
})
2022-09-21 16:50:02 +02:00
2022-09-15 18:48:58 +00:00
test('it parses custom scopes preference', async () => {
setInput('fail-on-scopes', 'runtime, development')
2022-11-08 10:52:30 +00:00
let config = await readConfig()
expect(config.fail_on_scopes).toEqual(['runtime', 'development'])
2022-09-15 18:48:58 +00:00
clearInputs()
setInput('fail-on-scopes', 'development')
2022-11-08 10:52:30 +00:00
config = await readConfig()
expect(config.fail_on_scopes).toEqual(['development'])
2022-09-15 18:48:58 +00:00
})
2022-09-21 16:50:02 +02:00
2022-09-15 18:48:58 +00:00
test('it raises an error when given invalid scope', async () => {
setInput('fail-on-scopes', 'runtime, zombies')
await expect(readConfig()).rejects.toThrow(/received 'zombies'/)
2022-09-15 18:48:58 +00:00
})
2022-11-08 10:52:30 +00:00
test('it defaults to an empty GHSA allowlist', async () => {
const config = await readConfig()
expect(config.allow_ghsas).toEqual([])
2022-09-22 21:34:18 +00:00
})
test('it successfully parses GHSA allowlist', async () => {
setInput('allow-ghsas', 'GHSA-abcd-1234-5679, GHSA-efgh-1234-5679')
2022-11-08 10:52:30 +00:00
const config = await readConfig()
expect(config.allow_ghsas).toEqual([
2022-09-22 21:34:18 +00:00
'GHSA-abcd-1234-5679',
'GHSA-efgh-1234-5679'
])
})
2022-10-21 13:51:02 +00:00
test('it defaults to checking licenses', async () => {
2022-11-08 10:52:30 +00:00
const config = await readConfig()
expect(config.license_check).toBe(true)
})
test('it parses the license-check input', async () => {
setInput('license-check', 'false')
2022-11-08 10:52:30 +00:00
let config = await readConfig()
expect(config.license_check).toEqual(false)
clearInputs()
setInput('license-check', 'true')
2022-11-08 10:52:30 +00:00
config = await readConfig()
expect(config.license_check).toEqual(true)
})
test('it defaults to checking vulnerabilities', async () => {
2022-11-08 10:52:30 +00:00
const config = await readConfig()
expect(config.vulnerability_check).toBe(true)
})
test('it parses the vulnerability-check input', async () => {
setInput('vulnerability-check', 'false')
2022-11-08 10:52:30 +00:00
let config = await readConfig()
expect(config.vulnerability_check).toEqual(false)
clearInputs()
setInput('vulnerability-check', 'true')
2022-11-08 10:52:30 +00:00
config = await readConfig()
expect(config.vulnerability_check).toEqual(true)
})
2022-10-31 07:55:17 +01:00
test('it is not possible to disable both checks', async () => {
2022-10-28 22:08:55 +02:00
setInput('license-check', 'false')
setInput('vulnerability-check', 'false')
await expect(readConfig()).rejects.toThrow(
/Can't disable both license-check and vulnerability-check/
)
2022-10-28 22:08:55 +02:00
})
2022-10-21 13:51:02 +00:00
describe('licenses that are not valid SPDX licenses', () => {
beforeAll(() => {
jest.spyOn(Utils, 'isSPDXValid').mockReturnValue(false)
})
test('it raises an error for invalid licenses in allow-licenses', async () => {
setInput('allow-licenses', ' BSD, GPL 2')
await expect(readConfig()).rejects.toThrow(
'Invalid license(s) in allow-licenses: BSD, GPL 2'
)
2022-10-21 13:51:02 +00:00
})
test('it raises an error for invalid licenses in deny-licenses', async () => {
setInput('deny-licenses', ' BSD, GPL 2')
await expect(readConfig()).rejects.toThrow(
'Invalid license(s) in deny-licenses: BSD, GPL 2'
)
2022-10-21 13:51:02 +00:00
})
})