import { afterEach, describe, expect, it, vi } from 'vitest'; import { createAgentClaimLink } from '../src/agent-claim.js'; import { DASHBOARD_URL } from '../src/constants.js'; import { deploymentInstructions, DEPLOY_HELP } from '../src/deploy-instructions.js'; import { renderWelcome } from '../src/welcome.js'; vi.mock('../src/agent-auth.js', async (importOriginal) => ({ ...(await importOriginal()), discoverAgentAuth: async () => ({ issuer: 'https://auth.example.com', agent_auth: { claim_endpoint: 'https://auth.example.com/agent/identity/claim' }, }), })); afterEach(() => vi.unstubAllGlobals()); const credentials = { registrationId: 'reg', issuer: 'https://auth.example.com', assertion: 'assertion-secret', claimToken: 'claim-secret', }; const site = { status: 'ready' as const, deploymentId: 'id', subdomain: 'docs', remote: 'https://git.example.com/repo', branch: 'main' as const, expiresAt: '2026-12-01T00:00:00.000Z', }; describe('deploy help and claim handoff', () => { it('uses the actual claim attempt API and returns its human-facing link', async () => { const request = vi.fn().mockResolvedValue( new Response( JSON.stringify({ attempt: { verification_uri: 'https://auth.example.com/verify?token=attempt%2Btoken%26value&other=ignored', }, }) ) ); vi.stubGlobal('fetch', request); expect( await createAgentClaimLink('https://api.example.com', credentials, 'user@example.com') ).toBe(`${DASHBOARD_URL}/agent-claim?token=attempt%2Btoken%26value`); expect(JSON.parse(request.mock.calls[0]?.[1].body)).toEqual({ type: 'service_auth', claim_token: 'claim-secret', login_hint: 'user@example.com', }); }); it('rejects a verification link without an attempt token', async () => { vi.stubGlobal( 'fetch', vi.fn().mockResolvedValue( new Response( JSON.stringify({ attempt: { verification_uri: 'https://auth.example.com/verify' }, }) ) ) ); await expect( createAgentClaimLink('https://api.example.com', credentials, 'user@example.com') ).rejects.toThrow(); }); it('keeps Git operations with the agent and omits identity credentials', () => { const text = deploymentInstructions( { status: 'ready', created: true, site, credentials, write: { remote: site.remote, branch: site.branch, token: 'write-secret', tokenExpiresAt: site.expiresAt, }, }, 'https://app.example.com/claim' ); expect(text).toContain('Do not force-push'); expect(text).toContain('mint claim --code '); expect(text).not.toContain('/auth.md'); expect(text).toContain('docs.json'); expect(text).toContain('https://app.example.com/claim'); expect(text).not.toContain('assertion-secret'); expect(text).not.toContain('claim-secret'); expect(text).not.toContain('write-secret'); }); it('documents the command in root help and explains that it does not push files', () => { expect(renderWelcome({ packageName: 'mint', signedIn: false })).toContain('deploy'); expect(DEPLOY_HELP).toContain('Commit and push the documentation yourself'); expect(DEPLOY_HELP).toContain('--new'); expect(DEPLOY_HELP).toContain('mint claim --code '); expect(renderWelcome({ packageName: 'mint', signedIn: false })).toContain('claim --email'); expect(DEPLOY_HELP).toContain('ask the user for their email'); }); });