fix: detach relation records in cache on record deletion (#3707)
* fix: detach relation records in cache on record deletion * fix: fix useGetRelationMetadata tests
This commit is contained in:
@ -0,0 +1,70 @@
|
||||
import { ReactNode, useEffect } from 'react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMetadata';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||
|
||||
import { TestApolloMetadataClientProvider } from '../__mocks__/ApolloMetadataClientProvider';
|
||||
|
||||
const Wrapper = ({ children }: { children: ReactNode }) => (
|
||||
<RecoilRoot>
|
||||
<MockedProvider addTypename={false}>
|
||||
<TestApolloMetadataClientProvider>
|
||||
{children}
|
||||
</TestApolloMetadataClientProvider>
|
||||
</MockedProvider>
|
||||
</RecoilRoot>
|
||||
);
|
||||
|
||||
describe('useGetRelationMetadata', () => {
|
||||
it('should return correct properties', async () => {
|
||||
const objectMetadataItems = getObjectMetadataItemsMock();
|
||||
const objectMetadata = objectMetadataItems.find(
|
||||
(item) => item.nameSingular === 'person',
|
||||
)!;
|
||||
const fieldMetadataItem = objectMetadata.fields.find(
|
||||
(field) => field.name === 'opportunities',
|
||||
)!;
|
||||
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
|
||||
|
||||
useEffect(() => {
|
||||
setMetadataItems(objectMetadataItems);
|
||||
}, [setMetadataItems]);
|
||||
|
||||
return useGetRelationMetadata();
|
||||
},
|
||||
{
|
||||
wrapper: Wrapper,
|
||||
initialProps: {},
|
||||
},
|
||||
);
|
||||
|
||||
const {
|
||||
relationFieldMetadataItem,
|
||||
relationObjectMetadataItem,
|
||||
relationType,
|
||||
} = result.current({ fieldMetadataItem }) ?? {};
|
||||
|
||||
const expectedRelationObjectMetadataItem = objectMetadataItems.find(
|
||||
(item) => item.nameSingular === 'opportunity',
|
||||
);
|
||||
const expectedRelationFieldMetadataItem =
|
||||
expectedRelationObjectMetadataItem?.fields.find(
|
||||
(field) => field.name === 'person',
|
||||
);
|
||||
|
||||
expect(relationObjectMetadataItem).toEqual(
|
||||
expectedRelationObjectMetadataItem,
|
||||
);
|
||||
expect(relationFieldMetadataItem).toEqual(
|
||||
expectedRelationFieldMetadataItem,
|
||||
);
|
||||
expect(relationType).toBe('ONE_TO_MANY');
|
||||
});
|
||||
});
|
||||
@ -1,55 +0,0 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { useRelationMetadata } from '@/object-metadata/hooks/useRelationMetadata';
|
||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||
|
||||
import { TestApolloMetadataClientProvider } from '../__mocks__/ApolloMetadataClientProvider';
|
||||
|
||||
const Wrapper = ({ children }: { children: ReactNode }) => (
|
||||
<RecoilRoot>
|
||||
<MockedProvider addTypename={false}>
|
||||
<TestApolloMetadataClientProvider>
|
||||
{children}
|
||||
</TestApolloMetadataClientProvider>
|
||||
</MockedProvider>
|
||||
</RecoilRoot>
|
||||
);
|
||||
|
||||
describe('useRelationMetadata', () => {
|
||||
it('should return correct properties', async () => {
|
||||
const { result, rerender } = renderHook(
|
||||
({ fieldMetadataItem }: { fieldMetadataItem?: FieldMetadataItem }) =>
|
||||
useRelationMetadata({ fieldMetadataItem }),
|
||||
{
|
||||
wrapper: Wrapper,
|
||||
initialProps: {},
|
||||
},
|
||||
);
|
||||
|
||||
const {
|
||||
relationFieldMetadataItem,
|
||||
relationObjectMetadataItem,
|
||||
relationType,
|
||||
} = result.current;
|
||||
|
||||
expect(relationFieldMetadataItem).toBeUndefined();
|
||||
expect(relationObjectMetadataItem).toBeUndefined();
|
||||
expect(relationType).toBeUndefined();
|
||||
|
||||
const objectMetadataItems = getObjectMetadataItemsMock();
|
||||
const objectMetadata = objectMetadataItems.find(
|
||||
(item) => item.nameSingular === 'person',
|
||||
)!;
|
||||
const fieldMetadataItem = objectMetadata.fields.find(
|
||||
(field) => field.name === 'opportunities',
|
||||
)!;
|
||||
|
||||
rerender({ fieldMetadataItem });
|
||||
|
||||
expect(result.current.relationType).toBe('ONE_TO_MANY');
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,67 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector';
|
||||
import { RelationType } from '@/settings/data-model/types/RelationType';
|
||||
import {
|
||||
FieldMetadataType,
|
||||
RelationMetadataType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||
|
||||
export const useGetRelationMetadata = () =>
|
||||
useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
({ fieldMetadataItem }: { fieldMetadataItem: FieldMetadataItem }) => {
|
||||
if (fieldMetadataItem.type !== FieldMetadataType.Relation) return null;
|
||||
|
||||
const relationMetadata =
|
||||
fieldMetadataItem.fromRelationMetadata ||
|
||||
fieldMetadataItem.toRelationMetadata;
|
||||
|
||||
if (!relationMetadata) return null;
|
||||
|
||||
const relationFieldMetadataId =
|
||||
'toFieldMetadataId' in relationMetadata
|
||||
? relationMetadata.toFieldMetadataId
|
||||
: relationMetadata.fromFieldMetadataId;
|
||||
|
||||
if (!relationFieldMetadataId) return null;
|
||||
|
||||
const relationType =
|
||||
relationMetadata.relationType === RelationMetadataType.OneToMany &&
|
||||
fieldMetadataItem.toRelationMetadata
|
||||
? 'MANY_TO_ONE'
|
||||
: (relationMetadata.relationType as RelationType);
|
||||
|
||||
const relationObjectMetadataNameSingular =
|
||||
'toObjectMetadata' in relationMetadata
|
||||
? relationMetadata.toObjectMetadata.nameSingular
|
||||
: relationMetadata.fromObjectMetadata.nameSingular;
|
||||
|
||||
const relationObjectMetadataItem = snapshot
|
||||
.getLoadable(
|
||||
objectMetadataItemFamilySelector({
|
||||
objectName: relationObjectMetadataNameSingular,
|
||||
objectNameType: 'singular',
|
||||
}),
|
||||
)
|
||||
.valueOrThrow();
|
||||
|
||||
if (!relationObjectMetadataItem) return null;
|
||||
|
||||
const relationFieldMetadataItem =
|
||||
relationObjectMetadataItem.fields.find(
|
||||
(field) => field.id === relationFieldMetadataId,
|
||||
);
|
||||
|
||||
if (!relationFieldMetadataItem) return null;
|
||||
|
||||
return {
|
||||
relationFieldMetadataItem,
|
||||
relationObjectMetadataItem,
|
||||
relationType,
|
||||
};
|
||||
},
|
||||
[],
|
||||
);
|
||||
@ -1,49 +0,0 @@
|
||||
import { RelationType } from '@/settings/data-model/types/RelationType';
|
||||
import { RelationMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
import { useObjectMetadataItemForSettings } from '../hooks/useObjectMetadataItemForSettings';
|
||||
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||
|
||||
export const useRelationMetadata = ({
|
||||
fieldMetadataItem,
|
||||
}: {
|
||||
fieldMetadataItem?: FieldMetadataItem;
|
||||
}) => {
|
||||
const { findObjectMetadataItemById } = useObjectMetadataItemForSettings();
|
||||
|
||||
const relationMetadata =
|
||||
fieldMetadataItem?.fromRelationMetadata ||
|
||||
fieldMetadataItem?.toRelationMetadata;
|
||||
|
||||
const relationType =
|
||||
relationMetadata?.relationType === RelationMetadataType.OneToMany &&
|
||||
fieldMetadataItem?.toRelationMetadata
|
||||
? 'MANY_TO_ONE'
|
||||
: (relationMetadata?.relationType as RelationType | undefined);
|
||||
|
||||
const relationObjectMetadataId =
|
||||
relationMetadata && 'toObjectMetadata' in relationMetadata
|
||||
? relationMetadata.toObjectMetadata.id
|
||||
: relationMetadata?.fromObjectMetadata.id;
|
||||
|
||||
const relationObjectMetadataItem = relationObjectMetadataId
|
||||
? findObjectMetadataItemById(relationObjectMetadataId)
|
||||
: undefined;
|
||||
|
||||
const relationFieldMetadataId =
|
||||
relationMetadata && 'toFieldMetadataId' in relationMetadata
|
||||
? relationMetadata.toFieldMetadataId
|
||||
: relationMetadata?.fromFieldMetadataId;
|
||||
|
||||
const relationFieldMetadataItem = relationFieldMetadataId
|
||||
? relationObjectMetadataItem?.fields?.find(
|
||||
(field) => field.id === relationFieldMetadataId,
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
relationFieldMetadataItem,
|
||||
relationObjectMetadataItem,
|
||||
relationType,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user