eionet2-dashboard 3.2.0 → 3.2.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.
- package/CHANGELOG.md +23 -0
- package/Jenkinsfile +2 -2
- package/api/getGraphData/index.js +3 -4
- package/package.json +2 -2
- package/tabs/package-lock.json +2927 -1866
- package/tabs/package.json +3 -3
- package/tabs/public/auth-start.html +2 -2
- package/tabs/src/components/App.test.jsx +67 -0
- package/tabs/src/components/BottomMenu.test.jsx +94 -0
- package/tabs/src/components/CustomColumnResizeIcon.test.jsx +17 -0
- package/tabs/src/components/CustomDrawer.test.jsx +14 -0
- package/tabs/src/components/CustomGridToolbar.test.jsx +8 -0
- package/tabs/src/components/EventDialogTitle.test.jsx +25 -0
- package/tabs/src/components/HtmlBox.test.jsx +41 -0
- package/tabs/src/components/Privacy.test.jsx +11 -0
- package/tabs/src/components/ResizableGrid.test.jsx +64 -0
- package/tabs/src/components/Tab.scss +6 -0
- package/tabs/src/components/Tab.test.jsx +463 -0
- package/tabs/src/components/TabConfig.test.jsx +27 -0
- package/tabs/src/components/TabPanel.test.jsx +31 -0
- package/tabs/src/components/TermsOfUse.test.jsx +11 -0
- package/tabs/src/components/UnderConstruction.test.jsx +13 -0
- package/tabs/src/components/UserMenu.test.jsx +53 -0
- package/tabs/src/components/activity/Activity.test.jsx +218 -0
- package/tabs/src/components/activity/ConsultationList.test.jsx +114 -0
- package/tabs/src/components/activity/EventList.test.jsx +164 -0
- package/tabs/src/components/activity/GroupsTags.test.jsx +23 -0
- package/tabs/src/components/activity/ObligationList.test.jsx +46 -0
- package/tabs/src/components/activity/PublicationList.test.jsx +46 -0
- package/tabs/src/components/activity/Reporting.test.jsx +11 -0
- package/tabs/src/components/event_rating/EventRating.test.jsx +63 -0
- package/tabs/src/components/event_rating/EventRatingDialog.test.jsx +28 -0
- package/tabs/src/components/event_registration/Approval.test.jsx +25 -0
- package/tabs/src/components/event_registration/ApprovalDialog.test.jsx +25 -0
- package/tabs/src/components/event_registration/ApprovalList.test.jsx +36 -0
- package/tabs/src/components/event_registration/EventExternalRegistration.test.jsx +219 -0
- package/tabs/src/components/event_registration/EventRegistration.test.jsx +208 -0
- package/tabs/src/components/my_country/AtAGlance.test.jsx +157 -0
- package/tabs/src/components/my_country/CountryMembers.test.jsx +117 -0
- package/tabs/src/components/my_country/CountryProgress.test.jsx +21 -0
- package/tabs/src/components/my_country/DataReporters.test.jsx +156 -0
- package/tabs/src/components/my_country/FullCircularProgress.test.jsx +19 -0
- package/tabs/src/components/my_country/GroupView.test.jsx +165 -0
- package/tabs/src/components/my_country/GroupsBoard.test.jsx +30 -0
- package/tabs/src/components/my_country/IndicatorCard.test.jsx +27 -0
- package/tabs/src/components/my_country/ManagementBoard.test.jsx +119 -0
- package/tabs/src/components/my_country/MyCountry.test.jsx +220 -0
- package/tabs/src/components/my_country/ProgressGauge.test.jsx +34 -0
- package/tabs/src/components/my_country/ScientificCommittee.test.jsx +11 -0
- package/tabs/src/components/my_country/UserCard.test.jsx +24 -0
- package/tabs/src/components/my_country/YearlyProgress.test.jsx +33 -0
- package/tabs/src/components/self_service/UserEdit.test.jsx +213 -0
- package/tabs/src/data/apiProvider.test.js +228 -0
- package/tabs/src/data/icsHelper.test.js +76 -0
- package/tabs/src/data/provider.test.js +351 -0
- package/tabs/src/data/reportingProvider.test.js +103 -0
- package/tabs/src/data/selfServiceProvider.test.js +108 -0
- package/tabs/src/data/selfServiceSharepointProvider.test.js +100 -0
- package/tabs/src/data/sharepointProvider.test.js +669 -0
- package/tabs/src/data/validator.test.js +34 -2
- package/tabs/yarn.lock +415 -414
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
jest.mock('react', () => {
|
|
2
|
+
const actual = jest.requireActual('react');
|
|
3
|
+
return {
|
|
4
|
+
...actual,
|
|
5
|
+
React: actual,
|
|
6
|
+
useState: jest.fn(actual.useState),
|
|
7
|
+
useEffect: jest.fn((fn) => fn()),
|
|
8
|
+
useCallback: jest.fn((fn) => fn),
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
import React from 'react';
|
|
13
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
14
|
+
import { Activity } from './Activity';
|
|
15
|
+
import {
|
|
16
|
+
getConsultations,
|
|
17
|
+
getMeetings,
|
|
18
|
+
getPublications,
|
|
19
|
+
getObligations,
|
|
20
|
+
} from '../../data/sharepointProvider';
|
|
21
|
+
import { useAppInsightsContext } from '@microsoft/applicationinsights-react-js';
|
|
22
|
+
|
|
23
|
+
jest.mock('./activity.scss', () => ({}));
|
|
24
|
+
|
|
25
|
+
jest.mock('@mui/material', () => {
|
|
26
|
+
const ReactLocal = require('react');
|
|
27
|
+
const passthrough =
|
|
28
|
+
(Tag = 'div') =>
|
|
29
|
+
({ children }) =>
|
|
30
|
+
ReactLocal.createElement(Tag, {}, children);
|
|
31
|
+
|
|
32
|
+
const ListItemButton = ({ children, onClick }) => {
|
|
33
|
+
onClick && onClick();
|
|
34
|
+
return <div>{children}</div>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
Backdrop: passthrough(),
|
|
39
|
+
CircularProgress: passthrough('span'),
|
|
40
|
+
Box: passthrough(),
|
|
41
|
+
ListItem: passthrough(),
|
|
42
|
+
ListItemIcon: passthrough(),
|
|
43
|
+
ListItemText: ({ primary }) => <div>{primary}</div>,
|
|
44
|
+
ListItemButton,
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
jest.mock('@mui/icons-material/Loop', () => () => <span>loop-icon</span>);
|
|
49
|
+
jest.mock('@mui/icons-material/FastForwardOutlined', () => () => <span>fast-forward-icon</span>);
|
|
50
|
+
jest.mock('@mui/icons-material/HistoryOutlined', () => () => <span>history-icon</span>);
|
|
51
|
+
jest.mock('@mui/icons-material/NextPlanOutlined', () => () => <span>next-plan-icon</span>);
|
|
52
|
+
|
|
53
|
+
jest.mock('./ConsultationList', () => ({
|
|
54
|
+
ConsultationList: () => <div>consultation-list</div>,
|
|
55
|
+
}));
|
|
56
|
+
jest.mock('./EventList', () => ({
|
|
57
|
+
EventList: () => <div>event-list</div>,
|
|
58
|
+
}));
|
|
59
|
+
jest.mock('./PublicationList', () => ({
|
|
60
|
+
PublicatonList: () => <div>publication-list</div>,
|
|
61
|
+
}));
|
|
62
|
+
jest.mock('./ObligationList', () => ({
|
|
63
|
+
ObligationList: () => <div>obligation-list</div>,
|
|
64
|
+
}));
|
|
65
|
+
|
|
66
|
+
jest.mock('../CustomDrawer', () => ({
|
|
67
|
+
__esModule: true,
|
|
68
|
+
default: ({ drawerOptions }) => <div>{drawerOptions}</div>,
|
|
69
|
+
}));
|
|
70
|
+
|
|
71
|
+
jest.mock('../../data/sharepointProvider', () => ({
|
|
72
|
+
getConsultations: jest.fn(),
|
|
73
|
+
getMeetings: jest.fn(),
|
|
74
|
+
getPublications: jest.fn(),
|
|
75
|
+
getObligations: jest.fn(),
|
|
76
|
+
}));
|
|
77
|
+
|
|
78
|
+
jest.mock('@microsoft/applicationinsights-react-js', () => ({
|
|
79
|
+
useAppInsightsContext: jest.fn(),
|
|
80
|
+
}));
|
|
81
|
+
|
|
82
|
+
function mockStateSequence(values) {
|
|
83
|
+
let index = 0;
|
|
84
|
+
React.useState.mockImplementation((initialValue) => {
|
|
85
|
+
if (index < values.length) {
|
|
86
|
+
const current = values[index];
|
|
87
|
+
index += 1;
|
|
88
|
+
return [current, jest.fn()];
|
|
89
|
+
}
|
|
90
|
+
return [initialValue, jest.fn()];
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function buildStates(tabsValue) {
|
|
95
|
+
return [
|
|
96
|
+
tabsValue,
|
|
97
|
+
[{ id: 'past' }],
|
|
98
|
+
[{ id: 'current' }],
|
|
99
|
+
[{ id: 'upcoming' }],
|
|
100
|
+
[{ id: 'open-consultation' }],
|
|
101
|
+
[{ id: 'review-consultation' }],
|
|
102
|
+
[{ id: 'final-consultation' }],
|
|
103
|
+
[{ id: 'future-consultation' }],
|
|
104
|
+
[{ id: 'open-survey' }],
|
|
105
|
+
[{ id: 'review-survey' }],
|
|
106
|
+
[{ id: 'final-survey' }],
|
|
107
|
+
[{ id: 'future-survey' }],
|
|
108
|
+
[{ id: 'future-publication' }],
|
|
109
|
+
[{ id: 'past-publication' }],
|
|
110
|
+
[{ id: 'upcoming-obligation' }],
|
|
111
|
+
[{ id: 'continuous-obligation' }],
|
|
112
|
+
false,
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
describe('Activity', () => {
|
|
117
|
+
const trackEvent = jest.fn();
|
|
118
|
+
const closeDrawer = jest.fn();
|
|
119
|
+
|
|
120
|
+
const baseProps = {
|
|
121
|
+
userInfo: { country: 'RO', isEionetUser: true, isNFP: true },
|
|
122
|
+
country: 'RO',
|
|
123
|
+
configuration: { DashboardNumberOfMonthsData: 24, PublicationsType: 'Report;Article' },
|
|
124
|
+
setData4Menu: jest.fn(),
|
|
125
|
+
openRating: jest.fn(),
|
|
126
|
+
openApproval: jest.fn(),
|
|
127
|
+
drawerOpen: true,
|
|
128
|
+
closeDrawer,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
beforeEach(() => {
|
|
132
|
+
jest.clearAllMocks();
|
|
133
|
+
React.useCallback.mockImplementation((fn) => fn);
|
|
134
|
+
React.useEffect.mockImplementation((fn) => fn());
|
|
135
|
+
React.useState.mockImplementation((initialValue) => [initialValue, jest.fn()]);
|
|
136
|
+
|
|
137
|
+
useAppInsightsContext.mockReturnValue({ trackEvent });
|
|
138
|
+
|
|
139
|
+
getMeetings.mockResolvedValue([{ IsCurrent: true }, { IsUpcoming: true }, { IsPast: true }]);
|
|
140
|
+
getConsultations.mockResolvedValue([]);
|
|
141
|
+
getPublications.mockResolvedValue([{ ItemType: 'Report', IsPast: false }]);
|
|
142
|
+
getObligations.mockResolvedValue([{ IsUpcoming: true, IsContinuous: false }]);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('renders drawer sections and event tab by default', () => {
|
|
146
|
+
mockStateSequence(buildStates(0));
|
|
147
|
+
|
|
148
|
+
const html = renderToStaticMarkup(<Activity {...baseProps} />);
|
|
149
|
+
|
|
150
|
+
expect(html).toContain('EVENTS');
|
|
151
|
+
expect(html).toContain('CONSULTATIONS');
|
|
152
|
+
expect(html).toContain('ENQUIRIES');
|
|
153
|
+
expect(html).toContain('PUBLICATIONS & OUTREACH');
|
|
154
|
+
expect(html).toContain('REPORTING OBLIGATIONS');
|
|
155
|
+
expect(html).toContain('event-list');
|
|
156
|
+
expect(closeDrawer).toHaveBeenCalled();
|
|
157
|
+
expect(trackEvent).toHaveBeenCalled();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test('renders consultations view for consultation tabs', () => {
|
|
161
|
+
mockStateSequence(buildStates(4));
|
|
162
|
+
|
|
163
|
+
const html = renderToStaticMarkup(<Activity {...baseProps} />);
|
|
164
|
+
|
|
165
|
+
expect(html).toContain('consultation-list');
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test('renders surveys view for enquiries tabs', () => {
|
|
169
|
+
mockStateSequence(buildStates(8));
|
|
170
|
+
|
|
171
|
+
const html = renderToStaticMarkup(<Activity {...baseProps} />);
|
|
172
|
+
|
|
173
|
+
expect(html).toContain('consultation-list');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('renders publications view', () => {
|
|
177
|
+
mockStateSequence(buildStates(11));
|
|
178
|
+
|
|
179
|
+
const html = renderToStaticMarkup(<Activity {...baseProps} />);
|
|
180
|
+
|
|
181
|
+
expect(html).toContain('publication-list');
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('renders obligations view', () => {
|
|
185
|
+
mockStateSequence(buildStates(13));
|
|
186
|
+
|
|
187
|
+
const html = renderToStaticMarkup(<Activity {...baseProps} />);
|
|
188
|
+
|
|
189
|
+
expect(html).toContain('obligation-list');
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test('loads activity data in effect', async () => {
|
|
193
|
+
mockStateSequence(buildStates(0));
|
|
194
|
+
|
|
195
|
+
renderToStaticMarkup(<Activity {...baseProps} />);
|
|
196
|
+
await Promise.resolve();
|
|
197
|
+
await Promise.resolve();
|
|
198
|
+
|
|
199
|
+
expect(getMeetings).toHaveBeenCalled();
|
|
200
|
+
expect(getConsultations).toHaveBeenCalled();
|
|
201
|
+
expect(getPublications).toHaveBeenCalled();
|
|
202
|
+
expect(getObligations).toHaveBeenCalled();
|
|
203
|
+
expect(baseProps.setData4Menu).toHaveBeenCalled();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test('handles meeting loading errors', async () => {
|
|
207
|
+
const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
208
|
+
getMeetings.mockRejectedValue(new Error('boom'));
|
|
209
|
+
mockStateSequence(buildStates(0));
|
|
210
|
+
|
|
211
|
+
renderToStaticMarkup(<Activity {...baseProps} />);
|
|
212
|
+
await Promise.resolve();
|
|
213
|
+
await Promise.resolve();
|
|
214
|
+
|
|
215
|
+
expect(logSpy).toHaveBeenCalledWith('boom');
|
|
216
|
+
logSpy.mockRestore();
|
|
217
|
+
});
|
|
218
|
+
});
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
3
|
+
import { ConsultationList } from './ConsultationList';
|
|
4
|
+
|
|
5
|
+
let mockGridProps;
|
|
6
|
+
|
|
7
|
+
jest.mock('../ResizableGrid', () => ({
|
|
8
|
+
__esModule: true,
|
|
9
|
+
default: (props) => {
|
|
10
|
+
mockGridProps = props;
|
|
11
|
+
return <div>grid-rows-{props.rows?.length || 0}</div>;
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
jest.mock('./GroupsTags', () => ({
|
|
16
|
+
GroupsTags: ({ groups }) => <div>groups-{groups?.length || 0}</div>,
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
describe('ConsultationList', () => {
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
mockGridProps = null;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('renders future consultations grid for tab 0', () => {
|
|
25
|
+
const html = renderToStaticMarkup(
|
|
26
|
+
<ConsultationList
|
|
27
|
+
configuration={{ DateFormatDashboard: 'dd-MMM-yyyy' }}
|
|
28
|
+
openConsultations={[]}
|
|
29
|
+
reviewConsultations={[]}
|
|
30
|
+
finalisedConsultations={[]}
|
|
31
|
+
futureConsultations={[{ id: 1, Title: 'Future' }]}
|
|
32
|
+
type="Consultations"
|
|
33
|
+
country="RO"
|
|
34
|
+
tabsValue={0}
|
|
35
|
+
/>,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
expect(html).toContain('grid-rows-1');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('renders open consultations grid for tab 1 and colors urgent values', () => {
|
|
42
|
+
const html = renderToStaticMarkup(
|
|
43
|
+
<ConsultationList
|
|
44
|
+
configuration={{ DateFormatDashboard: 'dd-MMM-yyyy' }}
|
|
45
|
+
openConsultations={[{ id: 1, Title: 'Open' }]}
|
|
46
|
+
reviewConsultations={[]}
|
|
47
|
+
finalisedConsultations={[]}
|
|
48
|
+
futureConsultations={[]}
|
|
49
|
+
type="Consultations"
|
|
50
|
+
country=""
|
|
51
|
+
tabsValue={1}
|
|
52
|
+
/>,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
expect(html).toContain('grid-rows-1');
|
|
56
|
+
const daysLeftColumn = mockGridProps.columns.find((column) => column.field === 'DaysLeft');
|
|
57
|
+
expect(daysLeftColumn.cellClassName({ value: 2 })).toBe('red-cell-text');
|
|
58
|
+
expect(daysLeftColumn.cellClassName({ value: 4 })).toBeUndefined();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('renders review grid for tab 2', () => {
|
|
62
|
+
const html = renderToStaticMarkup(
|
|
63
|
+
<ConsultationList
|
|
64
|
+
configuration={{ DateFormatDashboard: 'dd-MMM-yyyy' }}
|
|
65
|
+
openConsultations={[]}
|
|
66
|
+
reviewConsultations={[{ id: 3, Title: 'Review', Startdate: new Date('2026-01-01') }]}
|
|
67
|
+
finalisedConsultations={[]}
|
|
68
|
+
futureConsultations={[]}
|
|
69
|
+
type="Consultations"
|
|
70
|
+
country="RO"
|
|
71
|
+
tabsValue={2}
|
|
72
|
+
/>,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
expect(html).toContain('grid-rows-1');
|
|
76
|
+
expect(mockGridProps.columns.some((column) => column.field === 'DaysFinalised')).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('renders finalised grid for tab 3 and result/country cells', () => {
|
|
80
|
+
renderToStaticMarkup(
|
|
81
|
+
<ConsultationList
|
|
82
|
+
configuration={{
|
|
83
|
+
DateFormatDashboard: 'dd-MMM-yyyy',
|
|
84
|
+
ConsultationResultsTooltip: 'results',
|
|
85
|
+
CountryRespondedTooltip: 'responded',
|
|
86
|
+
}}
|
|
87
|
+
openConsultations={[]}
|
|
88
|
+
reviewConsultations={[]}
|
|
89
|
+
finalisedConsultations={[{ id: 4, Title: 'Final', Deadline: new Date('2026-02-01') }]}
|
|
90
|
+
futureConsultations={[]}
|
|
91
|
+
type="Consultations"
|
|
92
|
+
country=""
|
|
93
|
+
tabsValue={3}
|
|
94
|
+
/>,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const resultsColumn = mockGridProps.columns.find((column) => column.field === 'Results');
|
|
98
|
+
const respondantsColumn = mockGridProps.columns.find(
|
|
99
|
+
(column) => column.field === 'HasUserCountryResponded',
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const resultHtml = renderToStaticMarkup(
|
|
103
|
+
resultsColumn.renderCell({ row: { LinkToResults: 'https://example.org/results' } }),
|
|
104
|
+
);
|
|
105
|
+
const respondedHtml = renderToStaticMarkup(
|
|
106
|
+
respondantsColumn.renderCell({
|
|
107
|
+
row: { HasUserCountryResponded: false, Respondants: [{}, {}, {}] },
|
|
108
|
+
}),
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
expect(resultHtml).toContain('button');
|
|
112
|
+
expect(respondedHtml).toContain('3');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
3
|
+
import { EventList } from './EventList';
|
|
4
|
+
|
|
5
|
+
let mockGridProps;
|
|
6
|
+
|
|
7
|
+
jest.mock('../ResizableGrid', () => ({
|
|
8
|
+
__esModule: true,
|
|
9
|
+
default: (props) => {
|
|
10
|
+
mockGridProps = props;
|
|
11
|
+
return <div>grid-rows-{props.rows?.length || 0}</div>;
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
jest.mock('./GroupsTags', () => ({
|
|
16
|
+
GroupsTags: ({ groups }) => <div>groups-{groups?.length || 0}</div>,
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
jest.mock('../event_registration/EventRegistration', () => ({
|
|
20
|
+
EventRegistration: () => <div>event-registration</div>,
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
jest.mock('../event_registration/EventExternalRegistration', () => ({
|
|
24
|
+
EventExternalRegistration: () => <div>event-external-registration</div>,
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
jest.mock('../EventDialogTitle', () => ({
|
|
28
|
+
EventDialogTitle: () => <div>event-dialog-title</div>,
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
jest.mock('../../data/sharepointProvider', () => ({
|
|
32
|
+
getCurrentParticipant: jest.fn(),
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
jest.mock('../../static/images/teams-icon.svg', () => ({
|
|
36
|
+
ReactComponent: () => <svg />,
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
describe('EventList', () => {
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
mockGridProps = null;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('renders upcoming meetings grid for tab 0', () => {
|
|
45
|
+
const html = renderToStaticMarkup(
|
|
46
|
+
<EventList
|
|
47
|
+
userInfo={{ country: 'RO', isEionetUser: true, isNFP: true }}
|
|
48
|
+
configuration={{
|
|
49
|
+
DateFormatDashboard: 'dd-MMM-yyyy',
|
|
50
|
+
RegisterEventButtonTooltip: 'register',
|
|
51
|
+
RegisterOthersButtonTooltip: 'register others',
|
|
52
|
+
}}
|
|
53
|
+
pastMeetings={[]}
|
|
54
|
+
currentMeetings={[]}
|
|
55
|
+
upcomingMeetings={[
|
|
56
|
+
{
|
|
57
|
+
id: 1,
|
|
58
|
+
Title: 'Upcoming meeting',
|
|
59
|
+
MeetingType: 'Physical',
|
|
60
|
+
NoOfRegistered: 2,
|
|
61
|
+
IsUpcoming: true,
|
|
62
|
+
},
|
|
63
|
+
]}
|
|
64
|
+
tabsValue={0}
|
|
65
|
+
openRating={jest.fn()}
|
|
66
|
+
openApproval={jest.fn()}
|
|
67
|
+
/>,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
expect(html).toContain('grid-rows-1');
|
|
71
|
+
expect(mockGridProps.columns.some((column) => column.field === 'MeetingRegistrationLink')).toBe(
|
|
72
|
+
true,
|
|
73
|
+
);
|
|
74
|
+
expect(mockGridProps.columns.some((column) => column.field === 'Approval')).toBe(true);
|
|
75
|
+
expect(mockGridProps.columns.some((column) => column.field === 'id')).toBe(true);
|
|
76
|
+
expect(mockGridProps.columns.some((column) => column.field === 'NoOfRegistered')).toBe(true);
|
|
77
|
+
|
|
78
|
+
const registerColumn = mockGridProps.columns.find(
|
|
79
|
+
(column) => column.field === 'MeetingRegistrationLink',
|
|
80
|
+
);
|
|
81
|
+
const registerHtml = renderToStaticMarkup(
|
|
82
|
+
registerColumn.renderCell({ row: { MeetingType: 'physical', MeetingLink: '' } }),
|
|
83
|
+
);
|
|
84
|
+
expect(registerHtml).toContain('button');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('renders current meetings grid for tab 1', () => {
|
|
88
|
+
const html = renderToStaticMarkup(
|
|
89
|
+
<EventList
|
|
90
|
+
userInfo={{ country: 'RO', isEionetUser: true, isNFP: true }}
|
|
91
|
+
configuration={{ DateFormatDashboard: 'dd-MMM-yyyy', JoinEventButtonTooltip: 'join' }}
|
|
92
|
+
pastMeetings={[]}
|
|
93
|
+
currentMeetings={[
|
|
94
|
+
{
|
|
95
|
+
id: 2,
|
|
96
|
+
Title: 'Current meeting',
|
|
97
|
+
MeetingType: 'Online',
|
|
98
|
+
MeetingLink: 'https://example.org/meeting',
|
|
99
|
+
NoOfRegistered: 3,
|
|
100
|
+
IsCurrent: true,
|
|
101
|
+
AllowVote: true,
|
|
102
|
+
HasVoted: true,
|
|
103
|
+
MeetingStart: new Date('2026-01-01'),
|
|
104
|
+
},
|
|
105
|
+
]}
|
|
106
|
+
upcomingMeetings={[]}
|
|
107
|
+
tabsValue={1}
|
|
108
|
+
openRating={jest.fn()}
|
|
109
|
+
openApproval={jest.fn()}
|
|
110
|
+
/>,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
expect(html).toContain('grid-rows-1');
|
|
114
|
+
expect(mockGridProps.columns.some((column) => column.field === 'MeetingLink')).toBe(true);
|
|
115
|
+
expect(mockGridProps.columns.some((column) => column.field === 'AllowVote')).toBe(true);
|
|
116
|
+
|
|
117
|
+
const ratingColumn = mockGridProps.columns.find((column) => column.field === 'AllowVote');
|
|
118
|
+
const ratingHtml = renderToStaticMarkup(
|
|
119
|
+
ratingColumn.renderCell({ row: { AllowVote: true, HasVoted: true } }),
|
|
120
|
+
);
|
|
121
|
+
expect(ratingHtml).toContain('button');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('renders past meetings grid for tab 2 with participants and no rating for missing country', () => {
|
|
125
|
+
const html = renderToStaticMarkup(
|
|
126
|
+
<EventList
|
|
127
|
+
userInfo={{ country: '', isEionetUser: false, isNFP: false }}
|
|
128
|
+
configuration={{
|
|
129
|
+
DateFormatDashboard: 'dd-MMM-yyyy',
|
|
130
|
+
NoOfParticipantsTooltip: 'participants',
|
|
131
|
+
}}
|
|
132
|
+
pastMeetings={[
|
|
133
|
+
{
|
|
134
|
+
id: 3,
|
|
135
|
+
Title: 'Past meeting',
|
|
136
|
+
IsPast: true,
|
|
137
|
+
NoOfParticipants: 0,
|
|
138
|
+
MeetingStart: new Date('2026-01-01'),
|
|
139
|
+
MeetingEnd: new Date('2026-01-02'),
|
|
140
|
+
},
|
|
141
|
+
]}
|
|
142
|
+
currentMeetings={[]}
|
|
143
|
+
upcomingMeetings={[]}
|
|
144
|
+
tabsValue={2}
|
|
145
|
+
openRating={jest.fn()}
|
|
146
|
+
openApproval={jest.fn()}
|
|
147
|
+
/>,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
expect(html).toContain('grid-rows-1');
|
|
151
|
+
expect(mockGridProps.columns.some((column) => column.field === 'NoOfParticipants')).toBe(true);
|
|
152
|
+
expect(mockGridProps.columns.some((column) => column.field === 'AllowVote')).toBe(false);
|
|
153
|
+
|
|
154
|
+
const participantsColumn = mockGridProps.columns.find(
|
|
155
|
+
(column) => column.field === 'NoOfParticipants',
|
|
156
|
+
);
|
|
157
|
+
const participantsHtml = renderToStaticMarkup(
|
|
158
|
+
participantsColumn.renderCell({
|
|
159
|
+
row: { IsPast: true, NoOfParticipants: 0, ParticipantsUrl: '' },
|
|
160
|
+
}),
|
|
161
|
+
);
|
|
162
|
+
expect(participantsHtml).toContain('N/A');
|
|
163
|
+
});
|
|
164
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
3
|
+
import { GroupsTags } from './GroupsTags';
|
|
4
|
+
|
|
5
|
+
describe('GroupsTags', () => {
|
|
6
|
+
test('renders chips and dialog class when isDialog is true', () => {
|
|
7
|
+
const html = renderToStaticMarkup(
|
|
8
|
+
<GroupsTags groups={['A', 'B']} handleClick={jest.fn()} isDialog={true} />,
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
expect(html).toContain('groups-tags-dialog');
|
|
12
|
+
expect(html).toContain('A');
|
|
13
|
+
expect(html).toContain('B');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('renders without dialog class when isDialog is false', () => {
|
|
17
|
+
const html = renderToStaticMarkup(
|
|
18
|
+
<GroupsTags groups={['A']} handleClick={jest.fn()} isDialog={false} />,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
expect(html).not.toContain('groups-tags-dialog');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
3
|
+
import { ObligationList } from './ObligationList';
|
|
4
|
+
|
|
5
|
+
jest.mock('../ResizableGrid', () => ({
|
|
6
|
+
__esModule: true,
|
|
7
|
+
default: ({ rows }) => <div>grid-rows-{rows?.length || 0}</div>,
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
jest.mock('../HtmlBox', () => ({
|
|
11
|
+
HtmlBox: ({ html }) => <div>{html}</div>,
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
describe('ObligationList', () => {
|
|
15
|
+
test('renders intro text and upcoming obligations grid for tab 0', () => {
|
|
16
|
+
const html = renderToStaticMarkup(
|
|
17
|
+
<ObligationList
|
|
18
|
+
userInfo={{}}
|
|
19
|
+
configuration={{
|
|
20
|
+
DateFormatDashboard: 'dd-MMM-yyyy',
|
|
21
|
+
ReportingObligationsIntroText: 'Reporting intro',
|
|
22
|
+
}}
|
|
23
|
+
upcomingObligations={[{ id: 1, Title: 'Upcoming' }]}
|
|
24
|
+
continuousObligations={[]}
|
|
25
|
+
tabsValue={0}
|
|
26
|
+
/>,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
expect(html).toContain('Reporting intro');
|
|
30
|
+
expect(html).toContain('grid-rows-1');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('renders continuous obligations grid for tab 1', () => {
|
|
34
|
+
const html = renderToStaticMarkup(
|
|
35
|
+
<ObligationList
|
|
36
|
+
userInfo={{}}
|
|
37
|
+
configuration={{ DateFormatDashboard: 'dd-MMM-yyyy' }}
|
|
38
|
+
upcomingObligations={[]}
|
|
39
|
+
continuousObligations={[{ id: 1, Title: 'Continuous' }]}
|
|
40
|
+
tabsValue={1}
|
|
41
|
+
/>,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(html).toContain('grid-rows-1');
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
3
|
+
import { PublicatonList } from './PublicationList';
|
|
4
|
+
|
|
5
|
+
jest.mock('../ResizableGrid', () => ({
|
|
6
|
+
__esModule: true,
|
|
7
|
+
default: ({ rows }) => <div>grid-rows-{rows?.length || 0}</div>,
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
jest.mock('../HtmlBox', () => ({
|
|
11
|
+
HtmlBox: ({ html }) => <div>{html}</div>,
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
describe('PublicationList', () => {
|
|
15
|
+
test('renders intro text and future publications grid for tab 0', () => {
|
|
16
|
+
const html = renderToStaticMarkup(
|
|
17
|
+
<PublicatonList
|
|
18
|
+
userInfo={{}}
|
|
19
|
+
configuration={{
|
|
20
|
+
DateFormatDashboard: 'dd-MMM-yyyy',
|
|
21
|
+
PublicationsIntroText: 'Intro text',
|
|
22
|
+
}}
|
|
23
|
+
futurePublications={[{ id: 1, Title: 'Future Publication' }]}
|
|
24
|
+
pastPublications={[]}
|
|
25
|
+
tabsValue={0}
|
|
26
|
+
/>,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
expect(html).toContain('Intro text');
|
|
30
|
+
expect(html).toContain('grid-rows-1');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('renders past publications grid for tab 1', () => {
|
|
34
|
+
const html = renderToStaticMarkup(
|
|
35
|
+
<PublicatonList
|
|
36
|
+
userInfo={{}}
|
|
37
|
+
configuration={{ DateFormatDashboard: 'dd-MMM-yyyy' }}
|
|
38
|
+
futurePublications={[]}
|
|
39
|
+
pastPublications={[{ id: 1, Title: 'Past Publication' }]}
|
|
40
|
+
tabsValue={1}
|
|
41
|
+
/>,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(html).toContain('grid-rows-1');
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
3
|
+
import { Reporting } from './Reporting';
|
|
4
|
+
|
|
5
|
+
describe('Reporting', () => {
|
|
6
|
+
test('renders under construction message', () => {
|
|
7
|
+
const html = renderToStaticMarkup(<Reporting />);
|
|
8
|
+
|
|
9
|
+
expect(html).toContain('Page under construction');
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
3
|
+
import { EventRating } from './EventRating';
|
|
4
|
+
|
|
5
|
+
jest.mock('@mui/material', () => {
|
|
6
|
+
const ReactLocal = require('react');
|
|
7
|
+
const passthrough =
|
|
8
|
+
(Tag = 'div') =>
|
|
9
|
+
({ children }) =>
|
|
10
|
+
ReactLocal.createElement(Tag, {}, children);
|
|
11
|
+
|
|
12
|
+
const Rating = ({ value, getLabelText }) => (
|
|
13
|
+
<div>
|
|
14
|
+
<span>rating-value-{value}</span>
|
|
15
|
+
<span>{getLabelText ? getLabelText(value) : ''}</span>
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
Box: passthrough(),
|
|
21
|
+
Button: ({ children }) => <button>{children}</button>,
|
|
22
|
+
CircularProgress: passthrough('span'),
|
|
23
|
+
Backdrop: passthrough(),
|
|
24
|
+
Rating,
|
|
25
|
+
Typography: passthrough('span'),
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
jest.mock('@mui/icons-material/Check', () => () => <span>check-icon</span>);
|
|
30
|
+
jest.mock('@mui/icons-material/Save', () => () => <span>save-icon</span>);
|
|
31
|
+
jest.mock('@mui/icons-material/Star', () => () => <span>star-icon</span>);
|
|
32
|
+
|
|
33
|
+
jest.mock('../../data/sharepointProvider', () => ({
|
|
34
|
+
postRating: jest.fn(),
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
describe('EventRating', () => {
|
|
38
|
+
test('renders modal text, rating caption and confirm button', () => {
|
|
39
|
+
const html = renderToStaticMarkup(
|
|
40
|
+
<EventRating
|
|
41
|
+
configuration={{ EventRatingModalText: 'Please rate this event' }}
|
|
42
|
+
participant={{ id: 1 }}
|
|
43
|
+
event={{ id: 2 }}
|
|
44
|
+
onRate={jest.fn()}
|
|
45
|
+
/>,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
expect(html).toContain('Please rate this event');
|
|
49
|
+
expect(html).toContain('rating-value-5');
|
|
50
|
+
expect(html).toContain('5 Stars, Excellent');
|
|
51
|
+
expect(html).toContain('Excellent');
|
|
52
|
+
expect(html).toContain('Confirm rating');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('renders without optional modal text', () => {
|
|
56
|
+
const html = renderToStaticMarkup(
|
|
57
|
+
<EventRating configuration={{}} participant={{}} event={{}} onRate={jest.fn()} />,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
expect(html).not.toContain('Please rate this event');
|
|
61
|
+
expect(html).toContain('Confirm rating');
|
|
62
|
+
});
|
|
63
|
+
});
|