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,103 @@
|
|
|
1
|
+
jest.mock('./apiProvider', () => ({
|
|
2
|
+
apiGet: jest.fn(),
|
|
3
|
+
getConfiguration: jest.fn(),
|
|
4
|
+
}));
|
|
5
|
+
|
|
6
|
+
const { apiGet, getConfiguration } = require('./apiProvider');
|
|
7
|
+
const { getFlows } = require('./reportingProvider');
|
|
8
|
+
|
|
9
|
+
describe('getFlows', () => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
jest.clearAllMocks();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('returns empty array when country is missing', async () => {
|
|
15
|
+
const result = await getFlows();
|
|
16
|
+
|
|
17
|
+
expect(result).toEqual([]);
|
|
18
|
+
expect(getConfiguration).not.toHaveBeenCalled();
|
|
19
|
+
expect(apiGet).not.toHaveBeenCalled();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('maps paginated graph response and capitalizes status', async () => {
|
|
23
|
+
getConfiguration.mockResolvedValue({
|
|
24
|
+
SharepointSiteId: 'site-id',
|
|
25
|
+
ReportnetFlowsListId: 'flows-id',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
apiGet
|
|
29
|
+
.mockResolvedValueOnce({
|
|
30
|
+
graphClientMessage: {
|
|
31
|
+
value: [
|
|
32
|
+
{
|
|
33
|
+
id: '1',
|
|
34
|
+
fields: {
|
|
35
|
+
Country: 'RO',
|
|
36
|
+
DataflowId: 'DF-1',
|
|
37
|
+
DataflowName: 'Flow one',
|
|
38
|
+
DataflowURL: 'https://flow-1',
|
|
39
|
+
ObligationName: 'Obl',
|
|
40
|
+
ObligationURL: 'https://obl',
|
|
41
|
+
LegalInstrumentName: 'Law',
|
|
42
|
+
LegalInstrumentURL: 'https://law',
|
|
43
|
+
DeadlineDate: '2025-10-01',
|
|
44
|
+
Status: 'IN_PROGRESS',
|
|
45
|
+
ReporterEmails: 'a@example.org,b@example.org',
|
|
46
|
+
FirstReleaseDate: '2025-01-01',
|
|
47
|
+
LastReleaseDate: '2025-01-02',
|
|
48
|
+
DeliveryStatus: 'ok',
|
|
49
|
+
IsEEACore: true,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
'@odata.nextLink': 'next-page',
|
|
54
|
+
},
|
|
55
|
+
})
|
|
56
|
+
.mockResolvedValueOnce({
|
|
57
|
+
graphClientMessage: {
|
|
58
|
+
value: [
|
|
59
|
+
{
|
|
60
|
+
id: '2',
|
|
61
|
+
fields: {
|
|
62
|
+
Country: 'RO',
|
|
63
|
+
DataflowId: 'DF-2',
|
|
64
|
+
DataflowName: 'Flow two',
|
|
65
|
+
Status: 'DONE',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const result = await getFlows('RO');
|
|
73
|
+
|
|
74
|
+
expect(apiGet).toHaveBeenCalledTimes(2);
|
|
75
|
+
expect(apiGet.mock.calls[0][0]).toContain("$filter=fields/Country eq 'RO'");
|
|
76
|
+
expect(apiGet.mock.calls[1][0]).toBe('next-page');
|
|
77
|
+
expect(result).toHaveLength(2);
|
|
78
|
+
expect(result[0]).toEqual(
|
|
79
|
+
expect.objectContaining({
|
|
80
|
+
id: '1',
|
|
81
|
+
country: 'RO',
|
|
82
|
+
status: 'In progress',
|
|
83
|
+
reporterEmails: ['a@example.org', 'b@example.org'],
|
|
84
|
+
}),
|
|
85
|
+
);
|
|
86
|
+
expect(result[0].deadlineDate).toBeInstanceOf(Date);
|
|
87
|
+
expect(result[0].firstReleaseDate).toBeInstanceOf(Date);
|
|
88
|
+
expect(result[0].lastReleaseDate).toBeInstanceOf(Date);
|
|
89
|
+
expect(result[1].status).toBe('Done');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('returns empty array when api call fails', async () => {
|
|
93
|
+
getConfiguration.mockResolvedValue({
|
|
94
|
+
SharepointSiteId: 'site-id',
|
|
95
|
+
ReportnetFlowsListId: 'flows-id',
|
|
96
|
+
});
|
|
97
|
+
apiGet.mockRejectedValue(new Error('boom'));
|
|
98
|
+
|
|
99
|
+
const result = await getFlows('RO');
|
|
100
|
+
|
|
101
|
+
expect(result).toEqual([]);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
jest.mock('./apiProvider', () => ({
|
|
2
|
+
apiPatch: jest.fn(),
|
|
3
|
+
getConfiguration: jest.fn(),
|
|
4
|
+
logInfo: jest.fn(),
|
|
5
|
+
}));
|
|
6
|
+
|
|
7
|
+
const { apiPatch, getConfiguration, logInfo } = require('./apiProvider');
|
|
8
|
+
const { saveData } = require('./selfServiceProvider');
|
|
9
|
+
|
|
10
|
+
const baseUser = {
|
|
11
|
+
id: '77',
|
|
12
|
+
ADUserId: 'ad-1',
|
|
13
|
+
FirstName: 'Jane',
|
|
14
|
+
LastName: 'Doe',
|
|
15
|
+
Country: 'RO',
|
|
16
|
+
NFP: false,
|
|
17
|
+
Phone: '123',
|
|
18
|
+
Gender: 'Female',
|
|
19
|
+
JobTitle: 'Expert',
|
|
20
|
+
Department: 'Air',
|
|
21
|
+
Email: 'jane@example.org',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe('saveData', () => {
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
jest.clearAllMocks();
|
|
27
|
+
getConfiguration.mockResolvedValue({
|
|
28
|
+
SharepointSiteId: 'site-id',
|
|
29
|
+
UserListId: 'user-list-id',
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('saves AD user and SharePoint user for a normal user', async () => {
|
|
34
|
+
apiPatch.mockResolvedValue(undefined);
|
|
35
|
+
logInfo.mockResolvedValue(undefined);
|
|
36
|
+
|
|
37
|
+
const result = await saveData(baseUser);
|
|
38
|
+
|
|
39
|
+
expect(apiPatch).toHaveBeenNthCalledWith(1, '/users/ad-1', {
|
|
40
|
+
givenName: 'Jane',
|
|
41
|
+
surname: 'Doe',
|
|
42
|
+
displayName: 'Jane Doe (RO)',
|
|
43
|
+
department: 'Eionet',
|
|
44
|
+
});
|
|
45
|
+
expect(apiPatch).toHaveBeenNthCalledWith(
|
|
46
|
+
2,
|
|
47
|
+
'/sites/site-id/lists/user-list-id/items/77',
|
|
48
|
+
expect.objectContaining({
|
|
49
|
+
fields: expect.objectContaining({
|
|
50
|
+
Title: 'Jane Doe',
|
|
51
|
+
Phone: '123',
|
|
52
|
+
Gender: 'Female',
|
|
53
|
+
}),
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
expect(logInfo).toHaveBeenCalledWith(
|
|
57
|
+
'User edited information',
|
|
58
|
+
'',
|
|
59
|
+
baseUser,
|
|
60
|
+
'Edit user',
|
|
61
|
+
'jane@example.org',
|
|
62
|
+
);
|
|
63
|
+
expect(result).toEqual({ Success: true });
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('uses NFP display name format', async () => {
|
|
67
|
+
apiPatch.mockResolvedValue(undefined);
|
|
68
|
+
logInfo.mockResolvedValue(undefined);
|
|
69
|
+
|
|
70
|
+
await saveData({ ...baseUser, NFP: true });
|
|
71
|
+
|
|
72
|
+
expect(apiPatch).toHaveBeenNthCalledWith(
|
|
73
|
+
1,
|
|
74
|
+
'/users/ad-1',
|
|
75
|
+
expect.objectContaining({
|
|
76
|
+
displayName: 'Jane Doe (NFP-RO)',
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('returns wrapped error when AD update fails', async () => {
|
|
82
|
+
const error = new Error('ad failed');
|
|
83
|
+
apiPatch.mockRejectedValueOnce(error);
|
|
84
|
+
|
|
85
|
+
const result = await saveData(baseUser);
|
|
86
|
+
|
|
87
|
+
expect(result).toEqual({
|
|
88
|
+
Message: 'saveADUser',
|
|
89
|
+
Error: error,
|
|
90
|
+
Success: false,
|
|
91
|
+
});
|
|
92
|
+
expect(logInfo).not.toHaveBeenCalled();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('returns wrapped error when SharePoint update fails', async () => {
|
|
96
|
+
const error = new Error('sp failed');
|
|
97
|
+
apiPatch.mockResolvedValueOnce(undefined).mockRejectedValueOnce(error);
|
|
98
|
+
|
|
99
|
+
const result = await saveData(baseUser);
|
|
100
|
+
|
|
101
|
+
expect(result).toEqual({
|
|
102
|
+
Message: 'saveSPUser',
|
|
103
|
+
Error: error,
|
|
104
|
+
Success: false,
|
|
105
|
+
});
|
|
106
|
+
expect(logInfo).not.toHaveBeenCalled();
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
jest.mock('./apiProvider', () => ({
|
|
2
|
+
apiGet: jest.fn(),
|
|
3
|
+
getConfiguration: jest.fn(),
|
|
4
|
+
}));
|
|
5
|
+
|
|
6
|
+
const { apiGet, getConfiguration } = require('./apiProvider');
|
|
7
|
+
const {
|
|
8
|
+
getOrganisationList,
|
|
9
|
+
getSPUserByMail,
|
|
10
|
+
getGenderList,
|
|
11
|
+
} = require('./selfServiceSharepointProvider');
|
|
12
|
+
|
|
13
|
+
describe('selfServiceSharepointProvider', () => {
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
jest.clearAllMocks();
|
|
16
|
+
getConfiguration.mockResolvedValue({
|
|
17
|
+
SharepointSiteId: 'site-id',
|
|
18
|
+
OrganisationListId: 'org-list-id',
|
|
19
|
+
UserListId: 'user-list-id',
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('getOrganisationList maps organisations and applies country filter', async () => {
|
|
24
|
+
apiGet.mockResolvedValue({
|
|
25
|
+
graphClientMessage: {
|
|
26
|
+
value: [
|
|
27
|
+
{
|
|
28
|
+
id: 10,
|
|
29
|
+
fields: {
|
|
30
|
+
Title: 'Org 1',
|
|
31
|
+
Unspecified: false,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const result = await getOrganisationList('RO');
|
|
39
|
+
|
|
40
|
+
expect(apiGet).toHaveBeenCalledWith(
|
|
41
|
+
expect.stringContaining("$filter=fields/Country eq 'RO' or fields/Unspecified eq 1"),
|
|
42
|
+
);
|
|
43
|
+
expect(result).toEqual([
|
|
44
|
+
{
|
|
45
|
+
header: 'Org 1',
|
|
46
|
+
content: 10,
|
|
47
|
+
unspecified: false,
|
|
48
|
+
},
|
|
49
|
+
]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('getSPUserByMail returns first user and escapes apostrophe', async () => {
|
|
53
|
+
apiGet.mockResolvedValue({
|
|
54
|
+
graphClientMessage: {
|
|
55
|
+
value: [{ id: 1, fields: { Email: 'o@example.org' } }],
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const result = await getSPUserByMail("o'hara@example.org");
|
|
60
|
+
|
|
61
|
+
expect(apiGet).toHaveBeenCalledWith(expect.stringContaining("o''hara%40example.org"));
|
|
62
|
+
expect(result).toEqual({ id: 1, fields: { Email: 'o@example.org' } });
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('getSPUserByMail returns undefined when no result exists', async () => {
|
|
66
|
+
apiGet.mockResolvedValue({
|
|
67
|
+
graphClientMessage: {
|
|
68
|
+
value: [],
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const result = await getSPUserByMail('none@example.org');
|
|
73
|
+
|
|
74
|
+
expect(result).toBeUndefined();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('getGenderList returns choices from Gender column', async () => {
|
|
78
|
+
apiGet.mockResolvedValue({
|
|
79
|
+
graphClientMessage: {
|
|
80
|
+
value: [{ name: 'Title' }, { name: 'Gender', choice: { choices: ['Female', 'Male'] } }],
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const result = await getGenderList();
|
|
85
|
+
|
|
86
|
+
expect(result).toEqual(['Female', 'Male']);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('getGenderList returns empty array when Gender column is missing', async () => {
|
|
90
|
+
apiGet.mockResolvedValue({
|
|
91
|
+
graphClientMessage: {
|
|
92
|
+
value: [{ name: 'Title' }],
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const result = await getGenderList();
|
|
97
|
+
|
|
98
|
+
expect(result).toEqual([]);
|
|
99
|
+
});
|
|
100
|
+
});
|