5180 fichiers 38.5 Mo 0 téléchargements 236 vues mis à jour il y a 5 heures ui
nitro-v36-with-renderer-v36 / src / hooks / catalog / specialItemsDisplay.helpers.test.ts
specialItemsDisplay.helpers.test.ts 6.5 Ko Télécharger le fichier
import { describe, expect, it } from 'vitest';
import {
    carouselElementLayout,
    claimButtonFor,
    claimStateAfterAllVisited,
    claimStateAfterResponse,
    initialCarousel,
    initialClaimState,
    initialRotation,
    navigateCarousel,
    nextCarousel,
    parseSpecialItems,
    parseSpecialItemsLink,
    plaqueFor,
    previousCarousel,
    SpecialItemsClaimState,
    specialItemsRotationReducer,
    spotlightBlendFor,
    stepCarousel
} from './specialItemsDisplay.helpers';

const furni: Record<string, { id: number; name: string }> = {
    wf_storage_furni1: { id: 11, name: 'Furni Chest' },
    wf_storage_coins1: { id: 12, name: 'Credit Chest' }
};

const lookup = (className: string) => furni[className] ?? null;

const settle = (count: number, state = initialCarousel(), steps = 2000) => {
    let current = state;

    for (let i = 0; i < steps && current.animating; i++) current = stepCarousel(current, count, 16);

    return current;
};

describe('special items link and configuration', () => {
    it('reads the showcase key from special_items_display/<key>', () => {
        expect(parseSpecialItemsLink('special_items_display/chests')).toBe('chests');
        expect(parseSpecialItemsLink('special_items_display/')).toBe('');
        expect(parseSpecialItemsLink('special_items_display')).toBeNull();
    });

    it('keeps only furni entries the furnidata knows, indexed among the valid ones', () => {
        const items = parseSpecialItems('a,furni,wf_storage_furni1;b,furni,missing;c,badge,wf_storage_coins1;d,furni,wf_storage_coins1;broken', lookup);

        expect(items).toEqual([
            { index: 0, itemKey: 'a', classId: 11, furniName: 'Furni Chest' },
            { index: 1, itemKey: 'd', classId: 12, furniName: 'Credit Chest' }
        ]);
        expect(parseSpecialItems('', lookup)).toEqual([]);
    });
});

describe('free claim states', () => {
    it('fetches only when the showcase names a claim', () => {
        expect(initialClaimState('')).toBe(SpecialItemsClaimState.NOT_APPLICABLE);
        expect(initialClaimState('chests_starter')).toBe(SpecialItemsClaimState.FETCHING);
    });

    it('takes the has-claimed answer for its own claim while fetching', () => {
        expect(claimStateAfterResponse(SpecialItemsClaimState.FETCHING, 'x', 'x', false)).toBe(SpecialItemsClaimState.BROWSING);
        expect(claimStateAfterResponse(SpecialItemsClaimState.FETCHING, 'x', 'x', true)).toBe(SpecialItemsClaimState.CLAIMED);
        expect(claimStateAfterResponse(SpecialItemsClaimState.FETCHING, 'x', 'y', true)).toBe(SpecialItemsClaimState.FETCHING);
        expect(claimStateAfterResponse(SpecialItemsClaimState.CLAIMABLE, 'x', 'x', true)).toBe(SpecialItemsClaimState.CLAIMABLE);
    });

    it('becomes claimable once every item was seen while browsing', () => {
        expect(claimStateAfterAllVisited(SpecialItemsClaimState.BROWSING, 'x')).toBe(SpecialItemsClaimState.CLAIMABLE);
        expect(claimStateAfterAllVisited(SpecialItemsClaimState.FETCHING, 'x')).toBe(SpecialItemsClaimState.FETCHING);
        expect(claimStateAfterAllVisited(SpecialItemsClaimState.BROWSING, '')).toBe(SpecialItemsClaimState.BROWSING);
    });

    it('shows the official claim button per state', () => {
        expect(claimButtonFor(SpecialItemsClaimState.NOT_APPLICABLE).visible).toBe(false);
        expect(claimButtonFor(SpecialItemsClaimState.BROWSING)).toEqual({ visible: true, enabled: false, captionKey: 'special_items.claim' });
        expect(claimButtonFor(SpecialItemsClaimState.CLAIMABLE)).toEqual({ visible: true, enabled: true, captionKey: 'special_items.claim' });
        expect(claimButtonFor(SpecialItemsClaimState.CLAIMED)).toEqual({ visible: true, enabled: false, captionKey: 'special_items.claimed' });
    });
});

describe('carousel', () => {
    it('puts the centred item at the product template spot, fully focused', () => {
        const layout = carouselElementLayout(0, 0, 4);

        expect(layout.x).toBeCloseTo(70);
        expect(layout.y).toBeCloseTo(-40);
        expect(layout.focus).toBe(1);
        expect(layout.blend).toBe(1);
    });

    it('sends the other items round the back, taking the short way', () => {
        const back = carouselElementLayout(2, 0, 4);
        const wrapped = carouselElementLayout(3, 0, 4);

        expect(back.y).toBeCloseTo(-113);
        expect(back.focus).toBe(0);
        expect(back.blend).toBe(0.25);
        expect(wrapped.x).toBeCloseTo(-38);
        expect(carouselElementLayout(1, 0, 4).x).toBeCloseTo(178);
    });

    it('turns to the next item and settles exactly on it', () => {
        const moving = nextCarousel(initialCarousel(), 4);

        expect(moving).toMatchObject({ target: 1, animating: true, backwards: false });

        const settled = settle(4, moving);

        expect(settled).toMatchObject({ target: 1, position: 1, animating: false, extraCycles: 0 });
    });

    it('wraps backwards from the first item to the last', () => {
        const settled = settle(4, previousCarousel(initialCarousel(), 4));

        expect(settled).toMatchObject({ target: 3, position: 3, animating: false });
    });

    it('a page dot turns the short way round', () => {
        expect(navigateCarousel({ ...initialCarousel(), position: 3, target: 3 }, 0).backwards).toBe(true);
        expect(settle(4, navigateCarousel(initialCarousel(), 2))).toMatchObject({ position: 2, animating: false });
    });

    it('fades the plaque while the platform turns and restores it on arrival', () => {
        const moving = stepCarousel(nextCarousel(initialCarousel(), 4), 4, 16);

        expect(plaqueFor(moving, 0, 4).blend).toBeLessThan(1);
        expect(plaqueFor(settle(4, moving), 0, 4)).toEqual({ displayed: 1, blend: 1 });
        expect(spotlightBlendFor(1)).toBeCloseTo(1);
        expect(spotlightBlendFor(0.5)).toBe(0.4);
    });
});

describe('rotation reducer', () => {
    it('remembers every visited item and the plaque item', () => {
        let state = initialRotation();

        state = specialItemsRotationReducer(state, { type: 'next', count: 3 });
        for (let i = 0; i < 2000 && state.carousel.animating; i++) state = specialItemsRotationReducer(state, { type: 'tick', count: 3, deltaMs: 16 });

        expect([...state.visited].sort()).toEqual([0, 1]);
        expect(state.shown).toBe(1);
        expect(state.blend).toBe(1);

        state = specialItemsRotationReducer(state, { type: 'navigate', index: 2 });
        expect(state.visited.has(2)).toBe(true);
        expect(specialItemsRotationReducer(state, { type: 'reset' }).visited.size).toBe(1);
    });
});
15Sujets
1Dépôts
20Membres
2En 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