Exploring the implementation of initiating paypal in NestJs using Jest testing framework

Currently, I am creating a test for a method within NestJs that is responsible for initiating a Paypal Payment intent. When I execute either the yarn test:watch or simply yarn test command, the test described below runs successfully and passes. However, upon completion of the test, an error is thrown as shown below.

TEST

describe("PaymentsService", () => {
  let paymentsService: PaymentsService
  let paymentRepository
  let ordersService

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      imports: [
        StripeModule.forRoot({
          apiKey: "stripe.apiKey",
          apiVersion: "2020-08-27",
        }),
      ],
      providers: [
        PaymentsService,
        { provide: PaymentRepository, useFactory: mockPaymentRepository },
        { provide: UsersService, useFactory: mockUsersService },
        { provide: OrdersService, useFactory: mockOrdersService },
        {
          provide: Stripe,
          useFactory: () => ({
            checkout: {
              sessions: {
                create: jest.fn(),
              },
            },
          }),
        },
      ],
    }).compile()

    paymentsService = module.get<PaymentsService>(PaymentsService)
    paymentRepository = module.get<PaymentRepository>(PaymentRepository)
    ordersService = module.get<OrdersService>(OrdersService)
  })

  describe("initiatePaypalPayment", () => {
    it("will initiate paypal payment", async () => {
      ordersService.getOrder.mockResolvedValue(mockOrder)
      ordersService.calculateOrderPrice.mockResolvedValue(mockOrder.price)

      jest.doMock("paypal-rest-sdk", () => {
        return jest.fn(() => ({
          payment: {
            create: jest.fn(() => Promise.resolve({})),
          },
        }))
      })

      expect(
        await paymentsService.initiatePaypalPayment(
          { orderId: 10, voucherCode: "string" },
          mockedResponse
        )
      ).toEqual(undefined)
    })
  })
})

TEST RESULTS

 PASS  src/payments/payments.service.spec.ts
  PaymentsService
    initiatePaypalPayment
      ✓ will initiate paypal payment (117ms)

  console.log src/payments/payments.service.ts:72
    initiatePaypalPayment

  console.log src/payments/payments.service.ts:86
    totalPrice:  1000

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.926s, estimated 6s
Ran all test suites related to changed files.

Watch Usage
 › Press a to run all tests.
 › Press f to run only failed tests.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press q to quit watch mode.
 › Press Enter to trigger a test run.

  ●  Cannot log after tests are done. Did you forget to wait for something async in your test?
    Attempted to log "Error in paypap Error: Response Status : 401
        at IncomingMessage.<anonymous> (/home/user/Desktop/app/node_modules/paypal-rest-sdk/lib/client.js:130:23)
        at IncomingMessage.emit (events.js:326:22)
        at IncomingMessage.EventEmitter.emit (domain.js:483:12)
        at endReadableNT (_stream_readable.js:1241:12)
        at processTicksAndRejections (internal/process/task_queues.js:84:21) {
      response: {
        error: 'invalid_client',
        error_description: 'Client Authentication failed',
        httpStatusCode: 401
      },
      httpStatusCode: 401
    }".

      91 |         payment_method: 'paypal',
      92 |       },
    > 93 |       redirect_urls: {
         |                         ^
      94 |         return_url: 'www.example.com',
      95 |         cancel_url: 'www.example.com',
      96 |       },

      at IncomingMessage.<anonymous> (../node_modules/paypal-rest-sdk/lib/client.js:130:23)
      at processTicksAndRejections (../internal/process/task_queues.js:84:21) {
        response: {
          error: 'invalid_client',
          error_description: 'Client Authentication failed',
          httpStatusCode: 401
        },
        httpStatusCode: 401
      }".
      at console.log (../node_modules/@jest/console/build/CustomConsole.js:183:10)
      at payments/payments.service.ts:93:25
      at ../node_modules/paypal-rest-sdk/lib/api.js:102:13
      at ../node_modules/paypal-rest-sdk/lib/api.js:87:9
      at IncomingMessage.<anonymous> (../node_modules/paypal-rest-sdk/lib/client.js:140:13)

/home/user/Desktop/app/src/payments/payments.service.ts:94
                throw new common_1.InternalServerErrorException();
                ^

InternalServerErrorException: Internal Server Error
    at /home/user/Desktop/app/src/payments/payments.service.ts:115:15
    at /home/user/Desktop/app/node_modules/paypal-rest-sdk/lib/api.js:102:13
    at /home/user/Desktop/app/node_modules/paypal-rest-sdk/lib/api.js:87:9
    at IncomingMessage.<anonymous> (/home/user/Desktop/app/node_modules/paypal-rest-sdk/lib/client.js:140:13)
    at IncomingMessage.emit (events.js:326:22)
    at IncomingMessage.EventEmitter.emit (domain.js:483:12)
    at endReadableNT (_stream_readable.js:1241:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  response: { statusCode: 500, message: 'Internal Server Error' },
  status: 500
}
error Command failed with exit code 1.

The issue could be related to not correctly mocking the paypal-rest-sdk, but there may also be other reasons for this error occurrence. Any assistance on this matter would be greatly appreciated.

Answer №1

Encountering a 401 invalid_client / 'Client Authentication failed' error when using the PayPal API typically stems from one of two issues:

  • The REST APP/API credentials are inaccurate. It is essential to acquire a clientid + secret from and verify that your code is properly configured to utilize them.
  • Using sandbox API credentials in live/production mode, or the reverse scenario. It's crucial to understand that these two environments are entirely distinct, and credentials intended for one environment will not function in the other.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using constant variables as arguments in functions in TypeScript

While learning about TypeScript, I encountered some confusion regarding how it handles const variables. Let's consider a scenario where I define an interface for a number: interface MyNumber { value: number; } If I then create a constant MyNumbe ...

Executing Promises in a loop: TypeScript & Angular with IndexedDB

Currently, I am working on a data synchronization service where data is being retrieved from a web service and then stored in IndexedDB. In my TypeScript Angular Service, the code looks something like this: this.http .post(postUrl, postData) .suc ...

The Component TSX is reporting a Type error stating that the Property 'onChange' is not present in the type '{ key: string; value: Model; }' as required by Props

While running the following command: npm run build I encountered an error that needs resolution: /components/Lane.tsx:37:18 Type error: Property 'onChange' is missing in type '{ key: string; value: StepModel; }' but required in type &a ...

What is the best way to design a basic server component that has the ability to retrieve data in NextJS 13?

Exploring the world of NextJS, I am currently utilizing NextJS 13 with the new app directory instead of the traditional pages directory structure. Despite trying various methods to fetch data, none seem to be working as expected. The process should be stra ...

Tips for testing two conditions in Angular ngIf

I am facing a little issue trying to make this *ngIf statement work as expected. My goal is to display the div only if it is empty and the user viewing it is the owner. If the user is a guest and the div is empty, then it should not be shown. Here is my cu ...

What is the correct method for importing React in TypeScript (.tsx) to ensure optimal integration?

Within our TSX/React web application, we employ two distinct import styles for the react module: import * as React from "react"; as well as import React from "react" As far as I know, both methods function without any noticeable differences. Is there a ...

The input text in the Typeahead field does not reset even after calling this.setState

As I work on creating a watchlist with typeahead functionality to suggest options as the user types, I encountered an issue where the text box is not resetting after submission. I attempted the solution mentioned in this resource by calling this.setState( ...

When TypeScript error "ts(18004)" occurs, it is because of the object properties within all Prisma DB

I am currently in the process of verifying if a user's email already exists. To achieve this, I am utilizing Prisma Client's findUnique method. Below is the code snippet I have implemented: const userWithEmail = await prisma.user.findUnique({ ...

Best practice for incorporating types into a Redux-toolkit reducer

As someone who is relatively new to TypeScript, I have a specific goal in mind. I am looking to create an interface where: interface ActionType { fieldName: {any one key from the interface FormStateType listed below such as 'name', 'age&ap ...

Encountering an issue with core.js:15723 showing ERROR TypeError: Unable to access property 'toLowerCase' of an undefined value while using Angular 7

Below, I have provided my code which utilizes the lazyLoading Module. Please review my code and identify any errors. Currently facing TypeError: Cannot read property 'toLowerCase' of undefined in Angular 7. Model Class: export class C_data { ...

Developing an Injectable pipe with configuration in Nest.js

There are 2 ways to utilize pipes: @Param('foo', MyPipe) which generates MyPipe within the framework Alternatively, I could use @Param('foo', new MyPipe()). The first solution allows me to make use of @Injectable, which is necessary ...

Accessing React.FC in Another File with TypeScript - A Step-by-Step Guide

code - const Exne: React.FC <IProps> = ({x}) => { console.log('input', x); const [getx, assignx] = useState(x); console.log(getx, assignx); return(getx) }; Could you please provide instructions on how to acc ...

What is the reason for the return of undefined with getElementsByClassName() in puppeteer?

Currently, I am utilizing puppeteer to fetch certain elements from a webpage, specifically class items (divs). Although I understand that getElementsByClassName returns a list that needs to be looped through, the function always returns undefined for me, e ...

Converting a promise of type <any> to a promise of type <entity>: A beginner's guide

As a newcomer to TypeScript and NestJS, I am wondering how to convert Promise<any[]> to Promise<MyEntity[]> in order to successfully execute the following code: const usersfromTransaction = this.repoTransaction .createQueryBuilder() ...

Angular2- Retrieving configuration information during application launch

Implementing a method to load configuration data from an ASP.NET web API using HTTP at startup via APP_INITIALIZER. This approach was influenced by a discussion on Stack Overflow about loading configuration in Angular2 here and here. Snippet from app.modu ...

Issue with NgRx Testing: Callback in subscribe method fails to update during testing

I am currently working on testing a component that is responsible for editing shopping list items. Upon first loading, the component receives state values through store.select, which are: editedIngredient: null, editedIngredientIndex: -1 Based on these ...

Creating tests for subscription within the onInit() method in an Angular component

In my Spinner Component class, I have implemented a functionality to show/hide Progress Spinner using Angular Material. Below is the code snippet for the class: export class SpinnerComponent implements OnInit, OnDestroy { visible = true; private s ...

Angular 2 - Dependency Injection failing to function

I have created two different implementations for an interface and assigned them as providers for two separate components. However, I am encountering the following error: Error: Can't resolve all parameters for ChildComponent: (?). What could be the i ...

Finding a solution for duplicate date selections in NextJS using react-calendar

I am currently working on a calendar component using NextJS, typescript, tailwindcss, and the react-calendar library. I have encountered an issue with duplicate dates appearing in the calendar when selecting a date range. Although I have managed to handle ...

What is the best way to transfer data to the server in a loop without encountering synchronization issues?

I am working with an array of products in typescript (in angular) and my goal is to update their prices in the database using http calls. The way I currently insert them is as follows: array.foreach(element=>{ this.product.price=element; this.myS ...