Skip to content

Commit b47a34d

Browse files
authored
Merge branch 'main' into dependabot/npm_and_yarn/stylelint-7e83b71fdd
2 parents 1dc51e4 + dc2c6f1 commit b47a34d

File tree

12 files changed

+148
-14
lines changed

12 files changed

+148
-14
lines changed

src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/dashboard/Dashboard.test.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,37 @@ it("shows chart tooltip on the action needed tab, non-US user", async () => {
372372
expect(dialogContentPart).toBeInTheDocument();
373373
});
374374

375+
it("shows chart tooltip on the action needed tab, non-US user (feature flag IncreasedFreeMaxBreachEmails)", async () => {
376+
const user = userEvent.setup();
377+
const ComposedDashboard = composeStory(DashboardNonUsNoBreaches, Meta);
378+
render(
379+
<ComposedDashboard
380+
enabledFeatureFlags={["IncreasedFreeMaxBreachEmails"]}
381+
/>,
382+
);
383+
384+
const chartCaption = screen.getByText(
385+
"This chart shows how many times your info is actively exposed.",
386+
);
387+
expect(chartCaption).toBeInTheDocument();
388+
const chartTooltip = within(chartCaption).getByRole("button", {
389+
name: "Open modal",
390+
});
391+
expect(chartTooltip).toBeInTheDocument();
392+
await user.click(chartTooltip);
393+
394+
expect(
395+
screen.getByRole("dialog", {
396+
name: "About your number of active exposures",
397+
}),
398+
).toBeInTheDocument();
399+
400+
const dialogContentPart = screen.getByText(
401+
"This chart includes the total number of times we found each type of data exposed across all data breaches for up to ⁨20⁩ email addresses that you are currently monitoring.",
402+
);
403+
expect(dialogContentPart).toBeInTheDocument();
404+
});
405+
375406
it("shows chart tooltip on the fixed tab, non-US user", async () => {
376407
const user = userEvent.setup();
377408
const ComposedDashboard = composeStory(DashboardNonUsNoBreaches, Meta);

src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/EmailAddressAdder.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,16 @@ import { useL10n } from "../../../../../../hooks/l10n";
2121
import { ModalOverlay } from "../../../../../../components/client/dialog/ModalOverlay";
2222
import { Dialog } from "../../../../../../components/client/dialog/Dialog";
2323
import { type onAddEmail } from "./actions";
24-
import { CONST_MAX_NUM_ADDRESSES } from "../../../../../../../constants";
24+
import {
25+
CONST_MAX_NUM_ADDRESSES,
26+
CONST_MAX_NUM_ADDRESSES_PLUS,
27+
} from "../../../../../../../constants";
2528
import { useTelemetry } from "../../../../../../hooks/useTelemetry";
29+
import { FeatureFlagName } from "../../../../../../../db/tables/featureFlags";
2630

2731
export type Props = {
2832
onAddEmail: typeof onAddEmail;
33+
enabledFeatureFlags: FeatureFlagName[];
2934
};
3035

3136
export const EmailAddressAdder = (props: Props) => {
@@ -124,7 +129,11 @@ const EmailAddressAddForm = (props: Props) => {
124129
<>
125130
<p>
126131
{l10n.getString("add-email-your-account-includes", {
127-
total: CONST_MAX_NUM_ADDRESSES,
132+
total: props.enabledFeatureFlags.includes(
133+
"IncreasedFreeMaxBreachEmails",
134+
)
135+
? CONST_MAX_NUM_ADDRESSES_PLUS
136+
: CONST_MAX_NUM_ADDRESSES,
128137
})}
129138
</p>
130139
<form

src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/SettingsPageRedesign.test.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
SettingsEditYourInfo,
2626
SettingsEditYourInfoAdditionalMonitoredEmails,
2727
SettingsEditYourInfoMaxMonitoredEmails,
28+
SettingsEditYourInfoMaxMonitoredEmailsIncreased,
2829
} from "./stories/SettingsEditInfoNonUsUsers.stories";
2930
import { mockedActions } from "./stories/SettingsStoryWrapper";
3031

@@ -70,6 +71,25 @@ describe("Settings page redesign", () => {
7071
expect(maxEmailsIndicator).toBeInTheDocument();
7172
});
7273

74+
it("shows the max increased number of emails that can be added to the list of addresses to monitor for breaches", () => {
75+
const ComposedStory = composeStory(
76+
SettingsEditYourInfo,
77+
SettingsEditYourInfoMeta,
78+
);
79+
render(
80+
<ComposedStory
81+
enabledFeatureFlags={[
82+
"SidebarNavigationRedesign",
83+
"EditScanProfileDetails",
84+
"IncreasedFreeMaxBreachEmails",
85+
]}
86+
/>,
87+
);
88+
89+
const maxEmailsIndicator = screen.getByText("Add up to ⁨20⁩");
90+
expect(maxEmailsIndicator).toBeInTheDocument();
91+
});
92+
7393
it("adds an email to the list of addresses to monitor for breaches", async () => {
7494
mockedActions.onAddEmail.mockResolvedValue({
7595
success: true,
@@ -244,6 +264,19 @@ describe("Settings page redesign", () => {
244264
});
245265
expect(addEmailButton).not.toBeInTheDocument();
246266
});
267+
268+
it("does not show the option to add email addresses when the max increased number of email addresses have been added", () => {
269+
const ComposedStory = composeStory(
270+
SettingsEditYourInfoMaxMonitoredEmailsIncreased,
271+
SettingsEditYourInfoMeta,
272+
);
273+
render(<ComposedStory />);
274+
275+
const addEmailButton = screen.queryByRole("button", {
276+
name: "Add email address",
277+
});
278+
expect(addEmailButton).not.toBeInTheDocument();
279+
});
247280
});
248281

249282
describe("Edit your info (US users)", () => {

src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/actions.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { updateOnerepDataBrokerScanProfile } from "../../../../../../functions/s
3535
import { hasPremium } from "../../../../../../functions/universal/user";
3636
import { type NormalizedProfileData } from "./panels/SettingsPanelEditProfile/EditProfileForm";
3737
import { OnerepUsPhoneNumber } from "../../../../../../functions/server/onerep";
38+
import { getEnabledFeatureFlags } from "../../../../../../../db/tables/featureFlags";
3839

3940
export type AddEmailFormState =
4041
| { success?: never }
@@ -90,9 +91,16 @@ export async function onAddEmail(
9091
};
9192
}
9293

93-
const maxNumEmailAddresses = hasPremium(subscriber)
94+
const enabledFeatureFlags = await getEnabledFeatureFlags({
95+
email: subscriber.primary_email,
96+
});
97+
const maxNumEmailAddresses = enabledFeatureFlags.includes(
98+
"IncreasedFreeMaxBreachEmails",
99+
)
94100
? CONST_MAX_NUM_ADDRESSES_PLUS
95-
: CONST_MAX_NUM_ADDRESSES;
101+
: hasPremium(subscriber)
102+
? CONST_MAX_NUM_ADDRESSES_PLUS
103+
: CONST_MAX_NUM_ADDRESSES;
96104
const existingAddresses = [session.user.email]
97105
.concat(subscriber.email_addresses.map((emailRow) => emailRow.email))
98106
.map((address) => address.toLowerCase());
@@ -116,6 +124,7 @@ export async function onAddEmail(
116124
const unverifiedSubscriber = await addSubscriberUnverifiedEmailHash(
117125
subscriber,
118126
validatedEmailAddress.email,
127+
enabledFeatureFlags,
119128
);
120129

121130
await initEmail();

src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/panels/SettingsPanelEditInfo.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { useTelemetry } from "../../../../../../../hooks/useTelemetry";
2020
import { Button } from "../../../../../../../components/client/Button";
2121
import styles from "./SettingsPanelEditInfo.module.scss";
2222
import { type onRemoveEmail, type onAddEmail } from "../actions";
23+
import { FeatureFlagName } from "../../../../../../../../db/tables/featureFlags";
2324

2425
export type SettingsPanelEditInfoProps = {
2526
breachCountByEmailAddress: Record<string, number>;
@@ -32,6 +33,7 @@ export type SettingsPanelEditInfoProps = {
3233
onAddEmail: typeof onAddEmail;
3334
onRemoveEmail: typeof onRemoveEmail;
3435
};
36+
enabledFeatureFlags: FeatureFlagName[];
3537
};
3638

3739
function MonitoredEmail(props: {
@@ -156,7 +158,10 @@ function SettingsPanelEditInfo(props: SettingsPanelEditInfoProps) {
156158
</ul>
157159
<span className={styles.addEmailButton}>
158160
{hasMaxEmailAddresses && (
159-
<EmailAddressAdder onAddEmail={props.actions.onAddEmail} />
161+
<EmailAddressAdder
162+
onAddEmail={props.actions.onAddEmail}
163+
enabledFeatureFlags={props.enabledFeatureFlags}
164+
/>
160165
)}
161166
</span>
162167
</>

src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/panels/SettingsPanelEditInfoRedesign.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,13 @@ function MonitoredEmailAddressesSection(
227227
props: SettingsPanelEditInfoRedesignProps,
228228
) {
229229
const l10n = useL10n();
230-
const maxNumEmailAddresses = hasPremium(props.user)
230+
const maxNumEmailAddresses = props.enabledFeatureFlags.includes(
231+
"IncreasedFreeMaxBreachEmails",
232+
)
231233
? CONST_MAX_NUM_ADDRESSES_PLUS
232-
: CONST_MAX_NUM_ADDRESSES;
234+
: hasPremium(props.user)
235+
? CONST_MAX_NUM_ADDRESSES_PLUS
236+
: CONST_MAX_NUM_ADDRESSES;
233237
const hasMaxEmailAddresses =
234238
props.emailAddresses.length < maxNumEmailAddresses - 1;
235239

src/app/(proper_react)/(redesign)/(authenticated)/user/(dashboard)/settings/stories/SettingsEditInfoNonUsUsers.stories.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

55
import type { Meta, StoryObj } from "@storybook/nextjs";
6+
import { faker } from "@faker-js/faker";
67

78
import { SettingsWrapper } from "./SettingsStoryWrapper";
89
import { CONST_SETTINGS_TAB_SLUGS } from "../../../../../../../../constants";
@@ -68,3 +69,20 @@ export const SettingsEditYourInfoMaxMonitoredEmails: Story = {
6869
],
6970
},
7071
};
72+
73+
export const SettingsEditYourInfoMaxMonitoredEmailsIncreased: Story = {
74+
name: "Max monitored emails increased",
75+
args: {
76+
countryCode: "nl",
77+
activeTab: "edit-info",
78+
enabledFeatureFlags: [
79+
"SidebarNavigationRedesign",
80+
"EditScanProfileDetails",
81+
"IncreasedFreeMaxBreachEmails",
82+
],
83+
emailAddresses: [...Array(19)].map(() => ({
84+
...mockedVerifiedEmailSecond,
85+
email: faker.internet.email(),
86+
})),
87+
},
88+
};

src/app/(proper_react)/(redesign)/(public)/LandingViewRedesign/components/PricingPlanList.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,12 @@ export const PricingPlanList = (props: Props & ScanLimitProp) => {
331331
{
332332
elems: { b: <b /> },
333333
vars: {
334-
max_email_addresses: CONST_MAX_NUM_ADDRESSES,
334+
/* c8 ignore next 5 */
335+
max_email_addresses: props.enabledFeatureFlags.includes(
336+
"IncreasedFreeMaxBreachEmails",
337+
)
338+
? CONST_MAX_NUM_ADDRESSES_PLUS
339+
: CONST_MAX_NUM_ADDRESSES,
335340
},
336341
},
337342
)}

src/app/api/v1/user/email/route.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
} from "../../../../../constants";
2222
import { validateEmailAddress } from "../../../../../utils/emailAddress";
2323
import { hasPremium } from "../../../../functions/universal/user";
24+
import { getEnabledFeatureFlags } from "../../../../../db/tables/featureFlags";
2425

2526
interface EmailAddRequest {
2627
email: string;
@@ -50,9 +51,16 @@ export async function POST(req: NextRequest) {
5051
);
5152
}
5253

53-
const maxNumEmailAddresses = hasPremium(subscriber)
54+
const enabledFeatureFlags = await getEnabledFeatureFlags({
55+
email: subscriber.primary_email,
56+
});
57+
const maxNumEmailAddresses = enabledFeatureFlags.includes(
58+
"IncreasedFreeMaxBreachEmails",
59+
)
5460
? CONST_MAX_NUM_ADDRESSES_PLUS
55-
: CONST_MAX_NUM_ADDRESSES;
61+
: hasPremium(subscriber)
62+
? CONST_MAX_NUM_ADDRESSES_PLUS
63+
: CONST_MAX_NUM_ADDRESSES;
5664
if (emailCount >= maxNumEmailAddresses) {
5765
return NextResponse.json(
5866
{
@@ -90,6 +98,7 @@ export async function POST(req: NextRequest) {
9098
const unverifiedSubscriber = await addSubscriberUnverifiedEmailHash(
9199
subscriber,
92100
validatedEmail.email,
101+
enabledFeatureFlags,
93102
);
94103

95104
await initEmail();

src/app/components/client/Chart.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,13 @@ export const DoughnutChart = (props: Props) => {
111111
? "modal-active-number-of-exposures-part-one-premium"
112112
: "modal-active-number-of-exposures-part-one-all",
113113
{
114-
limit: props.isPremiumUser
114+
limit: props.enabledFeatureFlags.includes(
115+
"IncreasedFreeMaxBreachEmails",
116+
)
115117
? CONST_MAX_NUM_ADDRESSES_PLUS
116-
: CONST_MAX_NUM_ADDRESSES,
118+
: props.isPremiumUser
119+
? CONST_MAX_NUM_ADDRESSES_PLUS
120+
: CONST_MAX_NUM_ADDRESSES,
117121
},
118122
)}
119123
</p>

0 commit comments

Comments
 (0)