stripe service test
This commit is contained in:
1 parent
9222d0b62d
commit
f92d08810a
2 files changed
+114
-3
No files matched your search
@@ -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();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user