Refactor Views by cleaning the code, relying on apolloCache and improving performances (#4516)
* Wip refactoring view * Post merge conflicts * Fix review * Add create view capability * Fix create object missing view * Fix tests
This commit is contained in:
@ -1,27 +1,11 @@
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { MemoryRouter, useSearchParams } from 'react-router-dom';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import { RecoilRoot, useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { generateDeleteOneRecordMutation } from '@/object-record/utils/generateDeleteOneRecordMutation';
|
||||
import { getScopedStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedStateDeprecated';
|
||||
import {
|
||||
filterDefinition,
|
||||
viewFilter,
|
||||
} from '@/views/hooks/__tests__/useViewBar_ViewFilters.test';
|
||||
import {
|
||||
sortDefinition,
|
||||
viewSort,
|
||||
} from '@/views/hooks/__tests__/useViewBar_ViewSorts.test';
|
||||
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
||||
import { entityCountInCurrentViewScopedState } from '@/views/states/entityCountInCurrentViewScopedState';
|
||||
import { viewEditModeScopedState } from '@/views/states/viewEditModeScopedState';
|
||||
import { viewObjectMetadataIdScopeState } from '@/views/states/viewObjectMetadataIdScopeState';
|
||||
|
||||
const mockedUuid = 'mocked-uuid';
|
||||
jest.mock('uuid');
|
||||
@ -49,225 +33,19 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
>
|
||||
<MockedProvider mocks={mocks} addTypename={false}>
|
||||
<RecoilRoot>
|
||||
<ViewScope viewScopeId="viewScopeId">{children}</ViewScope>
|
||||
<ViewScope viewScopeId="viewScopeId" onCurrentViewChange={() => {}}>
|
||||
{children}
|
||||
</ViewScope>
|
||||
</RecoilRoot>
|
||||
</MockedProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
const renderHookConfig = {
|
||||
const _renderHookConfig = {
|
||||
wrapper: Wrapper,
|
||||
};
|
||||
|
||||
const viewBarId = 'viewBarTestId';
|
||||
const _viewBarId = 'viewBarTestId';
|
||||
|
||||
describe('useViewBar', () => {
|
||||
it('should set and get current view Id', () => {
|
||||
const { result } = renderHook(
|
||||
() => useViewBar({ viewBarId }),
|
||||
renderHookConfig,
|
||||
);
|
||||
|
||||
expect(result.current.scopeId).toBe(viewBarId);
|
||||
expect(result.current.currentViewId).toBeUndefined();
|
||||
|
||||
act(() => {
|
||||
result.current.setCurrentViewId('testId');
|
||||
});
|
||||
|
||||
expect(result.current.currentViewId).toBe('testId');
|
||||
});
|
||||
|
||||
it('should create view and update url params', async () => {
|
||||
const { result } = renderHook(() => {
|
||||
const viewBar = useViewBar({ viewBarId });
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
return {
|
||||
viewBar,
|
||||
searchParams,
|
||||
};
|
||||
}, renderHookConfig);
|
||||
await act(async () => {
|
||||
await result.current.viewBar.createView('Test View');
|
||||
});
|
||||
expect(result.current.searchParams[0].get('view')).toBe(mockedUuid);
|
||||
});
|
||||
|
||||
it('should delete current view and remove id from params', async () => {
|
||||
const { result } = renderHook(
|
||||
() => ({
|
||||
viewBar: useViewBar({ viewBarId }),
|
||||
searchParams: useSearchParams(),
|
||||
}),
|
||||
renderHookConfig,
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.viewBar.createView('Test View');
|
||||
result.current.viewBar.setCurrentViewId(mockedUuid);
|
||||
});
|
||||
expect(result.current.searchParams[0].get('view')).toBe(mockedUuid);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.viewBar.removeView(mockedUuid);
|
||||
});
|
||||
expect(result.current.searchParams[0].get('view')).toBeNull();
|
||||
|
||||
const addBookMutationMock = mocks[0].result;
|
||||
await waitFor(() => expect(addBookMutationMock).toHaveBeenCalled());
|
||||
});
|
||||
|
||||
it('should resetViewBar', async () => {
|
||||
const { result } = renderHook(() => {
|
||||
const viewBar = useViewBar({ viewBarId });
|
||||
const {
|
||||
currentViewFiltersState,
|
||||
currentViewSortsState,
|
||||
viewEditModeState,
|
||||
} = useViewScopedStates({
|
||||
viewScopeId: viewBarId,
|
||||
});
|
||||
const currentViewFilters = useRecoilValue(currentViewFiltersState);
|
||||
const currentViewSorts = useRecoilValue(currentViewSortsState);
|
||||
const viewEditMode = useRecoilValue(viewEditModeState);
|
||||
|
||||
return {
|
||||
viewBar,
|
||||
currentViewFilters,
|
||||
currentViewSorts,
|
||||
viewEditMode,
|
||||
};
|
||||
}, renderHookConfig);
|
||||
|
||||
act(() => {
|
||||
result.current.viewBar.resetViewBar();
|
||||
});
|
||||
|
||||
expect(result.current.currentViewFilters).toStrictEqual([]);
|
||||
expect(result.current.currentViewSorts).toStrictEqual([]);
|
||||
expect(result.current.viewEditMode).toBe('none');
|
||||
});
|
||||
|
||||
it('should handleViewNameSubmit', async () => {
|
||||
const { result } = renderHook(
|
||||
() => useViewBar({ viewBarId }),
|
||||
renderHookConfig,
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleViewNameSubmit('New View Name');
|
||||
});
|
||||
});
|
||||
|
||||
it('should update edit mode', async () => {
|
||||
const { result } = renderHook(
|
||||
() => ({
|
||||
viewBar: useViewBar({ viewBarId }),
|
||||
editMode: useRecoilState(
|
||||
getScopedStateDeprecated(viewEditModeScopedState, viewBarId),
|
||||
)[0],
|
||||
}),
|
||||
renderHookConfig,
|
||||
);
|
||||
|
||||
expect(result.current.editMode).toBe('none');
|
||||
await act(async () => {
|
||||
result.current.viewBar.setViewEditMode('create');
|
||||
});
|
||||
|
||||
expect(result.current.editMode).toBe('create');
|
||||
await act(async () => {
|
||||
result.current.viewBar.setViewEditMode('edit');
|
||||
});
|
||||
|
||||
expect(result.current.editMode).toBe('edit');
|
||||
});
|
||||
|
||||
it('should update url param', async () => {
|
||||
const { result } = renderHook(
|
||||
() => ({
|
||||
viewBar: useViewBar({ viewBarId }),
|
||||
searchParams: useSearchParams(),
|
||||
}),
|
||||
renderHookConfig,
|
||||
);
|
||||
expect(result.current.searchParams[0].get('view')).toBeNull();
|
||||
await act(async () => {
|
||||
result.current.viewBar.changeViewInUrl('view1');
|
||||
});
|
||||
expect(result.current.searchParams[0].get('view')).toBe('view1');
|
||||
});
|
||||
|
||||
it('should update object metadata id', async () => {
|
||||
const { result } = renderHook(
|
||||
() => ({
|
||||
viewBar: useViewBar({ viewBarId }),
|
||||
metadataId: useRecoilState(
|
||||
getScopedStateDeprecated(viewObjectMetadataIdScopeState, viewBarId),
|
||||
)[0],
|
||||
}),
|
||||
renderHookConfig,
|
||||
);
|
||||
|
||||
expect(result.current.metadataId).toBeUndefined();
|
||||
await act(async () => {
|
||||
result.current.viewBar.setViewObjectMetadataId('newId');
|
||||
});
|
||||
|
||||
expect(result.current.metadataId).toBe('newId');
|
||||
});
|
||||
|
||||
it('should update count in current view', async () => {
|
||||
const { result } = renderHook(
|
||||
() => ({
|
||||
viewBar: useViewBar({ viewBarId }),
|
||||
count: useRecoilState(
|
||||
getScopedStateDeprecated(
|
||||
entityCountInCurrentViewScopedState,
|
||||
viewBarId,
|
||||
),
|
||||
)[0],
|
||||
}),
|
||||
renderHookConfig,
|
||||
);
|
||||
|
||||
expect(result.current.count).toBe(0);
|
||||
await act(async () => {
|
||||
result.current.viewBar.setEntityCountInCurrentView(1);
|
||||
});
|
||||
|
||||
expect(result.current.count).toBe(1);
|
||||
});
|
||||
|
||||
it('should loadView', async () => {
|
||||
const { result } = renderHook(
|
||||
() => useViewBar({ viewBarId }),
|
||||
renderHookConfig,
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.loadView(mockedUuid);
|
||||
});
|
||||
});
|
||||
|
||||
it('should updateCurrentView', async () => {
|
||||
const { result } = renderHook(() => {
|
||||
const viewBar = useViewBar({ viewBarId });
|
||||
viewBar.setCurrentViewId(mockedUuid);
|
||||
|
||||
viewBar.setAvailableSortDefinitions([sortDefinition]);
|
||||
|
||||
viewBar.loadViewSorts([viewSort], mockedUuid);
|
||||
|
||||
viewBar.setAvailableFilterDefinitions([filterDefinition]);
|
||||
|
||||
viewBar.loadViewFilters([viewFilter], mockedUuid);
|
||||
|
||||
return { viewBar };
|
||||
}, renderHookConfig);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.viewBar.updateCurrentView();
|
||||
});
|
||||
});
|
||||
it('should set and get current view Id', () => {});
|
||||
});
|
||||
|
||||
@ -1,170 +0,0 @@
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { gql } from '@apollo/client';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import { RecoilRoot, useRecoilState, useRecoilValue } from 'recoil';
|
||||
|
||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
import { getScopedFamilyStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedFamilyStateDeprecated';
|
||||
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
||||
import { currentViewFieldsScopedFamilyState } from '@/views/states/currentViewFieldsScopedFamilyState';
|
||||
import { ViewField } from '@/views/types/ViewField';
|
||||
|
||||
const fieldMetadataId = '12ecdf87-506f-44a7-98c6-393e5f05b225';
|
||||
|
||||
const fieldDefinition: ColumnDefinition<FieldMetadata> = {
|
||||
size: 1,
|
||||
position: 1,
|
||||
fieldMetadataId,
|
||||
label: 'label',
|
||||
iconName: 'icon',
|
||||
type: 'TEXT',
|
||||
metadata: {
|
||||
placeHolder: 'placeHolder',
|
||||
fieldName: 'fieldName',
|
||||
},
|
||||
};
|
||||
const viewField: ViewField = {
|
||||
id: '88930a16-685f-493b-a96b-91ca55666bba',
|
||||
fieldMetadataId,
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 1,
|
||||
definition: fieldDefinition,
|
||||
};
|
||||
|
||||
const viewBarId = 'viewBarTestId';
|
||||
|
||||
const currentViewId = '23f5dceb-3482-4e3a-9bb4-2f52f2556be9';
|
||||
|
||||
const mocks = [
|
||||
{
|
||||
request: {
|
||||
query: gql`
|
||||
mutation CreateOneViewField($input: ViewFieldCreateInput!) {
|
||||
createViewField(data: $input) {
|
||||
__typename
|
||||
position
|
||||
isVisible
|
||||
fieldMetadataId
|
||||
viewId
|
||||
id
|
||||
size
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
input: {
|
||||
fieldMetadataId,
|
||||
viewId: currentViewId,
|
||||
isVisible: true,
|
||||
size: 1,
|
||||
position: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
result: jest.fn(() => ({
|
||||
data: { createViewField: { id: '' } },
|
||||
})),
|
||||
},
|
||||
];
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<MemoryRouter
|
||||
initialEntries={['/one', '/two', { pathname: '/three' }]}
|
||||
initialIndex={1}
|
||||
>
|
||||
<MockedProvider mocks={mocks} addTypename={false}>
|
||||
<RecoilRoot>
|
||||
<ViewScope viewScopeId="viewScopeId">{children}</ViewScope>
|
||||
</RecoilRoot>
|
||||
</MockedProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
const renderHookConfig = {
|
||||
wrapper: Wrapper,
|
||||
};
|
||||
|
||||
describe('useViewBar > viewFields', () => {
|
||||
it('should update current fields', async () => {
|
||||
const { result } = renderHook(
|
||||
() => ({
|
||||
viewBar: useViewBar({ viewBarId }),
|
||||
currentFields: useRecoilState(
|
||||
getScopedFamilyStateDeprecated(
|
||||
currentViewFieldsScopedFamilyState,
|
||||
viewBarId,
|
||||
currentViewId,
|
||||
),
|
||||
)[0],
|
||||
}),
|
||||
renderHookConfig,
|
||||
);
|
||||
|
||||
expect(result.current.currentFields).toStrictEqual([]);
|
||||
await act(async () => {
|
||||
result.current.viewBar.setCurrentViewId(currentViewId);
|
||||
result.current.viewBar.setViewObjectMetadataId('newId');
|
||||
result.current.viewBar.persistViewFields([viewField]);
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
expect(result.current.currentFields).toEqual([viewField]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should persist view fields', async () => {
|
||||
const { result } = renderHook(
|
||||
() => useViewBar({ viewBarId }),
|
||||
renderHookConfig,
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
result.current.setCurrentViewId(currentViewId);
|
||||
result.current.setViewObjectMetadataId('newId');
|
||||
await result.current.persistViewFields([viewField]);
|
||||
});
|
||||
|
||||
const persistViewFieldsMutation = mocks[0];
|
||||
|
||||
await waitFor(() =>
|
||||
expect(persistViewFieldsMutation.result).toHaveBeenCalled(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should load view fields', async () => {
|
||||
const currentViewId = 'ac8807fd-0065-436d-bdf6-94333d75af6e';
|
||||
|
||||
const { result } = renderHook(() => {
|
||||
const viewBar = useViewBar({ viewBarId });
|
||||
|
||||
const { currentViewFieldsState } = useViewScopedStates({
|
||||
viewScopeId: viewBarId,
|
||||
});
|
||||
const currentViewFields = useRecoilValue(currentViewFieldsState);
|
||||
|
||||
return {
|
||||
viewBar,
|
||||
currentViewFields,
|
||||
};
|
||||
}, renderHookConfig);
|
||||
|
||||
expect(result.current.currentViewFields).toStrictEqual([]);
|
||||
|
||||
await act(async () => {
|
||||
result.current.viewBar.setAvailableFieldDefinitions([fieldDefinition]);
|
||||
|
||||
await result.current.viewBar.loadViewFields([viewField], currentViewId);
|
||||
result.current.viewBar.setCurrentViewId(currentViewId);
|
||||
});
|
||||
|
||||
expect(result.current.currentViewFields).toStrictEqual([viewField]);
|
||||
});
|
||||
});
|
||||
@ -1,178 +0,0 @@
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||
|
||||
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
|
||||
import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition';
|
||||
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<MemoryRouter
|
||||
initialEntries={['/one', '/two', { pathname: '/three' }]}
|
||||
initialIndex={1}
|
||||
>
|
||||
<MockedProvider addTypename={false}>
|
||||
<RecoilRoot>
|
||||
<ViewScope viewScopeId="viewScopeId">{children}</ViewScope>
|
||||
</RecoilRoot>
|
||||
</MockedProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
const renderHookConfig = {
|
||||
wrapper: Wrapper,
|
||||
};
|
||||
|
||||
const viewBarId = 'viewBarTestId';
|
||||
|
||||
export const filterDefinition: FilterDefinition = {
|
||||
fieldMetadataId: '113ea8f8-1908-4c9c-9984-3f23c96b92f5',
|
||||
label: 'label',
|
||||
iconName: 'iconName',
|
||||
type: 'TEXT',
|
||||
};
|
||||
|
||||
export const viewFilter: ViewFilter = {
|
||||
id: 'id',
|
||||
fieldMetadataId: '113ea8f8-1908-4c9c-9984-3f23c96b92f5',
|
||||
operand: ViewFilterOperand.Is,
|
||||
value: 'value',
|
||||
displayValue: 'displayValue',
|
||||
definition: filterDefinition,
|
||||
};
|
||||
|
||||
const currentViewId = '23f5dceb-3482-4e3a-9bb4-2f52f2556be9';
|
||||
|
||||
describe('useViewBar > viewFilters', () => {
|
||||
it('should load view filters', async () => {
|
||||
const { result } = renderHook(() => {
|
||||
const viewBar = useViewBar({ viewBarId });
|
||||
|
||||
const { currentViewFiltersState } = useViewScopedStates({
|
||||
viewScopeId: viewBarId,
|
||||
});
|
||||
const currentViewFilters = useRecoilValue(currentViewFiltersState);
|
||||
|
||||
return {
|
||||
viewBar,
|
||||
currentViewFilters,
|
||||
};
|
||||
}, renderHookConfig);
|
||||
|
||||
expect(result.current.currentViewFilters).toStrictEqual([]);
|
||||
|
||||
await act(async () => {
|
||||
result.current.viewBar.setAvailableFilterDefinitions([filterDefinition]);
|
||||
|
||||
await result.current.viewBar.loadViewFilters([viewFilter], currentViewId);
|
||||
result.current.viewBar.setCurrentViewId(currentViewId);
|
||||
});
|
||||
|
||||
expect(result.current.currentViewFilters).toStrictEqual([viewFilter]);
|
||||
});
|
||||
|
||||
it('should upsertViewFilter', async () => {
|
||||
const { result } = renderHook(() => {
|
||||
const viewBar = useViewBar({ viewBarId });
|
||||
|
||||
viewBar.setAvailableFilterDefinitions([filterDefinition]);
|
||||
|
||||
viewBar.loadViewFilters([viewFilter], currentViewId);
|
||||
viewBar.setCurrentViewId(currentViewId);
|
||||
|
||||
const { currentViewFiltersState } = useViewScopedStates({
|
||||
viewScopeId: viewBarId,
|
||||
});
|
||||
const currentViewFilters = useRecoilValue(currentViewFiltersState);
|
||||
|
||||
return {
|
||||
viewBar,
|
||||
currentViewFilters,
|
||||
};
|
||||
}, renderHookConfig);
|
||||
|
||||
expect(result.current.currentViewFilters).toStrictEqual([viewFilter]);
|
||||
|
||||
const newFilters: Filter[] = [
|
||||
{
|
||||
fieldMetadataId: '113ea8f8-1908-4c9c-9984-3f23c96b92f5',
|
||||
value: 'value',
|
||||
displayValue: 'displayValue',
|
||||
operand: ViewFilterOperand.IsNot,
|
||||
definition: {
|
||||
fieldMetadataId: 'id',
|
||||
label: 'label',
|
||||
iconName: 'icon',
|
||||
type: 'TEXT',
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldMetadataId: 'd9487757-183e-4fa0-a554-a980850cb23d',
|
||||
value: 'value',
|
||||
displayValue: 'displayValue',
|
||||
operand: ViewFilterOperand.Contains,
|
||||
definition: {
|
||||
fieldMetadataId: 'id',
|
||||
label: 'label',
|
||||
iconName: 'icon',
|
||||
type: 'TEXT',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// upsert an existing filter
|
||||
act(() => {
|
||||
result.current.viewBar.upsertViewFilter(newFilters[0]);
|
||||
});
|
||||
|
||||
expect(result.current.currentViewFilters).toStrictEqual([
|
||||
{ ...newFilters[0], id: viewFilter.id },
|
||||
]);
|
||||
|
||||
// upsert a new filter
|
||||
act(() => {
|
||||
result.current.viewBar.upsertViewFilter(newFilters[1]);
|
||||
});
|
||||
|
||||
// expect currentViewFilters to contain both filters
|
||||
expect(result.current.currentViewFilters).toStrictEqual([
|
||||
{ ...newFilters[0], id: viewFilter.id },
|
||||
{ ...newFilters[1], id: undefined },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should remove view filter', () => {
|
||||
const { result } = renderHook(() => {
|
||||
const viewBar = useViewBar({ viewBarId });
|
||||
|
||||
viewBar.setAvailableFilterDefinitions([filterDefinition]);
|
||||
|
||||
viewBar.loadViewFilters([viewFilter], currentViewId);
|
||||
viewBar.setCurrentViewId(currentViewId);
|
||||
|
||||
const { currentViewFiltersState } = useViewScopedStates({
|
||||
viewScopeId: viewBarId,
|
||||
});
|
||||
const currentViewFilters = useRecoilValue(currentViewFiltersState);
|
||||
|
||||
return {
|
||||
viewBar,
|
||||
currentViewFilters,
|
||||
};
|
||||
}, renderHookConfig);
|
||||
|
||||
expect(result.current.currentViewFilters).toStrictEqual([viewFilter]);
|
||||
|
||||
// remove an existing filter
|
||||
act(() => {
|
||||
result.current.viewBar.removeViewFilter(filterDefinition.fieldMetadataId);
|
||||
});
|
||||
|
||||
expect(result.current.currentViewFilters).toStrictEqual([]);
|
||||
});
|
||||
});
|
||||
@ -1,165 +0,0 @@
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||
|
||||
import { Sort } from '@/object-record/object-sort-dropdown/types/Sort';
|
||||
import { SortDefinition } from '@/object-record/object-sort-dropdown/types/SortDefinition';
|
||||
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
||||
import { ViewSort } from '@/views/types/ViewSort';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<MemoryRouter
|
||||
initialEntries={['/one', '/two', { pathname: '/three' }]}
|
||||
initialIndex={1}
|
||||
>
|
||||
<MockedProvider addTypename={false}>
|
||||
<RecoilRoot>
|
||||
<ViewScope viewScopeId="viewScopeId">{children}</ViewScope>
|
||||
</RecoilRoot>
|
||||
</MockedProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
const renderHookConfig = {
|
||||
wrapper: Wrapper,
|
||||
};
|
||||
|
||||
const viewBarId = 'viewBarTestId';
|
||||
|
||||
export const sortDefinition: SortDefinition = {
|
||||
fieldMetadataId: '12ecdf87-506f-44a7-98c6-393e5f05b225',
|
||||
label: 'label',
|
||||
iconName: 'icon',
|
||||
};
|
||||
|
||||
export const viewSort: ViewSort = {
|
||||
id: '88930a16-685f-493b-a96b-91ca55666bba',
|
||||
fieldMetadataId: '12ecdf87-506f-44a7-98c6-393e5f05b225',
|
||||
direction: 'asc',
|
||||
definition: sortDefinition,
|
||||
};
|
||||
|
||||
describe('View Sorts', () => {
|
||||
const currentViewId = 'ac8807fd-0065-436d-bdf6-94333d75af6e';
|
||||
|
||||
it('should load view sorts', async () => {
|
||||
const { result } = renderHook(() => {
|
||||
const viewBar = useViewBar({ viewBarId });
|
||||
|
||||
const { currentViewSortsState } = useViewScopedStates({
|
||||
viewScopeId: viewBarId,
|
||||
});
|
||||
const currentViewSorts = useRecoilValue(currentViewSortsState);
|
||||
|
||||
return {
|
||||
viewBar,
|
||||
currentViewSorts,
|
||||
};
|
||||
}, renderHookConfig);
|
||||
|
||||
expect(result.current.currentViewSorts).toStrictEqual([]);
|
||||
|
||||
await act(async () => {
|
||||
result.current.viewBar.setAvailableSortDefinitions([sortDefinition]);
|
||||
|
||||
await result.current.viewBar.loadViewSorts([viewSort], currentViewId);
|
||||
result.current.viewBar.setCurrentViewId(currentViewId);
|
||||
});
|
||||
|
||||
expect(result.current.currentViewSorts).toStrictEqual([viewSort]);
|
||||
});
|
||||
|
||||
it('should upsertViewSort', async () => {
|
||||
const { result } = renderHook(() => {
|
||||
const viewBar = useViewBar({ viewBarId });
|
||||
|
||||
viewBar.setAvailableSortDefinitions([sortDefinition]);
|
||||
|
||||
viewBar.loadViewSorts([viewSort], currentViewId);
|
||||
viewBar.setCurrentViewId(currentViewId);
|
||||
|
||||
const { currentViewSortsState } = useViewScopedStates({
|
||||
viewScopeId: viewBarId,
|
||||
});
|
||||
const currentViewSorts = useRecoilValue(currentViewSortsState);
|
||||
|
||||
return {
|
||||
viewBar,
|
||||
currentViewSorts,
|
||||
};
|
||||
}, renderHookConfig);
|
||||
|
||||
expect(result.current.currentViewSorts).toStrictEqual([viewSort]);
|
||||
|
||||
const newSortFieldMetadataId = 'd9487757-183e-4fa0-a554-a980850cb23d';
|
||||
|
||||
const newSorts: Sort[] = [
|
||||
{
|
||||
fieldMetadataId: viewSort.fieldMetadataId,
|
||||
direction: 'desc',
|
||||
definition: sortDefinition,
|
||||
},
|
||||
{
|
||||
fieldMetadataId: newSortFieldMetadataId,
|
||||
direction: 'asc',
|
||||
definition: {
|
||||
...sortDefinition,
|
||||
fieldMetadataId: newSortFieldMetadataId,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// upsert an existing sort
|
||||
act(() => {
|
||||
result.current.viewBar.upsertViewSort(newSorts[0]);
|
||||
});
|
||||
|
||||
expect(result.current.currentViewSorts).toStrictEqual([
|
||||
{ ...newSorts[0], id: viewSort.id },
|
||||
]);
|
||||
|
||||
// upsert a new sort
|
||||
act(() => {
|
||||
result.current.viewBar.upsertViewSort(newSorts[1]);
|
||||
});
|
||||
|
||||
// expect currentViewSorts to contain both sorts
|
||||
expect(result.current.currentViewSorts).toStrictEqual([
|
||||
{ ...newSorts[0], id: viewSort.id },
|
||||
{ ...newSorts[1], id: undefined },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should remove view sort', () => {
|
||||
const { result } = renderHook(() => {
|
||||
const viewBar = useViewBar({ viewBarId });
|
||||
|
||||
viewBar.setAvailableSortDefinitions([sortDefinition]);
|
||||
|
||||
viewBar.loadViewSorts([viewSort], currentViewId);
|
||||
viewBar.setCurrentViewId(currentViewId);
|
||||
|
||||
const { currentViewSortsState } = useViewScopedStates({
|
||||
viewScopeId: viewBarId,
|
||||
});
|
||||
const currentViewSorts = useRecoilValue(currentViewSortsState);
|
||||
|
||||
return {
|
||||
viewBar,
|
||||
currentViewSorts,
|
||||
};
|
||||
}, renderHookConfig);
|
||||
|
||||
expect(result.current.currentViewSorts).toStrictEqual([viewSort]);
|
||||
|
||||
// remove an existing sort
|
||||
act(() => {
|
||||
result.current.viewBar.removeViewSort(sortDefinition.fieldMetadataId);
|
||||
});
|
||||
|
||||
expect(result.current.currentViewSorts).toStrictEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user