richie-education 2.28.2-dev26 → 2.28.2-dev53
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 +42 -17
- package/js/api/lms/dummy.ts +1 -12
- package/js/components/ContractFrame/AbstractContractFrame.spec.tsx +16 -9
- package/js/components/ContractFrame/AbstractContractFrame.tsx +28 -23
- package/js/components/ContractFrame/LearnerContractFrame.tsx +2 -2
- package/js/components/ContractFrame/_styles.scss +6 -14
- package/js/components/{SaleTunnel/CreditCardSelector → CreditCardSelector}/index.spec.tsx +15 -45
- package/js/components/{SaleTunnel/CreditCardSelector → CreditCardSelector}/index.tsx +17 -24
- package/js/components/DownloadContractButton/index.spec.tsx +1 -1
- package/js/components/OpenEdxFullNameForm/index.spec.tsx +229 -0
- package/js/components/OpenEdxFullNameForm/index.tsx +7 -7
- package/js/components/PaymentInterfaces/LyraPopIn.tsx +2 -2
- package/js/components/PaymentInterfaces/PayplugLightbox.tsx +1 -1
- package/js/components/PaymentInterfaces/__mocks__/index.tsx +1 -4
- package/js/components/PaymentInterfaces/types.ts +5 -2
- package/js/components/PaymentScheduleGrid/_styles.scss +13 -0
- package/js/components/PaymentScheduleGrid/index.tsx +50 -70
- package/js/components/PurchaseButton/index.spec.tsx +84 -37
- package/js/components/SaleTunnel/AddressSelector/index.spec.tsx +2 -1
- package/js/components/SaleTunnel/CertificateSaleTunnel/index.tsx +2 -2
- package/js/components/SaleTunnel/CredentialSaleTunnel/index.tsx +6 -10
- package/js/components/SaleTunnel/GenericSaleTunnel.tsx +80 -27
- package/js/components/SaleTunnel/SaleTunnelInformation/index.tsx +16 -20
- package/js/components/SaleTunnel/SaleTunnelSavePaymentMethod/_styles.scss +12 -0
- package/js/components/SaleTunnel/SaleTunnelSavePaymentMethod/index.tsx +160 -0
- package/js/components/SaleTunnel/SaleTunnelSuccess/index.tsx +15 -29
- package/js/components/SaleTunnel/Sponsors/SaleTunnelSponsors.scss +4 -5
- package/js/components/SaleTunnel/Sponsors/SaleTunnelSponsors.tsx +39 -11
- package/js/components/SaleTunnel/SubscriptionButton/_styles.scss +7 -0
- package/js/components/SaleTunnel/SubscriptionButton/index.tsx +201 -0
- package/js/components/SaleTunnel/_styles.scss +16 -5
- package/js/components/SaleTunnel/hooks/useTerms.tsx +0 -77
- package/js/components/SaleTunnel/index.credential.spec.tsx +14 -25
- package/js/components/SaleTunnel/index.full-process.spec.tsx +116 -48
- package/js/components/SaleTunnel/index.spec.tsx +334 -717
- package/js/components/SignContractButton/index.omniscientOrders.spec.tsx +16 -11
- package/js/components/SignContractButton/index.spec.tsx +16 -20
- package/js/components/SignContractButton/index.tsx +3 -1
- package/js/hooks/useCreditCards/index.spec.tsx +70 -6
- package/js/hooks/useCreditCards/index.ts +49 -11
- package/js/hooks/useOrders/index.spec.tsx +322 -0
- package/js/hooks/{useOrders.ts → useOrders/index.ts} +40 -14
- package/js/hooks/usePaymentSchedule.tsx +23 -0
- package/js/hooks/useProductOrder/index.spec.tsx +77 -60
- package/js/hooks/useProductOrder/index.tsx +2 -2
- package/js/hooks/useResources/useResourcesRoot.ts +4 -3
- package/js/index.tsx +2 -0
- package/js/pages/DashboardCreditCardsManagement/CreditCardBrandLogo.spec.tsx +1 -1
- package/js/pages/DashboardCreditCardsManagement/CreditCardBrandLogo.tsx +4 -2
- package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.spec.tsx +8 -5
- package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.spec.tsx +8 -9
- package/js/pages/TeacherDashboardCourseLearnersLayout/components/CourseLearnerDataGrid/index.spec.tsx +1 -1
- package/js/pages/TeacherDashboardCourseLearnersLayout/components/CourseLearnerDataGrid/index.tsx +1 -6
- package/js/settings/settings.test.ts +11 -2
- package/js/types/Joanie.ts +77 -31
- package/js/utils/OrderHelper/index.ts +47 -38
- package/js/utils/test/factories/joanie.ts +66 -68
- package/js/widgets/Dashboard/components/DashboardItem/CourseEnrolling/index.tsx +8 -18
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.spec.tsx +26 -32
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.tsx +11 -6
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.spec.tsx +114 -5
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.tsx +99 -12
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.spec.tsx +3 -1
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.useUnionResource.cache.spec.tsx +6 -7
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderPaymentDetailsModal/_styles.scss +7 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderPaymentDetailsModal/index.tsx +126 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderPaymentRetryModal/index.tsx +209 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateLearnerMessage/index.spec.tsx +18 -71
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateLearnerMessage/index.tsx +40 -25
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateMessage/index.tsx +28 -22
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.spec.tsx +18 -73
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.tsx +32 -16
- package/js/widgets/Dashboard/components/DashboardOrderLoader/index.tsx +3 -11
- package/js/widgets/Dashboard/components/Signature/SignatureDummy.tsx +25 -3
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCourseRuns/EnrollableCourseRunList.tsx +2 -6
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCourseRuns/index.spec.tsx +7 -14
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseRunItem/index.spec.tsx +7 -5
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseRunItem/index.tsx +5 -7
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +242 -332
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.stories.tsx +12 -13
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.tsx +10 -21
- package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/index.joanie.spec.tsx +2 -2
- package/package.json +2 -1
- package/scss/components/_index.scss +4 -2
- package/js/components/PaymentButton/_styles.scss +0 -27
- package/js/components/SaleTunnel/GenericPaymentButton/index.tsx +0 -338
- package/js/components/SaleTunnel/SaleTunnelNotValidated/index.tsx +0 -70
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/ProductSignatureHeader/index.tsx +0 -41
- /package/js/components/{SaleTunnel/CreditCardSelector → CreditCardSelector}/_styles.scss +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fetchMock from 'fetch-mock';
|
|
2
2
|
import { act, fireEvent, screen, waitFor } from '@testing-library/react';
|
|
3
|
+
import queryString from 'query-string';
|
|
3
4
|
import {
|
|
4
5
|
RichieContextFactory as mockRichieContextFactory,
|
|
5
6
|
PacedCourseFactory,
|
|
@@ -8,13 +9,13 @@ import {
|
|
|
8
9
|
import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
9
10
|
import {
|
|
10
11
|
AddressFactory,
|
|
11
|
-
|
|
12
|
+
CredentialOrderFactory,
|
|
12
13
|
CredentialProductFactory,
|
|
13
14
|
OrderGroupFactory,
|
|
14
15
|
} from 'utils/test/factories/joanie';
|
|
15
16
|
import type * as Joanie from 'types/Joanie';
|
|
16
17
|
import { Maybe } from 'types/utils';
|
|
17
|
-
import { OrderCredentialCreationPayload } from 'types/Joanie';
|
|
18
|
+
import { NOT_CANCELED_ORDER_STATES, OrderCredentialCreationPayload } from 'types/Joanie';
|
|
18
19
|
import { SaleTunnel, SaleTunnelProps } from 'components/SaleTunnel/index';
|
|
19
20
|
import { render } from 'utils/test/render';
|
|
20
21
|
import { getAddressLabel } from 'components/SaleTunnel/AddressSelector';
|
|
@@ -56,12 +57,6 @@ describe('SaleTunnel / Credential', () => {
|
|
|
56
57
|
return <SaleTunnel {...props} isOpen={true} onClose={() => {}} />;
|
|
57
58
|
};
|
|
58
59
|
|
|
59
|
-
const formatPrice = (price: number, currency: string) =>
|
|
60
|
-
new Intl.NumberFormat('en', {
|
|
61
|
-
currency,
|
|
62
|
-
style: 'currency',
|
|
63
|
-
}).format(price);
|
|
64
|
-
|
|
65
60
|
setupJoanieSession();
|
|
66
61
|
|
|
67
62
|
beforeEach(() => {
|
|
@@ -92,22 +87,23 @@ describe('SaleTunnel / Credential', () => {
|
|
|
92
87
|
const billingAddress: Joanie.Address = AddressFactory({ is_main: true }).one();
|
|
93
88
|
|
|
94
89
|
let createOrderPayload: Maybe<OrderCredentialCreationPayload>;
|
|
95
|
-
const {
|
|
90
|
+
const order = CredentialOrderFactory({ order_group_id: orderGroup.id }).one();
|
|
91
|
+
const orderQueryParameters = {
|
|
92
|
+
course_code: course.code,
|
|
93
|
+
product_id: product.id,
|
|
94
|
+
state: NOT_CANCELED_ORDER_STATES,
|
|
95
|
+
};
|
|
96
|
+
const url = `https://joanie.endpoint/api/v1.0/orders/?${queryString.stringify(orderQueryParameters)}`;
|
|
96
97
|
fetchMock
|
|
98
|
+
.get(url, [])
|
|
97
99
|
.get(
|
|
98
|
-
`https://joanie.endpoint/api/v1.0/
|
|
100
|
+
`https://joanie.endpoint/api/v1.0/courses/${course.code}/products/${product.id}/payment-schedule/`,
|
|
99
101
|
[],
|
|
100
102
|
)
|
|
101
|
-
.post('https://joanie.endpoint/api/v1.0/orders/', (
|
|
103
|
+
.post('https://joanie.endpoint/api/v1.0/orders/', (_, { body }) => {
|
|
102
104
|
createOrderPayload = JSON.parse(body as any);
|
|
103
105
|
return order;
|
|
104
106
|
})
|
|
105
|
-
.patch(`https://joanie.endpoint/api/v1.0/orders/${order.id}/submit/`, {
|
|
106
|
-
paymentInfo,
|
|
107
|
-
})
|
|
108
|
-
.get(`https://joanie.endpoint/api/v1.0/orders/${order.id}/`, {
|
|
109
|
-
...order,
|
|
110
|
-
})
|
|
111
107
|
.get('https://joanie.endpoint/api/v1.0/addresses/', [billingAddress], {
|
|
112
108
|
overwriteRoutes: true,
|
|
113
109
|
});
|
|
@@ -120,16 +116,9 @@ describe('SaleTunnel / Credential', () => {
|
|
|
120
116
|
await screen.findByText(getAddressLabel(billingAddress));
|
|
121
117
|
|
|
122
118
|
const $button = screen.getByRole('button', {
|
|
123
|
-
name: `
|
|
119
|
+
name: `Subscribe`,
|
|
124
120
|
}) as HTMLButtonElement;
|
|
125
121
|
|
|
126
|
-
const $terms = screen.getByLabelText(
|
|
127
|
-
'By checking this box, you accept the General Terms of Sale',
|
|
128
|
-
);
|
|
129
|
-
await act(async () => {
|
|
130
|
-
fireEvent.click($terms);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
122
|
// - Payment button should not be disabled.
|
|
134
123
|
expect($button.disabled).toBe(false);
|
|
135
124
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { screen, within } from '@testing-library/react';
|
|
1
|
+
import { act, screen, within } from '@testing-library/react';
|
|
2
2
|
import fetchMock from 'fetch-mock';
|
|
3
3
|
import queryString from 'query-string';
|
|
4
4
|
import userEvent from '@testing-library/user-event';
|
|
5
5
|
import countries from 'i18n-iso-countries';
|
|
6
|
+
import { getAllByRole } from '@testing-library/dom';
|
|
6
7
|
import {
|
|
7
8
|
RichieContextFactory as mockRichieContextFactory,
|
|
8
9
|
PacedCourseFactory,
|
|
@@ -13,10 +14,14 @@ import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
|
13
14
|
import CourseProductItem from 'widgets/SyllabusCourseRunsList/components/CourseProductItem';
|
|
14
15
|
import {
|
|
15
16
|
AddressFactory,
|
|
16
|
-
|
|
17
|
+
ContractFactory,
|
|
17
18
|
CourseProductRelationFactory,
|
|
19
|
+
CredentialOrderFactory,
|
|
20
|
+
CreditCardFactory,
|
|
21
|
+
PaymentFactory,
|
|
22
|
+
PaymentInstallmentFactory,
|
|
18
23
|
} from 'utils/test/factories/joanie';
|
|
19
|
-
import {
|
|
24
|
+
import { CourseRun, NOT_CANCELED_ORDER_STATES, OrderState } from 'types/Joanie';
|
|
20
25
|
import { Priority } from 'types';
|
|
21
26
|
import { expectMenuToBeClosed, expectMenuToBeOpen } from 'utils/test/Cunningham';
|
|
22
27
|
import { changeSelect } from 'components/Form/test-utils';
|
|
@@ -25,6 +30,7 @@ import { OpenEdxApiProfileFactory } from 'utils/test/factories/openEdx';
|
|
|
25
30
|
import { User } from 'types/User';
|
|
26
31
|
import { OpenEdxApiProfile } from 'types/openEdx';
|
|
27
32
|
import { createTestQueryClient } from 'utils/test/createTestQueryClient';
|
|
33
|
+
import { Deferred } from 'utils/test/deferred';
|
|
28
34
|
|
|
29
35
|
jest.mock('utils/context', () => ({
|
|
30
36
|
__esModule: true,
|
|
@@ -53,6 +59,12 @@ describe('SaleTunnel', () => {
|
|
|
53
59
|
let openApiEdxProfile: OpenEdxApiProfile;
|
|
54
60
|
setupJoanieSession();
|
|
55
61
|
|
|
62
|
+
const dateFormatter = Intl.DateTimeFormat('en', {
|
|
63
|
+
day: '2-digit',
|
|
64
|
+
month: 'short',
|
|
65
|
+
year: 'numeric',
|
|
66
|
+
});
|
|
67
|
+
|
|
56
68
|
const priceFormatter = (currency: string, price: number) =>
|
|
57
69
|
new Intl.NumberFormat('en', {
|
|
58
70
|
currency,
|
|
@@ -80,37 +92,37 @@ describe('SaleTunnel', () => {
|
|
|
80
92
|
fetchMock.get(`https://auth.test/api/v1.0/user/me`, richieUser);
|
|
81
93
|
});
|
|
82
94
|
|
|
83
|
-
it('tests the entire process of
|
|
95
|
+
it('tests the entire process of subscribing to a credential product', async () => {
|
|
84
96
|
/**
|
|
85
97
|
* Initialization.
|
|
86
98
|
*/
|
|
87
|
-
const
|
|
88
|
-
const {
|
|
99
|
+
const course = PacedCourseFactory().one();
|
|
100
|
+
const relation = CourseProductRelationFactory({ course }).one();
|
|
101
|
+
const paymentSchedule = PaymentInstallmentFactory().many(2);
|
|
102
|
+
const { product } = relation;
|
|
89
103
|
|
|
90
104
|
fetchMock.get(
|
|
91
105
|
`https://joanie.endpoint/api/v1.0/courses/${course.code}/products/${product.id}/`,
|
|
92
106
|
relation,
|
|
93
107
|
);
|
|
108
|
+
fetchMock.get(
|
|
109
|
+
`https://joanie.endpoint/api/v1.0/courses/${course.code}/products/${product.id}/payment-schedule/`,
|
|
110
|
+
paymentSchedule,
|
|
111
|
+
);
|
|
94
112
|
fetchMock.get(`https://joanie.endpoint/api/v1.0/enrollments/`, []);
|
|
95
113
|
const orderQueryParameters = {
|
|
96
114
|
product_id: product.id,
|
|
97
115
|
course_code: course.code,
|
|
98
|
-
state:
|
|
116
|
+
state: NOT_CANCELED_ORDER_STATES,
|
|
99
117
|
};
|
|
100
118
|
fetchMock.get(
|
|
101
119
|
`https://joanie.endpoint/api/v1.0/orders/?${queryString.stringify(orderQueryParameters)}`,
|
|
102
120
|
[],
|
|
103
121
|
);
|
|
104
122
|
|
|
105
|
-
render(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
course={PacedCourseFactory({ id: course.id, code: course.code }).one()}
|
|
109
|
-
/>,
|
|
110
|
-
{
|
|
111
|
-
queryOptions: { client: createTestQueryClient({ user: richieUser }) },
|
|
112
|
-
},
|
|
113
|
-
);
|
|
123
|
+
render(<CourseProductItem productId={product.id} course={course} />, {
|
|
124
|
+
queryOptions: { client: createTestQueryClient({ user: richieUser }) },
|
|
125
|
+
});
|
|
114
126
|
|
|
115
127
|
// Wait for product information to be fetched
|
|
116
128
|
await screen.findByRole('heading', { level: 3, name: product.title });
|
|
@@ -210,10 +222,11 @@ describe('SaleTunnel', () => {
|
|
|
210
222
|
|
|
211
223
|
// - User fulfills address fields
|
|
212
224
|
const address = AddressFactory({ is_main: true }).one();
|
|
213
|
-
fetchMock
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
225
|
+
fetchMock
|
|
226
|
+
.post('https://joanie.endpoint/api/v1.0/addresses/', address)
|
|
227
|
+
.get('https://joanie.endpoint/api/v1.0/addresses/', [address], {
|
|
228
|
+
overwriteRoutes: true,
|
|
229
|
+
});
|
|
217
230
|
|
|
218
231
|
await user.type($titleField, address.title);
|
|
219
232
|
await user.type($firstnameField, address.first_name);
|
|
@@ -229,16 +242,23 @@ describe('SaleTunnel', () => {
|
|
|
229
242
|
).toBeInTheDocument();
|
|
230
243
|
|
|
231
244
|
/**
|
|
232
|
-
* Make sure
|
|
245
|
+
* Make sure the payment schedule is displayed.
|
|
233
246
|
*/
|
|
234
|
-
screen.getByRole('heading', {
|
|
235
|
-
|
|
247
|
+
screen.getByRole('heading', { name: 'Payment schedule' });
|
|
248
|
+
paymentSchedule.forEach((installment, index) => {
|
|
249
|
+
const row = screen.getByTestId(installment.id);
|
|
250
|
+
const cells = getAllByRole(row, 'cell');
|
|
251
|
+
expect(cells).toHaveLength(4);
|
|
252
|
+
expect(cells[0]).toHaveTextContent((index + 1).toString());
|
|
253
|
+
expect(cells[1]).toHaveTextContent(
|
|
254
|
+
priceFormatter(installment.currency, installment.amount).replace(/(\u202F|\u00a0)/g, ' '),
|
|
255
|
+
);
|
|
256
|
+
expect(cells[2]).toHaveTextContent(
|
|
257
|
+
`Withdrawn on ${dateFormatter.format(new Date(installment.due_date))}`,
|
|
258
|
+
);
|
|
259
|
+
expect(cells[3]).toHaveTextContent(new RegExp(installment.state, 'i'));
|
|
236
260
|
});
|
|
237
|
-
screen.getByText('Use another credit card during payment');
|
|
238
261
|
|
|
239
|
-
/**
|
|
240
|
-
* Make sure the total is the correct one.
|
|
241
|
-
*/
|
|
242
262
|
const $totalAmount = screen.getByTestId('sale-tunnel__total__amount');
|
|
243
263
|
expect($totalAmount).toHaveTextContent(
|
|
244
264
|
'Total' +
|
|
@@ -246,34 +266,84 @@ describe('SaleTunnel', () => {
|
|
|
246
266
|
);
|
|
247
267
|
|
|
248
268
|
/**
|
|
249
|
-
*
|
|
269
|
+
* Subscribe
|
|
250
270
|
*/
|
|
251
|
-
const
|
|
252
|
-
'By checking this box, you accept the General Terms of Sale',
|
|
253
|
-
);
|
|
254
|
-
await user.click($terms);
|
|
255
|
-
|
|
256
|
-
const { payment_info: paymentInfo, ...order } = CredentialOrderWithPaymentFactory().one();
|
|
271
|
+
const order = CredentialOrderFactory({ state: OrderState.TO_SIGN }).one();
|
|
257
272
|
fetchMock
|
|
273
|
+
.post('https://joanie.endpoint/api/v1.0/orders/', order)
|
|
258
274
|
.get(
|
|
259
275
|
`https://joanie.endpoint/api/v1.0/orders/?${queryString.stringify(orderQueryParameters)}`,
|
|
260
276
|
[order],
|
|
261
277
|
{ overwriteRoutes: true },
|
|
262
|
-
)
|
|
263
|
-
.post('https://joanie.endpoint/api/v1.0/orders/', order)
|
|
264
|
-
.patch(`https://joanie.endpoint/api/v1.0/orders/${order.id}/submit/`, {
|
|
265
|
-
paymentInfo,
|
|
266
|
-
})
|
|
267
|
-
.get(`https://joanie.endpoint/api/v1.0/orders/${order.id}/`, {
|
|
268
|
-
...order,
|
|
269
|
-
});
|
|
278
|
+
);
|
|
270
279
|
|
|
271
280
|
const $button = screen.getByRole('button', {
|
|
272
|
-
name: `
|
|
281
|
+
name: `Subscribe`,
|
|
273
282
|
}) as HTMLButtonElement;
|
|
274
283
|
await user.click($button);
|
|
275
284
|
|
|
276
|
-
|
|
285
|
+
order.state = OrderState.TO_SAVE_PAYMENT_METHOD;
|
|
286
|
+
order.contract = ContractFactory({ student_signed_on: new Date().toISOString() }).one();
|
|
287
|
+
|
|
288
|
+
const checkSignatureDeferred = new Deferred();
|
|
289
|
+
|
|
290
|
+
fetchMock
|
|
291
|
+
.post(`https://joanie.endpoint/api/v1.0/orders/${order.id}/submit_for_signature/`, {
|
|
292
|
+
invitation_link: 'https://dummysignaturebackend.fr/contract/1/sign',
|
|
293
|
+
})
|
|
294
|
+
.post(`https://joanie.endpoint/api/v1.0/signature/notifications/`, 200)
|
|
295
|
+
.get(`https://joanie.endpoint/api/v1.0/orders/${order.id}/`, checkSignatureDeferred.promise, {
|
|
296
|
+
overwriteRoutes: true,
|
|
297
|
+
})
|
|
298
|
+
.get(
|
|
299
|
+
`https://joanie.endpoint/api/v1.0/orders/?${queryString.stringify(orderQueryParameters)}`,
|
|
300
|
+
[order],
|
|
301
|
+
{ overwriteRoutes: true },
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
const $signButton = await screen.findByRole('button', { name: 'Sign' });
|
|
305
|
+
await user.click($signButton);
|
|
306
|
+
|
|
307
|
+
screen.getByRole('heading', { name: 'Signing the contract ...' });
|
|
308
|
+
|
|
309
|
+
// Then the signature check polling should be started
|
|
310
|
+
await screen.findByRole('heading', { name: 'Verifying signature ...' });
|
|
311
|
+
expect(
|
|
312
|
+
screen.getByText(
|
|
313
|
+
'We are waiting for the signature to be validated from our signature platform. It can take up to few minutes. Do not close this page.',
|
|
314
|
+
),
|
|
315
|
+
).toBeInTheDocument();
|
|
316
|
+
expect(screen.getByRole('status')).toBeInTheDocument();
|
|
317
|
+
|
|
318
|
+
await act(async () => {
|
|
319
|
+
checkSignatureDeferred.resolve(order);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Save payment method step
|
|
324
|
+
*/
|
|
325
|
+
const paymentMethod = CreditCardFactory().one();
|
|
326
|
+
order.state = OrderState.PENDING;
|
|
327
|
+
order.credit_card_id = paymentMethod.id;
|
|
328
|
+
fetchMock
|
|
329
|
+
.post('https://joanie.endpoint/api/v1.0/credit-cards/tokenize-card/', PaymentFactory().one())
|
|
330
|
+
.post(`https://joanie.endpoint/api/v1.0/orders/${order.id}/payment-method/`, 200)
|
|
331
|
+
.get(
|
|
332
|
+
'https://joanie.endpoint/api/v1.0/credit-cards/',
|
|
333
|
+
{ results: [paymentMethod] },
|
|
334
|
+
{ overwriteRoutes: true },
|
|
335
|
+
)
|
|
336
|
+
.get(
|
|
337
|
+
`https://joanie.endpoint/api/v1.0/orders/?${queryString.stringify(orderQueryParameters)}`,
|
|
338
|
+
[order],
|
|
339
|
+
{ overwriteRoutes: true },
|
|
340
|
+
);
|
|
341
|
+
await screen.findByRole('heading', { name: 'Define a payment method' });
|
|
342
|
+
screen.getByText('Use another credit card');
|
|
343
|
+
|
|
344
|
+
const $defineButton = screen.getByRole('button', { name: 'Define' });
|
|
345
|
+
await user.click($defineButton);
|
|
346
|
+
|
|
277
347
|
screen.getByText('Payment interface component');
|
|
278
348
|
await user.click(screen.getByTestId('payment-success'));
|
|
279
349
|
|
|
@@ -282,11 +352,9 @@ describe('SaleTunnel', () => {
|
|
|
282
352
|
*/
|
|
283
353
|
|
|
284
354
|
// Make sure the success step is shown.
|
|
285
|
-
expect(screen.queryByTestId('generic-sale-tunnel-payment-step')).not.toBeInTheDocument();
|
|
286
355
|
await screen.findByTestId('generic-sale-tunnel-success-step');
|
|
287
|
-
screen.getByText('
|
|
288
|
-
screen.
|
|
289
|
-
screen.getByRole('link', { name: 'Sign the training contract' });
|
|
356
|
+
screen.getByText('Subscription confirmed!');
|
|
357
|
+
screen.getByRole('link', { name: 'Close' });
|
|
290
358
|
|
|
291
359
|
/**
|
|
292
360
|
* Make sure the product is displayed as bought ( it verifies cache is well updated ).
|