[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

@ -4,14 +4,14 @@ import { renderHook, waitFor } from '@testing-library/react';
import { act } from 'react';
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { getPeopleMock } from '~/testing/mock-data/people';
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
import { useDeleteMultipleRecordsAction } from '../useDeleteMultipleRecordsAction';
const personMockObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'person',
)!;
const peopleMock = getPeopleMock();
const peopleMock = getPeopleRecordConnectionMock();
const deleteManyRecordsMock = jest.fn();
const resetTableRowSelectionMock = jest.fn();

View File

@ -9,7 +9,7 @@ import {
getJestMetadataAndApolloMocksAndActionMenuWrapper,
} from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { getPeopleMock } from '~/testing/mock-data/people';
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
import { useDestroyMultipleRecordsAction } from '../useDestroyMultipleRecordsAction';
const personMockObjectMetadataItem = generatedMockObjectMetadataItems.find(
@ -20,10 +20,12 @@ const personMockObjectMetadataItemDeletedAtField =
if (personMockObjectMetadataItemDeletedAtField === undefined)
throw new Error('Should never occur');
const [firstPeopleMock, secondPeopleMock] = getPeopleMock().map((record) => ({
...record,
deletedAt: new Date().toISOString(),
}));
const [firstPeopleMock, secondPeopleMock] = getPeopleRecordConnectionMock().map(
(record) => ({
...record,
deletedAt: new Date().toISOString(),
}),
);
const destroyManyRecordsMock = jest.fn();
const resetTableRowSelectionMock = jest.fn();

View File

@ -3,14 +3,14 @@ import { renderHook, waitFor } from '@testing-library/react';
import { act } from 'react';
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { getPeopleMock } from '~/testing/mock-data/people';
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
import { useExportMultipleRecordsAction } from '../useExportMultipleRecordsAction';
const personMockObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'person',
)!;
const peopleMock = getPeopleMock();
const peopleMock = getPeopleRecordConnectionMock();
const downloadMock = jest.fn();

View File

@ -6,14 +6,14 @@ import {
getJestMetadataAndApolloMocksAndActionMenuWrapper,
} from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { getPeopleMock } from '~/testing/mock-data/people';
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
import { useAddToFavoritesSingleRecordAction } from '../useAddToFavoritesSingleRecordAction';
const personMockObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'person',
)!;
const peopleMock = getPeopleMock();
const peopleMock = getPeopleRecordConnectionMock();
const favoritesMock = [
{

View File

@ -3,14 +3,14 @@ import { renderHook } from '@testing-library/react';
import { act } from 'react';
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { getPeopleMock } from '~/testing/mock-data/people';
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
import { useDeleteSingleRecordAction } from '../useDeleteSingleRecordAction';
const personMockObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'person',
)!;
const peopleMock = getPeopleMock();
const peopleMock = getPeopleRecordConnectionMock();
const deleteOneRecordMock = jest.fn();

View File

@ -6,14 +6,14 @@ import {
getJestMetadataAndApolloMocksAndActionMenuWrapper,
} from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { getPeopleMock } from '~/testing/mock-data/people';
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
import { useRemoveFromFavoritesSingleRecordAction } from '../useRemoveFromFavoritesSingleRecordAction';
const personMockObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'person',
)!;
const peopleMock = getPeopleMock();
const peopleMock = getPeopleRecordConnectionMock();
const favoritesMock = [
{

View File

@ -9,7 +9,7 @@ import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { AppPath } from '@/types/AppPath';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType } from '@/views/types/ViewType';
import { getCompanyObjectMetadataItem } from '~/testing/mock-data/companies';
import { getMockCompanyObjectMetadataItem } from '~/testing/mock-data/companies';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { mockedUserData } from '~/testing/mock-data/users';
@ -35,7 +35,7 @@ const renderHooks = ({
{
id: 'viewId',
name: 'Test View',
objectMetadataId: getCompanyObjectMetadataItem().id,
objectMetadataId: getMockCompanyObjectMetadataItem().id,
type: ViewType.Table,
key: null,
isCompact: false,

View File

@ -1,11 +1,11 @@
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { getPeopleMock } from '~/testing/mock-data/people';
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { getRecordNodeFromRecord } from '../getRecordNodeFromRecord';
const peopleMock = getPeopleMock();
const peopleMock = getPeopleRecordConnectionMock();
describe('getRecordNodeFromRecord', () => {
it('computes relation records cache references by default', () => {

View File

@ -1,13 +1,13 @@
import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphql/utils/computeDepthOneRecordGqlFieldsFromRecord';
import {
getPersonObjectMetadataItem,
getPersonRecord,
allMockPersonRecords,
getMockPersonObjectMetadataItem,
} from '~/testing/mock-data/people';
describe('computeDepthOneRecordGqlFieldsFromRecord', () => {
const objectMetadataItem = getPersonObjectMetadataItem();
const objectMetadataItem = getMockPersonObjectMetadataItem();
it('Should handle basic call', () => {
const personRecord = getPersonRecord();
const personRecord = allMockPersonRecords[0];
const result = computeDepthOneRecordGqlFieldsFromRecord({
objectMetadataItem,
record: personRecord,

View File

@ -1,8 +1,8 @@
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
import { getPersonObjectMetadataItem } from '~/testing/mock-data/people';
import { getMockPersonObjectMetadataItem } from '~/testing/mock-data/people';
describe('generateDepthOneRecordGqlFields', () => {
const objectMetadataItem = getPersonObjectMetadataItem();
const objectMetadataItem = getMockPersonObjectMetadataItem();
it('Should handle basic call with standalone objectMetadataItem', () => {
const result = generateDepthOneRecordGqlFields({
objectMetadataItem,

View File

@ -1,6 +1,6 @@
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { gql } from '@apollo/client';
import { getPersonRecord } from '~/testing/mock-data/people';
import { getMockPersonRecord } from '~/testing/mock-data/people';
export const query = gql`
mutation DeleteManyPeople($filter: PersonFilterInput!) {
@ -17,7 +17,7 @@ export const personIds = [
];
export const personRecords = personIds.map<ObjectRecord>((personId, index) =>
getPersonRecord({ id: personId, deletedAt: null }, index),
getMockPersonRecord({ id: personId, deletedAt: null }, index),
);
export const variables = {

View File

@ -8,14 +8,4 @@ export const query = gql`
id
}
}
`;
export const variables = {
idToDelete: 'a7286b9a-c039-4a89-9567-2dfa7953cda9',
};
export const responseData = {
__typename: 'Person',
deletedAt: '2024-02-14T09:45:00Z',
id: 'a7286b9a-c039-4a89-9567-2dfa7953cda9',
};
`;

View File

@ -1,8 +1,8 @@
import { PERSON_FRAGMENT_WITH_DEPTH_ZERO_RELATIONS } from '@/object-record/hooks/__mocks__/personFragments';
import { gql } from '@apollo/client';
import { getPeopleMock } from '~/testing/mock-data/people';
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
const peopleMock = getPeopleMock();
const peopleMock = getPeopleRecordConnectionMock();
export const query = gql`
query FindDuplicatePerson($ids: [ID!]!) {

View File

@ -0,0 +1,624 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`useDeleteOneRecord A. Starting from empty cache 1. Should successfully delete record and update record cache entry 1`] = `
{
"__typename": "Person",
"deletedAt": "2024-02-14T09:45:00Z",
"id": "da3c2c4b-da01-4b81-9734-226069eb4cd0",
}
`;
exports[`useDeleteOneRecord B. Starting from filled cache 1. Should handle successfull record deletion 1`] = `
{
"__typename": "Person",
"city": "ASd",
"company": {
"__typename": "Company",
"address": {
"__typename": "Address",
"addressCity": "Dublin",
"addressCountry": "Ireland",
"addressLat": null,
"addressLng": null,
"addressPostcode": null,
"addressState": null,
"addressStreet1": "Eutaw Street",
"addressStreet2": null,
},
"createdAt": "2025-02-16T08:21:51.715Z",
"createdBy": {
"__typename": "Actor",
"context": {},
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"domainName": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "https://linkedin.com",
"secondaryLinks": [],
},
"employees": null,
"id": "20202020-3ec3-4fe3-8997-b76aa0bfa408",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": "Linkedin",
"position": 1,
},
"createdAt": "2024-08-02T09:52:46.814Z",
"createdBy": {
"__typename": "Actor",
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": "2024-02-14T09:45:00Z",
"id": "da3c2c4b-da01-4b81-9734-226069eb4cd0",
"jobTitle": "",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": {
"__typename": "FullName",
"firstName": "Test",
"lastName": "Test",
},
"noteTargets": [],
"phones": {
"primaryPhoneCallingCode": "+33",
"primaryPhoneCountryCode": "FR",
"primaryPhoneNumber": "781234562",
},
"position": 0,
"taskTargets": [],
"xLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
}
`;
exports[`useDeleteOneRecord B. Starting from filled cache 1. Should handle successfull record deletion 2`] = `
{
"__typename": "Company",
"accountOwner": null,
"address": {
"__typename": "Address",
"addressCity": "Dublin",
"addressCountry": "Ireland",
"addressLat": null,
"addressLng": null,
"addressPostcode": null,
"addressState": null,
"addressStreet1": "Eutaw Street",
"addressStreet2": null,
},
"createdAt": "2025-02-16T08:21:51.715Z",
"createdBy": {
"__typename": "Actor",
"context": {},
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"domainName": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "https://linkedin.com",
"secondaryLinks": [],
},
"employees": null,
"id": "20202020-3ec3-4fe3-8997-b76aa0bfa408",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": "Linkedin",
"noteTargets": [],
"opportunities": [
{},
],
"people": [
{
"__typename": "Person",
"city": "Seattle",
"createdAt": "2024-08-01T09:50:00.000Z",
"createdBy": {
"__typename": "Actor",
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"id": "20202020-1c0e-494c-a1b6-85b1c6fefaa5",
"jobTitle": "",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": {
"__typename": "FullName",
"firstName": "Christoph",
"lastName": "Callisto",
},
"phones": {
"primaryPhoneCallingCode": "+33",
"primaryPhoneCountryCode": "FR",
"primaryPhoneNumber": "781234562",
},
"position": 1,
"xLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
},
{
"__typename": "Person",
"city": "Los Angeles",
"createdAt": "2024-08-02T09:48:36.193Z",
"createdBy": {
"__typename": "Actor",
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"id": "20202020-ac73-4797-824e-87a1f5aea9e0",
"jobTitle": "",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": {
"__typename": "FullName",
"firstName": "Sylvie",
"lastName": "Palmer",
},
"phones": {
"primaryPhoneCallingCode": "+33",
"primaryPhoneCountryCode": "FR",
"primaryPhoneNumber": "781234576",
},
"position": 2,
"xLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
},
],
"position": 1,
"taskTargets": [],
}
`;
exports[`useDeleteOneRecord B. Starting from filled cache 2. Should handle optimistic cache on record deletion 1`] = `
{
"__typename": "Person",
"city": "ASd",
"company": {
"__typename": "Company",
"address": {
"__typename": "Address",
"addressCity": "Dublin",
"addressCountry": "Ireland",
"addressLat": null,
"addressLng": null,
"addressPostcode": null,
"addressState": null,
"addressStreet1": "Eutaw Street",
"addressStreet2": null,
},
"createdAt": "2025-02-16T08:21:51.715Z",
"createdBy": {
"__typename": "Actor",
"context": {},
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"domainName": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "https://linkedin.com",
"secondaryLinks": [],
},
"employees": null,
"id": "20202020-3ec3-4fe3-8997-b76aa0bfa408",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": "Linkedin",
"position": 1,
},
"createdAt": "2024-08-02T09:52:46.814Z",
"createdBy": {
"__typename": "Actor",
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": Any<String>,
"id": "da3c2c4b-da01-4b81-9734-226069eb4cd0",
"jobTitle": "",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": {
"__typename": "FullName",
"firstName": "Test",
"lastName": "Test",
},
"noteTargets": [],
"phones": {
"primaryPhoneCallingCode": "+33",
"primaryPhoneCountryCode": "FR",
"primaryPhoneNumber": "781234562",
},
"position": 0,
"taskTargets": [],
"xLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
}
`;
exports[`useDeleteOneRecord B. Starting from filled cache 2. Should handle optimistic cache on record deletion 2`] = `
{
"__typename": "Company",
"accountOwner": null,
"address": {
"__typename": "Address",
"addressCity": "Dublin",
"addressCountry": "Ireland",
"addressLat": null,
"addressLng": null,
"addressPostcode": null,
"addressState": null,
"addressStreet1": "Eutaw Street",
"addressStreet2": null,
},
"createdAt": "2025-02-16T08:21:51.715Z",
"createdBy": {
"__typename": "Actor",
"context": {},
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"domainName": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "https://linkedin.com",
"secondaryLinks": [],
},
"employees": null,
"id": "20202020-3ec3-4fe3-8997-b76aa0bfa408",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": "Linkedin",
"noteTargets": [],
"opportunities": [
{},
],
"people": [
{
"__typename": "Person",
"city": "Seattle",
"createdAt": "2024-08-01T09:50:00.000Z",
"createdBy": {
"__typename": "Actor",
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"id": "20202020-1c0e-494c-a1b6-85b1c6fefaa5",
"jobTitle": "",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": {
"__typename": "FullName",
"firstName": "Christoph",
"lastName": "Callisto",
},
"phones": {
"primaryPhoneCallingCode": "+33",
"primaryPhoneCountryCode": "FR",
"primaryPhoneNumber": "781234562",
},
"position": 1,
"xLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
},
{
"__typename": "Person",
"city": "Los Angeles",
"createdAt": "2024-08-02T09:48:36.193Z",
"createdBy": {
"__typename": "Actor",
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"id": "20202020-ac73-4797-824e-87a1f5aea9e0",
"jobTitle": "",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": {
"__typename": "FullName",
"firstName": "Sylvie",
"lastName": "Palmer",
},
"phones": {
"primaryPhoneCallingCode": "+33",
"primaryPhoneCountryCode": "FR",
"primaryPhoneNumber": "781234576",
},
"position": 2,
"xLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
},
],
"position": 1,
"taskTargets": [],
}
`;
exports[`useDeleteOneRecord B. Starting from filled cache 3. Should handle optimistic cache rollback on record deletion failure 1`] = `
{
"__typename": "Person",
"city": "ASd",
"company": {
"__typename": "Company",
"address": {
"__typename": "Address",
"addressCity": "Dublin",
"addressCountry": "Ireland",
"addressLat": null,
"addressLng": null,
"addressPostcode": null,
"addressState": null,
"addressStreet1": "Eutaw Street",
"addressStreet2": null,
},
"createdAt": "2025-02-16T08:21:51.715Z",
"createdBy": {
"__typename": "Actor",
"context": {},
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"domainName": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "https://linkedin.com",
"secondaryLinks": [],
},
"employees": null,
"id": "20202020-3ec3-4fe3-8997-b76aa0bfa408",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": "Linkedin",
"position": 1,
},
"createdAt": "2024-08-02T09:52:46.814Z",
"createdBy": {
"__typename": "Actor",
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"id": "da3c2c4b-da01-4b81-9734-226069eb4cd0",
"jobTitle": "",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": {
"__typename": "FullName",
"firstName": "Test",
"lastName": "Test",
},
"noteTargets": [],
"phones": {
"primaryPhoneCallingCode": "+33",
"primaryPhoneCountryCode": "FR",
"primaryPhoneNumber": "781234562",
},
"position": 0,
"taskTargets": [],
"xLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
}
`;
exports[`useDeleteOneRecord B. Starting from filled cache 3. Should handle optimistic cache rollback on record deletion failure 2`] = `
{
"__typename": "Company",
"accountOwner": null,
"address": {
"__typename": "Address",
"addressCity": "Dublin",
"addressCountry": "Ireland",
"addressLat": null,
"addressLng": null,
"addressPostcode": null,
"addressState": null,
"addressStreet1": "Eutaw Street",
"addressStreet2": null,
},
"createdAt": "2025-02-16T08:21:51.715Z",
"createdBy": {
"__typename": "Actor",
"context": {},
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"domainName": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "https://linkedin.com",
"secondaryLinks": [],
},
"employees": null,
"id": "20202020-3ec3-4fe3-8997-b76aa0bfa408",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": "Linkedin",
"noteTargets": [],
"opportunities": [
{},
],
"people": [
{
"__typename": "Person",
"city": "Seattle",
"createdAt": "2024-08-01T09:50:00.000Z",
"createdBy": {
"__typename": "Actor",
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"id": "20202020-1c0e-494c-a1b6-85b1c6fefaa5",
"jobTitle": "",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": {
"__typename": "FullName",
"firstName": "Christoph",
"lastName": "Callisto",
},
"phones": {
"primaryPhoneCallingCode": "+33",
"primaryPhoneCountryCode": "FR",
"primaryPhoneNumber": "781234562",
},
"position": 1,
"xLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
},
{
"__typename": "Person",
"city": "Los Angeles",
"createdAt": "2024-08-02T09:48:36.193Z",
"createdBy": {
"__typename": "Actor",
"name": "Tim Apple",
"source": "MANUAL",
"workspaceMemberId": "20202020-0687-4c41-b707-ed1bfca972a7",
},
"deletedAt": null,
"id": "20202020-ac73-4797-824e-87a1f5aea9e0",
"jobTitle": "",
"linkedinLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
"name": {
"__typename": "FullName",
"firstName": "Sylvie",
"lastName": "Palmer",
},
"phones": {
"primaryPhoneCallingCode": "+33",
"primaryPhoneCountryCode": "FR",
"primaryPhoneNumber": "781234576",
},
"position": 2,
"xLink": {
"__typename": "Links",
"primaryLinkLabel": "",
"primaryLinkUrl": "",
"secondaryLinks": [],
},
},
],
"position": 1,
"taskTargets": [],
}
`;

View File

@ -17,7 +17,7 @@ import { InMemoryCache } from '@apollo/client';
import { MockedResponse } from '@apollo/client/testing';
import { act } from 'react';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
import { getPersonObjectMetadataItem } from '~/testing/mock-data/people';
import { getMockPersonObjectMetadataItem } from '~/testing/mock-data/people';
const getDefaultMocks = (
overrides?: Partial<MockedResponse>,
): MockedResponse[] => [
@ -40,7 +40,7 @@ const mockRefetchAggregateQueries = jest.fn();
(useRefetchAggregateQueries as jest.Mock).mockReturnValue({
refetchAggregateQueries: mockRefetchAggregateQueries,
});
const objectMetadataItem = getPersonObjectMetadataItem();
const objectMetadataItem = getMockPersonObjectMetadataItem();
const objectMetadataItems = [objectMetadataItem];
const expectedCachedRecordsWithDeletedAt = personRecords.map(
(personRecord) => ({

View File

@ -1,24 +1,24 @@
import { renderHook, waitFor } from '@testing-library/react';
import { act } from 'react';
import { getRecordFromCache } from '@/object-record/cache/utils/getRecordFromCache';
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphql/utils/computeDepthOneRecordGqlFieldsFromRecord';
import {
query,
responseData,
variables,
} from '@/object-record/hooks/__mocks__/useDeleteOneRecord';
import { query } from '@/object-record/hooks/__mocks__/useDeleteOneRecord';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { InMemoryCache } from '@apollo/client';
import { MockedResponse } from '@apollo/client/testing';
import { expect } from '@storybook/jest';
import { InMemoryTestingCacheInstance } from '~/testing/cache/inMemoryTestingCacheInstance';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
import { getMockCompanyObjectMetadataItem } from '~/testing/mock-data/companies';
import {
getPersonObjectMetadataItem,
getPersonRecord,
allMockCompanyRecordsWithRelation,
findMockCompanyWithRelationRecord,
} from '~/testing/mock-data/companiesWithRelations';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import {
allMockPersonRecords,
getMockPersonObjectMetadataItem,
getMockPersonRecord,
} from '~/testing/mock-data/people';
jest.mock('@/object-record/hooks/useRefetchAggregateQueries');
@ -27,64 +27,63 @@ const mockRefetchAggregateQueries = jest.fn();
refetchAggregateQueries: mockRefetchAggregateQueries,
});
// TODO Should test relation deletion cache hydratation
describe('useDeleteOneRecord', () => {
let cache: InMemoryCache;
const personRecord = getMockPersonRecord({
deletedAt: null,
});
const relatedCompanyRecord = findMockCompanyWithRelationRecord({
id: personRecord.company.id,
});
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
const companyObjectMetadataItem = getMockCompanyObjectMetadataItem();
const objectMetadataItems = generatedMockObjectMetadataItems;
const getDefaultMocks = (
overrides?: Partial<MockedResponse>,
): MockedResponse[] => [
{
): MockedResponse[] => {
const deleteOneQueryMock: MockedResponse<
Record<string, any>,
Record<'idToDelete', string>
> = {
request: {
variables: { idToDelete: personRecord.id },
query,
variables,
},
result: jest.fn(() => ({
result: jest.fn((variables) => ({
data: {
deletePerson: responseData,
deletePerson: {
__typename: 'Person',
deletedAt: '2024-02-14T09:45:00Z',
id: variables.idToDelete,
},
},
})),
...overrides,
},
];
const defaultMocks = getDefaultMocks();
const personRecord = getPersonRecord({
id: 'a7286b9a-c039-4a89-9567-2dfa7953cda9',
deletedAt: null,
});
const objectMetadataItem = getPersonObjectMetadataItem();
const objectMetadataItems = [objectMetadataItem];
const assertCachedRecordMatch = (expectedRecord: ObjectRecord) => {
const cachedRecord = getRecordFromCache({
cache,
objectMetadataItem,
objectMetadataItems,
recordId: personRecord.id,
});
expect(cachedRecord).not.toBeNull();
if (cachedRecord === null) throw new Error('Should never occur');
// Find a way to reverse assertion
expect(expectedRecord).toMatchObject(cachedRecord);
};
return [deleteOneQueryMock];
};
const assertCachedRecordIsNull = () =>
expect(
getRecordFromCache({
cache,
objectMetadataItem,
objectMetadataItems,
recordId: personRecord.id,
}),
).toBeNull();
const defaultMocks = getDefaultMocks();
beforeEach(() => {
jest.clearAllMocks();
cache = new InMemoryCache();
});
describe('A. Starting from empty cache', () => {
const {
cache,
assertCachedRecordIsNull,
assertCachedRecordMatchSnapshot,
restoreCacheToInitialState,
} = new InMemoryTestingCacheInstance({
objectMetadataItems,
});
beforeEach(async () => restoreCacheToInitialState());
it('1. Should successfully delete record and update record cache entry', async () => {
const { result } = renderHook(
() =>
useDeleteOneRecord({
objectNameSingular: objectMetadataItem.nameSingular,
objectNameSingular: personObjectMetadataItem.nameSingular,
}),
{
wrapper: getJestMetadataAndApolloMocksWrapper({
@ -98,13 +97,22 @@ describe('useDeleteOneRecord', () => {
const deleteOneResult = await result.current.deleteOneRecord(
personRecord.id,
);
const expectedResult: ObjectRecord = {
expect(deleteOneResult).toStrictEqual<ObjectRecord>({
__typename: personRecord.__typename,
deletedAt: expect.any(String),
id: personRecord.id,
};
expect(deleteOneResult).toStrictEqual(expectedResult);
assertCachedRecordMatch(expectedResult);
});
assertCachedRecordMatchSnapshot({
recordId: personRecord.id,
objectMetadataItem: personObjectMetadataItem,
matchObject: {
deletedAt: expect.any(String),
},
});
assertCachedRecordIsNull({
objectMetadataItem: companyObjectMetadataItem,
recordId: personRecord.company.id,
});
});
expect(defaultMocks[0].result).toHaveBeenCalled();
@ -115,10 +123,11 @@ describe('useDeleteOneRecord', () => {
const apolloMocks: MockedResponse[] = getDefaultMocks({
delay: Number.POSITIVE_INFINITY,
});
expect(personRecord).toHaveProperty('company');
const { result } = renderHook(
() =>
useDeleteOneRecord({
objectNameSingular: objectMetadataItem.nameSingular,
objectNameSingular: personObjectMetadataItem.nameSingular,
}),
{
wrapper: getJestMetadataAndApolloMocksWrapper({
@ -131,7 +140,14 @@ describe('useDeleteOneRecord', () => {
await act(async () => {
result.current.deleteOneRecord(personRecord.id);
await waitFor(() => {
assertCachedRecordIsNull();
assertCachedRecordIsNull({
recordId: personRecord.id,
objectMetadataItem: personObjectMetadataItem,
});
assertCachedRecordIsNull({
recordId: personRecord.company.id,
objectMetadataItem: companyObjectMetadataItem,
});
});
});
@ -146,7 +162,7 @@ describe('useDeleteOneRecord', () => {
const { result } = renderHook(
() =>
useDeleteOneRecord({
objectNameSingular: objectMetadataItem.nameSingular,
objectNameSingular: personObjectMetadataItem.nameSingular,
}),
{
wrapper: getJestMetadataAndApolloMocksWrapper({
@ -161,32 +177,47 @@ describe('useDeleteOneRecord', () => {
await result.current.deleteOneRecord(personRecord.id);
fail('Should have thrown an error');
} catch (e) {
assertCachedRecordIsNull();
assertCachedRecordIsNull({
recordId: personRecord.id,
objectMetadataItem: personObjectMetadataItem,
});
assertCachedRecordIsNull({
recordId: relatedCompanyRecord.id,
objectMetadataItem: companyObjectMetadataItem,
});
}
});
});
});
describe('B. Starting from filled cache', () => {
const {
assertCachedRecordMatchSnapshot,
cache,
restoreCacheToInitialState,
} = new InMemoryTestingCacheInstance({
objectMetadataItems,
initialRecordsInCache: [
{
objectMetadataItem: companyObjectMetadataItem,
records: allMockCompanyRecordsWithRelation,
},
{
objectMetadataItem: personObjectMetadataItem,
records: allMockPersonRecords,
},
],
});
beforeEach(() => {
const recordGqlFields = computeDepthOneRecordGqlFieldsFromRecord({
objectMetadataItem,
record: personRecord,
});
updateRecordFromCache({
cache,
objectMetadataItem,
objectMetadataItems,
record: personRecord,
recordGqlFields,
});
restoreCacheToInitialState();
});
it('1. Should handle successfull record deletion', async () => {
const { result } = renderHook(
() =>
useDeleteOneRecord({
objectNameSingular: objectMetadataItem.nameSingular,
objectNameSingular: personObjectMetadataItem.nameSingular,
}),
{
wrapper: getJestMetadataAndApolloMocksWrapper({
@ -198,15 +229,23 @@ describe('useDeleteOneRecord', () => {
await act(async () => {
const res = await result.current.deleteOneRecord(personRecord.id);
expect(res).toBeDefined();
expect(res.deletedAt).toBeDefined();
expect(res).toHaveProperty('id', personRecord.id);
const personRecordWithDeletedAt = {
...personRecord,
expect(res).toMatchObject<ObjectRecord>({
__typename: 'Person',
id: personRecord.id,
deletedAt: expect.any(String),
};
assertCachedRecordMatch(personRecordWithDeletedAt);
});
assertCachedRecordMatchSnapshot({
recordId: personRecord.id,
objectMetadataItem: personObjectMetadataItem,
matchObject: {
deletedAt: expect.any(String),
},
});
assertCachedRecordMatchSnapshot({
objectMetadataItem: companyObjectMetadataItem,
recordId: personRecord.company.id,
});
});
expect(defaultMocks[0].result).toHaveBeenCalled();
@ -221,7 +260,7 @@ describe('useDeleteOneRecord', () => {
const { result } = renderHook(
() =>
useDeleteOneRecord({
objectNameSingular: objectMetadataItem.nameSingular,
objectNameSingular: personObjectMetadataItem.nameSingular,
}),
{
wrapper: getJestMetadataAndApolloMocksWrapper({
@ -234,11 +273,21 @@ describe('useDeleteOneRecord', () => {
await act(async () => {
result.current.deleteOneRecord(personRecord.id);
await waitFor(() => {
const personRecordWithDeletedAt = {
...personRecord,
deletedAt: expect.any(String),
};
assertCachedRecordMatch(personRecordWithDeletedAt);
assertCachedRecordMatchSnapshot({
recordId: personRecord.id,
objectMetadataItem: personObjectMetadataItem,
snapshotPropertyMatchers: {
// Request is paused then the cached get filled with optmistic deletedAt
deletedAt: expect.any(String),
},
matchObject: {
deletedAt: expect.any(String),
},
});
assertCachedRecordMatchSnapshot({
objectMetadataItem: companyObjectMetadataItem,
recordId: personRecord.company.id,
});
});
});
@ -253,7 +302,7 @@ describe('useDeleteOneRecord', () => {
const { result } = renderHook(
() =>
useDeleteOneRecord({
objectNameSingular: objectMetadataItem.nameSingular,
objectNameSingular: personObjectMetadataItem.nameSingular,
}),
{
wrapper: getJestMetadataAndApolloMocksWrapper({
@ -268,11 +317,17 @@ describe('useDeleteOneRecord', () => {
await result.current.deleteOneRecord(personRecord.id);
fail('Should have thrown an error');
} catch (e) {
const personRecordWithDeletedAt = {
...personRecord,
deletedAt: null,
};
assertCachedRecordMatch(personRecordWithDeletedAt);
assertCachedRecordMatchSnapshot({
recordId: personRecord.id,
objectMetadataItem: personObjectMetadataItem,
matchObject: {
deletedAt: null,
},
});
assertCachedRecordMatchSnapshot({
objectMetadataItem: companyObjectMetadataItem,
recordId: personRecord.company.id,
});
}
});

View File

@ -9,7 +9,8 @@ import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewCompon
import { MockedResponse } from '@apollo/client/testing';
import gql from 'graphql-tag';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
import { getPeopleMock } from '~/testing/mock-data/people';
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
const recordTableId = 'people';
const objectNameSingular = 'person';
const onColumnsChange = jest.fn();
@ -422,7 +423,7 @@ const mocks: MockedResponse[] = [
},
result: jest.fn(() => ({
data: {
people: getPeopleMock(),
people: getPeopleRecordConnectionMock(),
},
})),
},

View File

@ -7,21 +7,21 @@ import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/Componen
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { graphqlMocks } from '~/testing/graphqlMocks';
import { getPeopleMock } from '~/testing/mock-data/people';
import { allMockPersonRecords } from '~/testing/mock-data/people';
import { sleep } from '~/utils/sleep';
import { SingleRecordPicker } from '@/object-record/record-picker/components/SingleRecordPicker';
import { SingleRecordPickerRecord } from '../../types/SingleRecordPickerRecord';
const peopleMock = getPeopleMock();
const records = peopleMock.map<SingleRecordPickerRecord>((person) => ({
id: person.id,
name: person.name.firstName + ' ' + person.name.lastName,
avatarUrl: 'https://picsum.photos/200',
avatarType: 'rounded',
record: { ...person, __typename: 'Person' },
}));
const records = allMockPersonRecords.map<SingleRecordPickerRecord>(
(person) => ({
id: person.id,
name: person.name.firstName + ' ' + person.name.lastName,
avatarUrl: 'https://picsum.photos/200',
avatarType: 'rounded',
record: { ...person, __typename: 'Person' },
}),
);
const meta: Meta<typeof SingleRecordPicker> = {
title: 'UI/RecordPicker/SingleRecordPicker',

View File

@ -9,16 +9,14 @@ import { RecordStoreDecorator } from '~/testing/decorators/RecordStoreDecorator'
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { graphqlMocks } from '~/testing/graphqlMocks';
import { getCompaniesMock } from '~/testing/mock-data/companies';
import { getPeopleMock } from '~/testing/mock-data/people';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { allMockPersonRecords } from '~/testing/mock-data/people';
import { RecordDetailRelationSection } from '../RecordDetailRelationSection';
const companiesMock = getCompaniesMock();
const peopleMock = getPeopleMock();
const mockedCompanyObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'company',
);
@ -72,9 +70,9 @@ export const WithRecords: Story = {
records: [
{
...companiesMock[0],
people: peopleMock,
people: allMockPersonRecords,
},
...peopleMock,
...allMockPersonRecords,
],
},
};

View File

@ -4,9 +4,9 @@ import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphq
import { FieldActorForInputValue } from '@/object-record/record-field/types/FieldMetadata';
import { computeOptimisticRecordFromInput } from '@/object-record/utils/computeOptimisticRecordFromInput';
import { InMemoryCache } from '@apollo/client';
import { getCompanyObjectMetadataItem } from '~/testing/mock-data/companies';
import { getMockCompanyObjectMetadataItem } from '~/testing/mock-data/companies';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { getPersonObjectMetadataItem } from '~/testing/mock-data/people';
import { getMockPersonObjectMetadataItem } from '~/testing/mock-data/people';
import { mockCurrentWorkspaceMembers } from '~/testing/mock-data/workspace-members';
describe('computeOptimisticRecordFromInput', () => {
@ -14,7 +14,7 @@ describe('computeOptimisticRecordFromInput', () => {
const currentWorkspaceMemberFullname = `${currentWorkspaceMember.name.firstName} ${currentWorkspaceMember.name.lastName}`;
it('should generate correct optimistic record if no relation field is present', () => {
const cache = new InMemoryCache();
const personObjectMetadataItem = getPersonObjectMetadataItem();
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
const result = computeOptimisticRecordFromInput({
currentWorkspaceMember,
@ -33,7 +33,7 @@ describe('computeOptimisticRecordFromInput', () => {
it('should generate correct optimistic record with actor field', () => {
const cache = new InMemoryCache();
const personObjectMetadataItem = getPersonObjectMetadataItem();
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
const actorFieldValueForInput: FieldActorForInputValue = {
context: {},
source: 'API',
@ -62,7 +62,7 @@ describe('computeOptimisticRecordFromInput', () => {
it('should generate correct optimistic record createdBy when recordInput contains id', () => {
const cache = new InMemoryCache();
const personObjectMetadataItem = getPersonObjectMetadataItem();
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
const result = computeOptimisticRecordFromInput({
currentWorkspaceMember,
objectMetadataItems: generatedMockObjectMetadataItems,
@ -90,7 +90,7 @@ describe('computeOptimisticRecordFromInput', () => {
it('should generate correct optimistic record if relation field is present but cache is empty', () => {
const cache = new InMemoryCache();
const personObjectMetadataItem = getPersonObjectMetadataItem();
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
const result = computeOptimisticRecordFromInput({
currentWorkspaceMember,
@ -109,8 +109,8 @@ describe('computeOptimisticRecordFromInput', () => {
it('should generate correct optimistic record even if recordInput contains field __typename', () => {
const cache = new InMemoryCache();
const personObjectMetadataItem = getPersonObjectMetadataItem();
const companyObjectMetadataItem = getCompanyObjectMetadataItem();
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
const companyObjectMetadataItem = getMockCompanyObjectMetadataItem();
const companyRecord = {
id: '123',
@ -154,8 +154,8 @@ describe('computeOptimisticRecordFromInput', () => {
it('should generate correct optimistic record if relation field is present and cache is not empty', () => {
const cache = new InMemoryCache();
const personObjectMetadataItem = getPersonObjectMetadataItem();
const companyObjectMetadataItem = getCompanyObjectMetadataItem();
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
const companyObjectMetadataItem = getMockCompanyObjectMetadataItem();
const companyRecord = {
id: '123',
@ -198,7 +198,7 @@ describe('computeOptimisticRecordFromInput', () => {
it('should generate correct optimistic record if relation field is null and cache is empty', () => {
const cache = new InMemoryCache();
const personObjectMetadataItem = getPersonObjectMetadataItem();
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
const result = computeOptimisticRecordFromInput({
currentWorkspaceMember,
@ -218,7 +218,7 @@ describe('computeOptimisticRecordFromInput', () => {
it('should throw an error if recordInput contains fields unrelated to the current objectMetadata', () => {
const cache = new InMemoryCache();
const personObjectMetadataItem = getPersonObjectMetadataItem();
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
expect(() =>
computeOptimisticRecordFromInput({
@ -240,7 +240,7 @@ describe('computeOptimisticRecordFromInput', () => {
it('should throw an error if recordInput contains both the relationFieldId and relationField', () => {
const cache = new InMemoryCache();
const personObjectMetadataItem = getPersonObjectMetadataItem();
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
expect(() =>
computeOptimisticRecordFromInput({
@ -260,7 +260,7 @@ describe('computeOptimisticRecordFromInput', () => {
it('should throw an error if recordInput contains both the relationFieldId and relationField even if null', () => {
const cache = new InMemoryCache();
const personObjectMetadataItem = getPersonObjectMetadataItem();
const personObjectMetadataItem = getMockPersonObjectMetadataItem();
expect(() =>
computeOptimisticRecordFromInput({

View File

@ -6,11 +6,11 @@ import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadat
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { WorkflowStepActionDrawerDecorator } from '~/testing/decorators/WorkflowStepActionDrawerDecorator';
import { WorkflowStepDecorator } from '~/testing/decorators/WorkflowStepDecorator';
import { WorkspaceDecorator } from '~/testing/decorators/WorkspaceDecorator';
import { graphqlMocks } from '~/testing/graphqlMocks';
import { getPeopleMock } from '~/testing/mock-data/people';
import { allMockPersonRecords } from '~/testing/mock-data/people';
import { getWorkflowNodeIdMock } from '~/testing/mock-data/workflow';
import { WorkflowEditActionFormDeleteRecord } from '../WorkflowEditActionFormDeleteRecord';
import { WorkspaceDecorator } from '~/testing/decorators/WorkspaceDecorator';
const DEFAULT_ACTION = {
id: getWorkflowNodeIdMock(),
@ -100,7 +100,7 @@ export const DisabledWithEmptyValues: Story = {
},
};
const peopleMock = getPeopleMock()[0];
const peopleMock = allMockPersonRecords[0];
export const DisabledWithDefaultStaticValues: Story = {
args: {

View File

@ -6,11 +6,11 @@ import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadat
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { WorkflowStepActionDrawerDecorator } from '~/testing/decorators/WorkflowStepActionDrawerDecorator';
import { WorkflowStepDecorator } from '~/testing/decorators/WorkflowStepDecorator';
import { WorkspaceDecorator } from '~/testing/decorators/WorkspaceDecorator';
import { graphqlMocks } from '~/testing/graphqlMocks';
import { getPeopleMock } from '~/testing/mock-data/people';
import { allMockPersonRecords } from '~/testing/mock-data/people';
import { getWorkflowNodeIdMock } from '~/testing/mock-data/workflow';
import { WorkflowEditActionFormUpdateRecord } from '../WorkflowEditActionFormUpdateRecord';
import { WorkspaceDecorator } from '~/testing/decorators/WorkspaceDecorator';
const DEFAULT_ACTION = {
id: getWorkflowNodeIdMock(),
@ -128,7 +128,7 @@ export const DisabledWithEmptyValues: Story = {
},
};
const peopleMock = getPeopleMock()[0];
const peopleMock = allMockPersonRecords[0];
export const DisabledWithDefaultStaticValues: Story = {
args: {