test + docs: close 12 test gaps (~250 new tests) and expand testing guide to 34 parts

Implements all P0-P2 test gaps from docs/test-gap-prompt.md:
- Deployment service tests (20), target service tests (18), scheduler tests (8)
- Agent binary tests (48), CSR renewal tests (8), short-lived cert tests (7)
- Domain model tests (25), context cancellation tests (9), concurrency tests (7)
- Handler negative-path tests (23 across 5 files)
- Frontend error handling tests (86) and API client tests (7)

Expands testing-guide.md from 28 to 34 parts covering certificate export,
S/MIME/EKU, OCSP/DER CRL, body size limits, Apache/HAProxy connectors,
and sub-CA mode. Fixes stale profile count (4->5) and updates sign-off table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shankar0123
2026-03-28 17:57:25 -04:00
parent 63e6f3ef91
commit 03472072b8
30 changed files with 7422 additions and 23 deletions
+112
View File
@@ -316,3 +316,115 @@ func TestGetPrometheusMetrics_ZeroValues(t *testing.T) {
func containsLine(text, substr string) bool {
return strings.Contains(text, substr)
}
// Test GetCertificatesByStatus - method not allowed
func TestGetCertificatesByStatus_MethodNotAllowed(t *testing.T) {
mock := &MockStatsService{}
h := NewStatsHandler(mock)
req := httptest.NewRequest(http.MethodPost, "/api/v1/stats/certificates-by-status", nil)
w := httptest.NewRecorder()
h.GetCertificatesByStatus(w, req)
if w.Code != http.StatusMethodNotAllowed {
t.Errorf("expected 405, got %d", w.Code)
}
}
// Test GetCertificatesByStatus - service error
func TestGetCertificatesByStatus_ServiceError(t *testing.T) {
mock := &MockStatsService{
GetCertificatesByStatusFn: func(ctx context.Context) (interface{}, error) {
return nil, fmt.Errorf("db error")
},
}
h := NewStatsHandler(mock)
req := httptest.NewRequest(http.MethodGet, "/api/v1/stats/certificates-by-status", nil)
w := httptest.NewRecorder()
h.GetCertificatesByStatus(w, req)
if w.Code != http.StatusInternalServerError {
t.Errorf("expected 500, got %d", w.Code)
}
}
// Test GetExpirationTimeline - method not allowed
func TestGetExpirationTimeline_MethodNotAllowed(t *testing.T) {
mock := &MockStatsService{}
h := NewStatsHandler(mock)
req := httptest.NewRequest(http.MethodPost, "/api/v1/stats/expiration-timeline", nil)
w := httptest.NewRecorder()
h.GetExpirationTimeline(w, req)
if w.Code != http.StatusMethodNotAllowed {
t.Errorf("expected 405, got %d", w.Code)
}
}
// Test GetExpirationTimeline - service error
func TestGetExpirationTimeline_ServiceError(t *testing.T) {
mock := &MockStatsService{
GetExpirationTimelineFn: func(ctx context.Context, days int) (interface{}, error) {
return nil, fmt.Errorf("db error")
},
}
h := NewStatsHandler(mock)
req := httptest.NewRequest(http.MethodGet, "/api/v1/stats/expiration-timeline?days=30", nil)
w := httptest.NewRecorder()
h.GetExpirationTimeline(w, req)
if w.Code != http.StatusInternalServerError {
t.Errorf("expected 500, got %d", w.Code)
}
}
// Test GetJobTrends - method not allowed
func TestGetJobTrends_MethodNotAllowed(t *testing.T) {
mock := &MockStatsService{}
h := NewStatsHandler(mock)
req := httptest.NewRequest(http.MethodPost, "/api/v1/stats/job-trends", nil)
w := httptest.NewRecorder()
h.GetJobTrends(w, req)
if w.Code != http.StatusMethodNotAllowed {
t.Errorf("expected 405, got %d", w.Code)
}
}
// Test GetJobTrends - service error
func TestGetJobTrends_ServiceError(t *testing.T) {
mock := &MockStatsService{
GetJobStatsFn: func(ctx context.Context, days int) (interface{}, error) {
return nil, fmt.Errorf("db error")
},
}
h := NewStatsHandler(mock)
req := httptest.NewRequest(http.MethodGet, "/api/v1/stats/job-trends?days=14", nil)
w := httptest.NewRecorder()
h.GetJobTrends(w, req)
if w.Code != http.StatusInternalServerError {
t.Errorf("expected 500, got %d", w.Code)
}
}
// Test GetIssuanceRate - method not allowed
func TestGetIssuanceRate_MethodNotAllowed(t *testing.T) {
mock := &MockStatsService{}
h := NewStatsHandler(mock)
req := httptest.NewRequest(http.MethodPost, "/api/v1/stats/issuance-rate", nil)
w := httptest.NewRecorder()
h.GetIssuanceRate(w, req)
if w.Code != http.StatusMethodNotAllowed {
t.Errorf("expected 405, got %d", w.Code)
}
}
// Test GetIssuanceRate - service error
func TestGetIssuanceRate_ServiceError(t *testing.T) {
mock := &MockStatsService{
GetIssuanceRateFn: func(ctx context.Context, days int) (interface{}, error) {
return nil, fmt.Errorf("db error")
},
}
h := NewStatsHandler(mock)
req := httptest.NewRequest(http.MethodGet, "/api/v1/stats/issuance-rate?days=7", nil)
w := httptest.NewRecorder()
h.GetIssuanceRate(w, req)
if w.Code != http.StatusInternalServerError {
t.Errorf("expected 500, got %d", w.Code)
}
}