Add tests for modules/object-record/record-board (#3421)
* Add tests for `modules/object-record/record-board` Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: RubensRafael <rubensrafael2@live.com> * Revert unwanted changes Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: RubensRafael <rubensrafael2@live.com> --------- 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:
@ -0,0 +1,88 @@
|
|||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||||
|
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { useRecordBoardScopedStates } from '@/object-record/record-board/hooks/internal/useRecordBoardScopedStates';
|
||||||
|
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
||||||
|
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<MockedProvider>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordBoardScopeId = 'recordBoardScopeId';
|
||||||
|
|
||||||
|
const renderHookConfig = {
|
||||||
|
wrapper: Wrapper,
|
||||||
|
};
|
||||||
|
|
||||||
|
const useRecordBoardHook = () => {
|
||||||
|
const recordBoard = useRecordBoard({ recordBoardScopeId });
|
||||||
|
const { isBoardLoadedState, boardColumnsState, onFieldsChangeState } =
|
||||||
|
useRecordBoardScopedStates({
|
||||||
|
recordBoardScopeId: recordBoardScopeId,
|
||||||
|
});
|
||||||
|
const isBoardLoaded = useRecoilValue(isBoardLoadedState);
|
||||||
|
const boardColumns = useRecoilValue(boardColumnsState);
|
||||||
|
const onFieldsChange = useRecoilValue(onFieldsChangeState);
|
||||||
|
|
||||||
|
return {
|
||||||
|
recordBoard,
|
||||||
|
isBoardLoaded,
|
||||||
|
boardColumns,
|
||||||
|
onFieldsChange,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('useRecordBoard', () => {
|
||||||
|
it('should set isBoardLoadedState', async () => {
|
||||||
|
const { result } = renderHook(() => useRecordBoardHook(), renderHookConfig);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.recordBoard.setIsBoardLoaded(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(result.current.isBoardLoaded).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set boardColumnsState', async () => {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: '1',
|
||||||
|
position: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: '1',
|
||||||
|
position: 1,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const { result } = renderHook(() => useRecordBoardHook(), renderHookConfig);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.recordBoard.setBoardColumns(columns);
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(result.current.boardColumns).toEqual(columns);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set setOnFieldsChange', async () => {
|
||||||
|
const onFieldsChangeFunction = () => {};
|
||||||
|
const onFieldsChange = jest.fn(() => onFieldsChangeFunction);
|
||||||
|
const { result } = renderHook(() => useRecordBoardHook(), renderHookConfig);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.recordBoard.setOnFieldsChange(onFieldsChange);
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(result.current.onFieldsChange).toEqual(onFieldsChangeFunction);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
import { act, renderHook } from '@testing-library/react';
|
||||||
|
import gql from 'graphql-tag';
|
||||||
|
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { useCreateOpportunity } from '@/object-record/record-board/hooks/internal/useCreateOpportunity';
|
||||||
|
import { recordBoardCardIdsByColumnIdFamilyState } from '@/object-record/record-board/states/recordBoardCardIdsByColumnIdFamilyState';
|
||||||
|
|
||||||
|
const mockedUuid = 'mocked-uuid';
|
||||||
|
jest.mock('uuid', () => ({
|
||||||
|
v4: () => mockedUuid,
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
|
||||||
|
useMapFieldMetadataToGraphQLQuery: () => () => '\n',
|
||||||
|
}));
|
||||||
|
|
||||||
|
const mocks = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: gql`
|
||||||
|
mutation CreateOneOpportunity($input: OpportunityCreateInput!) {
|
||||||
|
createOpportunity(data: $input) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
id: mockedUuid,
|
||||||
|
pipelineStepId: 'pipelineStepId',
|
||||||
|
companyId: 'New Opportunity',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: jest.fn(() => ({
|
||||||
|
data: { createOpportunity: { id: '' } },
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<MockedProvider mocks={mocks} addTypename={false}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderHookConfig = {
|
||||||
|
wrapper: Wrapper,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('useCreateOpportunity', () => {
|
||||||
|
it('should create opportunity successfully', () => {
|
||||||
|
const companyIdname = 'New Opportunity';
|
||||||
|
const opportunityPipelineStepId = 'pipelineStepId';
|
||||||
|
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => ({
|
||||||
|
createOpportunity: useCreateOpportunity(),
|
||||||
|
recordBoardCardIdsByColumnId: useRecoilValue(
|
||||||
|
recordBoardCardIdsByColumnIdFamilyState(opportunityPipelineStepId),
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
renderHookConfig,
|
||||||
|
);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.createOpportunity(
|
||||||
|
companyIdname,
|
||||||
|
opportunityPipelineStepId,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.recordBoardCardIdsByColumnId).toStrictEqual([
|
||||||
|
mockedUuid,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
import { act, renderHook } from '@testing-library/react';
|
||||||
|
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { BoardCardIdContext } from '@/object-record/record-board/contexts/BoardCardIdContext';
|
||||||
|
import { useCurrentRecordBoardCardSelectedInternal } from '@/object-record/record-board/hooks/internal/useCurrentRecordBoardCardSelectedInternal';
|
||||||
|
import { useRecordBoardScopedStates } from '@/object-record/record-board/hooks/internal/useRecordBoardScopedStates';
|
||||||
|
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
||||||
|
import { actionBarOpenState } from '@/ui/navigation/action-bar/states/actionBarIsOpenState';
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
const boardCardId = 'boardCardId';
|
||||||
|
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<RecordBoardScope recordBoardScopeId={scopeId}>
|
||||||
|
<BoardCardIdContext.Provider value={boardCardId}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</BoardCardIdContext.Provider>
|
||||||
|
</RecordBoardScope>
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('useCurrentRecordBoardCardSelectedInternal', () => {
|
||||||
|
it('should update the data when selecting and deselecting the cardId', () => {
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => ({
|
||||||
|
currentCardSelect: useCurrentRecordBoardCardSelectedInternal(),
|
||||||
|
activeCardIdsState: useRecoilValue(
|
||||||
|
useRecordBoardScopedStates().activeCardIdsState,
|
||||||
|
),
|
||||||
|
actionBarOpenState: useRecoilValue(actionBarOpenState),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current.activeCardIdsState).toStrictEqual([]);
|
||||||
|
expect(result.current.actionBarOpenState).toBe(false);
|
||||||
|
expect(result.current.currentCardSelect.isCurrentCardSelected).toBe(false);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.currentCardSelect.setCurrentCardSelected(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.activeCardIdsState).toStrictEqual([boardCardId]);
|
||||||
|
expect(result.current.actionBarOpenState).toBe(true);
|
||||||
|
expect(result.current.currentCardSelect.isCurrentCardSelected).toBe(true);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.currentCardSelect.setCurrentCardSelected(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.activeCardIdsState).toStrictEqual([]);
|
||||||
|
expect(result.current.actionBarOpenState).toBe(false);
|
||||||
|
expect(result.current.currentCardSelect.isCurrentCardSelected).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,123 @@
|
|||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||||
|
import gql from 'graphql-tag';
|
||||||
|
import { RecoilRoot, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { BoardCardIdContext } from '@/object-record/record-board/contexts/BoardCardIdContext';
|
||||||
|
import { useCreateOpportunity } from '@/object-record/record-board/hooks/internal/useCreateOpportunity';
|
||||||
|
import { useCurrentRecordBoardCardSelectedInternal } from '@/object-record/record-board/hooks/internal/useCurrentRecordBoardCardSelectedInternal';
|
||||||
|
import { useDeleteSelectedRecordBoardCardsInternal } from '@/object-record/record-board/hooks/internal/useDeleteSelectedRecordBoardCardsInternal';
|
||||||
|
import { useRecordBoardScopedStates } from '@/object-record/record-board/hooks/internal/useRecordBoardScopedStates';
|
||||||
|
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
||||||
|
import { recordBoardCardIdsByColumnIdFamilyState } from '@/object-record/record-board/states/recordBoardCardIdsByColumnIdFamilyState';
|
||||||
|
|
||||||
|
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
|
||||||
|
useMapFieldMetadataToGraphQLQuery: jest.fn().mockReturnValue(() => '\n'),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const mockedUuid = 'mocked-uuid';
|
||||||
|
jest.mock('uuid', () => ({ v4: () => mockedUuid }));
|
||||||
|
|
||||||
|
const mocks = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: gql`
|
||||||
|
mutation DeleteManyOpportunities($filter: OpportunityFilterInput!) {
|
||||||
|
deleteOpportunities(filter: $filter) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
variables: { filter: { id: { in: [mockedUuid] } } },
|
||||||
|
},
|
||||||
|
result: jest.fn(() => ({
|
||||||
|
data: { deleteOpportunities: { id: '' } },
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: gql`
|
||||||
|
mutation CreateOneOpportunity($input: OpportunityCreateInput!) {
|
||||||
|
createOpportunity(data: $input) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
id: mockedUuid,
|
||||||
|
pipelineStepId: 'pipelineStepId',
|
||||||
|
companyId: 'New Opportunity',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: jest.fn(() => ({
|
||||||
|
data: { createOpportunity: { id: '' } },
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<MockedProvider mocks={mocks} addTypename={false}>
|
||||||
|
<RecordBoardScope recordBoardScopeId={scopeId}>
|
||||||
|
<BoardCardIdContext.Provider value={mockedUuid}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</BoardCardIdContext.Provider>
|
||||||
|
</RecordBoardScope>
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('useDeleteSelectedRecordBoardCardsInternal', () => {
|
||||||
|
it('should run apollo mutation and update recoil state when delete selected cards', async () => {
|
||||||
|
const companyIdname = 'New Opportunity';
|
||||||
|
const opportunityPipelineStepId = 'pipelineStepId';
|
||||||
|
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => ({
|
||||||
|
createOpportunity: useCreateOpportunity(),
|
||||||
|
deleteSelectedCards: useDeleteSelectedRecordBoardCardsInternal(),
|
||||||
|
setBoardColumns: useSetRecoilState(
|
||||||
|
useRecordBoardScopedStates({
|
||||||
|
recordBoardScopeId: scopeId,
|
||||||
|
}).boardColumnsState,
|
||||||
|
),
|
||||||
|
recordBoardCardIdsByColumnId: useRecoilValue(
|
||||||
|
recordBoardCardIdsByColumnIdFamilyState(opportunityPipelineStepId),
|
||||||
|
),
|
||||||
|
currentSelect: useCurrentRecordBoardCardSelectedInternal(),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.currentSelect.setCurrentCardSelected(true);
|
||||||
|
result.current.setBoardColumns([
|
||||||
|
{
|
||||||
|
id: opportunityPipelineStepId,
|
||||||
|
title: '1',
|
||||||
|
position: 1,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
result.current.createOpportunity(
|
||||||
|
companyIdname,
|
||||||
|
opportunityPipelineStepId,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.recordBoardCardIdsByColumnId).toStrictEqual([
|
||||||
|
mockedUuid,
|
||||||
|
]);
|
||||||
|
await act(async () => {
|
||||||
|
await result.current.deleteSelectedCards();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(result.current.recordBoardCardIdsByColumnId).toStrictEqual([]);
|
||||||
|
expect(mocks[0].result).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||||
|
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { useDeleteSelectedRecordBoardCardsInternal } from '@/object-record/record-board/hooks/internal/useDeleteSelectedRecordBoardCardsInternal';
|
||||||
|
import { useRecordBoardActionBarEntriesInternal } from '@/object-record/record-board/hooks/internal/useRecordBoardActionBarEntriesInternal';
|
||||||
|
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
||||||
|
import { IconTrash } from '@/ui/display/icon';
|
||||||
|
import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState';
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<MockedProvider>
|
||||||
|
<RecordBoardScope recordBoardScopeId={scopeId}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</RecordBoardScope>
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderHookConfig = {
|
||||||
|
wrapper: Wrapper,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('useRecordBoardActionBarEntriesInternal', () => {
|
||||||
|
it('should update actionBarEntries', async () => {
|
||||||
|
const { result } = renderHook(() => {
|
||||||
|
const deleteSelectedBoardCards =
|
||||||
|
useDeleteSelectedRecordBoardCardsInternal();
|
||||||
|
const newActionBarEntry = {
|
||||||
|
label: 'Delete',
|
||||||
|
Icon: IconTrash,
|
||||||
|
accent: 'danger',
|
||||||
|
onClick: deleteSelectedBoardCards,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
setActionBarEntries: useRecordBoardActionBarEntriesInternal(),
|
||||||
|
actionBarEntries: useRecoilValue(actionBarEntriesState),
|
||||||
|
newActionBarEntry,
|
||||||
|
};
|
||||||
|
}, renderHookConfig);
|
||||||
|
|
||||||
|
expect(result.current.actionBarEntries).toStrictEqual([]);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.setActionBarEntries.setActionBarEntries();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(JSON.stringify(result.current.actionBarEntries)).toBe(
|
||||||
|
JSON.stringify([result.current.newActionBarEntry]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,110 @@
|
|||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
|
import { renderHook } from '@testing-library/react';
|
||||||
|
import { RecoilRoot, useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { FieldType } from '@/object-record/field/types/FieldType';
|
||||||
|
import { useRecordBoardCardFieldsInternal } from '@/object-record/record-board/hooks/internal/useRecordBoardCardFieldsInternal';
|
||||||
|
import { onFieldsChangeScopedState } from '@/object-record/record-board/states/onFieldsChangeScopedState';
|
||||||
|
import { recordBoardCardFieldsScopedState } from '@/object-record/record-board/states/recordBoardCardFieldsScopedState';
|
||||||
|
import { savedRecordBoardCardFieldsScopedState } from '@/object-record/record-board/states/savedRecordBoardCardFieldsScopedState';
|
||||||
|
|
||||||
|
const recordBoardScopeId = 'recordBoardScopeId';
|
||||||
|
|
||||||
|
const renderHookConfig = {
|
||||||
|
wrapper: RecoilRoot,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('useRecordBoardCardFieldsInternal', () => {
|
||||||
|
it('should toggle field visibility', async () => {
|
||||||
|
const { result } = renderHook(() => {
|
||||||
|
const [cardFieldsList, setCardFieldsList] = useRecoilState(
|
||||||
|
recordBoardCardFieldsScopedState({ scopeId: recordBoardScopeId }),
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
boardCardFields: useRecordBoardCardFieldsInternal({
|
||||||
|
recordBoardScopeId,
|
||||||
|
}),
|
||||||
|
cardFieldsList,
|
||||||
|
setCardFieldsList,
|
||||||
|
};
|
||||||
|
}, renderHookConfig);
|
||||||
|
|
||||||
|
const field = {
|
||||||
|
position: 0,
|
||||||
|
fieldMetadataId: 'id',
|
||||||
|
label: 'label',
|
||||||
|
iconName: 'icon',
|
||||||
|
type: 'TEXT' as FieldType,
|
||||||
|
metadata: {
|
||||||
|
fieldName: 'fieldName',
|
||||||
|
},
|
||||||
|
isVisible: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.setCardFieldsList([field]);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.cardFieldsList[0].isVisible).toBe(true);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.boardCardFields.handleFieldVisibilityChange(field);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.cardFieldsList[0].isVisible).toBe(false);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.boardCardFields.handleFieldVisibilityChange({
|
||||||
|
...field,
|
||||||
|
isVisible: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.cardFieldsList[0].isVisible).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the onFieldsChange callback and update board card states', async () => {
|
||||||
|
const { result } = renderHook(() => {
|
||||||
|
const [onFieldsChange, setOnFieldsChange] = useRecoilState(
|
||||||
|
onFieldsChangeScopedState({ scopeId: recordBoardScopeId }),
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
boardCardFieldsHook: useRecordBoardCardFieldsInternal({
|
||||||
|
recordBoardScopeId,
|
||||||
|
}),
|
||||||
|
boardCardFieldsList: useRecoilValue(
|
||||||
|
recordBoardCardFieldsScopedState({ scopeId: recordBoardScopeId }),
|
||||||
|
),
|
||||||
|
savedBoardCardFieldsList: useRecoilValue(
|
||||||
|
savedRecordBoardCardFieldsScopedState({
|
||||||
|
scopeId: recordBoardScopeId,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
onFieldsChange,
|
||||||
|
setOnFieldsChange,
|
||||||
|
};
|
||||||
|
}, renderHookConfig);
|
||||||
|
|
||||||
|
const field = {
|
||||||
|
position: 0,
|
||||||
|
fieldMetadataId: 'id',
|
||||||
|
label: 'label',
|
||||||
|
iconName: 'icon',
|
||||||
|
type: 'TEXT' as FieldType,
|
||||||
|
metadata: {
|
||||||
|
fieldName: 'fieldName',
|
||||||
|
},
|
||||||
|
isVisible: true,
|
||||||
|
};
|
||||||
|
const onChangeFunction = jest.fn();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
result.current.setOnFieldsChange(() => onChangeFunction);
|
||||||
|
result.current.boardCardFieldsHook.handleFieldsReorder([field]);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(onChangeFunction).toHaveBeenCalledWith([field]);
|
||||||
|
expect(result.current.savedBoardCardFieldsList).toStrictEqual([field]);
|
||||||
|
expect(result.current.boardCardFieldsList).toStrictEqual([field]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,128 @@
|
|||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||||
|
import gql from 'graphql-tag';
|
||||||
|
import { RecoilRoot, useRecoilState, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { useBoardColumnsInternal } from '@/object-record/record-board/hooks/internal/useRecordBoardColumnsInternal';
|
||||||
|
import { useRecordBoardScopedStates } from '@/object-record/record-board/hooks/internal/useRecordBoardScopedStates';
|
||||||
|
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
||||||
|
import { BoardColumnDefinition } from '@/object-record/record-board/types/BoardColumnDefinition';
|
||||||
|
|
||||||
|
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
|
||||||
|
useMapFieldMetadataToGraphQLQuery: jest.fn().mockReturnValue(() => '\n'),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const mocks = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: gql`
|
||||||
|
mutation UpdateOnePipelineStep(
|
||||||
|
$idToUpdate: ID!
|
||||||
|
$input: PipelineStepUpdateInput!
|
||||||
|
) {
|
||||||
|
updatePipelineStep(id: $idToUpdate, data: $input) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
variables: { idToUpdate: '1', input: { position: 0 } },
|
||||||
|
},
|
||||||
|
result: jest.fn(() => ({
|
||||||
|
data: { updatePipelineStep: { id: '' } },
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<MockedProvider mocks={mocks} addTypename={false}>
|
||||||
|
<RecordBoardScope recordBoardScopeId={scopeId}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</RecordBoardScope>
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderHookConfig = {
|
||||||
|
wrapper: Wrapper,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('useBoardColumnsInternal', () => {
|
||||||
|
it('should update boardColumns state when moving to left and right', async () => {
|
||||||
|
const { result } = renderHook(() => {
|
||||||
|
const [boardColumnsList, setBoardColumnsList] = useRecoilState(
|
||||||
|
useRecordBoardScopedStates().boardColumnsState,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
boardColumns: useBoardColumnsInternal(),
|
||||||
|
boardColumnsList,
|
||||||
|
setBoardColumnsList,
|
||||||
|
};
|
||||||
|
}, renderHookConfig);
|
||||||
|
const columns: BoardColumnDefinition[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: '1',
|
||||||
|
position: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
title: '2',
|
||||||
|
position: 1,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
act(() => {
|
||||||
|
result.current.setBoardColumnsList(columns);
|
||||||
|
});
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.boardColumns.handleMoveBoardColumn('right', columns[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(result.current.boardColumnsList).toStrictEqual([
|
||||||
|
{ id: '2', title: '2', position: 0, index: 0 },
|
||||||
|
{ id: '1', title: '1', position: 1, index: 1 },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.boardColumns.handleMoveBoardColumn('left', columns[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(result.current.boardColumnsList).toStrictEqual([
|
||||||
|
{ id: '1', title: '1', position: 0, index: 0 },
|
||||||
|
{ id: '2', title: '2', position: 1, index: 1 },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call apollo mutation after persistBoardColumns', async () => {
|
||||||
|
const { result } = renderHook(() => {
|
||||||
|
return {
|
||||||
|
boardColumns: useBoardColumnsInternal(),
|
||||||
|
setBoardColumnsList: useSetRecoilState(
|
||||||
|
useRecordBoardScopedStates().boardColumnsState,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}, renderHookConfig);
|
||||||
|
const columns: BoardColumnDefinition[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: '1',
|
||||||
|
position: 0,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
act(() => {
|
||||||
|
result.current.setBoardColumnsList(columns);
|
||||||
|
});
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.boardColumns.persistBoardColumns();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mocks[0].result).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||||
|
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { useDeleteSelectedRecordBoardCardsInternal } from '@/object-record/record-board/hooks/internal/useDeleteSelectedRecordBoardCardsInternal';
|
||||||
|
import { useRecordBoardContextMenuEntriesInternal } from '@/object-record/record-board/hooks/internal/useRecordBoardContextMenuEntriesInternal';
|
||||||
|
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
||||||
|
import { IconTrash } from '@/ui/display/icon';
|
||||||
|
import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState';
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<MockedProvider>
|
||||||
|
<RecordBoardScope recordBoardScopeId={scopeId}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</RecordBoardScope>
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('useRecordBoardContextMenuEntriesInternal', () => {
|
||||||
|
it('should update contextEntries', async () => {
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => {
|
||||||
|
const deleteSelectedBoardCards =
|
||||||
|
useDeleteSelectedRecordBoardCardsInternal();
|
||||||
|
const newContextEntry = {
|
||||||
|
label: 'Delete',
|
||||||
|
Icon: IconTrash,
|
||||||
|
accent: 'danger',
|
||||||
|
onClick: deleteSelectedBoardCards,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
setContextEntries: useRecordBoardContextMenuEntriesInternal(),
|
||||||
|
contextEntries: useRecoilValue(contextMenuEntriesState),
|
||||||
|
newContextEntry,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current.contextEntries).toStrictEqual([]);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.setContextEntries.setContextMenuEntries();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(JSON.stringify(result.current.contextEntries)).toBe(
|
||||||
|
JSON.stringify([result.current.newContextEntry]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
import { act, renderHook } from '@testing-library/react';
|
||||||
|
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { useSetRecordBoardCardSelectedInternal } from '@/object-record/record-board/hooks/internal/useSetRecordBoardCardSelectedInternal';
|
||||||
|
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
||||||
|
import { isRecordBoardCardSelectedFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedFamilyState';
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
const boardCardId = 'boardCardId';
|
||||||
|
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<RecordBoardScope recordBoardScopeId={scopeId}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</RecordBoardScope>
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordBoardScopeId = 'recordBoardScopeId';
|
||||||
|
|
||||||
|
describe('useSetRecordBoardCardSelectedInternal', () => {
|
||||||
|
it('should update the data when selecting and deselecting the cardId', async () => {
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
cardSelect: useSetRecordBoardCardSelectedInternal({
|
||||||
|
recordBoardScopeId,
|
||||||
|
}),
|
||||||
|
isSelected: useRecoilValue(
|
||||||
|
isRecordBoardCardSelectedFamilyState(boardCardId),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current.isSelected).toBe(false);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.cardSelect.setCardSelected(boardCardId, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.isSelected).toBe(true);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.cardSelect.setCardSelected(boardCardId, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.isSelected).toBe(false);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.cardSelect.setCardSelected(boardCardId, true);
|
||||||
|
result.current.cardSelect.unselectAllActiveCards();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.isSelected).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
import { act, renderHook } from '@testing-library/react';
|
||||||
|
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { CompanyForBoard } from '@/companies/types/CompanyProgress';
|
||||||
|
import { useRecordBoardScopedStates } from '@/object-record/record-board/hooks/internal/useRecordBoardScopedStates';
|
||||||
|
import { useUpdateCompanyBoardColumnsInternal } from '@/object-record/record-board/hooks/internal/useUpdateCompanyBoardColumnsInternal';
|
||||||
|
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
||||||
|
import { recordBoardCardIdsByColumnIdFamilyState } from '@/object-record/record-board/states/recordBoardCardIdsByColumnIdFamilyState';
|
||||||
|
import { currentPipelineStepsState } from '@/pipeline/states/currentPipelineStepsState';
|
||||||
|
import { Opportunity } from '@/pipeline/types/Opportunity';
|
||||||
|
import { PipelineStep } from '@/pipeline/types/PipelineStep';
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<RecordBoardScope recordBoardScopeId={scopeId}>
|
||||||
|
<RecoilRoot>{children}</RecoilRoot>
|
||||||
|
</RecordBoardScope>
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('useUpdateCompanyBoardColumnsInternal', () => {
|
||||||
|
it('should update recoil state after updateCompanyBoardColumns call ', async () => {
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
updateCompanyBoardColumns: useUpdateCompanyBoardColumnsInternal(),
|
||||||
|
currentPipeline: useRecoilValue(currentPipelineStepsState),
|
||||||
|
boardColumns: useRecoilValue(
|
||||||
|
useRecordBoardScopedStates().boardColumnsState,
|
||||||
|
),
|
||||||
|
savedBoardColumns: useRecoilValue(
|
||||||
|
useRecordBoardScopedStates().savedBoardColumnsState,
|
||||||
|
),
|
||||||
|
idsByColumnId: useRecoilValue(
|
||||||
|
recordBoardCardIdsByColumnIdFamilyState('1'),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const pipelineSteps: PipelineStep[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
name: 'Step 1',
|
||||||
|
color: 'red',
|
||||||
|
position: 1,
|
||||||
|
createdAt: '2024-01-12',
|
||||||
|
updatedAt: '2024-01-12',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
name: 'Step 2',
|
||||||
|
color: 'blue',
|
||||||
|
position: 1,
|
||||||
|
createdAt: '2024-01-12',
|
||||||
|
updatedAt: '2024-01-12',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const opportunity: Opportunity = {
|
||||||
|
id: '123',
|
||||||
|
amount: {
|
||||||
|
amountMicros: 1000000,
|
||||||
|
currencyCode: 'USD',
|
||||||
|
},
|
||||||
|
closeDate: new Date('2024-02-01'),
|
||||||
|
probability: 0.75,
|
||||||
|
pipelineStepId: '1',
|
||||||
|
pipelineStep: pipelineSteps[0],
|
||||||
|
pointOfContactId: '456',
|
||||||
|
pointOfContact: {
|
||||||
|
id: '456',
|
||||||
|
name: {
|
||||||
|
firstName: 'John',
|
||||||
|
lastName: 'Doe',
|
||||||
|
},
|
||||||
|
avatarUrl: 'https://example.com/avatar.jpg',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const companyForBoard: CompanyForBoard = {
|
||||||
|
id: '789',
|
||||||
|
name: 'Acme Inc.',
|
||||||
|
domainName: 'acme.com',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(result.current.currentPipeline).toStrictEqual([]);
|
||||||
|
expect(result.current.savedBoardColumns).toStrictEqual([]);
|
||||||
|
expect(result.current.boardColumns).toStrictEqual([]);
|
||||||
|
expect(result.current.idsByColumnId).toStrictEqual([]);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.updateCompanyBoardColumns(
|
||||||
|
pipelineSteps,
|
||||||
|
[opportunity],
|
||||||
|
[companyForBoard],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedBoardColumns = [
|
||||||
|
{ id: '1', title: 'Step 1', colorCode: 'red', position: 1 },
|
||||||
|
{ id: '2', title: 'Step 2', colorCode: 'blue', position: 1 },
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(result.current.currentPipeline).toStrictEqual(pipelineSteps);
|
||||||
|
expect(result.current.savedBoardColumns).toStrictEqual(
|
||||||
|
expectedBoardColumns,
|
||||||
|
);
|
||||||
|
expect(result.current.boardColumns).toStrictEqual(expectedBoardColumns);
|
||||||
|
expect(result.current.idsByColumnId).toStrictEqual([opportunity.id]);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user