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