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
8 changes: 4 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ module.exports = {
],
coverageThreshold: {
global: {
statements: 70,
branches: 50,
functions: 60,
lines: 72,
statements: 77,
branches: 55,
functions: 65,
lines: 75,
},
// './redisinsight/ui/src/slices/**/*.ts': {
// statements: 90,
Expand Down
48 changes: 46 additions & 2 deletions redisinsight/__mocks__/monacoMock.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,49 @@
import * as React from 'react';
import React, { useEffect } from 'react';

export default function MonacoEditor(props) {
return <div {...props} data-testid="monaco"/>;
useEffect(() => {
props.editorDidMount && props.editorDidMount(
// editor
{
addCommand: jest.fn(),
getContribution: jest.fn(),
onKeyDown: jest.fn(),
onMouseDown: jest.fn(),
addAction: jest.fn(),
getAction: jest.fn(),
deltaDecorations: jest.fn(),
createContextKey: jest.fn(),
focus: jest.fn(),
onDidChangeCursorPosition: jest.fn(),
executeEdits: jest.fn()
},
// monaco
{
Range: jest.fn().mockImplementation(() => { return {} }),
languages: {
getLanguages: jest.fn(),
register: jest.fn(),
registerCompletionItemProvider: jest.fn().mockReturnValue({
dispose: jest.fn()
}),
registerSignatureHelpProvider: jest.fn().mockReturnValue({
dispose: jest.fn()
}),
setLanguageConfiguration: jest.fn(),
setMonarchTokensProvider: jest.fn(),
},
KeyMod: {},
KeyCode: {}
})
}, [])
return <input {...props} data-testid="monaco"/>;
}

export const languages = {
CompletionItemKind: {
Function: 1
},
CompletionItemInsertTextRule: {
InsertAsSnippet: 4
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { cloneDeep } from 'lodash'
import React from 'react'
import { instance, mock } from 'ts-mockito'
import { PluginEvents } from 'uiSrc/plugins/pluginEvents'
import { pluginApi } from 'uiSrc/services/PluginAPI'
import { cleanup, mockedStore, render } from 'uiSrc/utils/test-utils'
import QueryCardCliPlugin, { Props } from './QueryCardCliPlugin'

Expand All @@ -13,6 +15,28 @@ beforeEach(() => {
store.clearActions()
})

jest.mock('uiSrc/services/PluginAPI', () => ({
pluginApi: {
onEvent: jest.fn()
}
}))

jest.mock('uiSrc/slices/app/plugins', () => ({
...jest.requireActual('uiSrc/slices/app/plugins'),
appPluginsSelector: jest.fn().mockReturnValue({
visualizations: [
{
id: '1',
uniqId: '1',
name: 'test',
plugin: '',
activationMethod: 'render',
matchCommands: ['*'],
}
]
}),
}))

jest.mock('uiSrc/services', () => ({
...jest.requireActual('uiSrc/services'),
sessionStorageService: {
Expand All @@ -25,4 +49,20 @@ describe('QueryCardCliPlugin', () => {
it('should render', () => {
expect(render(<QueryCardCliPlugin {...instance(mockedProps)} />)).toBeTruthy()
})

it('should subscribes on events', () => {
const onEventMock = jest.fn();

(pluginApi.onEvent as jest.Mock).mockImplementation(onEventMock)

render(<QueryCardCliPlugin {...instance(mockedProps)} id="1" />)

expect(onEventMock).toBeCalledWith(expect.any(String), PluginEvents.heightChanged, expect.any(Function))
expect(onEventMock).toBeCalledWith(expect.any(String), PluginEvents.loaded, expect.any(Function))
expect(onEventMock).toBeCalledWith(expect.any(String), PluginEvents.error, expect.any(Function))
expect(onEventMock).toBeCalledWith(expect.any(String), PluginEvents.setHeaderText, expect.any(Function))
expect(onEventMock).toBeCalledWith(expect.any(String), PluginEvents.executeRedisCommand, expect.any(Function))
expect(onEventMock).toBeCalledWith(expect.any(String), PluginEvents.getState, expect.any(Function))
expect(onEventMock).toBeCalledWith(expect.any(String), PluginEvents.setState, expect.any(Function))
})
})
14 changes: 7 additions & 7 deletions redisinsight/ui/src/components/query/Query/Query.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ const Query = (props: Props) => {
query = '',
activeMode,
resultsMode,
setQuery,
onKeyDown,
onSubmit,
setQueryEl,
setIsCodeBtnDisabled = () => { },
onQueryChangeMode,
onChangeGroupMode
setQuery = () => {},
onKeyDown = () => {},
onSubmit = () => {},
setQueryEl = () => {},
setIsCodeBtnDisabled = () => {},
onQueryChangeMode = () => {},
onChangeGroupMode = () => {}
} = props
let contribution: Nullable<ISnippetController> = null
const [isDedicatedEditorOpen, setIsDedicatedEditorOpen] = useState(false)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,44 @@
import React from 'react'
import { instance, mock } from 'ts-mockito'
import { ITableColumn } from 'uiSrc/components/virtual-table/interfaces'
import { render } from 'uiSrc/utils/test-utils'
import VirtualGrid from './VirtualGrid'
import { IProps } from './interfaces'

const mockedProps = mock<IProps>()

const columns: ITableColumn[] = [
{
id: 'name',
label: 'Member',
staySearchAlwaysOpen: true,
initialSearchValue: '',
truncateText: true,
minWidth: 50
},
]

const items = ['member1', 'member2']

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

it('should render rows', () => {
expect(
render(
<VirtualGrid
{...instance(mockedProps)}
items={items}
columns={columns}
loading={false}
loadMoreItems={jest.fn()}
totalItemsCount={items.length}
/>
)
).toBeTruthy()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface Props {
}

const AckPopover = (props: Props) => {
const { id, isOpen, closePopover, showPopover, acknowledge } = props
const { id, isOpen, closePopover = () => {}, showPopover = () => {}, acknowledge = () => {} } = props
return (
<EuiPopover
key={id}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ describe('SearchDatabasesList', () => {
expect(render(<SearchDatabasesList />)).toBeTruthy()
})

it.skip('should call loadInstancesSuccess with after typing', async () => {
it('should call loadInstancesSuccess with after typing', async () => {
const state: RootState = store.getState();
(useSelector as jest.Mock).mockImplementation((callback: (arg0: RootState) => RootState) => callback({
...state,
Expand All @@ -79,9 +79,10 @@ describe('SearchDatabasesList', () => {
)
})

newInstancesMock[0].visible = false
newInstancesMock[1].visible = false

const expectedActions = [loadInstancesSuccess(newInstancesMock)]
expect(storeMock.getActions()).toEqual(expect.arrayContaining(expectedActions))
expect(storeMock.getActions()).toEqual(expectedActions)
})
})
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import React from 'react'
import { cloudSelector } from 'uiSrc/slices/instances/cloud'
import { render } from 'uiSrc/utils/test-utils'

import RedisCloudSubscriptionsPage from './RedisCloudSubscriptionsPage'

jest.mock('uiSrc/slices/instances/cloud', () => ({
...jest.requireActual('uiSrc/slices/instances/cloud'),
cloudSelector: jest.fn().mockReturnValue({
...jest.requireActual('uiSrc/slices/instances/cloud').initialState
})
}))

/**
* RedisCloudSubscriptionsPage tests
*
Expand All @@ -12,4 +20,26 @@ describe('RedisCloudSubscriptionsPage', () => {
it('should render', () => {
expect(render(<RedisCloudSubscriptionsPage />)).toBeTruthy()
})

it('should render with subscriptions', () => {
const cloudSelectorMock = jest.fn().mockReturnValue({
credentials: null,
loading: false,
error: '',
loaded: { instances: false },
account: { error: '', data: [] },
subscriptions: [
{
id: 123,
name: 'name',
numberOfDatabases: 123,
provider: 'provider',
region: 'region',
status: 'active',
},
]
})
cloudSelector.mockImplementation(cloudSelectorMock)
expect(render(<RedisCloudSubscriptionsPage />)).toBeTruthy()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react'
import Router from 'uiSrc/Router'
import { render } from 'uiSrc/utils/test-utils'
import RouteWithSubRoutes from 'uiSrc/utils/routerWithSubRoutes'
import ROUTES from 'uiSrc/components/main-router/constants/commonRoutes'

import ProtectedRoute from './ProtectedRoute'

describe('ProtectedRoute', () => {
it('should render', () => {
expect(render(
<Router>
<ProtectedRoute>
<RouteWithSubRoutes
key={1}
{...ROUTES[0]}
/>
</ProtectedRoute>
</Router>
))
.toBeTruthy()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react'
import HtmlToJsxString from '../formatter/HtmlToJsxString'

describe('HtmlToJsxString', () => {
it('should return proper string', async () => {
const div = (<div />)
const formatter = new HtmlToJsxString()
const result = await formatter.format(div)
expect(result).toEqual(String(div))
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { unified } from 'unified'
import MarkdownToJsxString from '../formatter/MarkdownToJsxString'

jest.mock('unified')
describe('MarkdownToJsxString', () => {
it('should call process', async () => {
// mock implementation
const useProcessMock = jest.fn().mockImplementation(() => Promise.resolve())
function useMock() {
return { use: useMock, process: useProcessMock }
}
(unified as jest.Mock).mockImplementation(() => ({
use: useMock
}))

await (new MarkdownToJsxString()).format('')
expect(useProcessMock).toBeCalled()
})
})
27 changes: 1 addition & 26 deletions redisinsight/ui/src/services/hooks/useWebworkers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState, useRef } from 'react'
import { useState } from 'react'
import { Nullable } from 'uiSrc/utils'

const workerHandler = (fn: (...args: any) => any) => {
Expand All @@ -7,31 +7,6 @@ const workerHandler = (fn: (...args: any) => any) => {
}
}

export const useWebworker = (fn: (...args: any) => any) => {
const [result, setResult] = useState<Nullable<any>>(null)
const [error, setError] = useState<Nullable<ErrorEvent>>(null)

const workerRef = useRef<Nullable<Worker>>(null)

useEffect(() => {
const worker = new Worker(
URL.createObjectURL(new Blob([`(${workerHandler})(${fn})`]))
)
workerRef.current = worker
worker.onmessage = (event) => setResult(event.data)
worker.onerror = (error: ErrorEvent) => setError(error)
return () => {
worker.terminate()
}
}, [fn])

return {
result,
error,
run: (value:any) => workerRef.current?.postMessage(value),
}
}

export const useDisposableWebworker = (fn: (...args: any) => any) => {
const [result, setResult] = useState<Nullable<any>>(null)
const [error, setError] = useState<Nullable<ErrorEvent>>(null)
Expand Down
24 changes: 24 additions & 0 deletions redisinsight/ui/src/services/tests/PluguinApi.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { pluginApi } from 'uiSrc/services/PluginAPI'

describe('PluginApi', () => {
it('should subscribe on event and receive data after emit', () => {
const mockCallback = jest.fn()
const data = { data: 'some data' }

pluginApi.onEvent('id1', 'someEvent', mockCallback)
pluginApi.sendEvent('id1', 'someEvent', data)

expect(mockCallback).toBeCalledWith(data)
})

it('should subscribe on event and not receive data after unregister all subscriptions and emit', () => {
const mockCallback = jest.fn()
const data = { data: 'some data' }

pluginApi.onEvent('id1', 'someEvent', mockCallback)
pluginApi.unregisterSubscriptions()
pluginApi.sendEvent('id1', 'someEvent', data)

expect(mockCallback).not.toBeCalled()
})
})
Loading