Skip to content

Commit 0a1b5ba

Browse files
authored
Feature/vise hendelses id frontend (#4259)
* - Add HendelseIdDataVisning component to display event IDs and related persons. - Implement HendelseIdPersonMiljoeInfo component for rendering event ID information. - Enhance DollyTooltip to support external tooltip properties. - Update PersonVisning to include HendelseIdPersonMiljoeInfo. - Add useHendelseId hook for fetching event ID data. - Update DollyEndpoints to include endpoint for fetching event IDs. - Modify DataVisning.less for new styles related to event ID display. - Bump version in package.json to 3.5.5. * - Deploy hendelses-id frontend - Update @typescript-eslint/eslint-plugin and @typescript-eslint/parser to version 8.61.0 - Upgrade electron-to-chromium to version 1.5.369 - Bump side-channel to version 1.1.1 - Update semver to version 7.8.3 #deploy-test-dolly-frontend * - Refactor HendelseIdDataVisning component to improve structure and readability. - Enhance styling in DataVisning.less for better layout and error indication. - Add handling for import status messages in HendelseIdDataVisning. - Update TidligereBestillinger to filter out invalid IDs before rendering. - Introduce state management for hover availability in HendelseIdDataVisning. #deploy-test-dolly-frontend * - Add tests for HendelseIdDataVisning component to ensure proper rendering and functionality. - Implement mock responses for various scenarios in HendelseIdDataVisning tests. - Update package dependencies to latest versions for improved stability and features. #deploy-test-dolly-frontend * - Update test assertions in HendelseIdDataVisning to remove Norwegian phrase and ensure visibility of 'hovedperson'. - Modify test to check for the presence of 'hovedperson' instead of 'Gå til hovedperson'. #deploy-test-dolly-frontend * - Deploy #deploy-test-dolly-frontend * - Deploy #deploy-test-dolly-frontend * - Update test to render ident without "(HOVEDPERSON)" suffix - Add warning for duplicate related idents in HendelseIdDataVisning - Change Alert component to StyledAlert for import notification - Refactor related persons handling to ensure uniqueness - Adjust button class for consistent styling #deploy-test-dolly-frontend
1 parent 6b04cc4 commit 0a1b5ba

13 files changed

Lines changed: 1276 additions & 163 deletions

File tree

apps/dolly-frontend/src/main/js/package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dolly",
3-
"version": "3.5.4",
3+
"version": "3.5.5",
44
"type": "module",
55
"description": "",
66
"main": "index.js",
@@ -23,7 +23,7 @@
2323
"license": "ISC",
2424
"dependencies": {
2525
"@hookform/resolvers": "^5.4.0",
26-
"@navikt/aksel-icons": "^8.11.1",
26+
"@navikt/aksel-icons": "^8.12.1",
2727
"@popperjs/core": "^2.11.8",
2828
"axios": "^1.17.0",
2929
"classnames": "^2.5.1",
@@ -58,9 +58,9 @@
5858
"devDependencies": {
5959
"@babel/core": "^7.29.7",
6060
"@hookform/error-message": "^2.0.1",
61-
"@navikt/aksel": "^8.11.1",
62-
"@navikt/ds-css": "^8.11.1",
63-
"@navikt/ds-react": "^8.11.1",
61+
"@navikt/aksel": "^8.12.1",
62+
"@navikt/ds-css": "^8.12.1",
63+
"@navikt/ds-react": "^8.12.1",
6464
"@playwright/experimental-ct-react": "^1.60.0",
6565
"@playwright/test": "^1.60.0",
6666
"@reduxjs/toolkit": "^2.12.0",
@@ -77,8 +77,8 @@
7777
"@types/react-modal": "^3.16.3",
7878
"@types/react-redux": "^7.1.34",
7979
"@types/redux-actions": "^2.6.5",
80-
"@typescript-eslint/eslint-plugin": "^8.60.1",
81-
"@typescript-eslint/parser": "^8.60.1",
80+
"@typescript-eslint/eslint-plugin": "^8.61.0",
81+
"@typescript-eslint/parser": "^8.61.0",
8282
"@vitejs/plugin-react": "^6.0.2",
8383
"@vitest/browser": "^4.1.8",
8484
"@vitest/browser-playwright": "^4.1.8",
@@ -96,7 +96,7 @@
9696
"less": "^4.6.4",
9797
"msw": "^2.14.6",
9898
"playwright": "^1.60.0",
99-
"prettier": "^3.8.3",
99+
"prettier": "^3.8.4",
100100
"react-dropzone": "^15.0.0",
101101
"react-pdf": "^10.4.1",
102102
"react-redux": "^9.3.0",

apps/dolly-frontend/src/main/js/playwright-ct.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export default defineConfig({
3737
resolve: {
3838
alias: {
3939
'@': path.resolve(__dirname, './src'),
40+
'#': path.resolve(__dirname, './playwright'),
4041
},
4142
},
4243
css: {
Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
import { expect, test } from '@playwright/experimental-ct-react'
2+
import { HendelseIdDataVisning } from '@/pages/gruppe/PersonVisning/PersonMiljoeinfo/HendelseIdDataVisning'
3+
import { Provider } from 'react-redux'
4+
import { configureStore } from '@reduxjs/toolkit'
5+
6+
const HENDELSE_ROUTE = /dolly-backend\/api\/v1\/hendelseid\/ident\//
7+
8+
const mainPersonResponse = {
9+
hovedperson: {
10+
ordrer: [
11+
{
12+
infoElement: 'PDL_SLETTING',
13+
hendelser: [{ status: 'OK' }],
14+
},
15+
{
16+
infoElement: 'PDL_OPPRETT_PERSON',
17+
hendelser: [{ status: 'OK' }],
18+
},
19+
{
20+
infoElement: 'PDL_DOEDSFALL',
21+
hendelser: [{ id: 1, status: 'OK', hendelseId: 'abc-123' }],
22+
},
23+
{
24+
infoElement: 'PDL_NAVN',
25+
hendelser: [
26+
{ id: 2, status: 'OK', hendelseId: 'def-456' },
27+
{ id: 3, status: 'OK', hendelseId: 'ghi-789' },
28+
],
29+
},
30+
{
31+
infoElement: 'PDL_SIVILSTAND',
32+
hendelser: [{ id: 1, status: 'OK', hendelseId: 'siv-1' }],
33+
},
34+
{
35+
infoElement: 'PDL_SIVILSTAND',
36+
hendelser: [{ id: 2, status: 'OK', hendelseId: 'siv-2' }],
37+
},
38+
],
39+
},
40+
relasjoner: [],
41+
}
42+
43+
const feilPersonResponse = {
44+
hovedperson: {
45+
ordrer: [
46+
{
47+
infoElement: 'PDL_SLETTING',
48+
hendelser: [{ status: 'FEIL', error: 'Mottaker svarer ikke, eller har for lang svartid.' }],
49+
},
50+
],
51+
},
52+
relasjoner: [],
53+
}
54+
55+
const relatertPersonResponse = {
56+
ident: '11111111111',
57+
ordrer: [
58+
{
59+
infoElement: 'PDL_FORELDRE_BARN_RELASJON',
60+
hendelser: [{ id: 7, status: 'OK', hendelseId: 'rel-789' }],
61+
},
62+
],
63+
}
64+
65+
const importertRelasjonResponse = {
66+
ident: '11111111111',
67+
ordrer: [],
68+
}
69+
70+
test.use({ viewport: { width: 1200, height: 800 } })
71+
72+
const testStore = configureStore({
73+
reducer: () => ({}),
74+
})
75+
76+
test('should render ident trigger button', async ({ mount }) => {
77+
const component = await mount(<HendelseIdDataVisning ident="12345678901" />)
78+
await expect(component.getByText('12345678901 (HOVEDPERSON)')).toBeVisible()
79+
})
80+
81+
test('should render trigger buttons for related persons', async ({ mount }) => {
82+
const component = await mount(
83+
<HendelseIdDataVisning
84+
ident="12345678901"
85+
relatertePersoner={[
86+
{ type: 'BARN', id: '11111111111' },
87+
{ type: 'PARTNER', id: '22222222222' },
88+
]}
89+
/>,
90+
)
91+
await expect(component.getByText('12345678901 (HOVEDPERSON)')).toBeVisible()
92+
await expect(component.getByText('11111111111 (BARN)')).toBeVisible()
93+
await expect(component.getByText('22222222222 (PARTNER)')).toBeVisible()
94+
})
95+
96+
test('should show one accordion category per infoElement on hover', async ({ mount, page }) => {
97+
await page.route(HENDELSE_ROUTE, async (route) => {
98+
await route.fulfill({
99+
status: 200,
100+
contentType: 'application/json',
101+
body: JSON.stringify(mainPersonResponse),
102+
})
103+
})
104+
105+
const component = await mount(<HendelseIdDataVisning ident="12345678901" />)
106+
107+
await component.getByText('12345678901 (HOVEDPERSON)').hover({ force: true })
108+
await expect(page.getByRole('button', { name: /dødsfall/i })).toBeVisible()
109+
await expect(page.getByRole('button', { name: /navn/i })).toBeVisible()
110+
await expect(page.getByRole('button', { name: /sivilstand/i })).toBeVisible()
111+
112+
await page.getByRole('button', { name: /dødsfall/i }).click()
113+
await expect(page.getByText('abc-123')).toBeVisible()
114+
})
115+
116+
test('should hide noise events without errors', async ({ mount, page }) => {
117+
await page.route(HENDELSE_ROUTE, async (route) => {
118+
await route.fulfill({
119+
status: 200,
120+
contentType: 'application/json',
121+
body: JSON.stringify(mainPersonResponse),
122+
})
123+
})
124+
125+
const component = await mount(<HendelseIdDataVisning ident="12345678901" />)
126+
127+
await component.getByText('12345678901 (HOVEDPERSON)').hover({ force: true })
128+
await expect(page.getByRole('button', { name: /dødsfall/i })).toBeVisible()
129+
await expect(page.getByRole('button', { name: /sletting/i })).toBeHidden()
130+
await expect(page.getByRole('button', { name: /opprett/i })).toBeHidden()
131+
})
132+
133+
test('should close on hover leave before any category is opened', async ({ mount, page }) => {
134+
await page.route(HENDELSE_ROUTE, async (route) => {
135+
await route.fulfill({
136+
status: 200,
137+
contentType: 'application/json',
138+
body: JSON.stringify(mainPersonResponse),
139+
})
140+
})
141+
142+
const component = await mount(<HendelseIdDataVisning ident="12345678901" />)
143+
144+
await component.getByText('12345678901 (HOVEDPERSON)').hover({ force: true })
145+
await expect(page.getByRole('button', { name: /dødsfall/i })).toBeVisible()
146+
147+
await page.mouse.move(0, 0)
148+
await expect(page.getByRole('button', { name: /dødsfall/i })).toBeHidden()
149+
})
150+
151+
test('should show a copy button per hendelse inside the same category', async ({ mount, page }) => {
152+
await page.route(HENDELSE_ROUTE, async (route) => {
153+
await route.fulfill({
154+
status: 200,
155+
contentType: 'application/json',
156+
body: JSON.stringify(mainPersonResponse),
157+
})
158+
})
159+
160+
const component = await mount(<HendelseIdDataVisning ident="12345678901" />)
161+
162+
await component.getByText('12345678901 (HOVEDPERSON)').hover({ force: true })
163+
await page.waitForTimeout(300)
164+
165+
await page.getByRole('button', { name: /navn/i }).first().click()
166+
await expect(page.getByText('def-456')).toBeVisible()
167+
await expect(page.getByText('ghi-789')).toBeVisible()
168+
const navnItem = page.locator('.aksel-accordion__item', {
169+
has: page.getByRole('button', { name: /navn/i }),
170+
})
171+
await expect(navnItem.locator('.aksel-copybutton')).toHaveCount(2)
172+
})
173+
174+
test('should colour the category red and show the error message on failure', async ({
175+
mount,
176+
page,
177+
}) => {
178+
await page.route(HENDELSE_ROUTE, async (route) => {
179+
await route.fulfill({
180+
status: 200,
181+
contentType: 'application/json',
182+
body: JSON.stringify(feilPersonResponse),
183+
})
184+
})
185+
186+
const component = await mount(<HendelseIdDataVisning ident="12345678901" />)
187+
188+
await component.getByText('12345678901 (HOVEDPERSON)').hover({ force: true })
189+
await expect(page.locator('.hendelse-kategori-feil')).toBeVisible()
190+
191+
await page.getByRole('button', { name: /sletting/i }).click()
192+
await expect(page.getByText('Mottaker svarer ikke, eller har for lang svartid.')).toBeVisible()
193+
})
194+
195+
test('should show imported-relation warning immediately and hide related hover button', async ({
196+
mount,
197+
page,
198+
}) => {
199+
await page.route(HENDELSE_ROUTE, async (route) => {
200+
const url = route.request().url()
201+
await route.fulfill({
202+
status: 200,
203+
contentType: 'application/json',
204+
body: JSON.stringify(
205+
url.includes('relatertIdent=11111111111') ? importertRelasjonResponse : mainPersonResponse,
206+
),
207+
})
208+
})
209+
210+
const component = await mount(
211+
<Provider store={testStore}>
212+
<HendelseIdDataVisning
213+
ident="12345678901"
214+
relatertePersoner={[{ type: 'BARN', id: '11111111111' }]}
215+
/>
216+
</Provider>,
217+
)
218+
219+
await expect(page.getByText(/importert/i)).toBeVisible()
220+
await expect(page.getByText(/hovedperson/i)).toBeVisible()
221+
await expect(component.getByRole('button', { name: '11111111111 (BARN)' })).toHaveCount(0)
222+
await expect(component.getByRole('button', { name: '12345678901 (HOVEDPERSON)' })).toHaveCount(0)
223+
})
224+
225+
test('should stay open after category interaction and close on click', async ({ mount, page }) => {
226+
await page.route(HENDELSE_ROUTE, async (route) => {
227+
await route.fulfill({
228+
status: 200,
229+
contentType: 'application/json',
230+
body: JSON.stringify(mainPersonResponse),
231+
})
232+
})
233+
234+
const component = await mount(<HendelseIdDataVisning ident="12345678901" />)
235+
236+
await component.getByText('12345678901 (HOVEDPERSON)').hover({ force: true })
237+
await page
238+
.getByRole('button', { name: /sivilstand/i })
239+
.first()
240+
.click()
241+
await expect(page.getByText('siv-1')).toBeVisible()
242+
243+
await page.mouse.move(0, 0)
244+
await expect(page.getByText('siv-1')).toBeVisible()
245+
246+
await component.getByText('12345678901 (HOVEDPERSON)').click({ force: true })
247+
await expect(page.getByText('siv-1')).toBeHidden()
248+
})
249+
250+
test('should request ordrer for relatert ident with correct query param', async ({
251+
mount,
252+
page,
253+
}) => {
254+
const requestedUrls: string[] = []
255+
await page.route(HENDELSE_ROUTE, async (route) => {
256+
const requestedUrl = route.request().url()
257+
requestedUrls.push(requestedUrl)
258+
if (requestedUrl.includes('relatertIdent=11111111111')) {
259+
await route.fulfill({
260+
status: 200,
261+
contentType: 'application/json',
262+
body: JSON.stringify(relatertPersonResponse),
263+
})
264+
} else {
265+
await route.fulfill({
266+
status: 200,
267+
contentType: 'application/json',
268+
body: JSON.stringify(mainPersonResponse),
269+
})
270+
}
271+
})
272+
273+
const component = await mount(
274+
<HendelseIdDataVisning
275+
ident="12345678901"
276+
relatertePersoner={[{ type: 'BARN', id: '11111111111' }]}
277+
/>,
278+
)
279+
await component.getByText('11111111111 (BARN)').hover({ force: true })
280+
await page.waitForTimeout(300)
281+
282+
await expect
283+
.poll(() => requestedUrls.some((url) => url.includes('relatertIdent=11111111111')))
284+
.toBe(true)
285+
})

0 commit comments

Comments
 (0)