import { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; import { NotFoundException } from '@nestjs/common'; import { DeploymentsService } from '../src/deployments/deployments.service'; import { Deployment } from '../src/deployments/entities/deployment.entity'; import { ApplicationsService } from '../src/applications/applications.service'; import { KubernetesService } from '../src/kubernetes/kubernetes.service'; import { BuildService } from '../src/build/build.service'; import { ClustersService } from '../src/clusters/clusters.service'; /** * Smoke test: deployment reads must enforce application ownership (IDOR fix). */ describe('Deployments authorization (e2e smoke)', () => { let service: DeploymentsService; const deploymentsRepository = { find: jest.fn(), findOne: jest.fn(), createQueryBuilder: jest.fn(), }; const applicationsService = { findOne: jest.fn(), }; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ DeploymentsService, { provide: getRepositoryToken(Deployment), useValue: deploymentsRepository }, { provide: ApplicationsService, useValue: applicationsService }, { provide: KubernetesService, useValue: {} }, { provide: BuildService, useValue: {} }, { provide: ClustersService, useValue: {} }, ], }).compile(); service = module.get(DeploymentsService); }); beforeEach(() => { jest.clearAllMocks(); }); it('rejects findOne when application ownership check fails', async () => { deploymentsRepository.findOne.mockResolvedValue({ id: 'd-1', applicationId: 'app-other', }); applicationsService.findOne.mockRejectedValue(new NotFoundException('Application not found')); await expect(service.findOne('d-1', 'user-a')).rejects.toThrow(NotFoundException); }); it('allows findOne when user owns the application', async () => { const deployment = { id: 'd-1', applicationId: 'app-1' }; deploymentsRepository.findOne.mockResolvedValue(deployment); applicationsService.findOne.mockResolvedValue({ id: 'app-1', userId: 'user-a' }); await expect(service.findOne('d-1', 'user-a')).resolves.toBe(deployment); }); });