5180 fichiers 38.5 Mo 0 téléchargements 482 vues mis à jour il y a 7 heures ui
nitro-v36-with-renderer-v36 / src / components / game-center / views / snowwar / SnowWarArenaHud.test.tsx
SnowWarArenaHud.test.tsx 6 Ko Télécharger le fichier
import { act, cleanup, fireEvent, render } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { SNOWWAR_OBJECT_AVATAR, SNOWWAR_STATE_NORMAL, SnowWarSimulation, tileToWorld } from '../../../../api/snowwar';
import { SnowWarArenaView } from './SnowWarArenaView';

const mocks = vi.hoisted(() => ({ snowWar: null as any }));

vi.mock('../../../../api', async (importOriginal) => ({
    ...(await importOriginal<any>()),
    LocalizeText: (key: string) => key,
    GetConfigurationValue: (_key: string, fallback: any) => fallback,
    GetSessionDataManager: () => ({ userId: 100 })
}));

vi.mock('../../../../common', () => ({
    LayoutAvatarImageView: () => <div />,
    LayoutFurniImageView: () => <div />,
    PIXEL_ART_RENDERING: 'pixelated'
}));

vi.mock('../../../floorplan-editor/FloorplanEditorView', () => ({ FloorplanEditorView: () => null }));
vi.mock('./SnowWarAvatarView', () => ({ SnowWarAvatarView: () => <div /> }));

vi.mock('../../../../hooks', () => ({
    useSnowWar: () => mocks.snowWar,
    useNotification: () => ({ showConfirm: vi.fn() })
}));

const avatar = (overrides: Record<string, number> = {}) => ({
    objectType: SNOWWAR_OBJECT_AVATAR,
    objectId: 1,
    userId: 100,
    teamId: 1,
    name: 'me',
    figure: 'hd-180-1',
    gender: 'M',
    worldX: tileToWorld(2),
    worldY: tileToWorld(2),
    rotation: 0,
    health: 5,
    snowballCount: 5,
    activityTimer: 0,
    activityState: SNOWWAR_STATE_NORMAL,
    score: 0,
    ...overrides
});

const hudImages = (container: HTMLElement) =>
    [ ...container.querySelectorAll('.snowwar-official-hud img, .snowwar-countdown img') ].map(img => img.getAttribute('src') ?? '');

describe('SnowWarArenaView HUD animations (AIR SnowWarUI)', () =>
{
    let simulation: SnowWarSimulation;

    beforeEach(() =>
    {
        vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue(null);
        // Deterministic clock: Date, timers and animation frames all advance by hand.
        vi.useFakeTimers({ toFake: [ 'Date', 'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'requestAnimationFrame', 'cancelAnimationFrame', 'performance' ] });
        simulation = new SnowWarSimulation();
        simulation.setLevel([ 'xxxxx', 'x000x', 'x000x', 'x000x', 'xxxxx' ].map(row => row.replace(/x/g, 'x')), [], []);
        simulation.applyFullStatus([ avatar() ]);
        mocks.snowWar = {
            phase: 'playing',
            levelData: { gameLengthSeconds: 120, canEditRoom: false, arenaName: '', mapId: 1, teamCount: 2, heightmapRows: [ '00000', '00000', '00000', '00000', '00000' ], items: [], machines: [], players: [] },
            secondsLeft: 100,
            preparingSeconds: 0,
            preparingEndsAt: 0,
            chatMessages: [],
            simulation,
            editing: false,
            walkTo: vi.fn(), throwAtLocation: vi.fn(), throwAtPlayer: vi.fn(), createSnowball: vi.fn(), exitGame: vi.fn(),
            startEditing: vi.fn(), saveArena: vi.fn(), stopEditing: vi.fn(), sendChat: vi.fn(), requestFullStatus: vi.fn()
        };
    });

    afterEach(() =>
    {
        cleanup();
        vi.restoreAllMocks();
        vi.useRealTimers();
    });

    it('uses the bundled HUD bitmaps', () =>
    {
        const { container } = render(<SnowWarArenaView />);

        const images = hudImages(container);
        expect(images.some(src => src.includes('ui_me_health_5'))).toBe(true);
        expect(images.every(src => !src.includes('snowstorm_client/official'))).toBe(true);
    });

    it('flashes the empty-ammo warning with no snowballs', () =>
    {
        simulation.avatars.get(1).snowballCount = 0;
        const { container } = render(<SnowWarArenaView />);

        expect(hudImages(container).some(src => src.includes('ui_no_balls_'))).toBe(true);
    });

    it('flashes minus when hit and plus when scoring', async () =>
    {
        const { container, rerender } = render(<SnowWarArenaView />);

        simulation.avatars.get(1).health = 4;
        await act(async () =>
        {
            rerender(<SnowWarArenaView />);
            vi.advanceTimersByTime(5);
        });
        // frameNow advances on animation frames; the flash frame shows within 200 ms of the hit.
        await act(async () => { vi.advanceTimersByTime(40); });
        expect(hudImages(container).some(src => src.includes('ui_me_minus_'))).toBe(true);

        // Let the minus flash run out (200 ms), then score.
        await act(async () => { vi.advanceTimersByTime(250); });
        simulation.avatars.get(1).score = 1;
        await act(async () => { rerender(<SnowWarArenaView />); });
        await act(async () => { vi.advanceTimersByTime(60); });
        expect(hudImages(container).some(src => src.includes('ui_me_plus_'))).toBe(true);
    });

    it('shows the AIR counter digits in the last preparing seconds', async () =>
    {
        mocks.snowWar.phase = 'preparing';
        mocks.snowWar.preparingEndsAt = Date.now() + 2_500;
        const { container } = render(<SnowWarArenaView />);
        await act(async () => { vi.advanceTimersByTime(40); });

        expect(hudImages(container).some(src => src.includes('explosion0003'))).toBe(true);
    });

    it('focuses the chat bar on Enter, leaves movement keys alone and sends on Enter', () =>
    {
        const { container } = render(<SnowWarArenaView />);
        const input = container.querySelector('.snowwar-chat-input input') as HTMLInputElement;

        fireEvent.keyDown(window, { key: 'q', code: 'KeyQ' });
        expect(document.activeElement).not.toBe(input);

        fireEvent.keyDown(window, { key: 'Enter', code: 'Enter' });
        expect(document.activeElement).toBe(input);

        fireEvent.change(input, { target: { value: 'hoi' } });
        fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });
        expect(mocks.snowWar.sendChat).toHaveBeenCalledWith('hoi');

        fireEvent.keyDown(input, { key: 'Escape', code: 'Escape' });
        expect(document.activeElement).not.toBe(input);
    });
});
15Sujets
1Dépôts
20Membres
3En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser