Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: tests & react query cache keys #3540

Merged
merged 8 commits into from
Jun 15, 2023
Merged

Conversation

djabarovgeorge
Copy link
Contributor

@djabarovgeorge djabarovgeorge commented May 30, 2023

What change does this PR introduce?

Fix the test.
Add the query to the cache key on all the cases.

Why was this change needed?

At the moment INFINITE_NOTIFICATIONS_QUERY_KEY could get the query object in useFetchNotifications but in other places, it was missing, which caused issues.

Other information (Screenshots)

Comment on lines 110 to 111
const { storeQuery } = useNotifications();
const { updateAction } = useUpdateAction({ query: storeQuery });
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure is it is the best way to do so, but at the moment we need to pass the query to the cache key..

@LetItRock
Copy link
Contributor

@djabarovgeorge left you a dm in the Discord, let's not merge this and chat about the changes

@@ -157,7 +157,7 @@ jobs:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup-project
- uses: mansagroup/nrwl-nx-action@v3
if: ${{matrix.projectName == '@novu/application-generic' }}
if: ${{matrix.projectName == '@novu/application-generic' || matrix.projectName == '@novu/notification-center'}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when there are the changes in the notification-center package then run the tests pipeline: lint, build, test

Comment on lines +43 to +46
"@testing-library/react": "^11.1.0",
"@testing-library/dom": "^9.3.0",
"@testing-library/user-event": "^12.1.10",
"@testing-library/jest-dom": "^4.2.4",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RTL for the notification-center package... I've added a couple of the unit/integration tests

Comment on lines +68 to +73
const [sessionInfo, setSessionInfo] = useState({
isSessionInitialized: false,
applicationIdentifier,
subscriberId,
subscriberHash,
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created the state for the data that is needed to initialize the session...

@@ -81,9 +86,9 @@ export function NovuProvider({
(newSession: ISession) => {
applyToken({ apiService, token: newSession.token });
initializeSocket(newSession);
setSessionInitialized(true);
setSessionInfo((old) => ({ ...old, isSessionInitialized: true }));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the callback called when the session is initialized... setting this flag to true will result in fetching the org, unseen count, and notifications...

Comment on lines +125 to +135
useEffect(() => {
setSessionInfo((old) => ({
...old,
isSessionInitialized: false,
applicationIdentifier,
subscriberId,
subscriberHash,
}));
logout();
queryClient.refetchQueries([...SESSION_QUERY_KEY, applicationIdentifier, subscriberId, subscriberHash]);
}, [logout, subscriberId, applicationIdentifier, subscriberHash]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when the props subscriberId, applicationIdentifier, subscriberHash are changing, set the session to isSessionInitialized: false and then reinitialize the session

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that the reinitialize will be in onSuccessfulSession?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes


export const useFeedUnseenCount = (
{ query }: { query?: IStoreQuery },
options: UseQueryOptions<ICountData, Error, ICountData> = {}
) => {
const { apiService, isSessionInitialized } = useNovuContext();
const setQueryKey = useSetQueryKey();
const feedUnseenCountQueryKey = useFeedUnseenCountQueryKey();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created a few helper hooks that do return the query keys... the hooks are reused in a couple places


const PROMISE_TIMEOUT = 150;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why but increasing the timeout helps tests to pass :D

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how hard was figuring it out 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I knew that the tests are correct, so wasn't that hard :)

Comment on lines +23 to +25
<StoreProvider stores={stores}>
<NotificationsProviderInternal>{children}</NotificationsProviderInternal>
</StoreProvider>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basically, I've created the new StoreProvider that allows us to use the storeQuery state inside of any public hooks like useUnseenCountQueryKey... this way we don't require the hook users to pass it through props... it's an internal state info

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing reason to refactor :)

Copy link
Contributor Author

@djabarovgeorge djabarovgeorge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As always amazing work and amazing addition tests left a couple of questions regarding things I was not sure about. @LetItRock

},
[apiService, setSessionInitialized, initializeSocket]
[apiService, setSessionInfo, initializeSocket]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between adding here setSessionInfo instead of sessionInfo?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setSessionInfo is a state setter ;)

setSessionInitialized(false);
}, [removeToken, disconnectSocket, apiService]);
setSessionInfo((old) => ({ ...old, isSessionInitialized: false }));
}, [setSessionInfo, disconnectSocket, apiService]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removeToken is not needed anymore?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed because it's a util that never changes ;)

);

useEffect(() => disconnectSocket, [disconnectSocket]);

useEffect(() => {
setSessionInfo((old) => ({
...old,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need ...old,? won't it will be overridden by the following params, or did you add for future proof if we will add more params to setSessionInfo object?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it's always better to do it for the future changes, like this way I won't need to revisit every setSessionInfo call

Comment on lines +125 to +135
useEffect(() => {
setSessionInfo((old) => ({
...old,
isSessionInitialized: false,
applicationIdentifier,
subscriberId,
subscriberHash,
}));
logout();
queryClient.refetchQueries([...SESSION_QUERY_KEY, applicationIdentifier, subscriberId, subscriberHash]);
}, [logout, subscriberId, applicationIdentifier, subscriberHash]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that the reinitialize will be in onSuccessfulSession?


export const useFetchUserPreferencesQueryKey = () => {
const setQueryKey = useSetQueryKey();
const queryKey = useMemo(() => setQueryKey(USER_PREFERENCES_QUERY_KEY), [setQueryKey]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const queryKey = useMemo(() => setQueryKey(USER_PREFERENCES_QUERY_KEY), [setQueryKey]);
const queryKey = useMemo(() => setQueryKey([...USER_PREFERENCES_QUERY_KEY]), [setQueryKey]);


const PROMISE_TIMEOUT = 150;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how hard was figuring it out 😅

jest.clearAllMocks();
queryClient.clear();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏

Comment on lines +23 to +25
<StoreProvider stores={stores}>
<NotificationsProviderInternal>{children}</NotificationsProviderInternal>
</StoreProvider>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing reason to refactor :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤩

@LetItRock LetItRock force-pushed the fix-test-&-react-query-cache-keys branch from 60f2bf4 to 19bc37e Compare June 14, 2023 16:18
import { FEED_UNSEEN_COUNT_QUERY_KEY } from './queryKeys';
import { useSetQueryKey } from './useSetQueryKey';

export const useFeedUnseenCountQueryKey = (query?: IStoreQuery) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I am following up, in this case, we can not get the query inside this hook from the useStore hook?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this hook is used in the useFeedUnseenCount which is used for every feed tab, which passes it's storeQuery to the hook useFeedUnseenCount --> useFeedUnseenCountQueryKey

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Jun 14, 2023
@LetItRock LetItRock added this pull request to the merge queue Jun 15, 2023
Merged via the queue into next with commit e10d9af Jun 15, 2023
32 checks passed
@LetItRock LetItRock deleted the fix-test-&-react-query-cache-keys branch June 15, 2023 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation @novu/notification-center
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants