stripe service test

This commit is contained in:
Alex Holliday committed 2025-12-16 21:20:19 +00:00
1 parent 9222d0b62d
commit f92d08810a
2 files changed
+114 -3

No files matched your search

+3 -3
View File
@@ -72,7 +72,7 @@ const UptimeMonitors = () => {
].filter(Boolean);
const monitorRequestUrl = `/monitors?${requestParams.join("&")}`;
const { response, loading, isValidating, error, refetch } = useGet<
const { response, loading, error, refetch } = useGet<
ApiResponse<IMonitorWithStats>
>(
monitorRequestUrl,
@@ -119,7 +119,7 @@ const UptimeMonitors = () => {
return (
<MonitorBasePageWithStates
loading={isValidating}
loading={loading}
error={error}
items={monitorItems}
page="uptime"
@@ -152,7 +152,7 @@ const UptimeMonitors = () => {
onStatusesChange={setSelectedStatuses}
searchString={searchString}
onSearchStringChange={setSearchString}
loading={isValidating}
loading={loading}
/>
<MonitorTable
monitors={monitors}
@@ -0,0 +1,111 @@
import StripeService from "@/services/system/StripeService.js";
// Mocks
jest.mock("@/db/models/index.js", () => ({
Org: { findOneAndUpdate: jest.fn() },
Monitor: { countDocuments: jest.fn(), find: jest.fn(), deleteMany: jest.fn() },
StatusPage: { countDocuments: jest.fn(), find: jest.fn(), deleteMany: jest.fn() },
NotificationChannel: { countDocuments: jest.fn(), find: jest.fn(), deleteMany: jest.fn() },
}));
import { Org, Monitor, StatusPage, NotificationChannel } from "@/db/models/index.js";
jest.mock("@/config/index.js", () => ({
config: {
STRIPE_SECRET: "sk_test_mock",
STRIPE_WEBHOOK_SECRET: "whsec_mock",
},
}));
// Mock Stripe constructor and webhooks
jest.mock("stripe", () => {
const mockConstructEvent = jest.fn();
const mockStripe = function () {
return {
webhooks: { constructEvent: mockConstructEvent },
};
};
mockStripe.__constructEvent = mockConstructEvent;
return { __esModule: true, default: mockStripe };
});
import Stripe from "stripe";
const buildSub = (overrides = {}) => ({
id: "sub_1",
metadata: { orgId: "org1" },
status: "active",
items: { data: [{ price: { id: "price_1", lookup_key: "pro" }, current_period_start: 1, current_period_end: 2 }] },
...overrides,
});
describe("StripeService", () => {
beforeEach(() => {
jest.clearAllMocks();
});
it("returns null when constructEvent fails", async () => {
(Stripe.__constructEvent).mockImplementation(() => {
throw new Error("bad sig");
});
const svc = new StripeService();
const res = await svc.webhook("evt", "sig");
expect(res).toBeNull();
});
it("handles subscription created/updated and updates org + prunes resources", async () => {
(Stripe.__constructEvent).mockReturnValue({
type: "customer.subscription.created",
data: { object: buildSub() },
});
Monitor.countDocuments.mockResolvedValue(30);
Monitor.find.mockReturnValue({ sort: () => ({ limit: () => ({ select: () => Promise.resolve([{ _id: "m1" }]) }) }) });
Monitor.deleteMany.mockResolvedValue({});
NotificationChannel.countDocuments.mockResolvedValue(0);
StatusPage.countDocuments.mockResolvedValue(0);
const svc = new StripeService();
const res = await svc.webhook("evt", "sig");
expect(Org.findOneAndUpdate).toHaveBeenCalledWith(
{ _id: "org1" },
expect.objectContaining({ $set: expect.objectContaining({ planKey: "pro" }) }),
{ new: true }
);
expect(Monitor.deleteMany).toHaveBeenCalled();
expect(res).toMatchObject({ status: "active" });
});
it("handles subscription deleted and resets org to free", async () => {
(Stripe.__constructEvent).mockReturnValue({
type: "customer.subscription.deleted",
data: { object: buildSub() },
});
const svc = new StripeService();
const res = await svc.webhook("evt", "sig");
expect(Org.findOneAndUpdate).toHaveBeenCalledWith(
{ _id: "org1" },
expect.objectContaining({ $set: expect.objectContaining({ planKey: "free" }), $unset: expect.any(Object) }),
{ new: true }
);
expect(res).toMatchObject({ status: "active" });
});
it("returns subscription for updated event", async () => {
(Stripe.__constructEvent).mockReturnValue({
type: "customer.subscription.updated",
data: { object: buildSub({ status: "past_due" }) },
});
const svc = new StripeService();
const res = await svc.webhook("evt", "sig");
expect(res).toMatchObject({ status: "past_due" });
});
it("returns null for other events", async () => {
(Stripe.__constructEvent).mockReturnValue({
type: "invoice.payment_succeeded",
data: { object: {} },
});
const svc = new StripeService();
const res = await svc.webhook("evt", "sig");
expect(res).toBeNull();
});
});