Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from 'uiSrc/utils/test-utils'
import { loadInstancesSuccess } from 'uiSrc/slices/instances/instances'
import { RootState, store } from 'uiSrc/slices/store'
import { Instance } from 'uiSrc/slices/interfaces'
import { ConnectionType, Instance } from 'uiSrc/slices/interfaces'
import SearchDatabasesList from './SearchDatabasesList'

jest.mock('react-redux', () => ({
Expand All @@ -20,14 +20,15 @@ jest.mock('react-redux', () => ({
}))

let storeMock: typeof mockedStore
const instancesMock: Instance[] = [
const connectedInstancesMock: Instance[] = [
{
id: '1',
name: 'local',
host: 'localhost',
port: 6379,
visible: true,
modules: [],
connectionType: ConnectionType.Sentinel,
lastConnection: new Date(),
tags: [
{
Expand All @@ -47,19 +48,56 @@ const instancesMock: Instance[] = [
port: 6379,
visible: true,
modules: [],
connectionType: ConnectionType.Cluster,
lastConnection: new Date(),
tags: [],
version: '',
},
}
]

beforeEach(() => {
cleanup()
storeMock = cloneDeep(mockedStore)
storeMock.clearActions()

const state: RootState = store.getState()
const otherInstancesMock: Instance[] = [
/*
Reasoning behind the mock data:
- The 'not_connected' instance simulates a Redis instance that is not currently connected.
- The 'some_future_unrecognized_connection_type' instance represents a Redis instance with a connection type that is not
recognized by the current application logic (e.g something is added in future and this part of the application is not yet aware of it).
*/
{
id: '3',
name: 'not_connected',
host: 'not_connected',
port: 6379,
visible: true,
modules: [],
connectionType: 'NOT CONNECTED' as any,
tags: [],
version: '',
},
{
id: '4',
name: 'some_future_unrecognized_connection_type',
host: 'some_future_unrecognized_connection_type',
port: 6379,
visible: true,
modules: [],
connectionType: 'UNRECOGNIZED' as any,
tags: [],
version: '',
},
{
id: '5',
name: 'undefined_connection_type',
host: 'undefined_connection_type',
port: 6379,
visible: true,
modules: [],
connectionType: undefined,
tags: [],
version: '',
}
]

const mockInitialState = (state: RootState, instances: Instance[], options?: { selectedTags?: Set<string> }) => {
;(useSelector as jest.Mock).mockImplementation(
(callback: (arg0: RootState) => RootState) =>
callback({
Expand All @@ -68,63 +106,87 @@ beforeEach(() => {
...state.connections,
instances: {
...state.connections.instances,
data: instancesMock,
data: instances,
},
tags: {
...state.connections.tags,
selectedTags: new Set(['env:prod']),
selectedTags: options?.selectedTags ?? state.connections.tags?.selectedTags,
},
},
}),
)
}

const simulateUserTypedInSearchBox = async (value: string) => {
await act(() => {
fireEvent.change(screen.getByTestId('search-database-list'), {
target: { value },
})
})
}

beforeEach(() => {
cleanup()
storeMock = cloneDeep(mockedStore)
storeMock.clearActions()
})

describe('SearchDatabasesList', () => {
it('should render', () => {
mockInitialState(
store.getState(),
connectedInstancesMock
)
expect(render(<SearchDatabasesList />)).toBeTruthy()
})

it('should call loadInstancesSuccess with after typing', async () => {
const state: RootState = store.getState()
;(useSelector as jest.Mock).mockImplementation(
(callback: (arg0: RootState) => RootState) =>
callback({
...state,
connections: {
...state.connections,
instances: {
...state.connections.instances,
data: instancesMock,
},
},
}),
it.each([
{
description: 'with connected instances',
instancesMock: connectedInstancesMock,
expectedInstances: [
{ ...connectedInstancesMock[0], visible: false },
{ ...connectedInstancesMock[1], visible: false }
]
},
{
description: 'with other than connected connectionType',
instancesMock: otherInstancesMock,
expectedInstances: [
{ ...otherInstancesMock[0], visible: false },
{ ...otherInstancesMock[1], visible: false },
{ ...otherInstancesMock[2], visible: false }
]
}
])('should call loadInstancesSuccess with all instances hidden after typing value not matching anything ($description)', async ({ instancesMock, expectedInstances }) => {
mockInitialState(
store.getState(),
instancesMock
)

const newInstancesMock = [...instancesMock]
render(<SearchDatabasesList />)

await act(() => {
fireEvent.change(screen.getByTestId('search-database-list'), {
target: { value: 'test' },
})
})

newInstancesMock[0].visible = false
newInstancesMock[1].visible = false
await simulateUserTypedInSearchBox('value_which_matches_nothing')

const expectedActions = [loadInstancesSuccess(newInstancesMock)]
const expectedActions = [loadInstancesSuccess(expectedInstances)]
expect(storeMock.getActions()).toEqual(expectedActions)
})

it('should call loadInstancesSuccess after selected tags state changes', async () => {
const newInstancesMock = [
{ ...instancesMock[0], visible: true },
{ ...instancesMock[1], visible: false },
it('should call loadInstancesSuccess with not matching instances hidden when selected tags in state are provided', async () => {
mockInitialState(
store.getState(),
connectedInstancesMock,
{ selectedTags: new Set(['env:prod']) }
)

const expectedInstancesAfterRendering = [
{ ...connectedInstancesMock[0], visible: true },
{ ...connectedInstancesMock[1], visible: false }
]

render(<SearchDatabasesList />)

const expectedActions = [loadInstancesSuccess(newInstancesMock)]
const expectedActions = [loadInstancesSuccess(expectedInstancesAfterRendering)]
expect(storeMock.getActions()).toEqual(expectedActions)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const SearchDatabasesList = () => {
item.host?.toString()?.indexOf(value) !== -1 ||
item.port?.toString()?.indexOf(value) !== -1 ||
(item.connectionType &&
CONNECTION_TYPE_DISPLAY[item.connectionType] &&
CONNECTION_TYPE_DISPLAY[item.connectionType]
?.toLowerCase()
?.indexOf(value) !== -1) ||
Expand Down
Loading