From 81626ba88d721157ced6f0c0036320d4665b30b5 Mon Sep 17 00:00:00 2001 From: Leo <108552997+lpskdl@users.noreply.github.com> Date: Fri, 16 Sep 2022 15:51:00 +0200 Subject: [PATCH] [v9.1.x] Browse: Hide dashboard actions if user does not have enough permission (#55279) * Browse: Hide dashboard actions if user does not have enough permission (#55218) * hide dashboard actions if user does not have enough permission * improve test description (cherry picked from commit 896d684065bad1fb21fc39afb9f101bf76dd1a37) * fix broken test on backport pr --- .../components/ManageDashboards.test.tsx | 70 +++++++++++++++++++ .../search/components/ManageDashboardsNew.tsx | 25 ++++--- 2 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 public/app/features/search/components/ManageDashboards.test.tsx diff --git a/public/app/features/search/components/ManageDashboards.test.tsx b/public/app/features/search/components/ManageDashboards.test.tsx new file mode 100644 index 00000000000..c2088a59aa8 --- /dev/null +++ b/public/app/features/search/components/ManageDashboards.test.tsx @@ -0,0 +1,70 @@ +import { render, screen, waitFor } from '@testing-library/react'; +import React from 'react'; +import { Provider } from 'react-redux'; + +import { contextSrv } from 'app/core/services/context_srv'; +import { configureStore } from 'app/store/configureStore'; +import { FolderDTO } from 'app/types'; + +import ManageDashboardsNew from './ManageDashboardsNew'; + +jest.mock('@grafana/runtime', () => { + const originMock = jest.requireActual('@grafana/runtime'); + return { + ...originMock, + reportInteraction: jest.fn(), + }; +}); +jest.mock('app/core/services/context_srv', () => { + const originMock = jest.requireActual('app/core/services/context_srv'); + + return { + ...originMock, + contextSrv: { + ...originMock.context_srv, + user: {}, + hasAccess: jest.fn(), + }, + }; +}); + +const setup = async (options?: { folder?: FolderDTO }) => { + const { folder = {} as FolderDTO } = options || {}; + const store = configureStore(); + + const { rerender } = await waitFor(() => + render( + + + + ) + ); + + return { rerender, store }; +}; + +jest.spyOn(console, 'error').mockImplementation(); + +describe('ManageDashboards', () => { + beforeEach(() => { + (contextSrv.hasAccess as jest.Mock).mockClear(); + }); + it("should hide and show dashboard actions based on user's permissions", async () => { + (contextSrv.hasAccess as jest.Mock).mockReturnValue(false); + + const { rerender, store } = await setup(); + + expect(screen.queryByRole('button', { name: /new/i })).not.toBeInTheDocument(); + + (contextSrv.hasAccess as jest.Mock).mockReturnValue(true); + await waitFor(() => + rerender( + + + + ) + ); + + expect(screen.getByRole('button', { name: /new/i })).toBeInTheDocument(); + }); +}); diff --git a/public/app/features/search/components/ManageDashboardsNew.tsx b/public/app/features/search/components/ManageDashboardsNew.tsx index 710a6ea2769..6f4a0b1ed4a 100644 --- a/public/app/features/search/components/ManageDashboardsNew.tsx +++ b/public/app/features/search/components/ManageDashboardsNew.tsx @@ -29,16 +29,20 @@ export const ManageDashboardsNew = React.memo(({ folder }: Props) => { const folderId = folder?.id; // const folderUid = folder?.uid; const canSave = folder?.canSave; + const { isEditor } = contextSrv; const hasEditPermissionInFolders = folder ? canSave : contextSrv.hasEditPermissionInFolders; - + const canCreateFolders = contextSrv.hasAccess(AccessControlAction.FoldersCreate, isEditor); + const canCreateDashboards = contextSrv.hasAccess( + AccessControlAction.DashboardsCreate, + hasEditPermissionInFolders || !!canSave + ); let [includePanels, setIncludePanels] = useLocalStorage(SEARCH_PANELS_LOCAL_STORAGE_KEY, true); if (!config.featureToggles.panelTitleSearch) { includePanels = false; } - const { isEditor } = contextSrv; - const [inputValue, setInputValue] = useState(query.query ?? ''); + const onSearchQueryChange = (e: React.ChangeEvent) => { e.preventDefault(); setInputValue(e.currentTarget.value); @@ -60,14 +64,13 @@ export const ManageDashboardsNew = React.memo(({ folder }: Props) => { suffix={false ? : null} /> - + {canCreateFolders && canCreateDashboards && ( + + )}