76bfdd3e8c
* build(deps-dev): bump prettier from 3.5.3 to 3.6.0 --- updated-dependencies: - dependency-name: prettier dependency-version: 3.6.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> * Fix format --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Peter Evans <[email protected]>
410 lines
12 KiB
TypeScript
410 lines
12 KiB
TypeScript
import {
|
|
Inputs,
|
|
Command,
|
|
SlashCommandPayload,
|
|
commandDefaults,
|
|
getCommandsConfigFromInputs,
|
|
getCommandsConfigFromJson,
|
|
actorHasPermission,
|
|
configIsValid,
|
|
tokeniseCommand,
|
|
getSlashCommandPayload
|
|
} from '../lib/command-helper'
|
|
|
|
describe('command-helper tests', () => {
|
|
test('building config with required inputs only', async () => {
|
|
const commands = ['list', 'of', 'slash', 'commands']
|
|
const inputs: Inputs = {
|
|
token: '',
|
|
reactionToken: '',
|
|
reactions: true,
|
|
commands: commands,
|
|
permission: 'write',
|
|
issueType: 'both',
|
|
allowEdits: false,
|
|
repository: 'peter-evans/slash-command-dispatch',
|
|
eventTypeSuffix: '-command',
|
|
staticArgs: [],
|
|
dispatchType: 'repository',
|
|
config: '',
|
|
configFromFile: ''
|
|
}
|
|
const config = getCommandsConfigFromInputs(inputs)
|
|
expect(config.length).toEqual(4)
|
|
for (var i = 0; i < config.length; i++) {
|
|
expect(config[i].command).toEqual(commands[i])
|
|
expect(config[i].permission).toEqual(commandDefaults.permission)
|
|
expect(config[i].issue_type).toEqual(commandDefaults.issue_type)
|
|
expect(config[i].allow_edits).toEqual(commandDefaults.allow_edits)
|
|
expect(config[i].repository).toEqual(commandDefaults.repository)
|
|
expect(config[i].event_type_suffix).toEqual(
|
|
commandDefaults.event_type_suffix
|
|
)
|
|
expect(config[i].static_args).toEqual(commandDefaults.static_args)
|
|
expect(config[i].dispatch_type).toEqual(commandDefaults.dispatch_type)
|
|
}
|
|
})
|
|
|
|
test('building config with optional inputs', async () => {
|
|
const commands = ['list', 'of', 'slash', 'commands']
|
|
const inputs: Inputs = {
|
|
token: '',
|
|
reactionToken: '',
|
|
reactions: true,
|
|
commands: commands,
|
|
permission: 'admin',
|
|
issueType: 'pull-request',
|
|
allowEdits: true,
|
|
repository: 'owner/repo',
|
|
eventTypeSuffix: '-cmd',
|
|
staticArgs: ['production', 'region=us-east-1'],
|
|
dispatchType: 'workflow',
|
|
config: '',
|
|
configFromFile: ''
|
|
}
|
|
const config = getCommandsConfigFromInputs(inputs)
|
|
expect(config.length).toEqual(4)
|
|
for (var i = 0; i < config.length; i++) {
|
|
expect(config[i].command).toEqual(commands[i])
|
|
expect(config[i].permission).toEqual(inputs.permission)
|
|
expect(config[i].issue_type).toEqual(inputs.issueType)
|
|
expect(config[i].allow_edits).toEqual(inputs.allowEdits)
|
|
expect(config[i].repository).toEqual(inputs.repository)
|
|
expect(config[i].event_type_suffix).toEqual(inputs.eventTypeSuffix)
|
|
expect(config[i].static_args).toEqual(inputs.staticArgs)
|
|
expect(config[i].dispatch_type).toEqual(inputs.dispatchType)
|
|
}
|
|
})
|
|
|
|
test('building config with required JSON only', async () => {
|
|
const json = `[
|
|
{
|
|
"command": "do-stuff"
|
|
},
|
|
{
|
|
"command": "test-all-the-things"
|
|
}
|
|
]`
|
|
const commands = ['do-stuff', 'test-all-the-things']
|
|
const config = getCommandsConfigFromJson(json)
|
|
expect(config.length).toEqual(2)
|
|
for (var i = 0; i < config.length; i++) {
|
|
expect(config[i].command).toEqual(commands[i])
|
|
expect(config[i].permission).toEqual(commandDefaults.permission)
|
|
expect(config[i].issue_type).toEqual(commandDefaults.issue_type)
|
|
expect(config[i].allow_edits).toEqual(commandDefaults.allow_edits)
|
|
expect(config[i].repository).toEqual(commandDefaults.repository)
|
|
expect(config[i].event_type_suffix).toEqual(
|
|
commandDefaults.event_type_suffix
|
|
)
|
|
expect(config[i].static_args).toEqual(commandDefaults.static_args)
|
|
expect(config[i].dispatch_type).toEqual(commandDefaults.dispatch_type)
|
|
}
|
|
})
|
|
|
|
test('building config with optional JSON properties', async () => {
|
|
const json = `[
|
|
{
|
|
"command": "do-stuff",
|
|
"permission": "admin",
|
|
"issue_type": "pull-request",
|
|
"allow_edits": true,
|
|
"repository": "owner/repo",
|
|
"event_type_suffix": "-cmd"
|
|
},
|
|
{
|
|
"command": "test-all-the-things",
|
|
"permission": "read",
|
|
"static_args": [
|
|
"production",
|
|
"region=us-east-1"
|
|
],
|
|
"dispatch_type": "workflow"
|
|
}
|
|
]`
|
|
const commands = ['do-stuff', 'test-all-the-things']
|
|
const config = getCommandsConfigFromJson(json)
|
|
expect(config.length).toEqual(2)
|
|
expect(config[0].command).toEqual(commands[0])
|
|
expect(config[0].permission).toEqual('admin')
|
|
expect(config[0].issue_type).toEqual('pull-request')
|
|
expect(config[0].allow_edits).toBeTruthy()
|
|
expect(config[0].repository).toEqual('owner/repo')
|
|
expect(config[0].event_type_suffix).toEqual('-cmd')
|
|
expect(config[0].static_args).toEqual([])
|
|
expect(config[0].dispatch_type).toEqual('repository')
|
|
expect(config[1].command).toEqual(commands[1])
|
|
expect(config[1].permission).toEqual('read')
|
|
expect(config[1].issue_type).toEqual(commandDefaults.issue_type)
|
|
expect(config[1].static_args).toEqual(['production', 'region=us-east-1'])
|
|
expect(config[1].dispatch_type).toEqual('workflow')
|
|
})
|
|
|
|
test('valid config', async () => {
|
|
const config: Command[] = [
|
|
{
|
|
command: 'test',
|
|
permission: 'write',
|
|
issue_type: 'both',
|
|
allow_edits: false,
|
|
repository: 'peter-evans/slash-command-dispatch',
|
|
event_type_suffix: '-command',
|
|
static_args: [],
|
|
dispatch_type: 'repository'
|
|
}
|
|
]
|
|
expect(configIsValid(config)).toEqual(null)
|
|
})
|
|
|
|
test('invalid permission level in config', async () => {
|
|
const config: Command[] = [
|
|
{
|
|
command: 'test',
|
|
permission: 'test-case-invalid-permission',
|
|
issue_type: 'both',
|
|
allow_edits: false,
|
|
repository: 'peter-evans/slash-command-dispatch',
|
|
event_type_suffix: '-command',
|
|
static_args: [],
|
|
dispatch_type: 'repository'
|
|
}
|
|
]
|
|
expect(configIsValid(config)).toEqual(
|
|
`'test-case-invalid-permission' is not a valid 'permission'.`
|
|
)
|
|
})
|
|
|
|
test('invalid issue type in config', async () => {
|
|
const config: Command[] = [
|
|
{
|
|
command: 'test',
|
|
permission: 'write',
|
|
issue_type: 'test-case-invalid-issue-type',
|
|
allow_edits: false,
|
|
repository: 'peter-evans/slash-command-dispatch',
|
|
event_type_suffix: '-command',
|
|
static_args: [],
|
|
dispatch_type: 'repository'
|
|
}
|
|
]
|
|
expect(configIsValid(config)).toEqual(
|
|
`'test-case-invalid-issue-type' is not a valid 'issue-type'.`
|
|
)
|
|
})
|
|
|
|
test('invalid dispatch type in config', async () => {
|
|
const config: Command[] = [
|
|
{
|
|
command: 'test',
|
|
permission: 'write',
|
|
issue_type: 'both',
|
|
allow_edits: false,
|
|
repository: 'peter-evans/slash-command-dispatch',
|
|
event_type_suffix: '-command',
|
|
static_args: [],
|
|
dispatch_type: 'test-case-invalid-dispatch-type'
|
|
}
|
|
]
|
|
expect(configIsValid(config)).toEqual(
|
|
`'test-case-invalid-dispatch-type' is not a valid 'dispatch-type'.`
|
|
)
|
|
})
|
|
|
|
test('actor does not have permission', async () => {
|
|
expect(actorHasPermission('none', 'read')).toBeFalsy()
|
|
expect(actorHasPermission('read', 'triage')).toBeFalsy()
|
|
expect(actorHasPermission('triage', 'write')).toBeFalsy()
|
|
expect(actorHasPermission('write', 'maintain')).toBeFalsy()
|
|
expect(actorHasPermission('maintain', 'admin')).toBeFalsy()
|
|
})
|
|
|
|
test('actor has permission', async () => {
|
|
expect(actorHasPermission('read', 'none')).toBeTruthy()
|
|
expect(actorHasPermission('triage', 'read')).toBeTruthy()
|
|
expect(actorHasPermission('write', 'triage')).toBeTruthy()
|
|
expect(actorHasPermission('admin', 'write')).toBeTruthy()
|
|
expect(actorHasPermission('write', 'write')).toBeTruthy()
|
|
})
|
|
|
|
test('command arguments are correctly tokenised', async () => {
|
|
const command = `a b=c "d e" f-g="h i" "j \\"k\\"" l="m \\"n\\" o"`
|
|
const commandTokens = [
|
|
`a`,
|
|
`b=c`,
|
|
`"d e"`,
|
|
`f-g="h i"`,
|
|
`"j \\"k\\""`,
|
|
`l="m \\"n\\" o"`
|
|
]
|
|
expect(tokeniseCommand(command)).toEqual(commandTokens)
|
|
})
|
|
|
|
test('tokenisation of malformed command arguments', async () => {
|
|
const command = `test arg named= quoted arg" named-arg="with \\"quoted value`
|
|
const commandTokens = [
|
|
'test',
|
|
'arg',
|
|
'named=',
|
|
'quoted',
|
|
`arg"`,
|
|
`named-arg="with`,
|
|
'\\"quoted',
|
|
'value'
|
|
]
|
|
expect(tokeniseCommand(command)).toEqual(commandTokens)
|
|
})
|
|
|
|
test('slash command payload with unnamed args', async () => {
|
|
const commandTokens = ['test', 'arg1', 'arg2', 'arg3']
|
|
const staticArgs = []
|
|
const payload: SlashCommandPayload = {
|
|
command: 'test',
|
|
args: {
|
|
all: 'arg1 arg2 arg3',
|
|
unnamed: {
|
|
all: 'arg1 arg2 arg3',
|
|
arg1: 'arg1',
|
|
arg2: 'arg2',
|
|
arg3: 'arg3'
|
|
},
|
|
named: {}
|
|
}
|
|
}
|
|
expect(getSlashCommandPayload(commandTokens, staticArgs)).toEqual(payload)
|
|
})
|
|
|
|
test('slash command payload with named args', async () => {
|
|
const commandTokens = [
|
|
'test',
|
|
'branch_name=main',
|
|
'arg1',
|
|
'test-id=123',
|
|
'arg2'
|
|
]
|
|
const staticArgs = []
|
|
const payload: SlashCommandPayload = {
|
|
command: 'test',
|
|
args: {
|
|
all: 'branch_name=main arg1 test-id=123 arg2',
|
|
unnamed: {
|
|
all: 'arg1 arg2',
|
|
arg1: 'arg1',
|
|
arg2: 'arg2'
|
|
},
|
|
named: {
|
|
branch_name: 'main',
|
|
'test-id': '123'
|
|
}
|
|
}
|
|
}
|
|
expect(getSlashCommandPayload(commandTokens, staticArgs)).toEqual(payload)
|
|
})
|
|
|
|
test('slash command payload with named args and static args', async () => {
|
|
const commandTokens = ['test', 'branch=main', 'arg1', 'dry-run']
|
|
const staticArgs = ['production', 'region=us-east-1']
|
|
const payload: SlashCommandPayload = {
|
|
command: 'test',
|
|
args: {
|
|
all: 'production region=us-east-1 branch=main arg1 dry-run',
|
|
unnamed: {
|
|
all: 'production arg1 dry-run',
|
|
arg1: 'production',
|
|
arg2: 'arg1',
|
|
arg3: 'dry-run'
|
|
},
|
|
named: {
|
|
region: 'us-east-1',
|
|
branch: 'main'
|
|
}
|
|
}
|
|
}
|
|
expect(getSlashCommandPayload(commandTokens, staticArgs)).toEqual(payload)
|
|
})
|
|
|
|
test('slash command payload with quoted args', async () => {
|
|
const commandTokens = [
|
|
`test`,
|
|
`a`,
|
|
`b=c`,
|
|
`"d e"`,
|
|
`f-g="h i"`,
|
|
`"j \\"k\\""`,
|
|
`l="m \\"n\\" o"`
|
|
]
|
|
const staticArgs = [`msg="x y z"`]
|
|
const payload: SlashCommandPayload = {
|
|
command: `test`,
|
|
args: {
|
|
all: `msg="x y z" a b=c "d e" f-g="h i" "j \\"k\\"" l="m \\"n\\" o"`,
|
|
unnamed: {
|
|
all: `a "d e" "j \\"k\\""`,
|
|
arg1: `a`,
|
|
arg2: `d e`,
|
|
arg3: `j \\"k\\"`
|
|
},
|
|
named: {
|
|
msg: `x y z`,
|
|
b: `c`,
|
|
'f-g': `h i`,
|
|
l: `m \\"n\\" o`
|
|
}
|
|
}
|
|
}
|
|
expect(getSlashCommandPayload(commandTokens, staticArgs)).toEqual(payload)
|
|
})
|
|
|
|
test('slash command payload with malformed named args', async () => {
|
|
const commandTokens = ['test', 'branch=', 'arg1', 'e.nv=prod', 'arg2']
|
|
const staticArgs = []
|
|
const payload: SlashCommandPayload = {
|
|
command: 'test',
|
|
args: {
|
|
all: 'branch= arg1 e.nv=prod arg2',
|
|
unnamed: {
|
|
all: 'branch= arg1 e.nv=prod arg2',
|
|
arg1: 'branch=',
|
|
arg2: 'arg1',
|
|
arg3: 'e.nv=prod',
|
|
arg4: 'arg2'
|
|
},
|
|
named: {}
|
|
}
|
|
}
|
|
expect(getSlashCommandPayload(commandTokens, staticArgs)).toEqual(payload)
|
|
})
|
|
|
|
test('slash command payload with malformed quoted args', async () => {
|
|
const commandTokens = [
|
|
'test',
|
|
'arg',
|
|
'named=',
|
|
'quoted',
|
|
`arg"`,
|
|
`named-arg="with`,
|
|
`\\"quoted`,
|
|
'value'
|
|
]
|
|
const staticArgs = []
|
|
const payload: SlashCommandPayload = {
|
|
command: 'test',
|
|
args: {
|
|
all: `arg named= quoted arg" named-arg="with \\"quoted value`,
|
|
unnamed: {
|
|
all: `arg named= quoted arg" \\"quoted value`,
|
|
arg1: 'arg',
|
|
arg2: 'named=',
|
|
arg3: 'quoted',
|
|
arg4: `arg"`,
|
|
arg5: `\\"quoted`,
|
|
arg6: 'value'
|
|
},
|
|
named: {
|
|
'named-arg': `"with`
|
|
}
|
|
}
|
|
}
|
|
expect(getSlashCommandPayload(commandTokens, staticArgs)).toEqual(payload)
|
|
})
|
|
})
|