fix(tests): fix test failures

- Fix Prettier formatting in 8 files
- Fix useProvisionedRequestHandler.test.ts by mocking config.bootData
- Ensures ContextSrv can be instantiated in tests
This commit is contained in:
Roberto Jimenez Sanchez
2025-12-02 21:53:45 +01:00
parent cf01ea372b
commit ea7ade6983
9 changed files with 83 additions and 69 deletions
@@ -65,8 +65,12 @@ export function BrowseActions({ folderDTO }: Props) {
};
const onDelete = async () => {
const selectedDashboards = Object.keys(selectedItemsForActions.dashboard).filter((uid) => selectedItemsForActions.dashboard[uid]);
const selectedFolders = Object.keys(selectedItemsForActions.folder).filter((uid) => selectedItemsForActions.folder[uid]);
const selectedDashboards = Object.keys(selectedItemsForActions.dashboard).filter(
(uid) => selectedItemsForActions.dashboard[uid]
);
const selectedFolders = Object.keys(selectedItemsForActions.folder).filter(
(uid) => selectedItemsForActions.folder[uid]
);
await deleteDashboards({ dashboardUIDs: selectedDashboards });
await deleteFolders({ folderUIDs: selectedFolders });
trackAction('delete', selectedItemsForActions);
@@ -74,8 +78,12 @@ export function BrowseActions({ folderDTO }: Props) {
};
const onMove = async (destinationUID: string) => {
const selectedDashboards = Object.keys(selectedItemsForActions.dashboard).filter((uid) => selectedItemsForActions.dashboard[uid]);
const selectedFolders = Object.keys(selectedItemsForActions.folder).filter((uid) => selectedItemsForActions.folder[uid]);
const selectedDashboards = Object.keys(selectedItemsForActions.dashboard).filter(
(uid) => selectedItemsForActions.dashboard[uid]
);
const selectedFolders = Object.keys(selectedItemsForActions.folder).filter(
(uid) => selectedItemsForActions.folder[uid]
);
await moveFolders({ folderUIDs: selectedFolders, destinationUID });
await moveDashboards({ dashboardUIDs: selectedDashboards, destinationUID });
@@ -133,13 +133,13 @@ export function FolderActionsButton({ folder, repoType, isReadOnlyRepo }: Props)
try {
// Collect all dashboards under this folder and its children
const dashboardUIDs = await collectAllDashboardsUnderFolder(folder.uid);
// Create selected items object with all dashboards
const selectedDashboards: Record<string, boolean> = {};
dashboardUIDs.forEach((uid) => {
selectedDashboards[uid] = true;
});
setExportSelectedDashboards(selectedDashboards);
setShowExportFolderDrawer(true);
} catch (error) {
@@ -183,9 +183,7 @@ export function FolderActionsButton({ folder, repoType, isReadOnlyRepo }: Props)
label={deleteLabel}
/>
)}
{provisioningEnabled && isUnmanagedFolder && (
<MenuItem onClick={handleExportFolder} label={exportLabel} />
)}
{provisioningEnabled && isUnmanagedFolder && <MenuItem onClick={handleExportFolder} label={exportLabel} />}
</Menu>
);
@@ -91,10 +91,7 @@ export const refetchChildren = createAsyncThunk(
export const selectFolderWithAllDashboards = createAsyncThunk(
'browseDashboards/selectFolderWithAllDashboards',
async (
{ folderUID, isSelected }: { folderUID: string; isSelected: boolean },
{ dispatch, getState }
) => {
async ({ folderUID, isSelected }: { folderUID: string; isSelected: boolean }, { dispatch, getState }) => {
const state = getState().browseDashboards;
// Find the folder item to get its parentUID and managedBy
@@ -102,15 +99,17 @@ export const selectFolderWithAllDashboards = createAsyncThunk(
if (!isSelected) {
// When deselecting, use the normal action - it will handle deselecting all children recursively
dispatch(setItemSelectionState({
item: {
kind: 'folder',
uid: folderUID,
parentUID: folderItem?.parentUID,
managedBy: folderItem?.managedBy
},
isSelected: false
}));
dispatch(
setItemSelectionState({
item: {
kind: 'folder',
uid: folderUID,
parentUID: folderItem?.parentUID,
managedBy: folderItem?.managedBy,
},
isSelected: false,
})
);
return;
}
@@ -119,15 +118,17 @@ export const selectFolderWithAllDashboards = createAsyncThunk(
const dashboardUIDs = await collectAllDashboardsUnderFolder(folderUID);
// First, select the folder itself
dispatch(setItemSelectionState({
item: {
kind: 'folder',
uid: folderUID,
parentUID: folderItem?.parentUID,
managedBy: folderItem?.managedBy
},
isSelected: true
}));
dispatch(
setItemSelectionState({
item: {
kind: 'folder',
uid: folderUID,
parentUID: folderItem?.parentUID,
managedBy: folderItem?.managedBy,
},
isSelected: true,
})
);
// Then select all dashboards found
// We need to get the parentUID for each dashboard from the state
@@ -136,15 +137,17 @@ export const selectFolderWithAllDashboards = createAsyncThunk(
const dashboardItem = findItem(state.rootItems?.items ?? [], state.childrenByParentUID, dashboardUID);
// Even if dashboard isn't in state, we can still select it by UID
// The reducer will handle setting selectedItems.dashboard[dashboardUID] = true
dispatch(setItemSelectionState({
item: {
kind: 'dashboard',
uid: dashboardUID,
parentUID: dashboardItem?.parentUID ?? folderUID, // Fallback to folderUID if not found
managedBy: dashboardItem?.managedBy
},
isSelected: true
}));
dispatch(
setItemSelectionState({
item: {
kind: 'dashboard',
uid: dashboardUID,
parentUID: dashboardItem?.parentUID ?? folderUID, // Fallback to folderUID if not found
managedBy: dashboardItem?.managedBy,
},
isSelected: true,
})
);
}
}
);
@@ -29,4 +29,3 @@ function ExportToRepositoryRenderer({ model }: SceneComponentProps<ExportToRepos
/>
);
}
@@ -57,10 +57,7 @@ export function RepositoryList({ items }: Props) {
}
onRemove={unmanagedCount > 0 ? handlePushUnmanaged : undefined}
>
<Trans
i18nKey="provisioning.folder-repository-list.partial-managed"
values={{ managedCount, resourceCount }}
>
<Trans i18nKey="provisioning.folder-repository-list.partial-managed" values={{ managedCount, resourceCount }}>
{{ managedCount }}/{{ resourceCount }} resources managed by Git sync.
</Trans>
{unmanagedCount > 0 && (
@@ -60,17 +60,15 @@ function FormContent({ initialValues, selectedItems, workflowOptions, onDismiss
}, [repositories, selectedRepositoryName, isLoadingRepos]);
// Get selected repository
const repositoryView: RepositoryView | undefined = repositories.find(
(repo) => repo.name === selectedRepositoryName
);
const repositoryView: RepositoryView | undefined = repositories.find((repo) => repo.name === selectedRepositoryName);
// Compute workflow options based on selected repository
const selectedWorkflowOptions = repositoryView ? getWorkflowOptions(repositoryView) : workflowOptions;
const selectedDefaultWorkflow = repositoryView
? getDefaultWorkflow(repositoryView)
: (workflowOptions[0]?.value === 'branch' || workflowOptions[0]?.value === 'write'
? workflowOptions[0].value
: undefined);
: workflowOptions[0]?.value === 'branch' || workflowOptions[0]?.value === 'write'
? workflowOptions[0].value
: undefined;
// Update workflow, branch, and path when repository changes
useEffect(() => {
@@ -216,13 +214,14 @@ function FormContent({ initialValues, selectedItems, workflowOptions, onDismiss
</Box>
{/* Show form-level errors */}
{errors.root && (
<Alert severity="error" title={String(errors.root.message)} />
)}
{errors.root && <Alert severity="error" title={String(errors.root.message)} />}
{/* Info if folders are selected */}
{Object.keys(selectedItems.folder || {}).filter((uid) => selectedItems.folder[uid]).length > 0 && (
<Alert severity="info" title={t('browse-dashboards.bulk-export-resources-form.folders-info', 'Folders in selection')}>
<Alert
severity="info"
title={t('browse-dashboards.bulk-export-resources-form.folders-info', 'Folders in selection')}
>
{t(
'browse-dashboards.bulk-export-resources-form.folders-info-description',
'Folders will be left behind. New folders will be created in the repository based on the resource folder structure.'
@@ -297,7 +296,10 @@ function FormContent({ initialValues, selectedItems, workflowOptions, onDismiss
<Input
type="text"
{...methods.register('path')}
placeholder={t('browse-dashboards.bulk-export-resources-form.path-placeholder', 'e.g., dashboards/')}
placeholder={t(
'browse-dashboards.bulk-export-resources-form.path-placeholder',
'e.g., dashboards/'
)}
/>
</Field>
)}
@@ -318,10 +320,7 @@ function FormContent({ initialValues, selectedItems, workflowOptions, onDismiss
<Button variant="secondary" fill="outline" onClick={onDismiss} disabled={isCreatingJob}>
<Trans i18nKey="browse-dashboards.bulk-export-resources-form.button-cancel">Cancel</Trans>
</Button>
<Button
type="submit"
disabled={!!job || isCreatingJob || hasSubmitted || !selectedRepositoryName}
>
<Button type="submit" disabled={!!job || isCreatingJob || hasSubmitted || !selectedRepositoryName}>
{isCreatingJob
? t('browse-dashboards.bulk-export-resources-form.button-exporting', 'Exporting...')
: t('browse-dashboards.bulk-export-resources-form.button-export', 'Export')}
@@ -382,4 +381,3 @@ const getPathPrefixStyles = (theme: GrafanaTheme2) => ({
whiteSpace: 'nowrap',
}),
});
@@ -7,9 +7,21 @@ import { ResourceWrapper } from 'app/api/clients/provisioning/v0alpha1';
import { useProvisionedRequestHandler, RequestHandlers } from './useProvisionedRequestHandler';
jest.mock('@grafana/runtime', () => ({
getAppEvents: jest.fn(),
}));
jest.mock('@grafana/runtime', () => {
const original = jest.requireActual('@grafana/runtime');
return {
...original,
getAppEvents: jest.fn(),
config: {
...original.config,
bootData: {
user: {},
settings: {},
navTree: [],
},
},
};
});
jest.mock('@grafana/i18n', () => ({
t: jest.fn((key: string, defaultValue: string) => defaultValue),
@@ -12,9 +12,10 @@ import { findItem } from '../../browse-dashboards/state/utils';
import { DashboardTreeSelection } from '../../browse-dashboards/types';
// This hook checks if selected items are unmanaged (not managed by any repository)
export function useSelectionUnmanagedStatus(
selectedItems: Omit<DashboardTreeSelection, 'panel' | '$all'>
): { hasUnmanaged: boolean; isLoading: boolean } {
export function useSelectionUnmanagedStatus(selectedItems: Omit<DashboardTreeSelection, 'panel' | '$all'>): {
hasUnmanaged: boolean;
isLoading: boolean;
} {
const browseState = useSelector((state) => state.browseDashboards);
const [, stateManager] = useSearchStateManager();
const isSearching = stateManager.hasSearchFilters();
@@ -155,4 +156,3 @@ export function useSelectionUnmanagedStatus(
return status;
}
@@ -69,4 +69,3 @@ export async function collectAllDashboardsUnderFolder(folderUID: string): Promis
return dashboardUIDs;
}