chore(front): move mocked-metadata helpers under src/testing (#20341)

## Summary

Follow-up to #20308. After that PR, production code no longer loads
mocked metadata when the user is unauthenticated. The remaining
mocked-metadata helpers (`useLoadMockedMetadata`,
`preloadMockedMetadata`) are now only consumed by Storybook decorators,
so move them next to the other testing-only utilities to make their
scope explicit and prevent accidental re-introduction of a runtime
dependency on mocks.

- `src/modules/metadata-store/hooks/useLoadMockedMetadata.ts`
  → `src/testing/hooks/useLoadMockedMetadata.ts`
- `src/modules/metadata-store/utils/preloadMockedMetadata.ts`
  → `src/testing/utils/preloadMockedMetadata.ts`

The three Storybook decorator imports
(`MockedMetadataLoadEffect`, `ObjectMetadataItemsDecorator`,
`WorkflowStepDecorator`) are updated to the new `~/testing/...` paths.

No runtime behavior change.

## Test plan

- [x] `npx oxlint --type-aware -c .oxlintrc.json` on touched files —
clean
- [x] `npx prettier --check` on touched files — clean
- [ ] CI: storybook, unit tests, e2e tests
This commit is contained in:
Charles Bochet
2026-05-07 10:32:41 +02:00
committed by GitHub
parent af76e04f8d
commit 027331c893
5 changed files with 6 additions and 6 deletions
@@ -1,4 +1,4 @@
import { useLoadMockedMetadata } from '@/metadata-store/hooks/useLoadMockedMetadata';
import { useLoadMockedMetadata } from '~/testing/hooks/useLoadMockedMetadata';
import { isMinimalMetadataReadyState } from '@/metadata-store/states/isMinimalMetadataReadyState';
import { metadataStoreState } from '@/metadata-store/states/metadataStoreState';
import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilyStateValue';
@@ -7,7 +7,7 @@ import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMembe
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { PreComputedChipGeneratorsProvider } from '@/object-metadata/components/PreComputedChipGeneratorsProvider';
import { useLoadMockedMetadata } from '@/metadata-store/hooks/useLoadMockedMetadata';
import { useLoadMockedMetadata } from '~/testing/hooks/useLoadMockedMetadata';
import { objectMetadataItemsSelector } from '@/object-metadata/states/objectMetadataItemsSelector';
import { getRecordFromRecordNode } from '@/object-record/cache/utils/getRecordFromRecordNode';
import { type WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
@@ -1,6 +1,6 @@
import { sidePanelWorkflowIdComponentState } from '@/side-panel/pages/workflow/states/sidePanelWorkflowIdComponentState';
import { SidePanelPageComponentInstanceContext } from '@/side-panel/states/contexts/SidePanelPageComponentInstanceContext';
import { useLoadMockedMetadata } from '@/metadata-store/hooks/useLoadMockedMetadata';
import { useLoadMockedMetadata } from '~/testing/hooks/useLoadMockedMetadata';
import { flowComponentState } from '@/workflow/states/flowComponentState';
import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
import { workflowVisualizerWorkflowRunIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowRunIdComponentState';
@@ -0,0 +1,83 @@
import { useUpdateMetadataStoreDraft } from '@/metadata-store/hooks/useUpdateMetadataStoreDraft';
import { metadataStoreState } from '@/metadata-store/states/metadataStoreState';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import {
preloadMockedMetadata,
type PreloadedMockedMetadata,
} from '~/testing/utils/preloadMockedMetadata';
const MOCKED_COLLECTION_HASH = 'mocked';
export const useLoadMockedMetadata = () => {
const store = useStore();
const { replaceDraft, applyChanges, resetMetadataStore } =
useUpdateMetadataStoreDraft();
const applyMockedMetadata = useCallback(
(data: PreloadedMockedMetadata) => {
resetMetadataStore();
replaceDraft(
'objectMetadataItems',
data.flatObjects,
MOCKED_COLLECTION_HASH,
);
replaceDraft(
'fieldMetadataItems',
data.flatFields,
MOCKED_COLLECTION_HASH,
);
replaceDraft(
'indexMetadataItems',
data.flatIndexes,
MOCKED_COLLECTION_HASH,
);
replaceDraft('views', data.flatViews, MOCKED_COLLECTION_HASH);
replaceDraft('viewFields', data.flatViewFields, MOCKED_COLLECTION_HASH);
replaceDraft('viewFilters', data.flatViewFilters, MOCKED_COLLECTION_HASH);
replaceDraft('viewSorts', data.flatViewSorts, MOCKED_COLLECTION_HASH);
replaceDraft('viewGroups', data.flatViewGroups, MOCKED_COLLECTION_HASH);
replaceDraft(
'viewFilterGroups',
data.flatViewFilterGroups,
MOCKED_COLLECTION_HASH,
);
replaceDraft(
'viewFieldGroups',
data.flatViewFieldGroups,
MOCKED_COLLECTION_HASH,
);
replaceDraft(
'navigationMenuItems',
data.navigationMenuItems,
MOCKED_COLLECTION_HASH,
);
applyChanges();
},
[replaceDraft, applyChanges, resetMetadataStore],
);
const isAlreadyMocked = useCallback(() => {
const entry = store.get(
metadataStoreState.atomFamily('objectMetadataItems'),
);
return (
entry.status === 'up-to-date' &&
entry.currentCollectionHash === MOCKED_COLLECTION_HASH
);
}, [store]);
const loadMockedMetadataAtomic = useCallback(async () => {
if (isAlreadyMocked()) {
return;
}
const data = await preloadMockedMetadata();
applyMockedMetadata(data);
}, [applyMockedMetadata, isAlreadyMocked]);
return { applyMockedMetadata, loadMockedMetadataAtomic };
};
@@ -0,0 +1,72 @@
import { splitObjectMetadataGqlResponse } from '@/metadata-store/utils/splitObjectMetadataGqlResponse';
import { splitViewWithRelated } from '@/metadata-store/utils/splitViewWithRelated';
import { type FlatFieldMetadataItem } from '@/metadata-store/types/FlatFieldMetadataItem';
import { type FlatIndexMetadataItem } from '@/metadata-store/types/FlatIndexMetadataItem';
import { type FlatObjectMetadataItem } from '@/metadata-store/types/FlatObjectMetadataItem';
import { type FlatView } from '@/metadata-store/types/FlatView';
import { type FlatViewField } from '@/metadata-store/types/FlatViewField';
import { type FlatViewFieldGroup } from '@/metadata-store/types/FlatViewFieldGroup';
import { type FlatViewFilter } from '@/metadata-store/types/FlatViewFilter';
import { type FlatViewFilterGroup } from '@/metadata-store/types/FlatViewFilterGroup';
import { type FlatViewGroup } from '@/metadata-store/types/FlatViewGroup';
import { type FlatViewSort } from '@/metadata-store/types/FlatViewSort';
import { type NavigationMenuItem } from '~/generated-metadata/graphql';
export type PreloadedMockedMetadata = {
flatObjects: FlatObjectMetadataItem[];
flatFields: FlatFieldMetadataItem[];
flatIndexes: FlatIndexMetadataItem[];
flatViews: FlatView[];
flatViewFields: FlatViewField[];
flatViewFilters: FlatViewFilter[];
flatViewSorts: FlatViewSort[];
flatViewGroups: FlatViewGroup[];
flatViewFilterGroups: FlatViewFilterGroup[];
flatViewFieldGroups: FlatViewFieldGroup[];
navigationMenuItems: NavigationMenuItem[];
};
export const preloadMockedMetadata =
async (): Promise<PreloadedMockedMetadata> => {
const [
{ mockedStandardObjectMetadataQueryResult },
{ mockedViews },
{ mockedNavigationMenuItems },
] = await Promise.all([
import(
'~/testing/mock-data/generated/metadata/objects/mock-objects-metadata'
),
import('~/testing/mock-data/generated/metadata/views/mock-views-data'),
import(
'~/testing/mock-data/generated/metadata/navigation-menu-items/mock-navigation-menu-items-data'
),
]);
const { flatObjects, flatFields, flatIndexes } =
splitObjectMetadataGqlResponse(mockedStandardObjectMetadataQueryResult);
const {
flatViews,
flatViewFields,
flatViewFilters,
flatViewSorts,
flatViewGroups,
flatViewFilterGroups,
flatViewFieldGroups,
} = splitViewWithRelated(mockedViews);
return {
flatObjects,
flatFields,
flatIndexes,
flatViews,
flatViewFields,
flatViewFilters,
flatViewSorts,
flatViewGroups,
flatViewFilterGroups,
flatViewFieldGroups,
navigationMenuItems: mockedNavigationMenuItems,
};
};