diff --git a/src/app/configure-tasks-app/ui/TemplateSidebar.tsx b/src/app/configure-tasks-app/ui/TemplateSidebar.tsx index 9d9339b71..75b5d3afe 100644 --- a/src/app/configure-tasks-app/ui/TemplateSidebar.tsx +++ b/src/app/configure-tasks-app/ui/TemplateSidebar.tsx @@ -48,7 +48,7 @@ export const TemplateSidebar = ({ const currentWorkflowState = workflowStates.find((el) => el?.id === currentTask?.workflowStateId) updateStatusValue(currentWorkflowState) } - }, [activeTemplate, workflowStates]) + }, [activeTemplate, workflowStates, updateStatusValue]) const windowWidth = useWindowWidth() const isMobile = windowWidth < 800 && windowWidth !== 0 diff --git a/src/hooks/useHandleSelectorComponent.test.tsx b/src/hooks/useHandleSelectorComponent.test.tsx new file mode 100644 index 000000000..8e4ab197b --- /dev/null +++ b/src/hooks/useHandleSelectorComponent.test.tsx @@ -0,0 +1,71 @@ +import { act } from 'react' +import { useEffect } from 'react' +import { JSDOM } from 'jsdom' +import type { SelectorType } from '@/components/inputs/Selector' +import { useHandleSelectorComponent } from '@/hooks/useHandleSelectorComponent' + +const initialItem = { id: 'initial' } +const updatedItem = { id: 'updated' } +const templateSelector = 'templateSelected' as SelectorType + +const setupDom = () => { + const dom = new JSDOM('
', { url: 'http://localhost' }) + const previousWindow = globalThis.window + const previousDocument = globalThis.document + const previousNavigator = globalThis.navigator + const previousActEnvironment = Object.getOwnPropertyDescriptor(globalThis, 'IS_REACT_ACT_ENVIRONMENT') + + Object.defineProperty(globalThis, 'window', { configurable: true, value: dom.window }) + Object.defineProperty(globalThis, 'document', { configurable: true, value: dom.window.document }) + Object.defineProperty(globalThis, 'navigator', { configurable: true, value: dom.window.navigator }) + Object.defineProperty(globalThis, 'IS_REACT_ACT_ENVIRONMENT', { configurable: true, value: true }) + + return () => { + Object.defineProperty(globalThis, 'window', { configurable: true, value: previousWindow }) + Object.defineProperty(globalThis, 'document', { configurable: true, value: previousDocument }) + Object.defineProperty(globalThis, 'navigator', { configurable: true, value: previousNavigator }) + if (previousActEnvironment) { + Object.defineProperty(globalThis, 'IS_REACT_ACT_ENVIRONMENT', previousActEnvironment) + } else { + Reflect.deleteProperty(globalThis, 'IS_REACT_ACT_ENVIRONMENT') + } + dom.window.close() + } +} + +describe('useHandleSelectorComponent', () => { + it('keeps the imperative updater stable after local selector state changes', async () => { + const cleanupDom = setupDom() + const { createRoot } = await import('react-dom/client') + const container = document.createElement('div') + document.body.appendChild(container) + const root = createRoot(container) + const effectRuns = jest.fn() + + const Probe = () => { + const { updateRenderingItem } = useHandleSelectorComponent({ + item: initialItem, + type: templateSelector, + }) + + useEffect(() => { + effectRuns() + updateRenderingItem(updatedItem) + }, [updateRenderingItem]) + + return null + } + + await act(async () => { + root.render(