"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const testing_1 = require("@nestjs/testing");
const core_1 = require("@nestjs/core");
const billing_controller_1 = require("../billing.controller");
const billing_service_1 = require("../services/billing.service");
const rbac_service_1 = require("../../rbac/services/rbac.service");
describe('BillingController', () => {
    let controller;
    let service;
    const mockRequestUser = {
        id: 'user-123',
        sub: 'user-123',
        tenant_id: 'tenant-123',
        email: 'test@example.com',
        role: 'admin',
    };
    const mockSubscription = {
        id: 'sub-123',
        tenant_id: 'tenant-123',
        plan_id: 'plan-123',
        status: 'active',
        current_period_start: new Date('2026-01-01'),
        current_period_end: new Date('2026-02-01'),
    };
    const mockInvoice = {
        id: 'inv-123',
        tenant_id: 'tenant-123',
        status: 'paid',
        total: 99.99,
    };
    const mockPaymentMethod = {
        id: 'pm-123',
        tenant_id: 'tenant-123',
        type: 'card',
        card_last_four: '4242',
        is_default: true,
    };
    beforeEach(async () => {
        const module = await testing_1.Test.createTestingModule({
            controllers: [billing_controller_1.BillingController],
            providers: [
                {
                    provide: billing_service_1.BillingService,
                    useValue: {
                        getSubscription: jest.fn(),
                        checkSubscriptionStatus: jest.fn(),
                        createSubscription: jest.fn(),
                        updateSubscription: jest.fn(),
                        cancelSubscription: jest.fn(),
                        changePlan: jest.fn(),
                        getInvoices: jest.fn(),
                        getInvoice: jest.fn(),
                        markInvoicePaid: jest.fn(),
                        voidInvoice: jest.fn(),
                        getPaymentMethods: jest.fn(),
                        addPaymentMethod: jest.fn(),
                        setDefaultPaymentMethod: jest.fn(),
                        removePaymentMethod: jest.fn(),
                        getBillingSummary: jest.fn(),
                    },
                },
                {
                    provide: rbac_service_1.RbacService,
                    useValue: {
                        userHasPermission: jest.fn().mockResolvedValue(true),
                        userHasAnyPermission: jest.fn().mockResolvedValue(true),
                    },
                },
                core_1.Reflector,
            ],
        }).compile();
        controller = module.get(billing_controller_1.BillingController);
        service = module.get(billing_service_1.BillingService);
    });
    afterEach(() => {
        jest.clearAllMocks();
    });
    describe('getSubscription', () => {
        it('should return current subscription', async () => {
            service.getSubscription.mockResolvedValue(mockSubscription);
            const result = await controller.getSubscription(mockRequestUser);
            expect(result).toEqual(mockSubscription);
            expect(service.getSubscription).toHaveBeenCalledWith('tenant-123');
        });
    });
    describe('getSubscriptionStatus', () => {
        it('should return subscription status', async () => {
            const status = { active: true, plan: 'pro', daysRemaining: 25 };
            service.checkSubscriptionStatus.mockResolvedValue(status);
            const result = await controller.getSubscriptionStatus(mockRequestUser);
            expect(result).toEqual(status);
            expect(service.checkSubscriptionStatus).toHaveBeenCalledWith('tenant-123');
        });
    });
    describe('createSubscription', () => {
        it('should create subscription', async () => {
            const createDto = { plan_id: 'plan-123', tenant_id: '' };
            service.createSubscription.mockResolvedValue(mockSubscription);
            const result = await controller.createSubscription(createDto, mockRequestUser);
            expect(result).toEqual(mockSubscription);
            expect(createDto.tenant_id).toBe('tenant-123');
        });
    });
    describe('updateSubscription', () => {
        it('should update subscription', async () => {
            const updateDto = { plan_id: 'plan-456' };
            const updated = { ...mockSubscription, plan_id: 'plan-456' };
            service.updateSubscription.mockResolvedValue(updated);
            const result = await controller.updateSubscription(updateDto, mockRequestUser);
            expect(result.plan_id).toBe('plan-456');
            expect(service.updateSubscription).toHaveBeenCalledWith('tenant-123', updateDto);
        });
    });
    describe('cancelSubscription', () => {
        it('should cancel subscription', async () => {
            const cancelDto = { immediately: false, reason: 'Not needed' };
            const cancelled = { ...mockSubscription, status: 'cancelled' };
            service.cancelSubscription.mockResolvedValue(cancelled);
            const result = await controller.cancelSubscription(cancelDto, mockRequestUser);
            expect(result.status).toBe('cancelled');
            expect(service.cancelSubscription).toHaveBeenCalledWith('tenant-123', cancelDto);
        });
    });
    describe('changePlan', () => {
        it('should change plan', async () => {
            const updated = { ...mockSubscription, plan_id: 'plan-456' };
            service.changePlan.mockResolvedValue(updated);
            const result = await controller.changePlan('plan-456', mockRequestUser);
            expect(result.plan_id).toBe('plan-456');
            expect(service.changePlan).toHaveBeenCalledWith('tenant-123', 'plan-456');
        });
    });
    describe('getInvoices', () => {
        it('should return paginated invoices', async () => {
            const invoicesResult = { data: [mockInvoice], total: 1, page: 1, limit: 10 };
            service.getInvoices.mockResolvedValue(invoicesResult);
            const result = await controller.getInvoices(mockRequestUser, 1, 10);
            expect(result).toEqual(invoicesResult);
            expect(service.getInvoices).toHaveBeenCalledWith('tenant-123', { page: 1, limit: 10 });
        });
    });
    describe('getInvoice', () => {
        it('should return invoice by id', async () => {
            service.getInvoice.mockResolvedValue(mockInvoice);
            const result = await controller.getInvoice('inv-123', mockRequestUser);
            expect(result).toEqual(mockInvoice);
            expect(service.getInvoice).toHaveBeenCalledWith('inv-123', 'tenant-123');
        });
    });
    describe('markInvoicePaid', () => {
        it('should mark invoice as paid', async () => {
            const paidInvoice = { ...mockInvoice, status: 'paid' };
            service.markInvoicePaid.mockResolvedValue(paidInvoice);
            const result = await controller.markInvoicePaid('inv-123', mockRequestUser);
            expect(result.status).toBe('paid');
            expect(service.markInvoicePaid).toHaveBeenCalledWith('inv-123', 'tenant-123');
        });
    });
    describe('voidInvoice', () => {
        it('should void invoice', async () => {
            const voidedInvoice = { ...mockInvoice, status: 'void' };
            service.voidInvoice.mockResolvedValue(voidedInvoice);
            const result = await controller.voidInvoice('inv-123', mockRequestUser);
            expect(result.status).toBe('void');
            expect(service.voidInvoice).toHaveBeenCalledWith('inv-123', 'tenant-123');
        });
    });
    describe('getPaymentMethods', () => {
        it('should return payment methods', async () => {
            service.getPaymentMethods.mockResolvedValue([mockPaymentMethod]);
            const result = await controller.getPaymentMethods(mockRequestUser);
            expect(result).toEqual([mockPaymentMethod]);
            expect(service.getPaymentMethods).toHaveBeenCalledWith('tenant-123');
        });
    });
    describe('addPaymentMethod', () => {
        it('should add payment method', async () => {
            const createDto = { type: 'card', external_payment_method_id: 'pm_test' };
            service.addPaymentMethod.mockResolvedValue(mockPaymentMethod);
            const result = await controller.addPaymentMethod(createDto, mockRequestUser);
            expect(result).toEqual(mockPaymentMethod);
            expect(service.addPaymentMethod).toHaveBeenCalledWith('tenant-123', createDto);
        });
    });
    describe('setDefaultPaymentMethod', () => {
        it('should set default payment method', async () => {
            const updatedMethod = { ...mockPaymentMethod, is_default: true };
            service.setDefaultPaymentMethod.mockResolvedValue(updatedMethod);
            const result = await controller.setDefaultPaymentMethod('pm-123', mockRequestUser);
            expect(result.is_default).toBe(true);
            expect(service.setDefaultPaymentMethod).toHaveBeenCalledWith('pm-123', 'tenant-123');
        });
    });
    describe('removePaymentMethod', () => {
        it('should remove payment method', async () => {
            service.removePaymentMethod.mockResolvedValue(undefined);
            const result = await controller.removePaymentMethod('pm-123', mockRequestUser);
            expect(result.message).toBe('Payment method removed');
            expect(service.removePaymentMethod).toHaveBeenCalledWith('pm-123', 'tenant-123');
        });
    });
    describe('getBillingSummary', () => {
        it('should return billing summary', async () => {
            const summary = {
                subscription: mockSubscription,
                nextInvoice: mockInvoice,
                paymentMethods: [mockPaymentMethod],
            };
            service.getBillingSummary.mockResolvedValue(summary);
            const result = await controller.getBillingSummary(mockRequestUser);
            expect(result).toEqual(summary);
            expect(service.getBillingSummary).toHaveBeenCalledWith('tenant-123');
        });
    });
});
//# sourceMappingURL=billing.controller.spec.js.map