richie-education 3.2.1-dev9 → 3.2.2-dev26
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/i18n/locales/ar-SA.json +29 -1
- package/i18n/locales/es-ES.json +29 -1
- package/i18n/locales/fa-IR.json +29 -1
- package/i18n/locales/fr-CA.json +29 -1
- package/i18n/locales/fr-FR.json +29 -1
- package/i18n/locales/ko-KR.json +29 -1
- package/i18n/locales/pt-PT.json +29 -1
- package/i18n/locales/ru-RU.json +29 -1
- package/i18n/locales/vi-VN.json +29 -1
- package/js/api/joanie.ts +144 -0
- package/js/components/PaymentInterfaces/types.ts +7 -0
- package/js/components/PaymentScheduleGrid/index.tsx +4 -2
- package/js/components/SaleTunnel/AddressSelector/index.spec.tsx +9 -2
- package/js/components/SaleTunnel/GenericSaleTunnel.tsx +33 -0
- package/js/components/SaleTunnel/SaleTunnelInformation/SaleTunnelInformationGroup.tsx +253 -0
- package/js/components/SaleTunnel/SaleTunnelInformation/SaleTunnelInformationSingular.tsx +314 -0
- package/js/components/SaleTunnel/SaleTunnelInformation/StepContent.tsx +528 -0
- package/js/components/SaleTunnel/SaleTunnelInformation/index.tsx +47 -261
- package/js/components/SaleTunnel/SaleTunnelSuccess/index.tsx +25 -11
- package/js/components/SaleTunnel/SubscriptionButton/index.tsx +54 -6
- package/js/components/SaleTunnel/_styles.scss +55 -0
- package/js/components/SaleTunnel/index.full-process-b2b.spec.tsx +356 -0
- package/js/components/SaleTunnel/{index.full-process.spec.tsx → index.full-process-b2c.spec.tsx} +4 -1
- package/js/components/SaleTunnel/index.spec.tsx +130 -1
- package/js/hooks/useBatchOrder/index.tsx +36 -0
- package/js/hooks/useContractArchive/index.ts +2 -0
- package/js/hooks/useOfferingOrganizations/index.tsx +38 -0
- package/js/hooks/useOrganizationAgreements.tsx/index.tsx +66 -0
- package/js/hooks/useOrganizationQuotes/index.tsx +56 -0
- package/js/hooks/usePaymentPlan.tsx +2 -1
- package/js/hooks/useTeacherPendingAgreementsCount/index.ts +34 -0
- package/js/pages/DashboardBatchOrderLayout/_styles.scss +5 -0
- package/js/pages/DashboardBatchOrderLayout/index.spec.tsx +78 -0
- package/js/pages/DashboardBatchOrderLayout/index.tsx +45 -0
- package/js/pages/DashboardBatchOrders/index.spec.tsx +237 -0
- package/js/pages/DashboardBatchOrders/index.tsx +84 -0
- package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardCourseContractsLayout/index.tsx +0 -1
- package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.tsx +3 -1
- package/js/pages/TeacherDashboardOrganizationAgreements/AgreementActionsBar.tsx +49 -0
- package/js/pages/TeacherDashboardOrganizationAgreements/BulkAgreementContractButton.tsx +79 -0
- package/js/pages/TeacherDashboardOrganizationAgreements/OrganizationAgreementFrame.tsx +71 -0
- package/js/pages/TeacherDashboardOrganizationAgreements/SignOrganizationAgreementButton.tsx +60 -0
- package/js/pages/TeacherDashboardOrganizationAgreements/hooks/useAgreementsAbilities.tsx +8 -0
- package/js/pages/TeacherDashboardOrganizationAgreements/hooks/useHasAgreementToDownload.tsx +27 -0
- package/js/pages/TeacherDashboardOrganizationAgreements/hooks/useTeacherAgreementsToSign.tsx +32 -0
- package/js/pages/TeacherDashboardOrganizationAgreements/index.spec.tsx +433 -0
- package/js/pages/TeacherDashboardOrganizationAgreements/index.tsx +130 -0
- package/js/pages/TeacherDashboardOrganizationAgreementsLayout/index.tsx +25 -0
- package/js/pages/TeacherDashboardOrganizationCourseLoader/index.spec.tsx +9 -0
- package/js/pages/TeacherDashboardOrganizationQuotes/_styles.scss +40 -0
- package/js/pages/TeacherDashboardOrganizationQuotes/index.full-process.spec.tsx +194 -0
- package/js/pages/TeacherDashboardOrganizationQuotes/index.spec.tsx +144 -0
- package/js/pages/TeacherDashboardOrganizationQuotes/index.tsx +521 -0
- package/js/pages/TeacherDashboardOrganizationQuotesLayout/index.tsx +26 -0
- package/js/translations/ar-SA.json +1 -1
- package/js/translations/es-ES.json +1 -1
- package/js/translations/fa-IR.json +1 -1
- package/js/translations/fr-CA.json +1 -1
- package/js/translations/fr-FR.json +1 -1
- package/js/translations/ko-KR.json +1 -1
- package/js/translations/pt-PT.json +1 -1
- package/js/translations/ru-RU.json +1 -1
- package/js/translations/vi-VN.json +1 -1
- package/js/types/Joanie.ts +216 -1
- package/js/utils/AbilitiesHelper/agreementAbilities.ts +14 -0
- package/js/utils/AbilitiesHelper/index.ts +7 -0
- package/js/utils/AbilitiesHelper/types.ts +12 -3
- package/js/utils/ObjectHelper/index.ts +20 -0
- package/js/utils/OrderHelper/index.ts +10 -0
- package/js/utils/errors/HttpError.ts +1 -0
- package/js/utils/test/factories/joanie.ts +156 -1
- package/js/widgets/Dashboard/components/DashboardBatchOrderLoader/_styles.scss +14 -0
- package/js/widgets/Dashboard/components/DashboardBatchOrderLoader/index.tsx +32 -0
- package/js/widgets/Dashboard/components/DashboardCard/index.spec.tsx +18 -0
- package/js/widgets/Dashboard/components/DashboardCard/index.stories.tsx +25 -2
- package/js/widgets/Dashboard/components/DashboardCard/index.tsx +4 -2
- package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/BatchOrderPaymentModal/BatchOrderPaymentManager.tsx +88 -0
- package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/BatchOrderPaymentModal/index.tsx +216 -0
- package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/DashboardBatchOrderSubItems.tsx +316 -0
- package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/index.spec.tsx +27 -0
- package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/index.tsx +175 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.tsx +5 -2
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrganizationBlock/index.tsx +4 -1
- package/js/widgets/Dashboard/components/DashboardItem/Order/_styles.scss +5 -0
- package/js/widgets/Dashboard/components/DashboardItem/_styles.scss +43 -0
- package/js/widgets/Dashboard/components/DashboardSidebar/components/AgreementNavLink/index.spec.tsx +214 -0
- package/js/widgets/Dashboard/components/DashboardSidebar/components/AgreementNavLink/index.tsx +47 -0
- package/js/widgets/Dashboard/components/LearnerDashboardSidebar/index.tsx +1 -0
- package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.spec.tsx +21 -3
- package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.tsx +9 -0
- package/js/widgets/Dashboard/utils/learnerRoutes.tsx +30 -0
- package/js/widgets/Dashboard/utils/learnerRoutesPaths.tsx +12 -0
- package/js/widgets/Dashboard/utils/teacherDashboardPaths.tsx +12 -0
- package/js/widgets/Dashboard/utils/teacherRoutes.tsx +17 -0
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +8 -2
- package/package.json +4 -1
- package/scss/colors/_theme.scss +1 -1
- package/scss/components/_index.scss +1 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import fetchMock from 'fetch-mock';
|
|
2
|
+
import { cleanup, screen } from '@testing-library/react';
|
|
3
|
+
import userEvent, { UserEvent } from '@testing-library/user-event';
|
|
4
|
+
import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
|
|
5
|
+
import { OrganizationQuoteFactory } from 'utils/test/factories/joanie';
|
|
6
|
+
import { expectNoSpinner } from 'utils/test/expectSpinner';
|
|
7
|
+
import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
8
|
+
import { render } from 'utils/test/render';
|
|
9
|
+
import { PaymentMethod } from 'components/PaymentInterfaces/types';
|
|
10
|
+
import { BatchOrderState } from 'types/Joanie';
|
|
11
|
+
import { browserDownloadFromBlob } from 'utils/download';
|
|
12
|
+
import TeacherDashboardOrganizationQuotes from '.';
|
|
13
|
+
|
|
14
|
+
jest.mock('utils/context', () => ({
|
|
15
|
+
__esModule: true,
|
|
16
|
+
default: mockRichieContextFactory({
|
|
17
|
+
authentication: { backend: 'fonzie', endpoint: 'https://auth.endpoint.test' },
|
|
18
|
+
joanie_backend: { endpoint: 'https://joanie.endpoint' },
|
|
19
|
+
}).one(),
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
jest.mock('utils/download', () => ({
|
|
23
|
+
browserDownloadFromBlob: jest.fn(),
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
let user: UserEvent;
|
|
27
|
+
|
|
28
|
+
describe('full process for the organization quotes dashboard', () => {
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
user = userEvent.setup();
|
|
31
|
+
jest.resetAllMocks();
|
|
32
|
+
});
|
|
33
|
+
setupJoanieSession();
|
|
34
|
+
|
|
35
|
+
it('should works with the full process workflow for any payment methods', async () => {
|
|
36
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/`, []);
|
|
37
|
+
|
|
38
|
+
const quoteQuoted = OrganizationQuoteFactory({
|
|
39
|
+
batch_order: {
|
|
40
|
+
state: BatchOrderState.QUOTED,
|
|
41
|
+
payment_method: PaymentMethod.CARD_PAYMENT,
|
|
42
|
+
available_actions: { next_action: 'confirm_quote' },
|
|
43
|
+
},
|
|
44
|
+
organization_signed_on: undefined,
|
|
45
|
+
}).one();
|
|
46
|
+
const quoteSendForSign = OrganizationQuoteFactory({
|
|
47
|
+
id: quoteQuoted.id,
|
|
48
|
+
batch_order: {
|
|
49
|
+
state: BatchOrderState.TO_SIGN,
|
|
50
|
+
payment_method: PaymentMethod.CARD_PAYMENT,
|
|
51
|
+
contract_submitted: false,
|
|
52
|
+
available_actions: { next_action: 'submit_for_signature' },
|
|
53
|
+
},
|
|
54
|
+
}).one();
|
|
55
|
+
const quoteWaitingForSign = OrganizationQuoteFactory({
|
|
56
|
+
id: quoteQuoted.id,
|
|
57
|
+
batch_order: {
|
|
58
|
+
state: BatchOrderState.TO_SIGN,
|
|
59
|
+
payment_method: PaymentMethod.CARD_PAYMENT,
|
|
60
|
+
contract_submitted: true,
|
|
61
|
+
available_actions: { next_action: null },
|
|
62
|
+
},
|
|
63
|
+
}).one();
|
|
64
|
+
const quotePending = OrganizationQuoteFactory({
|
|
65
|
+
id: quoteQuoted.id,
|
|
66
|
+
batch_order: {
|
|
67
|
+
state: BatchOrderState.PENDING,
|
|
68
|
+
payment_method: PaymentMethod.CARD_PAYMENT,
|
|
69
|
+
},
|
|
70
|
+
}).one();
|
|
71
|
+
const quoteProcessingPayment = OrganizationQuoteFactory({
|
|
72
|
+
id: quoteQuoted.id,
|
|
73
|
+
batch_order: {
|
|
74
|
+
state: BatchOrderState.PROCESS_PAYMENT,
|
|
75
|
+
payment_method: PaymentMethod.CARD_PAYMENT,
|
|
76
|
+
},
|
|
77
|
+
}).one();
|
|
78
|
+
const quoteDownload = OrganizationQuoteFactory({
|
|
79
|
+
id: quoteQuoted.id,
|
|
80
|
+
batch_order: {
|
|
81
|
+
state: BatchOrderState.COMPLETED,
|
|
82
|
+
payment_method: PaymentMethod.CARD_PAYMENT,
|
|
83
|
+
},
|
|
84
|
+
}).one();
|
|
85
|
+
|
|
86
|
+
const quotesResponses = [
|
|
87
|
+
{ results: [quoteQuoted], count: 1, previous: null, next: null },
|
|
88
|
+
{ results: [quoteSendForSign], count: 1, previous: null, next: null },
|
|
89
|
+
{ results: [quoteWaitingForSign], count: 1, previous: null, next: null },
|
|
90
|
+
{ results: [quotePending], count: 1, previous: null, next: null },
|
|
91
|
+
{ results: [quoteProcessingPayment], count: 1, previous: null, next: null },
|
|
92
|
+
{ results: [quoteDownload], count: 1, previous: null, next: null },
|
|
93
|
+
{ results: [quoteDownload], count: 1, previous: null, next: null },
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
fetchMock.get(
|
|
97
|
+
`https://joanie.endpoint/api/v1.0/organizations/1/quotes/?page=1&page_size=10`,
|
|
98
|
+
() => quotesResponses.shift(),
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
fetchMock.patch(`https://joanie.endpoint/api/v1.0/organizations/1/confirm-quote/`, 200);
|
|
102
|
+
|
|
103
|
+
fetchMock.post(
|
|
104
|
+
`https://joanie.endpoint/api/v1.0/organizations/1/submit-for-signature-batch-order/`,
|
|
105
|
+
200,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
fetchMock.get(
|
|
109
|
+
`https://joanie.endpoint/api/v1.0/organizations/1/download-quote/?quote_id=${quoteDownload.id}`,
|
|
110
|
+
{
|
|
111
|
+
status: 200,
|
|
112
|
+
body: new Blob(['test']),
|
|
113
|
+
},
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
render(<TeacherDashboardOrganizationQuotes />, {
|
|
117
|
+
routerOptions: {
|
|
118
|
+
path: '/organizations/:organizationId/quotes',
|
|
119
|
+
initialEntries: ['/organizations/1/quotes'],
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
await expectNoSpinner();
|
|
124
|
+
|
|
125
|
+
// Expand dashboard card
|
|
126
|
+
const wrapper = screen.getByTestId('dashboard-card__wrapper');
|
|
127
|
+
const card = wrapper.closest('.dashboard-card');
|
|
128
|
+
const toggle = await screen.findByTestId('dashboard-card__header__toggle');
|
|
129
|
+
await user.click(toggle);
|
|
130
|
+
expect(card).toHaveClass('dashboard-card--opened');
|
|
131
|
+
|
|
132
|
+
// Download quote
|
|
133
|
+
const downloadQuoteButton = await screen.findByRole('button', {
|
|
134
|
+
name: /Download quote/i,
|
|
135
|
+
});
|
|
136
|
+
expect(downloadQuoteButton).toBeVisible();
|
|
137
|
+
await user.click(downloadQuoteButton);
|
|
138
|
+
expect(browserDownloadFromBlob).toHaveBeenCalledTimes(1);
|
|
139
|
+
|
|
140
|
+
// First step : confirm quote
|
|
141
|
+
const confirmQuoteButton = await screen.findByRole('button', { name: /confirm quote/i });
|
|
142
|
+
expect(confirmQuoteButton).toBeVisible();
|
|
143
|
+
await user.click(confirmQuoteButton);
|
|
144
|
+
await screen.findByText(/total amount/i);
|
|
145
|
+
await user.type(screen.getByLabelText(/total amount/i), '1000');
|
|
146
|
+
await user.click(screen.getByRole('button', { name: /confirm quote/i }));
|
|
147
|
+
|
|
148
|
+
// Second step : to sign quote
|
|
149
|
+
const sendForSignatureButton = await screen.findByRole('button', {
|
|
150
|
+
name: /send quote for signature/i,
|
|
151
|
+
});
|
|
152
|
+
expect(sendForSignatureButton).toBeVisible();
|
|
153
|
+
await user.click(sendForSignatureButton);
|
|
154
|
+
|
|
155
|
+
// Third step : waiting for signature
|
|
156
|
+
const waitingSignatureButton = await screen.findByRole('button', {
|
|
157
|
+
name: /waiting signature/i,
|
|
158
|
+
});
|
|
159
|
+
expect(waitingSignatureButton).toBeVisible();
|
|
160
|
+
expect(waitingSignatureButton).toBeDisabled();
|
|
161
|
+
|
|
162
|
+
// Fourth step : pending payment
|
|
163
|
+
cleanup();
|
|
164
|
+
render(<TeacherDashboardOrganizationQuotes />, {
|
|
165
|
+
routerOptions: {
|
|
166
|
+
path: '/organizations/:organizationId/quotes',
|
|
167
|
+
initialEntries: ['/organizations/1/quotes'],
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
await expectNoSpinner();
|
|
171
|
+
|
|
172
|
+
const pendingPaymentButton = await screen.findByRole('button', {
|
|
173
|
+
name: /waiting payment/i,
|
|
174
|
+
});
|
|
175
|
+
expect(pendingPaymentButton).toBeVisible();
|
|
176
|
+
expect(pendingPaymentButton).toBeDisabled();
|
|
177
|
+
|
|
178
|
+
// Fifth step : process payment
|
|
179
|
+
cleanup();
|
|
180
|
+
render(<TeacherDashboardOrganizationQuotes />, {
|
|
181
|
+
routerOptions: {
|
|
182
|
+
path: '/organizations/:organizationId/quotes',
|
|
183
|
+
initialEntries: ['/organizations/1/quotes'],
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
await expectNoSpinner();
|
|
187
|
+
|
|
188
|
+
const processPaymentButton = await screen.findByRole('button', {
|
|
189
|
+
name: /processing payment/i,
|
|
190
|
+
});
|
|
191
|
+
expect(processPaymentButton).toBeVisible();
|
|
192
|
+
expect(processPaymentButton).toBeDisabled();
|
|
193
|
+
});
|
|
194
|
+
});
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import fetchMock from 'fetch-mock';
|
|
2
|
+
import { screen, waitFor } from '@testing-library/react';
|
|
3
|
+
import userEvent, { UserEvent } from '@testing-library/user-event';
|
|
4
|
+
import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
|
|
5
|
+
import { OrganizationQuoteFactory } from 'utils/test/factories/joanie';
|
|
6
|
+
import { expectNoSpinner } from 'utils/test/expectSpinner';
|
|
7
|
+
import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
8
|
+
import { render } from 'utils/test/render';
|
|
9
|
+
import { expectBannerInfo, expectBannerError } from 'utils/test/expectBanner';
|
|
10
|
+
import TeacherDashboardOrganizationQuotes from '.';
|
|
11
|
+
|
|
12
|
+
let user: UserEvent;
|
|
13
|
+
|
|
14
|
+
jest.mock('utils/context', () => ({
|
|
15
|
+
__esModule: true,
|
|
16
|
+
default: mockRichieContextFactory({
|
|
17
|
+
authentication: { backend: 'fonzie', endpoint: 'https://auth.endpoint.test' },
|
|
18
|
+
joanie_backend: { endpoint: 'https://joanie.endpoint' },
|
|
19
|
+
}).one(),
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
describe('pages/TeacherDashboardOrganizationQuotes', () => {
|
|
23
|
+
setupJoanieSession();
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
user = userEvent.setup();
|
|
26
|
+
jest.resetAllMocks();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should render a list of quotes for an organization', async () => {
|
|
30
|
+
const quoteList = OrganizationQuoteFactory().many(1);
|
|
31
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/`, []);
|
|
32
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/1/quotes/?page=1&page_size=10`, {
|
|
33
|
+
results: quoteList,
|
|
34
|
+
count: 0,
|
|
35
|
+
previous: null,
|
|
36
|
+
next: null,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
render(<TeacherDashboardOrganizationQuotes />, {
|
|
40
|
+
routerOptions: {
|
|
41
|
+
path: '/organizations/:organizationId/quotes',
|
|
42
|
+
initialEntries: ['/organizations/1/quotes'],
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await expectNoSpinner();
|
|
47
|
+
await Promise.all(
|
|
48
|
+
quoteList.map(async (quote) => {
|
|
49
|
+
expect(
|
|
50
|
+
await screen.findByText(`Batch order id: ${quote.batch_order.id}`),
|
|
51
|
+
).toBeInTheDocument();
|
|
52
|
+
const seats = quote.batch_order.nb_seats === 1 ? 'seat' : 'seats';
|
|
53
|
+
expect(
|
|
54
|
+
await screen.findByText(`${quote.batch_order.nb_seats} ${seats}`),
|
|
55
|
+
).toBeInTheDocument();
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should render an empty list of quotes for an organization', async () => {
|
|
61
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/`, []);
|
|
62
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/1/quotes/?page=1&page_size=10`, {
|
|
63
|
+
results: [],
|
|
64
|
+
count: 0,
|
|
65
|
+
previous: null,
|
|
66
|
+
next: null,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
render(<TeacherDashboardOrganizationQuotes />, {
|
|
70
|
+
routerOptions: {
|
|
71
|
+
path: '/organizations/:organizationId/quotes',
|
|
72
|
+
initialEntries: ['/organizations/1/quotes'],
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await expectNoSpinner();
|
|
77
|
+
await expectBannerInfo('No quotes found for this organization.');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should paginate', async () => {
|
|
81
|
+
const quoteList = OrganizationQuoteFactory().many(30);
|
|
82
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/`, []);
|
|
83
|
+
|
|
84
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/1/quotes/?page=1&page_size=10`, {
|
|
85
|
+
results: quoteList.slice(0, 10),
|
|
86
|
+
count: 30,
|
|
87
|
+
previous: null,
|
|
88
|
+
next: 'https://joanie.endpoint/api/v1.0/organizations/1/quotes/?page=2&page_size=10',
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/1/quotes/?page=2&page_size=10`, {
|
|
92
|
+
results: quoteList.slice(10, 20),
|
|
93
|
+
count: 30,
|
|
94
|
+
previous: 'https://joanie.endpoint/api/v1.0/organizations/1/quotes/?page=1&page_size=10',
|
|
95
|
+
next: 'https://joanie.endpoint/api/v1.0/organizations/1/quotes/?page=3&page_size=10',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
render(<TeacherDashboardOrganizationQuotes />, {
|
|
99
|
+
routerOptions: {
|
|
100
|
+
path: '/organizations/:organizationId/quotes',
|
|
101
|
+
initialEntries: ['/organizations/1/quotes'],
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await expectNoSpinner();
|
|
106
|
+
|
|
107
|
+
expect(
|
|
108
|
+
screen.getByText((content) => content.includes(quoteList[0].batch_order.id)),
|
|
109
|
+
).toBeInTheDocument();
|
|
110
|
+
expect(
|
|
111
|
+
screen.queryByText((content) => content.includes(quoteList[10].batch_order.id)),
|
|
112
|
+
).not.toBeInTheDocument();
|
|
113
|
+
|
|
114
|
+
const nextButton = screen.getByRole('link', { name: /page 2/i });
|
|
115
|
+
await user.click(nextButton);
|
|
116
|
+
|
|
117
|
+
await waitFor(() => {
|
|
118
|
+
expect(
|
|
119
|
+
screen.getByText((content) => content.includes(quoteList[10].batch_order.id)),
|
|
120
|
+
).toBeInTheDocument();
|
|
121
|
+
});
|
|
122
|
+
expect(
|
|
123
|
+
screen.queryByText((content) => content.includes(quoteList[0].batch_order.id)),
|
|
124
|
+
).not.toBeInTheDocument();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should display an error when API fails', async () => {
|
|
128
|
+
fetchMock.get('https://joanie.endpoint/api/v1.0/organizations/', []);
|
|
129
|
+
fetchMock.get(
|
|
130
|
+
'https://joanie.endpoint/api/v1.0/organizations/1/quotes/?page=1&page_size=10',
|
|
131
|
+
500,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
render(<TeacherDashboardOrganizationQuotes />, {
|
|
135
|
+
routerOptions: {
|
|
136
|
+
path: '/organizations/:organizationId/quotes',
|
|
137
|
+
initialEntries: ['/organizations/1/quotes'],
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
await expectNoSpinner();
|
|
142
|
+
await expectBannerError('An error occurred while fetching resources. Please retry later.');
|
|
143
|
+
});
|
|
144
|
+
});
|