import { cp, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import { afterEach, describe, expect, it } from 'vitest'; import { SHIPPED_FLEET_ARTIFACT_DISPOSITIONS, validateShippedFleetArtifactDispositions, } from './example-profile-dispositions.js'; const frameworkFleet = resolve( dirname(fileURLToPath(import.meta.url)), '..', '..', 'framework', 'fleet', ); const EXPECTED_DISPOSITIONS = [ 'examples/coding.yaml:v1-fixture', 'examples/general.yaml:v1-fixture', 'examples/hybrid.yaml:v1-fixture', 'examples/local-canary.yaml:v1-fixture', 'examples/minimal.yaml:v1-fixture', 'examples/operator-interaction.yaml:v1-fixture', 'examples/research.yaml:v1-fixture', 'profiles/business.yaml:canonical-profile', 'profiles/marketing.yaml:canonical-profile', 'profiles/personal-assistant.yaml:canonical-profile', 'profiles/research.yaml:canonical-profile', 'profiles/software-delivery.yaml:canonical-profile', 'services/operator-interaction.yaml:canonical-service-policy', ]; const declared = SHIPPED_FLEET_ARTIFACT_DISPOSITIONS.map( ({ path, disposition }): string => `${path}:${disposition}`, ); describe('shipped fleet example/profile/service disposition validation', (): void => { it('enumerates every inventory artifact with an explicit executable disposition', (): void => { expect(declared).toEqual(EXPECTED_DISPOSITIONS); }); it('validates every shipped artifact through its declared v1 or canonical path', async (): Promise => { const results = await validateShippedFleetArtifactDispositions({ frameworkFleet }); expect(results.map(({ path, disposition }): string => `${path}:${disposition}`)).toEqual( EXPECTED_DISPOSITIONS, ); expect(results.filter(({ disposition }): boolean => disposition === 'v1-fixture')).toHaveLength( 7, ); expect( results.filter(({ disposition }): boolean => disposition === 'canonical-profile'), ).toHaveLength(5); expect( results.find(({ path }): boolean => path === 'services/operator-interaction.yaml'), ).toMatchObject({ disposition: 'canonical-service-policy', }); }); let temporaryFleet: string | undefined; afterEach(async (): Promise => { if (temporaryFleet) await rm(temporaryFleet, { recursive: true, force: true }); temporaryFleet = undefined; }); it('fails closed when a shipped artifact lacks a declared disposition', async (): Promise => { temporaryFleet = await mkdtemp(join(tmpdir(), 'mosaic-dispositions-')); await cp(frameworkFleet, temporaryFleet, { recursive: true }); await writeFile(join(temporaryFleet, 'examples', 'undeclared.yaml'), 'version: 1\n'); await expect( validateShippedFleetArtifactDispositions({ frameworkFleet: temporaryFleet }), ).rejects.toThrow(/undeclared shipped fleet artifact.*examples\/undeclared.yaml/i); }); it('rejects a v1 fixture when its explicit version declaration is removed', async (): Promise => { temporaryFleet = await mkdtemp(join(tmpdir(), 'mosaic-dispositions-')); await cp(frameworkFleet, temporaryFleet, { recursive: true }); const fixturePath = join(temporaryFleet, 'examples', 'coding.yaml'); const fixture = await readFile(fixturePath, 'utf8'); await writeFile(fixturePath, fixture.replace(/^version: 1\n/, '')); await expect( validateShippedFleetArtifactDispositions({ frameworkFleet: temporaryFleet }), ).rejects.toThrow(/Fleet roster version must be 1/); }); });