diff --git a/front/src/AppWrapper.tsx b/front/src/AppWrapper.tsx
index 94076c583..d3784e6ab 100644
--- a/front/src/AppWrapper.tsx
+++ b/front/src/AppWrapper.tsx
@@ -3,6 +3,7 @@ import { BrowserRouter } from 'react-router-dom';
import { ApolloProvider } from './providers/apollo/ApolloProvider';
import { AppThemeProvider } from './providers/theme/AppThemeProvider';
+import { UserProvider } from './providers/user/UserProvider';
import { App } from './App';
export function AppWrapper() {
@@ -11,7 +12,9 @@ export function AppWrapper() {
-
+
+
+
diff --git a/front/src/modules/apollo/hooks/useApolloFactory.ts b/front/src/modules/apollo/hooks/useApolloFactory.ts
new file mode 100644
index 000000000..793145ec4
--- /dev/null
+++ b/front/src/modules/apollo/hooks/useApolloFactory.ts
@@ -0,0 +1,57 @@
+import { useEffect, useMemo, useRef } from 'react';
+import { InMemoryCache, NormalizedCacheObject } from '@apollo/client';
+import { useRecoilState } from 'recoil';
+
+import { tokenPairState } from '@/auth/states/tokenPairState';
+import { CommentThreadTarget } from '~/generated/graphql';
+
+import { ApolloFactory } from '../services/apollo.factory';
+
+export function useApolloFactory() {
+ const apolloRef = useRef | null>(null);
+
+ const [tokenPair, setTokenPair] = useRecoilState(tokenPairState);
+
+ const apolloClient = useMemo(() => {
+ apolloRef.current = new ApolloFactory({
+ uri: `${process.env.REACT_APP_API_URL}`,
+ cache: new InMemoryCache({
+ typePolicies: {
+ CommentThread: {
+ fields: {
+ commentThreadTargets: {
+ merge(
+ existing: CommentThreadTarget[] = [],
+ incoming: CommentThreadTarget[],
+ ) {
+ return [...incoming];
+ },
+ },
+ },
+ },
+ },
+ }),
+ defaultOptions: {
+ query: {
+ fetchPolicy: 'cache-first',
+ },
+ },
+ onTokenPairChange(tokenPair) {
+ setTokenPair(tokenPair);
+ },
+ onUnauthenticatedError() {
+ setTokenPair(null);
+ },
+ });
+
+ return apolloRef.current.getClient();
+ }, [setTokenPair]);
+
+ useEffect(() => {
+ if (apolloRef.current) {
+ apolloRef.current.updateTokenPair(tokenPair);
+ }
+ }, [tokenPair]);
+
+ return apolloClient;
+}
diff --git a/front/src/modules/apollo/hooks/useApolloMocked.ts b/front/src/modules/apollo/hooks/useApolloMocked.ts
new file mode 100644
index 000000000..91b706db4
--- /dev/null
+++ b/front/src/modules/apollo/hooks/useApolloMocked.ts
@@ -0,0 +1,44 @@
+import { useMemo } from 'react';
+import {
+ ApolloClient,
+ ApolloLink,
+ createHttpLink,
+ from,
+ InMemoryCache,
+} from '@apollo/client';
+
+import { mockedCompaniesData } from '~/testing/mock-data/companies';
+import { mockedUsersData } from '~/testing/mock-data/users';
+
+export default function useApolloMocked() {
+ const mockedClient = useMemo(() => {
+ const apiLink = createHttpLink({
+ uri: `${process.env.REACT_APP_API_URL}`,
+ });
+
+ const mockLink = new ApolloLink((operation, forward) => {
+ return forward(operation).map((response) => {
+ if (operation.operationName === 'GetCompanies') {
+ return { data: { companies: mockedCompaniesData } };
+ }
+ if (operation.operationName === 'GetCurrentUser') {
+ return { data: { users: [mockedUsersData[0]] } };
+ }
+
+ return response;
+ });
+ });
+
+ return new ApolloClient({
+ link: from([mockLink, apiLink]),
+ cache: new InMemoryCache(),
+ defaultOptions: {
+ query: {
+ fetchPolicy: 'cache-first',
+ },
+ },
+ });
+ }, []);
+
+ return mockedClient;
+}
diff --git a/front/src/providers/apollo/interfaces/apollo-manager.interface.ts b/front/src/modules/apollo/interfaces/apolloManager.interface.ts
similarity index 55%
rename from front/src/providers/apollo/interfaces/apollo-manager.interface.ts
rename to front/src/modules/apollo/interfaces/apolloManager.interface.ts
index f996688e8..8878734e2 100644
--- a/front/src/providers/apollo/interfaces/apollo-manager.interface.ts
+++ b/front/src/modules/apollo/interfaces/apolloManager.interface.ts
@@ -1,5 +1,8 @@
import { ApolloClient } from '@apollo/client';
+import { AuthTokenPair } from '~/generated/graphql';
+
export interface ApolloManager {
getClient(): ApolloClient;
+ updateTokenPair(tokenPair: AuthTokenPair | null): void;
}
diff --git a/front/src/providers/apollo/apollo.factory.ts b/front/src/modules/apollo/services/apollo.factory.ts
similarity index 85%
rename from front/src/providers/apollo/apollo.factory.ts
rename to front/src/modules/apollo/services/apollo.factory.ts
index 0dcb0358a..f89543b56 100644
--- a/front/src/providers/apollo/apollo.factory.ts
+++ b/front/src/modules/apollo/services/apollo.factory.ts
@@ -14,13 +14,12 @@ import { RetryLink } from '@apollo/client/link/retry';
import { Observable } from '@apollo/client/utilities';
import { renewToken } from '@/auth/services/AuthService';
-import { tokenService } from '@/auth/services/TokenService';
+import { AuthTokenPair } from '~/generated/graphql';
-import { assertNotNull } from '../../modules/utils/assert';
-import { promiseToObservable } from '../../modules/utils/promise-to-observable';
-
-import { ApolloManager } from './interfaces/apollo-manager.interface';
-import { loggerLink } from './logger';
+import { loggerLink } from '../../utils/apollo-logger';
+import { assertNotNull } from '../../utils/assert';
+import { promiseToObservable } from '../../utils/promise-to-observable';
+import { ApolloManager } from '../interfaces/apolloManager.interface';
const logger = loggerLink(() => 'Twenty');
@@ -35,17 +34,20 @@ const resolvePendingRequests = () => {
export interface Options extends ApolloClientOptions {
onError?: (err: GraphQLErrors | undefined) => void;
onNetworkError?: (err: Error | ServerParseError | ServerError) => void;
+ onTokenPairChange?: (tokenPair: AuthTokenPair) => void;
onUnauthenticatedError?: () => void;
}
export class ApolloFactory implements ApolloManager {
private client: ApolloClient;
+ private tokenPair: AuthTokenPair | null = null;
constructor(opts: Options) {
const {
uri,
onError: onErrorCb,
onNetworkError,
+ onTokenPairChange,
onUnauthenticatedError,
...options
} = opts;
@@ -56,13 +58,11 @@ export class ApolloFactory implements ApolloManager {
});
const authLink = setContext(async (_, { headers }) => {
- const credentials = tokenService.getTokenPair();
-
return {
headers: {
...headers,
- authorization: credentials?.accessToken
- ? `Bearer ${credentials?.accessToken}`
+ authorization: this.tokenPair?.accessToken.token
+ ? `Bearer ${this.tokenPair?.accessToken.token}`
: '',
},
};
@@ -93,8 +93,9 @@ export class ApolloFactory implements ApolloManager {
if (!isRefreshing) {
isRefreshing = true;
forward$ = promiseToObservable(
- renewToken(uri)
- .then(() => {
+ renewToken(uri, this.tokenPair)
+ .then((tokens) => {
+ onTokenPairChange?.(tokens);
resolvePendingRequests();
return true;
})
@@ -161,6 +162,10 @@ export class ApolloFactory implements ApolloManager {
});
}
+ updateTokenPair(tokenPair: AuthTokenPair | null) {
+ this.tokenPair = tokenPair;
+ }
+
getClient() {
return this.client;
}
diff --git a/front/src/modules/auth/hooks/useAuth.ts b/front/src/modules/auth/hooks/useAuth.ts
index 26fbb3f97..3584a0f07 100644
--- a/front/src/modules/auth/hooks/useAuth.ts
+++ b/front/src/modules/auth/hooks/useAuth.ts
@@ -3,11 +3,12 @@ import { useRecoilState } from 'recoil';
import { useChallengeMutation, useVerifyMutation } from '~/generated/graphql';
-import { tokenService } from '../services/TokenService';
import { currentUserState } from '../states/currentUserState';
import { isAuthenticatingState } from '../states/isAuthenticatingState';
+import { tokenPairState } from '../states/tokenPairState';
export function useAuth() {
+ const [, setTokenPair] = useRecoilState(tokenPairState);
const [, setCurrentUser] = useRecoilState(currentUserState);
const [, setIsAuthenticating] = useRecoilState(isAuthenticatingState);
@@ -50,14 +51,14 @@ export function useAuth() {
throw new Error('No verify result');
}
- tokenService.setTokenPair(verifyResult.data?.verify.tokens);
+ setTokenPair(verifyResult.data?.verify.tokens);
setIsAuthenticating(false);
setCurrentUser(verifyResult.data?.verify.user);
return verifyResult.data?.verify;
},
- [setCurrentUser, setIsAuthenticating, verify],
+ [setCurrentUser, setIsAuthenticating, setTokenPair, verify],
);
const handleLogin = useCallback(
@@ -70,8 +71,8 @@ export function useAuth() {
);
const handleLogout = useCallback(() => {
- tokenService.removeTokenPair();
- }, []);
+ setTokenPair(null);
+ }, [setTokenPair]);
return {
challenge: handleChallenge,
diff --git a/front/src/modules/auth/hooks/useFetchCurrentUser.ts b/front/src/modules/auth/hooks/useFetchCurrentUser.ts
new file mode 100644
index 000000000..e21997f5d
--- /dev/null
+++ b/front/src/modules/auth/hooks/useFetchCurrentUser.ts
@@ -0,0 +1,26 @@
+import { useEffect } from 'react';
+import jwt from 'jwt-decode';
+import { useRecoilState } from 'recoil';
+
+import { useGetCurrentUserQuery } from '~/generated/graphql';
+
+import { currentUserState } from '../states/currentUserState';
+import { tokenPairState } from '../states/tokenPairState';
+
+export function useFetchCurrentUser() {
+ const [, setCurrentUser] = useRecoilState(currentUserState);
+ const [tokenPair] = useRecoilState(tokenPairState);
+ const userId = tokenPair?.accessToken.token
+ ? jwt<{ sub: string }>(tokenPair.accessToken.token).sub
+ : null;
+ const { data } = useGetCurrentUserQuery({
+ variables: { uuid: userId },
+ });
+ const user = data?.users?.[0];
+
+ useEffect(() => {
+ if (user) {
+ setCurrentUser(user);
+ }
+ }, [user, setCurrentUser]);
+}
diff --git a/front/src/modules/auth/hooks/useIsLogged.ts b/front/src/modules/auth/hooks/useIsLogged.ts
index 16b05eb51..49bb0129c 100644
--- a/front/src/modules/auth/hooks/useIsLogged.ts
+++ b/front/src/modules/auth/hooks/useIsLogged.ts
@@ -1,21 +1,9 @@
-import { useEffect, useState } from 'react';
+import { useRecoilState } from 'recoil';
-import { cookieStorage } from '@/utils/cookie-storage';
+import { tokenPairState } from '../states/tokenPairState';
export function useIsLogged(): boolean {
- const [value, setValue] = useState(
- cookieStorage.getItem('accessToken'),
- );
+ const [tokenPair] = useRecoilState(tokenPairState);
- useEffect(() => {
- const updateValue = (newValue: string | undefined) => setValue(newValue);
-
- cookieStorage.addEventListener('accessToken', updateValue);
-
- return () => {
- cookieStorage.removeEventListener('accessToken', updateValue);
- };
- }, []);
-
- return !!value;
+ return !!tokenPair;
}
diff --git a/front/src/modules/auth/services/AuthService.ts b/front/src/modules/auth/services/AuthService.ts
index 3d5bb9c4a..af32226a0 100644
--- a/front/src/modules/auth/services/AuthService.ts
+++ b/front/src/modules/auth/services/AuthService.ts
@@ -5,17 +5,14 @@ import {
InMemoryCache,
UriFunction,
} from '@apollo/client';
-import jwt from 'jwt-decode';
-import { cookieStorage } from '@/utils/cookie-storage';
+import { loggerLink } from '@/utils/apollo-logger';
import {
+ AuthTokenPair,
RenewTokenDocument,
RenewTokenMutation,
RenewTokenMutationVariables,
} from '~/generated/graphql';
-import { loggerLink } from '~/providers/apollo/logger';
-
-import { tokenService } from './TokenService';
const logger = loggerLink(() => 'Twenty-Refresh');
@@ -60,29 +57,15 @@ const renewTokenMutation = async (
* @param uri string | UriFunction | undefined
* @returns TokenPair
*/
-export const renewToken = async (uri: string | UriFunction | undefined) => {
- const tokenPair = tokenService.getTokenPair();
-
+export const renewToken = async (
+ uri: string | UriFunction | undefined,
+ tokenPair: AuthTokenPair | undefined | null,
+) => {
if (!tokenPair) {
throw new Error('Refresh token is not defined');
}
- const data = await renewTokenMutation(uri, tokenPair.refreshToken);
+ const data = await renewTokenMutation(uri, tokenPair.refreshToken.token);
- tokenService.setTokenPair(data.renewToken.tokens);
-
- return data.renewToken;
-};
-
-export const getUserIdFromToken: () => string | null = () => {
- const accessToken = cookieStorage.getItem('accessToken');
- if (!accessToken) {
- return null;
- }
-
- try {
- return jwt<{ sub: string }>(accessToken).sub;
- } catch (error) {
- return null;
- }
+ return data.renewToken.tokens;
};
diff --git a/front/src/modules/auth/services/TokenService.ts b/front/src/modules/auth/services/TokenService.ts
deleted file mode 100644
index 9834ec88e..000000000
--- a/front/src/modules/auth/services/TokenService.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { cookieStorage } from '@/utils/cookie-storage';
-import { AuthTokenPair } from '~/generated/graphql';
-
-export class TokenService {
- getTokenPair() {
- const accessToken = cookieStorage.getItem('accessToken');
- const refreshToken = cookieStorage.getItem('refreshToken');
-
- if (!accessToken || !refreshToken) {
- return null;
- }
-
- return {
- accessToken,
- refreshToken,
- };
- }
-
- setTokenPair(tokens: AuthTokenPair) {
- cookieStorage.setItem('accessToken', tokens.accessToken.token, {
- secure: true,
- });
- cookieStorage.setItem('refreshToken', tokens.refreshToken.token, {
- secure: true,
- });
- }
-
- removeTokenPair() {
- cookieStorage.removeItem('accessToken');
- cookieStorage.removeItem('refreshToken');
- }
-}
-
-export const tokenService = new TokenService();
diff --git a/front/src/modules/auth/services/__tests__/AuthService.test.tsx b/front/src/modules/auth/services/__tests__/AuthService.test.tsx
deleted file mode 100644
index 1225cf744..000000000
--- a/front/src/modules/auth/services/__tests__/AuthService.test.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { cookieStorage } from '@/utils/cookie-storage';
-
-import { getUserIdFromToken } from '../AuthService';
-
-it('getUserIdFromToken returns null when the token is not present', async () => {
- const userId = getUserIdFromToken();
- expect(userId).toBeNull();
-});
-
-it('getUserIdFromToken returns null when the token is not valid', async () => {
- cookieStorage.setItem('accessToken', 'xxx-invalid-access');
- const userId = getUserIdFromToken();
- expect(userId).toBeNull();
-});
-
-it('getUserIdFromToken returns the right userId when the token is valid', async () => {
- cookieStorage.setItem(
- 'accessToken',
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzNzRmZTNhNS1kZjFlLTQxMTktYWZlMC0yYTYyYTJiYTQ4MWUiLCJ3b3Jrc3BhY2VJZCI6InR3ZW50eS03ZWQ5ZDIxMi0xYzI1LTRkMDItYmYyNS02YWVjY2Y3ZWE0MTkiLCJpYXQiOjE2ODY5OTI0ODgsImV4cCI6MTY4Njk5Mjc4OH0.IO7U5G14IrrQriw3JjrKVxmZgd6XKL6yUIwuNe_R55E',
- );
- const userId = getUserIdFromToken();
- expect(userId).toBe('374fe3a5-df1e-4119-afe0-2a62a2ba481e');
-});
-
-afterEach(() => {
- cookieStorage.clear();
-});
diff --git a/front/src/modules/auth/services/__tests__/TokenService.test.tsx b/front/src/modules/auth/services/__tests__/TokenService.test.tsx
deleted file mode 100644
index 47c3496cb..000000000
--- a/front/src/modules/auth/services/__tests__/TokenService.test.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import Cookies from 'js-cookie';
-
-import { tokenService } from '../TokenService';
-
-const tokenPair = {
- accessToken: {
- token:
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzNzRmZTNhNS1kZjFlLTQxMTktYWZlMC0yYTYyYTJiYTQ4MWUiLCJ3b3Jrc3BhY2VJZCI6InR3ZW50eS03ZWQ5ZDIxMi0xYzI1LTRkMDItYmYyNS02YWVjY2Y3ZWE0MTkiLCJpYXQiOjE2ODY5OTMxODIsImV4cCI6MTY4Njk5MzQ4Mn0.F_FD6nJ5fssR_47v2XFhtzqjr-wrEQpqaWVq8iIlLJw',
- expiresAt: '2023-06-17T09:18:02.942Z',
- },
- refreshToken: {
- token:
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzNzRmZTNhNS1kZjFlLTQxMTktYWZlMC0yYTYyYTJiYTQ4MWUiLCJpYXQiOjE2ODY5OTMxODIsImV4cCI6OTQ2Mjk5MzE4MiwianRpIjoiNzBmMWNhMjctOTYxYi00ZGZlLWEwOTUtMTY2OWEwOGViMTVjIn0.xEdX9dOGzrPHrPsivQYB9ipYGJH-mJ7GSIVPacmIzfY',
- expiresAt: '2023-09-15T09:13:02.952Z',
- },
-};
-
-it('getTokenPair is fullfiled when token is present', () => {
- tokenService.setTokenPair(tokenPair);
-
- // Otherwise the test will fail because Cookies-js seems to be async but functions aren't promises
- setTimeout(() => {
- expect(tokenService.getTokenPair()).toBe({
- accessToken: tokenPair.accessToken,
- refreshToken: tokenPair.refreshToken,
- });
- }, 10);
-});
-
-it('getTokenPair is null when token is not set', () => {
- expect(tokenService.getTokenPair()).toBeNull();
-});
-
-it('removeTokenPair clean cookie storage', () => {
- tokenService.setTokenPair(tokenPair);
- tokenService.removeTokenPair();
- expect(tokenService.getTokenPair()).toBeNull();
-});
-
-afterEach(() => {
- Cookies.remove('accessToken');
- Cookies.remove('refreshToken');
-});
diff --git a/front/src/modules/auth/states/tokenPairState.ts b/front/src/modules/auth/states/tokenPairState.ts
new file mode 100644
index 000000000..24bc61a91
--- /dev/null
+++ b/front/src/modules/auth/states/tokenPairState.ts
@@ -0,0 +1,29 @@
+import { atom, AtomEffect } from 'recoil';
+
+import { cookieStorage } from '@/utils/cookie-storage';
+import { AuthTokenPair } from '~/generated/graphql';
+
+const cookieStorageEffect =
+ (key: string): AtomEffect =>
+ ({ setSelf, onSet }) => {
+ const savedValue = cookieStorage.getItem(key);
+ if (savedValue != null) {
+ setSelf(JSON.parse(savedValue));
+ }
+
+ onSet((newValue, _, isReset) => {
+ if (!newValue) {
+ cookieStorage.removeItem(key);
+ return;
+ }
+ isReset
+ ? cookieStorage.removeItem(key)
+ : cookieStorage.setItem(key, JSON.stringify(newValue));
+ });
+ };
+
+export const tokenPairState = atom({
+ key: 'tokenPairState',
+ default: null,
+ effects: [cookieStorageEffect('tokenPair')],
+});
diff --git a/front/src/providers/apollo/logger/format-title.ts b/front/src/modules/utils/apollo-logger/format-title.ts
similarity index 100%
rename from front/src/providers/apollo/logger/format-title.ts
rename to front/src/modules/utils/apollo-logger/format-title.ts
diff --git a/front/src/providers/apollo/logger/index.ts b/front/src/modules/utils/apollo-logger/index.ts
similarity index 100%
rename from front/src/providers/apollo/logger/index.ts
rename to front/src/modules/utils/apollo-logger/index.ts
diff --git a/front/src/providers/apollo/logger/operation-type.ts b/front/src/modules/utils/apollo-logger/operation-type.ts
similarity index 100%
rename from front/src/providers/apollo/logger/operation-type.ts
rename to front/src/modules/utils/apollo-logger/operation-type.ts
diff --git a/front/src/modules/utils/cookie-storage.ts b/front/src/modules/utils/cookie-storage.ts
index ab98fa162..0fde168a0 100644
--- a/front/src/modules/utils/cookie-storage.ts
+++ b/front/src/modules/utils/cookie-storage.ts
@@ -1,12 +1,6 @@
import Cookies, { CookieAttributes } from 'js-cookie';
-type Listener = (
- newValue: string | undefined,
- oldValue: string | undefined,
-) => void;
-
class CookieStorage {
- private listeners: Record = {};
private keys: Set = new Set();
getItem(key: string): string | undefined {
@@ -14,49 +8,18 @@ class CookieStorage {
}
setItem(key: string, value: string, attributes?: CookieAttributes): void {
- const oldValue = this.getItem(key);
-
this.keys.add(key);
Cookies.set(key, value, attributes);
- this.dispatch(key, value, oldValue);
}
removeItem(key: string): void {
- const oldValue = this.getItem(key);
-
this.keys.delete(key);
Cookies.remove(key);
- this.dispatch(key, undefined, oldValue);
}
clear(): void {
this.keys.forEach((key) => this.removeItem(key));
}
-
- private dispatch(
- key: string,
- newValue: string | undefined,
- oldValue: string | undefined,
- ): void {
- if (this.listeners[key]) {
- this.listeners[key].forEach((callback) => callback(newValue, oldValue));
- }
- }
-
- addEventListener(key: string, callback: Listener): void {
- if (!this.listeners[key]) {
- this.listeners[key] = [];
- }
- this.listeners[key].push(callback);
- }
-
- removeEventListener(key: string, callback: Listener): void {
- if (this.listeners[key]) {
- this.listeners[key] = this.listeners[key].filter(
- (listener) => listener !== callback,
- );
- }
- }
}
export const cookieStorage = new CookieStorage();
diff --git a/front/src/providers/apollo/ApolloProvider.tsx b/front/src/providers/apollo/ApolloProvider.tsx
index baceed4b8..8c72dca7b 100644
--- a/front/src/providers/apollo/ApolloProvider.tsx
+++ b/front/src/providers/apollo/ApolloProvider.tsx
@@ -1,18 +1,20 @@
import { ApolloProvider as ApolloProviderBase } from '@apollo/client';
import { useRecoilState } from 'recoil';
+import { useApolloFactory } from '@/apollo/hooks/useApolloFactory';
+import useApolloMocked from '@/apollo/hooks/useApolloMocked';
import { isMockModeState } from '@/auth/states/isMockModeState';
-import { apolloClient } from './apollo-client';
-import { mockClient } from './mock-client';
-
export const ApolloProvider: React.FC = ({
children,
}) => {
+ const apolloClient = useApolloFactory();
+ const mockedClient = useApolloMocked();
+
const [isMockMode] = useRecoilState(isMockModeState);
return (
-
+
{children}
);
diff --git a/front/src/providers/apollo/apollo-client.ts b/front/src/providers/apollo/apollo-client.ts
deleted file mode 100644
index ec415b977..000000000
--- a/front/src/providers/apollo/apollo-client.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { InMemoryCache } from '@apollo/client';
-
-import { tokenService } from '@/auth/services/TokenService';
-import { CommentThreadTarget } from '~/generated/graphql';
-
-import { ApolloFactory } from './apollo.factory';
-
-const apollo = new ApolloFactory({
- uri: `${process.env.REACT_APP_API_URL}`,
- cache: new InMemoryCache({
- typePolicies: {
- CommentThread: {
- fields: {
- commentThreadTargets: {
- merge(
- existing: CommentThreadTarget[] = [],
- incoming: CommentThreadTarget[],
- ) {
- return [...incoming];
- },
- },
- },
- },
- },
- }),
- defaultOptions: {
- query: {
- fetchPolicy: 'cache-first',
- },
- },
- onUnauthenticatedError() {
- tokenService.removeTokenPair();
- },
-});
-
-export const apolloClient = apollo.getClient();
diff --git a/front/src/providers/apollo/mock-client.ts b/front/src/providers/apollo/mock-client.ts
deleted file mode 100644
index adbf3756c..000000000
--- a/front/src/providers/apollo/mock-client.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import {
- ApolloClient,
- ApolloLink,
- createHttpLink,
- from,
- InMemoryCache,
-} from '@apollo/client';
-
-import { mockedCompaniesData } from '~/testing/mock-data/companies';
-import { mockedUsersData } from '~/testing/mock-data/users';
-
-const apiLink = createHttpLink({
- uri: `${process.env.REACT_APP_API_URL}`,
-});
-
-const mockLink = new ApolloLink((operation, forward) => {
- return forward(operation).map((response) => {
- if (operation.operationName === 'GetCompanies') {
- return { data: { companies: mockedCompaniesData } };
- }
- if (operation.operationName === 'Verify') {
- return { data: { user: [mockedUsersData[0]], tokens: {} } };
- }
- return response;
- });
-});
-
-export const mockClient = new ApolloClient({
- link: from([mockLink, apiLink]),
- cache: new InMemoryCache(),
- defaultOptions: {
- query: {
- fetchPolicy: 'cache-first',
- },
- },
-});
diff --git a/front/src/providers/user/UserProvider.tsx b/front/src/providers/user/UserProvider.tsx
new file mode 100644
index 000000000..88faf52f4
--- /dev/null
+++ b/front/src/providers/user/UserProvider.tsx
@@ -0,0 +1,9 @@
+import { useFetchCurrentUser } from '@/auth/hooks/useFetchCurrentUser';
+
+export const UserProvider: React.FC = ({
+ children,
+}) => {
+ useFetchCurrentUser();
+
+ return <>{children}>;
+};
diff --git a/front/src/testing/graphqlMocks.ts b/front/src/testing/graphqlMocks.ts
index e31ad2ace..476f55283 100644
--- a/front/src/testing/graphqlMocks.ts
+++ b/front/src/testing/graphqlMocks.ts
@@ -11,7 +11,6 @@ import { GET_CURRENT_USER } from '@/users/services';
import {
GetCompaniesQuery,
GetPeopleQuery,
- GetUsersQuery,
SearchCompanyQuery,
SearchUserQuery,
} from '~/generated/graphql';
@@ -73,19 +72,9 @@ export const graphqlMocks = [
);
}),
graphql.query(getOperationName(GET_CURRENT_USER) ?? '', (req, res, ctx) => {
- const customWhere = {
- ...req.variables.where,
- id: {
- equals: req.variables.uuid,
- },
- };
-
- const returnedMockedData = filterAndSortData<
- GetUsersQuery['findManyUser'][0]
- >(mockedUsersData, customWhere, req.variables.orderBy, req.variables.limit);
return res(
ctx.data({
- users: returnedMockedData,
+ users: [mockedUsersData[0]],
}),
);
}),
diff --git a/front/src/testing/renderWrappers.tsx b/front/src/testing/renderWrappers.tsx
index d95a19d81..c41f9e977 100644
--- a/front/src/testing/renderWrappers.tsx
+++ b/front/src/testing/renderWrappers.tsx
@@ -4,6 +4,7 @@ import { ApolloProvider } from '@apollo/client';
import { RecoilRoot } from 'recoil';
import { DefaultLayout } from '@/ui/layout/DefaultLayout';
+import { UserProvider } from '~/providers/user/UserProvider';
import { ComponentStorybookLayout } from './ComponentStorybookLayout';
import { FullHeightStorybookLayout } from './FullHeightStorybookLayout';
@@ -17,11 +18,13 @@ export function getRenderWrapperForPage(
return (
-
-
- {children}
-
-
+
+
+
+ {children}
+
+
+
);