Stage 5: Add Prisma integration and enhance mission management
- Introduced Prisma as a dependency in package.json and updated pnpm-lock.yaml. - Created Prisma module and service for database interactions. - Added initial Prisma schema and migration for user, survivor, mission, and related entities. - Implemented throttling in the API using @nestjs/throttler for rate limiting. - Enhanced mission management logic to utilize Prisma for database transactions. - Updated missions controller and service to handle mission state and participant management. - Added Twitch PubSub service for real-time updates on mission states.
This commit is contained in:
@@ -198,6 +198,69 @@ describe('resolveEncounter', () => {
|
||||
expect(result.logText.length).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
|
||||
// Edge cases: modifier overflow / degenerate inputs
|
||||
it('massive positive perk modifier clamps probability to 1 — never throws', () => {
|
||||
const perk: Perk = {
|
||||
id: '00000000-0000-4000-a000-000000000003',
|
||||
key: 'overpowered',
|
||||
name: '',
|
||||
description: '',
|
||||
tags: [],
|
||||
modifiers: [{ target: 'successChance', type: 'additive', amount: 100 }],
|
||||
};
|
||||
const result = resolveEncounter(
|
||||
makeInput({ encounter: { key: 'gen', baseProbability: 0.5, tags: [] },
|
||||
survivor: { id: '00000000-0000-4000-a000-000000000002', state: 'active',
|
||||
stats: { objectives: 5, survival: 5, altruism: 5 }, perkSlots: [perk], hookCount: 0 } })
|
||||
);
|
||||
expect(result.success).toBe(true); // clamped to 1 → always succeeds
|
||||
});
|
||||
|
||||
it('massive negative perk modifier clamps probability to 0 — never throws', () => {
|
||||
const perk: Perk = {
|
||||
id: '00000000-0000-4000-a000-000000000003',
|
||||
key: 'cursed',
|
||||
name: '',
|
||||
description: '',
|
||||
tags: [],
|
||||
modifiers: [{ target: 'successChance', type: 'additive', amount: -100 }],
|
||||
};
|
||||
const result = resolveEncounter(
|
||||
makeInput({ encounter: { key: 'gen', baseProbability: 0.5, tags: [] },
|
||||
survivor: { id: '00000000-0000-4000-a000-000000000002', state: 'active',
|
||||
stats: { objectives: 5, survival: 5, altruism: 5 }, perkSlots: [perk], hookCount: 0 } })
|
||||
);
|
||||
expect(result.success).toBe(false); // clamped to 0 → always fails
|
||||
});
|
||||
|
||||
it('empty perkSlots array is handled without error', () => {
|
||||
expect(() =>
|
||||
resolveEncounter(makeInput({ survivor: {
|
||||
id: '00000000-0000-4000-a000-000000000002', state: 'active',
|
||||
stats: { objectives: 5, survival: 5, altruism: 5 }, perkSlots: [], hookCount: 0,
|
||||
} }))
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('sacrificed survivor produces no state change on failure', () => {
|
||||
const result = resolveEncounter(makeInput({
|
||||
encounter: { key: 'gen', baseProbability: 0, tags: [] },
|
||||
survivor: { id: '00000000-0000-4000-a000-000000000002', state: 'sacrificed',
|
||||
stats: { objectives: 1, survival: 1, altruism: 1 }, perkSlots: [], hookCount: 2 },
|
||||
}));
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.survivorStateChange).toBeNull();
|
||||
});
|
||||
|
||||
it('idle survivor produces no state change on failure', () => {
|
||||
const result = resolveEncounter(makeInput({
|
||||
encounter: { key: 'gen', baseProbability: 0, tags: [] },
|
||||
survivor: { id: '00000000-0000-4000-a000-000000000002', state: 'idle',
|
||||
stats: { objectives: 1, survival: 1, altruism: 1 }, perkSlots: [], hookCount: 0 },
|
||||
}));
|
||||
expect(result.survivorStateChange).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
// ── Property-based tests ──────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user