/
voting
/
frontend
Обзор
Документация
Войти
/
voting
/
frontend
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
main
test/userFlowHelpers.test.ts
319 строк
9 KB
TimPulin
043-wire-voting-screen-vote
19 июл 2026, 19:00
19 июл 2026, 19:00
0ca0a67
Код
Авторство
О чём код?
import { describe, expect, it } from 'vitest' import type { CurrentNominationNominationDto } from '../src/api/types' import type { UserFlowSnapshot } from '../src/types/user-flow' import { isResultScreenType, isSseScreenType, mapEventScreenTypeToSseScreenType, mapNominationToVotingProps, mapSseScreenTypeToResultScreenType, parseUserFlowSseEnvelope, resolveRouterScreen } from '../src/utils/userFlowHelpers' function makeSnapshot( overrides: Partial<UserFlowSnapshot> & { event?: Partial<UserFlowSnapshot['event']> nomination?: UserFlowSnapshot['nomination'] } = {} ): UserFlowSnapshot { return { event: { id: 'evt-1', name: 'Event', currentScreenType: 'NOMINATION', ...overrides.event }, nomination: overrides.nomination === undefined ? { id: 'nom-1', name: 'Best', status: 'OPEN', position: 1, nominees: [] } : overrides.nomination } } describe('mapEventScreenTypeToSseScreenType', () => { it('maps NOMINATION to nomination', () => { expect(mapEventScreenTypeToSseScreenType('NOMINATION')).toBe('nomination') }) it('maps NOMINATION_RESULT and FINAL_RESULT to SSE result screens', () => { expect(mapEventScreenTypeToSseScreenType('NOMINATION_RESULT')).toBe( 'nominationResult' ) expect(mapEventScreenTypeToSseScreenType('FINAL_RESULT')).toBe('finalResult') }) it('returns null for unknown screen type', () => { expect(mapEventScreenTypeToSseScreenType('UNKNOWN')).toBeNull() expect(mapEventScreenTypeToSseScreenType('')).toBeNull() }) }) describe('mapSseScreenTypeToResultScreenType', () => { it('maps SSE result screens to REST ResultScreenType', () => { expect(mapSseScreenTypeToResultScreenType('nominationResult')).toBe( 'NOMINATION_RESULT' ) expect(mapSseScreenTypeToResultScreenType('finalResult')).toBe('FINAL_RESULT') }) it('returns null for nomination', () => { expect(mapSseScreenTypeToResultScreenType('nomination')).toBeNull() }) }) describe('isSseScreenType', () => { it('accepts SSE screen types', () => { expect(isSseScreenType('nomination')).toBe(true) expect(isSseScreenType('nominationResult')).toBe(true) expect(isSseScreenType('finalResult')).toBe(true) }) it('rejects other values', () => { expect(isSseScreenType('NOMINATION')).toBe(false) expect(isSseScreenType('voting')).toBe(false) expect(isSseScreenType(null)).toBe(false) }) }) describe('isResultScreenType', () => { it('accepts result screen types', () => { expect(isResultScreenType('NOMINATION_RESULT')).toBe(true) expect(isResultScreenType('FINAL_RESULT')).toBe(true) }) it('rejects other values', () => { expect(isResultScreenType('NOMINATION')).toBe(false) expect(isResultScreenType(null)).toBe(false) expect(isResultScreenType(42)).toBe(false) }) }) describe('parseUserFlowSseEnvelope', () => { it('parses nominationChanged with unified payload', () => { expect( parseUserFlowSseEnvelope({ type: 'nominationChanged', data: { screenType: 'nomination', nominationId: 'nom-1' } }) ).toEqual({ type: 'nominationChanged', data: { screenType: 'nomination', nominationId: 'nom-1' } }) }) it('parses showResult with nominationResult and string nominationId', () => { expect( parseUserFlowSseEnvelope({ type: 'showResult', data: { screenType: 'nominationResult', nominationId: 'nom-1' } }) ).toEqual({ type: 'showResult', data: { screenType: 'nominationResult', nominationId: 'nom-1' } }) }) it('parses showResult with null nominationId', () => { expect( parseUserFlowSseEnvelope({ type: 'showResult', data: { screenType: 'finalResult', nominationId: null } }) ).toEqual({ type: 'showResult', data: { screenType: 'finalResult', nominationId: null } }) }) it('returns null for unpublished SSE types', () => { expect( parseUserFlowSseEnvelope({ type: 'votingOpened', data: {} }) ).toBeNull() expect( parseUserFlowSseEnvelope({ type: 'votingClosed', data: {} }) ).toBeNull() expect( parseUserFlowSseEnvelope({ type: 'eventStatusChanged', data: {} }) ).toBeNull() }) it('returns null for invalid payloads', () => { expect(parseUserFlowSseEnvelope(null)).toBeNull() expect(parseUserFlowSseEnvelope('x')).toBeNull() expect( parseUserFlowSseEnvelope({ type: 'nominationChanged', data: { screenType: 'nomination', nominationId: '' } }) ).toBeNull() expect( parseUserFlowSseEnvelope({ type: 'nominationChanged', data: { screenType: 'nomination' } }) ).toBeNull() expect( parseUserFlowSseEnvelope({ type: 'nominationChanged', data: { nominationId: 'nom-1' } }) ).toBeNull() expect( parseUserFlowSseEnvelope({ type: 'showResult', data: { screenType: 'nomination', nominationId: 'nom-1' } }) ).toBeNull() expect( parseUserFlowSseEnvelope({ type: 'nominationChanged', data: { screenType: 'nominationResult', nominationId: 'nom-1' } }) ).toBeNull() }) it('rejects legacy showResult SCREAMING_SNAKE payload', () => { expect( parseUserFlowSseEnvelope({ type: 'showResult', data: { screenType: 'NOMINATION_RESULT', nominationId: 'nom-1' } }) ).toBeNull() }) it('rejects legacy nominationChanged without screenType', () => { expect( parseUserFlowSseEnvelope({ type: 'nominationChanged', data: { nominationId: 'nom-1' } }) ).toBeNull() }) it('rejects legacy currentNominationId field', () => { expect( parseUserFlowSseEnvelope({ type: 'showResult', data: { screenType: 'finalResult', currentNominationId: 'nom-1' } }) ).toBeNull() }) }) describe('resolveRouterScreen', () => { it('returns nomination when nomination + active nomination', () => { expect( resolveRouterScreen({ currentScreen: 'nomination', snapshot: makeSnapshot(), isHydrating: false }) ).toBe('nomination') }) it('returns nominationResult when currentScreen is nominationResult', () => { expect( resolveRouterScreen({ currentScreen: 'nominationResult', snapshot: makeSnapshot({ event: { currentScreenType: 'NOMINATION_RESULT' }, nomination: null }), isHydrating: false }) ).toBe('nominationResult') }) it('returns finalResult when currentScreen is finalResult', () => { expect( resolveRouterScreen({ currentScreen: 'finalResult', snapshot: makeSnapshot({ event: { currentScreenType: 'FINAL_RESULT' }, nomination: null }), isHydrating: false }) ).toBe('finalResult') }) it('returns loading while hydrating', () => { expect( resolveRouterScreen({ currentScreen: 'nomination', snapshot: makeSnapshot(), isHydrating: true }) ).toBe('loading') }) it('returns loading when nomination with null nomination', () => { expect( resolveRouterScreen({ currentScreen: 'nomination', snapshot: makeSnapshot({ nomination: null }), isHydrating: false }) ).toBe('loading') }) it('returns loading when currentScreen is null without usable snapshot', () => { expect( resolveRouterScreen({ currentScreen: null, snapshot: null, isHydrating: false }) ).toBe('loading') }) }) describe('mapNominationToVotingProps', () => { const nomination: CurrentNominationNominationDto = { id: 'nom-1', name: 'Лучший доклад', status: 'CLOSED', position: 1, nominees: [ { id: 'n1', name: 'Иван Петров', description: null, photoFileId: 'file-1' }, { id: 'n2', name: 'Мария Сидорова', description: 'bio', photoFileId: null } ] } it('maps name and nominees to UI props; photoUrl and isClosed stay fixed', () => { const props = mapNominationToVotingProps(nomination) expect(props.title).toBe('Лучший доклад') expect(props.isClosed).toBe(false) expect(props.nominationId).toBe('nom-1') expect(props.candidates).toEqual([ { id: 'n1', fullName: 'Иван Петров', photoUrl: null }, { id: 'n2', fullName: 'Мария Сидорова', photoUrl: null } ]) }) it('maps empty nominees to empty candidates', () => { const props = mapNominationToVotingProps({ ...nomination, nominees: [] }) expect(props.nominationId).toBe('nom-1') expect(props.candidates).toEqual([]) }) })