Files
orca/config/scripts/sign-mac-app.test.mjs
T

119 lines
3.8 KiB
JavaScript

import { createRequire } from 'node:module'
import { resolve } from 'node:path'
import { expect, it } from 'vitest'
import { signMacApp } from './sign-mac-app.mjs'
const require = createRequire(import.meta.url)
const builderRequire = createRequire(require.resolve('electron-builder'))
const appBuilderRequire = createRequire(builderRequire.resolve('app-builder-lib'))
const { resolveFunction } = appBuilderRequire('app-builder-lib/out/util/resolve')
it('preserves file-specific signing policy and retries with fresh options', async () => {
const calls = []
const failure = new Error('timestamp service unavailable')
const options = {
app: '/fixture/Orca.app',
platform: 'darwin',
type: 'distribution',
identity: 'SIGNING_IDENTITY',
identityValidation: false,
keychain: '/fixture/signing.keychain',
binaries: ['/fixture/extra-helper'],
optionsForFile: (path) => ({ entitlements: `${path}.plist`, hardenedRuntime: true }),
ignore: [(path) => path.includes('/orcad-template/')],
preAutoEntitlements: false
}
let policy
const result = await signMacApp(options, {
async retry(task, retryOptions) {
policy = retryOptions
try {
return await task()
} catch (error) {
expect(error).toBe(failure)
return task()
}
},
async sign(received) {
calls.push(received)
if (calls.length === 1) {
throw failure
}
return 'signed'
}
})
expect(result).toBe('signed')
expect(policy).toEqual({ retries: 3, interval: 5000, backoff: 5000 })
expect(calls).toHaveLength(2)
expect(calls[0]).not.toBe(calls[1])
for (const received of calls) {
expect(received).toEqual({ ...options, batchCodesignCalls: true })
expect(received.optionsForFile).toBe(options.optionsForFile)
expect(received.optionsForFile('/fixture/helper')).toEqual({
entitlements: '/fixture/helper.plist',
hardenedRuntime: true
})
expect(received.ignore[0]('/fixture/orcad-template/helper')).toBe(true)
}
expect(options).not.toHaveProperty('batchCodesignCalls')
})
it('propagates signing failure after the retry policy is exhausted', async () => {
const failure = new Error('signature verification failed')
await expect(
signMacApp(
{},
{
retry: (task) => task(),
sign: async () => {
throw failure
}
}
)
).rejects.toBe(failure)
})
it.each([
{ ORCA_MAC_ADHOC: '1' },
{},
{ ORCA_MAC_RELEASE: '1' },
{ ORCA_MAC_HOURLY: '1' },
{ ORCA_MAC_DAILY: '1' },
{ ORCA_WIN_ADHOC: '1' }
])(
'uses batched signing and strict verification for every macOS release channel: %j',
async (env) => {
const configPath = resolve('config/electron-builder.config.cjs')
const saved = { ...process.env }
try {
for (const name of Object.keys(process.env)) {
if (name.startsWith('ORCA_')) {
delete process.env[name]
}
}
Object.assign(process.env, env)
delete require.cache[configPath]
const config = require(configPath)
if (
['ORCA_MAC_ADHOC', 'ORCA_MAC_RELEASE', 'ORCA_MAC_HOURLY', 'ORCA_MAC_DAILY'].some(
(name) => env[name] === '1'
)
) {
expect(config.mac.sign).toBe(resolve('config/scripts/sign-mac-app.mjs'))
const hook = await resolveFunction(undefined, config.mac.sign, 'sign', process.cwd())
expect(typeof hook).toBe('function')
expect(hook.name).toBe('sign')
expect(config.mac.signIgnore).toContain('/orcad-template/')
expect(config.forceCodeSigning).toBe(true)
expect(config.mac.hardenedRuntime).toBe(true)
expect(config.mac.notarize).toBe(true)
} else {
expect(config.mac.sign).toBeUndefined()
}
} finally {
process.env = saved
delete require.cache[configPath]
}
}
)