@centreon/ui 26.12.1 → 26.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/package.json +6 -3
  2. package/public/mockServiceWorker.js +31 -8
  3. package/src/Dashboard/Dashboard.browser.test.tsx +107 -0
  4. package/src/Form/Form.browser.test.tsx +445 -0
  5. package/src/Form/Inputs/ExclusiveCheckboxGroup.browser.test.tsx +304 -0
  6. package/src/Form/Inputs/SegmentedButtons.browser.test.tsx +113 -0
  7. package/src/InputField/Number/Number.browser.test.tsx +109 -0
  8. package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.browser.test.tsx +250 -0
  9. package/src/Listing/Listing.browser.test.tsx +476 -0
  10. package/src/Module/Module.browser.test.tsx +145 -0
  11. package/src/Pagination/Pagination.browser.test.tsx +184 -0
  12. package/src/RichTextEditor/RichTextEditor.browser.test.tsx +567 -0
  13. package/src/RichTextEditor/plugins/FloatingLinkEditorPlugin.tsx +3 -1
  14. package/src/TimePeriods/ResolutionTimePeriod.browser.test.tsx +143 -0
  15. package/src/TimePeriods/TimePeriods.browser.test.tsx +468 -0
  16. package/src/Typography/FluidTypography/FluidTypography.browser.test.tsx +54 -0
  17. package/src/api/useMutationQuery/useMutationQuery.browser.test.tsx +154 -0
  18. package/src/components/CollapsibleItem/CollapsibleItem.browser.test.tsx +120 -0
  19. package/src/components/CopyCommand/CopyCommand.browser.test.tsx +287 -0
  20. package/src/components/CrudPage/CrudPage.browser.test.tsx +659 -0
  21. package/src/components/DataTable/DataTable.browser.test.tsx +257 -0
  22. package/src/components/Form/AccessRights/AccessRights.browser.test.tsx +527 -0
  23. package/src/components/ItemComposition/ItemComposition.browser.test.tsx +172 -0
  24. package/src/components/Layout/PageLayout.browser.test.tsx +114 -0
  25. package/src/components/Modal/ConfirmationModal/ConfirmationModal.browser.test.tsx +237 -0
  26. package/src/components/SortableEntriesList/SortableEntriesList.browser.test.tsx +981 -0
  27. package/src/components/Tabs/Tabs.browser.test.tsx +115 -0
  28. package/src/utils/useFullscreen/Fullscreen.browser.test.tsx +176 -0
  29. package/src/utils/useLocale/useLocale.browser.test.tsx +49 -0
  30. package/src/utils/useLocaleTimezoneDate/{LocaleTimezoneDate.cypress.spec.tsx → LocaleTimezoneDate.browser.test.tsx} +24 -11
  31. package/src/Dashboard/Dashboard.cypress.spec.tsx +0 -71
  32. package/src/Form/Form.cypress.spec.tsx +0 -306
  33. package/src/Form/Inputs/ExclusiveCheckboxGroup.cypress.spec.tsx +0 -236
  34. package/src/Form/Inputs/SegmentedButtons.cypress.spec.tsx +0 -101
  35. package/src/InputField/Number/Number.cypress.spec.tsx +0 -89
  36. package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +0 -182
  37. package/src/Listing/Listing.cypress.spec.tsx +0 -349
  38. package/src/Module/Module.cypress.spec.tsx +0 -127
  39. package/src/Pagination/Pagination.cypress.spec.tsx +0 -140
  40. package/src/RichTextEditor/RichTextEditor.cypress.spec.tsx +0 -408
  41. package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +0 -74
  42. package/src/TimePeriods/TimePeriods.cypress.spec.tsx +0 -488
  43. package/src/Typography/FluidTypography/FluidTypography.cypress.spec.tsx +0 -27
  44. package/src/api/useMutationQuery/useMutationQuery.cypress.spec.tsx +0 -93
  45. package/src/components/CollapsibleItem/CollapsibleItem.cypress.spec.tsx +0 -76
  46. package/src/components/CopyCommand/CopyCommand.cypress.spec.tsx +0 -167
  47. package/src/components/CrudPage/CrudPage.cypress.spec.tsx +0 -561
  48. package/src/components/DataTable/DataTable.cypress.spec.tsx +0 -174
  49. package/src/components/Form/AccessRights/AccessRights.cypress.spec.tsx +0 -376
  50. package/src/components/ItemComposition/ItemComposition.cypress.spec.tsx +0 -112
  51. package/src/components/Layout/PageLayout.cypress.spec.tsx +0 -64
  52. package/src/components/Modal/ConfirmationModal/ConfirmationModal.cypress.spec.tsx +0 -171
  53. package/src/components/SortableEntriesList/SortableEntriesList.cypress.spec.tsx +0 -792
  54. package/src/components/Tabs/Tabs.cypress.spec.tsx +0 -69
  55. package/src/utils/useFullscreen/Fullscreen.cypress.spec.tsx +0 -130
  56. package/src/utils/useLocale/useLocale.cypress.spec.tsx +0 -40
@@ -0,0 +1,114 @@
1
+ import { rs } from '@rstest/core';
2
+ import { render } from '@test-setup/render';
3
+ import { screen, within } from '@testing-library/react';
4
+ import userEvent from '@testing-library/user-event';
5
+ import { T } from 'ramda';
6
+
7
+ import { PageHeader } from '..';
8
+ import { PageLayout } from '.';
9
+ import { AreaIndicator } from './AreaIndicator';
10
+
11
+ const initialize = (): void => {
12
+ render(
13
+ <PageLayout>
14
+ <PageLayout.Header>
15
+ <PageHeader>
16
+ <PageHeader.Menu>
17
+ <PageLayout.QuickAccess
18
+ create={rs.fn()}
19
+ elements={[
20
+ {
21
+ id: 1,
22
+ name: 'Entity'
23
+ }
24
+ ]}
25
+ goBack={rs.fn()}
26
+ isActive={T}
27
+ labels={{
28
+ create: 'Create',
29
+ goBack: 'Go back'
30
+ }}
31
+ navigateToElement={rs.fn()}
32
+ />
33
+ </PageHeader.Menu>
34
+ <PageHeader.Main>
35
+ <PageHeader.Title description="Description" title="Title" />
36
+ </PageHeader.Main>
37
+ <PageHeader.Actions>Actions</PageHeader.Actions>
38
+ </PageHeader>
39
+ </PageLayout.Header>
40
+ <PageLayout.Body>
41
+ <PageLayout.Actions>
42
+ <AreaIndicator name="Body actions" />
43
+ </PageLayout.Actions>
44
+ <h1>Content</h1>
45
+ </PageLayout.Body>
46
+ </PageLayout>
47
+ );
48
+ };
49
+
50
+ describe('Page layout', () => {
51
+ beforeEach(() => {
52
+ expect.hasAssertions();
53
+ initialize();
54
+ });
55
+
56
+ it('displays the page layout', async () => {
57
+ // The header (quick access button, title, description, actions) above
58
+ // the body (actions area, then content), and the quick access menu closed.
59
+ const header = document.querySelector('#header') as HTMLElement;
60
+ const body = document.querySelector('#page-body') as HTMLElement;
61
+
62
+ const title = await within(header).findByRole('heading', {
63
+ name: 'page header title'
64
+ });
65
+
66
+ expect(title).toBeVisible();
67
+ expect(title).toHaveTextContent(/^Title$/);
68
+ expect(within(header).getByText('Description')).toBeVisible();
69
+ expect(within(header).getByText('Actions')).toBeVisible();
70
+ expect(within(header).getByTestId('quickaccess')).toBeVisible();
71
+ expect(within(header).getByTestId('quickaccess')).toHaveAttribute(
72
+ 'data-is-active',
73
+ 'false'
74
+ );
75
+
76
+ const bodyActions = within(body).getByText('Body actions');
77
+ const content = within(body).getByRole('heading', { name: 'Content' });
78
+
79
+ expect(bodyActions).toBeVisible();
80
+ expect(content).toBeVisible();
81
+ expect(header.getBoundingClientRect().bottom).toBeLessThanOrEqual(
82
+ body.getBoundingClientRect().top
83
+ );
84
+ expect(bodyActions.getBoundingClientRect().bottom).toBeLessThanOrEqual(
85
+ content.getBoundingClientRect().top
86
+ );
87
+ expect(screen.queryByText('Entity')).not.toBeInTheDocument();
88
+ });
89
+
90
+ it('opens the quick access poppin when the corresponding logo is displayed', async () => {
91
+ await userEvent.click(await screen.findByTestId('quickaccess'));
92
+
93
+ expect(await screen.findByText('Entity')).toBeVisible();
94
+ expect(await screen.findByText('Create')).toBeVisible();
95
+ expect(await screen.findByText('Go back')).toBeVisible();
96
+
97
+ // The button shown as open, the active element selected, and "Go back"
98
+ // before "Create".
99
+ expect(screen.getByTestId('quickaccess')).toHaveAttribute(
100
+ 'data-is-active',
101
+ 'true'
102
+ );
103
+ expect(screen.getByRole('menuitem', { name: 'Entity' })).toHaveClass(
104
+ 'Mui-selected'
105
+ );
106
+ expect(
107
+ screen.getByRole('button', { name: 'Go back' }).getBoundingClientRect()
108
+ .right
109
+ ).toBeLessThanOrEqual(
110
+ screen.getByRole('button', { name: 'Create' }).getBoundingClientRect()
111
+ .left
112
+ );
113
+ });
114
+ });
@@ -0,0 +1,237 @@
1
+ import { Button } from '@mui/material';
2
+
3
+ import { rs } from '@rstest/core';
4
+ import { render } from '@test-setup/render';
5
+ import { screen, waitFor } from '@testing-library/react';
6
+ import userEvent from '@testing-library/user-event';
7
+ import { atom, createStore, Provider, useSetAtom } from 'jotai';
8
+
9
+ import {
10
+ ConfirmationModal,
11
+ type ConfirmationModalProps
12
+ } from './ConfirmationModal';
13
+
14
+ const testAtom = atom<string | null>(null);
15
+
16
+ const buttonLabel = 'Click to open modal';
17
+
18
+ const TestComponent = (args: ConfirmationModalProps<string>): JSX.Element => {
19
+ const setAtom = useSetAtom(testAtom);
20
+
21
+ return (
22
+ <>
23
+ <Button onClick={() => setAtom('John')}>{buttonLabel}</Button>
24
+ <ConfirmationModal<string> {...args} />
25
+ </>
26
+ );
27
+ };
28
+
29
+ const staticLabels = {
30
+ cancel: 'Cancel',
31
+ confirm: 'Confirm',
32
+ description: 'Description',
33
+ title: 'Title'
34
+ };
35
+
36
+ const dynamicLabels = {
37
+ cancel: 'Cancel',
38
+ confirm: 'Confirm',
39
+ description: (data: string | null): string => `Description ${data}`,
40
+ title: (data: string | null): string => `Hello ${data}`
41
+ };
42
+
43
+ type InitializeProps = Pick<
44
+ ConfirmationModalProps<string>,
45
+ 'labels' | 'disabled' | 'hasCloseButton' | 'isDanger'
46
+ >;
47
+
48
+ interface InitializeResult {
49
+ cancel: ReturnType<typeof rs.fn>;
50
+ confirm: ReturnType<typeof rs.fn>;
51
+ }
52
+
53
+ const initialize = (props: InitializeProps): InitializeResult => {
54
+ const store = createStore();
55
+
56
+ const cancel = rs.fn();
57
+ const confirm = rs.fn();
58
+
59
+ render(
60
+ <Provider store={store}>
61
+ <TestComponent
62
+ {...props}
63
+ atom={testAtom}
64
+ onCancel={cancel}
65
+ onConfirm={confirm}
66
+ />
67
+ </Provider>
68
+ );
69
+
70
+ return {
71
+ cancel,
72
+ confirm
73
+ };
74
+ };
75
+
76
+ const openModal = async (): Promise<void> => {
77
+ await userEvent.click(screen.getByText(buttonLabel));
78
+ };
79
+
80
+ // The open modal: the title, the description, then the Cancel and Confirm
81
+ // buttons, in that order.
82
+ const expectModalContent = async ({
83
+ description,
84
+ title
85
+ }: {
86
+ description: string;
87
+ title: string;
88
+ }): Promise<void> => {
89
+ const dialog = await screen.findByRole('dialog');
90
+
91
+ expect(screen.getByTestId('modal-header')).toHaveTextContent(
92
+ new RegExp(`^${title}$`)
93
+ );
94
+ expect(dialog).toHaveTextContent(description);
95
+ expect(screen.getByTestId('cancel')).toBeVisible();
96
+ expect(screen.getByTestId('cancel')).toHaveTextContent(/^Cancel$/);
97
+ expect(screen.getByTestId('confirm')).toBeVisible();
98
+ expect(screen.getByTestId('confirm')).toHaveTextContent(/^Confirm$/);
99
+ expect(
100
+ screen
101
+ .getByTestId('cancel')
102
+ .compareDocumentPosition(screen.getByTestId('confirm'))
103
+ ).toBe(Node.DOCUMENT_POSITION_FOLLOWING);
104
+ };
105
+
106
+ const expectModalClosed = async (): Promise<void> => {
107
+ await waitFor(() => {
108
+ expect(screen.queryByText('Title')).not.toBeInTheDocument();
109
+ });
110
+ expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
111
+ expect(screen.getByText(buttonLabel)).toBeVisible();
112
+ };
113
+
114
+ describe('Confirmation modal', () => {
115
+ beforeEach(() => {
116
+ expect.hasAssertions();
117
+ });
118
+
119
+ it('displays the modal with static labels', async () => {
120
+ initialize({ labels: staticLabels });
121
+
122
+ await openModal();
123
+
124
+ expect(await screen.findByText('Title')).toBeVisible();
125
+ expect(screen.getByText('Description')).toBeVisible();
126
+ expect(screen.getByLabelText('close')).toBeVisible();
127
+
128
+ await expectModalContent({ description: 'Description', title: 'Title' });
129
+ expect(screen.getByTestId('confirm')).toBeEnabled();
130
+ expect(screen.getByTestId('confirm')).toHaveAttribute(
131
+ 'data-is-danger',
132
+ 'false'
133
+ );
134
+ });
135
+
136
+ it('displays the modal with dynamic labels', async () => {
137
+ initialize({ labels: dynamicLabels });
138
+
139
+ await openModal();
140
+
141
+ expect(await screen.findByText('Hello John')).toBeVisible();
142
+ expect(screen.getByText('Description John')).toBeVisible();
143
+
144
+ await expectModalContent({
145
+ description: 'Description John',
146
+ title: 'Hello John'
147
+ });
148
+ expect(screen.getByLabelText('close')).toBeVisible();
149
+ });
150
+
151
+ it('displays the confirm button as disabled when a prop is set', async () => {
152
+ initialize({ disabled: true, labels: staticLabels });
153
+
154
+ await openModal();
155
+
156
+ expect(await screen.findByText('Confirm')).toBeVisible();
157
+ expect(screen.getByTestId('confirm')).toBeDisabled();
158
+
159
+ await expectModalContent({ description: 'Description', title: 'Title' });
160
+ expect(screen.getByTestId('cancel')).toBeEnabled();
161
+ });
162
+
163
+ it('displays the confirm button as danger when a prop is set', async () => {
164
+ initialize({ isDanger: true, labels: staticLabels });
165
+
166
+ await openModal();
167
+
168
+ expect(await screen.findByText('Confirm')).toBeVisible();
169
+ expect(screen.getByTestId('confirm')).toHaveAttribute(
170
+ 'data-is-danger',
171
+ 'true'
172
+ );
173
+
174
+ await expectModalContent({ description: 'Description', title: 'Title' });
175
+
176
+ // A red Confirm button: its background is the theme's error colour.
177
+ const errorColorProbe = document.createElement('div');
178
+ errorColorProbe.style.backgroundColor = 'var(--color-error-main)';
179
+ document.body.appendChild(errorColorProbe);
180
+ const errorColor = getComputedStyle(errorColorProbe).backgroundColor;
181
+ errorColorProbe.remove();
182
+
183
+ expect(errorColor).not.toBe('rgba(0, 0, 0, 0)');
184
+ expect(
185
+ getComputedStyle(screen.getByTestId('confirm')).backgroundColor
186
+ ).toBe(errorColor);
187
+ });
188
+
189
+ it('displays the modal without the close button when a prop is set', async () => {
190
+ initialize({ hasCloseButton: false, labels: staticLabels });
191
+
192
+ await openModal();
193
+
194
+ await expectModalContent({ description: 'Description', title: 'Title' });
195
+ expect(screen.queryByLabelText('close')).not.toBeInTheDocument();
196
+ });
197
+
198
+ it('closes the modal when the close button is clicked', async () => {
199
+ initialize({ labels: staticLabels });
200
+
201
+ await openModal();
202
+
203
+ expect(await screen.findByText('Title')).toBeVisible();
204
+
205
+ await userEvent.click(screen.getByLabelText('close'));
206
+
207
+ await expectModalClosed();
208
+ });
209
+
210
+ it('closes the modal when the cancel button is clicked', async () => {
211
+ const { cancel } = initialize({ labels: staticLabels });
212
+
213
+ await openModal();
214
+
215
+ expect(await screen.findByText('Title')).toBeVisible();
216
+
217
+ await userEvent.click(screen.getByText('Cancel'));
218
+
219
+ expect(cancel).toHaveBeenCalledWith('John');
220
+
221
+ await expectModalClosed();
222
+ });
223
+
224
+ it('closes the modal when the confirm button is clicked', async () => {
225
+ const { confirm } = initialize({ labels: staticLabels });
226
+
227
+ await openModal();
228
+
229
+ expect(await screen.findByText('Title')).toBeVisible();
230
+
231
+ await userEvent.click(screen.getByText('Confirm'));
232
+
233
+ expect(confirm).toHaveBeenCalledWith('John');
234
+
235
+ await expectModalClosed();
236
+ });
237
+ });