Skip to content

Commit a2d5765

Browse files
authored
Add Stripe deactivate link functionality to UI (#170)
1 parent 7198697 commit a2d5765

File tree

7 files changed

+160
-68
lines changed

7 files changed

+160
-68
lines changed

src/api/functions/auditLog.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ export function buildAuditLogTransactPut({
5656
}: {
5757
entry: AuditLogEntry;
5858
}): TransactWriteItem {
59-
if (process.env.DISABLE_AUDIT_LOG && process.env.RunEnvironment === "dev") {
60-
console.log(`Audit log entry: ${JSON.stringify(entry)}`);
61-
return {};
62-
}
6359
const item = buildMarshalledAuditLogItem(entry);
6460
return {
6561
Put: {

src/ui/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export type KnownGroups = {
2222

2323
export type ConfigType = {
2424
AadValidClientId: string;
25+
LinkryPublicUrl: string;
2526
ServiceConfiguration: Record<ValidServices, ServiceConfiguration>;
2627
KnownGroupMappings: KnownGroups;
2728
};
@@ -43,6 +44,7 @@ type EnvironmentConfigType = {
4344
const environmentConfig: EnvironmentConfigType = {
4445
"local-dev": {
4546
AadValidClientId: "d1978c23-6455-426a-be4d-528b2d2e4026",
47+
LinkryPublicUrl: "go.aws.qa.acmuiuc.org",
4648
ServiceConfiguration: {
4749
core: {
4850
friendlyName: "Core Management Service (NonProd)",
@@ -75,6 +77,7 @@ const environmentConfig: EnvironmentConfigType = {
7577
},
7678
dev: {
7779
AadValidClientId: "d1978c23-6455-426a-be4d-528b2d2e4026",
80+
LinkryPublicUrl: "go.aws.qa.acmuiuc.org",
7881
ServiceConfiguration: {
7982
core: {
8083
friendlyName: "Core Management Service (NonProd)",
@@ -107,6 +110,7 @@ const environmentConfig: EnvironmentConfigType = {
107110
},
108111
prod: {
109112
AadValidClientId: "43fee67e-e383-4071-9233-ef33110e9386",
113+
LinkryPublicUrl: "go.acm.illinois.edu",
110114
ServiceConfiguration: {
111115
core: {
112116
friendlyName: "Core Management Service",

src/ui/pages/linkry/LinkShortener.page.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,16 @@ import {
1616
} from "@mantine/core";
1717
import { useDisclosure } from "@mantine/hooks";
1818
import { notifications } from "@mantine/notifications";
19-
import {
20-
IconCancel,
21-
IconCross,
22-
IconEdit,
23-
IconPlus,
24-
IconTrash,
25-
} from "@tabler/icons-react";
26-
import dayjs from "dayjs";
19+
import { IconCancel, IconEdit, IconPlus, IconTrash } from "@tabler/icons-react";
2720
import React, { useEffect, useState } from "react";
2821
import { useNavigate } from "react-router-dom";
2922
import { z } from "zod";
3023

31-
import { capitalizeFirstLetter } from "./ManageLink.page.js";
32-
import FullScreenLoader from "@ui/components/AuthContext/LoadingScreen";
3324
import { AuthGuard } from "@ui/components/AuthGuard";
3425
import { useApi } from "@ui/util/api";
3526
import { AppRoles } from "@common/roles.js";
36-
import { wrap } from "module";
3727
import { linkRecord } from "@common/types/linkry.js";
28+
import { getRunEnvironmentConfig } from "@ui/config.js";
3829

3930
const wrapTextStyle: React.CSSProperties = {
4031
wordWrap: "break-word",
@@ -82,7 +73,7 @@ export const LinkShortener: React.FC = () => {
8273
}}
8374
>
8475
<Table.Td style={wrapTextStyle}>
85-
https://go.acm.illinois.edu/{link.slug}
76+
{getRunEnvironmentConfig().LinkryPublicUrl}/{link.slug}
8677
</Table.Td>
8778
<Table.Td style={wrapTextStyle}>
8879
<Anchor href={link.redirect} target="_blank" size="sm">

src/ui/pages/linkry/ManageLink.page.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ import { IconDeviceFloppy } from "@tabler/icons-react";
1919
import { LinkryGroupUUIDToGroupNameMap } from "@common/config";
2020
import FullScreenLoader from "@ui/components/AuthContext/LoadingScreen";
2121
import { LINKRY_MAX_SLUG_LENGTH } from "@common/types/linkry";
22+
import { getRunEnvironmentConfig } from "@ui/config";
2223

2324
export function capitalizeFirstLetter(string: string) {
2425
return string.charAt(0).toUpperCase() + string.slice(1);
2526
}
2627

27-
const baseUrl = "go.acm.illinois.edu";
28+
const baseUrl = getRunEnvironmentConfig().LinkryPublicUrl;
2829
const slugRegex = new RegExp("^(https?://)?[a-zA-Z0-9-._/]*$");
2930
const urlRegex = new RegExp("^https?://[a-zA-Z0-9-._/?=&+:]*$");
3031

@@ -205,7 +206,7 @@ export const ManageLinkPage: React.FC = () => {
205206
rightSectionWidth="150px"
206207
leftSection={
207208
<Button variant="outline" mr="auto" size="auto">
208-
{baseUrl || "go.acm.illinois.edu"}
209+
{baseUrl}
209210
</Button>
210211
}
211212
rightSection={
@@ -216,7 +217,7 @@ export const ManageLinkPage: React.FC = () => {
216217
color="blue"
217218
onClick={generateRandomSlug}
218219
>
219-
Generate Random URL
220+
Random
220221
</Button>
221222
)
222223
}

src/ui/pages/stripe/CurrentLinks.test.tsx

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ vi.mock("@ui/components/AuthContext", async () => {
1616

1717
describe("StripeCurrentLinksPanel Tests", () => {
1818
const getLinksMock = vi.fn();
19+
const deactivateLinkMock = vi.fn();
1920

2021
const renderComponent = async () => {
2122
await act(async () => {
@@ -26,7 +27,10 @@ describe("StripeCurrentLinksPanel Tests", () => {
2627
withCssVariables
2728
forceColorScheme="light"
2829
>
29-
<StripeCurrentLinksPanel getLinks={getLinksMock} />
30+
<StripeCurrentLinksPanel
31+
getLinks={getLinksMock}
32+
deactivateLink={deactivateLinkMock}
33+
/>
3034
</MantineProvider>
3135
</MemoryRouter>,
3236
);
@@ -151,10 +155,10 @@ describe("StripeCurrentLinksPanel Tests", () => {
151155
expect(checkbox).not.toBeChecked();
152156
});
153157

154-
it("triggers deactivation when clicking deactivate button", async () => {
158+
it("triggers deactivation when clicking deactivate button with all active", async () => {
155159
getLinksMock.mockResolvedValue([
156160
{
157-
id: "1",
161+
id: "abc123",
158162
active: true,
159163
invoiceId: "INV-001",
160164
invoiceAmountUsd: 5000,
@@ -163,7 +167,6 @@ describe("StripeCurrentLinksPanel Tests", () => {
163167
link: "http://example.com",
164168
},
165169
]);
166-
const notificationsMock = vi.spyOn(notifications, "show");
167170
await renderComponent();
168171

169172
const checkbox = screen.getByLabelText("Select row");
@@ -172,14 +175,64 @@ describe("StripeCurrentLinksPanel Tests", () => {
172175
const deactivateButton = await screen.findByText(/Deactivate 1 link/);
173176
await userEvent.click(deactivateButton);
174177

175-
expect(notificationsMock).toHaveBeenCalledWith(
176-
expect.objectContaining({
177-
title: "Feature not available",
178-
message: "Coming soon!",
179-
color: "yellow",
180-
}),
178+
expect(deactivateLinkMock).toHaveBeenCalledWith("abc123");
179+
});
180+
181+
it("doesn't show deactivation when clicking deactivate button on non-active", async () => {
182+
getLinksMock.mockResolvedValue([
183+
{
184+
id: "abc123",
185+
active: false,
186+
invoiceId: "INV-001",
187+
invoiceAmountUsd: 5000,
188+
userId: "[email protected]",
189+
createdAt: "2024-02-01",
190+
link: "http://example.com",
191+
},
192+
]);
193+
await renderComponent();
194+
195+
const checkbox = screen.getByLabelText("Select row");
196+
await userEvent.click(checkbox);
197+
198+
const deactivateButton = screen.queryByText(/Deactivate 1 link/);
199+
expect(deactivateButton).not.toBeInTheDocument();
200+
201+
expect(deactivateLinkMock).not.toHaveBeenCalled();
202+
});
203+
204+
it("only offers to deactivate one link when there is one active and one non-active", async () => {
205+
getLinksMock.mockResolvedValue([
206+
{
207+
id: "abc123",
208+
active: false,
209+
invoiceId: "INV-001",
210+
invoiceAmountUsd: 5000,
211+
userId: "[email protected]",
212+
createdAt: "2024-02-01",
213+
link: "http://example.com",
214+
},
215+
{
216+
id: "def456",
217+
active: true,
218+
invoiceId: "INV-002",
219+
invoiceAmountUsd: 5000,
220+
userId: "[email protected]",
221+
createdAt: "2024-02-01",
222+
link: "http://example.com",
223+
},
224+
]);
225+
await renderComponent();
226+
227+
const checkboxes = screen.getAllByLabelText("Select row");
228+
checkboxes.map(async (x) => await userEvent.click(x));
229+
230+
const deactivateButton = await screen.findByText(
231+
/Deactivate 1 active link/,
181232
);
233+
await userEvent.click(deactivateButton);
182234

183-
notificationsMock.mockRestore();
235+
expect(deactivateLinkMock).toHaveBeenCalledTimes(1);
236+
expect(deactivateLinkMock).toHaveBeenNthCalledWith(1, "def456");
184237
});
185238
});

0 commit comments

Comments
 (0)