Skip to content
Snippets Groups Projects
Unverified Commit b32cf746 authored by Jesse Devaney's avatar Jesse Devaney Committed by GitHub
Browse files

Add opt-in CC option to Admin Email Setting (#35478)

* Add opt-in option to CC recipients in admin email settings

* fix type errors

* add E2E tests for CC/BCC email option
parent 6e530e28
No related branches found
No related tags found
No related merge requests found
......@@ -54,6 +54,13 @@ export const clearInbox = () => {
return cy.request("DELETE", `http://localhost:${WEB_PORT}/email/all`);
};
export const viewEmailPage = emailSubject => {
const webmailInterface = `http://localhost:${WEB_PORT}`;
cy.window().then(win => (win.location.href = webmailInterface));
cy.findByText(emailSubject).click();
};
export const openEmailPage = emailSubject => {
const webmailInterface = `http://localhost:${WEB_PORT}`;
......
......@@ -16,6 +16,8 @@ import {
setupSubscriptionWithRecipient,
openPulseSubscription,
sendEmailAndVisitIt,
clickSend,
viewEmailPage,
} from "e2e/support/helpers";
import { ORDERS_DASHBOARD_ID } from "e2e/support/cypress_sample_instance_data";
import { USERS } from "e2e/support/cypress_data";
......@@ -152,6 +154,46 @@ describe("scenarios > dashboard > subscriptions", () => {
cy.findByText("Email this dashboard").should("exist");
});
});
it("should send as BCC by default", () => {
const ORDERS_DASHBOARD_NAME = "Orders in a dashboard";
assignRecipients();
sidebar().within(() => {
clickSend();
});
viewEmailPage(ORDERS_DASHBOARD_NAME);
cy.get(".main-container").within(() => {
cy.findByText("Bcc:").should("exist");
cy.findByText(`${admin.email}`).should("exist");
cy.findByText(`${normal.email}`).should("exist");
});
});
it("should send as CC when opted-in", () => {
// opt-in to CC
cy.visit("/admin/settings/email");
cy.findByTestId("bcc-enabled?-setting")
.findByLabelText("CC - Disclose recipients")
.click();
const ORDERS_DASHBOARD_NAME = "Orders in a dashboard";
assignRecipients();
sidebar().within(() => {
clickSend();
});
viewEmailPage(ORDERS_DASHBOARD_NAME);
cy.get(".main-container").within(() => {
cy.findByText("Bcc:").should("not.exist");
cy.findByText(`${admin.email}`).should("exist");
cy.findByText(`${normal.email}`).should("exist");
});
});
});
describe("let non-users unsubscribe from subscriptions", () => {
......@@ -639,6 +681,23 @@ function assignRecipient({
.blur(); // blur is needed to close the popover
}
function assignRecipients({
users = [admin, normal],
dashboard_id = ORDERS_DASHBOARD_ID,
} = {}) {
openDashboardSubscriptions(dashboard_id);
cy.findByText("Email it").click();
const userInput = users
.map(user => `${user.first_name} ${user.last_name}{enter}`)
.join("");
cy.findByPlaceholderText("Enter user names or email addresses")
.click()
.type(userInput)
.blur(); // blur is needed to close the popover
}
function clickButton(button_name) {
cy.contains(button_name).closest(".Button").should("not.be.disabled").click();
}
......
......@@ -138,6 +138,7 @@ export const createMockSettings = (opts?: Partial<Settings>): Settings => ({
"application-name": "Metabase",
"available-fonts": [],
"available-locales": null,
"bcc-enabled?": true,
"cloud-gateway-ips": null,
"custom-formatting": {},
"custom-homepage": false,
......
......@@ -196,6 +196,7 @@ export interface Settings {
"application-name": string;
"available-fonts": string[];
"available-locales": LocaleData[] | null;
"bcc-enabled?": boolean;
"cloud-gateway-ips": string[] | null;
"custom-formatting": FormattingSettings;
"custom-homepage": boolean;
......
import { Radio } from "metabase/ui";
interface Options {
value: boolean;
name: string;
}
interface BccToggleWidgetProps {
onChange: (value: boolean) => void;
setting: {
key: "bcc-enabled?";
value?: boolean;
defaultValue: true;
options: Options[];
};
}
const stringValue = (value: boolean): "true" | "false" => `${value}`;
export function BccToggleWidget({ onChange, setting }: BccToggleWidgetProps) {
return (
<Radio.Group
mt="0.25rem"
value={stringValue(setting.value ?? setting.defaultValue)}
onChange={value => onChange(value === "true")}
>
{setting.options.map(({ value, name }) => (
<Radio key={name} mb="0.5rem" value={stringValue(value)} label={name} />
))}
</Radio.Group>
);
}
......@@ -41,6 +41,7 @@ import SectionDivider from "./components/widgets/SectionDivider";
import SettingsUpdatesForm from "./components/SettingsUpdatesForm/SettingsUpdatesForm";
import SettingsEmailForm from "./components/SettingsEmailForm";
import { BccToggleWidget } from "./components/Email/BccToggleWidget";
import SetupCheckList from "./setup/components/SetupCheckList";
import SlackSettings from "./slack/containers/SlackSettings";
import {
......@@ -262,6 +263,20 @@ export const ADMIN_SETTINGS_SECTIONS = {
widget: SettingCommaDelimitedInput,
validations: [["email_list", t`That's not a valid email address`]],
},
{
key: "bcc-enabled?",
display_name: t`Add Recipients as CC or BCC`,
description: t`Control the visibility of recipients.`,
options: [
{ value: true, name: t`BCC - Hide recipients` },
{
value: false,
name: t`CC - Disclose recipients`,
},
],
defaultValue: true,
widget: BccToggleWidget,
},
],
},
slack: {
......
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