From e9da00b0799dd709ffb18dda07560c460bdf8217 Mon Sep 17 00:00:00 2001 From: Hank McCord Date: Mon, 22 Jan 2024 15:22:33 -0500 Subject: [PATCH] Add Iceberg stager --- src/scripts/main.js | 1 - .../modules/stages/environments/iceberg.ts | 43 +++++++++++++++++++ src/scripts/modules/stages/index.ts | 2 + src/scripts/modules/stages/legacy.js | 26 ----------- .../exemptions/environments/iceberg.spec.ts | 11 ++--- .../stages/environments/iceberg.spec.ts | 27 +++++++++--- 6 files changed, 73 insertions(+), 37 deletions(-) create mode 100644 src/scripts/modules/stages/environments/iceberg.ts diff --git a/src/scripts/main.js b/src/scripts/main.js index 49e4ad5b..695f0723 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1180,7 +1180,6 @@ import * as detailingFuncs from './modules/details/legacy'; "Foreword Farm": stagingFuncs.addForewordFarmStage, "Furoma Rift": stagingFuncs.addFuromaRiftStage, "Gnawnian Express Station": stagingFuncs.addTrainStage, - "Iceberg": stagingFuncs.addIcebergStage, "Seasonal Garden": stagingFuncs.addSeasonalGardenStage, "Sunken City": stagingFuncs.addSunkenCityStage, "Table of Contents": stagingFuncs.addTableOfContentsStage, diff --git a/src/scripts/modules/stages/environments/iceberg.ts b/src/scripts/modules/stages/environments/iceberg.ts new file mode 100644 index 00000000..9c690e1d --- /dev/null +++ b/src/scripts/modules/stages/environments/iceberg.ts @@ -0,0 +1,43 @@ +import {type User} from '@scripts/types/hg'; +import {type IntakeMessage} from '@scripts/types/mhct'; +import {type IStager} from '../stages.types'; + +const ICEBERGE_PHASES = [ 'Treacherous Tunnels', 'Brutal Bulwark', 'Bombing Run', 'The Mad Depths', 'Icewing\'s Lair', 'Hidden Depths', 'The Deep Lair', 'General'] as const; +type IcebergPhase = typeof ICEBERGE_PHASES[number]; + +export class IcebergStager implements IStager { + readonly environment: string = 'Iceberg'; + + readonly phaseToStage: Record = { + 'Treacherous Tunnels': '0-300ft', + 'Brutal Bulwark': '301-600ft', + 'Bombing Run': '601-1600ft', + 'The Mad Depths': '1601-1800ft', + 'Icewing\'s Lair': '1800ft', + 'Hidden Depths': '1801-2000ft', + 'The Deep Lair': '2000ft', + 'General': 'Generals', + }; + + /** + * Report the current distance / obstacle. + * TODO: Stage / hunt details for first & second icewing hunting? + */ + addStage(message: IntakeMessage, userPre: User, userPost: User, journal: unknown): void { + const quest = userPre.quests.QuestIceberg; + + if (!quest) { + throw new Error('QuestIceberg is undefined'); + } + + if (!this.isIcebergPhase(quest.current_phase)) { + throw new Error('Skipping unknown Iceberg stage'); + } + + message.stage = this.phaseToStage[quest.current_phase]; + } + + private isIcebergPhase(value: string): value is IcebergPhase { + return ICEBERGE_PHASES.includes(value as IcebergPhase); + } +} diff --git a/src/scripts/modules/stages/index.ts b/src/scripts/modules/stages/index.ts index 048d78f1..88639985 100644 --- a/src/scripts/modules/stages/index.ts +++ b/src/scripts/modules/stages/index.ts @@ -10,6 +10,7 @@ import {ForbiddenGroveStager} from './environments/forbiddenGrove'; import {FortRoxStager} from './environments/fortRox'; import {FungalCavernStager} from './environments/fungalCavern'; import {HarbourStager} from './environments/harbour'; +import {IcebergStager} from './environments/iceberg'; import {IceFortressStager} from './environments/iceFortress'; import {LabyrinthStager} from './environments/labyrinth'; import {LivingGardenStager} from './environments/livingGarden'; @@ -36,6 +37,7 @@ const stageModules: IStager[] = [ new FortRoxStager(), new FungalCavernStager(), new HarbourStager(), + new IcebergStager(), new IceFortressStager(), new LabyrinthStager(), new LivingGardenStager(), diff --git a/src/scripts/modules/stages/legacy.js b/src/scripts/modules/stages/legacy.js index 5f76b224..11673d3f 100644 --- a/src/scripts/modules/stages/legacy.js +++ b/src/scripts/modules/stages/legacy.js @@ -105,32 +105,6 @@ export function addSeasonalGardenStage(message, user, user_post, hunt) { } } -/** - * Report the current distance / obstacle. - * TODO: Stage / hunt details for first & second icewing hunting? - * @param {import("@scripts/types/mhct").IntakeMessage} message The message to be sent. - * @param {import("@scripts/types/hg").User} user The user state object, when the hunt was invoked (pre-hunt). - * @param {import("@scripts/types/hg").User} user_post The user state object, after the hunt. - * @param {unknown} hunt The journal entry corresponding to the active hunt. - */ -export function addIcebergStage(message, user, user_post, hunt) { - const quest = user.quests.QuestIceberg; - message.stage = (({ - "Treacherous Tunnels": "0-300ft", - "Brutal Bulwark": "301-600ft", - "Bombing Run": "601-1600ft", - "The Mad Depths": "1601-1800ft", - "Icewing's Lair": "1800ft", - "Hidden Depths": "1801-2000ft", - "The Deep Lair": "2000ft", - "General": "Generals", - })[quest.current_phase]); - - if (!message.stage) { - message.location = null; - } -} - /** * Report the zone and depth, if any. * @param {Object } message The message to be sent. diff --git a/tests/scripts/hunt-filter/exemptions/environments/iceberg.spec.ts b/tests/scripts/hunt-filter/exemptions/environments/iceberg.spec.ts index dbb3532e..636cb25f 100644 --- a/tests/scripts/hunt-filter/exemptions/environments/iceberg.spec.ts +++ b/tests/scripts/hunt-filter/exemptions/environments/iceberg.spec.ts @@ -1,5 +1,6 @@ import {IntakeRejectionEngine} from '@scripts/hunt-filter/engine'; -import {addIcebergStage} from '@scripts/modules/stages/legacy'; +import {IcebergStager} from '@scripts/modules/stages/environments/iceberg'; +import {IStager} from '@scripts/modules/stages/stages.types'; import {User} from '@scripts/types/hg'; import {IntakeMessage} from '@scripts/types/mhct'; import {LoggerService} from '@scripts/util/logger'; @@ -7,12 +8,12 @@ import {getDefaultIntakeMessage, getDefaultUser} from '@tests/scripts/hunt-filte describe('Iceberg exemptions', () => { let logger: LoggerService; - let stager: (message: IntakeMessage, pre: User, post: User, journal: unknown) => void; + let stager: IStager; let target: IntakeRejectionEngine; beforeEach(() => { logger = {} as LoggerService; - stager = addIcebergStage; + stager = new IcebergStager(); target = new IntakeRejectionEngine(logger); logger.debug = jest.fn(); @@ -93,8 +94,8 @@ describe('Iceberg exemptions', () => { /** Sets the pre and post message stage based on current pre and post user */ function calculateStage() { - stager(preMessage, preUser, {} as User, {}); - stager(postMessage, postUser, {} as User, {}); + stager.addStage(preMessage, preUser, {} as User, {}); + stager.addStage(postMessage, postUser, {} as User, {}); } }); diff --git a/tests/scripts/modules/stages/environments/iceberg.spec.ts b/tests/scripts/modules/stages/environments/iceberg.spec.ts index 22034a7a..25e63184 100644 --- a/tests/scripts/modules/stages/environments/iceberg.spec.ts +++ b/tests/scripts/modules/stages/environments/iceberg.spec.ts @@ -1,8 +1,13 @@ -import {addIcebergStage} from "@scripts/modules/stages/legacy"; +import {IcebergStager} from "@scripts/modules/stages/environments/iceberg"; import {User} from "@scripts/types/hg"; import {IntakeMessage} from "@scripts/types/mhct"; describe('Iceberg Stages', () => { + it('should be for the "Iceberg" environment', () => { + const stager = new IcebergStager(); + expect(stager.environment).toBe('Iceberg'); + }); + it.each` phase | expected ${'Treacherous Tunnels'} | ${'0-300ft'} @@ -14,6 +19,7 @@ describe('Iceberg Stages', () => { ${'The Deep Lair'} | ${'2000ft'} ${'General'} | ${'Generals'} `('should set stage to $expected when in the $phase phase', ({expected, phase}) => { + const stager = new IcebergStager(); const message = {} as IntakeMessage; const preUser = {quests: {QuestIceberg: { current_phase: phase, @@ -21,12 +27,13 @@ describe('Iceberg Stages', () => { const postUser = {} as User; const journal = {}; - addIcebergStage(message, preUser, postUser, journal); + stager.addStage(message, preUser, postUser, journal); expect(message.stage).toBe(expected); }); - it('should set location to null on unknown phase', () => { + it('should should throw on unknown phase', () => { + const stager = new IcebergStager(); const message = {location: {}} as IntakeMessage; const preUser = {quests: {QuestIceberg: { current_phase: 'Aard\'s Lair', @@ -34,8 +41,18 @@ describe('Iceberg Stages', () => { const postUser = {} as User; const journal = {}; - addIcebergStage(message, preUser, postUser, journal); + expect(() => stager.addStage(message, preUser, postUser, journal)) + .toThrow('Skipping unknown Iceberg stage'); + }); + + it.each([undefined, null])('should throw when QuestIceberg is %p', (state) => { + const stager = new IcebergStager(); + const message = {location: {}} as IntakeMessage; + const preUser = {quests: {QuestIceberg: state}} as User; + const postUser = {} as User; + const journal = {}; - expect(message.location).toBe(null); + expect(() => stager.addStage(message, preUser, postUser, journal)) + .toThrow('QuestIceberg is undefined'); }); });