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

Create a fresh type by dynamically adjusting/filtering its attributes

Suppose we have a type defined as follows: type PromiseFunc = () => Promise<unknown>; type A = { key1: string; key2: string; key3: PromiseFunc; key4: string; key5: PromiseFunc; key6: SomeOtherType1[]; key7: SomeOtherType2[]; key8: ...

Sending error messages from server to client (leveraging Express and Backbone)

I'm struggling with passing server error messages to a client after thrashing around for a while. Here's what I have on the server side (simplified): export function get(req: express.ExpressServerRequest, res: express.ExpressServerResponse) { ...

Can the hexadecimal value from an input type color be extracted and used to populate form fields that will then be displayed in a table after submission?

Hello everyone, I'm new to this platform and seeking guidance on how to improve my post! I recently created a CRUD app using Angular. It consists of a basic form with 4 fields, a color picker using input type='color', and a submit button. U ...

Creating a type-safe dictionary for custom theme styles in Base Web

In my Next.js project, I decided to use the Base Web UI component framework. To customize the colors, I extended the Theme object following the guidelines provided at . Interestingly, the documentation refers to the theme type as ThemeT, but in practice, i ...

What could be causing my controller method in TypeScript to throw an error message unexpectedly?

Hey there. I'm diving into TypeScript and currently working on converting an Express backend to TS. Everything was smooth sailing until I encountered some unexpected issues. Specifically, the lines const hasVoted = poll.votedBy.some((voter): boolean = ...

When integrating the @azure/msal-angular import into the Angular application, the screen unexpectedly goes blank,

Starting a new Angular app and everything is rendering as expected at localhost:4200 until the following change is made: @NgModule({ declarations: [ AppComponent, HeaderBannerComponent, MainContentComponent, FooterContentinfoComponent ...

Angular interceptor allows the execution of code after the outgoing request has completed its process

In the process of creating a simple interceptor, I have encountered an issue. The interceptor is designed to check if an outgoing request is targeting a specific endpoint type, namely events and favoriteevents. While the interceptor works almost as intend ...

Optimizing your data layer in Angular2: A Guide to Best Practices

As a newcomer to Angular2, I am diving into hands-on learning. My current project involves building multiple views with parent components, child components, and database services. After successfully creating one view, I am now gearing up to implement other ...

Exploring the capabilities of indexing an array within an array in Nativescript

I am working with JSON data retrieved from an API and trying to figure out how to index an array inside an array using Nativescript. JS: cart [{ JS: "_id": "5d3988cd287bad2943686920", JS: "userid": "11E76234942299FCC13FFA163EDC2079", JS: "products": ...

Why is it necessary to use "new" with a Mongoose model in TypeScript?

I'm a bit confused here, but let me try to explain. When creating a new mongoose.model, I do it like this: let MyModel = moongoose.model<IMyModel>("myModel", MyModelSchema); What exactly is the difference between MyModel and let newModel = ne ...

Initial 16 characters of the deciphered message are nonsensical

In a specific scenario, I encounter data encryption from the API followed by decryption in TypeScript. I have utilized CryptoJS for decryption in TypeScript. Below is the decryption code snippet: decrypt(source: string, iv: string): string { var key = envi ...

The function of type 'PromiseConstructor' is not executable. Should 'new' be added? React TypeScript

.then causing issues in TypeScript. interface Props { type: string; user: object; setUserAuth: Promise<any>; } const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); if (type === "signup" ...

What is the best way to define an Array of Objects in a TypeORM Graphql Schema?

I'm currently working on a project involving 2 Postgres Models - users and posts. Each user can have multiple posts, creating a One to Many Relation between the two. My goal is to create a user profile function that allows me to access data of a singl ...

What is the best way to perform unit testing on a React ReduxSaga using Jest and Enzyme?

Recently delving into the world of react and redux, I am currently working on a project where I aim to integrate redux using reduxsauce and redux-saga. However, I am facing challenges in writing unit tests for these components. Here is how my folder struct ...

Is there a way for me to use TypeScript to infer the type of the value returned by Map.get()?

type FuncType<O extends Object> = (option: O) => boolean export const funcMap: Map<string, Function> = new Map() const func1: FuncType<Object> = () => true const func2: FuncType<{prop: number}> = ({ prop }) => prop !== 0 ...

What is the process for retrieving the chosen country code using material-ui-phone-number?

When incorporating user input for phone numbers, I have opted to utilize a package titled material-ui-phone-number. However, the challenge arises when attempting to retrieve the country code to verify if the user has included a 0 after the code. This infor ...

Tips for sending information back to the previous screen in React Native Navigation version 5

Recently, I upgraded to react native navigation version 5 and now I am facing an issue with sending data back to the previous screen when making a goBack() call. To navigate to the next view, I use: const onSelectCountry = item => { console.log(it ...

Organize Dates in React Table

I need help with sorting the Date column in my code. Currently, the sorting is being done alphabetically. Here is the JSON data and code snippet: JSON [ { "date": "Jun-2022" }, { "date": "Jul-2022" } ...

Dragging element position updated

After implementing a ngFor loop in my component to render multiple CdkDrag elements from an array, I encountered the issue of their positions updating when deleting one element and splicing the array. Is there a way to prevent this unwanted position update ...

Error: The specified type definition file for '__mocks__' could not be located

I encountered this error upon transitioning to yarn workspaces and turbo for my collection of nextjs projects. Although it appears to be associated with jest, none of my package.json files contain jest. I have a hunch that it might be linked to a sub-depen ...