diff --git a/package.json b/package.json index fcf2731..5d85b4c 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "build-watch": "webpack --watch", "prepare": "yarn run build", "test": "jest --watch", - "test:ci": "CI=true jest --watch=false --watchAll=false --coverage --ci --reporters=default" + "test:ci": "CI=true jest --watch=false --watchAll=false --coverage --ci --reporters=default --collectCoverageFrom=src/**/*" }, "keywords": [], "author": "", diff --git a/src/useFlags.test.ts b/src/useFlags.test.ts new file mode 100644 index 0000000..896cf0a --- /dev/null +++ b/src/useFlags.test.ts @@ -0,0 +1,59 @@ +import React from 'react'; +import { renderHook } from '@testing-library/react-hooks/native'; +import useFlags from './useFlags'; +import type { IToggle } from 'unleash-proxy-client'; +import { act } from 'react-dom/test-utils'; + +const toggles = [ + { + name: 'string', + enabled: true, + variant: { + name: 'string', + enabled: false, + }, + impressionData: false, + }, + { + name: 'string', + enabled: true, + variant: { + name: 'string', + enabled: false, + }, + impressionData: false, + }, +]; +test('should return flags', () => { + jest.spyOn(React, 'useContext').mockImplementation(() => ({ + client: { + getAllToggles: () => toggles, + on: jest.fn(), + }, + })); + + const { result } = renderHook(() => useFlags()); + expect(result.current).toEqual(toggles); +}); + +test('should update flags on update event', async () => { + const updatedToggles: IToggle[] = []; + const client = { + getAllToggles: jest.fn(), + on: jest.fn(), + off: jest.fn(), + }; + client.getAllToggles.mockReturnValue(toggles); + + jest.spyOn(React, 'useContext').mockImplementation(() => ({ + client, + })); + + const { result } = renderHook(() => useFlags()); + expect(result.current).toEqual(toggles); + client.getAllToggles.mockReturnValue(updatedToggles); + await act(async () => { + client.on.mock.calls[0][1](); + }); + expect(result.current).toEqual(updatedToggles); +}); diff --git a/src/useFlags.ts b/src/useFlags.ts index 9587a85..1630144 100644 --- a/src/useFlags.ts +++ b/src/useFlags.ts @@ -1,10 +1,23 @@ -import { useContext } from 'react'; +import { useContext, useEffect, useState } from 'react'; import FlagContext from './FlagContext'; const useFlags = () => { const { client } = useContext(FlagContext); + const [flags, setFlags] = useState(client.getAllToggles()); - return client.getAllToggles(); + useEffect(() => { + const onUpdate = () => { + setFlags(client.getAllToggles()); + }; + + client.on('update', onUpdate); + + return () => { + client.off('update', onUpdate); + }; + }, []); + + return flags; }; export default useFlags; diff --git a/src/useUnleashContext.test.ts b/src/useUnleashContext.test.ts index 89193cc..e0a7537 100644 --- a/src/useUnleashContext.test.ts +++ b/src/useUnleashContext.test.ts @@ -6,8 +6,8 @@ const useContextSpy = jest.spyOn(React, 'useContext'); const updateContextMock = jest.fn().mockName('updateContext'); test('should return the updateContext function from context', () => { - useContextSpy.mockReturnValue({ updateContext : updateContextMock}); + useContextSpy.mockReturnValue({ updateContext: updateContextMock }); const { result } = renderHook(() => useUnleashContext()); expect(result.current).toBe(updateContextMock); -}); \ No newline at end of file +});