mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 15:01:32 +00:00
Implement M4: comprehensive test coverage with 120 tests
Service layer (63 tests): certificate, agent, audit, job, notification, policy, and renewal services with mock repositories covering threshold alerting, deduplication, status transitions, and job processing. Handler layer (46 tests): certificate and agent HTTP handlers using httptest with mock service interfaces, covering success/error paths, pagination, JSON marshaling, and path parameter extraction. Integration (11 subtests): end-to-end certificate lifecycle test exercising real services and Local CA issuer through HTTP API — create cert, trigger renewal, process jobs, register agent, heartbeat, verify audit trail. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,771 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/shankar0123/certctl/internal/domain"
|
||||
"github.com/shankar0123/certctl/internal/repository"
|
||||
)
|
||||
|
||||
var errNotFound = errors.New("not found")
|
||||
|
||||
// mockCertRepo is a test implementation of CertificateRepository
|
||||
type mockCertRepo struct {
|
||||
Certs map[string]*domain.ManagedCertificate
|
||||
Versions map[string][]*domain.CertificateVersion
|
||||
CreateErr error
|
||||
UpdateErr error
|
||||
GetErr error
|
||||
ListErr error
|
||||
ListVersionsErr error
|
||||
ListVersionsResult []*domain.CertificateVersion
|
||||
CreateVersionErr error
|
||||
ArchiveErr error
|
||||
}
|
||||
|
||||
func (m *mockCertRepo) List(ctx context.Context, filter *repository.CertificateFilter) ([]*domain.ManagedCertificate, int, error) {
|
||||
if m.ListErr != nil {
|
||||
return nil, 0, m.ListErr
|
||||
}
|
||||
var certs []*domain.ManagedCertificate
|
||||
for _, c := range m.Certs {
|
||||
certs = append(certs, c)
|
||||
}
|
||||
return certs, len(certs), nil
|
||||
}
|
||||
|
||||
func (m *mockCertRepo) Get(ctx context.Context, id string) (*domain.ManagedCertificate, error) {
|
||||
if m.GetErr != nil {
|
||||
return nil, m.GetErr
|
||||
}
|
||||
cert, ok := m.Certs[id]
|
||||
if !ok {
|
||||
return nil, errNotFound
|
||||
}
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
func (m *mockCertRepo) Create(ctx context.Context, cert *domain.ManagedCertificate) error {
|
||||
if m.CreateErr != nil {
|
||||
return m.CreateErr
|
||||
}
|
||||
m.Certs[cert.ID] = cert
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockCertRepo) Update(ctx context.Context, cert *domain.ManagedCertificate) error {
|
||||
if m.UpdateErr != nil {
|
||||
return m.UpdateErr
|
||||
}
|
||||
m.Certs[cert.ID] = cert
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockCertRepo) Archive(ctx context.Context, id string) error {
|
||||
if m.ArchiveErr != nil {
|
||||
return m.ArchiveErr
|
||||
}
|
||||
cert, ok := m.Certs[id]
|
||||
if !ok {
|
||||
return errNotFound
|
||||
}
|
||||
cert.Status = domain.CertificateStatusArchived
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockCertRepo) ListVersions(ctx context.Context, certID string) ([]*domain.CertificateVersion, error) {
|
||||
if m.ListVersionsErr != nil {
|
||||
return nil, m.ListVersionsErr
|
||||
}
|
||||
if m.ListVersionsResult != nil {
|
||||
return m.ListVersionsResult, nil
|
||||
}
|
||||
return m.Versions[certID], nil
|
||||
}
|
||||
|
||||
func (m *mockCertRepo) CreateVersion(ctx context.Context, version *domain.CertificateVersion) error {
|
||||
if m.CreateVersionErr != nil {
|
||||
return m.CreateVersionErr
|
||||
}
|
||||
m.Versions[version.CertificateID] = append(m.Versions[version.CertificateID], version)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockCertRepo) GetExpiringCertificates(ctx context.Context, before time.Time) ([]*domain.ManagedCertificate, error) {
|
||||
var expiring []*domain.ManagedCertificate
|
||||
for _, c := range m.Certs {
|
||||
if c.ExpiresAt.Before(before) {
|
||||
expiring = append(expiring, c)
|
||||
}
|
||||
}
|
||||
return expiring, nil
|
||||
}
|
||||
|
||||
func (m *mockCertRepo) AddCert(cert *domain.ManagedCertificate) {
|
||||
m.Certs[cert.ID] = cert
|
||||
}
|
||||
|
||||
// mockJobRepo is a test implementation of JobRepository
|
||||
type mockJobRepo struct {
|
||||
Jobs map[string]*domain.Job
|
||||
StatusUpdates map[string]domain.JobStatus
|
||||
CreateErr error
|
||||
UpdateErr error
|
||||
UpdateStatusErr error
|
||||
GetErr error
|
||||
ListErr error
|
||||
ListByStatusErr error
|
||||
DeleteErr error
|
||||
}
|
||||
|
||||
func (m *mockJobRepo) List(ctx context.Context) ([]*domain.Job, error) {
|
||||
if m.ListErr != nil {
|
||||
return nil, m.ListErr
|
||||
}
|
||||
var jobs []*domain.Job
|
||||
for _, j := range m.Jobs {
|
||||
jobs = append(jobs, j)
|
||||
}
|
||||
return jobs, nil
|
||||
}
|
||||
|
||||
func (m *mockJobRepo) Get(ctx context.Context, id string) (*domain.Job, error) {
|
||||
if m.GetErr != nil {
|
||||
return nil, m.GetErr
|
||||
}
|
||||
job, ok := m.Jobs[id]
|
||||
if !ok {
|
||||
return nil, errNotFound
|
||||
}
|
||||
return job, nil
|
||||
}
|
||||
|
||||
func (m *mockJobRepo) Create(ctx context.Context, job *domain.Job) error {
|
||||
if m.CreateErr != nil {
|
||||
return m.CreateErr
|
||||
}
|
||||
m.Jobs[job.ID] = job
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockJobRepo) Update(ctx context.Context, job *domain.Job) error {
|
||||
if m.UpdateErr != nil {
|
||||
return m.UpdateErr
|
||||
}
|
||||
m.Jobs[job.ID] = job
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockJobRepo) Delete(ctx context.Context, id string) error {
|
||||
if m.DeleteErr != nil {
|
||||
return m.DeleteErr
|
||||
}
|
||||
delete(m.Jobs, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockJobRepo) ListByStatus(ctx context.Context, status domain.JobStatus) ([]*domain.Job, error) {
|
||||
if m.ListByStatusErr != nil {
|
||||
return nil, m.ListByStatusErr
|
||||
}
|
||||
var jobs []*domain.Job
|
||||
for _, j := range m.Jobs {
|
||||
if j.Status == status {
|
||||
jobs = append(jobs, j)
|
||||
}
|
||||
}
|
||||
return jobs, nil
|
||||
}
|
||||
|
||||
func (m *mockJobRepo) ListByCertificate(ctx context.Context, certID string) ([]*domain.Job, error) {
|
||||
var jobs []*domain.Job
|
||||
for _, j := range m.Jobs {
|
||||
if j.CertificateID == certID {
|
||||
jobs = append(jobs, j)
|
||||
}
|
||||
}
|
||||
return jobs, nil
|
||||
}
|
||||
|
||||
func (m *mockJobRepo) UpdateStatus(ctx context.Context, id string, status domain.JobStatus, errMsg string) error {
|
||||
if m.UpdateStatusErr != nil {
|
||||
return m.UpdateStatusErr
|
||||
}
|
||||
job, ok := m.Jobs[id]
|
||||
if !ok {
|
||||
return errNotFound
|
||||
}
|
||||
job.Status = status
|
||||
if errMsg != "" {
|
||||
job.LastError = &errMsg
|
||||
}
|
||||
m.StatusUpdates[id] = status
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockJobRepo) GetPendingJobs(ctx context.Context, jobType domain.JobType) ([]*domain.Job, error) {
|
||||
var jobs []*domain.Job
|
||||
for _, j := range m.Jobs {
|
||||
if j.Type == jobType && j.Status == domain.JobStatusPending {
|
||||
jobs = append(jobs, j)
|
||||
}
|
||||
}
|
||||
return jobs, nil
|
||||
}
|
||||
|
||||
func (m *mockJobRepo) AddJob(job *domain.Job) {
|
||||
m.Jobs[job.ID] = job
|
||||
}
|
||||
|
||||
// mockNotifRepo is a test implementation of NotificationRepository
|
||||
type mockNotifRepo struct {
|
||||
Notifications []*domain.NotificationEvent
|
||||
CreateErr error
|
||||
ListErr error
|
||||
UpdateErr error
|
||||
}
|
||||
|
||||
func (m *mockNotifRepo) Create(ctx context.Context, notif *domain.NotificationEvent) error {
|
||||
if m.CreateErr != nil {
|
||||
return m.CreateErr
|
||||
}
|
||||
m.Notifications = append(m.Notifications, notif)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockNotifRepo) List(ctx context.Context, filter *repository.NotificationFilter) ([]*domain.NotificationEvent, error) {
|
||||
if m.ListErr != nil {
|
||||
return nil, m.ListErr
|
||||
}
|
||||
return m.Notifications, nil
|
||||
}
|
||||
|
||||
func (m *mockNotifRepo) UpdateStatus(ctx context.Context, id string, status string, sentAt time.Time) error {
|
||||
if m.UpdateErr != nil {
|
||||
return m.UpdateErr
|
||||
}
|
||||
for _, n := range m.Notifications {
|
||||
if n.ID == id {
|
||||
n.Status = status
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errNotFound
|
||||
}
|
||||
|
||||
func (m *mockNotifRepo) AddNotification(notif *domain.NotificationEvent) {
|
||||
m.Notifications = append(m.Notifications, notif)
|
||||
}
|
||||
|
||||
// mockAuditRepo is a test implementation of AuditRepository
|
||||
type mockAuditRepo struct {
|
||||
Events []*domain.AuditEvent
|
||||
CreateErr error
|
||||
ListErr error
|
||||
}
|
||||
|
||||
func (m *mockAuditRepo) Create(ctx context.Context, event *domain.AuditEvent) error {
|
||||
if m.CreateErr != nil {
|
||||
return m.CreateErr
|
||||
}
|
||||
m.Events = append(m.Events, event)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockAuditRepo) List(ctx context.Context, filter *repository.AuditFilter) ([]*domain.AuditEvent, error) {
|
||||
if m.ListErr != nil {
|
||||
return nil, m.ListErr
|
||||
}
|
||||
// Apply filtering like the real repo
|
||||
var filtered []*domain.AuditEvent
|
||||
for _, e := range m.Events {
|
||||
if filter != nil {
|
||||
if filter.ResourceType != "" && e.ResourceType != filter.ResourceType {
|
||||
continue
|
||||
}
|
||||
if filter.ResourceID != "" && e.ResourceID != filter.ResourceID {
|
||||
continue
|
||||
}
|
||||
if filter.Actor != "" && e.Actor != filter.Actor {
|
||||
continue
|
||||
}
|
||||
if !filter.From.IsZero() && e.Timestamp.Before(filter.From) {
|
||||
continue
|
||||
}
|
||||
if !filter.To.IsZero() && e.Timestamp.After(filter.To) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
filtered = append(filtered, e)
|
||||
}
|
||||
return filtered, nil
|
||||
}
|
||||
|
||||
func (m *mockAuditRepo) AddEvent(event *domain.AuditEvent) {
|
||||
m.Events = append(m.Events, event)
|
||||
}
|
||||
|
||||
// mockPolicyRepo is a test implementation of PolicyRepository
|
||||
type mockPolicyRepo struct {
|
||||
Rules map[string]*domain.PolicyRule
|
||||
Violations []*domain.PolicyViolation
|
||||
CreateRuleErr error
|
||||
UpdateRuleErr error
|
||||
DeleteRuleErr error
|
||||
GetRuleErr error
|
||||
ListRulesErr error
|
||||
CreateViolationErr error
|
||||
ListViolationsErr error
|
||||
}
|
||||
|
||||
func (m *mockPolicyRepo) ListRules(ctx context.Context) ([]*domain.PolicyRule, error) {
|
||||
if m.ListRulesErr != nil {
|
||||
return nil, m.ListRulesErr
|
||||
}
|
||||
var rules []*domain.PolicyRule
|
||||
for _, r := range m.Rules {
|
||||
rules = append(rules, r)
|
||||
}
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func (m *mockPolicyRepo) GetRule(ctx context.Context, id string) (*domain.PolicyRule, error) {
|
||||
if m.GetRuleErr != nil {
|
||||
return nil, m.GetRuleErr
|
||||
}
|
||||
rule, ok := m.Rules[id]
|
||||
if !ok {
|
||||
return nil, errNotFound
|
||||
}
|
||||
return rule, nil
|
||||
}
|
||||
|
||||
func (m *mockPolicyRepo) CreateRule(ctx context.Context, rule *domain.PolicyRule) error {
|
||||
if m.CreateRuleErr != nil {
|
||||
return m.CreateRuleErr
|
||||
}
|
||||
m.Rules[rule.ID] = rule
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockPolicyRepo) UpdateRule(ctx context.Context, rule *domain.PolicyRule) error {
|
||||
if m.UpdateRuleErr != nil {
|
||||
return m.UpdateRuleErr
|
||||
}
|
||||
m.Rules[rule.ID] = rule
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockPolicyRepo) DeleteRule(ctx context.Context, id string) error {
|
||||
if m.DeleteRuleErr != nil {
|
||||
return m.DeleteRuleErr
|
||||
}
|
||||
delete(m.Rules, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockPolicyRepo) CreateViolation(ctx context.Context, violation *domain.PolicyViolation) error {
|
||||
if m.CreateViolationErr != nil {
|
||||
return m.CreateViolationErr
|
||||
}
|
||||
m.Violations = append(m.Violations, violation)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockPolicyRepo) ListViolations(ctx context.Context, filter *repository.AuditFilter) ([]*domain.PolicyViolation, error) {
|
||||
if m.ListViolationsErr != nil {
|
||||
return nil, m.ListViolationsErr
|
||||
}
|
||||
return m.Violations, nil
|
||||
}
|
||||
|
||||
func (m *mockPolicyRepo) AddRule(rule *domain.PolicyRule) {
|
||||
m.Rules[rule.ID] = rule
|
||||
}
|
||||
|
||||
// mockRenewalPolicyRepo is a test implementation of RenewalPolicyRepository
|
||||
type mockRenewalPolicyRepo struct {
|
||||
Policies map[string]*domain.RenewalPolicy
|
||||
GetErr error
|
||||
ListErr error
|
||||
}
|
||||
|
||||
func (m *mockRenewalPolicyRepo) Get(ctx context.Context, id string) (*domain.RenewalPolicy, error) {
|
||||
if m.GetErr != nil {
|
||||
return nil, m.GetErr
|
||||
}
|
||||
policy, ok := m.Policies[id]
|
||||
if !ok {
|
||||
return nil, errNotFound
|
||||
}
|
||||
return policy, nil
|
||||
}
|
||||
|
||||
func (m *mockRenewalPolicyRepo) List(ctx context.Context) ([]*domain.RenewalPolicy, error) {
|
||||
if m.ListErr != nil {
|
||||
return nil, m.ListErr
|
||||
}
|
||||
var policies []*domain.RenewalPolicy
|
||||
for _, p := range m.Policies {
|
||||
policies = append(policies, p)
|
||||
}
|
||||
return policies, nil
|
||||
}
|
||||
|
||||
func (m *mockRenewalPolicyRepo) AddPolicy(policy *domain.RenewalPolicy) {
|
||||
m.Policies[policy.ID] = policy
|
||||
}
|
||||
|
||||
// mockAgentRepo is a test implementation of AgentRepository
|
||||
type mockAgentRepo struct {
|
||||
Agents map[string]*domain.Agent
|
||||
HeartbeatUpdates map[string]time.Time
|
||||
CreateErr error
|
||||
UpdateErr error
|
||||
DeleteErr error
|
||||
GetErr error
|
||||
ListErr error
|
||||
UpdateHeartbeatErr error
|
||||
GetByAPIKeyErr error
|
||||
}
|
||||
|
||||
func (m *mockAgentRepo) List(ctx context.Context) ([]*domain.Agent, error) {
|
||||
if m.ListErr != nil {
|
||||
return nil, m.ListErr
|
||||
}
|
||||
var agents []*domain.Agent
|
||||
for _, a := range m.Agents {
|
||||
agents = append(agents, a)
|
||||
}
|
||||
return agents, nil
|
||||
}
|
||||
|
||||
func (m *mockAgentRepo) Get(ctx context.Context, id string) (*domain.Agent, error) {
|
||||
if m.GetErr != nil {
|
||||
return nil, m.GetErr
|
||||
}
|
||||
agent, ok := m.Agents[id]
|
||||
if !ok {
|
||||
return nil, errNotFound
|
||||
}
|
||||
return agent, nil
|
||||
}
|
||||
|
||||
func (m *mockAgentRepo) Create(ctx context.Context, agent *domain.Agent) error {
|
||||
if m.CreateErr != nil {
|
||||
return m.CreateErr
|
||||
}
|
||||
m.Agents[agent.ID] = agent
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockAgentRepo) Update(ctx context.Context, agent *domain.Agent) error {
|
||||
if m.UpdateErr != nil {
|
||||
return m.UpdateErr
|
||||
}
|
||||
m.Agents[agent.ID] = agent
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockAgentRepo) Delete(ctx context.Context, id string) error {
|
||||
if m.DeleteErr != nil {
|
||||
return m.DeleteErr
|
||||
}
|
||||
delete(m.Agents, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockAgentRepo) UpdateHeartbeat(ctx context.Context, id string) error {
|
||||
if m.UpdateHeartbeatErr != nil {
|
||||
return m.UpdateHeartbeatErr
|
||||
}
|
||||
agent, ok := m.Agents[id]
|
||||
if !ok {
|
||||
return errNotFound
|
||||
}
|
||||
now := time.Now()
|
||||
agent.LastHeartbeatAt = &now
|
||||
m.HeartbeatUpdates[id] = now
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockAgentRepo) GetByAPIKey(ctx context.Context, keyHash string) (*domain.Agent, error) {
|
||||
if m.GetByAPIKeyErr != nil {
|
||||
return nil, m.GetByAPIKeyErr
|
||||
}
|
||||
for _, a := range m.Agents {
|
||||
if a.APIKeyHash == keyHash {
|
||||
return a, nil
|
||||
}
|
||||
}
|
||||
return nil, errNotFound
|
||||
}
|
||||
|
||||
func (m *mockAgentRepo) AddAgent(agent *domain.Agent) {
|
||||
m.Agents[agent.ID] = agent
|
||||
}
|
||||
|
||||
// mockTargetRepo is a test implementation of TargetRepository
|
||||
type mockTargetRepo struct {
|
||||
Targets map[string]*domain.DeploymentTarget
|
||||
CreateErr error
|
||||
UpdateErr error
|
||||
DeleteErr error
|
||||
GetErr error
|
||||
ListErr error
|
||||
ListByCertErr error
|
||||
}
|
||||
|
||||
func (m *mockTargetRepo) List(ctx context.Context) ([]*domain.DeploymentTarget, error) {
|
||||
if m.ListErr != nil {
|
||||
return nil, m.ListErr
|
||||
}
|
||||
var targets []*domain.DeploymentTarget
|
||||
for _, t := range m.Targets {
|
||||
targets = append(targets, t)
|
||||
}
|
||||
return targets, nil
|
||||
}
|
||||
|
||||
func (m *mockTargetRepo) Get(ctx context.Context, id string) (*domain.DeploymentTarget, error) {
|
||||
if m.GetErr != nil {
|
||||
return nil, m.GetErr
|
||||
}
|
||||
target, ok := m.Targets[id]
|
||||
if !ok {
|
||||
return nil, errNotFound
|
||||
}
|
||||
return target, nil
|
||||
}
|
||||
|
||||
func (m *mockTargetRepo) Create(ctx context.Context, target *domain.DeploymentTarget) error {
|
||||
if m.CreateErr != nil {
|
||||
return m.CreateErr
|
||||
}
|
||||
m.Targets[target.ID] = target
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockTargetRepo) Update(ctx context.Context, target *domain.DeploymentTarget) error {
|
||||
if m.UpdateErr != nil {
|
||||
return m.UpdateErr
|
||||
}
|
||||
m.Targets[target.ID] = target
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockTargetRepo) Delete(ctx context.Context, id string) error {
|
||||
if m.DeleteErr != nil {
|
||||
return m.DeleteErr
|
||||
}
|
||||
delete(m.Targets, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockTargetRepo) ListByCertificate(ctx context.Context, certID string) ([]*domain.DeploymentTarget, error) {
|
||||
if m.ListByCertErr != nil {
|
||||
return nil, m.ListByCertErr
|
||||
}
|
||||
return m.List(ctx)
|
||||
}
|
||||
|
||||
func (m *mockTargetRepo) AddTarget(target *domain.DeploymentTarget) {
|
||||
m.Targets[target.ID] = target
|
||||
}
|
||||
|
||||
// mockIssuerConnector is a test implementation of IssuerConnector
|
||||
type mockIssuerConnector struct {
|
||||
Result *IssuanceResult
|
||||
Err error
|
||||
}
|
||||
|
||||
func (m *mockIssuerConnector) IssueCertificate(ctx context.Context, commonName string, sans []string, csrPEM string) (*IssuanceResult, error) {
|
||||
if m.Err != nil {
|
||||
return nil, m.Err
|
||||
}
|
||||
if m.Result != nil {
|
||||
return m.Result, nil
|
||||
}
|
||||
now := time.Now()
|
||||
return &IssuanceResult{
|
||||
Serial: "test-serial-123",
|
||||
CertPEM: "-----BEGIN CERTIFICATE-----\ntest\n-----END CERTIFICATE-----",
|
||||
ChainPEM: "-----BEGIN CERTIFICATE-----\nchain\n-----END CERTIFICATE-----",
|
||||
NotBefore: now,
|
||||
NotAfter: now.AddDate(1, 0, 0),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *mockIssuerConnector) RenewCertificate(ctx context.Context, commonName string, sans []string, csrPEM string) (*IssuanceResult, error) {
|
||||
if m.Err != nil {
|
||||
return nil, m.Err
|
||||
}
|
||||
return m.IssueCertificate(ctx, commonName, sans, csrPEM)
|
||||
}
|
||||
|
||||
// Constructor functions for mocks
|
||||
|
||||
func newMockCertificateRepository() *mockCertRepo {
|
||||
return &mockCertRepo{
|
||||
Certs: make(map[string]*domain.ManagedCertificate),
|
||||
Versions: make(map[string][]*domain.CertificateVersion),
|
||||
}
|
||||
}
|
||||
|
||||
func newMockJobRepository() *mockJobRepo {
|
||||
return &mockJobRepo{
|
||||
Jobs: make(map[string]*domain.Job),
|
||||
StatusUpdates: make(map[string]domain.JobStatus),
|
||||
}
|
||||
}
|
||||
|
||||
func newMockNotificationRepository() *mockNotifRepo {
|
||||
return &mockNotifRepo{
|
||||
Notifications: make([]*domain.NotificationEvent, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func newMockAuditRepository() *mockAuditRepo {
|
||||
return &mockAuditRepo{
|
||||
Events: make([]*domain.AuditEvent, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func newMockPolicyRepository() *mockPolicyRepo {
|
||||
return &mockPolicyRepo{
|
||||
Rules: make(map[string]*domain.PolicyRule),
|
||||
Violations: make([]*domain.PolicyViolation, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func newMockRenewalPolicyRepository() *mockRenewalPolicyRepo {
|
||||
return &mockRenewalPolicyRepo{
|
||||
Policies: make(map[string]*domain.RenewalPolicy),
|
||||
}
|
||||
}
|
||||
|
||||
func newMockAgentRepository() *mockAgentRepo {
|
||||
return &mockAgentRepo{
|
||||
Agents: make(map[string]*domain.Agent),
|
||||
HeartbeatUpdates: make(map[string]time.Time),
|
||||
}
|
||||
}
|
||||
|
||||
func newMockTargetRepository() *mockTargetRepo {
|
||||
return &mockTargetRepo{
|
||||
Targets: make(map[string]*domain.DeploymentTarget),
|
||||
}
|
||||
}
|
||||
|
||||
func newMockIssuerRepository() *mockIssuerRepository {
|
||||
return &mockIssuerRepository{
|
||||
issuers: make(map[string]*domain.Issuer),
|
||||
}
|
||||
}
|
||||
|
||||
// mockIssuerRepository is a test implementation of IssuerRepository
|
||||
type mockIssuerRepository struct {
|
||||
issuers map[string]*domain.Issuer
|
||||
GetErr error
|
||||
ListErr error
|
||||
CreateErr error
|
||||
UpdateErr error
|
||||
DeleteErr error
|
||||
}
|
||||
|
||||
func (m *mockIssuerRepository) List(ctx context.Context) ([]*domain.Issuer, error) {
|
||||
if m.ListErr != nil {
|
||||
return nil, m.ListErr
|
||||
}
|
||||
var issuers []*domain.Issuer
|
||||
for _, i := range m.issuers {
|
||||
issuers = append(issuers, i)
|
||||
}
|
||||
return issuers, nil
|
||||
}
|
||||
|
||||
func (m *mockIssuerRepository) Get(ctx context.Context, id string) (*domain.Issuer, error) {
|
||||
if m.GetErr != nil {
|
||||
return nil, m.GetErr
|
||||
}
|
||||
issuer, ok := m.issuers[id]
|
||||
if !ok {
|
||||
return nil, errNotFound
|
||||
}
|
||||
return issuer, nil
|
||||
}
|
||||
|
||||
func (m *mockIssuerRepository) Create(ctx context.Context, issuer *domain.Issuer) error {
|
||||
if m.CreateErr != nil {
|
||||
return m.CreateErr
|
||||
}
|
||||
m.issuers[issuer.ID] = issuer
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockIssuerRepository) Update(ctx context.Context, issuer *domain.Issuer) error {
|
||||
if m.UpdateErr != nil {
|
||||
return m.UpdateErr
|
||||
}
|
||||
m.issuers[issuer.ID] = issuer
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockIssuerRepository) Delete(ctx context.Context, id string) error {
|
||||
if m.DeleteErr != nil {
|
||||
return m.DeleteErr
|
||||
}
|
||||
delete(m.issuers, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockIssuerRepository) AddIssuer(issuer *domain.Issuer) {
|
||||
m.issuers[issuer.ID] = issuer
|
||||
}
|
||||
|
||||
// mockNotifier is a simple notifier for testing
|
||||
type mockNotifier struct {
|
||||
messages []*mockNotifierMessage
|
||||
SendErr error
|
||||
}
|
||||
|
||||
type mockNotifierMessage struct {
|
||||
Recipient string
|
||||
Subject string
|
||||
Body string
|
||||
}
|
||||
|
||||
func newMockNotifier() *mockNotifier {
|
||||
return &mockNotifier{
|
||||
messages: make([]*mockNotifierMessage, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *mockNotifier) Send(ctx context.Context, recipient string, subject string, body string) error {
|
||||
if m.SendErr != nil {
|
||||
return m.SendErr
|
||||
}
|
||||
m.messages = append(m.messages, &mockNotifierMessage{
|
||||
Recipient: recipient,
|
||||
Subject: subject,
|
||||
Body: body,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockNotifier) Channel() string {
|
||||
return "Email"
|
||||
}
|
||||
|
||||
func (m *mockNotifier) getSentCount() int {
|
||||
return len(m.messages)
|
||||
}
|
||||
|
||||
func (m *mockNotifier) getLastMessage() *mockNotifierMessage {
|
||||
if len(m.messages) == 0 {
|
||||
return nil
|
||||
}
|
||||
return m.messages[len(m.messages)-1]
|
||||
}
|
||||
Reference in New Issue
Block a user