Skip to content
Snippets Groups Projects
Unverified Commit 004ee0ab authored by Alexander Polyankin's avatar Alexander Polyankin Committed by GitHub
Browse files

Do not show edit model menu options without write permissions (#32261)

parent 6e14e94f
No related branches found
No related tags found
No related merge requests found
......@@ -41,26 +41,30 @@ if (hasPremiumFeature("content_management")) {
const isVerified = isItemVerified(latestModerationReview);
if (isModerator) {
return {
title: isVerified
? t`Remove verification`
: isDataset
? t`Verify this model`
: t`Verify this question`,
icon: isVerified ? "close" : verifiedIconName,
action: () => {
if (isVerified) {
removeReview({ itemId: id, itemType: "card" });
} else {
verifyItem({ itemId: id, itemType: "card" });
}
reload();
return [
{
title: isVerified
? t`Remove verification`
: isDataset
? t`Verify this model`
: t`Verify this question`,
icon: isVerified ? "close" : verifiedIconName,
action: () => {
if (isVerified) {
removeReview({ itemId: id, itemType: "card" });
} else {
verifyItem({ itemId: id, itemType: "card" });
}
reload();
},
testId: isVerified
? "moderation-remove-verification-action"
: "moderation-verify-action",
},
testId: isVerified
? "moderation-remove-verification-action"
: "moderation-verify-action",
};
];
}
return [];
},
});
}
......@@ -198,7 +198,7 @@ export const PLUGIN_MODERATION = {
question?: Question,
isModerator?: boolean,
reload?: () => void,
) => ({}),
) => [],
};
export const PLUGIN_CACHING = {
......
......@@ -128,14 +128,14 @@ const QuestionActions = ({
}
extraButtons.push(
PLUGIN_MODERATION.getMenuItems(
...PLUGIN_MODERATION.getMenuItems(
question,
isModerator,
dispatchSoftReloadCard,
),
);
if (isDataset) {
if (canWrite && isDataset) {
extraButtons.push(
{
title: t`Edit query definition`,
......@@ -237,12 +237,14 @@ const QuestionActions = ({
/>
</ViewHeaderIconButtonContainer>
</Tooltip>
<EntityMenu
triggerAriaLabel={t`Move, archive, and more...`}
items={extraButtons}
triggerIcon="ellipsis"
tooltip={t`Move, archive, and more...`}
/>
{extraButtons.length > 0 && (
<EntityMenu
triggerAriaLabel={t`Move, archive, and more...`}
items={extraButtons}
triggerIcon="ellipsis"
tooltip={t`Move, archive, and more...`}
/>
)}
</>
);
};
......
import userEvent from "@testing-library/user-event";
import { renderWithProviders, screen } from "__support__/ui";
import { getMetadata } from "metabase/selectors/metadata";
import { Card, Database } from "metabase-types/api";
import { createMockCard, createMockNativeCard } from "metabase-types/api/mocks";
import { createSampleDatabase } from "metabase-types/api/mocks/presets";
import { createMockState } from "metabase-types/store/mocks";
import { createMockEntitiesState } from "__support__/store";
import QuestionActions from "metabase/query_builder/components/QuestionActions";
import { createMockCard, createMockNativeCard } from "metabase-types/api/mocks";
import { getMetadata } from "metabase/selectors/metadata";
import { Card } from "metabase-types/api";
import {
getIcon,
queryIcon,
renderWithProviders,
screen,
} from "__support__/ui";
import Question from "metabase-lib/Question";
import QuestionActions from "./QuestionActions";
const TEST_STRUCTURED_CARD = createMockCard();
const TEST_NATIVE_CARD = createMockNativeCard();
const ICON_CASES_CARDS = [
createMockCard({ name: "GUI" }),
createMockNativeCard({ name: "SQL" }),
];
const iconList = [
const ICON_CASES_LABELS = [
{ label: "bookmark icon", tooltipText: "Bookmark" },
{ label: "info icon", tooltipText: "More info" },
{
......@@ -20,9 +28,19 @@ const iconList = [
},
];
function setup({ card }: { card: Card }) {
const ICON_CASES = ICON_CASES_CARDS.flatMap(card =>
ICON_CASES_LABELS.map(labels => ({ ...labels, card })),
);
interface SetupOpts {
card: Card;
databases?: Database[];
}
function setup({ card, databases = [createSampleDatabase()] }: SetupOpts) {
const state = createMockState({
entities: createMockEntitiesState({
databases,
questions: [card],
}),
});
......@@ -46,22 +64,55 @@ function setup({ card }: { card: Card }) {
);
}
describe("Question Actions | Icons", () => {
["structured", "native"].forEach(queryType => {
iconList.forEach(({ label, tooltipText }) => {
it(`should display the "${label}" icon with the "${tooltipText}" tooltip for ${queryType} questions`, async () => {
setup({
card:
queryType === "structured"
? TEST_STRUCTURED_CARD
: TEST_NATIVE_CARD,
});
describe("QuestionActions", () => {
it.each(ICON_CASES)(
`should display the "$label" icon with the "$tooltipText" tooltip for $card.name questions`,
async ({ label, tooltipText, card }) => {
setup({ card });
await userEvent.hover(screen.getByRole("button", { name: label }));
const tooltip = screen.getByRole("tooltip", { name: tooltipText });
expect(tooltip).toHaveAttribute("data-placement", "top");
expect(tooltip).toHaveTextContent(tooltipText);
},
);
await userEvent.hover(screen.getByRole("button", { name: label }));
const tooltip = screen.getByRole("tooltip", { name: tooltipText });
expect(tooltip).toHaveAttribute("data-placement", "top");
expect(tooltip).toHaveTextContent(tooltipText);
});
it("should allow to edit the model only with write permissions", () => {
setup({
card: createMockCard({
dataset: true,
can_write: true,
}),
});
userEvent.click(getIcon("ellipsis"));
expect(screen.getByText("Edit query definition")).toBeInTheDocument();
expect(screen.getByText("Edit metadata")).toBeInTheDocument();
});
it("should not allow to edit the model without write permissions", () => {
setup({
card: createMockCard({
dataset: true,
can_write: false,
}),
});
userEvent.click(getIcon("ellipsis"));
expect(screen.queryByText("Edit query definition")).not.toBeInTheDocument();
expect(screen.queryByText("Edit metadata")).not.toBeInTheDocument();
});
it("should not render the menu when there are no menu items", () => {
setup({
card: createMockCard({
dataset: true,
can_write: false,
}),
databases: [],
});
expect(getIcon("info")).toBeInTheDocument();
expect(queryIcon("ellipsis")).not.toBeInTheDocument();
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment