312 lines
8.5 KiB
JavaScript
312 lines
8.5 KiB
JavaScript
import React from 'react'
|
|
import { renderHook, act } from '@testing-library/react-hooks'
|
|
import { ApiProvider } from './provider'
|
|
import { useChildList } from './hooks'
|
|
import store from './store'
|
|
import init from './__mocks__/@skolplattformen/embedded-api'
|
|
import createStorage from './__mocks__/AsyncStorage'
|
|
import reporter from './__mocks__/reporter'
|
|
import { etjanstChildren } from './reducers'
|
|
|
|
const pause = (ms = 0) => new Promise((r) => setTimeout(r, ms))
|
|
|
|
describe('useChildList()', () => {
|
|
let api
|
|
let storage
|
|
let echildrenCache
|
|
let skola24Cache
|
|
let echildrenResponse
|
|
let skola24Response
|
|
const wrapper = ({ children }) => (
|
|
<ApiProvider api={api} storage={storage} reporter={reporter}>
|
|
{children}
|
|
</ApiProvider>
|
|
)
|
|
beforeEach(() => {
|
|
echildrenCache = [{ id: 2, name: 'Uwe Übrink (elev)' }]
|
|
skola24Cache = [
|
|
{ personGuid: '2', firstName: 'Uwe', lastName: 'Vredstein Übrink' },
|
|
]
|
|
|
|
echildrenResponse = [{ id: 1, name: 'Uwe Übrink (elev)' }]
|
|
skola24Response = [
|
|
{ personGuid: '1', firstName: 'Uwe', lastName: 'Vredstein Übrink' },
|
|
]
|
|
|
|
api = init()
|
|
api.getPersonalNumber.mockReturnValue('123')
|
|
|
|
api.getChildren.mockImplementation(
|
|
() =>
|
|
new Promise((res) => {
|
|
setTimeout(() => res(echildrenResponse), 50)
|
|
})
|
|
)
|
|
api.getSkola24Children.mockImplementation(
|
|
() =>
|
|
new Promise((res) => {
|
|
setTimeout(() => res(skola24Response), 50)
|
|
})
|
|
)
|
|
storage = createStorage(
|
|
{
|
|
'123_etjanst_children': echildrenCache,
|
|
'123_skola24_children': skola24Cache,
|
|
},
|
|
2
|
|
)
|
|
})
|
|
afterEach(async () => {
|
|
await act(async () => {
|
|
await pause(70)
|
|
store.dispatch({ entity: 'ALL', type: 'CLEAR' })
|
|
})
|
|
})
|
|
it('returns correct initial value', () => {
|
|
const { result } = renderHook(() => useChildList(), { wrapper })
|
|
|
|
expect(result.current.status).toEqual('pending')
|
|
})
|
|
it('calls api', async () => {
|
|
await act(async () => {
|
|
api.isLoggedIn = true
|
|
const { waitForNextUpdate } = renderHook(() => useChildList(), {
|
|
wrapper,
|
|
})
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
|
|
expect(api.getChildren).toHaveBeenCalled()
|
|
expect(api.getSkola24Children).toHaveBeenCalled()
|
|
})
|
|
})
|
|
it('only calls api once', async () => {
|
|
await act(async () => {
|
|
api.isLoggedIn = true
|
|
renderHook(() => useChildList(), { wrapper })
|
|
const { waitForNextUpdate } = renderHook(() => useChildList(), {
|
|
wrapper,
|
|
})
|
|
|
|
await waitForNextUpdate()
|
|
renderHook(() => useChildList(), { wrapper })
|
|
await waitForNextUpdate()
|
|
renderHook(() => useChildList(), { wrapper })
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
|
|
const { result } = renderHook(() => useChildList(), { wrapper })
|
|
|
|
expect(api.getChildren).toHaveBeenCalledTimes(1)
|
|
expect(api.getSkola24Children).toHaveBeenCalledTimes(1)
|
|
expect(result.current.status).toEqual('loaded')
|
|
})
|
|
})
|
|
it('calls cache', async () => {
|
|
await act(async () => {
|
|
api.isLoggedIn = true
|
|
const { result, waitForNextUpdate } = renderHook(() => useChildList(), {
|
|
wrapper,
|
|
})
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
|
|
expect(result.current.data).toEqual([
|
|
{
|
|
id: 2,
|
|
name: 'Uwe Übrink (elev)',
|
|
personGuid: '2',
|
|
firstName: 'Uwe',
|
|
lastName: 'Vredstein Übrink',
|
|
},
|
|
])
|
|
})
|
|
})
|
|
it('updates status to loading', async () => {
|
|
await act(async () => {
|
|
api.isLoggedIn = true
|
|
const { result, waitForNextUpdate } = renderHook(() => useChildList(), {
|
|
wrapper,
|
|
})
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
|
|
expect(result.current.status).toEqual('loading')
|
|
})
|
|
})
|
|
it('updates status to loaded', async () => {
|
|
await act(async () => {
|
|
api.isLoggedIn = true
|
|
const { result, waitForNextUpdate } = renderHook(() => useChildList(), {
|
|
wrapper,
|
|
})
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
|
|
expect(result.current.status).toEqual('loaded')
|
|
})
|
|
})
|
|
it('stores in cache if not fake', async () => {
|
|
await act(async () => {
|
|
api.isLoggedIn = true
|
|
api.isFake = false
|
|
|
|
const { waitForNextUpdate } = renderHook(() => useChildList(), {
|
|
wrapper,
|
|
})
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await pause(20)
|
|
|
|
expect(storage.cache['123_etjanst_children']).toEqual(
|
|
JSON.stringify(echildrenResponse)
|
|
)
|
|
expect(storage.cache['123_skola24_children']).toEqual(
|
|
JSON.stringify(skola24Response)
|
|
)
|
|
})
|
|
})
|
|
it('does not store in cache if fake', async () => {
|
|
await act(async () => {
|
|
api.isLoggedIn = true
|
|
api.isFake = true
|
|
|
|
const { result, waitForNextUpdate } = renderHook(() => useChildList(), {
|
|
wrapper,
|
|
})
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await pause(20)
|
|
|
|
expect(result.current.status).toEqual('loaded')
|
|
expect(storage.cache['123_etjanst_children']).toEqual(
|
|
JSON.stringify(echildrenCache)
|
|
)
|
|
expect(storage.cache['123_skola24_children']).toEqual(
|
|
JSON.stringify(skola24Cache)
|
|
)
|
|
})
|
|
})
|
|
it('retries if etjanst-api fails', async () => {
|
|
await act(async () => {
|
|
api.isLoggedIn = true
|
|
const error = new Error('fail')
|
|
api.getChildren.mockRejectedValueOnce(error)
|
|
|
|
const { result, waitForNextUpdate } = renderHook(() => useChildList(), {
|
|
wrapper,
|
|
})
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
|
|
expect(result.current.error).toEqual(error)
|
|
expect(result.current.status).toEqual('loading')
|
|
expect(result.current.data).toEqual(echildrenCache)
|
|
|
|
jest.advanceTimersToNextTimer()
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
|
|
expect(result.current.status).toEqual('loaded')
|
|
expect(result.current.data).toEqual([
|
|
{
|
|
id: 1,
|
|
name: 'Uwe Übrink (elev)',
|
|
personGuid: '1',
|
|
firstName: 'Uwe',
|
|
lastName: 'Vredstein Übrink',
|
|
},
|
|
])
|
|
})
|
|
})
|
|
it('gives up after 3 retries', async () => {
|
|
await act(async () => {
|
|
api.isLoggedIn = true
|
|
const error = new Error('fail')
|
|
api.getChildren.mockRejectedValueOnce(error)
|
|
api.getChildren.mockRejectedValueOnce(error)
|
|
api.getChildren.mockRejectedValueOnce(error)
|
|
|
|
const { result, waitForNextUpdate } = renderHook(() => useChildList(), {
|
|
wrapper,
|
|
})
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
|
|
expect(result.current.error).toEqual(error)
|
|
expect(result.current.status).toEqual('loading')
|
|
expect(result.current.data).toEqual(echildrenCache)
|
|
|
|
jest.advanceTimersToNextTimer()
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
|
|
expect(result.current.error).toEqual(error)
|
|
expect(result.current.status).toEqual('error')
|
|
expect(result.current.data).toEqual([
|
|
{
|
|
id: 2,
|
|
name: 'Uwe Übrink (elev)',
|
|
personGuid: '1',
|
|
firstName: 'Uwe',
|
|
lastName: 'Vredstein Übrink',
|
|
},
|
|
])
|
|
})
|
|
})
|
|
it('reports if api fails', async () => {
|
|
await act(async () => {
|
|
api.isLoggedIn = true
|
|
const error = new Error('fail')
|
|
api.getChildren.mockRejectedValueOnce(error)
|
|
|
|
const { result, waitForNextUpdate } = renderHook(() => useChildList(), {
|
|
wrapper,
|
|
})
|
|
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
await waitForNextUpdate()
|
|
|
|
expect(result.current.error).toEqual(error)
|
|
|
|
expect(reporter.error).toHaveBeenCalledWith(
|
|
error,
|
|
'Error getting ETJANST_CHILDREN from API'
|
|
)
|
|
})
|
|
})
|
|
})
|