cadfa70e60
* #708 apply strictier linting rules and fix simple eslint bugs * #708 fix eslint errors relate to promise * #708 fix eslint import/no-extraneous-dependencies * #708 fix eslint errors of react-hook * #708 enable eslint check for typescript --------- Co-authored-by: lethemanh <lethemanh@lethemanhs-MacBook-Pro.local>
183 lines
4.7 KiB
TypeScript
183 lines
4.7 KiB
TypeScript
import { useAppDispatch, useAppSelector } from '@/app/hooks'
|
|
import { getCalendarsListAsync } from '@/features/Calendars/services/getCalendarsListAsync'
|
|
import { CallbackResume } from '@/features/User/LoginCallback'
|
|
import * as oidcAuth from '@/features/User/oidcAuth'
|
|
import {
|
|
getOpenPaasUserDataAsync,
|
|
setTokens,
|
|
setUserData
|
|
} from '@/features/User/userSlice'
|
|
import { render, waitFor } from '@testing-library/react'
|
|
import { replace } from 'redux-first-history'
|
|
import { renderWithProviders } from '../../utils/Renderwithproviders'
|
|
import { setAppLoading } from '@/app/loadingSlice'
|
|
|
|
// Mocks
|
|
jest.mock('@/app/hooks', () => ({
|
|
useAppDispatch: jest.fn(),
|
|
useAppSelector: jest.fn(() => ({
|
|
user: {
|
|
userData: null,
|
|
tokens: null,
|
|
loading: false,
|
|
error: null
|
|
},
|
|
calendars: {
|
|
list: {},
|
|
pending: false,
|
|
error: null
|
|
}
|
|
}))
|
|
}))
|
|
|
|
jest.mock('@/features/User/oidcAuth', () => ({
|
|
Callback: jest.fn()
|
|
}))
|
|
|
|
jest.mock('@/features/User/userSlice', () => {
|
|
const mockGetUser = Object.assign(
|
|
jest.fn(() => ({ type: 'GET_USER_ID' })),
|
|
{
|
|
pending: { type: 'GET_USER_ID/pending' },
|
|
fulfilled: { type: 'GET_USER_ID/fulfilled' },
|
|
rejected: { type: 'GET_USER_ID/rejected' }
|
|
}
|
|
)
|
|
|
|
return {
|
|
setUserData: jest.fn(data => ({ type: 'SET_USER', payload: data })),
|
|
setTokens: jest.fn(tokens => ({ type: 'SET_TOKENS', payload: tokens })),
|
|
getOpenPaasUserDataAsync: mockGetUser
|
|
}
|
|
})
|
|
|
|
jest.mock('@/features/Calendars/services/getCalendarsListAsync', () => {
|
|
const mockGetCalendars = Object.assign(
|
|
jest.fn(() => ({ type: 'GET_CALENDARS' })),
|
|
{
|
|
pending: { type: 'GET_CALENDARS/pending' },
|
|
fulfilled: { type: 'GET_CALENDARS/fulfilled' },
|
|
rejected: { type: 'GET_CALENDARS/rejected' }
|
|
}
|
|
)
|
|
|
|
return {
|
|
getCalendarsListAsync: mockGetCalendars
|
|
}
|
|
})
|
|
|
|
describe('CallbackResume', () => {
|
|
const dispatch = jest.fn()
|
|
let mockUserState: any
|
|
let mockCalendarsState: any
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks()
|
|
;(useAppDispatch as unknown as jest.Mock).mockReturnValue(dispatch)
|
|
|
|
// Initialize mock states
|
|
mockUserState = {
|
|
userData: null,
|
|
tokens: null,
|
|
loading: false,
|
|
error: null
|
|
}
|
|
mockCalendarsState = {
|
|
list: {},
|
|
pending: false,
|
|
error: null
|
|
}
|
|
;(useAppSelector as jest.Mock).mockImplementation(selector => {
|
|
const state = {
|
|
user: mockUserState,
|
|
calendars: mockCalendarsState
|
|
}
|
|
return selector(state)
|
|
})
|
|
})
|
|
|
|
it('should call Callback and dispatch necessary actions', async () => {
|
|
const mockTokenSet = { access_token: 'abc' }
|
|
const mockUserInfo = { name: 'Test User' }
|
|
|
|
const mockData = {
|
|
tokenSet: mockTokenSet,
|
|
userinfo: mockUserInfo
|
|
}
|
|
|
|
;(oidcAuth.Callback as jest.Mock).mockResolvedValue(mockData)
|
|
|
|
sessionStorage.setItem(
|
|
'redirectState',
|
|
JSON.stringify({ code_verifier: 'verifier123', state: 'state456' })
|
|
)
|
|
|
|
const { rerender } = render(<CallbackResume />)
|
|
|
|
await waitFor(() => {
|
|
expect(oidcAuth.Callback).toHaveBeenCalledWith('verifier123', 'state456')
|
|
})
|
|
await waitFor(() => {
|
|
expect(dispatch).toHaveBeenCalledWith(setAppLoading(true))
|
|
})
|
|
await waitFor(() => {
|
|
expect(dispatch).toHaveBeenCalledWith(setUserData(mockUserInfo))
|
|
})
|
|
await waitFor(() => {
|
|
expect(dispatch).toHaveBeenCalledWith(setTokens(mockTokenSet))
|
|
})
|
|
await waitFor(() => {
|
|
expect(dispatch).toHaveBeenCalledWith(getOpenPaasUserDataAsync())
|
|
})
|
|
await waitFor(() => {
|
|
expect(dispatch).toHaveBeenCalledWith(getCalendarsListAsync())
|
|
})
|
|
|
|
// Simulate async actions completing by updating mock state
|
|
mockUserState = {
|
|
userData: mockUserInfo,
|
|
tokens: mockTokenSet,
|
|
loading: false,
|
|
error: null
|
|
}
|
|
mockCalendarsState = {
|
|
list: { calendar1: {} },
|
|
pending: false,
|
|
error: null
|
|
}
|
|
|
|
// Re-render to trigger navigation effect
|
|
rerender(<CallbackResume />)
|
|
|
|
await waitFor(
|
|
() => {
|
|
expect(dispatch).toHaveBeenCalledWith(setAppLoading(false))
|
|
},
|
|
{ timeout: 3000 }
|
|
)
|
|
await waitFor(
|
|
() => {
|
|
expect(dispatch).toHaveBeenCalledWith(replace('/calendar'))
|
|
},
|
|
{ timeout: 3000 }
|
|
)
|
|
await waitFor(() => {
|
|
expect(sessionStorage.getItem('redirectState')).toBe(null)
|
|
})
|
|
await waitFor(() => {
|
|
expect(sessionStorage.getItem('tokenSet')).toEqual(
|
|
JSON.stringify(mockTokenSet)
|
|
)
|
|
})
|
|
})
|
|
|
|
it('should handle missing redirectState gracefully', async () => {
|
|
sessionStorage.removeItem('redirectState')
|
|
renderWithProviders(<CallbackResume />)
|
|
|
|
await waitFor(() => {
|
|
expect(dispatch).toHaveBeenCalledWith(replace('/'))
|
|
})
|
|
})
|
|
})
|