centralize collection of action inputs (#72)
Signed-off-by: Brian DeHamer <[email protected]>
This commit is contained in:
@@ -2,12 +2,17 @@
|
||||
* Unit tests for the action's entrypoint, src/index.ts
|
||||
*/
|
||||
|
||||
import * as core from '@actions/core'
|
||||
import * as main from '../src/main'
|
||||
|
||||
// Mock the action's entrypoint
|
||||
const runMock = jest.spyOn(main, 'run').mockImplementation()
|
||||
const getBooleanInputMock = jest.spyOn(core, 'getBooleanInput')
|
||||
|
||||
describe('index', () => {
|
||||
beforeEach(() => {
|
||||
getBooleanInputMock.mockImplementation(() => false)
|
||||
})
|
||||
it('calls run when imported', async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
require('../src/index')
|
||||
|
||||
+48
-58
@@ -20,8 +20,6 @@ import * as main from '../src/main'
|
||||
// Mock the GitHub Actions core library
|
||||
const infoMock = jest.spyOn(core, 'info')
|
||||
const startGroupMock = jest.spyOn(core, 'startGroup')
|
||||
const getInputMock = jest.spyOn(core, 'getInput')
|
||||
const getBooleanInputMock = jest.spyOn(core, 'getBooleanInput')
|
||||
const setOutputMock = jest.spyOn(core, 'setOutput')
|
||||
const setFailedMock = jest.spyOn(core, 'setFailed')
|
||||
|
||||
@@ -38,6 +36,20 @@ const runMock = jest.spyOn(main, 'run')
|
||||
const mockAgent = new MockAgent()
|
||||
setGlobalDispatcher(mockAgent)
|
||||
|
||||
const defaultInputs: main.RunInputs = {
|
||||
predicate: '',
|
||||
predicateType: '',
|
||||
predicatePath: '',
|
||||
subjectName: '',
|
||||
subjectDigest: '',
|
||||
subjectPath: '',
|
||||
pushToRegistry: false,
|
||||
githubToken: '',
|
||||
privateSigning: false,
|
||||
batchSize: 50,
|
||||
batchDelay: 5000
|
||||
}
|
||||
|
||||
describe('action', () => {
|
||||
// Capture original environment variables and GitHub context so we can restore
|
||||
// them after each test
|
||||
@@ -95,24 +107,22 @@ describe('action', () => {
|
||||
})
|
||||
|
||||
describe('when ACTIONS_ID_TOKEN_REQUEST_URL is not set', () => {
|
||||
const inputs = {
|
||||
'subject-digest': subjectDigest,
|
||||
'subject-name': subjectName,
|
||||
'predicate-type': predicateType,
|
||||
const inputs: main.RunInputs = {
|
||||
...defaultInputs,
|
||||
subjectDigest,
|
||||
subjectName,
|
||||
predicateType,
|
||||
predicate,
|
||||
'github-token': 'gh-token'
|
||||
githubToken: 'gh-token'
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
// Nullify the OIDC token URL
|
||||
process.env.ACTIONS_ID_TOKEN_REQUEST_URL = ''
|
||||
|
||||
getInputMock.mockImplementation(mockInput(inputs))
|
||||
getBooleanInputMock.mockImplementation(() => false)
|
||||
})
|
||||
|
||||
it('sets a failed status', async () => {
|
||||
await main.run()
|
||||
await main.run(inputs)
|
||||
|
||||
expect(runMock).toHaveReturned()
|
||||
expect(setFailedMock).toHaveBeenCalledWith(
|
||||
@@ -124,12 +134,8 @@ describe('action', () => {
|
||||
})
|
||||
|
||||
describe('when no inputs are provided', () => {
|
||||
beforeEach(() => {
|
||||
getInputMock.mockImplementation(() => '')
|
||||
})
|
||||
|
||||
it('sets a failed status', async () => {
|
||||
await main.run()
|
||||
await main.run(defaultInputs)
|
||||
|
||||
expect(runMock).toHaveReturned()
|
||||
expect(setFailedMock).toHaveBeenCalledWith(
|
||||
@@ -139,12 +145,13 @@ describe('action', () => {
|
||||
})
|
||||
|
||||
describe('when the repository is private', () => {
|
||||
const inputs = {
|
||||
'subject-digest': subjectDigest,
|
||||
'subject-name': subjectName,
|
||||
'predicate-type': predicateType,
|
||||
const inputs: main.RunInputs = {
|
||||
...defaultInputs,
|
||||
subjectDigest,
|
||||
subjectName,
|
||||
predicateType,
|
||||
predicate,
|
||||
'github-token': 'gh-token'
|
||||
githubToken: 'gh-token'
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -154,9 +161,6 @@ describe('action', () => {
|
||||
repo: { owner: 'foo', repo: 'bar' }
|
||||
})
|
||||
|
||||
getInputMock.mockImplementation(mockInput(inputs))
|
||||
getBooleanInputMock.mockImplementation(() => false)
|
||||
|
||||
await mockFulcio({
|
||||
baseURL: 'https://fulcio.githubapp.com',
|
||||
strict: false
|
||||
@@ -165,7 +169,7 @@ describe('action', () => {
|
||||
})
|
||||
|
||||
it('invokes the action w/o error', async () => {
|
||||
await main.run()
|
||||
await main.run(inputs)
|
||||
|
||||
expect(runMock).toHaveReturned()
|
||||
expect(setFailedMock).not.toHaveBeenCalledWith()
|
||||
@@ -204,12 +208,14 @@ describe('action', () => {
|
||||
const getRegCredsSpy = jest.spyOn(oci, 'getRegistryCredentials')
|
||||
const attachArtifactSpy = jest.spyOn(oci, 'attachArtifactToImage')
|
||||
|
||||
const inputs = {
|
||||
'subject-digest': subjectDigest,
|
||||
'subject-name': subjectName,
|
||||
'predicate-type': predicateType,
|
||||
const inputs: main.RunInputs = {
|
||||
...defaultInputs,
|
||||
subjectDigest,
|
||||
subjectName,
|
||||
predicateType,
|
||||
predicate,
|
||||
'github-token': 'gh-token'
|
||||
githubToken: 'gh-token',
|
||||
pushToRegistry: true
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -219,11 +225,6 @@ describe('action', () => {
|
||||
repo: { owner: 'foo', repo: 'bar' }
|
||||
})
|
||||
|
||||
// Mock the action's inputs
|
||||
getInputMock.mockImplementation(mockInput(inputs))
|
||||
// This is where we mock the push-to-registry input
|
||||
getBooleanInputMock.mockImplementation(() => true)
|
||||
|
||||
await mockFulcio({
|
||||
baseURL: 'https://fulcio.sigstore.dev',
|
||||
strict: false
|
||||
@@ -244,7 +245,7 @@ describe('action', () => {
|
||||
})
|
||||
|
||||
it('invokes the action w/o error', async () => {
|
||||
await main.run()
|
||||
await main.run(inputs)
|
||||
|
||||
expect(runMock).toHaveReturned()
|
||||
expect(setFailedMock).not.toHaveBeenCalled()
|
||||
@@ -291,6 +292,7 @@ describe('action', () => {
|
||||
|
||||
describe('when the subject count exceeds the batch size', () => {
|
||||
let dir = ''
|
||||
const filename = 'subject'
|
||||
let scope: nock.Scope
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -298,7 +300,6 @@ describe('action', () => {
|
||||
nock.cleanAll()
|
||||
|
||||
const subjectCount = 5
|
||||
const filename = 'subject'
|
||||
const content = 'file content'
|
||||
|
||||
// Set-up temp directory
|
||||
@@ -340,17 +341,6 @@ describe('action', () => {
|
||||
payload: { repository: { visibility: 'private' } },
|
||||
repo: { owner: 'foo', repo: 'bar' }
|
||||
})
|
||||
|
||||
const inputs = {
|
||||
'subject-path': path.join(dir, `${filename}-*`),
|
||||
'predicate-type': predicateType,
|
||||
predicate,
|
||||
'github-token': 'gh-token',
|
||||
'batch-size': '2',
|
||||
'batch-delay': '500'
|
||||
}
|
||||
getInputMock.mockImplementation(mockInput(inputs))
|
||||
getBooleanInputMock.mockImplementation(() => false)
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
@@ -359,7 +349,16 @@ describe('action', () => {
|
||||
})
|
||||
|
||||
it('invokes the action w/o error', async () => {
|
||||
await main.run()
|
||||
const inputs: main.RunInputs = {
|
||||
...defaultInputs,
|
||||
subjectPath: path.join(dir, `${filename}-*`),
|
||||
predicateType,
|
||||
predicate,
|
||||
githubToken: 'gh-token',
|
||||
batchSize: 2,
|
||||
batchDelay: 500
|
||||
}
|
||||
await main.run(inputs)
|
||||
|
||||
expect(runMock).toHaveReturned()
|
||||
expect(setFailedMock).not.toHaveBeenCalled()
|
||||
@@ -380,15 +379,6 @@ describe('action', () => {
|
||||
})
|
||||
})
|
||||
|
||||
function mockInput(inputs: Record<string, string>): typeof core.getInput {
|
||||
return (name: string): string => {
|
||||
if (name in inputs) {
|
||||
return inputs[name]
|
||||
}
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
// Stubbing the GitHub context is a bit tricky. We need to use
|
||||
// `Object.defineProperty` because `github.context` is read-only.
|
||||
function setGHContext(context: object): void {
|
||||
|
||||
+46
-40
@@ -1,91 +1,97 @@
|
||||
import fs from 'fs/promises'
|
||||
import os from 'os'
|
||||
import path from 'path'
|
||||
import { predicateFromInputs } from '../src/predicate'
|
||||
import { predicateFromInputs, PredicateInputs } from '../src/predicate'
|
||||
|
||||
describe('subjectFromInputs', () => {
|
||||
afterEach(() => {
|
||||
process.env['INPUT_PREDICATE'] = ''
|
||||
process.env['INPUT_PREDICATE-PATH'] = ''
|
||||
process.env['INPUT_PREDICATE-TYPE'] = ''
|
||||
})
|
||||
const blankInputs: PredicateInputs = {
|
||||
predicateType: '',
|
||||
predicate: '',
|
||||
predicatePath: ''
|
||||
}
|
||||
|
||||
describe('when no inputs are provided', () => {
|
||||
it('throws an error', () => {
|
||||
expect(() => predicateFromInputs()).toThrow(/predicate-type/i)
|
||||
expect(() => predicateFromInputs(blankInputs)).toThrow(/predicate-type/i)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when neither predicate path nor predicate are provided', () => {
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_PREDICATE-TYPE'] = 'https://example.com/predicate'
|
||||
})
|
||||
|
||||
it('throws an error', () => {
|
||||
expect(() => predicateFromInputs()).toThrow(
|
||||
const inputs: PredicateInputs = {
|
||||
...blankInputs,
|
||||
predicateType: 'https://example.com/predicate'
|
||||
}
|
||||
|
||||
expect(() => predicateFromInputs(inputs)).toThrow(
|
||||
/one of predicate-path or predicate must be provided/i
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when both predicate path and predicate are provided', () => {
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_PREDICATE-PATH'] = 'path/to/predicate'
|
||||
process.env['INPUT_PREDICATE'] = '{}'
|
||||
process.env['INPUT_PREDICATE-TYPE'] = 'https://example.com/predicate'
|
||||
})
|
||||
|
||||
it('throws an error', () => {
|
||||
expect(() => predicateFromInputs()).toThrow(
|
||||
const inputs: PredicateInputs = {
|
||||
predicateType: 'https://example.com/predicate',
|
||||
predicate: '{}',
|
||||
predicatePath: 'path/to/predicate'
|
||||
}
|
||||
|
||||
expect(() => predicateFromInputs(inputs)).toThrow(
|
||||
/only one of predicate-path or predicate may be provided/i
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when specifying a predicate path', () => {
|
||||
let dir = ''
|
||||
const filename = 'subject'
|
||||
const predicateType = 'https://example.com/predicate'
|
||||
const content = '{}'
|
||||
let predicatePath = ''
|
||||
|
||||
beforeEach(async () => {
|
||||
// Set-up temp directory
|
||||
const tmpDir = await fs.realpath(os.tmpdir())
|
||||
dir = await fs.mkdtemp(tmpDir + path.sep)
|
||||
const dir = await fs.mkdtemp(tmpDir + path.sep)
|
||||
|
||||
const filename = 'subject'
|
||||
predicatePath = path.join(dir, filename)
|
||||
|
||||
// Write file to temp directory
|
||||
await fs.writeFile(path.join(dir, filename), content)
|
||||
await fs.writeFile(predicatePath, content)
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
// Clean-up temp directory
|
||||
await fs.rm(dir, { recursive: true })
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_PREDICATE-PATH'] = path.join(dir, filename)
|
||||
process.env['INPUT_PREDICATE-TYPE'] = 'https://example.com/predicate'
|
||||
await fs.rm(path.parse(predicatePath).dir, { recursive: true })
|
||||
})
|
||||
|
||||
it('returns the predicate', () => {
|
||||
expect(predicateFromInputs()).toEqual({
|
||||
type: 'https://example.com/predicate',
|
||||
params: {}
|
||||
const inputs: PredicateInputs = {
|
||||
...blankInputs,
|
||||
predicateType,
|
||||
predicatePath
|
||||
}
|
||||
expect(predicateFromInputs(inputs)).toEqual({
|
||||
type: predicateType,
|
||||
params: JSON.parse(content)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when specifying a predicate value', () => {
|
||||
const predicateType = 'https://example.com/predicate'
|
||||
const content = '{}'
|
||||
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_PREDICATE'] = content
|
||||
process.env['INPUT_PREDICATE-TYPE'] = 'https://example.com/predicate'
|
||||
})
|
||||
|
||||
it('returns the predicate', () => {
|
||||
expect(predicateFromInputs()).toEqual({
|
||||
type: 'https://example.com/predicate',
|
||||
params: {}
|
||||
const inputs: PredicateInputs = {
|
||||
...blankInputs,
|
||||
predicateType,
|
||||
predicate: content
|
||||
}
|
||||
|
||||
expect(predicateFromInputs(inputs)).toEqual({
|
||||
type: predicateType,
|
||||
params: JSON.parse(content)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
+106
-98
@@ -2,47 +2,45 @@ import crypto from 'crypto'
|
||||
import fs from 'fs/promises'
|
||||
import os from 'os'
|
||||
import path from 'path'
|
||||
import { subjectFromInputs } from '../src/subject'
|
||||
import { subjectFromInputs, SubjectInputs } from '../src/subject'
|
||||
|
||||
describe('subjectFromInputs', () => {
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_PUSH-TO-REGISTRY'] = 'false'
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
process.env['INPUT_SUBJECT-PATH'] = ''
|
||||
process.env['INPUT_SUBJECT-DIGEST'] = ''
|
||||
process.env['INPUT_SUBJECT-NAME'] = ''
|
||||
})
|
||||
const blankInputs: SubjectInputs = {
|
||||
subjectPath: '',
|
||||
subjectName: '',
|
||||
subjectDigest: ''
|
||||
}
|
||||
|
||||
describe('when no inputs are provided', () => {
|
||||
it('throws an error', async () => {
|
||||
await expect(subjectFromInputs()).rejects.toThrow(
|
||||
await expect(subjectFromInputs(blankInputs)).rejects.toThrow(
|
||||
/one of subject-path or subject-digest must be provided/i
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when both subject path and subject digest are provided', () => {
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_SUBJECT-PATH'] = 'path/to/subject'
|
||||
process.env['INPUT_SUBJECT-DIGEST'] = 'digest'
|
||||
})
|
||||
|
||||
it('throws an error', async () => {
|
||||
await expect(subjectFromInputs()).rejects.toThrow(
|
||||
const inputs: SubjectInputs = {
|
||||
subjectName: 'foo',
|
||||
subjectPath: 'path/to/subject',
|
||||
subjectDigest: 'digest'
|
||||
}
|
||||
|
||||
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||
/only one of subject-path or subject-digest may be provided/i
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when subject digest is provided but not the name', () => {
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_SUBJECT-DIGEST'] = 'digest'
|
||||
})
|
||||
|
||||
it('throws an error', async () => {
|
||||
await expect(subjectFromInputs()).rejects.toThrow(
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectDigest: 'digest'
|
||||
}
|
||||
|
||||
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||
/subject-name must be provided when using subject-digest/i
|
||||
)
|
||||
})
|
||||
@@ -52,39 +50,42 @@ describe('subjectFromInputs', () => {
|
||||
const name = 'Subject'
|
||||
|
||||
describe('when the digest is malformed', () => {
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_SUBJECT-DIGEST'] = 'digest'
|
||||
process.env['INPUT_SUBJECT-NAME'] = name
|
||||
})
|
||||
|
||||
it('throws an error', async () => {
|
||||
await expect(subjectFromInputs()).rejects.toThrow(
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectDigest: 'digest',
|
||||
subjectName: name
|
||||
}
|
||||
|
||||
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||
/subject-digest must be in the format "sha256:<hex-digest>"/i
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the alogrithm is not supported', () => {
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_SUBJECT-DIGEST'] = 'md5:deadbeef'
|
||||
process.env['INPUT_SUBJECT-NAME'] = name
|
||||
})
|
||||
|
||||
it('throws an error', async () => {
|
||||
await expect(subjectFromInputs()).rejects.toThrow(
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectDigest: 'md5:deadbeef',
|
||||
subjectName: name
|
||||
}
|
||||
|
||||
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||
/subject-digest must be in the format "sha256:<hex-digest>"/i
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the sha256 digest is malformed', () => {
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_SUBJECT-DIGEST'] = 'sha256:deadbeef'
|
||||
process.env['INPUT_SUBJECT-NAME'] = name
|
||||
})
|
||||
|
||||
it('throws an error', async () => {
|
||||
await expect(subjectFromInputs()).rejects.toThrow(
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectDigest: 'sha256:deadbeef',
|
||||
subjectName: name
|
||||
}
|
||||
|
||||
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||
/subject-digest must be in the format "sha256:<hex-digest>"/i
|
||||
)
|
||||
})
|
||||
@@ -95,13 +96,14 @@ describe('subjectFromInputs', () => {
|
||||
const digest =
|
||||
'7d070f6b64d9bcc530fe99cc21eaaa4b3c364e0b2d367d7735671fa202a03b32'
|
||||
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_SUBJECT-DIGEST'] = `${alg}:${digest}`
|
||||
process.env['INPUT_SUBJECT-NAME'] = name
|
||||
})
|
||||
|
||||
it('returns the subject', async () => {
|
||||
const subject = await subjectFromInputs()
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectDigest: `${alg}:${digest}`,
|
||||
subjectName: name
|
||||
}
|
||||
|
||||
const subject = await subjectFromInputs(inputs)
|
||||
|
||||
expect(subject).toBeDefined()
|
||||
expect(subject).toHaveLength(1)
|
||||
@@ -110,20 +112,21 @@ describe('subjectFromInputs', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the push-to-registry is true', () => {
|
||||
describe('when the downcaseName is true', () => {
|
||||
const imageName = 'ghcr.io/FOO/bar'
|
||||
const alg = 'sha256'
|
||||
const digest =
|
||||
'7d070f6b64d9bcc530fe99cc21eaaa4b3c364e0b2d367d7735671fa202a03b32'
|
||||
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_SUBJECT-DIGEST'] = `${alg}:${digest}`
|
||||
process.env['INPUT_SUBJECT-NAME'] = imageName
|
||||
process.env['INPUT_PUSH-TO-REGISTRY'] = 'true'
|
||||
})
|
||||
|
||||
it('returns the subject (with name downcased)', async () => {
|
||||
const subject = await subjectFromInputs()
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectDigest: `${alg}:${digest}`,
|
||||
subjectName: imageName,
|
||||
downcaseName: true
|
||||
}
|
||||
|
||||
const subject = await subjectFromInputs(inputs)
|
||||
|
||||
expect(subject).toBeDefined()
|
||||
expect(subject).toHaveLength(1)
|
||||
@@ -135,12 +138,13 @@ describe('subjectFromInputs', () => {
|
||||
|
||||
describe('when specifying a subject path', () => {
|
||||
describe('when the file does NOT exist', () => {
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_SUBJECT-PATH'] = '/f/a/k/e'
|
||||
})
|
||||
|
||||
it('throws an error', async () => {
|
||||
await expect(subjectFromInputs()).rejects.toThrow(
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectPath: '/f/a/k/e'
|
||||
}
|
||||
|
||||
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||
/could not find subject at path/i
|
||||
)
|
||||
})
|
||||
@@ -178,12 +182,13 @@ describe('subjectFromInputs', () => {
|
||||
})
|
||||
|
||||
describe('when no name is provided', () => {
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_SUBJECT-PATH'] = path.join(dir, filename)
|
||||
})
|
||||
|
||||
it('returns the subject', async () => {
|
||||
const subject = await subjectFromInputs()
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectPath: path.join(dir, filename)
|
||||
}
|
||||
|
||||
const subject = await subjectFromInputs(inputs)
|
||||
|
||||
expect(subject).toBeDefined()
|
||||
expect(subject).toHaveLength(1)
|
||||
@@ -195,13 +200,14 @@ describe('subjectFromInputs', () => {
|
||||
describe('when a name is provided', () => {
|
||||
const name = 'mysubject'
|
||||
|
||||
beforeEach(() => {
|
||||
process.env['INPUT_SUBJECT-PATH'] = path.join(dir, filename)
|
||||
process.env['INPUT_SUBJECT-NAME'] = name
|
||||
})
|
||||
|
||||
it('returns the subject', async () => {
|
||||
const subject = await subjectFromInputs()
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectPath: path.join(dir, filename),
|
||||
subjectName: name
|
||||
}
|
||||
|
||||
const subject = await subjectFromInputs(inputs)
|
||||
|
||||
expect(subject).toBeDefined()
|
||||
expect(subject).toHaveLength(1)
|
||||
@@ -211,12 +217,13 @@ describe('subjectFromInputs', () => {
|
||||
})
|
||||
|
||||
describe('when a file glob is supplied', () => {
|
||||
beforeEach(async () => {
|
||||
process.env['INPUT_SUBJECT-PATH'] = path.join(dir, 'subject-*')
|
||||
})
|
||||
|
||||
it('returns the multiple subjects', async () => {
|
||||
const subjects = await subjectFromInputs()
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectPath: path.join(dir, 'subject-*')
|
||||
}
|
||||
|
||||
const subjects = await subjectFromInputs(inputs)
|
||||
|
||||
expect(subjects).toBeDefined()
|
||||
expect(subjects).toHaveLength(3)
|
||||
@@ -230,12 +237,13 @@ describe('subjectFromInputs', () => {
|
||||
})
|
||||
|
||||
describe('when a file glob is supplied which also matches non-files', () => {
|
||||
beforeEach(async () => {
|
||||
process.env['INPUT_SUBJECT-PATH'] = `${dir}*`
|
||||
})
|
||||
|
||||
it('returns the subjects (excluding non-files)', async () => {
|
||||
const subjects = await subjectFromInputs()
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectPath: `${dir}*`
|
||||
}
|
||||
|
||||
const subjects = await subjectFromInputs(inputs)
|
||||
|
||||
expect(subjects).toBeDefined()
|
||||
expect(subjects).toHaveLength(7)
|
||||
@@ -243,13 +251,13 @@ describe('subjectFromInputs', () => {
|
||||
})
|
||||
|
||||
describe('when a comma-separated list is supplied', () => {
|
||||
beforeEach(async () => {
|
||||
process.env['INPUT_SUBJECT-PATH'] =
|
||||
`${path.join(dir, 'subject-1')},${path.join(dir, 'subject-2')}`
|
||||
})
|
||||
|
||||
it('returns the multiple subjects', async () => {
|
||||
const subjects = await subjectFromInputs()
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectPath: `${path.join(dir, 'subject-1')},${path.join(dir, 'subject-2')}`
|
||||
}
|
||||
|
||||
const subjects = await subjectFromInputs(inputs)
|
||||
|
||||
expect(subjects).toBeDefined()
|
||||
expect(subjects).toHaveLength(2)
|
||||
@@ -266,13 +274,13 @@ describe('subjectFromInputs', () => {
|
||||
})
|
||||
|
||||
describe('when a multi-line list is supplied', () => {
|
||||
beforeEach(async () => {
|
||||
process.env['INPUT_SUBJECT-PATH'] =
|
||||
`${path.join(dir, 'subject-0')}\n${path.join(dir, 'subject-2')}`
|
||||
})
|
||||
|
||||
it('returns the multiple subjects', async () => {
|
||||
const subjects = await subjectFromInputs()
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectPath: `${path.join(dir, 'subject-0')}\n${path.join(dir, 'subject-2')}`
|
||||
}
|
||||
|
||||
const subjects = await subjectFromInputs(inputs)
|
||||
|
||||
expect(subjects).toBeDefined()
|
||||
expect(subjects).toHaveLength(2)
|
||||
@@ -289,13 +297,13 @@ describe('subjectFromInputs', () => {
|
||||
})
|
||||
|
||||
describe('when a multi-line glob list is supplied', () => {
|
||||
beforeEach(async () => {
|
||||
process.env['INPUT_SUBJECT-PATH'] =
|
||||
`${path.join(dir, 'subject-*')}\n ${path.join(dir, 'other-*')} `
|
||||
})
|
||||
|
||||
it('returns the multiple subjects', async () => {
|
||||
const subjects = await subjectFromInputs()
|
||||
const inputs: SubjectInputs = {
|
||||
...blankInputs,
|
||||
subjectPath: `${path.join(dir, 'subject-*')}\n ${path.join(dir, 'other-*')} `
|
||||
}
|
||||
|
||||
const subjects = await subjectFromInputs(inputs)
|
||||
|
||||
expect(subjects).toBeDefined()
|
||||
expect(subjects).toHaveLength(6)
|
||||
|
||||
Reference in New Issue
Block a user