From f97650d7f61e6d540de1ae96570c33a632855d49 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Tue, 26 May 2026 21:54:31 +0200 Subject: [PATCH] fix(rooms): useDoorState handles roomEnter reset + test-order isolation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code review of Task 2 (commit 07bbc0c7) found two real issues: 1. The GetGuestRoomResultEvent handler did not handle parser.roomEnter, so after the consumer migration (Tasks 5-8) a successful room entry would no longer dismiss the door dialog. Fix: reset to INITIAL when parser.roomEnter is true, before the roomForward branch. 2. The test suite was order-dependent — the useBetween singleton persisted state across tests, so 'exposes the initial NONE snapshot' passed only because it ran first. Fix: beforeEach renders the hook once, calls reset(), then unmounts; afterEach calls cleanup(). Plus one new test case verifying the roomEnter -> reset behavior. --- src/hooks/rooms/widgets/useDoorState.test.tsx | 34 +++++++++++++++++-- src/hooks/rooms/widgets/useDoorState.ts | 5 +++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/hooks/rooms/widgets/useDoorState.test.tsx b/src/hooks/rooms/widgets/useDoorState.test.tsx index 1176d07..2655230 100644 --- a/src/hooks/rooms/widgets/useDoorState.test.tsx +++ b/src/hooks/rooms/widgets/useDoorState.test.tsx @@ -1,8 +1,8 @@ -import { act, renderHook } from '@testing-library/react'; +import { act, cleanup, renderHook } from '@testing-library/react'; import { DoorbellMessageEvent, FlatAccessDeniedMessageEvent, GenericErrorEvent, GetGuestRoomResultEvent, RoomDataParser, RoomDoorbellAcceptedEvent } from '@nitrots/nitro-renderer'; -import { beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { DoorStateType } from '../../../api'; import { clearMockEventDispatcher, mockEventDispatcher } from '../../../nitro-renderer.mock'; import { useDoorState } from './useDoorState'; @@ -19,6 +19,14 @@ describe('useDoorState', () => beforeEach(() => { clearMockEventDispatcher(); + const { result, unmount } = renderHook(() => useDoorState()); + act(() => result.current.reset()); + unmount(); + }); + + afterEach(() => + { + cleanup(); }); it('exposes the initial NONE snapshot', () => @@ -136,6 +144,28 @@ describe('useDoorState', () => expect(result.current.snapshot.state).toBe(before); }); + it('GetGuestRoomResultEvent with roomEnter=true resets snapshot to NONE', () => + { + const { result } = renderHook(() => useDoorState()); + // First put the hook into a non-NONE state via doorbell + act(() => + { + mockEventDispatcher.dispatchEvent(makeParserlessEvent(DoorbellMessageEvent, { userName: '' })); + }); + expect(result.current.snapshot.state).toBe(DoorStateType.STATE_WAITING); + // Then roomEnter event should dismiss it + act(() => + { + mockEventDispatcher.dispatchEvent(makeParserlessEvent(GetGuestRoomResultEvent, { + roomEnter: true, + roomForward: false, + data: {} + })); + }); + expect(result.current.snapshot.state).toBe(DoorStateType.NONE); + expect(result.current.snapshot.roomInfo).toBeNull(); + }); + it('reset() returns snapshot to NONE', () => { const { result } = renderHook(() => useDoorState()); diff --git a/src/hooks/rooms/widgets/useDoorState.ts b/src/hooks/rooms/widgets/useDoorState.ts index 1fadbba..b9dbb05 100644 --- a/src/hooks/rooms/widgets/useDoorState.ts +++ b/src/hooks/rooms/widgets/useDoorState.ts @@ -49,6 +49,11 @@ const useDoorStateStore = () => const handleGuestRoom = useCallback((event: GetGuestRoomResultEvent) => { const parser = event.getParser(); + if(parser.roomEnter) + { + setSnapshot(INITIAL); + return; + } if(!parser.roomForward) return; if(parser.data.ownerName === GetSessionDataManager().userName) return; if(parser.isGroupMember) return;