diff --git a/eslint.config.mjs b/eslint.config.mjs index 14ff4e1..a2f32be 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -51,7 +51,7 @@ export default tseslint.config( }, ], '@typescript-eslint/no-explicit-any': 'error', - '@typescript-eslint/no-require-imports': 'off', + '@typescript-eslint/no-require-imports': 'error', 'import-x/extensions': [ 'error', 'ignorePackages', @@ -96,23 +96,8 @@ export default tseslint.config( languageOptions: { sourceType: 'commonjs', }, - }, - { - files: ['src/types/vendor.d.ts'], - rules: { - '@typescript-eslint/no-explicit-any': 'off', - }, - }, - { - files: ['tests/**/*.ts'], rules: { - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-unsafe-argument': 'off', - '@typescript-eslint/no-unsafe-assignment': 'off', - '@typescript-eslint/no-unsafe-call': 'off', - '@typescript-eslint/no-unsafe-member-access': 'off', - '@typescript-eslint/no-unsafe-return': 'off', - 'import-x/extensions': 'off', + '@typescript-eslint/no-require-imports': 'off', }, }, { diff --git a/src/reporters/aaci.ts b/src/reporters/aaci.ts index f327d81..4a9bc63 100644 --- a/src/reporters/aaci.ts +++ b/src/reporters/aaci.ts @@ -9,6 +9,7 @@ import type { GameApiPostBody, GameApiResponseBody, } from '../types/game-api' +import type { Reporter } from '../types/reporter' import type { NightBattleEquip } from './utils' interface AACIShip { @@ -40,7 +41,7 @@ type EquipSelectorResult = Array<[Partial?, Partial number[] type AACIModule = typeof aaciModule -export default class AACIReporter extends BaseReporter { +export default class AACIReporter extends BaseReporter implements Reporter { getShipAACIs: GetShipAACIs | null = null constructor() { diff --git a/src/reporters/create-item.ts b/src/reporters/create-item.ts index 44ec617..acae44f 100644 --- a/src/reporters/create-item.ts +++ b/src/reporters/create-item.ts @@ -7,17 +7,21 @@ import type { GameApiPostBody, GameApiResponseBody, } from '../types/game-api' +import type { Reporter } from '../types/reporter' +import { parseInt10 } from '../types/window-state' -type CreateItemPostBody = Pick< +type CreateItemPostBodyKey = keyof Pick< APIReqKousyouCreateitemRequest, 'api_item1' | 'api_item2' | 'api_item3' | 'api_item4' > +type CreateItemPostBody = Record + type CreateItemResponseBody = Pick const isCreateItemPostBody = (postBody: GameApiPostBody): postBody is CreateItemPostBody => - ['api_item1', 'api_item2', 'api_item3', 'api_item4'].every( - (key) => typeof postBody[key] === 'string', + (['api_item1', 'api_item2', 'api_item3', 'api_item4'] as CreateItemPostBodyKey[]).every((key) => + ['number', 'string'].includes(typeof postBody[key]), ) const isCreateItemResponseBody = (body: GameApiResponseBody): body is CreateItemResponseBody => @@ -25,7 +29,7 @@ const isCreateItemResponseBody = (body: GameApiResponseBody): body is CreateItem typeof body === 'object' && Array.isArray((body as Partial).api_get_items) -export default class CreateItemReporter extends BaseReporter { +export default class CreateItemReporter extends BaseReporter implements Reporter { handle( method: GameApiMethod, path: GameApiPath, @@ -47,10 +51,10 @@ export default class CreateItemReporter extends BaseReporter { body.api_get_items.forEach((item) => { void this.report('/api/report/v2/create_item', { items: [ - parseInt(postBody.api_item1), - parseInt(postBody.api_item2), - parseInt(postBody.api_item3), - parseInt(postBody.api_item4), + parseInt10(postBody.api_item1), + parseInt10(postBody.api_item2), + parseInt10(postBody.api_item3), + parseInt10(postBody.api_item4), ], itemId: item.api_slotitem_id, teitokuLv: _teitokuLv, diff --git a/src/reporters/create-ship.ts b/src/reporters/create-ship.ts index 6d70562..c89c83c 100644 --- a/src/reporters/create-ship.ts +++ b/src/reporters/create-ship.ts @@ -7,8 +7,10 @@ import type { GameApiPostBody, GameApiResponseBody, } from '../types/game-api' +import type { Reporter } from '../types/reporter' +import { parseInt10 } from '../types/window-state' -type CreateShipPostBody = Pick< +type CreateShipPostBodyKey = keyof Pick< APIReqKousyouCreateshipRequest, | 'api_highspeed' | 'api_item1' @@ -20,6 +22,8 @@ type CreateShipPostBody = Pick< | 'api_large_flag' > +type CreateShipPostBody = Record + type CreateShipKdock = Pick< APIGetMemberKdockResponse, 'api_created_ship_id' | 'api_item1' | 'api_item2' | 'api_item3' | 'api_item4' | 'api_item5' @@ -35,7 +39,7 @@ interface CreateShipReportPayload { shipId: number } -const createShipPostBodyKeys: Array = [ +const createShipPostBodyKeys: CreateShipPostBodyKey[] = [ 'api_highspeed', 'api_item1', 'api_item2', @@ -47,9 +51,9 @@ const createShipPostBodyKeys: Array = [ ] const isCreateShipPostBody = (postBody: GameApiPostBody): postBody is CreateShipPostBody => - createShipPostBodyKeys.every((key) => typeof postBody[key] === 'string') + createShipPostBodyKeys.every((key) => ['number', 'string'].includes(typeof postBody[key])) -export default class CreateShipReporter extends BaseReporter { +export default class CreateShipReporter extends BaseReporter implements Reporter { creating: boolean kdockId: number info: CreateShipReportPayload | null @@ -74,7 +78,7 @@ export default class CreateShipReporter extends BaseReporter { return } this.creating = true - this.kdockId = parseInt(postBody.api_kdock_id) - 1 + this.kdockId = parseInt10(postBody.api_kdock_id) - 1 const secretaryIdx = _decks[0]?.api_ship[0] const secretary = secretaryIdx == null ? undefined : _ships[secretaryIdx] if (!secretary) { @@ -84,15 +88,15 @@ export default class CreateShipReporter extends BaseReporter { } this.info = { items: [ - parseInt(postBody.api_item1), - parseInt(postBody.api_item2), - parseInt(postBody.api_item3), - parseInt(postBody.api_item4), - parseInt(postBody.api_item5), + parseInt10(postBody.api_item1), + parseInt10(postBody.api_item2), + parseInt10(postBody.api_item3), + parseInt10(postBody.api_item4), + parseInt10(postBody.api_item5), ], kdockId: this.kdockId, - largeFlag: parseInt(postBody.api_large_flag) != 0, - highspeed: parseInt(postBody.api_highspeed), + largeFlag: parseInt10(postBody.api_large_flag) != 0, + highspeed: parseInt10(postBody.api_highspeed), secretary: secretary.api_ship_id, teitokuLv: _teitokuLv, shipId: -1, diff --git a/src/reporters/drop-ship.ts b/src/reporters/drop-ship.ts index b48d09e..edeb0af 100644 --- a/src/reporters/drop-ship.ts +++ b/src/reporters/drop-ship.ts @@ -7,6 +7,7 @@ import type { GameApiPostBody, GameApiResponseBody, } from '../types/game-api' +import type { Reporter } from '../types/reporter' interface EnemyReportSource extends PlaneCountData { api_eParam?: number[][] @@ -111,7 +112,7 @@ const makeEnemyReport = (data: EnemyReportSource = {}) => { } } -export default class DropShipReporter extends BaseReporter { +export default class DropShipReporter extends BaseReporter implements Reporter { mapLv: number[] drop: DropReport | null ownedShipSnapshot: Record | null diff --git a/src/reporters/night-battle-ci.ts b/src/reporters/night-battle-ci.ts index c9ecb72..68075fe 100644 --- a/src/reporters/night-battle-ci.ts +++ b/src/reporters/night-battle-ci.ts @@ -15,6 +15,7 @@ import type { GameApiPostBody, GameApiResponseBody, } from '../types/game-api' +import type { Reporter } from '../types/reporter' interface NightBattleShip { api_kyouka: number[] @@ -47,7 +48,7 @@ interface NightBattleCIBody { type ShipSelectorResult = [Partial?, Partial?] type EquipSelectorResult = Array<[Partial?, Partial?, unknown?]> -export default class NightBattleCIReporter extends BaseReporter { +export default class NightBattleCIReporter extends BaseReporter implements Reporter { processData = (body: NightBattleCIBody, time: number) => { const state = window.getStore() diff --git a/src/reporters/night-contact.ts b/src/reporters/night-contact.ts index 3b7c61e..b45e9d6 100644 --- a/src/reporters/night-contact.ts +++ b/src/reporters/night-contact.ts @@ -7,6 +7,7 @@ import type { GameApiPostBody, GameApiResponseBody, } from '../types/game-api' +import type { Reporter } from '../types/reporter' import { getWindowShip, getWindowSlotItem } from '../types/window-state' import type { WindowShip, WindowSlotItem } from '../types/window-state' @@ -15,7 +16,7 @@ import type { WindowShip, WindowSlotItem } from '../types/window-state' // 2. Only one contactable plane equipped. // 3. Plane level must be equal or larger than 0. // 4. Plane count must larger than 0. -export default class NightContactReportor extends BaseReporter { +export default class NightContactReportor extends BaseReporter implements Reporter { VALID_PLANE_ID: number isValid: boolean | null diff --git a/src/reporters/quest.ts b/src/reporters/quest.ts index 83c0dc2..fe04cf7 100644 --- a/src/reporters/quest.ts +++ b/src/reporters/quest.ts @@ -10,6 +10,7 @@ import type { GameApiPostBody, GameApiResponseBody, } from '../types/game-api' +import type { Reporter } from '../types/reporter' const createHash = _.memoize((text: string) => crypto.createHash('md5').update(text).digest('hex')) @@ -34,7 +35,7 @@ type QuestRewardPostBody = Pick< > & Record<`api_select_no${number}`, string | undefined> -export default class QuestReporter extends BaseReporter { +export default class QuestReporter extends BaseReporter implements Reporter { knownQuests: string[] enabled: boolean quests: QuestWithKey[] diff --git a/src/reporters/remodel-item.ts b/src/reporters/remodel-item.ts index 5374384..3c4ee92 100644 --- a/src/reporters/remodel-item.ts +++ b/src/reporters/remodel-item.ts @@ -8,6 +8,7 @@ import type { GameApiPostBody, GameApiResponseBody, } from '../types/game-api' +import type { Reporter } from '../types/reporter' type RemodelItemDetailPostBody = { api_slot_id: string | number @@ -22,7 +23,7 @@ type RemodelItemSlotBody = Pick ({ }) // Collecting remodel recipes -export default class RemodelRecipeReporter extends BaseReporter { +export default class RemodelRecipeReporter extends BaseReporter implements Reporter { id: number itemId: number itemLevel: number diff --git a/src/reporters/ship-stat.ts b/src/reporters/ship-stat.ts index a7976d0..c27fdac 100644 --- a/src/reporters/ship-stat.ts +++ b/src/reporters/ship-stat.ts @@ -7,6 +7,7 @@ import type { GameApiPostBody, GameApiResponseBody, } from '../types/game-api' +import type { Reporter } from '../types/reporter' type ShipStatShip = Pick< APIShipData, @@ -24,7 +25,7 @@ interface ShipStatResponseBody { api_ship_data?: ShipStatShip[] } -export default class ShipStatReporter extends BaseReporter { +export default class ShipStatReporter extends BaseReporter implements Reporter { handle = ( method: GameApiMethod, path: GameApiPath, diff --git a/src/types/game-api.ts b/src/types/game-api.ts index 7069797..bc0bc9b 100644 --- a/src/types/game-api.ts +++ b/src/types/game-api.ts @@ -1,6 +1,6 @@ export type GameApiMethod = string export type GameApiPath = string -export type GameApiPostBody = Record +export type GameApiPostBody = Record export type GameApiResponseBody = unknown export interface GameResponseEventDetail { diff --git a/src/types/vendor.d.ts b/src/types/vendor.d.ts index c0a86ec..90c51c9 100644 --- a/src/types/vendor.d.ts +++ b/src/types/vendor.d.ts @@ -16,7 +16,7 @@ declare module '@sentry/electron' { } declare module 'electron' { - const electron: any + const electron: unknown export = electron } diff --git a/tests/helpers/reporter-test-harness.ts b/tests/helpers/reporter-test-harness.ts index 45f2c12..0eeb57a 100644 --- a/tests/helpers/reporter-test-harness.ts +++ b/tests/helpers/reporter-test-harness.ts @@ -2,7 +2,7 @@ import { createHash } from 'node:crypto' import Module from 'node:module' import { vi } from 'vitest' import packageMeta from '../../package.json' -import type { WindowSlotItem } from '../../src/types/window-state' +import type { PoiWindowStoreState, WindowShip, WindowSlotItem } from '../../src/types/window-state' import SourceAACIReporter from '../../src/reporters/aaci' import SourceBaseReporter from '../../src/reporters/base' import SourceCreateItemReporter from '../../src/reporters/create-item' @@ -15,8 +15,32 @@ import SourceRemodelItemReporter from '../../src/reporters/remodel-item' import SourceRemodelRecipeReporter from '../../src/reporters/remodel-recipe' import SourceShipStatReporter from '../../src/reporters/ship-stat' +type TestWindowShip = WindowShip & Record +type TestWindowShipOverrides = Partial +type GetShipAACIs = (ship: { api_ship_id?: number }, equips?: unknown) => number[] +type TestStore = Record & { + battle: { _status: { result: { deckHp: number[] } } } + const: { $ships: Record> } + sortie: { sortieMapId: number } +} +type FetchResponseStub = { + ok?: boolean + status?: number + statusText?: string + json?: () => Promise + text?: () => Promise +} + const state = vi.hoisted(() => { - const ship = (overrides: Record = {}): any => ({ + const defaultStore = (): TestStore => ({ + sortie: { sortieMapId: 1 }, + battle: { _status: { result: { deckHp: [] } } }, + const: { $ships: {} }, + }) + + const defaultGetShipAACIs: GetShipAACIs = () => [] + + const ship = (overrides: TestWindowShipOverrides = {}): TestWindowShip => ({ api_ship_id: 100, api_lv: 50, api_cond: 49, @@ -26,13 +50,13 @@ const state = vi.hoisted(() => { }) const selectorState = { - store: {} as any, + store: defaultStore(), ships: new Map(), equips: new Map(), } - const aaciState: { getShipAACIs: any } = { - getShipAACIs: vi.fn(() => [] as number[]), + const aaciState: { getShipAACIs: GetShipAACIs } = { + getShipAACIs: vi.fn(defaultGetShipAACIs), } const momentState = { @@ -41,8 +65,8 @@ const state = vi.hoisted(() => { } const fetchState = { - calls: [] as any[][], - implementation: async (..._args: any[]): Promise => ({ + calls: [] as unknown[][], + implementation: async (..._args: unknown[]): Promise => ({ ok: true, status: 200, statusText: 'OK', @@ -58,9 +82,13 @@ const state = vi.hoisted(() => { } const createWindow = () => - ({ + Object.assign(globalThis, { POI_VERSION: '10.7.0', + LATEST_COMMIT: 'test-commit', + ROOT: '/test/root', + APPDATA_PATH: '/test/appdata', SERVER_HOSTNAME: 'example.invalid', + name: 'test-window', _decks: [{ api_ship: [1, 2] }], _ships: { 1: ship({ api_ship_id: 101, api_lv: 80, api_cond: 53 }), @@ -75,11 +103,15 @@ const state = vi.hoisted(() => { _teitokuLv: 120, _nickName: 'Admiral', _nickNameId: 99, - getStore: () => selectorState.store, - }) as unknown as Window & typeof globalThis + getStore: () => selectorState.store as PoiWindowStoreState, + }) - globalThis.window = createWindow() - ;(globalThis as any).__reporterTestHarnessState = { + Object.defineProperty(globalThis, 'window', { + configurable: true, + writable: true, + value: createWindow(), + }) + globalThis.__reporterTestHarnessState = { aaciState, selectorState, } @@ -96,10 +128,14 @@ const state = vi.hoisted(() => { export const { aaciState, fetchState, momentState, selectorState, sentryState } = state -;(globalThis as unknown as { __REPORTER_VERSION__: string }).__REPORTER_VERSION__ = - packageMeta.version +Object.defineProperty(globalThis, '__REPORTER_VERSION__', { + configurable: true, + writable: true, + value: packageMeta.version, +}) declare global { + var __reporterTestHarnessState: unknown var __reporterTestHarnessPatched: boolean | undefined } @@ -127,7 +163,7 @@ vi.mock('@sentry/electron', () => ({ })) vi.mock('node-fetch', () => ({ - default: async (...args: any[]) => { + default: async (...args: unknown[]) => { fetchState.calls.push(args) return fetchState.implementation(...args) }, @@ -164,7 +200,7 @@ if (!globalThis.__reporterTestHarnessPatched) { globalThis.__reporterTestHarnessPatched = true } -export const ship = (overrides: Record = {}): any => ({ +export const ship = (overrides: TestWindowShipOverrides = {}): TestWindowShip => ({ api_ship_id: 100, api_lv: 50, api_cond: 49, @@ -186,20 +222,24 @@ export const equip = ({ api_houm: houm, }) -export const AACIReporter: any = SourceAACIReporter -export const BaseReporter: any = SourceBaseReporter -export const CreateItemReporter: any = SourceCreateItemReporter -export const CreateShipReporter: any = SourceCreateShipReporter -export const DropShipReporter: any = SourceDropShipReporter -export const NightBattleCIReporter: any = SourceNightBattleCIReporter -export const NightContactReportor: any = SourceNightContactReportor -export const QuestReporter: any = SourceQuestReporter -export const RemodelItemReporter: any = SourceRemodelItemReporter -export const RemodelRecipeReporter: any = SourceRemodelRecipeReporter -export const ShipStatReporter: any = SourceShipStatReporter +export const AACIReporter = SourceAACIReporter +export const BaseReporter = SourceBaseReporter +export const CreateItemReporter = SourceCreateItemReporter +export const CreateShipReporter = SourceCreateShipReporter +export const DropShipReporter = SourceDropShipReporter +export const NightBattleCIReporter = SourceNightBattleCIReporter +export const NightContactReportor = SourceNightContactReportor +export const QuestReporter = SourceQuestReporter +export const RemodelItemReporter = SourceRemodelItemReporter +export const RemodelRecipeReporter = SourceRemodelRecipeReporter +export const ShipStatReporter = SourceShipStatReporter export const resetReporterTestState = () => { - globalThis.window = state.createWindow() + Object.defineProperty(globalThis, 'window', { + configurable: true, + writable: true, + value: state.createWindow(), + }) selectorState.store = { sortie: { sortieMapId: 1 }, battle: { _status: { result: { deckHp: [] } } }, @@ -223,9 +263,10 @@ export const resetReporterTestState = () => { sentryState.tags = [] } -export const attachReportSpy = (reporter: { report: (...args: any[]) => Promise }): any => { - reporter.report = vi.fn(() => Promise.resolve()) - return reporter.report +export const attachReportSpy = (reporter: SourceBaseReporter) => { + const report = vi.fn(() => Promise.resolve()) + reporter.report = report + return report } export const teitokuHash = () => diff --git a/tests/reporters/aaci.test.ts b/tests/reporters/aaci.test.ts index 84ec0c7..8a4a500 100644 --- a/tests/reporters/aaci.test.ts +++ b/tests/reporters/aaci.test.ts @@ -18,10 +18,15 @@ describe('AACIReporter', () => { reporter.getShipAACIs = null const report = attachReportSpy(reporter) - reporter.handle('POST', '/kcsapi/api_req_sortie/battle', { - api_deck_id: 1, - api_kouku: { api_stage2: { api_e_count: 1 } }, - }) + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battle', + { + api_deck_id: 1, + api_kouku: { api_stage2: { api_e_count: 1 } }, + }, + {}, + ) expect(report).not.toHaveBeenCalled() }) @@ -30,18 +35,28 @@ describe('AACIReporter', () => { const reporter = new AACIReporter() const report = attachReportSpy(reporter) - reporter.handle('POST', '/kcsapi/api_req_sortie/battle', { - api_deck_id: 2, - api_kouku: { api_stage2: { api_e_count: 1 } }, - }) + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battle', + { + api_deck_id: 2, + api_kouku: { api_stage2: { api_e_count: 1 } }, + }, + {}, + ) window._decks = [{ api_ship: [1] }] selectorState.ships.set(1, [ship({ api_ship_id: 400 }), {}]) selectorState.equips.set(1, [[equip({ id: 10 }), { api_name: 'gun' }]]) aaciState.getShipAACIs = vi.fn(() => [5]) - reporter.handle('POST', '/kcsapi/api_req_sortie/battle', { - api_deck_id: 1, - api_kouku: { api_stage2: { api_e_count: 0 } }, - }) + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battle', + { + api_deck_id: 1, + api_kouku: { api_stage2: { api_e_count: 0 } }, + }, + {}, + ) expect(report).not.toHaveBeenCalled() }) @@ -70,15 +85,20 @@ describe('AACIReporter', () => { const reporter = new AACIReporter() const report = attachReportSpy(reporter) - reporter.handle('POST', '/kcsapi/api_req_sortie/battle', { - api_deck_id: 1, - api_kouku: { - api_stage2: { - api_e_count: 1, - api_air_fire: { api_idx: 0, api_kind: 5 }, + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battle', + { + api_deck_id: 1, + api_kouku: { + api_stage2: { + api_e_count: 1, + api_air_fire: { api_idx: 0, api_kind: 5 }, + }, }, }, - }) + {}, + ) expect(report).toHaveBeenCalledWith('/api/report/v2/aaci', { poiVersion: '10.7.0', @@ -104,10 +124,15 @@ describe('AACIReporter', () => { const reporter = new AACIReporter() const report = attachReportSpy(reporter) - reporter.handle('POST', '/kcsapi/api_req_sortie/battle', { - api_deck_id: 1, - api_kouku: { api_stage2: { api_e_count: 1 } }, - }) + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battle', + { + api_deck_id: 1, + api_kouku: { api_stage2: { api_e_count: 1 } }, + }, + {}, + ) expect(report).not.toHaveBeenCalled() }) @@ -131,10 +156,15 @@ describe('AACIReporter', () => { const reporter = new AACIReporter() const report = attachReportSpy(reporter) - reporter.handle('POST', '/kcsapi/api_req_sortie/battle', { - api_deck_id: 1, - api_kouku: { api_stage2: { api_e_count: 1 } }, - }) + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battle', + { + api_deck_id: 1, + api_kouku: { api_stage2: { api_e_count: 1 } }, + }, + {}, + ) expect(report).toHaveBeenCalledWith( '/api/report/v2/aaci', diff --git a/tests/reporters/base.test.ts b/tests/reporters/base.test.ts index adb89f0..cc957b9 100644 --- a/tests/reporters/base.test.ts +++ b/tests/reporters/base.test.ts @@ -1,5 +1,5 @@ -import { createRequire } from 'node:module' import { beforeEach, describe, expect, it, vi } from 'vitest' +import packageMeta from '../../package.json' import { BaseReporter, @@ -8,8 +8,6 @@ import { sentryState, } from '../helpers/reporter-test-harness' -const require = createRequire(__filename) -const packageMeta = require('../../package.json') const reporterUserAgent = `Reporter/${packageMeta.version} poi/10.7.0` beforeEach(resetReporterTestState) diff --git a/tests/reporters/create-item.test.ts b/tests/reporters/create-item.test.ts index a57b848..c86b479 100644 --- a/tests/reporters/create-item.test.ts +++ b/tests/reporters/create-item.test.ts @@ -26,7 +26,7 @@ describe('CreateItemReporter', () => { 'POST', '/kcsapi/api_req_kousyou/createitem', { api_get_items: [{ api_slotitem_id: 25 }, { api_slotitem_id: -1 }] }, - { api_item1: '10', api_item2: '20', api_item3: '30', api_item4: '40' }, + { api_item1: 10, api_item2: 20, api_item3: 30, api_item4: 40 }, ) expect(report).toHaveBeenCalledTimes(2) diff --git a/tests/reporters/create-ship.test.ts b/tests/reporters/create-ship.test.ts index 2008647..b2c5d2e 100644 --- a/tests/reporters/create-ship.test.ts +++ b/tests/reporters/create-ship.test.ts @@ -27,30 +27,35 @@ describe('CreateShipReporter', () => { '/kcsapi/api_req_kousyou/createship', {}, { - api_kdock_id: '2', - api_item1: '30', - api_item2: '31', - api_item3: '32', - api_item4: '33', - api_item5: '1', - api_large_flag: '1', - api_highspeed: '0', - }, - ) - reporter.handle('GET', '/kcsapi/api_get_member/kdock', [{}, { api_item1: 999 }], {}) - expect(report).not.toHaveBeenCalled() - - reporter.handle('GET', '/kcsapi/api_get_member/kdock', [ - {}, - { + api_kdock_id: 2, api_item1: 30, api_item2: 31, api_item3: 32, api_item4: 33, api_item5: 1, - api_created_ship_id: 400, + api_large_flag: 1, + api_highspeed: 0, }, - ]) + ) + reporter.handle('GET', '/kcsapi/api_get_member/kdock', [{}, { api_item1: 999 }], {}) + expect(report).not.toHaveBeenCalled() + + reporter.handle( + 'GET', + '/kcsapi/api_get_member/kdock', + [ + {}, + { + api_item1: 30, + api_item2: 31, + api_item3: 32, + api_item4: 33, + api_item5: 1, + api_created_ship_id: 400, + }, + ], + {}, + ) expect(report).toHaveBeenCalledWith('/api/report/v2/create_ship', { items: [30, 31, 32, 33, 1], @@ -136,7 +141,7 @@ describe('CreateShipReporter', () => { } reporter.kdockId = 9 - expect(() => reporter.handle('GET', '/kcsapi/api_get_member/kdock', [])).not.toThrow() + expect(() => reporter.handle('GET', '/kcsapi/api_get_member/kdock', [], {})).not.toThrow() expect(report).not.toHaveBeenCalled() expect(consoleError).toHaveBeenCalledWith('Invalid kdock create ship report data') diff --git a/tests/reporters/drop-ship.test.ts b/tests/reporters/drop-ship.test.ts index a590391..97b4314 100644 --- a/tests/reporters/drop-ship.test.ts +++ b/tests/reporters/drop-ship.test.ts @@ -19,9 +19,14 @@ describe('DropShipReporter', () => { const reporter = new DropShipReporter() const report = attachReportSpy(reporter) - reporter.handle('GET', '/kcsapi/api_get_member/mapinfo', { - api_map_info: [{ api_id: 12, api_eventmap: { api_selected_rank: 3 } }], - }) + reporter.handle( + 'GET', + '/kcsapi/api_get_member/mapinfo', + { + api_map_info: [{ api_id: 12, api_eventmap: { api_selected_rank: 3 } }], + }, + {}, + ) reporter.handle( 'POST', '/kcsapi/api_req_map/select_eventmap_rank', @@ -32,33 +37,48 @@ describe('DropShipReporter', () => { api_rank: '4', }, ) - reporter.handle('POST', '/kcsapi/api_req_map/start', { - api_maparea_id: 1, - api_mapinfo_no: 2, - api_no: 5, - api_event_id: 5, - }) - reporter.handle('POST', '/kcsapi/api_req_sortie/battle', { - api_ship_ke: [0, 900], - api_ship_lv: [0, 1], - api_e_maxhps: [0, 30], - api_eParam: [[0, 0, 0, 0]], - api_eSlot: [[-1, -1, -1, -1]], - api_formation: [1, 4], - api_kouku: { - api_stage1: { api_e_count: 12, api_e_lostcount: 2 }, - api_stage2: { api_e_count: 4 }, + reporter.handle( + 'POST', + '/kcsapi/api_req_map/start', + { + api_maparea_id: 1, + api_mapinfo_no: 2, + api_no: 5, + api_event_id: 5, }, - }) - reporter.handle('POST', '/kcsapi/api_req_sortie/battleresult', { - api_enemy_info: { api_deck_name: 'Enemy Fleet' }, - api_quest_name: 'A Victory', - api_win_rank: 'S', - api_get_base_exp: 120, - api_get_ship: { api_ship_id: 201 }, - api_get_useitem: { api_useitem_id: 301 }, - api_get_eventitem: [{ api_type: 1, api_id: 2, api_value: 3, api_slot_level: 4 }], - }) + {}, + ) + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battle', + { + api_ship_ke: [0, 900], + api_ship_lv: [0, 1], + api_e_maxhps: [0, 30], + api_eParam: [[0, 0, 0, 0]], + api_eSlot: [[-1, -1, -1, -1]], + api_formation: [1, 4], + api_kouku: { + api_stage1: { api_e_count: 12, api_e_lostcount: 2 }, + api_stage2: { api_e_count: 4 }, + }, + }, + {}, + ) + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battleresult', + { + api_enemy_info: { api_deck_name: 'Enemy Fleet' }, + api_quest_name: 'A Victory', + api_win_rank: 'S', + api_get_base_exp: 120, + api_get_ship: { api_ship_id: 201 }, + api_get_useitem: { api_useitem_id: 301 }, + api_get_eventitem: [{ api_type: 1, api_id: 2, api_value: 3, api_slot_level: 4 }], + }, + {}, + ) await Promise.resolve() expect(report).toHaveBeenNthCalledWith(1, '/api/report/v2/select_rank', { @@ -116,25 +136,35 @@ describe('DropShipReporter', () => { const reporter = new DropShipReporter() const report = attachReportSpy(reporter) - reporter.handle('POST', '/kcsapi/api_req_map/start', { - api_maparea_id: 2, - api_mapinfo_no: 3, - api_no: 4, - api_event_id: 1, - api_destruction_battle: { - api_ship_ke: [0, 800], - api_kouku: { - api_stage1: { api_e_count: 3, api_e_lostcount: 1 }, - api_stage2: { api_e_count: 2 }, + reporter.handle( + 'POST', + '/kcsapi/api_req_map/start', + { + api_maparea_id: 2, + api_mapinfo_no: 3, + api_no: 4, + api_event_id: 1, + api_destruction_battle: { + api_ship_ke: [0, 800], + api_kouku: { + api_stage1: { api_e_count: 3, api_e_lostcount: 1 }, + api_stage2: { api_e_count: 2 }, + }, }, }, - }) - reporter.handle('POST', '/kcsapi/api_req_sortie/battleresult', { - api_enemy_info: { api_deck_name: 'No Drop' }, - api_quest_name: '', - api_win_rank: 'A', - api_get_base_exp: 50, - }) + {}, + ) + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battleresult', + { + api_enemy_info: { api_deck_name: 'No Drop' }, + api_quest_name: '', + api_win_rank: 'A', + api_get_base_exp: 50, + }, + {}, + ) await Promise.resolve() expect(report).toHaveBeenNthCalledWith( @@ -165,18 +195,28 @@ describe('DropShipReporter', () => { const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) expect(() => - reporter.handle('POST', '/kcsapi/api_req_sortie/battle', { - api_formation: [1, 4], - api_ship_ke: [0, 900], - }), + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battle', + { + api_formation: [1, 4], + api_ship_ke: [0, 900], + }, + {}, + ), ).not.toThrow() expect(() => - reporter.handle('POST', '/kcsapi/api_req_sortie/battleresult', { - api_enemy_info: { api_deck_name: 'Enemy Fleet' }, - api_get_base_exp: 120, - api_quest_name: 'A Victory', - api_win_rank: 'S', - }), + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battleresult', + { + api_enemy_info: { api_deck_name: 'Enemy Fleet' }, + api_get_base_exp: 120, + api_quest_name: 'A Victory', + api_win_rank: 'S', + }, + {}, + ), ).not.toThrow() expect(report).not.toHaveBeenCalled() diff --git a/tests/reporters/night-battle-ci.test.ts b/tests/reporters/night-battle-ci.test.ts index ca861b6..e2a5582 100644 --- a/tests/reporters/night-battle-ci.test.ts +++ b/tests/reporters/night-battle-ci.test.ts @@ -89,7 +89,24 @@ describe('NightBattleCIReporter', () => { const reporter = new NightBattleCIReporter() const report = attachReportSpy(reporter) - reporter.processData({ api_hougeki: {} }, 123456) + reporter.processData( + { + api_f_maxhps: [], + api_f_nowhps: [], + api_flare_pos: [], + api_hougeki: { + api_at_eflag: [], + api_at_list: [], + api_cl_list: [], + api_damage: [], + api_df_list: [], + api_si_list: [], + api_sp_list: [], + }, + api_ship_ke: [], + }, + 123456, + ) expect(report).not.toHaveBeenCalled() }) diff --git a/tests/reporters/night-contact.test.ts b/tests/reporters/night-contact.test.ts index 2e6d59b..f019e80 100644 --- a/tests/reporters/night-contact.test.ts +++ b/tests/reporters/night-contact.test.ts @@ -22,14 +22,24 @@ describe('NightContactReportor', () => { const reporter = new NightContactReportor() const report = attachReportSpy(reporter) - reporter.handle('POST', '/kcsapi/api_req_sortie/battle', { - api_midnight_flag: 1, - api_kouku: { api_stage1: { api_f_count: 1, api_e_count: 0, api_disp_seiku: 1 } }, - }) - reporter.handle('POST', '/kcsapi/api_req_battle_midnight/battle', { - api_deck_id: 1, - api_touch_plane: [102, -1], - }) + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battle', + { + api_midnight_flag: 1, + api_kouku: { api_stage1: { api_f_count: 1, api_e_count: 0, api_disp_seiku: 1 } }, + }, + {}, + ) + reporter.handle( + 'POST', + '/kcsapi/api_req_battle_midnight/battle', + { + api_deck_id: 1, + api_touch_plane: [102, -1], + }, + {}, + ) expect(report).toHaveBeenCalledWith('/api/report/v2/night_contcat', { fleetType: 0, @@ -52,10 +62,15 @@ describe('NightContactReportor', () => { const reporter = new NightContactReportor() const report = attachReportSpy(reporter) - reporter.handle('POST', '/kcsapi/api_req_battle_midnight/sp_midnight', { - api_deck_id: 1, - api_touch_plane: [-1, -1], - }) + reporter.handle( + 'POST', + '/kcsapi/api_req_battle_midnight/sp_midnight', + { + api_deck_id: 1, + api_touch_plane: [-1, -1], + }, + {}, + ) expect(report).not.toHaveBeenCalled() }) @@ -65,10 +80,15 @@ describe('NightContactReportor', () => { const report = attachReportSpy(reporter) expect(() => - reporter.handle('POST', '/kcsapi/api_req_sortie/battle', { - api_midnight_flag: 1, - api_kouku: {}, - }), + reporter.handle( + 'POST', + '/kcsapi/api_req_sortie/battle', + { + api_midnight_flag: 1, + api_kouku: {}, + }, + {}, + ), ).not.toThrow() expect(reporter.isValid).toBe(false) diff --git a/tests/reporters/quest.test.ts b/tests/reporters/quest.test.ts index 30dc407..6495a95 100644 --- a/tests/reporters/quest.test.ts +++ b/tests/reporters/quest.test.ts @@ -16,17 +16,22 @@ describe('QuestReporter', () => { reporter.knownQuests = [] const report = attachReportSpy(reporter) - reporter.handle('GET', '/kcsapi/api_get_member/questlist', { - api_list: [ - { - api_no: 101, - api_title: 'Sortie', - api_detail: 'Win once', - api_category: 2, - api_type: 3, - }, - ], - }) + reporter.handle( + 'GET', + '/kcsapi/api_get_member/questlist', + { + api_list: [ + { + api_no: 101, + api_title: 'Sortie', + api_detail: 'Win once', + api_category: 2, + api_type: 3, + }, + ], + }, + {}, + ) expect(report).toHaveBeenCalledWith('/api/report/v3/quest', { quests: [ { @@ -75,17 +80,22 @@ describe('QuestReporter', () => { reporter.knownQuests = [knownHash.slice(0, 8)] const report = attachReportSpy(reporter) - reporter.handle('GET', '/kcsapi/api_get_member/questlist', { - api_list: [ - { - api_no: 101, - api_title: 'Sortie', - api_detail: 'Win once', - api_category: 2, - api_type: 3, - }, - ], - }) + reporter.handle( + 'GET', + '/kcsapi/api_get_member/questlist', + { + api_list: [ + { + api_no: 101, + api_title: 'Sortie', + api_detail: 'Win once', + api_category: 2, + api_type: 3, + }, + ], + }, + {}, + ) expect(report).not.toHaveBeenCalled() }) diff --git a/tests/reporters/remodel-recipe.test.ts b/tests/reporters/remodel-recipe.test.ts index b0dcd97..c712495 100644 --- a/tests/reporters/remodel-recipe.test.ts +++ b/tests/reporters/remodel-recipe.test.ts @@ -191,7 +191,7 @@ describe('RemodelRecipeReporter', () => { const reporter = new RemodelRecipeReporter() const report = attachReportSpy(reporter) - reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody) + reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody, {}) reporter.handle('POST', '/kcsapi/api_req_kousyou/remodel_slotlist_detail', detailBody, { api_id: '33', api_slot_id: 501, @@ -251,7 +251,7 @@ describe('RemodelRecipeReporter', () => { api_id: '33', }, ) - reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody) + reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody, {}) reporter.handle('POST', '/kcsapi/api_req_kousyou/remodel_slotlist_detail', detailBody, { api_id: '33', api_slot_id: 501, @@ -294,7 +294,7 @@ describe('RemodelRecipeReporter', () => { const report = attachReportSpy(reporter) const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) - reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody) + reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody, {}) expect(report).not.toHaveBeenCalled() expect(consoleError).toHaveBeenCalledWith('Invalid remodel recipe fleet context') @@ -307,7 +307,7 @@ describe('RemodelRecipeReporter', () => { const report = attachReportSpy(reporter) const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) - reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody) + reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody, {}) reporter.handle( 'POST', '/kcsapi/api_req_kousyou/remodel_slotlist_detail', @@ -332,7 +332,7 @@ describe('RemodelRecipeReporter', () => { const report = attachReportSpy(reporter) const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) - reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody) + reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody, {}) reporter.handle('POST', '/kcsapi/api_req_kousyou/remodel_slotlist_detail', detailBody, { api_id: '33', api_slot_id: 501, @@ -360,7 +360,7 @@ describe('RemodelRecipeReporter', () => { const report = attachReportSpy(reporter) const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) - reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody) + reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody, {}) reporter.handle('POST', '/kcsapi/api_req_kousyou/remodel_slotlist_detail', detailBody, { api_id: '33', api_slot_id: 501, @@ -377,7 +377,7 @@ describe('RemodelRecipeReporter', () => { const report = attachReportSpy(reporter) const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) - reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody) + reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody, {}) reporter.handle('POST', '/kcsapi/api_req_kousyou/remodel_slotlist_detail', detailBody, { api_id: '33', api_slot_id: 501, @@ -408,7 +408,7 @@ describe('RemodelRecipeReporter', () => { const report = attachReportSpy(reporter) const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) - reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody) + reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody, {}) reporter.handle('POST', '/kcsapi/api_req_kousyou/remodel_slotlist_detail', detailBody, { api_id: '33', api_slot_id: 501, @@ -440,7 +440,7 @@ describe('RemodelRecipeReporter', () => { const report = attachReportSpy(reporter) const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) - reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody) + reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody, {}) reporter.handle('POST', '/kcsapi/api_req_kousyou/remodel_slotlist_detail', detailBody, { api_id: '33', api_slot_id: 501, @@ -477,7 +477,7 @@ describe('RemodelRecipeReporter', () => { const reporter = new RemodelRecipeReporter() const report = attachReportSpy(reporter) - reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody) + reporter.handle('GET', '/kcsapi/api_req_kousyou/remodel_slotlist', listBody, {}) reporter.handle( 'POST', '/kcsapi/api_req_kousyou/remodel_slotlist_detail', diff --git a/tests/reporters/ship-stat.test.ts b/tests/reporters/ship-stat.test.ts index da2b3b9..a294fa1 100644 --- a/tests/reporters/ship-stat.test.ts +++ b/tests/reporters/ship-stat.test.ts @@ -13,20 +13,26 @@ describe('ShipStatReporter', () => { const reporter = new ShipStatReporter() const report = attachReportSpy(reporter) - reporter.handle('GET', '/kcsapi/api_get_member/ship3', { - api_ship_data: [ - { - api_ship_id: 600, - api_lv: 77, - api_slot: [-1, -1, -1, -1], - api_slot_ex: -1, - api_kyouka: [0, 0, 0, 0, 0, 0, 9], - api_sakuteki: [50, 80], - api_taisen: [70, 100], - api_kaihi: [60, 90], - }, - ], - }) + reporter.handle( + 'GET', + '/kcsapi/api_get_member/ship3', + { + api_ship_data: [ + { + api_ship_id: 600, + api_lv: 77, + api_slot: [-1, -1, -1, -1], + api_slot_ex: -1, + api_kyouka: [0, 0, 0, 0, 0, 0, 9], + api_sakuteki: [50, 80], + api_taisen: [70, 100], + api_kaihi: [60, 90], + }, + ], + }, + {}, + 0, + ) expect(report).toHaveBeenCalledWith('/api/report/v2/ship_stat', { id: 600, lv: 77, @@ -39,15 +45,21 @@ describe('ShipStatReporter', () => { }) report.mockClear() - reporter.handle('GET', '/kcsapi/api_get_member/ship3', { - api_ship_data: [ - { - api_slot: [10, -1, -1, -1], - api_slot_ex: -1, - api_kyouka: [], - }, - ], - }) + reporter.handle( + 'GET', + '/kcsapi/api_get_member/ship3', + { + api_ship_data: [ + { + api_slot: [10, -1, -1, -1], + api_slot_ex: -1, + api_kyouka: [], + }, + ], + }, + {}, + 0, + ) expect(report).not.toHaveBeenCalled() }) @@ -55,10 +67,16 @@ describe('ShipStatReporter', () => { const reporter = new ShipStatReporter() const report = attachReportSpy(reporter) - reporter.handle('GET', '/kcsapi/api_get_member/ship3', {}) - reporter.handle('GET', '/kcsapi/api_get_member/ship3', { - api_ship_data: [], - }) + reporter.handle('GET', '/kcsapi/api_get_member/ship3', {}, {}, 0) + reporter.handle( + 'GET', + '/kcsapi/api_get_member/ship3', + { + api_ship_data: [], + }, + {}, + 0, + ) expect(report).not.toHaveBeenCalled() }) diff --git a/tsdown.config.ts b/tsdown.config.mjs similarity index 70% rename from tsdown.config.ts rename to tsdown.config.mjs index f3857d0..9087648 100644 --- a/tsdown.config.ts +++ b/tsdown.config.mjs @@ -1,7 +1,9 @@ -const { defineConfig } = require('tsdown') -const packageMeta = require('./package.json') +import { readFileSync } from 'node:fs' +import { defineConfig } from 'tsdown' -module.exports = defineConfig({ +const { version } = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8')) + +export default defineConfig({ entry: { index: 'src/index.ts', }, @@ -9,7 +11,7 @@ module.exports = defineConfig({ outExtensions: () => ({ js: '.js' }), format: ['cjs'], define: { - __REPORTER_VERSION__: JSON.stringify(packageMeta.version), + __REPORTER_VERSION__: JSON.stringify(version), }, deps: { neverBundle: [