Skip to content
Snippets Groups Projects
Commit f0cd4a11 authored by Adel LAKHDAR's avatar Adel LAKHDAR
Browse files

Merge branch '681-add-tests-for-analysis' into 'dev'

test(analysis): add tests for Comparison & FPI

See merge request !1176
parents ee2b97f1 b0aaa9a3
Branches
Tags
2 merge requests!12413.1 Release,!1176test(analysis): add tests for Comparison & FPI
import { act, render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { FluidType } from 'enums'
import { PerformanceIndicator } from 'models'
import React from 'react'
import { Provider } from 'react-redux'
import { setPeriod } from 'store/analysis/analysis.slice'
import { createMockEcolyoStore, mockAnalysisState } from 'tests/__mocks__/store'
import Comparison from './Comparison'
jest.mock('services/consumption.service', () => {
return jest.fn().mockImplementation(() => ({
fetchAvgTemperature: jest.fn().mockResolvedValue(25.3),
getPerformanceIndicators: jest.fn().mockResolvedValue([]),
}))
})
const mockFluidsWithData = [
FluidType.ELECTRICITY,
FluidType.WATER,
FluidType.GAS,
]
const mockPerformanceIndicators: PerformanceIndicator[] = [
{
compareValue: 203.49,
percentageVariation: 0.12261044768784712,
value: 178.54,
},
{
compareValue: 7926.82,
percentageVariation: 0.020542916327102145,
value: 7763.98,
},
{
compareValue: 1316.46,
percentageVariation: -0.0009191316105312541,
value: 1317.67,
},
]
describe('Comparison component', () => {
it('renders loading state', async () => {
render(
<Provider store={createMockEcolyoStore()}>
<Comparison fluidsWithData={[]} monthPerformanceIndicators={[]} />
</Provider>
)
await waitFor(() => {
expect(screen.getByRole('progressbar')).toBeInTheDocument()
})
})
it('switches between monthly and yearly periods', async () => {
const store = createMockEcolyoStore({
analysis: { ...mockAnalysisState, period: 'month' },
global: {
fluidTypes: mockFluidsWithData,
},
})
const mockDispatch = jest.fn()
jest.spyOn(store, 'dispatch').mockImplementation(mockDispatch)
render(
<Provider store={store}>
<Comparison
fluidsWithData={mockFluidsWithData}
monthPerformanceIndicators={mockPerformanceIndicators}
/>
</Provider>
)
const yearlyButton = await screen.findByRole('button', {
name: `analysis.compare.year_tab`,
})
const monthlyButton = await screen.findByRole('button', {
name: `analysis.compare.month_tab`,
})
await act(async () => {
await userEvent.click(yearlyButton)
expect(mockDispatch).toHaveBeenCalledWith(setPeriod('year'))
})
await act(async () => {
await userEvent.click(monthlyButton)
expect(mockDispatch).toHaveBeenCalledWith(setPeriod('month'))
})
})
it('renders performance indicators and weather correctly', async () => {
const store = createMockEcolyoStore({
analysis: { ...mockAnalysisState },
global: {
fluidTypes: mockFluidsWithData,
},
})
render(
<Provider store={store}>
<Comparison
fluidsWithData={mockFluidsWithData}
monthPerformanceIndicators={mockPerformanceIndicators}
/>
</Provider>
)
const indicators = await screen.findAllByRole('button', { name: /fluid/i })
expect(indicators.length).toBe(mockFluidsWithData.length)
expect(
await screen.findByText('analysis.temperature_comparison.unit')
).toBeInTheDocument()
})
})
......@@ -57,7 +57,6 @@ const Comparison = ({
fluidsWithData.length * 84 +
(fluidsWithData.length - 1) * 10 +
NAVIGATION_HEIGHT
useEffect(() => {
let subscribed = true
async function populateData() {
......@@ -82,6 +81,7 @@ const Comparison = ({
setIsLoading(false)
}
}
populateData()
return () => {
subscribed = false
......
import { AnyAction } from '@reduxjs/toolkit'
import { act, render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { FluidType } from 'enums'
import { DateTime } from 'luxon'
import { PerformanceIndicator } from 'models'
import React from 'react'
import { Provider } from 'react-redux'
import { createMockEcolyoStore } from 'tests/__mocks__/store'
import FluidPerformanceIndicator from './FluidPerformanceIndicator'
const monthlyStore = createMockEcolyoStore()
const yearlyStore = createMockEcolyoStore({ analysis: { period: 'year' } })
const mockedNavigate = jest.fn()
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockedNavigate,
}))
const elecPerformanceIndicator: PerformanceIndicator = {
value: 100,
compareValue: 90,
percentageVariation: 0.1,
}
const waterPerformanceIndicator: PerformanceIndicator = {
value: 140,
compareValue: 150,
percentageVariation: -0.1,
}
const comparisonDate = DateTime.local(2024, 4, 15)
describe('FluidPerformanceIndicator component', () => {
it('should render elec indicators correctly and navigate on click', async () => {
const dispatchSpy = jest.spyOn(monthlyStore, 'dispatch')
const setShowCompareMock = jest.fn()
dispatchSpy.mockImplementation((action: AnyAction) => {
if (action.type === 'chart/setShowCompare') {
setShowCompareMock(action.payload)
}
return action
})
const { container } = render(
<Provider store={monthlyStore}>
<FluidPerformanceIndicator
performanceIndicator={elecPerformanceIndicator}
fluidType={FluidType.ELECTRICITY}
comparisonDate={comparisonDate}
/>
</Provider>
)
expect(screen.getByTestId('fluid-type-ELECTRICITY')).toHaveTextContent(
'ELECTRICITY'
)
expect(screen.getByTestId('fluid-value-ELECTRICITY')).toHaveTextContent(
'100'
)
expect(
screen.getByTestId('fluid-comparison-ELECTRICITY')
).toHaveTextContent('+10,00 % / avril 2024')
await act(async () => {
await userEvent.click(screen.getByRole('button'))
})
expect(mockedNavigate).toHaveBeenCalledWith('/consumption/electricity')
expect(dispatchSpy).toHaveBeenCalledWith({
type: 'chart/setShowCompare',
payload: false,
})
expect(container).toMatchSnapshot()
})
it('should render water indicators correctly and dispatch setShowCompare year on click', async () => {
const dispatchSpy = jest.spyOn(yearlyStore, 'dispatch')
const setShowCompareMock = jest.fn()
dispatchSpy.mockImplementation((action: AnyAction) => {
if (action.type === 'chart/setShowCompare') {
setShowCompareMock(action.payload)
}
return action
})
render(
<Provider store={yearlyStore}>
<FluidPerformanceIndicator
performanceIndicator={waterPerformanceIndicator}
fluidType={FluidType.WATER}
comparisonDate={comparisonDate}
/>
</Provider>
)
expect(screen.getByTestId('fluid-type-WATER')).toHaveTextContent('WATER')
expect(screen.getByTestId('fluid-value-WATER')).toHaveTextContent('140')
expect(screen.getByTestId('fluid-comparison-WATER')).toHaveTextContent(
'-10,00 % / avril 2024'
)
await act(async () => {
await userEvent.click(screen.getByRole('button'))
})
expect(mockedNavigate).toHaveBeenCalledWith('/consumption/water')
expect(dispatchSpy).toHaveBeenCalledWith({
type: 'chart/setShowCompare',
payload: true,
})
})
it('should render "no data" message when value is not available', () => {
const performanceIndicator: PerformanceIndicator = {
value: null,
compareValue: null,
percentageVariation: null,
}
const { container } = render(
<Provider store={monthlyStore}>
<FluidPerformanceIndicator
performanceIndicator={performanceIndicator}
fluidType={FluidType.WATER}
comparisonDate={comparisonDate}
/>
</Provider>
)
expect(container).toMatchSnapshot()
expect(
screen.getByText('performance_indicator.fpi.no_data')
).toBeInTheDocument()
})
})
import React from 'react'
import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
import { useI18n } from 'cozy-ui/transpiled/react/I18n'
import { FluidType, TimeStep } from 'enums'
import { DateTime } from 'luxon'
import { PerformanceIndicator } from 'models'
import React from 'react'
import { useNavigate } from 'react-router-dom'
import { setCurrentTimeStep, setShowCompare } from 'store/chart/chart.slice'
import { useAppDispatch, useAppSelector } from 'store/hooks'
......@@ -57,7 +57,10 @@ const FluidPerformanceIndicator = ({
return (
<button className="fpi" onClick={() => handleFluidClick(fluidType)}>
<StyledIcon icon={iconType} size={50} />
<div className="fpi-content">
<div
data-testid={`fluid-type-${FluidType[fluidType]}`}
className="fpi-content"
>
{!displayedValue && (
<div className="fpi-content-no-data">
<span>{t('performance_indicator.fpi.no_data')}</span>
......@@ -65,7 +68,10 @@ const FluidPerformanceIndicator = ({
)}
{displayedValue && (
<>
<div className="fpi-value">
<div
data-testid={`fluid-value-${FluidType[fluidType]}`}
className="fpi-value"
>
<span className="fpi-load">{displayedValue}</span>
<span className="fpi-unit">
{t(`FLUID.${FluidType[fluidType]}.UNIT`)}
......@@ -77,7 +83,10 @@ const FluidPerformanceIndicator = ({
</span>
)}
{performanceIndicator?.percentageVariation !== null && (
<div className="fpi-comparison">
<div
data-testid={`fluid-comparison-${FluidType[fluidType]}`}
className="fpi-comparison"
>
<span
className={`percent ${positive ? 'positive' : 'negative'}`}
>
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FluidPerformanceIndicator component should render "no data" message when value is not available 1`] = `
<div>
<button
class="fpi"
>
<svg
aria-hidden="true"
class="styles__icon___23x3R"
height="50"
width="50"
>
<use
xlink:href="#test-file-stub"
/>
</svg>
<div
class="fpi-content"
data-testid="fluid-type-WATER"
>
<div
class="fpi-content-no-data"
>
<span>
performance_indicator.fpi.no_data
</span>
</div>
</div>
</button>
</div>
`;
exports[`FluidPerformanceIndicator component should render elec indicators correctly and navigate on click 1`] = `
<div>
<button
class="fpi"
>
<svg
aria-hidden="true"
class="styles__icon___23x3R"
height="50"
width="50"
>
<use
xlink:href="#test-file-stub"
/>
</svg>
<div
class="fpi-content"
data-testid="fluid-type-ELECTRICITY"
>
<div
class="fpi-value"
data-testid="fluid-value-ELECTRICITY"
>
<span
class="fpi-load"
>
100,00
</span>
<span
class="fpi-unit"
>
FLUID.ELECTRICITY.UNIT
</span>
</div>
<div
class="fpi-comparison"
data-testid="fluid-comparison-ELECTRICITY"
>
<span
class="percent positive"
>
+10,00 %
</span>
<span
class="fpi-comparison-date"
>
/ avril 2024
</span>
</div>
</div>
</button>
</div>
`;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment