richie-education 2.25.0-b2.dev32 → 2.25.0-b2.dev35
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/js/api/joanie.ts +26 -3
- package/js/api/lms/dummy.spec.ts +9 -1
- package/js/api/lms/dummy.ts +12 -2
- package/js/contexts/SessionContext/BaseSessionProvider.tsx +4 -12
- package/js/contexts/SessionContext/JoanieSessionProvider.tsx +4 -11
- package/js/contexts/SessionContext/index.spec.tsx +2 -4
- package/js/hooks/useContractArchive/index.download.spec.tsx +119 -0
- package/js/hooks/useContractArchive/index.spec.tsx +91 -0
- package/js/hooks/useContractArchive/index.ts +83 -0
- package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.spec.tsx +136 -0
- package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.timer.spec.tsx +144 -0
- package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.tsx +73 -0
- package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.spec.tsx +166 -0
- package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.tsx +23 -8
- package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.spec.tsx +74 -0
- package/js/pages/TeacherDashboardContractsLayout/hooks/useCheckContractArchiveExists/index.spec.tsx +124 -0
- package/js/pages/TeacherDashboardContractsLayout/hooks/useCheckContractArchiveExists/index.tsx +73 -0
- package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/contractArchiveLocalStorage.spec.ts +85 -0
- package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/contractArchiveLocalStorage.ts +50 -0
- package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.spec.tsx +266 -0
- package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.tsx +153 -0
- package/js/pages/TeacherDashboardContractsLayout/hooks/useHasContractToDownload/index.spec.tsx +100 -0
- package/js/pages/TeacherDashboardContractsLayout/hooks/useHasContractToDownload/index.tsx +23 -0
- package/js/settings.ts +7 -0
- package/js/types/Joanie.ts +5 -0
- package/js/utils/errors/HttpError.ts +1 -0
- package/package.json +1 -1
package/js/pages/TeacherDashboardContractsLayout/hooks/useHasContractToDownload/index.spec.tsx
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import fetchMock from 'fetch-mock';
|
|
2
|
+
import { faker } from '@faker-js/faker';
|
|
3
|
+
import { renderHook, waitFor } from '@testing-library/react';
|
|
4
|
+
import { IntlProvider } from 'react-intl';
|
|
5
|
+
import { QueryClientProvider } from '@tanstack/react-query';
|
|
6
|
+
import { PropsWithChildren } from 'react';
|
|
7
|
+
import { PER_PAGE } from 'settings';
|
|
8
|
+
import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
|
|
9
|
+
import { ContractState } from 'types/Joanie';
|
|
10
|
+
import { ContractFactory } from 'utils/test/factories/joanie';
|
|
11
|
+
import { createTestQueryClient } from 'utils/test/createTestQueryClient';
|
|
12
|
+
import JoanieSessionProvider from 'contexts/SessionContext/JoanieSessionProvider';
|
|
13
|
+
import useHasContractToDownload from '.';
|
|
14
|
+
|
|
15
|
+
jest.mock('utils/context', () => ({
|
|
16
|
+
__esModule: true,
|
|
17
|
+
default: mockRichieContextFactory({
|
|
18
|
+
authentication: { backend: 'fonzie', endpoint: 'https://auth.test' },
|
|
19
|
+
joanie_backend: { endpoint: 'https://joanie.test' },
|
|
20
|
+
}).one(),
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
describe('hooks/useHasContractToDownload', () => {
|
|
24
|
+
const Wrapper = ({ children }: PropsWithChildren) => {
|
|
25
|
+
return (
|
|
26
|
+
<IntlProvider locale="en">
|
|
27
|
+
<QueryClientProvider client={createTestQueryClient({ user: true })}>
|
|
28
|
+
<JoanieSessionProvider>{children}</JoanieSessionProvider>
|
|
29
|
+
</QueryClientProvider>
|
|
30
|
+
</IntlProvider>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
// Joanie providers calls
|
|
36
|
+
fetchMock.get('https://joanie.test/api/v1.0/orders/', []);
|
|
37
|
+
fetchMock.get('https://joanie.test/api/v1.0/credit-cards/', []);
|
|
38
|
+
fetchMock.get('https://joanie.test/api/v1.0/addresses/', []);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
afterEach(() => {
|
|
42
|
+
fetchMock.restore();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should return null when joanie request is pending', async () => {
|
|
46
|
+
const organizationId = faker.string.uuid();
|
|
47
|
+
const contractListUrl = `https://joanie.test/api/v1.0/organizations/${organizationId}/contracts/?signature_state=${ContractState.SIGNED}&page=1&page_size=${PER_PAGE.teacherContractList}`;
|
|
48
|
+
fetchMock.get(contractListUrl, {
|
|
49
|
+
count: 1,
|
|
50
|
+
next: null,
|
|
51
|
+
previous: null,
|
|
52
|
+
results: [ContractFactory().one()],
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const { result } = renderHook(() => useHasContractToDownload(organizationId), {
|
|
56
|
+
wrapper: Wrapper,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
expect(result.current).toBeNull();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should return true when joanie return some signed contracts', async () => {
|
|
63
|
+
const organizationId = faker.string.uuid();
|
|
64
|
+
const contractListUrl = `https://joanie.test/api/v1.0/organizations/${organizationId}/contracts/?signature_state=${ContractState.SIGNED}&page=1&page_size=${PER_PAGE.teacherContractList}`;
|
|
65
|
+
fetchMock.get(contractListUrl, {
|
|
66
|
+
count: 1,
|
|
67
|
+
next: null,
|
|
68
|
+
previous: null,
|
|
69
|
+
results: [ContractFactory().one()],
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const { result } = renderHook(() => useHasContractToDownload(organizationId), {
|
|
73
|
+
wrapper: Wrapper,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await waitFor(() => {
|
|
77
|
+
expect(fetchMock.calls().map((call) => call[0])).toContain(contractListUrl);
|
|
78
|
+
expect(result.current).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("should return false when joanie doesn't return any signed contracts", async () => {
|
|
83
|
+
const organizationId = faker.string.uuid();
|
|
84
|
+
const contractListUrl = `https://joanie.test/api/v1.0/organizations/${organizationId}/contracts/?signature_state=${ContractState.SIGNED}&page=1&page_size=${PER_PAGE.teacherContractList}`;
|
|
85
|
+
fetchMock.get(contractListUrl, {
|
|
86
|
+
count: 0,
|
|
87
|
+
next: null,
|
|
88
|
+
previous: null,
|
|
89
|
+
results: [],
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const { result } = renderHook(() => useHasContractToDownload(organizationId), {
|
|
93
|
+
wrapper: Wrapper,
|
|
94
|
+
});
|
|
95
|
+
await waitFor(() => {
|
|
96
|
+
expect(fetchMock.calls().map((call) => call[0])).toContain(contractListUrl);
|
|
97
|
+
expect(result.current).toBe(false);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useOrganizationContracts } from 'hooks/useContracts';
|
|
2
|
+
import { PER_PAGE } from 'settings';
|
|
3
|
+
import { ContractState, Organization } from 'types/Joanie';
|
|
4
|
+
|
|
5
|
+
const useHasContractToDownload = (organizationId: Organization['id']) => {
|
|
6
|
+
const {
|
|
7
|
+
items: contracts,
|
|
8
|
+
states: { isFetched },
|
|
9
|
+
} = useOrganizationContracts({
|
|
10
|
+
organization_id: organizationId,
|
|
11
|
+
signature_state: ContractState.SIGNED,
|
|
12
|
+
page: 1,
|
|
13
|
+
page_size: PER_PAGE.teacherContractList,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
if (!isFetched) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return contracts.length > 0;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default useHasContractToDownload;
|
package/js/settings.ts
CHANGED
|
@@ -46,6 +46,13 @@ export const CONTRACT_SETTINGS = {
|
|
|
46
46
|
dummySignatureSignTimeout: 2000,
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
export const CONTRACT_DOWNLOAD_SETTINGS = {
|
|
50
|
+
// Interval in ms to poll the related contract's archive.
|
|
51
|
+
pollInterval: 1000,
|
|
52
|
+
contractArchiveLocalStorageKey: 'RICHIE_CONTRACT_ARCHIVE',
|
|
53
|
+
contractArchiveLocalVaklidityDurationMs: 10 * 60 * 60 * 1000, // 10min
|
|
54
|
+
};
|
|
55
|
+
|
|
49
56
|
const DEFAULT_PER_PAGE = 50;
|
|
50
57
|
export const PER_PAGE = {
|
|
51
58
|
teacherContractList: 25,
|
package/js/types/Joanie.ts
CHANGED
|
@@ -520,6 +520,11 @@ interface APIUser {
|
|
|
520
520
|
? Promise<Nullable<Contract>>
|
|
521
521
|
: Promise<PaginatedResponse<Contract>>;
|
|
522
522
|
download(id: string): Promise<File>;
|
|
523
|
+
zip_archive: {
|
|
524
|
+
check: (id: string) => Promise<Response>;
|
|
525
|
+
create: ({ organization_id }: { organization_id: string }) => Promise<{ url: string }>;
|
|
526
|
+
get: (id: string) => Promise<File>;
|
|
527
|
+
};
|
|
523
528
|
};
|
|
524
529
|
}
|
|
525
530
|
|