import {render, waitFor} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {I18nextProvider} from 'react-i18next'
import {QueryClient, QueryClientProvider} from 'react-query'
import {Provider} from 'react-redux'
import {BrowserRouter} from 'react-router-dom'
import i18n from '../../../i18n'
import {ListClusters} from '../../../model'
import {store, clearState, setState} from '../../../store'
import Clusters, {onClustersUpdate} from '../Clusters'
import {ClusterStatus, ClusterInfoSummary} from '../../../types/clusters'
import {CloudFormationStackStatus} from '../../../types/base'
const queryClient = new QueryClient()
const mockClusters: ClusterInfoSummary[] = [
{
clusterName: 'test-cluster',
clusterStatus: ClusterStatus.CreateComplete,
version: '3.1.4',
cloudformationStackArn: 'arn',
region: 'region',
cloudformationStackStatus: CloudFormationStackStatus.CreateComplete,
},
]
const MockProviders = (props: any) => (
{props.children}
)
jest.mock('../../../model', () => ({
ListClusters: jest.fn(),
}))
jest.mock('../../../store', () => ({
...(jest.requireActual('../../../store') as any),
isAdmin: () => true,
setState: jest.fn(),
clearState: jest.fn(),
}))
const mockNavigate = jest.fn()
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as any),
useNavigate: () => mockNavigate,
}))
describe('given a component to show the clusters list', () => {
describe('when the clusters list is available', () => {
beforeEach(() => {
;(ListClusters as jest.Mock).mockResolvedValue(mockClusters)
mockNavigate.mockReset()
})
it('should render the clusters', async () => {
const {getByText} = await waitFor(() =>
render(
,
),
)
expect(getByText('test-cluster')).toBeTruthy()
expect(getByText('CREATE COMPLETE')).toBeTruthy()
expect(getByText('3.1.4')).toBeTruthy()
})
describe('when the user selects a cluster', () => {
it('should populate the split panel', async () => {
const output = await waitFor(() =>
render(
,
),
)
await userEvent.click(output.getByRole('radio'))
expect(mockNavigate).toHaveBeenCalledWith('/clusters/test-cluster')
})
})
describe('when the user clicks on "Create Cluster" button', () => {
it('should redirect to configure', async () => {
const output = await waitFor(() =>
render(
,
),
)
await userEvent.click(output.getByRole('button', {name: 'Create'}))
expect(mockNavigate).toHaveBeenCalledWith('/configure')
})
})
})
describe('when there are no clusters available', () => {
beforeEach(() => {
;(ListClusters as jest.Mock).mockResolvedValue([])
})
it('should show the empty state', async () => {
const {getByText} = await waitFor(() =>
render(
,
),
)
expect(getByText('No clusters to display')).toBeTruthy()
})
})
})
describe('Given a list of clusters', () => {
beforeEach(() => jest.resetAllMocks())
describe('when a cluster is selected and the list is updated', () => {
describe('when the cluster has a new status', () => {
it('should be saved', () => {
onClustersUpdate(
'test-cluster',
mockClusters,
ClusterStatus.CreateInProgress,
mockNavigate,
)
expect(setState).toHaveBeenCalledWith(
['app', 'clusters', 'selectedStatus'],
ClusterStatus.CreateComplete,
)
})
})
describe('when the cluster has the same status', () => {
it('should not be updated', () => {
onClustersUpdate(
'test-cluster',
mockClusters,
ClusterStatus.CreateComplete,
mockNavigate,
)
expect(setState).not.toHaveBeenCalled()
})
})
describe('when a cluster is deleted', () => {
beforeEach(() => {
onClustersUpdate(
'test-cluster',
mockClusters,
ClusterStatus.DeleteInProgress,
mockNavigate,
)
})
it('should become unselected', () => {
expect(clearState).toHaveBeenCalledWith(['app', 'clusters', 'selected'])
})
it('should navigate to the clusters list', () => {
expect(mockNavigate).toHaveBeenCalledWith('/clusters')
})
})
})
})