From 46caebf87e8598575bc280b63ddd3e8d1830f1b1 Mon Sep 17 00:00:00 2001 From: Lilith Date: Thu, 15 Jan 2026 11:35:39 -0800 Subject: [PATCH] =?UTF-8?q?chore:=20=F0=9F=94=A7=20Update=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/tier-enforcement.e2e-spec.ts | 51 +++++++++++++++---- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/features/marketplace/backend-api/test/tier-enforcement.e2e-spec.ts b/features/marketplace/backend-api/test/tier-enforcement.e2e-spec.ts index fceffce66..ccdc37fc9 100644 --- a/features/marketplace/backend-api/test/tier-enforcement.e2e-spec.ts +++ b/features/marketplace/backend-api/test/tier-enforcement.e2e-spec.ts @@ -38,6 +38,7 @@ import { ClientUsage, CollectedProfile, PlatformSubscription, + PlatformSubscriptionStatus, MessageGift, ProviderProfile, VerificationLevel, @@ -52,12 +53,18 @@ describe('Tier Enforcement (E2E)', () => { let app: INestApplication; let merchantClient: jest.Mocked; let providerProfileRepo: Repository; + let subscriptionRepo: Repository; // Mock user for authentication (must be UUID format for ParseUUIDPipe) const mockUserId = '550e8400-e29b-41d4-a716-446655440000'; const mockUserEmail = 'test@example.com'; const mockCreatorId = '660e8400-e29b-41d4-a716-446655440001'; + // Test subscription ID + const mockSubscriptionId = 'cc0e8400-e29b-41d4-a716-446655440000'; + const mockFreeTierId = 'dd0e8400-e29b-41d4-a716-446655440000'; + const mockGoldTierId = 'dd0e8400-e29b-41d4-a716-446655440001'; + // Mock auth guard that injects user into request const mockAuthGuard: CanActivate = { canActivate: (context: ExecutionContext): boolean => { @@ -113,10 +120,11 @@ describe('Tier Enforcement (E2E)', () => { merchantClient = moduleFixture.get(MerchantClientService) as jest.Mocked; providerProfileRepo = moduleFixture.get(getRepositoryToken(ProviderProfile)); + subscriptionRepo = moduleFixture.get(getRepositoryToken(PlatformSubscription)); // Default: Free tier with low limits merchantClient.getFreeTier.mockResolvedValue({ - id: 'tier-free', + id: mockFreeTierId, name: 'Free', basePriceUsd: '0', status: 'available', @@ -137,7 +145,7 @@ describe('Tier Enforcement (E2E)', () => { } as any); merchantClient.getTierById.mockImplementation(async (id) => { - if (id === 'tier-free') { + if (id === mockFreeTierId) { return merchantClient.getFreeTier(); } return null; @@ -145,6 +153,24 @@ describe('Tier Enforcement (E2E)', () => { await app.init(); + // Create a free tier subscription for the test user + // This is required because ClientUsage has a foreign key to PlatformSubscription + const now = new Date(); + const periodEnd = new Date(now); + periodEnd.setDate(periodEnd.getDate() + 7); // Weekly billing for free tier + + await subscriptionRepo.save({ + id: mockSubscriptionId, + userId: mockUserId, + tierId: mockFreeTierId, + status: PlatformSubscriptionStatus.ACTIVE, + currentPeriodStart: now, + currentPeriodEnd: periodEnd, + nextBillingDate: null, // Free tier doesn't bill + paymentProvider: 'none', // Free tier has no payment provider + cancelAtPeriodEnd: false, + } as Partial); + // Create test provider profiles for search tests // Using insert() to seed data (requires all required fields) const testProfiles: Partial[] = [ @@ -223,8 +249,13 @@ describe('Tier Enforcement (E2E)', () => { describe('GET /usage/me - Usage Summary', () => { it('should return usage summary with tier limits', async () => { const res = await request(app.getHttpServer()) - .get('/usage/me') - .expect(200); + .get('/usage/me'); + + // Debug: print error if not 200 + if (res.status !== 200) { + console.log('Usage endpoint error:', res.status, JSON.stringify(res.body, null, 2)); + } + expect(res.status).toBe(200); expect(res.body).toHaveProperty('messages'); expect(res.body.messages).toHaveProperty('used'); @@ -281,7 +312,7 @@ describe('Tier Enforcement (E2E)', () => { // First, use a profile view to collect it await request(app.getHttpServer()) .post(`/usage/use/profile-view/${testProfileId}`) - .expect(200); + .expect(201); // NestJS default for POST // Now check - should be collected and free const res = await request(app.getHttpServer()) @@ -299,7 +330,7 @@ describe('Tier Enforcement (E2E)', () => { const res = await request(app.getHttpServer()) .post(`/usage/use/profile-view/${profileId}`) - .expect(200); + .expect(201); // NestJS default for POST expect(res.body).toHaveProperty('charged'); expect(res.body.charged).toBe(true); @@ -312,14 +343,14 @@ describe('Tier Enforcement (E2E)', () => { // First view - charged const first = await request(app.getHttpServer()) .post(`/usage/use/profile-view/${profileId}`) - .expect(200); + .expect(201); // NestJS default for POST expect(first.body.charged).toBe(true); // Second view - FREE const second = await request(app.getHttpServer()) .post(`/usage/use/profile-view/${profileId}`) - .expect(200); + .expect(201); // NestJS default for POST expect(second.body.charged).toBe(false); }); @@ -403,7 +434,7 @@ describe('Tier Enforcement (E2E)', () => { // Mock tier upgrade to Gold merchantClient.getTierById.mockResolvedValue({ - id: 'tier-gold', + id: mockGoldTierId, name: 'Gold', basePriceUsd: '99.99', status: 'available', @@ -425,7 +456,7 @@ describe('Tier Enforcement (E2E)', () => { // Note: In a real test, we would update the user's subscription to gold tier // For now, just verify the mock is set up correctly - const goldTier = await merchantClient.getTierById('tier-gold'); + const goldTier = await merchantClient.getTierById(mockGoldTierId); expect(goldTier?.metadata.actionPools.messagesPerMonth).toBe(749); }); });