emilkowalski / sonner

An opinionated toast component for React.
https://sonner.emilkowal.ski
MIT License
7.69k stars 237 forks source link

toast.promise does not work with Jest #435

Open ashkan117 opened 3 weeks ago

ashkan117 commented 3 weeks ago

Describe the feature / bug 📝:

I'm currently using sonner like the following

toast.promise(apiPromiseCall, {
  loading: 'Loading...',
  success: (data) => {
    return `${data.name} toast has been added`;
  },
  error: 'Error',
});

When testing I want to mock out this api call but when used in tandem with sonner this fails with the following error.

  TypeError: n is not a function

    >  98 |     toast.promise(
          |           ^
       99 |       mockedApiCall(...),
      100 |       {
      101 |         loading: 'Loading message,

A workaround I am using is to manually handle the states with the apiCall.then().catch() methods

Steps to reproduce the bug 🔁:

  1. Mock a promise function using jest.spyOn
  2. Trigger the event that calls the toast

I can try to add more details so let me know what else might be useful.

ARKN-SOL commented 3 weeks ago

I've stumbled upon this error in a different context. It's because sonner does an outdated check if a promise is a Promise.

This is the responsible line of code: src/state.ts#L124 A promise doesn't need to be an instance of Promise to be a promise (yeah ... I know). It only needs to have a .then() method. This Stackoverflow answer has a good summary. TL;DR: Sonner should use Promise.resolve(foo) instead of testing for type.