TWNTY-3480 - Add tests for modules/object-record/relation-picker/hooks (#3547)
Add tests for `modules/object-record/relation-picker/hooks` Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com> Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: RubensRafael <rubensrafael2@live.com>
This commit is contained in:
committed by
GitHub
parent
1bb7ff3730
commit
8d206fd2c8
@ -0,0 +1,29 @@
|
|||||||
|
import { ChangeEvent } from 'react';
|
||||||
|
import { act, renderHook } from '@testing-library/react';
|
||||||
|
import { RecoilRoot } from 'recoil';
|
||||||
|
|
||||||
|
import { useEntitySelectSearch } from '@/object-record/relation-picker/hooks/useEntitySelectSearch';
|
||||||
|
import { RelationPickerScopeInternalContext } from '@/object-record/relation-picker/scopes/scope-internal-context/RelationPickerScopeInternalContext';
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<RelationPickerScopeInternalContext.Provider value={{ scopeId }}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</RelationPickerScopeInternalContext.Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('useEntitySelectSearch', () => {
|
||||||
|
it('should update searchFilter after change event', async () => {
|
||||||
|
const { result } = renderHook(() => useEntitySelectSearch(), {
|
||||||
|
wrapper: Wrapper,
|
||||||
|
});
|
||||||
|
const filter = 'value';
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.handleSearchFilterChange({
|
||||||
|
currentTarget: { value: filter },
|
||||||
|
} as ChangeEvent<HTMLInputElement>);
|
||||||
|
});
|
||||||
|
expect(result.current.searchFilter).toBe(filter);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
import { renderHook } from '@testing-library/react';
|
||||||
|
import { RecoilRoot } from 'recoil';
|
||||||
|
|
||||||
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { useLimitPerMetadataItem } from '@/object-record/relation-picker/hooks/useLimitPerMetadataItem';
|
||||||
|
import { RelationPickerScopeInternalContext } from '@/object-record/relation-picker/scopes/scope-internal-context/RelationPickerScopeInternalContext';
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<RelationPickerScopeInternalContext.Provider value={{ scopeId }}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</RelationPickerScopeInternalContext.Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('useLimitPerMetadataItem', () => {
|
||||||
|
const objectData: ObjectMetadataItem[] = [
|
||||||
|
{
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
id: 'id',
|
||||||
|
isActive: true,
|
||||||
|
isCustom: true,
|
||||||
|
isSystem: true,
|
||||||
|
labelPlural: 'labelPlural',
|
||||||
|
labelSingular: 'labelSingular',
|
||||||
|
namePlural: 'namePlural',
|
||||||
|
nameSingular: 'nameSingular',
|
||||||
|
updatedAt: 'updatedAt',
|
||||||
|
fields: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
it('should return object with nameSingular and default limit', async () => {
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => useLimitPerMetadataItem({ objectMetadataItems: objectData }),
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current.limitPerMetadataItem).toStrictEqual({
|
||||||
|
limitNameSingular: 60,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an object with nameSingular and specified limit', async () => {
|
||||||
|
const { result } = renderHook(
|
||||||
|
() =>
|
||||||
|
useLimitPerMetadataItem({ objectMetadataItems: objectData, limit: 30 }),
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current.limitPerMetadataItem).toStrictEqual({
|
||||||
|
limitNameSingular: 30,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
import { act, renderHook } from '@testing-library/react';
|
||||||
|
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
|
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||||
|
import { useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray } from '@/object-record/relation-picker/hooks/useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray';
|
||||||
|
import { RelationPickerScopeInternalContext } from '@/object-record/relation-picker/scopes/scope-internal-context/RelationPickerScopeInternalContext';
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<RelationPickerScopeInternalContext.Provider value={{ scopeId }}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</RelationPickerScopeInternalContext.Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
const objectMetadataItemsMock = getObjectMetadataItemsMock();
|
||||||
|
|
||||||
|
const opportunityId = 'cb702502-4b1d-488e-9461-df3fb096ebf6';
|
||||||
|
const personId = 'ab091fd9-1b81-4dfd-bfdb-564ffee032a2';
|
||||||
|
|
||||||
|
describe('useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray', () => {
|
||||||
|
it('should return object formatted from objectMetadataItemsState', async () => {
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
formattedRecord:
|
||||||
|
useMultiObjectRecordsQueryResultFormattedAsObjectRecordForSelectArray(
|
||||||
|
{
|
||||||
|
multiObjectRecordsQueryResult: {
|
||||||
|
opportunities: {
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
node: {
|
||||||
|
id: opportunityId,
|
||||||
|
pointOfContactId:
|
||||||
|
'e992bda7-d797-4e12-af04-9b427f42244c',
|
||||||
|
updatedAt: '2023-11-30T11:13:15.308Z',
|
||||||
|
createdAt: '2023-11-30T11:13:15.308Z',
|
||||||
|
},
|
||||||
|
cursor: 'cursor',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
pageInfo: {},
|
||||||
|
},
|
||||||
|
people: {
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
node: {
|
||||||
|
id: personId,
|
||||||
|
updatedAt: '2023-11-30T11:13:15.308Z',
|
||||||
|
createdAt: '2023-11-30T11:13:15.308Z',
|
||||||
|
},
|
||||||
|
cursor: 'cursor',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
pageInfo: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
setObjectMetadata: useSetRecoilState(objectMetadataItemsState),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
act(() => {
|
||||||
|
result.current.setObjectMetadata(objectMetadataItemsMock);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
result.current.formattedRecord.objectRecordForSelectArray.length,
|
||||||
|
).toBe(2);
|
||||||
|
|
||||||
|
const [opportunityRecordForSelect, personRecordForSelect] =
|
||||||
|
result.current.formattedRecord.objectRecordForSelectArray;
|
||||||
|
|
||||||
|
expect(opportunityRecordForSelect.objectMetadataItem.namePlural).toBe(
|
||||||
|
'opportunities',
|
||||||
|
);
|
||||||
|
expect(opportunityRecordForSelect.record.id).toBe(opportunityId);
|
||||||
|
expect(opportunityRecordForSelect.recordIdentifier.linkToShowPage).toBe(
|
||||||
|
`/opportunities/${opportunityId}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(personRecordForSelect.objectMetadataItem.namePlural).toBe('people');
|
||||||
|
expect(personRecordForSelect.record.id).toBe(personId);
|
||||||
|
expect(personRecordForSelect.recordIdentifier.linkToShowPage).toBe(
|
||||||
|
`/object/person/${personId}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,169 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||||
|
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { useMultiObjectSearch } from '@/object-record/relation-picker/hooks/useMultiObjectSearch';
|
||||||
|
|
||||||
|
const query = gql`
|
||||||
|
query FindManyRecordsMultipleMetadataItems(
|
||||||
|
$filterNameSingular: NameSingularFilterInput
|
||||||
|
$orderByNameSingular: NameSingularOrderByInput
|
||||||
|
$lastCursorNameSingular: String
|
||||||
|
$limitNameSingular: Float = 5
|
||||||
|
) {
|
||||||
|
namePlural(
|
||||||
|
filter: $filterNameSingular
|
||||||
|
orderBy: $orderByNameSingular
|
||||||
|
first: $limitNameSingular
|
||||||
|
after: $lastCursorNameSingular
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
cursor
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
hasNextPage
|
||||||
|
startCursor
|
||||||
|
endCursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const response = {
|
||||||
|
namePlural: {
|
||||||
|
edges: [{ node: { id: 'nodeId' }, cursor: 'cursor' }],
|
||||||
|
pageInfo: { startCursor: '', hasNextPage: '', endCursor: '' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const mocks = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query,
|
||||||
|
variables: {
|
||||||
|
filterNameSingular: { and: [{}, { id: { in: ['1'] } }] },
|
||||||
|
orderByNameSingular: { createdAt: 'DescNullsLast' },
|
||||||
|
limitNameSingular: 60,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: jest.fn(() => ({
|
||||||
|
data: response,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query,
|
||||||
|
variables: {
|
||||||
|
filterNameSingular: { id: { in: ['1'] } },
|
||||||
|
orderByNameSingular: { createdAt: 'DescNullsLast' },
|
||||||
|
limitNameSingular: 60,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: jest.fn(() => ({
|
||||||
|
data: response,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query,
|
||||||
|
variables: {
|
||||||
|
limitNameSingular: 60,
|
||||||
|
filterNameSingular: { and: [{}, { not: { id: { in: ['1'] } } }] },
|
||||||
|
orderByNameSingular: { createdAt: 'DescNullsLast' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: jest.fn(() => ({
|
||||||
|
data: response,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<MockedProvider mocks={mocks} addTypename={false}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('useMultiObjectSearch', () => {
|
||||||
|
it('should return object formatted from objectMetadataItemsState', async () => {
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => ({
|
||||||
|
multiObjects: useMultiObjectSearch({
|
||||||
|
searchFilterValue: '',
|
||||||
|
selectedObjectRecordIds: [
|
||||||
|
{
|
||||||
|
objectNameSingular: 'nameSingular',
|
||||||
|
id: '1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
setObjectMetadata: useSetRecoilState(objectMetadataItemsState),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const objectData: ObjectMetadataItem[] = [
|
||||||
|
{
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
id: 'id',
|
||||||
|
isActive: true,
|
||||||
|
isCustom: true,
|
||||||
|
isSystem: false,
|
||||||
|
labelPlural: 'labelPlural',
|
||||||
|
labelSingular: 'labelSingular',
|
||||||
|
namePlural: 'namePlural',
|
||||||
|
nameSingular: 'nameSingular',
|
||||||
|
updatedAt: 'updatedAt',
|
||||||
|
fields: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
act(() => {
|
||||||
|
result.current.setObjectMetadata(objectData);
|
||||||
|
});
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mocks[0].result).toHaveBeenCalled();
|
||||||
|
expect(mocks[1].result).toHaveBeenCalled();
|
||||||
|
expect(mocks[2].result).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
const expectedData = [
|
||||||
|
{
|
||||||
|
objectMetadataItem: {
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
id: 'id',
|
||||||
|
isActive: true,
|
||||||
|
isCustom: true,
|
||||||
|
isSystem: false,
|
||||||
|
labelPlural: 'labelPlural',
|
||||||
|
labelSingular: 'labelSingular',
|
||||||
|
namePlural: 'namePlural',
|
||||||
|
nameSingular: 'nameSingular',
|
||||||
|
updatedAt: 'updatedAt',
|
||||||
|
fields: [],
|
||||||
|
},
|
||||||
|
record: { id: 'nodeId' },
|
||||||
|
recordIdentifier: {
|
||||||
|
id: 'nodeId',
|
||||||
|
name: '',
|
||||||
|
avatarUrl: '',
|
||||||
|
avatarType: 'rounded',
|
||||||
|
linkToShowPage: '/object/nameSingular/nodeId',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
expect(result.current.multiObjects.selectedObjectRecords).toStrictEqual(
|
||||||
|
expectedData,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
result.current.multiObjects.filteredSelectedObjectRecords,
|
||||||
|
).toStrictEqual(expectedData);
|
||||||
|
expect(result.current.multiObjects.objectRecordsToSelect).toStrictEqual(
|
||||||
|
expectedData,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user