131 lines
4.0 KiB
TypeScript
131 lines
4.0 KiB
TypeScript
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);
|
|
});
|
|
|
|
});
|