This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/consent-service/internal/services/consent_service_test.go
BreakPilot Dev 19855efacc
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed
feat: BreakPilot PWA - Full codebase (clean push without large binaries)
All services: admin-v2, studio-v2, website, ai-compliance-sdk,
consent-service, klausur-service, voice-service, and infrastructure.
Large PDFs and compiled binaries excluded via .gitignore.
2026-02-11 13:25:58 +01:00

519 lines
12 KiB
Go

package services
import (
"testing"
"time"
"github.com/google/uuid"
)
// TestConsentService_CreateConsent tests creating a new consent
func TestConsentService_CreateConsent(t *testing.T) {
// This is a unit test with table-driven approach
tests := []struct {
name string
userID uuid.UUID
versionID uuid.UUID
consented bool
expectError bool
errorContains string
}{
{
name: "valid consent - accepted",
userID: uuid.New(),
versionID: uuid.New(),
consented: true,
expectError: false,
},
{
name: "valid consent - declined",
userID: uuid.New(),
versionID: uuid.New(),
consented: false,
expectError: false,
},
{
name: "empty user ID",
userID: uuid.Nil,
versionID: uuid.New(),
consented: true,
expectError: true,
errorContains: "user ID",
},
{
name: "empty version ID",
userID: uuid.New(),
versionID: uuid.Nil,
consented: true,
expectError: true,
errorContains: "version ID",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Validate inputs (in real implementation this would be in the service)
var hasError bool
if tt.userID == uuid.Nil {
hasError = true
} else if tt.versionID == uuid.Nil {
hasError = true
}
// Assert
if tt.expectError && !hasError {
t.Errorf("Expected error containing '%s', got nil", tt.errorContains)
}
if !tt.expectError && hasError {
t.Error("Expected no error, got error")
}
})
}
}
// TestConsentService_WithdrawConsent tests withdrawing consent
func TestConsentService_WithdrawConsent(t *testing.T) {
tests := []struct {
name string
consentID uuid.UUID
userID uuid.UUID
expectError bool
errorContains string
}{
{
name: "valid withdrawal",
consentID: uuid.New(),
userID: uuid.New(),
expectError: false,
},
{
name: "empty consent ID",
consentID: uuid.Nil,
userID: uuid.New(),
expectError: true,
errorContains: "consent ID",
},
{
name: "empty user ID",
consentID: uuid.New(),
userID: uuid.Nil,
expectError: true,
errorContains: "user ID",
},
{
name: "both empty",
consentID: uuid.Nil,
userID: uuid.Nil,
expectError: true,
errorContains: "ID",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Validate
var hasError bool
if tt.consentID == uuid.Nil || tt.userID == uuid.Nil {
hasError = true
}
// Assert
if tt.expectError && !hasError {
t.Errorf("Expected error containing '%s', got nil", tt.errorContains)
}
if !tt.expectError && hasError {
t.Error("Expected no error, got error")
}
})
}
}
// TestConsentService_CheckConsent tests checking consent status
func TestConsentService_CheckConsent(t *testing.T) {
tests := []struct {
name string
userID uuid.UUID
documentType string
language string
hasConsent bool
needsUpdate bool
expectedConsent bool
expectedNeedsUpd bool
}{
{
name: "user has current consent",
userID: uuid.New(),
documentType: "terms",
language: "de",
hasConsent: true,
needsUpdate: false,
expectedConsent: true,
expectedNeedsUpd: false,
},
{
name: "user has outdated consent",
userID: uuid.New(),
documentType: "privacy",
language: "de",
hasConsent: true,
needsUpdate: true,
expectedConsent: true,
expectedNeedsUpd: true,
},
{
name: "user has no consent",
userID: uuid.New(),
documentType: "cookies",
language: "de",
hasConsent: false,
needsUpdate: true,
expectedConsent: false,
expectedNeedsUpd: true,
},
{
name: "english language",
userID: uuid.New(),
documentType: "terms",
language: "en",
hasConsent: true,
needsUpdate: false,
expectedConsent: true,
expectedNeedsUpd: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Simulate consent check logic
hasConsent := tt.hasConsent
needsUpdate := tt.needsUpdate
// Assert
if hasConsent != tt.expectedConsent {
t.Errorf("Expected hasConsent=%v, got %v", tt.expectedConsent, hasConsent)
}
if needsUpdate != tt.expectedNeedsUpd {
t.Errorf("Expected needsUpdate=%v, got %v", tt.expectedNeedsUpd, needsUpdate)
}
})
}
}
// TestConsentService_GetConsentHistory tests retrieving consent history
func TestConsentService_GetConsentHistory(t *testing.T) {
tests := []struct {
name string
userID uuid.UUID
expectError bool
expectEmpty bool
}{
{
name: "valid user with consents",
userID: uuid.New(),
expectError: false,
expectEmpty: false,
},
{
name: "valid user without consents",
userID: uuid.New(),
expectError: false,
expectEmpty: true,
},
{
name: "invalid user ID",
userID: uuid.Nil,
expectError: true,
expectEmpty: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Validate
var err error
if tt.userID == uuid.Nil {
err = &ValidationError{Field: "user ID", Message: "required"}
}
// Assert error expectation
if tt.expectError && err == nil {
t.Error("Expected error, got nil")
}
if !tt.expectError && err != nil {
t.Errorf("Expected no error, got %v", err)
}
})
}
}
// TestConsentService_UpdateConsent tests updating existing consent
func TestConsentService_UpdateConsent(t *testing.T) {
tests := []struct {
name string
consentID uuid.UUID
userID uuid.UUID
newConsented bool
expectError bool
}{
{
name: "update to consented",
consentID: uuid.New(),
userID: uuid.New(),
newConsented: true,
expectError: false,
},
{
name: "update to not consented",
consentID: uuid.New(),
userID: uuid.New(),
newConsented: false,
expectError: false,
},
{
name: "invalid consent ID",
consentID: uuid.Nil,
userID: uuid.New(),
newConsented: true,
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var err error
if tt.consentID == uuid.Nil {
err = &ValidationError{Field: "consent ID", Message: "required"}
}
if tt.expectError && err == nil {
t.Error("Expected error, got nil")
}
if !tt.expectError && err != nil {
t.Errorf("Expected no error, got %v", err)
}
})
}
}
// TestConsentService_GetConsentStats tests getting consent statistics
func TestConsentService_GetConsentStats(t *testing.T) {
tests := []struct {
name string
documentType string
totalUsers int
consentedUsers int
expectedRate float64
}{
{
name: "100% consent rate",
documentType: "terms",
totalUsers: 100,
consentedUsers: 100,
expectedRate: 100.0,
},
{
name: "50% consent rate",
documentType: "privacy",
totalUsers: 100,
consentedUsers: 50,
expectedRate: 50.0,
},
{
name: "0% consent rate",
documentType: "cookies",
totalUsers: 100,
consentedUsers: 0,
expectedRate: 0.0,
},
{
name: "no users",
documentType: "terms",
totalUsers: 0,
consentedUsers: 0,
expectedRate: 0.0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Calculate consent rate
var consentRate float64
if tt.totalUsers > 0 {
consentRate = float64(tt.consentedUsers) / float64(tt.totalUsers) * 100
}
// Assert
if consentRate != tt.expectedRate {
t.Errorf("Expected consent rate %.2f%%, got %.2f%%", tt.expectedRate, consentRate)
}
})
}
}
// TestConsentService_BulkConsentCheck tests checking multiple consents at once
func TestConsentService_BulkConsentCheck(t *testing.T) {
tests := []struct {
name string
userID uuid.UUID
documentTypes []string
expectError bool
}{
{
name: "check multiple documents",
userID: uuid.New(),
documentTypes: []string{"terms", "privacy", "cookies"},
expectError: false,
},
{
name: "check single document",
userID: uuid.New(),
documentTypes: []string{"terms"},
expectError: false,
},
{
name: "empty document list",
userID: uuid.New(),
documentTypes: []string{},
expectError: false,
},
{
name: "invalid user ID",
userID: uuid.Nil,
documentTypes: []string{"terms"},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var err error
if tt.userID == uuid.Nil {
err = &ValidationError{Field: "user ID", Message: "required"}
}
if tt.expectError && err == nil {
t.Error("Expected error, got nil")
}
if !tt.expectError && err != nil {
t.Errorf("Expected no error, got %v", err)
}
})
}
}
// TestConsentService_ConsentVersionComparison tests version comparison logic
func TestConsentService_ConsentVersionComparison(t *testing.T) {
tests := []struct {
name string
currentVersion string
consentedVersion string
needsUpdate bool
}{
{
name: "same version",
currentVersion: "1.0.0",
consentedVersion: "1.0.0",
needsUpdate: false,
},
{
name: "minor version update",
currentVersion: "1.1.0",
consentedVersion: "1.0.0",
needsUpdate: true,
},
{
name: "major version update",
currentVersion: "2.0.0",
consentedVersion: "1.0.0",
needsUpdate: true,
},
{
name: "patch version update",
currentVersion: "1.0.1",
consentedVersion: "1.0.0",
needsUpdate: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Simple version comparison (in real implementation use proper semver)
needsUpdate := tt.currentVersion != tt.consentedVersion
if needsUpdate != tt.needsUpdate {
t.Errorf("Expected needsUpdate=%v, got %v", tt.needsUpdate, needsUpdate)
}
})
}
}
// TestConsentService_ConsentDeadlineCheck tests deadline validation
func TestConsentService_ConsentDeadlineCheck(t *testing.T) {
now := time.Now()
tests := []struct {
name string
deadline time.Time
isOverdue bool
daysLeft int
}{
{
name: "deadline in 30 days",
deadline: now.AddDate(0, 0, 30),
isOverdue: false,
daysLeft: 30,
},
{
name: "deadline in 7 days",
deadline: now.AddDate(0, 0, 7),
isOverdue: false,
daysLeft: 7,
},
{
name: "deadline today",
deadline: now,
isOverdue: false,
daysLeft: 0,
},
{
name: "deadline 1 day overdue",
deadline: now.AddDate(0, 0, -1),
isOverdue: true,
daysLeft: -1,
},
{
name: "deadline 30 days overdue",
deadline: now.AddDate(0, 0, -30),
isOverdue: true,
daysLeft: -30,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Calculate if overdue
isOverdue := tt.deadline.Before(now)
daysLeft := int(tt.deadline.Sub(now).Hours() / 24)
if isOverdue != tt.isOverdue {
t.Errorf("Expected isOverdue=%v, got %v", tt.isOverdue, isOverdue)
}
// Allow 1 day difference due to time precision
if abs(daysLeft-tt.daysLeft) > 1 {
t.Errorf("Expected daysLeft=%d, got %d", tt.daysLeft, daysLeft)
}
})
}
}
// Helper functions
// abs returns the absolute value of an integer
func abs(n int) int {
if n < 0 {
return -n
}
return n
}