Files
eden/tests/contracts.test.ts

222 lines
16 KiB
TypeScript

import { describe, expect, test } from 'bun:test';
import {
CAPABILITY_DEFINITIONS,
CAPABILITY_REQUIREMENTS,
ESI_ASSETS_SCOPE,
ESI_STRUCTURES_SCOPE,
ESI_WALLET_SCOPE,
gateCapabilityWithAuthorization,
validateCapabilityScopes,
validateResourceCapabilityScopes,
validateConsentCallback,
validateDatasetJobFence,
validateCompleteReportPins,
validateInventoryCursorUse,
validateInventoryPageResult,
} from '../src/lib/domain/capabilities';
import { absentLocation, afterEndInventoryCursorState, afterEndInventoryResult, ambiguousType, appendDatasetState, authorization, borrowedInventoryCursorLookup, changedQueryInventoryCursorLookup, changedRevisionInventoryCursorLookup, consent, datasetState, inventoryCursor, inventoryCursorLookup, inventoryCursorState, inventoryQuery, inventoryResult, approvedMoneyPolicy, singletonRows, systemListedStationPlaceholder, syntheticResource, systemJob, verifiedNamelessStation, walletResult } from '../fixtures/contracts/t02';
describe('T02 typed contract fixtures', () => {
test('separates snapshot generations from append checkpoints and unknown upstream time', () => {
expect(datasetState.coverage).toEqual({ kind: 'snapshot', generation: 'assets-g7', complete: true });
expect(datasetState.fetchedAt).toBeGreaterThan(0);
expect(datasetState.upstreamEffectiveAt).toBeNull();
expect(appendDatasetState.coverage.kind).toBe('append');
if (appendDatasetState.coverage.kind === 'append') {
expect(appendDatasetState.coverage.checkpoint).toBe('journal-from-90000000000000001');
}
expect(typeof authorization.grantRevision).toBe('number');
expect(typeof authorization.credentialVersion).toBe('number');
});
test('binds consent to one session, capability, scopes and selected resources', () => {
expect(consent.state).toBe('pending');
expect(consent.sessionId).toBe('session-fixture-1');
expect(consent.resourceRequests[0]?.resource.authorizationRevision).toBe(7);
expect(consent.resourceRequests[0]?.requestedScopes).toEqual([ESI_ASSETS_SCOPE]);
});
test('keeps system job authority distinct from user resources', () => {
expect(systemJob.authority).toBe('system');
expect(systemJob.owner).toEqual({ kind: 'system', service: 'reference' });
expect(systemJob.publicationFence.resources).toHaveLength(0);
expect(validateDatasetJobFence(systemJob)).toEqual({ valid: true });
});
test('pins inventory cursors and reports to authorized resources and all matching rows', () => {
expect(inventoryQuery.cursor).toBe(inventoryCursor);
expect(inventoryCursorState.token).toBe(inventoryCursor.token);
expect(inventoryCursorState.status).toBe('active');
expect(inventoryCursorState.position).toEqual({ offset: 0, lastItemId: null });
expect(inventoryQuery.sort.tieBreaker).toBe('item_id');
expect(inventoryQuery.authorizationRevisions['character:90000000000000001']).toBe(7);
expect(inventoryCursorState.pin.callerUserId).toBe('fixture-user-a');
expect(validateInventoryCursorUse(inventoryCursorState, inventoryCursorLookup)).toEqual({ valid: true });
expect(validateInventoryCursorUse(inventoryCursorState, borrowedInventoryCursorLookup)).toEqual({ valid: false, reason: 'caller_mismatch' });
expect(validateInventoryCursorUse(inventoryCursorState, changedQueryInventoryCursorLookup)).toEqual({ valid: false, reason: 'query_mismatch' });
expect(validateInventoryCursorUse(inventoryCursorState, changedRevisionInventoryCursorLookup)).toEqual({ valid: false, reason: 'authorization_mismatch' });
expect(validateInventoryCursorUse(inventoryCursorState, { ...inventoryCursorLookup, selectedResources: [{ ...syntheticResource, principal: { kind: 'character', ownerUserId: 'fixture-user-b', id: syntheticResource.principal.id } }] })).toEqual({ valid: false, reason: 'resource_mismatch' });
expect(validateInventoryCursorUse(inventoryCursorState, { ...inventoryCursorLookup, selectedResources: [syntheticResource, syntheticResource] })).toEqual({ valid: false, reason: 'resource_mismatch' });
expect(validateInventoryCursorUse({ ...inventoryCursorState, position: { offset: -1, lastItemId: null } } as unknown as typeof inventoryCursorState, inventoryCursorLookup)).toEqual({ valid: false, reason: 'malformed_state' });
expect(validateInventoryCursorUse({ ...inventoryCursorState, position: { offset: 1, lastItemId: '01' } }, inventoryCursorLookup)).toEqual({ valid: false, reason: 'malformed_state' });
expect(validateInventoryCursorUse({ ...inventoryCursorState, position: { offset: 1, lastItemId: '1\n' } }, inventoryCursorLookup)).toEqual({ valid: false, reason: 'malformed_state' });
expect(validateInventoryCursorUse({ ...inventoryCursorState, status: 'unexpected' } as unknown as typeof inventoryCursorState, inventoryCursorLookup)).toEqual({ valid: false, reason: 'malformed_state' });
expect(inventoryCursorState.pin.authorizationEpochs['character:90000000000000001']).toBe(1);
expect(inventoryResult.status).toBe('ready');
if (inventoryResult.status === 'ready') {
expect(inventoryResult.summary.scope).toBe('all_matching_rows');
expect(inventoryResult.pageState).toBe('initial');
expect(inventoryResult.provenance.input.snapshotGenerations.assets).toBe('assets-g7');
expect(inventoryResult.provenance.input.referenceVersion).toBe('reference-g1');
expect(validateInventoryPageResult(inventoryResult)).toEqual({ valid: true });
expect(validateInventoryPageResult({ ...inventoryResult, pageState: 'unexpected' } as unknown as typeof inventoryResult)).toEqual({ valid: false, reason: 'invalid_page_state' });
expect(validateInventoryPageResult({ ...inventoryResult, status: 'unexpected' } as unknown as typeof inventoryResult)).toEqual({ valid: false, reason: 'invalid_page_state' });
expect(validateCompleteReportPins(inventoryResult.provenance.input)).toEqual({ valid: true });
expect(validateCompleteReportPins({ ...inventoryResult.provenance.input, selectedResources: [syntheticResource, syntheticResource] })).toEqual({ valid: false, reason: 'duplicate_resource' });
expect(validateCompleteReportPins({ ...inventoryResult.provenance.input, datasetPins: [inventoryResult.provenance.input.datasetPins[0]!, inventoryResult.provenance.input.datasetPins[0]!] })).toEqual({ valid: false, reason: 'duplicate_pin' });
expect(validateCompleteReportPins({ ...inventoryResult.provenance.input, datasetPins: [{ ...inventoryResult.provenance.input.datasetPins[0]!, authorizationRevision: 8 }] })).toEqual({ valid: false, reason: 'revision_mismatch' });
}
});
test('after-end pages keep all-matching summaries and terminate the cursor', () => {
expect(afterEndInventoryResult.status).toBe('ready');
if (afterEndInventoryResult.status === 'ready') {
expect(afterEndInventoryResult.pageState).toBe('after_end');
expect(afterEndInventoryResult.rows).toHaveLength(0);
expect(afterEndInventoryResult.summary.matchingRows).toBe(2);
expect(afterEndInventoryResult.nextCursor).toBeNull();
expect(afterEndInventoryCursorState.status).toBe('exhausted');
expect(afterEndInventoryCursorState.position.lastItemId).toBe('90000000000000042');
expect(validateInventoryPageResult(afterEndInventoryResult)).toEqual({ valid: true });
expect(validateInventoryPageResult({
status: 'ready', rows: [], summary: { matchingRows: 2, matchingQuantity: '0', estimatedValue: null, scope: 'all_matching_rows' },
nextCursor: null, pageState: 'initial', provenance: inventoryResult.provenance!,
} as unknown as Parameters<typeof validateInventoryPageResult>[0])).toEqual({ valid: false, reason: 'empty_page_summary' });
expect(validateInventoryPageResult({ ...afterEndInventoryResult, nextCursor: inventoryCursor } as unknown as typeof afterEndInventoryResult)).toEqual({ valid: false, reason: 'terminal_cursor' });
}
});
test('singleton facts preserve true, false and legacy unknown states', () => {
expect(singletonRows.map((row) => row.isSingleton)).toEqual([true, false, null]);
});
test('station evidence preserves verified, system-listed, and absent states', () => {
expect(verifiedNamelessStation.name).toBeNull();
expect(verifiedNamelessStation.evidence).toBe('verified');
expect(verifiedNamelessStation.sourceVerified).toBe(true);
expect(systemListedStationPlaceholder.evidence).toBe('system_listed');
expect(systemListedStationPlaceholder.sourceVerified).toBe(false);
expect(absentLocation.kind).toBe('unknown');
expect(absentLocation.sourceVerified).toBeNull();
expect(absentLocation.parentId).toBeNull();
});
test('ambiguous entity matches remain explicit instead of selecting by name', () => {
expect(ambiguousType.status).toBe('ambiguous');
if (ambiguousType.status === 'ambiguous') expect(ambiguousType.candidates).toHaveLength(2);
});
test('wallet is a separately labelled component and preserves signed cents', () => {
expect(walletResult.status).toBe('ready');
if (walletResult.status === 'ready') {
expect(walletResult.components[0]?.component).toBe('wallet_balance');
expect(walletResult.components[0]?.amount).toBe('-125');
expect(walletResult.components[0]?.credentialVersion).toBe(2);
expect(walletResult.provenance.input.datasetPins[0]?.dataset).toBe('wallet_balance');
}
});
test('capability metadata is allowlisted and wallet consent is opt-in', () => {
expect(CAPABILITY_REQUIREMENTS.wallet_balance).toEqual(['wallet_balance']);
expect(CAPABILITY_DEFINITIONS.wallet_balance.requiredScopes).toEqual([ESI_WALLET_SCOPE]);
expect(CAPABILITY_DEFINITIONS.inventory_query.requiredScopes).toEqual([ESI_ASSETS_SCOPE]);
expect(CAPABILITY_DEFINITIONS.inventory_locations.requiredScopes).toEqual([ESI_ASSETS_SCOPE, ESI_STRUCTURES_SCOPE]);
expect(validateCapabilityScopes('inventory_locations', [ESI_ASSETS_SCOPE]).missingScopes).toEqual([ESI_STRUCTURES_SCOPE]);
expect(validateCapabilityScopes('inventory_locations', [ESI_ASSETS_SCOPE, ESI_STRUCTURES_SCOPE]).valid).toBe(true);
expect(validateCapabilityScopes('wallet_balance', [ESI_WALLET_SCOPE]).valid).toBe(true);
expect(validateCapabilityScopes('wallet_balance', [ESI_WALLET_SCOPE, ESI_WALLET_SCOPE]).duplicateScopes).toEqual([ESI_WALLET_SCOPE]);
expect(validateCapabilityScopes('wallet_balance', []).missingScopes).toEqual([ESI_WALLET_SCOPE]);
expect(validateCapabilityScopes('wallet_balance', [ESI_WALLET_SCOPE, ESI_ASSETS_SCOPE], [ESI_ASSETS_SCOPE]).preservedScopes).toEqual([ESI_ASSETS_SCOPE]);
expect(validateResourceCapabilityScopes('wallet_balance', consent.resourceRequests[0]!).principal).toEqual(syntheticResource.principal);
expect(validateResourceCapabilityScopes('inventory_query', {
...consent.resourceRequests[0]!,
resource: { ...syntheticResource, requiredScopes: [ESI_WALLET_SCOPE] },
}).missingScopes).toEqual([ESI_WALLET_SCOPE]);
const accepted = {
status: 'accepted',
bindingId: consent.bindingId,
resourceGrants: [{
request: consent.resourceRequests[0]!,
grantedScopes: [ESI_ASSETS_SCOPE],
grantRevision: 7,
credentialVersion: 3,
authorizationEpoch: 1,
}],
} as const;
expect(validateConsentCallback(consent, accepted, 1_700_000_100_000)).toEqual({ valid: true });
expect(validateConsentCallback(consent, { ...accepted, resourceGrants: [{ ...accepted.resourceGrants[0]!, request: { ...accepted.resourceGrants[0]!.request, resource: { ...syntheticResource, principal: { ownerUserId: 'fixture-user-a', id: syntheticResource.principal.id, kind: 'character' } } } }] }, 1_700_000_100_000)).toEqual({ valid: true });
expect(validateConsentCallback(consent, {
...accepted,
resourceGrants: [{ ...accepted.resourceGrants[0]!, request: { ...accepted.resourceGrants[0]!.request, resource: { ...syntheticResource, principal: { kind: 'character', id: '90000000000000002', ownerUserId: 'fixture-user-a' } } } }],
}, 1_700_000_100_000)).toEqual({ valid: false, reason: 'resource_mismatch' });
expect(validateConsentCallback(consent, accepted, consent.expiresAt)).toEqual({ valid: false, reason: 'binding_mismatch' });
expect(validateConsentCallback(consent, { ...accepted, resourceGrants: [{ ...accepted.resourceGrants[0]!, grantRevision: Number.NaN }] }, 1_700_000_100_000)).toEqual({ valid: false, reason: 'revision_mismatch' });
expect(validateCapabilityScopes('wallet_balance', ['unallowlisted.scope']).valid).toBe(false);
expect(gateCapabilityWithAuthorization('wallet_balance', {
userId: 'fixture-user-a', resourceAuthorizations: [], selectedResources: [], datasets: [],
}).status).toBe('requirements_missing');
expect(gateCapabilityWithAuthorization('wallet_balance', {
userId: 'fixture-user-a', resourceAuthorizations: [{
...authorization, principal: { kind: 'corporation', id: '99000000000000001', ownerUserId: 'fixture-user-a' }, grantedScopes: [ESI_WALLET_SCOPE],
}], selectedResources: [{
principal: { kind: 'corporation', id: '99000000000000001', ownerUserId: 'fixture-user-a' },
requiredScopes: [ESI_WALLET_SCOPE], authorizationRevision: 1, authorizationEpoch: 1,
}], datasets: [],
}).status).toBe('requirements_missing');
expect(gateCapabilityWithAuthorization('inventory_query', {
userId: 'fixture-user-a', resourceAuthorizations: [authorization], selectedResources: [
{ principal: { kind: 'character', id: '90000000000000001', ownerUserId: 'fixture-user-a' }, requiredScopes: [ESI_ASSETS_SCOPE], authorizationRevision: 7, authorizationEpoch: 1 },
], datasets: [datasetState, { ...datasetState, principal: { kind: 'system', id: 'reference-public' }, dataset: 'reference_data' }],
}).status).toBe('available');
expect(gateCapabilityWithAuthorization('inventory_query', {
userId: 'fixture-user-a', resourceAuthorizations: [authorization], selectedResources: [syntheticResource], datasets: [
datasetState,
{ ...datasetState, dataset: 'reference_data' },
],
}).status).toBe('requirements_missing');
expect(gateCapabilityWithAuthorization('inventory_query', {
userId: 'fixture-user-a', resourceAuthorizations: [authorization], selectedResources: [syntheticResource], datasets: [
{ ...datasetState, authorizationEpoch: 2 },
{ ...datasetState, principal: { kind: 'system', id: 'reference-public' }, dataset: 'reference_data' },
],
}).status).toBe('requirements_missing');
expect(gateCapabilityWithAuthorization('inventory_query', {
userId: 'fixture-user-a', resourceAuthorizations: [authorization], selectedResources: [
syntheticResource,
{ principal: { kind: 'character', id: '90000000000000002', ownerUserId: 'fixture-user-a' }, requiredScopes: [ESI_ASSETS_SCOPE], authorizationRevision: 7, authorizationEpoch: 1 },
], datasets: [datasetState, { ...datasetState, principal: { kind: 'system', id: 'reference-public' }, dataset: 'reference_data' }],
}).status).toBe('requirements_missing');
expect(gateCapabilityWithAuthorization('inventory_query', {
userId: 'fixture-user-a', resourceAuthorizations: [
authorization,
{ ...authorization, principal: { kind: 'character', id: '90000000000000002', ownerUserId: 'fixture-user-a' }, grantedScopes: [] },
], selectedResources: [
syntheticResource,
{ principal: { kind: 'character', id: '90000000000000002', ownerUserId: 'fixture-user-a' }, requiredScopes: [ESI_ASSETS_SCOPE], authorizationRevision: 7, authorizationEpoch: 1 },
], datasets: [datasetState, { ...datasetState, principal: { kind: 'character', id: '90000000000000002', ownerUserId: 'fixture-user-a' }, dataset: 'assets' }, { ...datasetState, principal: { kind: 'system', id: 'reference-public' }, dataset: 'reference_data' }],
}).status).toBe('requirements_missing');
});
test('approved money policy fixes grammar, bounds and signed rounding', () => {
expect(approvedMoneyPolicy.input).toBe('decimal_text');
expect(approvedMoneyPolicy.rounding).toBe('half_away_from_zero');
expect(approvedMoneyPolicy.grammar).toBe('json_number_ascii_decimal');
expect(approvedMoneyPolicy.maxRawInputCharacters).toBe(8192);
expect(approvedMoneyPolicy.maxCoefficientDigits).toBe(4096);
expect(approvedMoneyPolicy.exponentRange).toEqual([-1000, 1000]);
expect(approvedMoneyPolicy.centsShiftRange).toEqual([-1000, 1000]);
expect(approvedMoneyPolicy.canonicalizeNegativeZero).toBe(true);
expect(authorization.staleAuthority.maximumWindowMs).toBeNull();
});
});