richie-education 2.28.0 → 2.28.2-dev23
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/fr-FR.json +10 -10
- package/js/components/AddressesManagement/AddressForm/validationSchema.spec.ts +2 -2
- package/js/components/PaymentInterfaces/LyraPopIn.tsx +10 -3
- package/js/components/PaymentInterfaces/types.ts +1 -1
- package/js/components/PurchaseButton/index.spec.tsx +9 -9
- package/js/components/PurchaseButton/index.tsx +2 -1
- package/js/components/SaleTunnel/GenericPaymentButton/index.tsx +13 -3
- package/js/components/SaleTunnel/hooks/useTerms.tsx +2 -2
- package/js/components/SaleTunnel/index.credential.spec.tsx +2 -2
- package/js/components/SaleTunnel/index.full-process.spec.tsx +11 -4
- package/js/components/SaleTunnel/index.spec.tsx +2 -2
- package/js/components/SaleTunnel/index.stories.tsx +3 -2
- package/js/components/SaleTunnel/index.tsx +2 -2
- package/js/translations/fr-FR.json +1 -1
- package/js/types/commonDataProps.ts +0 -1
- package/js/types/index.ts +6 -0
- package/js/utils/CourseRunHelper/index.spec.ts +35 -0
- package/js/utils/CourseRunHelper/index.ts +13 -0
- package/js/utils/react-query/useSessionQuery/index.ts +1 -1
- package/js/utils/test/factories/richie.ts +16 -2
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.spec.tsx +35 -5
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.tsx +11 -10
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/CourseProductItemFooter/index.tsx +3 -2
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +32 -30
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.stories.tsx +5 -6
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.tsx +3 -2
- package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.login.spec.tsx +5 -3
- package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.logout.spec.tsx +5 -3
- package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.tsx +2 -2
- package/js/widgets/SyllabusCourseRunsList/components/SyllabusAsideList/index.tsx +11 -4
- package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRun/index.tsx +20 -9
- package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRunCompacted/index.tsx +111 -0
- package/js/widgets/SyllabusCourseRunsList/index.spec.tsx +311 -15
- package/js/widgets/SyllabusCourseRunsList/index.tsx +24 -8
- package/package.json +44 -44
- package/tsconfig.json +1 -1
package/i18n/locales/fr-FR.json
CHANGED
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
},
|
|
126
126
|
"components.ContractStatus.learnerSignedOn": {
|
|
127
127
|
"description": "Label for the date of sign of a training contract by the learner",
|
|
128
|
-
"message": "Vous avez signé ce contrat de formation.
|
|
128
|
+
"message": "Vous avez signé ce contrat de formation. Signé le {date}"
|
|
129
129
|
},
|
|
130
130
|
"components.ContractStatus.organizationSignedOn": {
|
|
131
131
|
"description": "Label for the date of sign of a training contract by the organization",
|
|
@@ -253,7 +253,7 @@
|
|
|
253
253
|
},
|
|
254
254
|
"components.CourseRunEnrollment.enroll": {
|
|
255
255
|
"description": "CTA for users who can enroll in the course run or could enroll if they logged in.",
|
|
256
|
-
"message": "
|
|
256
|
+
"message": "Je m'inscris"
|
|
257
257
|
},
|
|
258
258
|
"components.CourseRunEnrollment.enrolled": {
|
|
259
259
|
"description": "Help text for users who see the \"Go to course\" CTA on course run enrollment",
|
|
@@ -281,7 +281,7 @@
|
|
|
281
281
|
},
|
|
282
282
|
"components.CourseRunEnrollment.loginToEnroll": {
|
|
283
283
|
"description": "Helper text in the enroll button for non logged in users",
|
|
284
|
-
"message": "
|
|
284
|
+
"message": "Je me connecte pour m’inscrire"
|
|
285
285
|
},
|
|
286
286
|
"components.CourseRunEnrollment.unenroll": {
|
|
287
287
|
"description": "Help text below the \"Unenroll now\" CTA when an enrollment attempt has already failed.",
|
|
@@ -1209,7 +1209,7 @@
|
|
|
1209
1209
|
},
|
|
1210
1210
|
"components.SaleTunnel.loginToPurchase": {
|
|
1211
1211
|
"description": "Label displayed inside the product's CTA when user is not logged in",
|
|
1212
|
-
"message": "
|
|
1212
|
+
"message": "Je me connecte pour m’inscrire {product}"
|
|
1213
1213
|
},
|
|
1214
1214
|
"components.SaleTunnel.noCourseRunToPurchaseCertificate": {
|
|
1215
1215
|
"description": "Label displayed below the product's CTA when there is no courseRun",
|
|
@@ -1261,7 +1261,7 @@
|
|
|
1261
1261
|
},
|
|
1262
1262
|
"components.SaleTunnelSuccess.successDetailMessage": {
|
|
1263
1263
|
"description": "Text to remind that order's invoice will be send by email soon",
|
|
1264
|
-
"message": "Vous allez recevoir votre
|
|
1264
|
+
"message": "Vous allez recevoir votre preuve de paiement par mail dans quelques instants."
|
|
1265
1265
|
},
|
|
1266
1266
|
"components.SaleTunnelSuccess.successDetailSignatureMessage": {
|
|
1267
1267
|
"description": "Text to remind that order needs to be signed",
|
|
@@ -1281,7 +1281,7 @@
|
|
|
1281
1281
|
},
|
|
1282
1282
|
"components.SaleTunnelSuccessNotValidated.description": {
|
|
1283
1283
|
"description": "Text to remind that order's invoice will be send by email soon",
|
|
1284
|
-
"message": "Votre paiement a été accepté mais la validation de votre commande prend plus de temps que prévu, vous pouvez fermer cette fenêtre et revenir plus tard. Vous allez recevoir votre
|
|
1284
|
+
"message": "Votre paiement a été accepté mais la validation de votre commande prend plus de temps que prévu, vous pouvez fermer cette fenêtre et revenir plus tard. Vous allez recevoir votre preuve de paiement par mail dans quelques instants."
|
|
1285
1285
|
},
|
|
1286
1286
|
"components.SaleTunnelSuccessNotValidated.title": {
|
|
1287
1287
|
"description": "Message to confirm that order has been created",
|
|
@@ -1429,7 +1429,7 @@
|
|
|
1429
1429
|
},
|
|
1430
1430
|
"components.SyllabusCourseRun.coursePeriod": {
|
|
1431
1431
|
"description": "Course date of an opened course run block",
|
|
1432
|
-
"message": "
|
|
1432
|
+
"message": "Du {startDate} {endDate, select, undefined {} other {au {endDate}}}"
|
|
1433
1433
|
},
|
|
1434
1434
|
"components.SyllabusCourseRun.enrollment": {
|
|
1435
1435
|
"description": "Title of the enrollment dates section of an opened course run block",
|
|
@@ -1437,7 +1437,7 @@
|
|
|
1437
1437
|
},
|
|
1438
1438
|
"components.SyllabusCourseRun.enrollmentPeriod": {
|
|
1439
1439
|
"description": "Enrollment date of an opened course run block",
|
|
1440
|
-
"message": "
|
|
1440
|
+
"message": "Du {startDate} {endDate, select, undefined {} other {au {endDate}}}"
|
|
1441
1441
|
},
|
|
1442
1442
|
"components.SyllabusCourseRun.languages": {
|
|
1443
1443
|
"description": "Title of the languages section of an opened course run block",
|
|
@@ -2025,7 +2025,7 @@
|
|
|
2025
2025
|
},
|
|
2026
2026
|
"utils.ContractHelper.learnerSigned": {
|
|
2027
2027
|
"description": "Label for signed contract status in learner point of view",
|
|
2028
|
-
"message": "
|
|
2028
|
+
"message": "Signé"
|
|
2029
2029
|
},
|
|
2030
2030
|
"utils.ContractHelper.learnerUnsigned": {
|
|
2031
2031
|
"description": "Label for unsigned contract status in learner point of view",
|
|
@@ -2037,7 +2037,7 @@
|
|
|
2037
2037
|
},
|
|
2038
2038
|
"utils.ContractHelper.organizationSigned": {
|
|
2039
2039
|
"description": "Label for signed contract status in organization point of view",
|
|
2040
|
-
"message": "
|
|
2040
|
+
"message": "Signé"
|
|
2041
2041
|
},
|
|
2042
2042
|
"utils.ContractHelper.organizationUnsigned": {
|
|
2043
2043
|
"description": "Label for unsigned contract status in organization point of view",
|
|
@@ -15,7 +15,7 @@ describe('validationSchema', () => {
|
|
|
15
15
|
first_name: faker.person.firstName(),
|
|
16
16
|
last_name: faker.person.lastName(),
|
|
17
17
|
postcode: faker.location.zipCode(),
|
|
18
|
-
title: faker.lorem.word(),
|
|
18
|
+
title: faker.lorem.word({ length: { min: 2, max: 15 } }),
|
|
19
19
|
save: false,
|
|
20
20
|
};
|
|
21
21
|
|
|
@@ -130,7 +130,7 @@ describe('validationSchema', () => {
|
|
|
130
130
|
result.current.setValue('first_name', faker.person.firstName());
|
|
131
131
|
result.current.setValue('last_name', faker.person.lastName());
|
|
132
132
|
result.current.setValue('postcode', faker.location.zipCode());
|
|
133
|
-
result.current.setValue('title', faker.lorem.word());
|
|
133
|
+
result.current.setValue('title', faker.lorem.word({ length: { min: 2, max: 15 } }));
|
|
134
134
|
result.current.trigger();
|
|
135
135
|
});
|
|
136
136
|
|
|
@@ -25,11 +25,13 @@ const LyraPopIn = ({
|
|
|
25
25
|
const intl = useIntl();
|
|
26
26
|
const shouldAbort = useRef<Boolean>(true);
|
|
27
27
|
|
|
28
|
-
const handleError = (error?: Error) => {
|
|
29
|
-
if (error) handle(`[LyraPopIn] - ${error}`);
|
|
28
|
+
const handleError = (error?: Error | string) => {
|
|
29
|
+
if (error && typeof error === 'string') handle(`[LyraPopIn] - ${error}`);
|
|
30
30
|
|
|
31
31
|
if (shouldAbort.current) {
|
|
32
32
|
onError(PaymentErrorMessageId.ERROR_ABORTING);
|
|
33
|
+
} else if (typeof error === 'string') {
|
|
34
|
+
onError(error);
|
|
33
35
|
} else {
|
|
34
36
|
onError(PaymentErrorMessageId.ERROR_DEFAULT);
|
|
35
37
|
}
|
|
@@ -95,8 +97,13 @@ const LyraPopIn = ({
|
|
|
95
97
|
// Do not close the pop-in if the error is a invalid data error (CLIENT_3XX).
|
|
96
98
|
// https://docs.lyra.com/fr/rest/V4.0/javascript/features/js_error_management.html#client004
|
|
97
99
|
if (!error.errorCode.startsWith('CLIENT_3')) {
|
|
100
|
+
shouldAbort.current = false;
|
|
98
101
|
await KR.closePopin(formId);
|
|
99
|
-
|
|
102
|
+
let errorMessages = error.errorMessage;
|
|
103
|
+
if (error.detailedErrorMessage) {
|
|
104
|
+
errorMessages += `: ${error.detailedErrorMessage}`;
|
|
105
|
+
}
|
|
106
|
+
handleError(errorMessages);
|
|
100
107
|
}
|
|
101
108
|
};
|
|
102
109
|
|
|
@@ -42,5 +42,5 @@ export type Payment = DummyPayment | PayplugPayment | LyraPayment;
|
|
|
42
42
|
|
|
43
43
|
export type PaymentInterfaceProps<P extends Payment = Payment> = P & {
|
|
44
44
|
onSuccess: () => void;
|
|
45
|
-
onError: (messageId: PaymentErrorMessageId) => void;
|
|
45
|
+
onError: (messageId: string | PaymentErrorMessageId) => void;
|
|
46
46
|
};
|
|
@@ -6,12 +6,12 @@ import userEvent from '@testing-library/user-event';
|
|
|
6
6
|
import { CunninghamProvider } from '@openfun/cunningham-react';
|
|
7
7
|
import {
|
|
8
8
|
CourseStateFactory,
|
|
9
|
+
PacedCourseFactory,
|
|
9
10
|
UserFactory,
|
|
10
11
|
RichieContextFactory as mockRichieContextFactory,
|
|
11
12
|
} from 'utils/test/factories/richie';
|
|
12
13
|
import {
|
|
13
14
|
CertificateProductFactory,
|
|
14
|
-
CourseLightFactory,
|
|
15
15
|
EnrollmentFactory,
|
|
16
16
|
ProductFactory,
|
|
17
17
|
} from 'utils/test/factories/joanie';
|
|
@@ -89,7 +89,7 @@ describe('PurchaseButton', () => {
|
|
|
89
89
|
<PurchaseButton
|
|
90
90
|
product={product}
|
|
91
91
|
disabled={false}
|
|
92
|
-
course={
|
|
92
|
+
course={PacedCourseFactory({ code: '00000' }).one()}
|
|
93
93
|
/>
|
|
94
94
|
</Wrapper>,
|
|
95
95
|
);
|
|
@@ -112,7 +112,7 @@ describe('PurchaseButton', () => {
|
|
|
112
112
|
<PurchaseButton
|
|
113
113
|
product={product}
|
|
114
114
|
disabled={false}
|
|
115
|
-
course={
|
|
115
|
+
course={PacedCourseFactory({ code: courseCode }).one()}
|
|
116
116
|
/>
|
|
117
117
|
</Wrapper>,
|
|
118
118
|
);
|
|
@@ -146,7 +146,7 @@ describe('PurchaseButton', () => {
|
|
|
146
146
|
<PurchaseButton
|
|
147
147
|
product={product}
|
|
148
148
|
disabled={false}
|
|
149
|
-
course={
|
|
149
|
+
course={PacedCourseFactory({ code: courseCode }).one()}
|
|
150
150
|
/>
|
|
151
151
|
</Wrapper>,
|
|
152
152
|
);
|
|
@@ -181,7 +181,7 @@ describe('PurchaseButton', () => {
|
|
|
181
181
|
<PurchaseButton
|
|
182
182
|
product={product}
|
|
183
183
|
disabled={false}
|
|
184
|
-
course={
|
|
184
|
+
course={PacedCourseFactory({ code: courseCode }).one()}
|
|
185
185
|
/>
|
|
186
186
|
</Wrapper>,
|
|
187
187
|
);
|
|
@@ -214,7 +214,7 @@ describe('PurchaseButton', () => {
|
|
|
214
214
|
<PurchaseButton
|
|
215
215
|
product={product}
|
|
216
216
|
disabled={false}
|
|
217
|
-
course={
|
|
217
|
+
course={PacedCourseFactory({ code: courseCode }).one()}
|
|
218
218
|
/>
|
|
219
219
|
</Wrapper>,
|
|
220
220
|
);
|
|
@@ -251,7 +251,7 @@ describe('PurchaseButton', () => {
|
|
|
251
251
|
<PurchaseButton
|
|
252
252
|
product={product}
|
|
253
253
|
disabled={false}
|
|
254
|
-
course={
|
|
254
|
+
course={PacedCourseFactory({ code: courseCode }).one()}
|
|
255
255
|
/>
|
|
256
256
|
</Wrapper>,
|
|
257
257
|
);
|
|
@@ -384,7 +384,7 @@ describe('PurchaseButton', () => {
|
|
|
384
384
|
<PurchaseButton
|
|
385
385
|
product={product}
|
|
386
386
|
disabled={false}
|
|
387
|
-
course={
|
|
387
|
+
course={PacedCourseFactory({ code: courseCode }).one()}
|
|
388
388
|
/>
|
|
389
389
|
</Wrapper>,
|
|
390
390
|
);
|
|
@@ -414,7 +414,7 @@ describe('PurchaseButton', () => {
|
|
|
414
414
|
<PurchaseButton
|
|
415
415
|
product={product}
|
|
416
416
|
disabled={true}
|
|
417
|
-
course={
|
|
417
|
+
course={PacedCourseFactory({ code: courseCode }).one()}
|
|
418
418
|
/>
|
|
419
419
|
</Wrapper>,
|
|
420
420
|
);
|
|
@@ -7,6 +7,7 @@ import * as Joanie from 'types/Joanie';
|
|
|
7
7
|
import { isOpenedCourseRunCertificate, isOpenedCourseRunCredential } from 'utils/CourseRuns';
|
|
8
8
|
import { SaleTunnel, SaleTunnelProps } from 'components/SaleTunnel';
|
|
9
9
|
import { Organization } from 'types/Joanie';
|
|
10
|
+
import { PacedCourse } from 'types';
|
|
10
11
|
|
|
11
12
|
const messages = defineMessages({
|
|
12
13
|
loginToPurchase: {
|
|
@@ -52,7 +53,7 @@ interface PurchaseButtonPropsBase {
|
|
|
52
53
|
|
|
53
54
|
interface CredentialPurchaseButtonProps extends PurchaseButtonPropsBase {
|
|
54
55
|
product: Joanie.CredentialProduct;
|
|
55
|
-
course:
|
|
56
|
+
course: PacedCourse;
|
|
56
57
|
enrollment?: undefined;
|
|
57
58
|
}
|
|
58
59
|
|
|
@@ -97,7 +97,7 @@ export const GenericPaymentButton = ({ buildOrderPayload }: Props) => {
|
|
|
97
97
|
const { methods: orderMethods } = useOrders(undefined, { enabled: false });
|
|
98
98
|
const [payment, setPayment] = useState<PaymentInfo>();
|
|
99
99
|
const [state, setState] = useState<ComponentStates>(ComponentStates.IDLE);
|
|
100
|
-
const [error, setError] = useState<PaymentErrorMessageId>();
|
|
100
|
+
const [error, setError] = useState<PaymentErrorMessageId | string>();
|
|
101
101
|
const hasPaymentId = (p: Maybe<Payment>): p is Extract<Payment, PaymentWithId> => {
|
|
102
102
|
return Boolean(p?.hasOwnProperty('payment_id'));
|
|
103
103
|
};
|
|
@@ -256,7 +256,9 @@ export const GenericPaymentButton = ({ buildOrderPayload }: Props) => {
|
|
|
256
256
|
checkOrderValidity();
|
|
257
257
|
};
|
|
258
258
|
|
|
259
|
-
const handleError = (
|
|
259
|
+
const handleError = (
|
|
260
|
+
messageId: PaymentErrorMessageId | string = PaymentErrorMessageId.ERROR_DEFAULT,
|
|
261
|
+
) => {
|
|
260
262
|
setState(ComponentStates.ERROR);
|
|
261
263
|
setError(messageId);
|
|
262
264
|
};
|
|
@@ -274,6 +276,8 @@ export const GenericPaymentButton = ({ buildOrderPayload }: Props) => {
|
|
|
274
276
|
.catch(() => {
|
|
275
277
|
handleError();
|
|
276
278
|
});
|
|
279
|
+
} else if (error && !messages.hasOwnProperty(error)) {
|
|
280
|
+
orderMethods.invalidate();
|
|
277
281
|
} else if (state === ComponentStates.ERROR) {
|
|
278
282
|
setPayment(undefined);
|
|
279
283
|
}
|
|
@@ -320,7 +324,13 @@ export const GenericPaymentButton = ({ buildOrderPayload }: Props) => {
|
|
|
320
324
|
)}
|
|
321
325
|
{state === ComponentStates.ERROR && (
|
|
322
326
|
<p className="payment-button__error" id="sale-tunnel-payment-error" tabIndex={-1}>
|
|
323
|
-
|
|
327
|
+
{!error || messages.hasOwnProperty(error) ? (
|
|
328
|
+
<FormattedMessage
|
|
329
|
+
{...messages[(error as PaymentErrorMessageId) || PaymentErrorMessageId.ERROR_DEFAULT]}
|
|
330
|
+
/>
|
|
331
|
+
) : (
|
|
332
|
+
error
|
|
333
|
+
)}
|
|
324
334
|
</p>
|
|
325
335
|
)}
|
|
326
336
|
</>
|
|
@@ -29,8 +29,8 @@ export const useTerms = ({
|
|
|
29
29
|
error,
|
|
30
30
|
}: {
|
|
31
31
|
product: Product;
|
|
32
|
-
onError: (error: PaymentErrorMessageId) => void;
|
|
33
|
-
error?: PaymentErrorMessageId;
|
|
32
|
+
onError: (error: PaymentErrorMessageId | string) => void;
|
|
33
|
+
error?: PaymentErrorMessageId | string;
|
|
34
34
|
}) => {
|
|
35
35
|
const intl = useIntl();
|
|
36
36
|
const [termsAccepted, setTermsAccepted] = useState(false);
|
|
@@ -2,12 +2,12 @@ import fetchMock from 'fetch-mock';
|
|
|
2
2
|
import { act, fireEvent, screen, waitFor } from '@testing-library/react';
|
|
3
3
|
import {
|
|
4
4
|
RichieContextFactory as mockRichieContextFactory,
|
|
5
|
+
PacedCourseFactory,
|
|
5
6
|
UserFactory,
|
|
6
7
|
} from 'utils/test/factories/richie';
|
|
7
8
|
import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
8
9
|
import {
|
|
9
10
|
AddressFactory,
|
|
10
|
-
CourseFactory,
|
|
11
11
|
CredentialOrderWithPaymentFactory,
|
|
12
12
|
CredentialProductFactory,
|
|
13
13
|
OrderGroupFactory,
|
|
@@ -86,7 +86,7 @@ describe('SaleTunnel / Credential', () => {
|
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
it('should create an order with an order group', async () => {
|
|
89
|
-
const course =
|
|
89
|
+
const course = PacedCourseFactory().one();
|
|
90
90
|
const product = CredentialProductFactory().one();
|
|
91
91
|
const orderGroup = OrderGroupFactory().one();
|
|
92
92
|
const billingAddress: Joanie.Address = AddressFactory({ is_main: true }).one();
|
|
@@ -5,6 +5,7 @@ import userEvent from '@testing-library/user-event';
|
|
|
5
5
|
import countries from 'i18n-iso-countries';
|
|
6
6
|
import {
|
|
7
7
|
RichieContextFactory as mockRichieContextFactory,
|
|
8
|
+
PacedCourseFactory,
|
|
8
9
|
UserFactory,
|
|
9
10
|
} from 'utils/test/factories/richie';
|
|
10
11
|
import { render } from 'utils/test/render';
|
|
@@ -12,8 +13,8 @@ import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
|
12
13
|
import CourseProductItem from 'widgets/SyllabusCourseRunsList/components/CourseProductItem';
|
|
13
14
|
import {
|
|
14
15
|
AddressFactory,
|
|
15
|
-
CourseProductRelationFactory,
|
|
16
16
|
CredentialOrderWithPaymentFactory,
|
|
17
|
+
CourseProductRelationFactory,
|
|
17
18
|
} from 'utils/test/factories/joanie';
|
|
18
19
|
import { ACTIVE_ORDER_STATES, CourseRun } from 'types/Joanie';
|
|
19
20
|
import { Priority } from 'types';
|
|
@@ -101,9 +102,15 @@ describe('SaleTunnel', () => {
|
|
|
101
102
|
[],
|
|
102
103
|
);
|
|
103
104
|
|
|
104
|
-
render(
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
render(
|
|
106
|
+
<CourseProductItem
|
|
107
|
+
productId={product.id}
|
|
108
|
+
course={PacedCourseFactory({ id: course.id, code: course.code }).one()}
|
|
109
|
+
/>,
|
|
110
|
+
{
|
|
111
|
+
queryOptions: { client: createTestQueryClient({ user: richieUser }) },
|
|
112
|
+
},
|
|
113
|
+
);
|
|
107
114
|
|
|
108
115
|
// Wait for product information to be fetched
|
|
109
116
|
await screen.findByRole('heading', { level: 3, name: product.title });
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
CertificateOrderWithOneClickPaymentFactory,
|
|
9
9
|
CertificateOrderWithPaymentFactory,
|
|
10
10
|
CertificateProductFactory,
|
|
11
|
-
CourseFactory,
|
|
12
11
|
CredentialOrderWithOneClickPaymentFactory,
|
|
13
12
|
CredentialOrderWithPaymentFactory,
|
|
14
13
|
CredentialProductFactory,
|
|
@@ -17,6 +16,7 @@ import {
|
|
|
17
16
|
} from 'utils/test/factories/joanie';
|
|
18
17
|
import {
|
|
19
18
|
RichieContextFactory as mockRichieContextFactory,
|
|
19
|
+
PacedCourseFactory,
|
|
20
20
|
UserFactory,
|
|
21
21
|
} from 'utils/test/factories/richie';
|
|
22
22
|
import { render } from 'utils/test/render';
|
|
@@ -70,7 +70,7 @@ describe.each([
|
|
|
70
70
|
({ productType, ProductFactory, OrderWithOneClickPaymentFactory, OrderWithPaymentFactory }) => {
|
|
71
71
|
let nbApiCalls: number;
|
|
72
72
|
|
|
73
|
-
const course =
|
|
73
|
+
const course = PacedCourseFactory().one();
|
|
74
74
|
const enrollment =
|
|
75
75
|
productType === ProductType.CERTIFICATE ? EnrollmentFactory().one() : undefined;
|
|
76
76
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { StoryObj, Meta } from '@storybook/react';
|
|
2
2
|
import { BaseJoanieAppWrapper } from 'utils/test/wrappers/BaseJoanieAppWrapper';
|
|
3
|
-
import {
|
|
3
|
+
import { ProductFactory } from 'utils/test/factories/joanie';
|
|
4
|
+
import { PacedCourseFactory } from 'utils/test/factories/richie';
|
|
4
5
|
import { SaleTunnel, SaleTunnelProps } from './index';
|
|
5
6
|
|
|
6
7
|
export default {
|
|
@@ -10,7 +11,7 @@ export default {
|
|
|
10
11
|
isOpen: true,
|
|
11
12
|
product: ProductFactory().one(),
|
|
12
13
|
onClose: () => {},
|
|
13
|
-
course:
|
|
14
|
+
course: PacedCourseFactory().one(),
|
|
14
15
|
// enrollment?: Enrollment;
|
|
15
16
|
// product: CredentialProduct | CertificateProduct;
|
|
16
17
|
// orderGroup?: OrderGroup;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ModalProps } from '@openfun/cunningham-react';
|
|
2
2
|
import {
|
|
3
3
|
CertificateProduct,
|
|
4
|
-
CourseLight,
|
|
5
4
|
CredentialProduct,
|
|
6
5
|
Enrollment,
|
|
7
6
|
Order,
|
|
@@ -12,12 +11,13 @@ import {
|
|
|
12
11
|
} from 'types/Joanie';
|
|
13
12
|
import { CredentialSaleTunnel } from 'components/SaleTunnel/CredentialSaleTunnel';
|
|
14
13
|
import { CertificateSaleTunnel } from 'components/SaleTunnel/CertificateSaleTunnel';
|
|
14
|
+
import { PacedCourse } from 'types';
|
|
15
15
|
|
|
16
16
|
export interface SaleTunnelProps extends Pick<ModalProps, 'isOpen' | 'onClose'> {
|
|
17
17
|
product: Product;
|
|
18
18
|
organizations?: Organization[];
|
|
19
19
|
|
|
20
|
-
course?:
|
|
20
|
+
course?: PacedCourse;
|
|
21
21
|
enrollment?: Enrollment;
|
|
22
22
|
orderGroup?: OrderGroup;
|
|
23
23
|
onFinish?: (order: Order) => void;
|