Git Product home page Git Product logo

Comments (8)

ItsMeJules avatar ItsMeJules commented on May 25, 2024 1

I think I found the issue. I had to wrap the waitForNextUpdate into an act just after rendering the component. As there's a state update on mount.

  it('should check notifications permission on mount', async () => {
    const { result, waitForNextUpdate } = renderHook(() => useNotificationsScreen());

    await act(async () => {
      await waitForNextUpdate();
    });

    expect(checkNotifications).toHaveBeenCalled();
    expect(result.current.notificationsEnabled).toBe(true);
  });

from react-native-permissions.

zoontek avatar zoontek commented on May 25, 2024

@ItsMeJules What mock are you using? Are you sure it actually trigger a re-render?

from react-native-permissions.

ItsMeJules avatar ItsMeJules commented on May 25, 2024

@zoontek All the mocked implementations are provided in the sample code. Or else I didn't understand your question. I am, when working on the feature, it was re-setting the state and re-rendering my components based on the return value of the custom hook.

from react-native-permissions.

zoontek avatar zoontek commented on May 25, 2024

@ItsMeJules Yes, I saw it after. It was poorly formatted and unreadable at first.
First, try to use the repository mock: https://github.com/zoontek/react-native-permissions/blob/master/mock.js

from react-native-permissions.

zoontek avatar zoontek commented on May 25, 2024

Reading your code, it's normal, no issue here.
You are using this as a mock:

jest.mock('react-native-permissions', () => ({
  checkNotifications: jest.fn(), // ⚠️ sync function, returns void (undefined)
}));

Except you should use this:

jest.mock('react-native-permissions', () => ({
  checkNotifications: jest.fn(async () => ({ status: "granted" })),
}));

Then this:

export const useNotificationsScreen = () => {
  const { navigate } = useNavigation<NavigationScreenProp<any, any>>();
  const [notificationsEnabled, setNotificationsEnabled] = useState(false);

  useEffect(() => {
    (async () => {
      const { status } = await checkNotifications(); // will return undefined, and crash as it cannot be destructured
      setNotificationsEnabled(status === 'granted'); // never fired
    })();
  }, []);
...
}

PS: There's a "Testing with Jest" part in the README that help to setup the mock: https://github.com/zoontek/react-native-permissions?tab=readme-ov-file#testing-with-jest

from react-native-permissions.

ItsMeJules avatar ItsMeJules commented on May 25, 2024

@zoontek I have it mocked in my jest-stup.ts file. As so :

jest.mock('react-native-permissions', () => require('react-native-permissions/mock'));

This is how I call my jest-setup.ts config file in my jest.config.js

  setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'],

I did read the testing with jest part in the README.md and found it a little scarce.

Applying your latest edited reply, I still have the same issue.

jest.mock('react-native-permissions', () => ({
  checkNotifications: jest.fn(async () => ({ status: 'granted' })),
}));

describe('useNotificationsScreen', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });
  it('should check notifications permission on mount', async () => {
    jest.mocked(checkNotifications).mockResolvedValue({
      status: 'granted',
      settings: {},
    } as NotificationsResponse); // <- I also tried removing this whole line and still timed out.

    const { result, waitForNextUpdate } = renderHook(() => useNotificationsScreen());

    await waitForNextUpdate().then(() => {
      console.log('waitForNextUpdate');
    });

    expect(checkNotifications).toHaveBeenCalled();
    expect(result.current.notificationsEnabled).toBe(true);
  });

from react-native-permissions.

zoontek avatar zoontek commented on May 25, 2024

@ItsMeJules Create a repository with this, I will check / fix it.

from react-native-permissions.

zoontek avatar zoontek commented on May 25, 2024

Good to know, I'm closing this.

from react-native-permissions.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.