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
147 changes: 85 additions & 62 deletions redisinsight/ui/src/pages/rdi/statistics/StatisticsPage.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ import { cloneDeep } from 'lodash'
import React from 'react'
import reactRouterDom from 'react-router-dom'

import {
rdiPipelineStatusSelector,
getPipelineStatus,
} from 'uiSrc/slices/rdi/pipeline'
import { getPipelineStatus } from 'uiSrc/slices/rdi/pipeline'
import {
getStatistics,
rdiStatisticsSelector,
Expand All @@ -25,9 +22,60 @@ import {
} from 'uiSrc/utils/test-utils'
import { PageNames, Pages } from 'uiSrc/constants'
import { setLastPageContext } from 'uiSrc/slices/app/context'
import { RdiPipelineStatus } from 'uiSrc/slices/interfaces'

import StatisticsPage from './StatisticsPage'

const CONNECTIONS_DATA = {
connections: {
Connection1: {
status: 'good',
type: 'type1',
host: 'Redis-Cloud',
port: 12000,
database: 'admin',
user: 'admin',
},
},
dataStreams: {
Stream1: {
total: 35,
pending: 2,
inserted: 2530,
updated: 65165,
deleted: 1,
filtered: 0,
rejected: 5,
deduplicated: 0,
lastArrival: '1 Hour',
},
},
processingPerformance: {
totalBatches: 3427,
batchSizeAvg: '0.93',
readTimeAvg: '13',
processTimeAvg: '24',
ackTimeAvg: '6.2',
totalTimeAvg: '6.1',
recPerSecAvg: 110,
},
rdiPipelineStatus: {
rdiVersion: '2.0',
address: '172.17.0.2:12006',
runStatus: 'Started',
syncMode: 'Streaming',
},
clients: {
9875: {
addr: '172.16.0.2:62356',
name: 'redis-di-cli',
ageSec: 100,
idleSec: 2,
user: 'default',
},
},
}

jest.mock('uiSrc/slices/rdi/instances', () => ({
...jest.requireActual('uiSrc/slices/rdi/instances'),
connectedInstanceSelector: jest.fn().mockReturnValue({
Expand Down Expand Up @@ -57,55 +105,8 @@ jest.mock('uiSrc/slices/rdi/statistics', () => ({
rdiStatisticsSelector: jest.fn().mockReturnValue({
loading: false,
results: {
data: {
connections: {
Connection1: {
status: 'good',
type: 'type1',
host: 'Redis-Cloud',
port: 12000,
database: 'admin',
user: 'admin',
},
},
dataStreams: {
Stream1: {
total: 35,
pending: 2,
inserted: 2530,
updated: 65165,
deleted: 1,
filtered: 0,
rejected: 5,
deduplicated: 0,
lastArrival: '1 Hour',
},
},
processingPerformance: {
totalBatches: 3427,
batchSizeAvg: '0.93',
readTimeAvg: '13',
processTimeAvg: '24',
ackTimeAvg: '6.2',
totalTimeAvg: '6.1',
recPerSecAvg: 110,
},
rdiPipelineStatus: {
rdiVersion: '2.0',
address: '172.17.0.2:12006',
runStatus: 'Started',
syncMode: 'Streaming',
},
clients: {
9875: {
addr: '172.16.0.2:62356',
name: 'redis-di-cli',
ageSec: 100,
idleSec: 2,
user: 'default',
},
},
},
status: 'success',
data: CONNECTIONS_DATA
},
}),
}))
Expand Down Expand Up @@ -134,23 +135,45 @@ describe('StatisticsPage', () => {
expect(document.title).toBe('name - Pipeline Status')
})

it('renders null when statisticsData is not available', () => {
it('renders null when statisticsResults is not available', () => {
;(rdiStatisticsSelector as jest.Mock).mockReturnValueOnce({
data: null,
loading: false,
results: null,
})
const { container } = render(<StatisticsPage />)
expect(container.firstChild).toBeNull()
})

it('renders the empty state when pipeline data is empty', () => {
;(rdiPipelineStatusSelector as jest.Mock).mockReturnValueOnce({
data: {
components: {},
pipelines: {},
it('renders the empty state when statistics status is not success', () => {
;(rdiStatisticsSelector as jest.Mock).mockReturnValueOnce({
loading: false,
results: {
status: null,
data: CONNECTIONS_DATA
},
})
const { getByText } = render(<StatisticsPage />)
expect(getByText('No pipeline deployed yet')).toBeInTheDocument()
render(<StatisticsPage />)
expect(screen.getByTestId('empty-pipeline')).toBeInTheDocument()
})

it('renders the empty state when statistics status is success but data is missing', () => {
;(rdiStatisticsSelector as jest.Mock).mockReturnValueOnce({
loading: false,
results: {
status: RdiPipelineStatus.Success,
data: null,
},
})
render(<StatisticsPage />)
expect(screen.getByTestId('empty-pipeline')).toBeInTheDocument()
})

it('renders statistics sections when status is success and data exists', () => {
render(<StatisticsPage />)

// Check that statistics sections are rendered instead of empty state
expect(screen.queryByTestId('empty-pipeline')).not.toBeInTheDocument()
expect(screen.getByTestId('processing-performance-info-refresh-btn')).toBeInTheDocument()
})

it('should call proper telemetry on page view', () => {
Expand Down
15 changes: 5 additions & 10 deletions redisinsight/ui/src/pages/rdi/statistics/StatisticsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { get } from 'lodash'
import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useParams } from 'react-router-dom'
import { EuiLoadingSpinner, EuiText } from '@elastic/eui'

import { connectedInstanceSelector } from 'uiSrc/slices/rdi/instances'
import {
getPipelineStatusAction,
rdiPipelineStatusSelector,
} from 'uiSrc/slices/rdi/pipeline'
import { getPipelineStatusAction } from 'uiSrc/slices/rdi/pipeline'
import {
fetchRdiStatistics,
rdiStatisticsSelector,
Expand All @@ -22,7 +18,7 @@ import {
import { formatLongName, Nullable, setTitle } from 'uiSrc/utils'
import { setLastPageContext } from 'uiSrc/slices/app/context'
import { PageNames } from 'uiSrc/constants'
import { IPipelineStatus, PipelineStatus } from 'uiSrc/slices/interfaces'
import { IRdiStatistics, RdiPipelineStatus } from 'uiSrc/slices/interfaces'
import Clients from './clients'
import DataStreams from './data-streams'
import Empty from './empty'
Expand All @@ -32,8 +28,8 @@ import TargetConnections from './target-connections'

import styles from './styles.module.scss'

const isPipelineDeployed = (data: Nullable<IPipelineStatus>) =>
get(data, ['pipelines', 'default', 'status']) === PipelineStatus.Ready
const shouldShowStatistics = (data: Nullable<IRdiStatistics>) =>
data?.status === RdiPipelineStatus.Success && !!data?.data

const StatisticsPage = () => {
const [pageLoading, setPageLoading] = useState(true)
Expand All @@ -46,7 +42,6 @@ const StatisticsPage = () => {
const { name: connectedRdiInstanceName } = useSelector(
connectedInstanceSelector,
)
const { data: statusData } = useSelector(rdiPipelineStatusSelector)
const rdiInstanceName = formatLongName(connectedRdiInstanceName, 33, 0, '...')
setTitle(`${rdiInstanceName} - Pipeline Status`)

Expand Down Expand Up @@ -131,7 +126,7 @@ const StatisticsPage = () => {
<EuiLoadingSpinner size="xl" />
</div>
)}
{!isPipelineDeployed(statusData) ? (
{!shouldShowStatistics(statisticsResults) ? (
// TODO add loader
<Empty rdiInstanceId={rdiInstanceId} />
) : (
Expand Down
4 changes: 2 additions & 2 deletions redisinsight/ui/src/pages/rdi/statistics/empty/Empty.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const Empty = ({ rdiInstanceId }: Props) => {
const history = useHistory()

return (
<Panel data-testid="empty-pipeline">
<div className={styles.emptyPipelineContainer}>
<Panel>
<div className={styles.emptyPipelineContainer} data-testid="empty-pipeline">
<EuiImage src={EmptyPipelineIcon} alt="empty" size="s" />
<Spacer size="xl" />
<EuiText>No pipeline deployed yet</EuiText>
Expand Down
Loading