/**
* @jest-environment jsdom
*/
/* eslint-disable sonarjs/no-identical-functions */
import '@abraham/reflection'
import { GLOBAL_KEY_SYMBOL, RETRY_KEY_SYMBOL } from '@sigi/core'
import { Injector } from '@sigi/di'
import { useEffect } from 'react'
import { render, act } from '@testing-library/react'
import { SSRContext, useModule } from '../index.browser'
import { CountModule, ServiceModule, Service } from './__fixtures__'
const ComponentWithSelector = () => {
const [state, actions] = useModule(CountModule, {
selector: (s) => ({
count: s.count + 1,
}),
})
useEffect(() => {
actions.setName('new name')
}, [actions])
return {state.count}
}
const MODULES = [CountModule, ServiceModule, Service]
describe('client ssr hydration', () => {
it('should restore state from global with selector', () => {
// @ts-expect-error
global[GLOBAL_KEY_SYMBOL] = {
CountModule: {
count: 10,
name: '',
},
}
const testRenderer = render(
,
)
expect(testRenderer.baseElement.querySelector('span')?.textContent).toBe('11')
// @ts-expect-error
delete global[GLOBAL_KEY_SYMBOL]
testRenderer.unmount()
})
it('should not restore state from global if state is null', () => {
// @ts-expect-error
global[GLOBAL_KEY_SYMBOL] = {
OtherModule: {
count: 10,
name: '',
},
}
const injector = new Injector().addProviders(MODULES)
const testRenderer = render(
,
)
act(() => {
testRenderer.rerender(
,
)
})
expect(testRenderer.baseElement.querySelector('span')?.textContent).toBe('1')
// @ts-expect-error
delete global[GLOBAL_KEY_SYMBOL]
testRenderer.unmount()
})
it('should restore and skip first action on client side', () => {
const Component = () => {
const [state, actions] = useModule(CountModule)
useEffect(() => {
actions.getCount()
}, [actions])
return {state.count}
}
// @ts-expect-error
global[GLOBAL_KEY_SYMBOL] = {
CountModule: {
count: 2,
name: '',
},
}
const injector = new Injector().addProviders(MODULES)
const testRenderer = render(
,
)
act(() => {
testRenderer.rerender(
,
)
})
expect(testRenderer.baseElement.querySelector('span')?.textContent).toBe('2')
// @ts-expect-error
delete global[GLOBAL_KEY_SYMBOL]
testRenderer.unmount()
})
it('should retry action if needed on client side', () => {
const Component = () => {
const [state, dispatcher] = useModule(ServiceModule)
useEffect(() => {
dispatcher.setNameWithFailure(void 0)
}, [dispatcher])
return {state.name}
}
// @ts-expect-error
global[RETRY_KEY_SYMBOL] = {
ServiceModule: ['setNameWithFailure'],
}
const injector = new Injector().addProviders(MODULES)
const testRenderer = render(
,
)
// eslint-disable-next-line sonarjs/no-identical-functions
act(() => {
testRenderer.rerender(
,
)
})
expect(testRenderer.baseElement.querySelector('span')?.textContent).toBe('From retry')
// @ts-expect-error
delete global[GLOBAL_KEY_SYMBOL]
testRenderer.unmount()
})
})