test(09-04): RED — failing splitCerts spec (fullchain PEM, P7B bundle, malformed)
- splitCerts fullchain PEM: expects count 2, two single-PEM-block certs with correct CN - splitCerts P7B PEM bundle: expects at least one cert in result - splitCerts malformed input: expects BadRequestException - All three tests FAIL against NotImplementedException stub (RED confirmed) - All 16 prior tests still pass
This commit is contained in:
@@ -220,3 +220,105 @@ describe('parseCert', () => {
|
||||
).rejects.toThrow(BadRequestException);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// splitCerts — RED tests (CERT-02)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('splitCerts', () => {
|
||||
let service: CertManagerService;
|
||||
let cert1Pem: string;
|
||||
let cert2Pem: string;
|
||||
let fullchainBuffer: Buffer;
|
||||
let p7bBuffer: Buffer;
|
||||
const CN1 = 'split1.example.com';
|
||||
const CN2 = 'split2.example.com';
|
||||
|
||||
beforeAll(() => {
|
||||
service = new CertManagerService();
|
||||
|
||||
// Build cert 1 (RSA-1024 for speed)
|
||||
const keys1 = forge.pki.rsa.generateKeyPair(1024);
|
||||
const c1 = forge.pki.createCertificate();
|
||||
c1.publicKey = keys1.publicKey;
|
||||
c1.serialNumber = '01';
|
||||
c1.validity.notBefore = new Date();
|
||||
c1.validity.notAfter = new Date();
|
||||
c1.validity.notAfter.setFullYear(c1.validity.notBefore.getFullYear() + 1);
|
||||
const attrs1 = [{ name: 'commonName', value: CN1 }];
|
||||
c1.setSubject(attrs1);
|
||||
c1.setIssuer(attrs1);
|
||||
c1.sign(keys1.privateKey, forge.md.sha256.create());
|
||||
cert1Pem = forge.pki.certificateToPem(c1);
|
||||
|
||||
// Build cert 2
|
||||
const keys2 = forge.pki.rsa.generateKeyPair(1024);
|
||||
const c2 = forge.pki.createCertificate();
|
||||
c2.publicKey = keys2.publicKey;
|
||||
c2.serialNumber = '02';
|
||||
c2.validity.notBefore = new Date();
|
||||
c2.validity.notAfter = new Date();
|
||||
c2.validity.notAfter.setFullYear(c2.validity.notBefore.getFullYear() + 1);
|
||||
const attrs2 = [{ name: 'commonName', value: CN2 }];
|
||||
c2.setSubject(attrs2);
|
||||
c2.setIssuer(attrs2);
|
||||
c2.sign(keys2.privateKey, forge.md.sha256.create());
|
||||
cert2Pem = forge.pki.certificateToPem(c2);
|
||||
|
||||
// Fullchain fixture: two PEMs concatenated
|
||||
const fullchainPem = cert1Pem + '\n' + cert2Pem;
|
||||
fullchainBuffer = Buffer.from(fullchainPem, 'utf-8');
|
||||
|
||||
// P7B fixture: PEM-wrapped PKCS7 SignedData bundle with both certs
|
||||
const p7 = forge.pkcs7.createSignedData();
|
||||
p7.addCertificate(c1);
|
||||
p7.addCertificate(c2);
|
||||
const p7DerBytes = forge.asn1.toDer(p7.toAsn1()).getBytes();
|
||||
const p7PemStr = forge.pem.encode({ type: 'PKCS7', body: p7DerBytes });
|
||||
p7bBuffer = Buffer.from(p7PemStr, 'utf-8');
|
||||
}, 30000); // 30s — two RSA-1024 keygens
|
||||
|
||||
it('returns count 2 and two certs each with a single PEM block and correct CN for fullchain PEM', async () => {
|
||||
// RED: splitCerts throws NotImplementedException — FAIL
|
||||
const result = await (service.splitCerts({
|
||||
file: { originalname: 'fullchain.pem', buffer: fullchainBuffer },
|
||||
}) as Promise<any>);
|
||||
expect(result.count).toBe(2);
|
||||
expect(result.certs).toHaveLength(2);
|
||||
|
||||
// Each cert content decodes to exactly one BEGIN CERTIFICATE block
|
||||
for (const entry of result.certs) {
|
||||
const decoded = Buffer.from(entry.content, 'base64').toString('utf-8');
|
||||
const matches = decoded.match(/-----BEGIN CERTIFICATE-----/g);
|
||||
expect(matches).toHaveLength(1);
|
||||
}
|
||||
|
||||
// CN values are present
|
||||
const cns = result.certs.map((c: any) => c.subject.cn);
|
||||
expect(cns).toContain(CN1);
|
||||
expect(cns).toContain(CN2);
|
||||
|
||||
// validity.notAfter is present and looks like ISO 8601
|
||||
for (const entry of result.certs) {
|
||||
expect(entry.validity.notAfter).toMatch(/^\d{4}-\d{2}-\d{2}T/);
|
||||
}
|
||||
});
|
||||
|
||||
it('returns enclosed certs from a P7B PEM bundle', async () => {
|
||||
// RED: splitCerts throws NotImplementedException — FAIL
|
||||
const result = await (service.splitCerts({
|
||||
file: { originalname: 'bundle.p7b', buffer: p7bBuffer },
|
||||
}) as Promise<any>);
|
||||
expect(result.count).toBeGreaterThanOrEqual(1);
|
||||
expect(result.certs.length).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
|
||||
it('throws BadRequestException for malformed input', async () => {
|
||||
// RED: splitCerts throws NotImplementedException (not BadRequestException) — FAIL
|
||||
await expect(
|
||||
service.splitCerts({
|
||||
file: { originalname: 'bad.pem', buffer: Buffer.from('this is garbage') },
|
||||
}),
|
||||
).rejects.toThrow(BadRequestException);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user