diff --git a/packages/twenty-front/src/modules/companies/hooks/__tests__/useSpreadsheetCompanyImport.test.tsx b/packages/twenty-front/src/modules/companies/hooks/__tests__/useSpreadsheetCompanyImport.test.tsx
new file mode 100644
index 000000000..57ac3d8c3
--- /dev/null
+++ b/packages/twenty-front/src/modules/companies/hooks/__tests__/useSpreadsheetCompanyImport.test.tsx
@@ -0,0 +1,137 @@
+import { ReactNode } from 'react';
+import { gql } from '@apollo/client';
+import { MockedProvider } from '@apollo/client/testing';
+import { act, renderHook, waitFor } from '@testing-library/react';
+import { RecoilRoot, useRecoilValue } from 'recoil';
+
+import { spreadsheetImportState } from '@/spreadsheet-import/states/spreadsheetImportState';
+import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
+
+import { useSpreadsheetCompanyImport } from '../useSpreadsheetCompanyImport';
+
+const companyId = 'cb2e9f4b-20c3-4759-9315-4ffeecfaf71a';
+
+jest.mock('uuid', () => ({
+ v4: jest.fn(() => companyId),
+}));
+
+jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
+ useMapFieldMetadataToGraphQLQuery: () => () => '\n',
+}));
+
+const companyMocks = [
+ {
+ request: {
+ query: gql`
+ mutation CreateCompanies($data: [CompanyCreateInput!]!) {
+ createCompanies(data: $data) {
+ id
+ }
+ }
+ `,
+ variables: {
+ data: [
+ {
+ name: 'Example Company',
+ domainName: 'example.com',
+ idealCustomerProfile: true,
+ address: undefined,
+ employees: undefined,
+ id: companyId,
+ },
+ ],
+ },
+ },
+ result: jest.fn(() => ({
+ data: {
+ createCompanies: [
+ {
+ id: companyId,
+ },
+ ],
+ },
+ })),
+ },
+];
+
+const fakeCsv = () => {
+ const csvContent = 'name\nExample Company';
+ const blob = new Blob([csvContent], { type: 'text/csv' });
+ return new File([blob], 'fakeData.csv', { type: 'text/csv' });
+};
+
+const Wrapper = ({ children }: { children: ReactNode }) => (
+
+
+
+ {children}
+
+
+
+);
+
+describe('useSpreadsheetCompanyImport', () => {
+ it('should work as expected', async () => {
+ const { result } = renderHook(
+ () => {
+ const spreadsheetImport = useRecoilValue(spreadsheetImportState);
+ const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport();
+ return { openCompanySpreadsheetImport, spreadsheetImport };
+ },
+ {
+ wrapper: Wrapper,
+ },
+ );
+
+ const { spreadsheetImport, openCompanySpreadsheetImport } = result.current;
+
+ expect(spreadsheetImport.isOpen).toBe(false);
+ expect(spreadsheetImport.options).toBeNull();
+
+ await act(async () => {
+ openCompanySpreadsheetImport();
+ });
+
+ const { spreadsheetImport: updatedImport } = result.current;
+
+ expect(updatedImport.isOpen).toBe(true);
+ expect(updatedImport.options).toHaveProperty('onSubmit');
+ expect(updatedImport.options?.onSubmit).toBeInstanceOf(Function);
+ expect(updatedImport.options).toHaveProperty('fields');
+ expect(Array.isArray(updatedImport.options?.fields)).toBe(true);
+
+ act(() => {
+ updatedImport.options?.onSubmit(
+ {
+ validData: [
+ {
+ id: companyId,
+ name: 'Example Company',
+ domainName: 'example.com',
+ idealCustomerProfile: true,
+ address: undefined,
+ employees: undefined,
+ },
+ ],
+ invalidData: [],
+ all: [
+ {
+ id: companyId,
+ name: 'Example Company',
+ domainName: 'example.com',
+ __index: 'cbc3985f-dde9-46d1-bae2-c124141700ac',
+ idealCustomerProfile: true,
+ address: undefined,
+ employees: undefined,
+ },
+ ],
+ },
+ fakeCsv(),
+ );
+ });
+
+ await waitFor(() => {
+ expect(companyMocks[0].result).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/packages/twenty-front/src/modules/favorites/hooks/__mocks__/useFavorites.ts b/packages/twenty-front/src/modules/favorites/hooks/__mocks__/useFavorites.ts
new file mode 100644
index 000000000..f45c0c7ae
--- /dev/null
+++ b/packages/twenty-front/src/modules/favorites/hooks/__mocks__/useFavorites.ts
@@ -0,0 +1,166 @@
+import { gql } from '@apollo/client';
+
+import { AvatarType } from '@/users/components/Avatar';
+import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
+
+export const mockId = '8f3b2121-f194-4ba4-9fbf-2d5a37126806';
+export const favoriteId = 'f088c8c9-05d2-4276-b065-b863cc7d0b33';
+export const mockRecord = { id: 'f088c8c9-05d2-4276-b065-b863cc7d0b33' };
+
+export const initialFavorites = [
+ {
+ id: '1',
+ position: 0,
+ key: mockId,
+ labelIdentifier: 'favoriteLabel',
+ avatarUrl: 'example.com',
+ avatarType: 'squared' as AvatarType,
+ link: 'example.com',
+ recordId: '1',
+ person: { id: '1', name: 'John Doe' },
+ company: { id: '2', name: 'ABC Corp' },
+ },
+ {
+ id: '2',
+ position: 1,
+ key: mockId,
+ labelIdentifier: 'favoriteLabel',
+ avatarUrl: 'example.com',
+ avatarType: 'squared' as AvatarType,
+ link: 'example.com',
+ recordId: '1',
+ person: { id: '3', name: 'Jane Doe' },
+ company: { id: '4', name: 'Company Test' },
+ },
+ {
+ id: '3',
+ position: 2,
+ key: mockId,
+ labelIdentifier: 'favoriteLabel',
+ avatarUrl: 'example.com',
+ avatarType: 'squared' as AvatarType,
+ link: 'example.com',
+ recordId: '1',
+ },
+];
+
+export const sortedFavorites = [
+ {
+ id: '1',
+ recordId: '1',
+ position: 0,
+ avatarType: 'rounded',
+ avatarUrl: '',
+ labelIdentifier: ' ',
+ link: '/object/person/1',
+ },
+ {
+ id: '2',
+ recordId: '3',
+ position: 1,
+ avatarType: 'rounded',
+ avatarUrl: '',
+ labelIdentifier: ' ',
+ link: '/object/person/3',
+ },
+ {
+ id: '3',
+ position: 2,
+ key: '8f3b2121-f194-4ba4-9fbf-2d5a37126806',
+ labelIdentifier: 'favoriteLabel',
+ avatarUrl: 'example.com',
+ avatarType: 'squared',
+ link: 'example.com',
+ recordId: '1',
+ },
+];
+
+export const mocks = [
+ {
+ request: {
+ query: gql`
+ mutation CreateOneFavorite($input: FavoriteCreateInput!) {
+ createFavorite(data: $input) {
+ id
+ }
+ }
+ `,
+ variables: {
+ input: {
+ id: mockId,
+ favoritesId: favoriteId,
+ favorites: { id: favoriteId },
+ position: 4,
+ workspaceMemberId: '1',
+ },
+ },
+ },
+ result: jest.fn(() => ({
+ data: {
+ createFavorite: {
+ id: favoriteId,
+ },
+ },
+ })),
+ },
+ {
+ request: {
+ query: gql`
+ mutation DeleteOneFavorite($idToDelete: ID!) {
+ deleteFavorite(id: $idToDelete) {
+ id
+ }
+ }
+ `,
+ variables: { idToDelete: favoriteId },
+ },
+ result: jest.fn(() => ({
+ data: {
+ deleteFavorite: {
+ id: favoriteId,
+ },
+ },
+ })),
+ },
+ {
+ request: {
+ query: gql`
+ mutation UpdateOneFavorite(
+ $idToUpdate: ID!
+ $input: FavoriteUpdateInput!
+ ) {
+ updateFavorite(id: $idToUpdate, data: $input) {
+ id
+ }
+ }
+ `,
+ variables: {
+ idToUpdate: '1',
+ input: {
+ position: 2,
+ },
+ },
+ },
+ result: jest.fn(() => ({
+ data: {
+ updateFavorite: {
+ id: favoriteId,
+ },
+ },
+ })),
+ },
+];
+
+export const mockWorkspaceMember = {
+ id: '1',
+ name: {
+ firstName: 'First',
+ lastName: 'Last',
+ },
+ avatarUrl: '',
+ locale: 'en-US',
+ colorScheme: 'Dark' as ColorScheme,
+ createdAt: '',
+ updatedAt: '',
+ userId: '1',
+};
diff --git a/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx
new file mode 100644
index 000000000..0b0ce2b4f
--- /dev/null
+++ b/packages/twenty-front/src/modules/favorites/hooks/__tests__/useFavorites.test.tsx
@@ -0,0 +1,162 @@
+import { ReactNode } from 'react';
+import { MockedProvider } from '@apollo/client/testing';
+import { DropResult, ResponderProvided } from '@hello-pangea/dnd';
+import { act, renderHook, waitFor } from '@testing-library/react';
+import { RecoilRoot, useSetRecoilState } from 'recoil';
+
+import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
+import { useFavorites } from '@/favorites/hooks/useFavorites';
+import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
+import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
+import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
+
+import {
+ favoriteId,
+ initialFavorites,
+ mockId,
+ mockRecord,
+ mocks,
+ mockWorkspaceMember,
+ sortedFavorites,
+} from '../__mocks__/useFavorites';
+
+jest.mock('uuid', () => ({
+ v4: jest.fn(() => mockId),
+}));
+
+jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
+ useMapFieldMetadataToGraphQLQuery: () => () => '\n',
+}));
+
+jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
+ useFindManyRecords: () => ({ records: initialFavorites }),
+}));
+
+const mockObjectMetadataItems = getObjectMetadataItemsMock();
+
+const Wrapper = ({ children }: { children: ReactNode }) => (
+
+
+
+ {children}
+
+
+
+);
+
+describe('useFavorites', () => {
+ it('should fetch favorites successfully', async () => {
+ const { result } = renderHook(
+ () => {
+ const setCurrentWorkspaceMember = useSetRecoilState(
+ currentWorkspaceMemberState,
+ );
+ setCurrentWorkspaceMember(mockWorkspaceMember);
+
+ const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
+ setMetadataItems(mockObjectMetadataItems);
+
+ return useFavorites();
+ },
+ {
+ wrapper: Wrapper,
+ },
+ );
+
+ expect(result.current.favorites).toEqual(sortedFavorites);
+ });
+
+ it('should createOneFavorite successfully', async () => {
+ const { result } = renderHook(
+ () => {
+ const setCurrentWorkspaceMember = useSetRecoilState(
+ currentWorkspaceMemberState,
+ );
+ setCurrentWorkspaceMember(mockWorkspaceMember);
+
+ const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
+ setMetadataItems(mockObjectMetadataItems);
+
+ return useFavorites();
+ },
+ {
+ wrapper: Wrapper,
+ },
+ );
+
+ result.current.createFavorite(mockRecord, 'favorites');
+
+ await waitFor(() => {
+ expect(mocks[0].result).toHaveBeenCalled();
+ });
+ });
+
+ it('should deleteOneRecord successfully', async () => {
+ const { result } = renderHook(
+ () => {
+ const setCurrentWorkspaceMember = useSetRecoilState(
+ currentWorkspaceMemberState,
+ );
+ setCurrentWorkspaceMember(mockWorkspaceMember);
+
+ const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
+ setMetadataItems(mockObjectMetadataItems);
+
+ return useFavorites();
+ },
+ {
+ wrapper: Wrapper,
+ },
+ );
+
+ result.current.deleteFavorite(favoriteId);
+
+ await waitFor(() => {
+ expect(mocks[1].result).toHaveBeenCalled();
+ });
+ });
+
+ it('should handle reordering favorites successfully', async () => {
+ const { result } = renderHook(
+ () => {
+ const setCurrentWorkspaceMember = useSetRecoilState(
+ currentWorkspaceMemberState,
+ );
+ setCurrentWorkspaceMember(mockWorkspaceMember);
+
+ const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
+ setMetadataItems(mockObjectMetadataItems);
+
+ return useFavorites();
+ },
+ {
+ wrapper: Wrapper,
+ },
+ );
+
+ act(() => {
+ const dragAndDropResult: DropResult = {
+ source: { index: 0, droppableId: 'droppableId' },
+ destination: { index: 2, droppableId: 'droppableId' },
+ combine: null,
+ mode: 'FLUID',
+ draggableId: 'draggableId',
+ type: 'type',
+ reason: 'DROP',
+ };
+
+ const responderProvided: ResponderProvided = {
+ announce: (message: string) => console.log(message),
+ };
+
+ result.current.handleReorderFavorite(
+ dragAndDropResult,
+ responderProvided,
+ );
+ });
+
+ await waitFor(() => {
+ expect(mocks[2].result).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useMapToObjectRecordIdentifier.test.tsx b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useMapToObjectRecordIdentifier.test.tsx
index 03c09f5d6..11fb35d6e 100644
--- a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useMapToObjectRecordIdentifier.test.tsx
+++ b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useMapToObjectRecordIdentifier.test.tsx
@@ -26,7 +26,7 @@ describe('useMapToObjectRecordIdentifier', () => {
expect(result.current).toEqual({
id: 'id',
name: 'Sheldon Cooper',
- avatarUrl: null,
+ avatarUrl: '',
avatarType: 'rounded',
linkToShowPage: '/object/person/id',
});