test(09-01): add failing spec for cert-manager seed + helpers (RED)
- Test: seedCertManagerModule calls seedModule with slug='cert-manager', category='security-tools', isSystem=true - Test: detectFormat returns pem/der/pfx/p7b based on extension + content sniff - Test: getFingerprint returns uppercase colon-separated hex (sha1 + sha256) - Test: parsePemChain returns array of length 2 for two concatenated PEMs
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
import * as forge from 'node-forge';
|
||||
import { beforeAll, describe, expect, it, vi } from 'vitest';
|
||||
import { seedCertManagerModule } from './cert-manager.seed';
|
||||
import { CertManagerService } from './cert-manager.service';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Test helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Generate a self-signed X.509 cert via node-forge (RSA 1024 — fast for tests) */
|
||||
function generateSelfSignedCert(): forge.pki.Certificate {
|
||||
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: 'test.example.com' }];
|
||||
cert.setSubject(attrs);
|
||||
cert.setIssuer(attrs);
|
||||
cert.sign(keys.privateKey, forge.md.sha256.create());
|
||||
return cert;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tests
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('seedCertManagerModule', () => {
|
||||
it('calls moduleRegistryService.seedModule once with cert-manager slug', async () => {
|
||||
const mockSeedModule = vi.fn().mockResolvedValue(undefined);
|
||||
const mockModuleRegistryService = { seedModule: mockSeedModule } as any;
|
||||
|
||||
await seedCertManagerModule(mockModuleRegistryService);
|
||||
|
||||
expect(mockSeedModule).toHaveBeenCalledTimes(1);
|
||||
const arg = mockSeedModule.mock.calls[0][0];
|
||||
expect(arg.slug).toBe('cert-manager');
|
||||
expect(arg.category).toBe('security-tools');
|
||||
expect(arg.isSystem).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CertManagerService helpers', () => {
|
||||
let service: CertManagerService;
|
||||
let testCert: forge.pki.Certificate;
|
||||
|
||||
beforeAll(() => {
|
||||
service = new CertManagerService();
|
||||
testCert = generateSelfSignedCert();
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// detectFormat
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
describe('detectFormat', () => {
|
||||
it('returns "pfx" for .pfx extension', () => {
|
||||
const buf = Buffer.from([0x30, 0x82]); // arbitrary binary
|
||||
expect(service.detectFormat('cert.pfx', buf)).toBe('pfx');
|
||||
});
|
||||
|
||||
it('returns "p7b" for .p7b extension', () => {
|
||||
const buf = Buffer.from([0x30, 0x82]);
|
||||
expect(service.detectFormat('cert.p7b', buf)).toBe('p7b');
|
||||
});
|
||||
|
||||
it('returns "der" for .der extension', () => {
|
||||
const buf = Buffer.from([0x30, 0x82]);
|
||||
expect(service.detectFormat('cert.der', buf)).toBe('der');
|
||||
});
|
||||
|
||||
it('returns "pem" for .pem extension', () => {
|
||||
const buf = Buffer.from('-----BEGIN CERTIFICATE-----\nfake\n-----END CERTIFICATE-----');
|
||||
expect(service.detectFormat('cert.pem', buf)).toBe('pem');
|
||||
});
|
||||
|
||||
it('returns "pem" for .cer extension with PEM content', () => {
|
||||
const buf = Buffer.from('-----BEGIN CERTIFICATE-----\nfake\n-----END CERTIFICATE-----');
|
||||
expect(service.detectFormat('cert.cer', buf)).toBe('pem');
|
||||
});
|
||||
|
||||
it('returns "der" for .cer extension with binary (non-PEM) content', () => {
|
||||
const buf = Buffer.from([0x30, 0x82, 0x01, 0x00]);
|
||||
expect(service.detectFormat('cert.cer', buf)).toBe('der');
|
||||
});
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// getFingerprint
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
describe('getFingerprint', () => {
|
||||
it('returns uppercase colon-separated hex for sha256', () => {
|
||||
const fp = service.getFingerprint(testCert, 'sha256');
|
||||
// e.g. "AA:BB:CC:..."
|
||||
expect(fp).toMatch(/^[0-9A-F]{2}(:[0-9A-F]{2})+$/);
|
||||
});
|
||||
|
||||
it('returns uppercase colon-separated hex for sha1', () => {
|
||||
const fp = service.getFingerprint(testCert, 'sha1');
|
||||
expect(fp).toMatch(/^[0-9A-F]{2}(:[0-9A-F]{2})+$/);
|
||||
});
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// parsePemChain
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
describe('parsePemChain', () => {
|
||||
it('returns array of length 2 for two concatenated cert PEMs', () => {
|
||||
const cert1 = generateSelfSignedCert();
|
||||
const cert2 = generateSelfSignedCert();
|
||||
const pem1 = forge.pki.certificateToPem(cert1);
|
||||
const pem2 = forge.pki.certificateToPem(cert2);
|
||||
const chain = pem1 + '\n' + pem2;
|
||||
|
||||
const parsed = service.parsePemChain(chain);
|
||||
expect(parsed).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('returns array of length 1 for a single PEM', () => {
|
||||
const pem = forge.pki.certificateToPem(testCert);
|
||||
const parsed = service.parsePemChain(pem);
|
||||
expect(parsed).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user