Activity as standard object (#6219)
In this PR I layout the first steps to migrate Activity to a traditional Standard objects Since this is a big transition, I'd rather split it into several deployments / PRs <img width="1512" alt="image" src="https://github.com/user-attachments/assets/012e2bbf-9d1b-4723-aaf6-269ef588b050"> --------- Co-authored-by: Charles Bochet <charles@twenty.com> Co-authored-by: bosiraphael <71827178+bosiraphael@users.noreply.github.com> Co-authored-by: Weiko <corentin@twenty.com> Co-authored-by: Faisal-imtiyaz123 <142205282+Faisal-imtiyaz123@users.noreply.github.com> Co-authored-by: Prateek Jain <prateekj1171998@gmail.com>
This commit is contained in:
@ -6,6 +6,7 @@ import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useActivities } from '@/activities/hooks/useActivities';
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
||||
import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members';
|
||||
|
||||
@ -20,16 +21,14 @@ const mockActivityTarget = {
|
||||
};
|
||||
|
||||
const mockActivity = {
|
||||
__typename: 'Activity',
|
||||
__typename: 'Note',
|
||||
updatedAt: '2021-08-03T19:20:06.000Z',
|
||||
createdAt: '2021-08-03T19:20:06.000Z',
|
||||
completedAt: '2021-08-03T19:20:06.000Z',
|
||||
status: 'DONE',
|
||||
reminderAt: '2021-08-03T19:20:06.000Z',
|
||||
title: 'title',
|
||||
authorId: '1',
|
||||
body: 'body',
|
||||
dueAt: '2021-08-03T19:20:06.000Z',
|
||||
type: 'type',
|
||||
assigneeId: '1',
|
||||
id: '234',
|
||||
};
|
||||
@ -102,13 +101,13 @@ const mocks: MockedResponse[] = [
|
||||
{
|
||||
request: {
|
||||
query: gql`
|
||||
query FindManyActivities(
|
||||
$filter: ActivityFilterInput
|
||||
$orderBy: [ActivityOrderByInput]
|
||||
query FindManyTasks(
|
||||
$filter: TaskFilterInput
|
||||
$orderBy: [TaskOrderByInput]
|
||||
$lastCursor: String
|
||||
$limit: Int
|
||||
) {
|
||||
activities(
|
||||
tasks(
|
||||
filter: $filter
|
||||
orderBy: $orderBy
|
||||
first: $limit
|
||||
@ -117,17 +116,13 @@ const mocks: MockedResponse[] = [
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
createdAt
|
||||
reminderAt
|
||||
authorId
|
||||
title
|
||||
completedAt
|
||||
updatedAt
|
||||
body
|
||||
dueAt
|
||||
type
|
||||
id
|
||||
assigneeId
|
||||
updatedAt
|
||||
createdAt
|
||||
body
|
||||
status
|
||||
dueAt
|
||||
}
|
||||
cursor
|
||||
}
|
||||
@ -178,6 +173,7 @@ describe('useActivities', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useActivities({
|
||||
objectNameSingular: CoreObjectNameSingular.Task,
|
||||
targetableObjects: [],
|
||||
activitiesFilters: {},
|
||||
activitiesOrderByVariables: [{}],
|
||||
@ -200,6 +196,7 @@ describe('useActivities', () => {
|
||||
);
|
||||
|
||||
const activities = useActivities({
|
||||
objectNameSingular: CoreObjectNameSingular.Task,
|
||||
targetableObjects: [
|
||||
{ targetObjectNameSingular: 'company', id: '123' },
|
||||
],
|
||||
|
||||
@ -7,8 +7,8 @@ import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||
import { getRecordFromRecordNode } from '@/object-record/cache/utils/getRecordFromRecordNode';
|
||||
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
||||
import { JestObjectMetadataItemSetter } from '~/testing/jest/JestObjectMetadataItemSetter';
|
||||
import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members';
|
||||
@ -16,108 +16,95 @@ const mockObjectMetadataItems = getObjectMetadataItemsMock();
|
||||
|
||||
const cache = new InMemoryCache();
|
||||
|
||||
const activityNode = {
|
||||
id: '3ecaa1be-aac7-463a-a38e-64078dd451d5',
|
||||
const taskTarget = {
|
||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb300',
|
||||
createdAt: '2023-04-26T10:12:42.33625+00:00',
|
||||
updatedAt: '2023-04-26T10:23:42.33625+00:00',
|
||||
reminderAt: null,
|
||||
title: 'My very first note',
|
||||
type: 'Note',
|
||||
body: '',
|
||||
dueAt: '2023-04-26T10:12:42.33625+00:00',
|
||||
completedAt: null,
|
||||
author: null,
|
||||
assignee: null,
|
||||
assigneeId: null,
|
||||
authorId: null,
|
||||
comments: {
|
||||
edges: [],
|
||||
companyId: null,
|
||||
company: null,
|
||||
personId: '89bb825c-171e-4bcc-9cf7-43448d6fb280',
|
||||
person: {
|
||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb280',
|
||||
createdAt: '2023-04-26T10:12:42.33625+00:00',
|
||||
updatedAt: '2023-04-26T10:23:42.33625+00:00',
|
||||
city: 'City',
|
||||
name: {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
},
|
||||
__typename: 'Person',
|
||||
},
|
||||
activityTargets: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb300',
|
||||
createdAt: '2023-04-26T10:12:42.33625+00:00',
|
||||
updatedAt: '2023-04-26T10:23:42.33625+00:00',
|
||||
personId: null,
|
||||
companyId: '89bb825c-171e-4bcc-9cf7-43448d6fb280',
|
||||
company: {
|
||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb280',
|
||||
name: 'Airbnb',
|
||||
domainName: {
|
||||
primaryLinkUrl: 'https://www.airbnb.com',
|
||||
primaryLinkLabel: '',
|
||||
secondaryLinks: null,
|
||||
},
|
||||
},
|
||||
person: null,
|
||||
activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb230',
|
||||
activity: {
|
||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb230',
|
||||
createdAt: '2023-04-26T10:12:42.33625+00:00',
|
||||
updatedAt: '2023-04-26T10:23:42.33625+00:00',
|
||||
},
|
||||
__typename: 'ActivityTarget',
|
||||
},
|
||||
__typename: 'ActivityTargetEdge',
|
||||
},
|
||||
],
|
||||
__typename: 'ActivityTargetConnection',
|
||||
taskId: '89bb825c-171e-4bcc-9cf7-43448d6fb230',
|
||||
task: {
|
||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb230',
|
||||
createdAt: '2023-04-26T10:12:42.33625+00:00',
|
||||
updatedAt: '2023-04-26T10:23:42.33625+00:00',
|
||||
dueAt: null,
|
||||
body: '{}',
|
||||
title: 'Task title',
|
||||
assigneeId: null,
|
||||
__typename: 'Task',
|
||||
},
|
||||
__typename: 'Activity' as const,
|
||||
__typename: 'TaskTarget',
|
||||
};
|
||||
|
||||
cache.writeFragment({
|
||||
fragment: gql`
|
||||
fragment CreateOneActivityInCache on Activity {
|
||||
id
|
||||
createdAt
|
||||
fragment TaskTargetFragment on TaskTarget {
|
||||
__typename
|
||||
updatedAt
|
||||
reminderAt
|
||||
title
|
||||
body
|
||||
dueAt
|
||||
completedAt
|
||||
author
|
||||
assignee
|
||||
assigneeId
|
||||
authorId
|
||||
activityTargets {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
createdAt
|
||||
updatedAt
|
||||
personId
|
||||
companyId
|
||||
company {
|
||||
id
|
||||
name
|
||||
domainName {
|
||||
primaryLinkUrl
|
||||
primaryLinkLabel
|
||||
secondaryLinks
|
||||
}
|
||||
}
|
||||
person
|
||||
activityId
|
||||
activity {
|
||||
id
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
__typename
|
||||
}
|
||||
createdAt
|
||||
personId
|
||||
taskId
|
||||
companyId
|
||||
id
|
||||
task {
|
||||
__typename
|
||||
createdAt
|
||||
title
|
||||
updatedAt
|
||||
body
|
||||
dueAt
|
||||
id
|
||||
assigneeId
|
||||
}
|
||||
person {
|
||||
__typename
|
||||
id
|
||||
createdAt
|
||||
updatedAt
|
||||
city
|
||||
name {
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
}
|
||||
__typename
|
||||
company {
|
||||
__typename
|
||||
id
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`,
|
||||
id: activityNode.id,
|
||||
data: activityNode,
|
||||
id: `TaskTarget:${taskTarget.id}`,
|
||||
data: taskTarget,
|
||||
});
|
||||
|
||||
const task = {
|
||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb230',
|
||||
createdAt: '2023-04-26T10:12:42.33625+00:00',
|
||||
updatedAt: '2023-04-26T10:23:42.33625+00:00',
|
||||
title: 'Task title',
|
||||
body: null,
|
||||
assigneeId: null,
|
||||
status: null,
|
||||
dueAt: '2023-04-26T10:12:42.33625+00:00',
|
||||
assignee: null,
|
||||
__typename: 'Task' as any,
|
||||
taskTargets: [taskTarget],
|
||||
};
|
||||
|
||||
const Wrapper = ({ children }: { children: ReactNode }) => (
|
||||
<RecoilRoot>
|
||||
<MockedProvider cache={cache}>
|
||||
@ -142,7 +129,8 @@ describe('useActivityTargetObjectRecords', () => {
|
||||
);
|
||||
|
||||
const { activityTargetObjectRecords } = useActivityTargetObjectRecords(
|
||||
getRecordFromRecordNode({ recordNode: activityNode as any }),
|
||||
task,
|
||||
CoreObjectNameSingular.Task,
|
||||
);
|
||||
|
||||
return {
|
||||
@ -158,18 +146,17 @@ describe('useActivityTargetObjectRecords', () => {
|
||||
result.current.setCurrentWorkspaceMember(mockWorkspaceMembers[0]);
|
||||
result.current.setObjectMetadataItems(mockObjectMetadataItems);
|
||||
});
|
||||
|
||||
const activityTargetObjectRecords =
|
||||
result.current.activityTargetObjectRecords;
|
||||
|
||||
expect(activityTargetObjectRecords).toHaveLength(1);
|
||||
expect(activityTargetObjectRecords[0].activityTarget).toEqual(
|
||||
activityNode.activityTargets.edges[0].node,
|
||||
);
|
||||
expect(activityTargetObjectRecords[0].activityTarget).toEqual(taskTarget);
|
||||
expect(activityTargetObjectRecords[0].targetObject).toEqual(
|
||||
activityNode.activityTargets.edges[0].node.company,
|
||||
taskTarget.person,
|
||||
);
|
||||
expect(
|
||||
activityTargetObjectRecords[0].targetObjectMetadataItem.nameSingular,
|
||||
).toEqual('company');
|
||||
).toEqual('person');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,131 +0,0 @@
|
||||
import { MockedProvider, MockedResponse } from '@apollo/client/testing';
|
||||
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||
import gql from 'graphql-tag';
|
||||
import { ReactNode } from 'react';
|
||||
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useActivityTargetsForTargetableObject } from '@/activities/hooks/useActivityTargetsForTargetableObject';
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
||||
import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members';
|
||||
|
||||
const mockActivityTarget = {
|
||||
__typename: 'ActivityTarget',
|
||||
updatedAt: '2021-08-03T19:20:06.000Z',
|
||||
createdAt: '2021-08-03T19:20:06.000Z',
|
||||
personId: '1',
|
||||
activityId: '234',
|
||||
companyId: '1',
|
||||
id: '123',
|
||||
};
|
||||
|
||||
const defaultResponseData = {
|
||||
pageInfo: {
|
||||
hasNextPage: false,
|
||||
startCursor: '',
|
||||
endCursor: '',
|
||||
},
|
||||
totalCount: 1,
|
||||
};
|
||||
|
||||
const mocks: MockedResponse[] = [
|
||||
{
|
||||
request: {
|
||||
query: gql`
|
||||
query FindManyActivityTargets(
|
||||
$filter: ActivityTargetFilterInput
|
||||
$orderBy: [ActivityTargetOrderByInput]
|
||||
$lastCursor: String
|
||||
$limit: Int
|
||||
) {
|
||||
activityTargets(
|
||||
filter: $filter
|
||||
orderBy: $orderBy
|
||||
first: $limit
|
||||
after: $lastCursor
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
updatedAt
|
||||
createdAt
|
||||
personId
|
||||
activityId
|
||||
companyId
|
||||
id
|
||||
}
|
||||
cursor
|
||||
}
|
||||
pageInfo {
|
||||
hasNextPage
|
||||
hasPreviousPage
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
filter: { personId: { eq: '1234' } },
|
||||
orderBy: undefined,
|
||||
lastCursor: undefined,
|
||||
limit: undefined,
|
||||
},
|
||||
},
|
||||
result: jest.fn(() => ({
|
||||
data: {
|
||||
activityTargets: {
|
||||
...defaultResponseData,
|
||||
edges: [
|
||||
{
|
||||
node: mockActivityTarget,
|
||||
cursor: '1',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
})),
|
||||
},
|
||||
];
|
||||
|
||||
const Wrapper = ({ children }: { children: ReactNode }) => (
|
||||
<RecoilRoot>
|
||||
<MockedProvider mocks={mocks} addTypename={false}>
|
||||
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
|
||||
{children}
|
||||
</SnackBarProviderScope>
|
||||
</MockedProvider>
|
||||
</RecoilRoot>
|
||||
);
|
||||
|
||||
describe('useActivityTargetsForTargetableObject', () => {
|
||||
it('works as expected', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const setCurrentWorkspaceMember = useSetRecoilState(
|
||||
currentWorkspaceMemberState,
|
||||
);
|
||||
|
||||
const res = useActivityTargetsForTargetableObject({
|
||||
targetableObject: {
|
||||
id: '1234',
|
||||
targetObjectNameSingular: 'person',
|
||||
},
|
||||
});
|
||||
return { ...res, setCurrentWorkspaceMember };
|
||||
},
|
||||
{ wrapper: Wrapper },
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.setCurrentWorkspaceMember(mockWorkspaceMembers[0]);
|
||||
});
|
||||
|
||||
expect(result.current.loadingActivityTargets).toBe(true);
|
||||
|
||||
await waitFor(() => !result.current.loadingActivityTargets);
|
||||
|
||||
expect(result.current.activityTargets).toEqual([mockActivityTarget]);
|
||||
});
|
||||
});
|
||||
@ -1,106 +0,0 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { MockedProvider, MockedResponse } from '@apollo/client/testing';
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import gql from 'graphql-tag';
|
||||
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useCreateActivityInCache } from '@/activities/hooks/useCreateActivityInCache';
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
||||
import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members';
|
||||
|
||||
const mocks: MockedResponse[] = [
|
||||
{
|
||||
request: {
|
||||
query: gql`
|
||||
query FindOneWorkspaceMember($objectRecordId: ID!) {
|
||||
workspaceMember(filter: { id: { eq: $objectRecordId } }) {
|
||||
__typename
|
||||
colorScheme
|
||||
name {
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
locale
|
||||
userId
|
||||
avatarUrl
|
||||
createdAt
|
||||
updatedAt
|
||||
id
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: { objectRecordId: '20202020-1553-45c6-a028-5a9064cce07f' },
|
||||
},
|
||||
result: jest.fn(() => ({
|
||||
data: {
|
||||
workspaceMember: mockWorkspaceMembers[0],
|
||||
},
|
||||
})),
|
||||
},
|
||||
];
|
||||
|
||||
const Wrapper = ({ children }: { children: ReactNode }) => (
|
||||
<RecoilRoot>
|
||||
<MockedProvider mocks={mocks} addTypename={false}>
|
||||
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
|
||||
{children}
|
||||
</SnackBarProviderScope>
|
||||
</MockedProvider>
|
||||
</RecoilRoot>
|
||||
);
|
||||
|
||||
const mockObjectMetadataItems = getObjectMetadataItemsMock();
|
||||
|
||||
describe('useCreateActivityInCache', () => {
|
||||
it('Should create activity in cache', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const setCurrentWorkspaceMember = useSetRecoilState(
|
||||
currentWorkspaceMemberState,
|
||||
);
|
||||
const setObjectMetadataItems = useSetRecoilState(
|
||||
objectMetadataItemsState,
|
||||
);
|
||||
const setRecordStore = useSetRecoilState(
|
||||
recordStoreFamilyState('1234'),
|
||||
);
|
||||
|
||||
const res = useCreateActivityInCache();
|
||||
return {
|
||||
...res,
|
||||
setCurrentWorkspaceMember,
|
||||
setObjectMetadataItems,
|
||||
setRecordStore,
|
||||
};
|
||||
},
|
||||
{ wrapper: Wrapper },
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.setRecordStore({
|
||||
id: '1234',
|
||||
__typename: 'Person',
|
||||
});
|
||||
result.current.setCurrentWorkspaceMember(mockWorkspaceMembers[0]);
|
||||
result.current.setObjectMetadataItems(mockObjectMetadataItems);
|
||||
});
|
||||
|
||||
act(() => {
|
||||
const res = result.current.createActivityInCache({
|
||||
type: 'Note',
|
||||
targetObject: {
|
||||
targetObjectNameSingular: 'person',
|
||||
id: '1234',
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.createdActivityInCache).toHaveProperty('id');
|
||||
expect(res.createdActivityInCache).toHaveProperty('__typename');
|
||||
expect(res.createdActivityInCache).toHaveProperty('activityTargets');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -6,22 +6,16 @@ import { ReactNode } from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { useCreateActivityInDB } from '@/activities/hooks/useCreateActivityInDB';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
||||
import { mockedActivities } from '~/testing/mock-data/activities';
|
||||
import { mockedTasks } from '~/testing/mock-data/tasks';
|
||||
|
||||
const mockedDate = '2024-03-15T12:00:00.000Z';
|
||||
const toISOStringMock = jest.fn(() => mockedDate);
|
||||
global.Date.prototype.toISOString = toISOStringMock;
|
||||
|
||||
const mockedActivity = {
|
||||
...pick(mockedActivities[0], [
|
||||
'id',
|
||||
'title',
|
||||
'body',
|
||||
'type',
|
||||
'completedAt',
|
||||
'dueAt',
|
||||
]),
|
||||
...pick(mockedTasks[0], ['id', 'title', 'body', 'type', 'status', 'dueAt']),
|
||||
updatedAt: mockedDate,
|
||||
};
|
||||
|
||||
@ -36,7 +30,7 @@ const mocks: MockedResponse[] = [
|
||||
reminderAt
|
||||
authorId
|
||||
title
|
||||
completedAt
|
||||
status
|
||||
updatedAt
|
||||
body
|
||||
dueAt
|
||||
@ -77,14 +71,19 @@ const Wrapper = ({ children }: { children: ReactNode }) => (
|
||||
|
||||
describe('useCreateActivityInDB', () => {
|
||||
it('Should create activity in DB', async () => {
|
||||
const { result } = renderHook(() => useCreateActivityInDB(), {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useCreateActivityInDB({
|
||||
activityObjectNameSingular: CoreObjectNameSingular.Task,
|
||||
}),
|
||||
{
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.createActivityInDB({
|
||||
...mockedActivity,
|
||||
__typename: 'Activity',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { ReactNode } from 'react';
|
||||
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||
|
||||
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
|
||||
import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
||||
|
||||
const Wrapper = ({ children }: { children: ReactNode }) => (
|
||||
@ -17,12 +17,12 @@ describe('useOpenActivityRightDrawer', () => {
|
||||
it('works as expected', () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const openActivityRightDrawer = useOpenActivityRightDrawer();
|
||||
const openActivityRightDrawer = useOpenActivityRightDrawer({
|
||||
objectNameSingular: CoreObjectNameSingular.Task,
|
||||
});
|
||||
const viewableRecordId = useRecoilValue(viewableRecordIdState);
|
||||
const activityIdInDrawer = useRecoilValue(activityIdInDrawerState);
|
||||
return {
|
||||
openActivityRightDrawer,
|
||||
activityIdInDrawer,
|
||||
viewableRecordId,
|
||||
};
|
||||
},
|
||||
@ -31,12 +31,10 @@ describe('useOpenActivityRightDrawer', () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.activityIdInDrawer).toBeNull();
|
||||
expect(result.current.viewableRecordId).toBeNull();
|
||||
act(() => {
|
||||
result.current.openActivityRightDrawer('123');
|
||||
});
|
||||
expect(result.current.activityIdInDrawer).toBe('123');
|
||||
expect(result.current.viewableRecordId).toBe('123');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,23 +1,71 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { MockedProvider, MockedResponse } from '@apollo/client/testing';
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { ReactNode } from 'react';
|
||||
import { RecoilRoot, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
||||
import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
||||
import gql from 'graphql-tag';
|
||||
import pick from 'lodash.pick';
|
||||
import { mockedTasks } from '~/testing/mock-data/tasks';
|
||||
|
||||
const mockUUID = '37873e04-2f83-4468-9ab7-3f87da6cafad';
|
||||
const mockedDate = '2024-03-15T12:00:00.000Z';
|
||||
const toISOStringMock = jest.fn(() => mockedDate);
|
||||
global.Date.prototype.toISOString = toISOStringMock;
|
||||
|
||||
jest.mock('uuid', () => ({
|
||||
v4: () => mockUUID,
|
||||
}));
|
||||
const mockedActivity = {
|
||||
...pick(mockedTasks[0], ['id', 'title', 'body', 'type', 'status', 'dueAt']),
|
||||
updatedAt: mockedDate,
|
||||
};
|
||||
|
||||
const mocks: MockedResponse[] = [
|
||||
{
|
||||
request: {
|
||||
query: gql`
|
||||
mutation CreateOneActivity($input: ActivityCreateInput!) {
|
||||
createActivity(data: $input) {
|
||||
__typename
|
||||
createdAt
|
||||
reminderAt
|
||||
authorId
|
||||
title
|
||||
status
|
||||
updatedAt
|
||||
body
|
||||
dueAt
|
||||
type
|
||||
id
|
||||
assigneeId
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
input: mockedActivity,
|
||||
},
|
||||
},
|
||||
result: jest.fn(() => ({
|
||||
data: {
|
||||
createActivity: {
|
||||
...mockedActivity,
|
||||
__typename: 'Activity',
|
||||
assigneeId: '',
|
||||
authorId: '1',
|
||||
reminderAt: null,
|
||||
createdAt: mockedDate,
|
||||
},
|
||||
},
|
||||
})),
|
||||
},
|
||||
];
|
||||
|
||||
const Wrapper = ({ children }: { children: ReactNode }) => (
|
||||
<RecoilRoot>
|
||||
<MockedProvider addTypename={false}>{children}</MockedProvider>
|
||||
<MockedProvider addTypename={false} mocks={mocks}>
|
||||
{children}
|
||||
</MockedProvider>
|
||||
</RecoilRoot>
|
||||
);
|
||||
|
||||
@ -27,15 +75,15 @@ describe('useOpenCreateActivityDrawer', () => {
|
||||
it('works as expected', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const openActivityRightDrawer = useOpenCreateActivityDrawer();
|
||||
const openActivityRightDrawer = useOpenCreateActivityDrawer({
|
||||
activityObjectNameSingular: CoreObjectNameSingular.Note,
|
||||
});
|
||||
const viewableRecordId = useRecoilValue(viewableRecordIdState);
|
||||
const activityIdInDrawer = useRecoilValue(activityIdInDrawerState);
|
||||
const setObjectMetadataItems = useSetRecoilState(
|
||||
objectMetadataItemsState,
|
||||
);
|
||||
return {
|
||||
openActivityRightDrawer,
|
||||
activityIdInDrawer,
|
||||
viewableRecordId,
|
||||
setObjectMetadataItems,
|
||||
};
|
||||
@ -49,15 +97,11 @@ describe('useOpenCreateActivityDrawer', () => {
|
||||
result.current.setObjectMetadataItems(mockObjectMetadataItems);
|
||||
});
|
||||
|
||||
expect(result.current.activityIdInDrawer).toBeNull();
|
||||
expect(result.current.viewableRecordId).toBeNull();
|
||||
await act(async () => {
|
||||
result.current.openActivityRightDrawer({
|
||||
type: 'Note',
|
||||
targetableObjects: [],
|
||||
});
|
||||
});
|
||||
expect(result.current.activityIdInDrawer).toBe(mockUUID);
|
||||
expect(result.current.viewableRecordId).toBe(mockUUID);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user