richie-education 3.3.2-dev32 → 3.3.2-dev33

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.
@@ -236,7 +236,12 @@ export const SaleTunnelInformationSingular = () => {
236
236
  </div>
237
237
  )}
238
238
  {paymentMode === PaymentMode.CPF ? (
239
- <CpfPayment deepLink={deepLink!} />
239
+ <CpfPayment
240
+ deepLink={deepLink!}
241
+ discount={discount}
242
+ voucherError={voucherError}
243
+ setVoucherError={setVoucherError}
244
+ />
240
245
  ) : (
241
246
  <>
242
247
  {needsPayment && (
@@ -499,7 +504,17 @@ const PaymentScheduleBlock = ({ schedule }: { schedule: PaymentSchedule }) => {
499
504
  );
500
505
  };
501
506
 
502
- const CpfPayment = ({ deepLink }: { deepLink: string }) => {
507
+ const CpfPayment = ({
508
+ deepLink,
509
+ discount,
510
+ voucherError,
511
+ setVoucherError,
512
+ }: {
513
+ deepLink: string;
514
+ discount?: string;
515
+ voucherError: HttpError | null;
516
+ setVoucherError: (value: HttpError | null) => void;
517
+ }) => {
503
518
  return (
504
519
  <div className="sale-tunnel__cpf">
505
520
  <p className="description mb-s">
@@ -514,6 +529,7 @@ const CpfPayment = ({ deepLink }: { deepLink: string }) => {
514
529
  >
515
530
  <FormattedMessage {...messages.cpfButtonLabel} />
516
531
  </Button>
532
+ <Voucher discount={discount} voucherError={voucherError} setVoucherError={setVoucherError} />
517
533
  </div>
518
534
  );
519
535
  };
@@ -110,9 +110,6 @@ const SubscriptionButton = ({ buildOrderPayload }: Props) => {
110
110
  paymentMode,
111
111
  } = useSaleTunnelContext();
112
112
 
113
- if (paymentMode === PaymentMode.CPF) {
114
- return null;
115
- }
116
113
  const { methods: orderMethods } = useOrders(undefined, { enabled: false });
117
114
  const { methods: batchOrderMethods } = useBatchOrder();
118
115
  const [state, setState] = useState<ComponentStates>(ComponentStates.IDLE);
@@ -138,12 +135,17 @@ const SubscriptionButton = ({ buildOrderPayload }: Props) => {
138
135
  return;
139
136
  }
140
137
 
141
- if (!billingAddress && needsPayment) {
138
+ if (!billingAddress && needsPayment && paymentMode !== PaymentMode.CPF) {
142
139
  handleError(SubscriptionErrorMessageId.ERROR_ADDRESS);
143
140
  return;
144
141
  }
145
142
 
146
- if (!saleTunnelProps.isWithdrawable && !hasWaivedWithdrawalRight && needsPayment) {
143
+ if (
144
+ !saleTunnelProps.isWithdrawable &&
145
+ !hasWaivedWithdrawalRight &&
146
+ needsPayment &&
147
+ paymentMode !== PaymentMode.CPF
148
+ ) {
147
149
  handleError(SubscriptionErrorMessageId.ERROR_WITHDRAWAL_RIGHT);
148
150
  return;
149
151
  }
@@ -222,4 +222,51 @@ describe('SaleTunnel / Credential', () => {
222
222
  // - Classic billing information section should be displayed.
223
223
  expect(screen.getByText(/this information will be used for billing/i)).toBeInTheDocument();
224
224
  });
225
+
226
+ it('should display voucher input and subscribe button in CPF mode', async () => {
227
+ const course = PacedCourseFactory().one();
228
+ const product = CredentialProductFactory().one();
229
+ const billingAddress: Joanie.Address = AddressFactory({ is_main: true }).one();
230
+ const deepLink = 'https://placeholder.com/course/1';
231
+ const orderQueryParameters = {
232
+ course_code: course.code,
233
+ product_id: product.id,
234
+ state: NOT_CANCELED_ORDER_STATES,
235
+ };
236
+
237
+ fetchMock
238
+ .get(
239
+ `https://joanie.endpoint/api/v1.0/orders/?${queryString.stringify(orderQueryParameters)}`,
240
+ [],
241
+ )
242
+ .get(
243
+ `https://joanie.endpoint/api/v1.0/courses/${course.code}/products/${product.id}/payment-plan/`,
244
+ [],
245
+ )
246
+ .get(
247
+ `https://joanie.endpoint/api/v1.0/courses/${course.code}/products/${product.id}/deep-link/`,
248
+ { deep_link: deepLink },
249
+ )
250
+ .get('https://joanie.endpoint/api/v1.0/addresses/', [billingAddress], {
251
+ overwriteRoutes: true,
252
+ });
253
+
254
+ const user = userEvent.setup({ delay: null });
255
+
256
+ render(<Wrapper product={product} course={course} />, {
257
+ queryOptions: { client: createTestQueryClient({ user: richieUser }) },
258
+ });
259
+
260
+ await screen.findByRole('heading', { level: 3, name: /payment method/i });
261
+
262
+ // Switch to CPF mode
263
+ await user.click(screen.getByRole('radio', { name: /my training account \(cpf\)/i }));
264
+
265
+ // - Voucher input should be visible in CPF mode.
266
+ expect(screen.getByLabelText('Voucher code')).toBeInTheDocument();
267
+ expect(screen.getByRole('button', { name: 'Validate' })).toBeInTheDocument();
268
+
269
+ // - Subscribe button should be visible in CPF mode.
270
+ expect(screen.getByRole('button', { name: 'Subscribe' })).toBeInTheDocument();
271
+ });
225
272
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "richie-education",
3
- "version": "3.3.2-dev32",
3
+ "version": "3.3.2-dev33",
4
4
  "description": "A CMS to build learning portals for Open Education",
5
5
  "main": "sandbox/manage.py",
6
6
  "scripts": {