From 8f6d5802333b16b4d9797d8bddf4e765cd17ab3d Mon Sep 17 00:00:00 2001 From: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Date: Mon, 2 Feb 2026 10:13:17 +0000 Subject: [PATCH] fix: monthly integration (#27498) Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> --- ...onthlyProrationService.integration-test.ts | 60 +++++++++++++------ 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts b/packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts index 4163996c6d..aa55a72f23 100644 --- a/packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts +++ b/packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts @@ -5,18 +5,35 @@ import type { Team, User } from "@calcom/prisma/client"; import { MembershipRole } from "@calcom/prisma/enums"; import { createMemberships } from "@calcom/trpc/server/routers/viewer/teams/inviteMember/utils"; import { beforeEach, describe, expect, it, vi } from "vitest"; + import { buildMonthlyProrationMetadata } from "../../../lib/proration-utils"; import type { IBillingProviderService } from "../../billingProvider/IBillingProviderService"; import { SeatChangeTrackingService } from "../../seatTracking/SeatChangeTrackingService"; import { MonthlyProrationService } from "../MonthlyProrationService"; +function getTestDates() { + const now = new Date(); + const year = now.getUTCFullYear(); + const month = now.getUTCMonth(); // 0-indexed + + const monthKey = `${year}-${String(month + 1).padStart(2, "0")}`; + + const subscriptionStart = new Date(Date.UTC(year, month - 6, 1, 0, 0, 0)); + const subscriptionEnd = new Date(Date.UTC(year, month + 6, 1, 0, 0, 0)); + const subscriptionTrialEnd = new Date(Date.UTC(year, month - 6, 8, 0, 0, 0)); + + return { monthKey, subscriptionStart, subscriptionEnd, subscriptionTrialEnd }; +} + const mockBillingService: IBillingProviderService = { createInvoiceItem: vi .fn() .mockResolvedValue({ invoiceItemId: "ii_test_123" }), deleteInvoiceItem: vi.fn().mockResolvedValue(undefined), createInvoice: vi.fn().mockResolvedValue({ invoiceId: "in_test_123" }), - finalizeInvoice: vi.fn().mockResolvedValue({ invoiceUrl: "https://invoice.stripe.com/test" }), + finalizeInvoice: vi + .fn() + .mockResolvedValue({ invoiceUrl: "https://invoice.stripe.com/test" }), getSubscription: vi.fn().mockResolvedValue({ items: [ { @@ -43,12 +60,10 @@ const mockBillingService: IBillingProviderService = { createPaymentIntent: vi .fn() .mockResolvedValue({ id: "pi_test_123", client_secret: "secret_123" }), - createSubscriptionCheckout: vi - .fn() - .mockResolvedValue({ - checkoutUrl: "https://checkout.test", - sessionId: "cs_test_123", - }), + createSubscriptionCheckout: vi.fn().mockResolvedValue({ + checkoutUrl: "https://checkout.test", + sessionId: "cs_test_123", + }), createPrice: vi.fn().mockResolvedValue({ priceId: "price_test_123" }), getPrice: vi.fn().mockResolvedValue(null), getSubscriptionStatus: vi.fn().mockResolvedValue(null), @@ -58,7 +73,9 @@ const mockBillingService: IBillingProviderService = { updateCustomer: vi.fn().mockResolvedValue(undefined), getPaymentIntentFailureReason: vi.fn().mockResolvedValue(null), hasDefaultPaymentMethod: vi.fn().mockResolvedValue(true), -} as IBillingProviderService; + voidInvoice: vi.fn().mockResolvedValue(undefined), + createSubscriptionUsageRecord: vi.fn().mockResolvedValue(undefined), +} satisfies IBillingProviderService; const mockFeaturesRepository: IFeaturesRepository = { checkIfFeatureIsEnabledGlobally: vi.fn().mockResolvedValue(true), @@ -88,7 +105,8 @@ describe("MonthlyProrationService Integration Tests", () => { let testUser: User; let testTeam: Team; let billingCustomerId: string; - const monthKey = "2026-01"; + const testDates = getTestDates(); + const monthKey = testDates.monthKey; beforeEach(async () => { const timestamp = Date.now(); @@ -119,10 +137,6 @@ describe("MonthlyProrationService Integration Tests", () => { }, }); - const subscriptionStart = new Date("2025-06-01T00:00:00Z"); - const subscriptionEnd = new Date("2026-06-01T00:00:00Z"); - const subscriptionTrialEnd = new Date("2025-06-08T00:00:00Z"); - billingCustomerId = `cus_test_${timestamp}`; await prisma.teamBilling.create({ @@ -134,9 +148,9 @@ describe("MonthlyProrationService Integration Tests", () => { billingPeriod: "ANNUALLY", pricePerSeat: 12000, paidSeats: 0, - subscriptionStart, - subscriptionEnd, - subscriptionTrialEnd, + subscriptionStart: testDates.subscriptionStart, + subscriptionEnd: testDates.subscriptionEnd, + subscriptionTrialEnd: testDates.subscriptionTrialEnd, status: "ACTIVE", planName: "TEAM", }, @@ -234,6 +248,7 @@ describe("MonthlyProrationService Integration Tests", () => { userId: testUser.id, triggeredBy: testUser.id, seatCount: 2, + monthKey, }); await seatTracker.logSeatRemoval({ @@ -241,6 +256,7 @@ describe("MonthlyProrationService Integration Tests", () => { userId: testUser.id, triggeredBy: testUser.id, seatCount: 2, + monthKey, }); const proration = await prorationService.createProrationForTeam({ @@ -293,9 +309,9 @@ describe("MonthlyProrationService Integration Tests", () => { billingPeriod: "ANNUALLY", pricePerSeat: 10000, paidSeats: 0, - subscriptionStart: new Date("2025-06-01T00:00:00Z"), - subscriptionEnd: new Date("2026-06-01T00:00:00Z"), - subscriptionTrialEnd: new Date("2025-06-08T00:00:00Z"), + subscriptionStart: testDates.subscriptionStart, + subscriptionEnd: testDates.subscriptionEnd, + subscriptionTrialEnd: testDates.subscriptionTrialEnd, status: "ACTIVE", planName: "TEAM", }, @@ -308,6 +324,7 @@ describe("MonthlyProrationService Integration Tests", () => { userId: testUser.id, triggeredBy: testUser.id, seatCount: 2, + monthKey, }); await seatTracker.logSeatAddition({ @@ -315,6 +332,7 @@ describe("MonthlyProrationService Integration Tests", () => { userId: testUser.id, triggeredBy: testUser.id, seatCount: 3, + monthKey, }); const prorationService = new MonthlyProrationService({ @@ -347,6 +365,7 @@ describe("MonthlyProrationService Integration Tests", () => { userId: testUser.id, triggeredBy: testUser.id, seatCount: 2, + monthKey, }); const proration = await prorationService.createProrationForTeam({ @@ -378,6 +397,7 @@ describe("MonthlyProrationService Integration Tests", () => { userId: testUser.id, triggeredBy: testUser.id, seatCount: 2, + monthKey, }); const proration = await prorationService.createProrationForTeam({ @@ -415,6 +435,7 @@ describe("MonthlyProrationService Integration Tests", () => { userId: testUser.id, triggeredBy: testUser.id, seatCount: 2, + monthKey, }); const proration = await prorationService.createProrationForTeam({ @@ -453,6 +474,7 @@ describe("MonthlyProrationService Integration Tests", () => { userId: testUser.id, triggeredBy: testUser.id, seatCount: 2, + monthKey, }); const proration = await prorationService.createProrationForTeam({