Skip to content

Commit

Permalink
#RI-31 - Logical databases
Browse files Browse the repository at this point in the history
  • Loading branch information
egor-zalenski committed Dec 10, 2024
1 parent 6577d79 commit ca02933
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import React from 'react'
import { mock } from 'ts-mockito'
import { Mock } from 'vitest'

import { KeyTypes, SelectedKeyActionType } from 'uiSrc/constants'
import * as utils from 'uiSrc/utils'
import { apiService, vscodeApi } from 'uiSrc/services'
import * as useContext from 'uiSrc/store/hooks/use-context/useContext'
import * as useSelectedKeyStore from 'uiSrc/store/hooks/use-selected-key-store/useSelectedKeyStore'
import { Database } from 'uiSrc/store'
import { constants, fireEvent, render, waitForStack } from 'testSrc/helpers'
import { LogicalDatabaseWrapper, Props } from './LogicalDatabaseWrapper'
import * as useKeys from '../../hooks/useKeys'

const mockDatabase = constants.DATABASE
const mockedProps = {
...mock<Props>(<div />),
database: mockDatabase,
}
beforeEach(() => {
apiService.get = vi.fn().mockResolvedValue({ status: 200, data: {} })
})

vi.spyOn(utils, 'sendEventTelemetry')
vi.spyOn(vscodeApi, 'postMessage')

const fnMock = vi.fn()
const addKeyIntoTreeMock = vi.fn()
const deleteKeyFromTreeMock = vi.fn();
(vi.spyOn(useKeys, 'useKeysApi') as Mock).mockImplementation(() => ({
fetchPatternKeysAction: fnMock,
setDatabaseId: fnMock,
setDatabaseIndex: fnMock,
addKeyIntoTree: addKeyIntoTreeMock,
deleteKeyFromTree: deleteKeyFromTreeMock,
}))
const setKeysTreeSortMock = vi.fn()
const resetKeysTreeMock = vi.fn();
(vi.spyOn(useContext, 'useContextApi') as Mock).mockImplementation(() => ({
setKeysTreeSort: setKeysTreeSortMock,
resetKeysTree: resetKeysTreeMock,
}))

describe('LogicalDatabaseWrapper', () => {
it('should render', () => {
expect(render(<LogicalDatabaseWrapper {...mockedProps} />)).toBeTruthy()
})

describe('selectedKeyAction', () => {
const setSelectedKeyActionMock = vi.fn()
const setSelectedKeyMock = vi.fn()
const spySelectedKey = vi.spyOn(useSelectedKeyStore, 'useSelectedKeyStore') as Mock

const selectedKeyAction = {
type: SelectedKeyActionType.Removed,
database: {
id: constants.DATABASE_ID,
},
keyInfo: {
key: constants.KEY_NAME_1,
keyType: KeyTypes.Hash,
},
}

spySelectedKey.mockImplementation(() => ({
setSelectedKeyAction: setSelectedKeyActionMock,
setSelectedKey: setSelectedKeyMock,
selectedKeyAction,
}))

afterEach(() => {
vi.restoreAllMocks()
})

it('should call deleteKeyFromTree and setSelectedKeyAction action after if selected key action is Removed', async () => {
render(<LogicalDatabaseWrapper {...mockedProps} database={{ id: constants.DATABASE_ID } as Database} />)

await waitForStack()

expect(setSelectedKeyActionMock).toBeCalledWith(null)
expect(deleteKeyFromTreeMock).toBeCalledWith(constants.KEY_NAME_1)
})

it('should not call any mocks if database is not equal', async () => {
render(<LogicalDatabaseWrapper {...mockedProps} database={{ id: '123123' } as Database} />)

await waitForStack()

expect(setSelectedKeyActionMock).not.toBeCalled()
expect(deleteKeyFromTreeMock).not.toBeCalled()
expect(addKeyIntoTreeMock).not.toBeCalled()
})

it('should not call any mocks if type is not defined', async () => {
render(<LogicalDatabaseWrapper {...mockedProps} database={{ id: constants.DATABASE_ID } as Database} />)

await waitForStack()

expect(setSelectedKeyActionMock).not.toBeCalled()
expect(deleteKeyFromTreeMock).not.toBeCalled()
expect(addKeyIntoTreeMock).not.toBeCalled()
})

it('should call addKeyIntoTree action after if selected key action is Added', async () => {
const spySelectedKey = vi.spyOn(useSelectedKeyStore, 'useSelectedKeyStore') as Mock

const setSelectedKeyActionMock = vi.fn()
const setSelectedKeyMock = vi.fn()

spySelectedKey.mockImplementation(() => ({
selectedKeyAction: {
...selectedKeyAction,
type: SelectedKeyActionType.Added,
},
setSelectedKeyAction: setSelectedKeyActionMock,
setSelectedKey: setSelectedKeyMock,
}))

render(<LogicalDatabaseWrapper {...mockedProps} database={{ id: constants.DATABASE_ID } as Database} />)

expect(setSelectedKeyMock).toBeCalledWith({ name: constants.KEY_NAME_1 })
expect(setSelectedKeyActionMock).toBeCalledWith(null)
expect(deleteKeyFromTreeMock).not.toBeCalled()
expect(addKeyIntoTreeMock).not.toBeCalled()
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useEffect, useState } from 'react'
import cx from 'classnames'
import { useShallow } from 'zustand/react/shallow'

import { SelectedKeyActionType } from 'uiSrc/constants'
import { Database, useSelectedKeyStore } from 'uiSrc/store'
import { useKeysApi } from '../../hooks/useKeys'

export interface Props {
database: Database
dbIndex?: number
children: React.ReactNode
}

export const LogicalDatabaseWrapper = ({ children, database }: Props) => {
const { id: dbId, db: dbIndex } = database
const { selectedKeyAction, setSelectedKeyAction, setSelectedKey } = useSelectedKeyStore(useShallow((state) => ({
selectedKeyAction: state.action,
setSelectedKeyAction: state.setSelectedKeyAction,
setSelectedKey: state.processSelectedKeySuccess,
})))

const [renderChildren, setRenderChildren] = useState<boolean>(false)

const keysApi = useKeysApi()

useEffect(() => {
keysApi.setDatabaseId(dbId)
keysApi.setDatabaseIndex(dbIndex ?? 0)

setRenderChildren(true)
}, [])

useEffect(() => {
const { type, keyInfo, database: databaseAction } = selectedKeyAction || {}
const { key, keyType, newKey } = keyInfo || {}
const { id: databaseId, db: databaseIndex } = databaseAction || {}

if (!type || (databaseId! + databaseIndex !== dbId + dbIndex)) {
return
}

switch (type) {
case SelectedKeyActionType.Added:
keysApi.addKeyIntoTree(key!, keyType!)
setSelectedKey({ name: key! })
break
case SelectedKeyActionType.Removed:
keysApi.deleteKeyFromTree(key!)
break
case SelectedKeyActionType.Renamed:
keysApi.editKeyName(key!, newKey!)
break
default:
break
}
setSelectedKeyAction(null)
}, [selectedKeyAction])

return (
<div
className={cx('flex w-full flex-col')}
data-testid={`logical-database-${dbId}-${dbIndex}`}
>
{renderChildren && children}
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { LogicalDatabaseWrapper } from './LogicalDatabaseWrapper'
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.databaseNameWrapper {
@apply flex pl-3.5 cursor-pointer text-ellipsis whitespace-nowrap overflow-hidden items-center;
}

.databaseName {
@apply text-ellipsis whitespace-nowrap overflow-hidden flex items-center;
}

.icon {
@apply mr-2 w-[14px] h-[14px] min-w-[14px] ml-[3px];

&Nested {
@apply m-0;
}
}

0 comments on commit ca02933

Please sign in to comment.