Files
publish-immutable-action/__tests__/config.test.ts
T
2024-08-28 12:10:13 +01:00

332 lines
9.8 KiB
TypeScript

import * as core from '@actions/core'
import * as github from '@actions/github'
import * as cfg from '../src/config'
import * as apiClient from '../src/api-client'
let getContainerRegistryURLMock: jest.SpyInstance
let getRepositoryMetadataMock: jest.SpyInstance
let getInputMock: jest.SpyInstance
const ghcrUrl = new URL('https://ghcr.io')
describe('config.resolvePublishActionOptions', () => {
beforeEach(() => {
getContainerRegistryURLMock = jest
.spyOn(apiClient, 'getContainerRegistryURL')
.mockImplementation()
getRepositoryMetadataMock = jest
.spyOn(apiClient, 'getRepositoryMetadata')
.mockImplementation()
getInputMock = jest.spyOn(core, 'getInput').mockImplementation()
configureEventContext()
})
afterEach(() => {
jest.clearAllMocks()
clearEventContext()
})
it('throws an error when the token is not provided', async () => {
getInputMock.mockReturnValueOnce(undefined)
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find GITHUB_TOKEN.'
)
})
it('throws an error when the event is not provided', async () => {
getInputMock.mockReturnValueOnce('token')
github.context.eventName = ''
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find event name.'
)
})
it('throws an error when the ref is not provided', async () => {
getInputMock.mockReturnValueOnce('token')
github.context.ref = ''
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find GITHUB_REF.'
)
})
it('throws an error when the workspaceDir is not provided', async () => {
getInputMock.mockReturnValueOnce('token')
process.env.GITHUB_WORKSPACE = ''
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find GITHUB_WORKSPACE.'
)
})
it('throws an error when the repository is not provided', async () => {
getInputMock.mockReturnValueOnce('token')
github.context.payload.repository = undefined
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find Repository.'
)
})
it('throws an error when the apiBaseUrl is not provided', async () => {
getInputMock.mockReturnValueOnce('token')
github.context.apiUrl = ''
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find GITHUB_API_URL.'
)
})
it('throws an error when the runnerTempDir is not provided', async () => {
getInputMock.mockReturnValueOnce('token')
process.env.RUNNER_TEMP = ''
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find RUNNER_TEMP.'
)
})
it('throws an error when the sha is not provided', async () => {
getInputMock.mockReturnValueOnce('token')
github.context.sha = ''
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find GITHUB_SHA.'
)
})
it('throws an error when the githubServerUrl is not provided', async () => {
getInputMock.mockReturnValueOnce('token')
github.context.serverUrl = ''
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find GITHUB_SERVER_URL.'
)
})
it('throws an error when the repositoryId is not provided', async () => {
getInputMock.mockReturnValueOnce('token')
process.env.GITHUB_REPOSITORY_ID = ''
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find GITHUB_REPOSITORY_ID.'
)
})
it('throws an error when the repositoryOwnerId is not provided', async () => {
getInputMock.mockReturnValueOnce('token')
process.env.GITHUB_REPOSITORY_OWNER_ID = ''
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find GITHUB_REPOSITORY_OWNER_ID.'
)
})
it('throws an error when getting the container registry URL fails', async () => {
getInputMock.mockReturnValueOnce('token')
getContainerRegistryURLMock.mockRejectedValue(
new Error('Failed to get container registry URL')
)
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Failed to get container registry URL'
)
})
it('throws an error when getting the repository metadata fails', async () => {
getInputMock.mockReturnValueOnce('token')
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
getRepositoryMetadataMock.mockRejectedValue(
new Error('Failed to get repository metadata')
)
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Failed to get repository metadata'
)
})
it('throws an error when returned repository visibility is empty', async () => {
getInputMock.mockReturnValueOnce('token')
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
getRepositoryMetadataMock.mockResolvedValue({
visibility: ''
})
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Could not find repository visibility.'
)
})
it('throws an error when returned repository id does not match env var', async () => {
getInputMock.mockReturnValueOnce('token')
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
getRepositoryMetadataMock.mockResolvedValue({
visibility: 'public',
ownerId: '12345',
repoId: '54321'
})
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Repository ID mismatch.'
)
})
it('throws an error when returned repository owner id does not match env var', async () => {
getInputMock.mockReturnValueOnce('token')
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
getRepositoryMetadataMock.mockResolvedValue({
visibility: 'public',
ownerId: '123124',
repoId: 'repositoryId'
})
await expect(cfg.resolvePublishActionOptions()).rejects.toThrow(
'Repository Owner ID mismatch.'
)
})
it('returns options when all values are present', async () => {
getInputMock.mockImplementation((name: string) => {
expect(name).toBe('github-token')
return 'token'
})
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
getRepositoryMetadataMock.mockResolvedValue({
visibility: 'public',
repoId: 'repositoryId',
ownerId: 'repositoryOwnerId'
})
const options = await cfg.resolvePublishActionOptions()
expect(options).toEqual({
nameWithOwner: 'nameWithOwner',
ref: 'ref',
workspaceDir: 'workspaceDir',
event: 'release',
apiBaseUrl: 'apiBaseUrl',
runnerTempDir: 'runnerTempDir',
sha: 'sha',
repositoryVisibility: 'public',
repositoryId: 'repositoryId',
repositoryOwnerId: 'repositoryOwnerId',
isEnterprise: false,
containerRegistryUrl: ghcrUrl,
token: 'token'
})
})
it('sets enterprise to true when the server URL is not github.com or ghe.com', async () => {
getInputMock.mockImplementation((name: string) => {
expect(name).toBe('github-token')
return 'token'
})
getContainerRegistryURLMock.mockResolvedValue(ghcrUrl)
getRepositoryMetadataMock.mockResolvedValue({
visibility: 'public',
repoId: 'repositoryId',
ownerId: 'repositoryOwnerId'
})
github.context.serverUrl = 'https://github-enterprise.com'
const options = await cfg.resolvePublishActionOptions()
expect(options).toEqual({
nameWithOwner: 'nameWithOwner',
ref: 'ref',
workspaceDir: 'workspaceDir',
event: 'release',
apiBaseUrl: 'apiBaseUrl',
runnerTempDir: 'runnerTempDir',
sha: 'sha',
repositoryId: 'repositoryId',
repositoryOwnerId: 'repositoryOwnerId',
isEnterprise: true,
containerRegistryUrl: ghcrUrl,
token: 'token',
repositoryVisibility: 'public'
})
})
})
describe('config.serializeOptions', () => {
it('serializes the options, ignoring internal keys', () => {
const options: cfg.PublishActionOptions = {
nameWithOwner: 'nameWithOwner',
ref: 'ref',
workspaceDir: 'workspaceDir',
event: 'release',
apiBaseUrl: 'apiBaseUrl',
runnerTempDir: 'runnerTempDir',
sha: 'sha',
repositoryId: 'repositoryId',
repositoryOwnerId: 'repositoryOwnerId',
isEnterprise: false,
containerRegistryUrl: ghcrUrl,
token: 'token',
repositoryVisibility: 'public'
}
const serialized = cfg.serializeOptions(options)
// Parse the JSON
const parsed = JSON.parse(serialized)
expect(parsed.nameWithOwner).toBe('nameWithOwner')
expect(parsed.ref).toBe('ref')
expect(parsed.workspaceDir).toBe('workspaceDir')
expect(parsed.event).toBe('release')
expect(parsed.apiBaseUrl).toBe('apiBaseUrl')
expect(parsed.sha).toBe('sha')
expect(parsed.isEnterprise).toBe(false)
expect(parsed.containerRegistryUrl).toBe(ghcrUrl.toString())
expect(parsed.token).toBeUndefined()
expect(parsed.repositoryId).toBeUndefined()
expect(parsed.repositoryOwnerId).toBeUndefined()
expect(parsed.runnerTempDir).toBeUndefined()
})
})
function configureEventContext(): void {
github.context.ref = 'ref'
github.context.eventName = 'release'
github.context.apiUrl = 'apiBaseUrl'
github.context.sha = 'sha'
github.context.serverUrl = 'https://github.com/'
github.context.payload = {
repository: {
full_name: 'nameWithOwner',
name: 'name',
owner: {
login: 'owner'
}
}
}
process.env.RUNNER_TEMP = 'runnerTempDir'
process.env.GITHUB_WORKSPACE = 'workspaceDir'
process.env.GITHUB_REPOSITORY_ID = 'repositoryId'
process.env.GITHUB_REPOSITORY_OWNER_ID = 'repositoryOwnerId'
}
function clearEventContext(): void {
github.context.ref = ''
github.context.eventName = ''
github.context.apiUrl = ''
github.context.sha = ''
github.context.serverUrl = ''
github.context.payload = {}
process.env.RUNNER_TEMP = ''
process.env.GITHUB_WORKSPACE = ''
process.env.GITHUB_REPOSITORY_ID = ''
process.env.GITHUB_REPOSITORY_OWNER_ID = ''
}