[TEST] Covering useDeleteOne relations optimistic cache behavior (#10238)

## Introduction
Added coverage on the `useDeleteOneRecord` hooks, especially its
optimistic behavior feature.
Introduced a new testing tool `InMemoryTestingCacheInstance` that has
builtin very basic expectors in order to avoid future duplication when
covering others record hooks `update, create, destroy` etc etc

## Notes
Added few comments in this PR regarding some builtin functions I've
created around companies and people mocked object model and that I think
could be cool to spread and centralize within a dedicated "class
template"

Also put in light that unless I'm mistaken some tests are running on
`RecordNode` and not `RecordObject`

Took few directions on my own that as I always I would suggestion nor
remarks on them !

Let me know

## Misc
- Should we refactor `useDeleteOneRecord` tests to follow `eachTesting`
pattern ? => I feel like this is inappropriate as this hooks is already
high level, the only plus value would be less tests code despite
readability IMO
This commit is contained in:
Paul Rastoin
2025-03-03 10:22:26 +01:00
committed by GitHub
parent c6e5238d71
commit 2e4c596644
30 changed files with 2989 additions and 289 deletions

View File

@ -1,50 +1,7 @@
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { isDefined } from 'twenty-shared';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
export const getCompaniesMock = () => {
return companiesQueryResult.companies.edges.map((edge) => edge.node);
};
export const getCompanyObjectMetadataItem = () => {
const companyObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'company',
);
if (!companyObjectMetadataItem) {
throw new Error('Company object metadata item not found');
}
return companyObjectMetadataItem;
};
export const getCompanyDuplicateMock = () => {
return {
...companiesQueryResult.companies.edges[0].node,
id: '8b40856a-2ec9-4c03-8bc0-c032c89e1824',
};
};
export const getEmptyCompanyMock = () => {
return {
id: '9231e6ee-4cc2-4c7b-8c55-dff16f4d968a',
name: '',
domainName: {
__typename: 'Links',
primaryLinkUrl: '',
primaryLinkLabel: '',
secondaryLinks: [],
},
address: {},
accountOwner: null,
createdAt: null,
updatedAt: null,
employees: null,
idealCustomerProfile: null,
linkedinLink: null,
xLink: null,
_activityCount: null,
__typename: 'Company',
};
};
export const companiesQueryResult = {
companies: {
__typename: 'CompanyConnection',
@ -774,3 +731,75 @@ export const companiesQueryResult = {
],
},
};
const allMockedCompanyRecords = companiesQueryResult.companies.edges.map(
(edge) => edge.node,
);
export const getCompaniesMock = () => {
return [...allMockedCompanyRecords];
};
export const getMockCompanyObjectMetadataItem = () => {
const companyObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'company',
);
if (!companyObjectMetadataItem) {
throw new Error('Company object metadata item not found');
}
return companyObjectMetadataItem;
};
export const getCompanyDuplicateMock = () => {
return {
...companiesQueryResult.companies.edges[0].node,
id: '8b40856a-2ec9-4c03-8bc0-c032c89e1824',
};
};
export const getMockCompanyRecord = (
overrides?: Partial<ObjectRecord>,
index = 0,
) => {
return {
...allMockedCompanyRecords[index],
...overrides,
};
};
export const findMockCompanyRecord = ({
id: queriedCompanyId,
}: Pick<ObjectRecord, 'id'>) => {
const company = allMockedCompanyRecords.find(
({ id: currentCompanyId }) => currentCompanyId === queriedCompanyId,
);
if (!isDefined(company)) {
throw new Error(`Could not find company with id, ${queriedCompanyId}`);
}
return company;
};
export const getEmptyCompanyMock = () => {
return {
id: '9231e6ee-4cc2-4c7b-8c55-dff16f4d968a',
name: '',
domainName: {
__typename: 'Links',
primaryLinkUrl: '',
primaryLinkLabel: '',
secondaryLinks: [],
},
address: {},
accountOwner: null,
createdAt: null,
updatedAt: null,
employees: null,
idealCustomerProfile: null,
linkedinLink: null,
xLink: null,
_activityCount: null,
__typename: 'Company',
};
};

File diff suppressed because it is too large Load Diff

View File

@ -1,73 +1,9 @@
import { getRecordFromRecordNode } from '@/object-record/cache/utils/getRecordFromRecordNode';
import { RecordGqlConnection } from '@/object-record/graphql/types/RecordGqlConnection';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { FieldMetadataType } from 'twenty-shared';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
export const getPeopleMock = (): ObjectRecord[] => {
const peopleMock = peopleQueryResult.people.edges.map((edge) => edge.node);
return peopleMock;
};
export const getPersonObjectMetadataItem = () => {
const personObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'person',
);
if (!personObjectMetadataItem) {
throw new Error('Person object metadata item not found');
}
return personObjectMetadataItem;
};
export const getPersonFieldMetadataItem = (
fieldMetadataType: FieldMetadataType,
objectMetadataItem = getPersonObjectMetadataItem(),
) => {
const result = objectMetadataItem.fields.find(
(field) => field.type === fieldMetadataType,
);
if (!result) {
throw new Error(
`Person fieldmetadata item type ${fieldMetadataType} not found`,
);
}
return result;
};
export const getPersonRecord = (
overrides?: Partial<ObjectRecord>,
index = 0,
) => {
const personRecords = getPeopleMock();
return {
...personRecords[index],
...overrides,
};
};
export const mockedEmptyPersonData = {
id: 'ce7f0a37-88d7-4cd8-8b41-6721c57195b5',
firstName: '',
lastName: '',
phone: null,
email: null,
city: null,
createdBy: null,
displayName: null,
avatarUrl: null,
createdAt: null,
jobTitle: null,
linkedinUrl: null,
xUrl: null,
_activityCount: null,
company: null,
deletedAt: null,
__typename: 'Person',
};
export const peopleQueryResult = {
people: {
__typename: 'PersonConnection',
@ -1762,3 +1698,71 @@ export const peopleQueryResult = {
],
},
} satisfies { people: RecordGqlConnection };
export const allMockPersonRecords = peopleQueryResult.people.edges.map((edge) =>
getRecordFromRecordNode({ recordNode: edge.node }),
);
export const getPeopleRecordConnectionMock = () => {
const peopleMock = peopleQueryResult.people.edges.map((edge) => edge.node);
return peopleMock;
};
export const getMockPersonObjectMetadataItem = () => {
const personObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'person',
);
if (!personObjectMetadataItem) {
throw new Error('Person object metadata item not found');
}
return personObjectMetadataItem;
};
export const getMockPersonFieldMetadataItem = (
fieldMetadataType: FieldMetadataType,
objectMetadataItem = getMockPersonObjectMetadataItem(),
) => {
const result = objectMetadataItem.fields.find(
(field) => field.type === fieldMetadataType,
);
if (!result) {
throw new Error(
`Person fieldmetadata item type ${fieldMetadataType} not found`,
);
}
return result;
};
export const getMockPersonRecord = (
overrides?: Partial<ObjectRecord>,
index = 0,
) => {
return {
...allMockPersonRecords[index],
...overrides,
};
};
export const mockedEmptyPersonData = {
id: 'ce7f0a37-88d7-4cd8-8b41-6721c57195b5',
firstName: '',
lastName: '',
phone: null,
email: null,
city: null,
createdBy: null,
displayName: null,
avatarUrl: null,
createdAt: null,
jobTitle: null,
linkedinUrl: null,
xUrl: null,
_activityCount: null,
company: null,
deletedAt: null,
__typename: 'Person',
};