test(09-03): RED — failing parseCert spec (PEM/DER/PFX/wrong-password/malformed)
Tessera CI/CD / Tests (push) Has been cancelled
Tessera CI/CD / Build & Publish Images (push) Has been cancelled
Tessera CI/CD / Lint & Type Check (push) Has been cancelled

- Added parseCert describe block with 5 failing tests
- Covers PEM input, DER input, PFX+correct-password, PFX+wrong-password (BadRequestException), malformed input (BadRequestException)
- Existing 11 helper tests still pass
- Fixtures built via node-forge (RSA-1024, DER from asn1.toDer, PFX via toPkcs12Asn1)
This commit is contained in:
2026-07-01 23:39:39 +02:00
parent b1aa1d0d2d
commit 7c2e506a2e
@@ -1,3 +1,4 @@
import { BadRequestException } from '@nestjs/common';
import * as forge from 'node-forge'; import * as forge from 'node-forge';
import { beforeAll, describe, expect, it, vi } from 'vitest'; import { beforeAll, describe, expect, it, vi } from 'vitest';
import { seedCertManagerModule } from './cert-manager.seed'; import { seedCertManagerModule } from './cert-manager.seed';
@@ -128,3 +129,94 @@ describe('CertManagerService helpers', () => {
}); });
}); });
}); });
// ---------------------------------------------------------------------------
// parseCert — RED tests (CERT-01, CERT-05 read half)
// ---------------------------------------------------------------------------
describe('parseCert', () => {
let service: CertManagerService;
let certPem: string;
let certDerBuffer: Buffer;
let pfxBuffer: Buffer;
const CN = 'parsecert.example.com';
beforeAll(() => {
service = new CertManagerService();
// Create a cert+key pair for all fixtures (RSA-1024 for speed)
const keys = forge.pki.rsa.generateKeyPair(1024);
const cert = forge.pki.createCertificate();
cert.publicKey = keys.publicKey;
cert.serialNumber = '01';
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
const attrs = [{ name: 'commonName', value: CN }];
cert.setSubject(attrs);
cert.setIssuer(attrs);
cert.sign(keys.privateKey, forge.md.sha256.create());
// PEM fixture
certPem = forge.pki.certificateToPem(cert);
// DER fixture — binary encoding required (Pitfall 1)
const derBytes = forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes();
certDerBuffer = Buffer.from(derBytes, 'binary');
// PFX fixture with password 'secret'
const p12Asn1 = forge.pkcs12.toPkcs12Asn1(
keys.privateKey,
[cert],
'secret',
{ algorithm: '3des' },
);
const p12DerBytes = forge.asn1.toDer(p12Asn1).getBytes();
pfxBuffer = Buffer.from(p12DerBytes, 'binary');
}, 15000); // 15s timeout — RSA keygen can be slow in pure JS
it('returns CertDetails with subject.cn, fingerprint.sha256, keyType RSA, keyBits, isExpired false for PEM input', async () => {
// RED: parseCert currently throws NotImplementedException — this test will FAIL
const result = await (service.parseCert({ pemText: certPem }) as Promise<any>);
expect(result.subject.cn).toBe(CN);
expect(result.fingerprint.sha256).toMatch(/^[0-9A-F]{2}(:[0-9A-F]{2})+$/);
expect(result.keyType).toBe('RSA');
expect(result.keyBits).toBe(1024);
expect(result.validity.isExpired).toBe(false);
});
it('returns CertDetails with matching subject.cn for DER input', async () => {
// RED: parseCert throws NotImplementedException — this test will FAIL
const result = await (service.parseCert({
file: { originalname: 'c.der', buffer: certDerBuffer },
}) as Promise<any>);
expect(result.subject.cn).toBe(CN);
});
it('returns CertDetails for PFX with correct password', async () => {
// RED: parseCert throws NotImplementedException — this test will FAIL
const result = await (service.parseCert({
file: { originalname: 'c.pfx', buffer: pfxBuffer },
password: 'secret',
}) as Promise<any>);
expect(result.subject.cn).toBe(CN);
});
it('throws BadRequestException for PFX with wrong password', async () => {
// RED: currently throws NotImplementedException (not BadRequestException) — FAIL
await expect(
service.parseCert({
file: { originalname: 'c.pfx', buffer: pfxBuffer },
password: 'wrong',
}),
).rejects.toThrow(BadRequestException);
});
it('throws BadRequestException for malformed PEM input', async () => {
// RED: currently throws NotImplementedException (not BadRequestException) — FAIL
await expect(
service.parseCert({ pemText: 'not a cert' }),
).rejects.toThrow(BadRequestException);
});
});