5180 fichiers 38.5 Mo 0 téléchargements 595 vues mis à jour il y a 8 heures ui
nitro-v36-with-renderer-v36 / src / components / catalog / views / page / layout / vip-gifts / CatalogLayoutVipGiftsView.test.tsx
CatalogLayoutVipGiftsView.test.tsx 6.9 Ko Télécharger le fichier
import { SelectClubGiftComposer } from '@octane/renderer';
import { cleanup, fireEvent, render, screen, within } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { SendMessageComposer } from '../../../../../../api';
import { useClubGifts, useNotification, usePurse } from '../../../../../../hooks';
import { CatalogLayoutVipGiftsView } from './CatalogLayoutVipGiftsView';

const textOverrides = vi.hoisted(() => new Map<string, string>());

const furniData = vi.hoisted(
    () =>
        new Map<number, { className: string; name: string; description: string }>([
            [10, { className: 'hc19_1', name: 'HC Sofa', description: 'hc19_1.desc' }],
            [20, { className: 'vip_lamp', name: 'VIP Lamp', description: 'Shines for VIPs' }]
        ])
);

vi.mock('@octane/renderer', async (importOriginal) => ({
    ...(await importOriginal<typeof import('@octane/renderer')>()),
    GetSessionDataManager: () => ({ getFloorItemData: (id: number) => furniData.get(id) ?? null, getWallItemData: () => null })
}));

vi.mock('../../../../../../api', async (importOriginal) => {
    const actual = await importOriginal<typeof import('../../../../../../api')>();

    return {
        ...actual,
        LocalizeText: (key: string, _names?: string[], values?: string[]) =>
            textOverrides.has(key) ? textOverrides.get(key) : values?.length ? `${key}:${values.join(',')}` : key,
        ProductImageUtility: { getProductCategory: () => 1, getProductImageUrl: () => '' },
        SendMessageComposer: vi.fn()
    };
});

vi.mock('../../../../../../hooks', async (importOriginal) => {
    const actual = await importOriginal<typeof import('../../../../../../hooks')>();

    return {
        ...actual,
        useClubGifts: vi.fn(),
        useNotification: vi.fn(),
        usePurse: vi.fn()
    };
});

const offer = (offerId: number, localizationId: string, furniClassId: number) => ({
    localizationId,
    offerId,
    products: [{ extraParam: '', furniClassId, productType: 's' }]
});

const clubGifts = (giftsAvailable: number, daysUntilNextGift = 0) => {
    const giftData = new Map([
        [1, { daysRequired: 31, isSelectable: true, isVip: false, offerId: 1 }],
        [2, { daysRequired: 93, isSelectable: false, isVip: true, offerId: 2 }]
    ]);

    return {
        daysUntilNextGift,
        getOfferExtraData: (offerId: number) => giftData.get(offerId),
        giftsAvailable,
        offers: [offer(2, 'gift_two', 20), offer(1, 'gift_one', 10)]
    };
};

const showConfirm = vi.fn();

const renderView = () => render(<CatalogLayoutVipGiftsView page={{ layoutCode: 'club_gifts' } as any} hideNavigation={() => undefined} />);

afterEach(cleanup);

beforeEach(() => {
    vi.clearAllMocks();
    textOverrides.clear();
    vi.mocked(useNotification).mockReturnValue({ showConfirm } as any);
    vi.mocked(usePurse).mockReturnValue({ purse: { isVip: true, pastClubDays: 20, pastVipDays: 13 } } as any);
    vi.mocked(useClubGifts).mockReturnValue({ data: clubGifts(2) } as any);
});

describe('club gifts page', () => {
    it('shows the gift state and the past club days (AIR hides the past vip days)', () => {
        renderView();

        expect(screen.getByText('catalog.club_gift.available:2')).toBeInTheDocument();
        expect(screen.getByText('catalog.club_gift.past_club.long:2,1')).toBeInTheDocument();
        expect(screen.queryByText(/catalog\.club_gift\.past_vip/)).not.toBeInTheDocument();
    });

    it('omits the past days lines while the purse is unknown', () => {
        vi.mocked(usePurse).mockReturnValue({ purse: null } as any);
        vi.mocked(useClubGifts).mockReturnValue({ data: clubGifts(0) } as any);

        renderView();

        expect(screen.getByText('catalog.club_gift.no_club')).toBeInTheDocument();
        expect(screen.queryByText(/catalog\.club_gift\.past_club/)).not.toBeInTheDocument();
        expect(screen.queryByText(/catalog\.club_gift\.past_vip/)).not.toBeInTheDocument();
    });

    it('falls back to the long past-club text when the pack leaves the short form empty', () => {
        textOverrides.set('catalog.club_gift.past_club', '');
        vi.mocked(usePurse).mockReturnValue({ purse: { isVip: true, pastClubDays: 10, pastVipDays: 2 } } as any);

        renderView();

        expect(screen.getByText('catalog.club_gift.past_club.long:12,0')).toBeInTheDocument();
    });

    it('lists each gift with its furnidata name, description, requirement and vip mark, by days required', () => {
        const { container } = renderView();
        const rows = container.querySelectorAll('.octane-catalog-club-gift');

        expect(rows).toHaveLength(2);

        const [clubGift, vipGift] = Array.from(rows) as HTMLElement[];

        expect(within(clubGift).getByText('HC Sofa')).toBeInTheDocument();
        expect(clubGift).not.toHaveTextContent('hc19_1.desc');
        expect(within(clubGift).getByText('catalog.club_gift.selectable')).toBeInTheDocument();
        expect(clubGift.querySelector('.octane-catalog-club-gift__vip')).toBeNull();

        expect(within(vipGift).getByText('VIP Lamp')).toBeInTheDocument();
        expect(within(vipGift).getByText('Shines for VIPs')).toBeInTheDocument();
        expect(within(vipGift).getByText('catalog.club_gift.vip_missing.long:18,2')).toBeInTheDocument();
        expect(vipGift.querySelector('.octane-catalog-club-gift__vip')).not.toBeNull();
    });

    it('enables the select button only for a selectable gift while gifts are available', () => {
        renderView();

        const [selectable, locked] = screen.getAllByRole('button', { name: 'catalog.club_gift.select' });

        expect(selectable).toHaveAttribute('aria-disabled', 'false');
        expect(locked).toHaveAttribute('aria-disabled', 'true');

        fireEvent.click(locked);

        expect(showConfirm).not.toHaveBeenCalled();
    });

    it('disables every select button when no gift is available', () => {
        vi.mocked(useClubGifts).mockReturnValue({ data: clubGifts(0, 4) } as any);

        renderView();

        expect(screen.getByText('catalog.club_gift.days_until_next:4')).toBeInTheDocument();

        for (const button of screen.getAllByRole('button', { name: 'catalog.club_gift.select' })) {
            expect(button).toHaveAttribute('aria-disabled', 'true');
        }
    });

    it('sends the selection after the confirmation', () => {
        showConfirm.mockImplementation((_message: string, onConfirm: () => void) => onConfirm());

        renderView();

        fireEvent.click(screen.getAllByRole('button', { name: 'catalog.club_gift.select' })[0]);

        expect(showConfirm).toHaveBeenCalledWith('catalog.club_gift.confirm', expect.any(Function), null);
        expect(SendMessageComposer).toHaveBeenCalledTimes(1);
        expect(vi.mocked(SendMessageComposer).mock.calls[0][0]).toBeInstanceOf(SelectClubGiftComposer);
        expect((vi.mocked(SendMessageComposer).mock.calls[0][0] as any).getMessageArray()).toEqual(['gift_one']);
    });
});
15Sujets
1Dépôts
20Membres
4En 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