837f0fa63f
Close deployment IDOR and gate stub payment endpoints, add production secret validation, health probes, Redis-backed build progress, GitHub Actions CI, expanded tests, billing/k8s refactors, and ops runbooks. Co-authored-by: Cursor <cursoragent@cursor.com>
64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
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);
|
|
});
|
|
});
|