mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 20:31:30 +00:00
7cb453a336
Mechanical reformat. The new 'gofmt drift' CI step (added in
ci-pipeline-cleanup Phase 4, commit 0f205a8) surfaced 111 files
with accumulated gofmt drift across cmd/, internal/, and deploy/test/.
Each file's diff is gofmt-standard: whitespace adjustments, intra-
group import sorting (alphabetical by import path within blank-line-
separated groups), and struct-tag column alignment. No semantic
changes — verified via 'git diff --ignore-all-space' which shows only
the line-position deltas from import reordering.
The gate stays in place after this commit. Going forward it catches
gofmt drift at PR time.
128 lines
4.2 KiB
Go
128 lines
4.2 KiB
Go
package domain
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestNotificationType_Constants(t *testing.T) {
|
|
tests := map[string]NotificationType{
|
|
"ExpirationWarning": NotificationTypeExpirationWarning,
|
|
"RenewalSuccess": NotificationTypeRenewalSuccess,
|
|
"RenewalFailure": NotificationTypeRenewalFailure,
|
|
"DeploymentSuccess": NotificationTypeDeploymentSuccess,
|
|
"DeploymentFailure": NotificationTypeDeploymentFailure,
|
|
"PolicyViolation": NotificationTypePolicyViolation,
|
|
"Revocation": NotificationTypeRevocation,
|
|
}
|
|
for expected, got := range tests {
|
|
if string(got) != expected {
|
|
t.Errorf("expected %q, got %q", expected, string(got))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNotificationChannel_Constants(t *testing.T) {
|
|
tests := map[string]NotificationChannel{
|
|
"Email": NotificationChannelEmail,
|
|
"Webhook": NotificationChannelWebhook,
|
|
"Slack": NotificationChannelSlack,
|
|
"Teams": NotificationChannelTeams,
|
|
"PagerDuty": NotificationChannelPagerDuty,
|
|
"OpsGenie": NotificationChannelOpsGenie,
|
|
}
|
|
for expected, got := range tests {
|
|
if string(got) != expected {
|
|
t.Errorf("expected %q, got %q", expected, string(got))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNotificationEvent_Fields(t *testing.T) {
|
|
// This test verifies the NotificationEvent struct can be instantiated
|
|
// with all expected fields.
|
|
certID := "mc-123"
|
|
errorMsg := "failed to send"
|
|
event := &NotificationEvent{
|
|
ID: "notif-1",
|
|
Type: NotificationTypeExpirationWarning,
|
|
CertificateID: &certID,
|
|
Channel: NotificationChannelSlack,
|
|
Recipient: "alerts@example.com",
|
|
Message: "Certificate expiring in 30 days",
|
|
Status: "sent",
|
|
Error: &errorMsg,
|
|
}
|
|
|
|
if event.ID != "notif-1" {
|
|
t.Errorf("expected ID 'notif-1', got %s", event.ID)
|
|
}
|
|
|
|
if event.Type != NotificationTypeExpirationWarning {
|
|
t.Errorf("expected type ExpirationWarning, got %s", string(event.Type))
|
|
}
|
|
|
|
if event.Channel != NotificationChannelSlack {
|
|
t.Errorf("expected channel Slack, got %s", string(event.Channel))
|
|
}
|
|
|
|
if event.CertificateID == nil || *event.CertificateID != "mc-123" {
|
|
t.Errorf("expected CertificateID mc-123, got %v", event.CertificateID)
|
|
}
|
|
|
|
if event.Error == nil || *event.Error != "failed to send" {
|
|
t.Errorf("expected error 'failed to send', got %v", event.Error)
|
|
}
|
|
}
|
|
|
|
// TestNotificationStatus_Constants verifies that I-005 introduces a typed
|
|
// NotificationStatus alongside canonical lowercase string constants covering
|
|
// the pending → sent, pending → failed → dead, and pending → read transitions.
|
|
// The Red signal here is a compile error: the type and the NotificationStatusDead
|
|
// constant do not exist before Phase 2 Green.
|
|
func TestNotificationStatus_Constants(t *testing.T) {
|
|
tests := map[string]NotificationStatus{
|
|
"pending": NotificationStatusPending,
|
|
"sent": NotificationStatusSent,
|
|
"failed": NotificationStatusFailed,
|
|
"dead": NotificationStatusDead,
|
|
"read": NotificationStatusRead,
|
|
}
|
|
for expected, got := range tests {
|
|
if string(got) != expected {
|
|
t.Errorf("expected %q, got %q", expected, string(got))
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestNotificationEvent_RetryFields verifies the I-005 retry/DLQ columns are
|
|
// surfaced on the domain model: a RetryCount counter, a nullable NextRetryAt
|
|
// timestamp used by the retry-sweep partial index, and a nullable LastError
|
|
// string preserving the most recent transient failure for operator triage.
|
|
// The Red signal is a compile error — these fields do not exist yet.
|
|
func TestNotificationEvent_RetryFields(t *testing.T) {
|
|
next := time.Now().Add(2 * time.Minute)
|
|
lastErr := "connection refused"
|
|
event := &NotificationEvent{
|
|
ID: "notif-retry-001",
|
|
Type: NotificationTypeExpirationWarning,
|
|
Channel: NotificationChannelWebhook,
|
|
Recipient: "https://hooks.example.com/certs",
|
|
Message: "retry me",
|
|
Status: string(NotificationStatusFailed),
|
|
RetryCount: 3,
|
|
NextRetryAt: &next,
|
|
LastError: &lastErr,
|
|
}
|
|
|
|
if event.RetryCount != 3 {
|
|
t.Errorf("expected RetryCount 3, got %d", event.RetryCount)
|
|
}
|
|
if event.NextRetryAt == nil || !event.NextRetryAt.Equal(next) {
|
|
t.Errorf("expected NextRetryAt %v, got %v", next, event.NextRetryAt)
|
|
}
|
|
if event.LastError == nil || *event.LastError != "connection refused" {
|
|
t.Errorf("expected LastError 'connection refused', got %v", event.LastError)
|
|
}
|
|
}
|