fix: monthly integration (#27498)

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
This commit is contained in:
sean-brydon
2026-02-02 12:13:17 +02:00
committed by GitHub
co-authored by Anik Dhabal Babu
parent d29c8a4fa2
commit 8f6d580233
@@ -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({