import { describe, expect, test } from 'vitest'; import { BARK_BATTLE_DIFFICULTY_PRESETS, type BarkBattleDraftConfig, type BarkBattleFinishResponse, type BarkBattlePersonalBestSummary, type BarkBattleWorkStats, } from './barkBattle'; describe('Bark Battle shared contracts', () => { test('default draft config fixture uses normal difficulty and camelCase fields', () => { const draft: BarkBattleDraftConfig = { draftId: 'draft-bark-1', title: '汪汪声浪挑战', description: '轻配置草稿', themePreset: 'city-park', playerDogSkinPreset: 'corgi', opponentDogSkinPreset: 'husky', difficultyPreset: 'normal', leaderboardEnabled: true, updatedAt: '2026-05-13T03:00:00.000Z', }; expect(BARK_BATTLE_DIFFICULTY_PRESETS).toEqual(['easy', 'normal', 'hard']); expect(draft.difficultyPreset).toBe('normal'); expect(Object.keys(draft)).toEqual([ 'draftId', 'title', 'description', 'themePreset', 'playerDogSkinPreset', 'opponentDogSkinPreset', 'difficultyPreset', 'leaderboardEnabled', 'updatedAt', ]); }); test('finish accepted player_win fixture exposes backend adjudication result', () => { const response: BarkBattleFinishResponse = { status: 'accepted', runId: 'run-bark-1', workId: 'work-bark-1', configVersion: 3, rulesetVersion: 'bark-battle-ruleset-v1', difficultyPreset: 'hard', serverResult: 'player_win', scoreSummary: { finalEnergy: 87, triggerCount: 42, maxVolume: 0.96, averageVolume: 0.61, comboMax: 9, durationMs: 30000, }, leaderboardScore: 870429630, antiCheatFlags: [], updatedAt: '2026-05-13T03:00:30.000Z', }; expect(response.status).toBe('accepted'); expect(response.serverResult).toBe('player_win'); expect(response.scoreSummary.finalEnergy).toBe(87); expect(response.antiCheatFlags).toEqual([]); }); test('work stats fixture tracks starts, finishes, result counts, flags and energy summary', () => { const stats: BarkBattleWorkStats = { workId: 'work-bark-1', configVersion: 3, rulesetVersion: 'bark-battle-ruleset-v1', difficultyPreset: 'normal', playStartCount: 18, finishCount: 15, winCount: 8, drawCount: 2, lossCount: 5, flaggedCount: 1, leaderboardEntryCount: 7, bestLeaderboardScore: 930389410, bestFinalEnergy: 93, averageFinalEnergy: 41.25, updatedAt: '2026-05-13T04:00:00.000Z', }; expect(stats.playStartCount).toBe(18); expect(stats.finishCount).toBe(15); expect(stats.winCount + stats.drawCount + stats.lossCount).toBe(15); expect(stats.flaggedCount).toBe(1); expect(stats.bestFinalEnergy).toBeGreaterThan(stats.averageFinalEnergy); }); test('optional score fields may be omitted instead of serialized as null', () => { const finishWithoutLeaderboard: BarkBattleFinishResponse = { status: 'accepted', runId: 'run-bark-no-rank', workId: 'work-bark-1', configVersion: 3, rulesetVersion: 'bark-battle-ruleset-v1', difficultyPreset: 'normal', serverResult: 'draw', scoreSummary: { finalEnergy: 50, triggerCount: 12, maxVolume: 0.7, averageVolume: 0.5, comboMax: 3, durationMs: 30000, }, antiCheatFlags: [], updatedAt: '2026-05-13T03:00:30.000Z', }; const personalBestWithoutWin: BarkBattlePersonalBestSummary = { workId: 'work-bark-1', rulesetVersion: 'bark-battle-ruleset-v1', difficultyPreset: 'normal', winCount: 0, drawCount: 1, lossCount: 2, finishCount: 3, updatedAt: '2026-05-13T04:00:00.000Z', }; expect('leaderboardScore' in finishWithoutLeaderboard).toBe(false); expect('bestLeaderboardScore' in personalBestWithoutWin).toBe(false); expect('bestFinalEnergy' in personalBestWithoutWin).toBe(false); }); });