Add Configuration Actions tab for shell and script action definitions.
Admins can manage built-in and custom actions with placeholders, ENV vars, and actions.create/update/delete permissions.
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import {
|
||||
createAction,
|
||||
deleteAction,
|
||||
deleteGroup,
|
||||
deleteNode,
|
||||
deleteUser,
|
||||
fetchActions,
|
||||
fetchGroups,
|
||||
fetchHealth,
|
||||
fetchNetwork,
|
||||
@@ -11,6 +14,7 @@ import {
|
||||
fetchStatus,
|
||||
fetchUsers,
|
||||
getApiBaseUrl,
|
||||
patchAction,
|
||||
saveNetwork,
|
||||
saveSecurity,
|
||||
upsertGroup,
|
||||
@@ -622,3 +626,93 @@ describe('nodes API', () => {
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('actions API', () => {
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
it('fetches actions', async () => {
|
||||
const fetchMock = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
actions: [
|
||||
{
|
||||
id: 'a1',
|
||||
name: 'Uptime',
|
||||
description: 'uptime',
|
||||
kind: 'shell',
|
||||
body: 'uptime',
|
||||
env: [],
|
||||
builtin: true,
|
||||
created_at: '2026-01-01T00:00:00.000Z',
|
||||
updated_at: '2026-01-01T00:00:00.000Z',
|
||||
},
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
const payload = await fetchActions(fetchMock)
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
'http://localhost:8080/api/v1/actions',
|
||||
expect.objectContaining({ credentials: 'include' }),
|
||||
)
|
||||
expect(payload.actions).toHaveLength(1)
|
||||
expect(payload.actions[0]?.name).toBe('Uptime')
|
||||
})
|
||||
|
||||
it('creates an action', async () => {
|
||||
const fetchMock = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => ({ actions: [] }),
|
||||
})
|
||||
|
||||
await createAction(
|
||||
{
|
||||
name: 'Echo',
|
||||
description: 'echo ip',
|
||||
kind: 'shell',
|
||||
body: 'echo {{node.ip}}',
|
||||
env: [{ name: 'APP_HOME', value: '/opt/app' }],
|
||||
},
|
||||
fetchMock,
|
||||
)
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
'http://localhost:8080/api/v1/actions',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({
|
||||
name: 'Echo',
|
||||
description: 'echo ip',
|
||||
kind: 'shell',
|
||||
body: 'echo {{node.ip}}',
|
||||
env: [{ name: 'APP_HOME', value: '/opt/app' }],
|
||||
}),
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('patches and deletes an action', async () => {
|
||||
const fetchMock = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => ({ actions: [] }),
|
||||
})
|
||||
|
||||
await patchAction('custom-1', { name: 'Renamed', body: 'echo hi' }, fetchMock)
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
'http://localhost:8080/api/v1/actions?id=custom-1',
|
||||
expect.objectContaining({
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ name: 'Renamed', body: 'echo hi' }),
|
||||
}),
|
||||
)
|
||||
|
||||
await deleteAction('custom-1', fetchMock)
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
'http://localhost:8080/api/v1/actions?id=custom-1',
|
||||
expect.objectContaining({ method: 'DELETE' }),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user