Skip to content

Commit 0b7fe6e

Browse files
committed
feature: changed text on purpose summary page, added alerts (PIN-9127)
1 parent ddc12a4 commit 0b7fe6e

File tree

11 files changed

+253
-62
lines changed

11 files changed

+253
-62
lines changed

__mocks__/data/purpose.mocks.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,65 @@ const createMockPurposeUsesPersonalDataAnswerYes = createMockFactory<Purpose>({
183183
rulesetExpiration: '2030-01-01T00:00:00Z',
184184
})
185185

186+
const createMockPurposeCallsExceed = createMockFactory<Purpose>({
187+
id: 'purpose-id',
188+
title: 'Test Purpose',
189+
consumer: { id: 'consumer-id', name: 'Consumer Name' },
190+
eservice: {
191+
id: 'eservice-id',
192+
name: 'Test Eservice',
193+
mode: 'DELIVER',
194+
producer: { id: 'producer-id', name: 'Producer Name' },
195+
personalData: false,
196+
descriptor: {
197+
id: 'descriptor-id',
198+
state: 'PUBLISHED',
199+
version: '1',
200+
audience: ['test'],
201+
},
202+
},
203+
agreement: { id: 'agreement-id', state: 'ACTIVE', canBeUpgraded: false },
204+
riskAnalysisForm: {
205+
answers: { usesPersonalData: ['YES'] },
206+
version: '3.1',
207+
riskAnalysisId: 'risk-analysis-id',
208+
},
209+
versions: [
210+
{
211+
createdAt: '2023-02-03T07:59:52.458Z',
212+
dailyCalls: 1,
213+
firstActivationAt: '2023-02-03T08:26:43.139Z',
214+
id: '3a5c9422-876c-4de8-828a-66586fd68b55',
215+
riskAnalysisDocument: {
216+
contentType: 'application/pdf',
217+
createdAt: '2023-02-03T08:26:43.049Z',
218+
id: '3562b028-0193-45fa-acf9-4bbe1ced352a',
219+
},
220+
state: 'ACTIVE',
221+
},
222+
],
223+
clients: [],
224+
description: '',
225+
isFreeOfCharge: false,
226+
dailyCallsPerConsumer: 0,
227+
currentVersion: {
228+
createdAt: '2023-02-03T07:59:52.458Z',
229+
dailyCalls: 1,
230+
firstActivationAt: '2023-02-03T08:26:43.139Z',
231+
id: '3a5c9422-876c-4de8-828a-66586fd68b55',
232+
riskAnalysisDocument: {
233+
contentType: 'application/pdf',
234+
createdAt: '2023-02-03T08:26:43.049Z',
235+
id: '3562b028-0193-45fa-acf9-4bbe1ced352a',
236+
},
237+
state: 'ACTIVE',
238+
},
239+
dailyCallsTotal: 0,
240+
hasUnreadNotifications: false,
241+
isDocumentReady: false,
242+
rulesetExpiration: undefined,
243+
})
244+
186245
const createMockPurposeCompatiblePersonalDataYes = createMockFactory<Purpose>({
187246
...createMockPurposeUsesPersonalDataAnswerNo(),
188247
riskAnalysisForm: {
@@ -199,11 +258,37 @@ const createMockPurposeCompatiblePersonalDataNo = createMockFactory<Purpose>({
199258
},
200259
})
201260

261+
const createMockPurposeCallsPerConsumerExceed = createMockFactory<Purpose>({
262+
...createMockPurposeCallsExceed(),
263+
currentVersion: {
264+
id: '1',
265+
state: 'ACTIVE',
266+
createdAt: '2023-02-03T07:59:52.458Z',
267+
dailyCalls: 2,
268+
},
269+
dailyCallsPerConsumer: 1,
270+
dailyCallsTotal: 10,
271+
})
272+
273+
const createMockPurposeCallsTotalExceed = createMockFactory<Purpose>({
274+
...createMockPurposeCallsExceed(),
275+
currentVersion: {
276+
id: '1',
277+
state: 'ACTIVE',
278+
createdAt: '2023-02-03T07:59:52.458Z',
279+
dailyCalls: 2,
280+
},
281+
dailyCallsPerConsumer: 10,
282+
dailyCallsTotal: 1,
283+
})
284+
202285
export {
203286
createMockPurpose,
204287
createMockRiskAnalysisFormConfig,
205288
createMockPurposeUsesPersonalDataAnswerNo,
206289
createMockPurposeUsesPersonalDataAnswerYes,
207290
createMockPurposeCompatiblePersonalDataYes,
208291
createMockPurposeCompatiblePersonalDataNo,
292+
createMockPurposeCallsPerConsumerExceed,
293+
createMockPurposeCallsTotalExceed,
209294
}

src/components/shared/SummaryAccordion.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ export const SummaryAccordion: React.FC<SummaryAccordionProps> = ({
4141
},
4242
}}
4343
>
44-
<Box>
44+
<Box sx={{ display: 'flex', alignItems: 'center' }}>
4545
<Typography variant="subtitle2">{headline}</Typography>
46-
<Typography sx={{ mt: 2 }} variant="h6">
46+
<Typography sx={{ ml: 1 }} variant="h6">
4747
{title}
4848
</Typography>
4949
</Box>

src/pages/ConsumerPurposeSummaryPage/ConsumerPurposeSummary.page.tsx

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react'
22
import { useTranslation } from 'react-i18next'
33
import { useNavigate, useParams } from '@/router'
4-
import { Alert, Button, Stack, Tooltip, Typography } from '@mui/material'
4+
import { Alert, Button, Stack, Tooltip } from '@mui/material'
55
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'
66
import CreateIcon from '@mui/icons-material/Create'
77
import PublishIcon from '@mui/icons-material/Publish'
@@ -18,11 +18,8 @@ import {
1818
import { useGetConsumerPurposeAlertProps } from './hooks/useGetConsumerPurposeAlertProps'
1919
import { useQuery } from '@tanstack/react-query'
2020
import { AuthHooks } from '@/api/auth'
21-
import {
22-
checkIsRulesetExpired,
23-
getDaysToExpiration,
24-
getFormattedExpirationDate,
25-
} from '@/utils/purpose.utils'
21+
import { checkIsRulesetExpired } from '@/utils/purpose.utils'
22+
import { ConsumerPurposeSummaryAlertContainer } from './components/ConsumerPurposeSummaryAlertContainer'
2623

2724
const ConsumerPurposeSummaryPage: React.FC = () => {
2825
const { t } = useTranslation('purpose')
@@ -38,8 +35,6 @@ const ConsumerPurposeSummaryPage: React.FC = () => {
3835

3936
const expirationDate = purpose?.rulesetExpiration
4037

41-
const daysToExpiration = getDaysToExpiration(expirationDate)
42-
4338
const isRulesetExpired = checkIsRulesetExpired(expirationDate)
4439

4540
const alertProps = useGetConsumerPurposeAlertProps(purpose)
@@ -123,7 +118,7 @@ const ConsumerPurposeSummaryPage: React.FC = () => {
123118

124119
return (
125120
<PageContainer
126-
title={purpose?.title}
121+
title={t('summary.title')}
127122
isLoading={isLoading}
128123
backToAction={{
129124
label: t('backToListBtn'),
@@ -148,31 +143,11 @@ const ConsumerPurposeSummaryPage: React.FC = () => {
148143
</SummaryAccordion>
149144
</React.Suspense>
150145
</Stack>
151-
{expirationDate && !isRulesetExpired && (
152-
<Alert sx={{ mt: 3 }} severity="info">
153-
{t('summary.alerts.infoRulesetExpiration', {
154-
days: daysToExpiration,
155-
date: getFormattedExpirationDate(expirationDate),
156-
})}
157-
</Alert>
158-
)}
159-
{isRulesetExpired && (
160-
<Alert severity="error" sx={{ alignItems: 'center', mt: 3 }} variant="outlined">
161-
<Stack spacing={13} direction="row" alignItems="center">
162-
{' '}
163-
{/**TODO FIX SPACING */}
164-
<Typography>{t('summary.alerts.rulesetExpired.label')}</Typography>
165-
<Button
166-
variant="naked"
167-
size="medium"
168-
sx={{ fontWeight: 700, mr: 1 }}
169-
onClick={() => navigate('SUBSCRIBE_PURPOSE_CREATE')}
170-
>
171-
{t('summary.alerts.rulesetExpired.action')}
172-
</Button>
173-
</Stack>
174-
</Alert>
175-
)}
146+
<ConsumerPurposeSummaryAlertContainer
147+
purpose={purpose}
148+
isRulesetExpired={isRulesetExpired}
149+
expirationDate={expirationDate}
150+
/>
176151
<Stack spacing={1} sx={{ mt: 4 }} direction="row" justifyContent="end">
177152
<Button
178153
startIcon={<DeleteOutlineIcon />}
@@ -199,7 +174,7 @@ const ConsumerPurposeSummaryPage: React.FC = () => {
199174
variant="contained"
200175
onClick={handlePublishDraft}
201176
>
202-
{tCommon('publishDraft')}
177+
{tCommon('publish')}
203178
</Button>
204179
</span>
205180
</Tooltip>

src/pages/ConsumerPurposeSummaryPage/__tests__/ConsumerPurposeSummary.page.test.tsx

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
createMockPurposeUsesPersonalDataAnswerNo,
1414
createMockPurposeCompatiblePersonalDataYes,
1515
createMockPurposeCompatiblePersonalDataNo,
16+
createMockPurposeCallsPerConsumerExceed,
17+
createMockPurposeCallsTotalExceed,
1618
} from '@/../__mocks__/data/purpose.mocks'
1719

1820
const mockPurposeId = 'test-purpose-id'
@@ -63,11 +65,15 @@ vi.mock('./hooks/useGetConsumerPurposeAlertProps', () => ({
6365
useGetConsumerPurposeAlertProps: () => undefined,
6466
}))
6567

66-
vi.mock('@/utils/purpose.utils', () => ({
67-
checkIsRulesetExpired: vi.fn(),
68-
getDaysToExpiration: vi.fn(),
69-
getFormattedExpirationDate: vi.fn(),
70-
}))
68+
vi.mock('@/utils/purpose.utils', async () => {
69+
const actual = await vi.importActual('@/utils/purpose.utils')
70+
return {
71+
...(actual as Record<string, unknown>),
72+
checkIsRulesetExpired: vi.fn(),
73+
getDaysToExpiration: vi.fn(),
74+
getFormattedExpirationDate: vi.fn(),
75+
}
76+
})
7177

7278
describe('ConsumerPurposeSummaryPage', () => {
7379
beforeEach(() => {
@@ -88,7 +94,7 @@ describe('ConsumerPurposeSummaryPage', () => {
8894
withRouterContext: true,
8995
})
9096

91-
expect(screen.getByText('Test Purpose')).toBeInTheDocument()
97+
expect(screen.getByText('summary.title')).toBeInTheDocument()
9298
})
9399

94100
it('disables publish button when personal data answer is incompatible (case: user answer NO, eservice personalData true)', () => {
@@ -103,7 +109,7 @@ describe('ConsumerPurposeSummaryPage', () => {
103109
})
104110

105111
const publishButton = screen.getByRole('button', {
106-
name: 'publishDraft',
112+
name: 'publish',
107113
})
108114

109115
expect(publishButton).toBeDisabled()
@@ -121,7 +127,7 @@ describe('ConsumerPurposeSummaryPage', () => {
121127
})
122128

123129
const publishButton = screen.getByRole('button', {
124-
name: 'publishDraft',
130+
name: 'publish',
125131
})
126132

127133
expect(publishButton).toBeDisabled()
@@ -139,7 +145,7 @@ describe('ConsumerPurposeSummaryPage', () => {
139145
})
140146

141147
const publishButton = screen.getByRole('button', {
142-
name: 'publishDraft',
148+
name: 'publish',
143149
})
144150

145151
expect(publishButton).toBeEnabled()
@@ -157,7 +163,7 @@ describe('ConsumerPurposeSummaryPage', () => {
157163
})
158164

159165
const publishButton = screen.getByRole('button', {
160-
name: 'publishDraft',
166+
name: 'publish',
161167
})
162168

163169
expect(publishButton).toBeEnabled()
@@ -188,7 +194,7 @@ describe('ConsumerPurposeSummaryPage', () => {
188194
withRouterContext: true,
189195
})
190196

191-
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
197+
expect(screen.queryByText('summary.alerts.infoRulesetExpiration')).not.toBeInTheDocument()
192198
})
193199
it('shows alert if isRulesetExpired is true', () => {
194200
vi.mocked(checkIsRulesetExpired).mockReturnValue(true)
@@ -207,4 +213,34 @@ describe('ConsumerPurposeSummaryPage', () => {
207213

208214
expect(screen.getByText('summary.alerts.rulesetExpired.label')).toBeInTheDocument()
209215
})
216+
it('shows info alert when daily calls exceed calls per consumer', () => {
217+
useQueryMock.mockReturnValue({
218+
data: createMockPurposeCallsPerConsumerExceed(),
219+
isLoading: false,
220+
})
221+
222+
renderWithApplicationContext(<ConsumerPurposeSummaryPage />, {
223+
withReactQueryContext: true,
224+
withRouterContext: true,
225+
})
226+
227+
expect(screen.getByText('summary.alerts.infoDailyCallsPerConsumerExceed')).toBeInTheDocument()
228+
})
229+
it('shows info alert when daily calls exceed total calls', () => {
230+
useQueryMock.mockReturnValue({
231+
data: createMockPurposeCallsTotalExceed(),
232+
isLoading: false,
233+
})
234+
235+
renderWithApplicationContext(<ConsumerPurposeSummaryPage />, {
236+
withReactQueryContext: true,
237+
withRouterContext: true,
238+
})
239+
240+
console.log('----------------')
241+
screen.debug(undefined, 1000000)
242+
console.log('----------------')
243+
244+
expect(screen.getByText('summary.alerts.infoDailyCallsTotalExceed')).toBeInTheDocument()
245+
})
210246
})
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import type { Purpose } from '@/api/api.generatedTypes'
2+
import {
3+
checkIsRulesetExpired,
4+
getDaysToExpiration,
5+
getFormattedExpirationDate,
6+
getPurposeSummaryInfoAlertLabel,
7+
} from '@/utils/purpose.utils'
8+
import { Alert, Button, Stack, Typography } from '@mui/material'
9+
import { useNavigate } from '@/router'
10+
import React from 'react'
11+
import { useTranslation } from 'react-i18next'
12+
13+
type ConsumerPurposeSummaryAlertContainerProps = {
14+
purpose: Purpose | undefined
15+
expirationDate?: string
16+
isRulesetExpired: boolean
17+
}
18+
19+
export const ConsumerPurposeSummaryAlertContainer: React.FC<
20+
ConsumerPurposeSummaryAlertContainerProps
21+
> = ({ purpose, expirationDate, isRulesetExpired }) => {
22+
const { t } = useTranslation('purpose')
23+
24+
const navigate = useNavigate()
25+
26+
const daysToExpiration = getDaysToExpiration(expirationDate)
27+
28+
const infoAlertLabel = getPurposeSummaryInfoAlertLabel(purpose)
29+
30+
return (
31+
<>
32+
{expirationDate && !isRulesetExpired && (
33+
<Alert sx={{ mt: 3 }} severity="info">
34+
{t('summary.alerts.infoRulesetExpiration', {
35+
days: daysToExpiration,
36+
date: getFormattedExpirationDate(expirationDate),
37+
})}
38+
</Alert>
39+
)}
40+
{isRulesetExpired && (
41+
<Alert severity="error" sx={{ alignItems: 'center', mt: 3 }} variant="outlined">
42+
<Stack spacing={13} direction="row" alignItems="center">
43+
{' '}
44+
{/**TODO FIX SPACING */}
45+
<Typography>{t('summary.alerts.rulesetExpired.label')}</Typography>
46+
<Button
47+
variant="naked"
48+
size="medium"
49+
sx={{ fontWeight: 700, mr: 1 }}
50+
onClick={() => navigate('SUBSCRIBE_PURPOSE_CREATE')}
51+
>
52+
{t('summary.alerts.rulesetExpired.action')}
53+
</Button>
54+
</Stack>
55+
</Alert>
56+
)}
57+
{!expirationDate && !isRulesetExpired && (
58+
<Alert severity="info" sx={{ mt: 3 }}>
59+
{t(infoAlertLabel)}
60+
</Alert>
61+
)}
62+
</>
63+
)
64+
}

src/pages/ConsumerPurposeSummaryPage/components/ConsumerPurposeSummaryGeneralInformationAccordion.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ export const ConsumerPurposeSummaryGeneralInformationAccordion: React.FC<
3636
>
3737
{t('eservice.value', {
3838
name: purpose.eservice.name,
39-
version: purpose.eservice.descriptor.version,
4039
})}
4140
</Link>
4241
}

0 commit comments

Comments
 (0)