diff --git a/apps/api/src/turn-in/turn-in.service.spec.ts b/apps/api/src/turn-in/turn-in.service.spec.ts index 698f7d0..8bf9405 100644 --- a/apps/api/src/turn-in/turn-in.service.spec.ts +++ b/apps/api/src/turn-in/turn-in.service.spec.ts @@ -1,3 +1,4 @@ +import { HttpException } from '@nestjs/common'; import { DataSource, EntityManager, EntityTarget } from 'typeorm'; import { Character } from '../characters/entities/character.entity'; import { CharacterItem } from '../items/entities/character-item.entity'; @@ -168,6 +169,30 @@ async function expectTurnInDomainError(promise: Promise, code: string): expect(error.code).toBe(code); } +/** + * `characterNotFound` is shared from `travel.errors`, so it is not a + * TurnInDomainError. Assert on the wire contract -- code plus status -- + * the way `reputation.service.spec.ts` does for the same shared error. + */ +async function expectHttpErrorWithCode( + promise: Promise, + code: string, + status: number, +): Promise { + let error: unknown; + try { + await promise; + } catch (cause) { + error = cause; + } + expect(error).toBeInstanceOf(HttpException); + if (!(error instanceof HttpException)) { + throw new Error('Expected HttpException'); + } + expect(error.getStatus()).toBe(status); + expect(error.getResponse()).toMatchObject({ code }); +} + describe('TurnInService', () => { describe('turnIn', () => { it('consumes the exact quantity, grants silver and reputation atomically', async () => { @@ -232,6 +257,19 @@ describe('TurnInService', () => { expect(state.characters[0].silver).toBe(10); }); + it('rejects an unknown character, mutating nothing', async () => { + const { service, state } = createService(createState()); + + await expectHttpErrorWithCode( + service.turnIn('unknown-character', 'ash-pelt-border-guard', 1), + 'CHARACTER_NOT_FOUND', + 404, + ); + expect(state.characterItems[0].quantity).toBe(5); + expect(state.characters[0].silver).toBe(10); + expect(state.characterReputation).toHaveLength(0); + }); + it('rejects a disabled turn-in', async () => { const state = createState({ turnIns: [turnInDefinition({ enabled: false })] }); const { service } = createService(state);