Skip to content
Snippets Groups Projects
Unverified Commit 7854e07a authored by Oisin Coveney's avatar Oisin Coveney Committed by GitHub
Browse files

fix: Ensure interactive embedding CTA matches instance features (#44197)

parent 81a586df
No related branches found
No related tags found
No related merge requests found
Showing
with 148 additions and 3 deletions
......@@ -4,6 +4,7 @@ import {
PLUGIN_ADMIN_SETTINGS_UPDATES,
PLUGIN_EMBEDDING,
} from "metabase/plugins";
import { isInteractiveEmbeddingEnabled } from "metabase-enterprise/embedding/selectors";
import { hasPremiumFeature } from "metabase-enterprise/settings";
import { EmbeddingAppOriginDescription } from "./components/EmbeddingAppOriginDescription";
......@@ -16,6 +17,8 @@ const SLUG = "embedding-in-other-applications/full-app";
if (hasPremiumFeature("embedding")) {
PLUGIN_EMBEDDING.isEnabled = () => true;
PLUGIN_EMBEDDING.isInteractiveEmbeddingEnabled =
isInteractiveEmbeddingEnabled;
PLUGIN_ADMIN_SETTINGS_UPDATES.push(sections => {
return {
......
import { getPlan } from "metabase/common/utils/plan";
import { getSetting } from "metabase/selectors/settings";
import type { EnterpriseState } from "metabase-enterprise/settings/types";
export const isInteractiveEmbeddingEnabled = (state: EnterpriseState) => {
const plan = getPlan(getSetting(state, "token-features"));
return plan === "pro-cloud" || plan === "pro-self-hosted";
};
......@@ -445,6 +445,7 @@ export const PLUGIN_MODEL_PERSISTENCE = {
export const PLUGIN_EMBEDDING = {
isEnabled: () => false,
isInteractiveEmbeddingEnabled: (_state: State) => false,
};
export const PLUGIN_CONTENT_VERIFICATION = {
......
......@@ -3,7 +3,8 @@ import { t } from "ttag";
import { getPlan } from "metabase/common/utils/plan";
import Link from "metabase/core/components/Link";
import { useSelector } from "metabase/lib/redux";
import { getIsPaidPlan, getSetting } from "metabase/selectors/settings";
import { PLUGIN_EMBEDDING } from "metabase/plugins";
import { getSetting } from "metabase/selectors/settings";
import { Text, Group, Stack, Box } from "metabase/ui";
import {
......@@ -14,12 +15,14 @@ import {
} from "./InteractiveEmbeddingCTA.styled";
const useCTAText = () => {
const isPaidPlan = useSelector(getIsPaidPlan);
const isInteractiveEmbeddingEnabled = useSelector(
PLUGIN_EMBEDDING.isInteractiveEmbeddingEnabled,
);
const plan = useSelector(state =>
getPlan(getSetting(state, "token-features")),
);
if (isPaidPlan) {
if (isInteractiveEmbeddingEnabled) {
return {
showProBadge: false,
description: t`Your plan allows you to use Interactive Embedding create interactive embedding experiences with drill-through and more.`,
......
import { screen } from "__support__/ui";
import { setup } from "./setup";
describe("InteractiveEmbeddingCTA", () => {
it("should display a CTA to the product page when plan is OSS", () => {
setup();
expect(screen.getByText("Interactive Embedding")).toBeInTheDocument();
expect(screen.getByText("Pro")).toBeInTheDocument();
expect(
screen.getByText(
"Give your customers the full power of Metabase in your own app, with SSO, advanced permissions, customization, and more.",
),
).toBeInTheDocument();
expect(screen.getByTestId("interactive-embedding-cta")).toHaveAttribute(
"href",
"https://www.metabase.com/product/embedded-analytics?utm_source=oss&utm_media=static-embed-popover",
);
});
});
import { screen } from "__support__/ui";
import { type InteractiveEmbeddingCTASetupOptions, setup } from "./setup";
const setupEnterprise = (
opts?: Partial<InteractiveEmbeddingCTASetupOptions>,
) => {
setup({
...opts,
hasEnterprisePlugins: true,
});
};
describe("InteractiveEmbeddingCTA", () => {
it("should display a CTA to the product page when plan is starter", () => {
setupEnterprise();
expect(screen.getByText("Interactive Embedding")).toBeInTheDocument();
expect(screen.getByText("Pro")).toBeInTheDocument();
expect(
screen.getByText(
"Give your customers the full power of Metabase in your own app, with SSO, advanced permissions, customization, and more.",
),
).toBeInTheDocument();
expect(screen.getByTestId("interactive-embedding-cta")).toHaveAttribute(
"href",
"https://www.metabase.com/product/embedded-analytics?utm_source=oss&utm_media=static-embed-popover",
);
});
});
import userEvent from "@testing-library/user-event";
import { Route } from "react-router";
import { screen, renderWithProviders } from "__support__/ui";
import { checkNotNull } from "metabase/lib/types";
import { createMockTokenStatus } from "metabase-types/api/mocks";
import {
createMockSettingsState,
createMockState,
} from "metabase-types/store/mocks";
import { screen } from "__support__/ui";
import { createMockTokenFeatures } from "metabase-types/api/mocks";
import { InteractiveEmbeddingCTA } from "./InteractiveEmbeddingCTA";
import { type InteractiveEmbeddingCTASetupOptions, setup } from "./setup";
const setup = ({ isPaidPlan }: { isPaidPlan: boolean }) => {
const { history } = renderWithProviders(
<Route path="*" component={InteractiveEmbeddingCTA}></Route>,
{
storeInitialState: createMockState({
settings: createMockSettingsState({
"token-status": createMockTokenStatus({ valid: isPaidPlan }),
}),
}),
withRouter: true,
},
);
return {
history: checkNotNull(history),
};
const setupPremium = (opts?: Partial<InteractiveEmbeddingCTASetupOptions>) => {
return setup({
...opts,
tokenFeatures: createMockTokenFeatures({ embedding: true }),
hasEnterprisePlugins: true,
});
};
describe("InteractiveEmbeddingCTA", () => {
it("renders correctly for paid plan", async () => {
const { history } = setup({ isPaidPlan: true });
it("should display a link to the embedding settings when plan is pro", async () => {
const { history } = setupPremium();
expect(screen.getByText("Interactive Embedding")).toBeInTheDocument();
expect(screen.queryByText("Pro")).not.toBeInTheDocument();
......@@ -46,21 +31,4 @@ describe("InteractiveEmbeddingCTA", () => {
"/admin/settings/embedding-in-other-applications/full-app",
);
});
it("renders correctly for OSS", () => {
setup({ isPaidPlan: false });
expect(screen.getByText("Interactive Embedding")).toBeInTheDocument();
expect(screen.getByText("Pro")).toBeInTheDocument();
expect(
screen.getByText(
"Give your customers the full power of Metabase in your own app, with SSO, advanced permissions, customization, and more.",
),
).toBeInTheDocument();
expect(screen.getByTestId("interactive-embedding-cta")).toHaveAttribute(
"href",
"https://www.metabase.com/product/embedded-analytics?utm_source=oss&utm_media=static-embed-popover",
);
});
});
import { Route } from "react-router";
import { setupEnterprisePlugins } from "__support__/enterprise";
import { mockSettings } from "__support__/settings";
import { renderWithProviders } from "__support__/ui";
import { checkNotNull } from "metabase/lib/types";
import { InteractiveEmbeddingCTA } from "metabase/public/components/EmbedModal/SelectEmbedTypePane/InteractiveEmbeddingCTA";
import type { TokenFeatures } from "metabase-types/api";
import { createMockTokenFeatures } from "metabase-types/api/mocks";
import { createMockState } from "metabase-types/store/mocks";
export type InteractiveEmbeddingCTASetupOptions = {
tokenFeatures?: TokenFeatures;
hasEnterprisePlugins?: boolean;
isPaidPlan?: boolean;
};
export const setup = ({
tokenFeatures = createMockTokenFeatures(),
hasEnterprisePlugins = false,
}: InteractiveEmbeddingCTASetupOptions = {}) => {
const settings = mockSettings({ "token-features": tokenFeatures });
const state = createMockState({
settings,
});
if (hasEnterprisePlugins) {
setupEnterprisePlugins();
}
const { history } = renderWithProviders(
<Route path="*" component={InteractiveEmbeddingCTA}></Route>,
{
storeInitialState: state,
withRouter: true,
},
);
return {
history: checkNotNull(history),
};
};
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