diff --git a/src/components/User/Preferences/UserPreferenceProvider.test.tsx b/src/components/User/Preferences/UserPreferenceProvider.test.tsx new file mode 100644 index 000000000..bf065ce7b --- /dev/null +++ b/src/components/User/Preferences/UserPreferenceProvider.test.tsx @@ -0,0 +1,49 @@ +import { render } from '@testing-library/react'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { useLocale } from 'src/hooks/useLocale'; +import { GetUserQuery } from '../GetUser.generated'; +import { UserPreferenceProvider } from './UserPreferenceProvider'; + +const Consumer: React.FC = () => { + const locale = useLocale(); + + return

Locale: {locale}

; +}; + +describe('UserPreferenceProvider', () => { + it('always renders children', () => { + const { getByText } = render( + + Children + , + ); + + expect(getByText('Children')).toBeInTheDocument(); + }); + + it('provides locale', async () => { + const { getByText, findByText } = render( + + mocks={{ + GetUser: { + user: { + preferences: { + localeDisplay: 'es', + }, + }, + }, + }} + > + + + + , + ); + + // Initial default locale + expect(getByText('Locale: en-US')).toBeInTheDocument(); + + // Locale loaded from query + expect(await findByText('Locale: es')).toBeInTheDocument(); + }); +}); diff --git a/src/components/User/Preferences/UserPreferenceProvider.tsx b/src/components/User/Preferences/UserPreferenceProvider.tsx index e057e6578..21146c81a 100644 --- a/src/components/User/Preferences/UserPreferenceProvider.tsx +++ b/src/components/User/Preferences/UserPreferenceProvider.tsx @@ -1,5 +1,4 @@ import React, { createContext, useContext, useEffect, useState } from 'react'; -import { useSession } from 'next-auth/react'; import i18next from 'src/lib/i18n'; import { useGetUserQuery } from '../GetUser.generated'; @@ -19,20 +18,19 @@ interface Props { children?: React.ReactNode; } export const UserPreferenceProvider: React.FC = ({ children }) => { - const { data: session } = useSession(); - const { data: user, loading } = useGetUserQuery({ skip: !session }); + const { data } = useGetUserQuery(); const [locale, setLocale] = useState('en-US'); useEffect(() => { - if (user) { - i18next.changeLanguage(user.user.preferences?.language ?? 'en'); - setLocale(user.user.preferences?.locale ?? 'en-US'); + if (data) { + i18next.changeLanguage(data.user.preferences?.language ?? 'en'); + setLocale(data.user.preferences?.locale ?? 'en-US'); } - }, [user]); + }, [data]); return ( - {!loading && children} + {children} ); }; diff --git a/src/lib/client.ts b/src/lib/client.ts index e2b6b91e7..b189acfa4 100644 --- a/src/lib/client.ts +++ b/src/lib/client.ts @@ -54,8 +54,9 @@ const httpLink = new BatchHttpLink({ fetch, }); -const errorLink = onError(({ graphQLErrors, networkError }) => { - if (graphQLErrors) { +const clientErrorLink = onError(({ graphQLErrors, networkError }) => { + // Don't show sign out and display errors on the login page because the user won't be logged in + if (graphQLErrors && window.location.pathname !== '/login') { graphQLErrors.map(({ message, extensions }) => { if (extensions?.code === 'AUTHENTICATION_ERROR') { signOut({ redirect: true, callbackUrl: 'signOut' }).then(() => { @@ -101,7 +102,7 @@ if (process.browser && process.env.NODE_ENV === 'production') { } const client = new ApolloClient({ - link: errorLink.concat(httpLink), + link: clientErrorLink.concat(httpLink), cache, assumeImmutableResults: true, defaultOptions: { diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts index 2ce8a614e..b5656faf9 100644 --- a/src/lib/i18n.ts +++ b/src/lib/i18n.ts @@ -15,10 +15,10 @@ i18next useSuspense: false, }, detection: { - order: ['navigator', 'htmlTag'], + order: ['localStorage', 'navigator', 'htmlTag'], }, backend: { - loadPath: '../../locales/{{lng}}/translation.json', + loadPath: '/locales/{{lng}}/translation.json', }, });