A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
688 lines
17 KiB
Go
688 lines
17 KiB
Go
package jitsi
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// ========================================
|
|
// Test Helpers
|
|
// ========================================
|
|
|
|
func createTestService() *JitsiService {
|
|
return NewJitsiService(Config{
|
|
BaseURL: "http://localhost:8443",
|
|
AppID: "breakpilot",
|
|
AppSecret: "test-secret-key",
|
|
})
|
|
}
|
|
|
|
func createTestServiceWithoutAuth() *JitsiService {
|
|
return NewJitsiService(Config{
|
|
BaseURL: "http://localhost:8443",
|
|
})
|
|
}
|
|
|
|
// ========================================
|
|
// Unit Tests: Service Creation
|
|
// ========================================
|
|
|
|
func TestNewJitsiService_ValidConfig_CreatesService(t *testing.T) {
|
|
cfg := Config{
|
|
BaseURL: "http://localhost:8443",
|
|
AppID: "test-app",
|
|
AppSecret: "test-secret",
|
|
}
|
|
|
|
service := NewJitsiService(cfg)
|
|
|
|
if service == nil {
|
|
t.Fatal("Expected service to be created, got nil")
|
|
}
|
|
if service.baseURL != cfg.BaseURL {
|
|
t.Errorf("Expected baseURL %s, got %s", cfg.BaseURL, service.baseURL)
|
|
}
|
|
if service.appID != cfg.AppID {
|
|
t.Errorf("Expected appID %s, got %s", cfg.AppID, service.appID)
|
|
}
|
|
if service.appSecret != cfg.AppSecret {
|
|
t.Errorf("Expected appSecret %s, got %s", cfg.AppSecret, service.appSecret)
|
|
}
|
|
if service.httpClient == nil {
|
|
t.Error("Expected httpClient to be initialized")
|
|
}
|
|
}
|
|
|
|
func TestNewJitsiService_TrailingSlash_Removed(t *testing.T) {
|
|
service := NewJitsiService(Config{
|
|
BaseURL: "http://localhost:8443/",
|
|
})
|
|
|
|
if service.baseURL != "http://localhost:8443" {
|
|
t.Errorf("Expected trailing slash to be removed, got %s", service.baseURL)
|
|
}
|
|
}
|
|
|
|
func TestGetBaseURL_ReturnsConfiguredURL(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
result := service.GetBaseURL()
|
|
|
|
if result != "http://localhost:8443" {
|
|
t.Errorf("Expected 'http://localhost:8443', got '%s'", result)
|
|
}
|
|
}
|
|
|
|
func TestIsAuthEnabled_WithSecret_ReturnsTrue(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
if !service.IsAuthEnabled() {
|
|
t.Error("Expected auth to be enabled when secret is configured")
|
|
}
|
|
}
|
|
|
|
func TestIsAuthEnabled_WithoutSecret_ReturnsFalse(t *testing.T) {
|
|
service := createTestServiceWithoutAuth()
|
|
|
|
if service.IsAuthEnabled() {
|
|
t.Error("Expected auth to be disabled when secret is not configured")
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// Unit Tests: Room Name Generation
|
|
// ========================================
|
|
|
|
func TestSanitizeRoomName_ValidInput_ReturnsCleanName(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "simple name",
|
|
input: "meeting",
|
|
expected: "meeting",
|
|
},
|
|
{
|
|
name: "with spaces",
|
|
input: "My Meeting Room",
|
|
expected: "my-meeting-room",
|
|
},
|
|
{
|
|
name: "german umlauts",
|
|
input: "Schüler Müller",
|
|
expected: "schueler-mueller",
|
|
},
|
|
{
|
|
name: "special characters",
|
|
input: "Test@#$%Meeting!",
|
|
expected: "testmeeting",
|
|
},
|
|
{
|
|
name: "consecutive hyphens",
|
|
input: "test---meeting",
|
|
expected: "test-meeting",
|
|
},
|
|
{
|
|
name: "leading trailing hyphens",
|
|
input: "-test-meeting-",
|
|
expected: "test-meeting",
|
|
},
|
|
{
|
|
name: "eszett",
|
|
input: "Straße",
|
|
expected: "strasse",
|
|
},
|
|
{
|
|
name: "numbers",
|
|
input: "Klasse 5a",
|
|
expected: "klasse-5a",
|
|
},
|
|
}
|
|
|
|
service := createTestService()
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := service.sanitizeRoomName(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("Expected '%s', got '%s'", tt.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSanitizeRoomName_LongName_Truncated(t *testing.T) {
|
|
service := createTestService()
|
|
longName := strings.Repeat("a", 100)
|
|
|
|
result := service.sanitizeRoomName(longName)
|
|
|
|
if len(result) > 50 {
|
|
t.Errorf("Expected max 50 chars, got %d", len(result))
|
|
}
|
|
}
|
|
|
|
func TestGenerateRoomName_ReturnsUniqueNames(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
name1 := service.generateRoomName()
|
|
name2 := service.generateRoomName()
|
|
|
|
if name1 == name2 {
|
|
t.Error("Expected unique room names")
|
|
}
|
|
if !strings.HasPrefix(name1, "breakpilot-") {
|
|
t.Errorf("Expected prefix 'breakpilot-', got '%s'", name1)
|
|
}
|
|
}
|
|
|
|
func TestGenerateTrainingRoomName_IncludesTitle(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
result := service.generateTrainingRoomName("Go Workshop")
|
|
|
|
if !strings.HasPrefix(result, "go-workshop-") {
|
|
t.Errorf("Expected to start with 'go-workshop-', got '%s'", result)
|
|
}
|
|
}
|
|
|
|
func TestGeneratePassword_ReturnsValidPassword(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
password := service.generatePassword()
|
|
|
|
if len(password) != 8 {
|
|
t.Errorf("Expected 8 char password, got %d", len(password))
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// Unit Tests: Meeting Link Creation
|
|
// ========================================
|
|
|
|
func TestCreateMeetingLink_BasicMeeting_ReturnsValidLink(t *testing.T) {
|
|
service := createTestServiceWithoutAuth()
|
|
|
|
meeting := Meeting{
|
|
RoomName: "test-room",
|
|
DisplayName: "Test User",
|
|
}
|
|
|
|
link, err := service.CreateMeetingLink(context.Background(), meeting)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if link.RoomName != "test-room" {
|
|
t.Errorf("Expected room name 'test-room', got '%s'", link.RoomName)
|
|
}
|
|
if link.URL != "http://localhost:8443/test-room" {
|
|
t.Errorf("Expected URL 'http://localhost:8443/test-room', got '%s'", link.URL)
|
|
}
|
|
if link.JoinURL != "http://localhost:8443/test-room" {
|
|
t.Errorf("Expected JoinURL 'http://localhost:8443/test-room', got '%s'", link.JoinURL)
|
|
}
|
|
}
|
|
|
|
func TestCreateMeetingLink_NoRoomName_GeneratesName(t *testing.T) {
|
|
service := createTestServiceWithoutAuth()
|
|
|
|
meeting := Meeting{
|
|
DisplayName: "Test User",
|
|
}
|
|
|
|
link, err := service.CreateMeetingLink(context.Background(), meeting)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if link.RoomName == "" {
|
|
t.Error("Expected room name to be generated")
|
|
}
|
|
if !strings.HasPrefix(link.RoomName, "breakpilot-") {
|
|
t.Errorf("Expected generated room name to start with 'breakpilot-', got '%s'", link.RoomName)
|
|
}
|
|
}
|
|
|
|
func TestCreateMeetingLink_WithPassword_IncludesPassword(t *testing.T) {
|
|
service := createTestServiceWithoutAuth()
|
|
|
|
meeting := Meeting{
|
|
RoomName: "test-room",
|
|
Password: "secret123",
|
|
}
|
|
|
|
link, err := service.CreateMeetingLink(context.Background(), meeting)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if link.Password != "secret123" {
|
|
t.Errorf("Expected password 'secret123', got '%s'", link.Password)
|
|
}
|
|
}
|
|
|
|
func TestCreateMeetingLink_WithAuth_IncludesJWT(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
meeting := Meeting{
|
|
RoomName: "test-room",
|
|
DisplayName: "Test User",
|
|
Email: "test@example.com",
|
|
}
|
|
|
|
link, err := service.CreateMeetingLink(context.Background(), meeting)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if link.JWT == "" {
|
|
t.Error("Expected JWT to be generated")
|
|
}
|
|
if !strings.Contains(link.JoinURL, "jwt=") {
|
|
t.Error("Expected JoinURL to contain JWT parameter")
|
|
}
|
|
if link.ExpiresAt == nil {
|
|
t.Error("Expected ExpiresAt to be set")
|
|
}
|
|
}
|
|
|
|
func TestCreateMeetingLink_WithConfig_IncludesParams(t *testing.T) {
|
|
service := createTestServiceWithoutAuth()
|
|
|
|
meeting := Meeting{
|
|
RoomName: "test-room",
|
|
Config: &MeetingConfig{
|
|
StartWithAudioMuted: true,
|
|
StartWithVideoMuted: true,
|
|
RequireDisplayName: true,
|
|
},
|
|
}
|
|
|
|
link, err := service.CreateMeetingLink(context.Background(), meeting)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if !strings.Contains(link.JoinURL, "startWithAudioMuted=true") {
|
|
t.Error("Expected JoinURL to contain audio muted config")
|
|
}
|
|
if !strings.Contains(link.JoinURL, "startWithVideoMuted=true") {
|
|
t.Error("Expected JoinURL to contain video muted config")
|
|
}
|
|
}
|
|
|
|
func TestCreateMeetingLink_Moderator_SetsModeratorURL(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
meeting := Meeting{
|
|
RoomName: "test-room",
|
|
DisplayName: "Admin",
|
|
Moderator: true,
|
|
}
|
|
|
|
link, err := service.CreateMeetingLink(context.Background(), meeting)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if link.ModeratorURL == "" {
|
|
t.Error("Expected ModeratorURL to be set for moderator")
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// Unit Tests: Specialized Meeting Types
|
|
// ========================================
|
|
|
|
func TestCreateTrainingSession_ReturnsOptimizedConfig(t *testing.T) {
|
|
service := createTestServiceWithoutAuth()
|
|
|
|
link, err := service.CreateTrainingSession(
|
|
context.Background(),
|
|
"Go Grundlagen",
|
|
"Max Trainer",
|
|
"trainer@example.com",
|
|
60,
|
|
)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if !strings.Contains(link.RoomName, "go-grundlagen") {
|
|
t.Errorf("Expected room name to contain 'go-grundlagen', got '%s'", link.RoomName)
|
|
}
|
|
// Config should have lobby enabled for training
|
|
if !strings.Contains(link.JoinURL, "enableLobby=true") {
|
|
t.Error("Expected training to have lobby enabled")
|
|
}
|
|
}
|
|
|
|
func TestCreateQuickMeeting_ReturnsSimpleMeeting(t *testing.T) {
|
|
service := createTestServiceWithoutAuth()
|
|
|
|
link, err := service.CreateQuickMeeting(context.Background(), "Quick User")
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if link.RoomName == "" {
|
|
t.Error("Expected room name to be generated")
|
|
}
|
|
}
|
|
|
|
func TestCreateParentTeacherMeeting_ReturnsSecureMeeting(t *testing.T) {
|
|
service := createTestServiceWithoutAuth()
|
|
scheduledTime := time.Now().Add(24 * time.Hour)
|
|
|
|
link, err := service.CreateParentTeacherMeeting(
|
|
context.Background(),
|
|
"Frau Müller",
|
|
"Herr Schmidt",
|
|
"Max Mustermann",
|
|
scheduledTime,
|
|
)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if !strings.Contains(link.RoomName, "elterngespraech") {
|
|
t.Errorf("Expected room name to contain 'elterngespraech', got '%s'", link.RoomName)
|
|
}
|
|
if link.Password == "" {
|
|
t.Error("Expected password for parent-teacher meeting")
|
|
}
|
|
if !strings.Contains(link.JoinURL, "enableLobby=true") {
|
|
t.Error("Expected lobby to be enabled")
|
|
}
|
|
}
|
|
|
|
func TestCreateClassMeeting_ReturnsMeetingForClass(t *testing.T) {
|
|
service := createTestServiceWithoutAuth()
|
|
|
|
link, err := service.CreateClassMeeting(
|
|
context.Background(),
|
|
"5a",
|
|
"Herr Lehrer",
|
|
"Mathematik",
|
|
)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if !strings.Contains(link.RoomName, "klasse-5a") {
|
|
t.Errorf("Expected room name to contain 'klasse-5a', got '%s'", link.RoomName)
|
|
}
|
|
// Students should be muted by default
|
|
if !strings.Contains(link.JoinURL, "startWithAudioMuted=true") {
|
|
t.Error("Expected students to start muted")
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// Unit Tests: JWT Generation
|
|
// ========================================
|
|
|
|
func TestGenerateJWT_ValidClaims_ReturnsValidToken(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
meeting := Meeting{
|
|
RoomName: "test-room",
|
|
DisplayName: "Test User",
|
|
Email: "test@example.com",
|
|
Moderator: true,
|
|
Duration: 60,
|
|
}
|
|
|
|
token, expiresAt, err := service.generateJWT(meeting, "test-room")
|
|
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if token == "" {
|
|
t.Error("Expected token to be generated")
|
|
}
|
|
if expiresAt == nil {
|
|
t.Error("Expected expiration time to be set")
|
|
}
|
|
|
|
// Verify token structure (header.payload.signature)
|
|
parts := strings.Split(token, ".")
|
|
if len(parts) != 3 {
|
|
t.Errorf("Expected 3 JWT parts, got %d", len(parts))
|
|
}
|
|
|
|
// Decode and verify payload
|
|
payloadJSON, err := base64.RawURLEncoding.DecodeString(parts[1])
|
|
if err != nil {
|
|
t.Fatalf("Failed to decode payload: %v", err)
|
|
}
|
|
|
|
var claims JWTClaims
|
|
if err := json.Unmarshal(payloadJSON, &claims); err != nil {
|
|
t.Fatalf("Failed to unmarshal claims: %v", err)
|
|
}
|
|
|
|
if claims.Room != "test-room" {
|
|
t.Errorf("Expected room 'test-room', got '%s'", claims.Room)
|
|
}
|
|
if !claims.Moderator {
|
|
t.Error("Expected moderator to be true")
|
|
}
|
|
if claims.Context == nil || claims.Context.User == nil {
|
|
t.Error("Expected user context to be set")
|
|
}
|
|
if claims.Context.User.Name != "Test User" {
|
|
t.Errorf("Expected user name 'Test User', got '%s'", claims.Context.User.Name)
|
|
}
|
|
}
|
|
|
|
func TestGenerateJWT_WithFeatures_IncludesFeatures(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
meeting := Meeting{
|
|
RoomName: "test-room",
|
|
Features: &MeetingFeatures{
|
|
Recording: true,
|
|
Transcription: true,
|
|
},
|
|
}
|
|
|
|
token, _, err := service.generateJWT(meeting, "test-room")
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
|
|
parts := strings.Split(token, ".")
|
|
payloadJSON, _ := base64.RawURLEncoding.DecodeString(parts[1])
|
|
|
|
var claims JWTClaims
|
|
json.Unmarshal(payloadJSON, &claims)
|
|
|
|
if claims.Features == nil {
|
|
t.Error("Expected features to be set")
|
|
}
|
|
if claims.Features.Recording != "true" {
|
|
t.Errorf("Expected recording 'true', got '%s'", claims.Features.Recording)
|
|
}
|
|
}
|
|
|
|
func TestGenerateJWT_NoSecret_ReturnsError(t *testing.T) {
|
|
service := createTestServiceWithoutAuth()
|
|
|
|
meeting := Meeting{RoomName: "test"}
|
|
|
|
_, _, err := service.generateJWT(meeting, "test")
|
|
|
|
if err == nil {
|
|
t.Error("Expected error when secret is not configured")
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// Unit Tests: Health Check
|
|
// ========================================
|
|
|
|
func TestHealthCheck_ServerAvailable_ReturnsNil(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
}))
|
|
defer server.Close()
|
|
|
|
service := NewJitsiService(Config{BaseURL: server.URL})
|
|
|
|
err := service.HealthCheck(context.Background())
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestHealthCheck_ServerError_ReturnsError(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}))
|
|
defer server.Close()
|
|
|
|
service := NewJitsiService(Config{BaseURL: server.URL})
|
|
|
|
err := service.HealthCheck(context.Background())
|
|
|
|
if err == nil {
|
|
t.Error("Expected error for server error response")
|
|
}
|
|
}
|
|
|
|
func TestHealthCheck_ServerUnreachable_ReturnsError(t *testing.T) {
|
|
service := NewJitsiService(Config{BaseURL: "http://localhost:59999"})
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
|
defer cancel()
|
|
|
|
err := service.HealthCheck(ctx)
|
|
|
|
if err == nil {
|
|
t.Error("Expected error for unreachable server")
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// Unit Tests: URL Building
|
|
// ========================================
|
|
|
|
func TestBuildEmbedURL_BasicRoom_ReturnsURL(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
url := service.BuildEmbedURL("test-room", "", nil)
|
|
|
|
if url != "http://localhost:8443/test-room" {
|
|
t.Errorf("Expected 'http://localhost:8443/test-room', got '%s'", url)
|
|
}
|
|
}
|
|
|
|
func TestBuildEmbedURL_WithDisplayName_IncludesParam(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
url := service.BuildEmbedURL("test-room", "Max Mustermann", nil)
|
|
|
|
if !strings.Contains(url, "displayName=Max") {
|
|
t.Errorf("Expected URL to contain display name, got '%s'", url)
|
|
}
|
|
}
|
|
|
|
func TestBuildEmbedURL_WithConfig_IncludesParams(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
config := &MeetingConfig{
|
|
StartWithAudioMuted: true,
|
|
StartWithVideoMuted: true,
|
|
}
|
|
|
|
url := service.BuildEmbedURL("test-room", "", config)
|
|
|
|
if !strings.Contains(url, "startWithAudioMuted=true") {
|
|
t.Error("Expected URL to contain audio muted config")
|
|
}
|
|
if !strings.Contains(url, "startWithVideoMuted=true") {
|
|
t.Error("Expected URL to contain video muted config")
|
|
}
|
|
}
|
|
|
|
func TestBuildIFrameCode_DefaultSize_Returns800x600(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
code := service.BuildIFrameCode("test-room", 0, 0)
|
|
|
|
if !strings.Contains(code, "width=\"800\"") {
|
|
t.Error("Expected default width 800")
|
|
}
|
|
if !strings.Contains(code, "height=\"600\"") {
|
|
t.Error("Expected default height 600")
|
|
}
|
|
if !strings.Contains(code, "test-room") {
|
|
t.Error("Expected room name in iframe")
|
|
}
|
|
if !strings.Contains(code, "allow=\"camera; microphone") {
|
|
t.Error("Expected camera/microphone permissions")
|
|
}
|
|
}
|
|
|
|
func TestBuildIFrameCode_CustomSize_ReturnsCorrectDimensions(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
code := service.BuildIFrameCode("test-room", 1920, 1080)
|
|
|
|
if !strings.Contains(code, "width=\"1920\"") {
|
|
t.Error("Expected width 1920")
|
|
}
|
|
if !strings.Contains(code, "height=\"1080\"") {
|
|
t.Error("Expected height 1080")
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// Unit Tests: Server Info
|
|
// ========================================
|
|
|
|
func TestGetServerInfo_ReturnsInfo(t *testing.T) {
|
|
service := createTestService()
|
|
|
|
info := service.GetServerInfo()
|
|
|
|
if info["base_url"] != "http://localhost:8443" {
|
|
t.Errorf("Expected base_url, got '%s'", info["base_url"])
|
|
}
|
|
if info["app_id"] != "breakpilot" {
|
|
t.Errorf("Expected app_id 'breakpilot', got '%s'", info["app_id"])
|
|
}
|
|
if info["auth_enabled"] != "true" {
|
|
t.Errorf("Expected auth_enabled 'true', got '%s'", info["auth_enabled"])
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
// Unit Tests: Helper Functions
|
|
// ========================================
|
|
|
|
func TestBoolToString_True_ReturnsTrue(t *testing.T) {
|
|
result := boolToString(true)
|
|
if result != "true" {
|
|
t.Errorf("Expected 'true', got '%s'", result)
|
|
}
|
|
}
|
|
|
|
func TestBoolToString_False_ReturnsFalse(t *testing.T) {
|
|
result := boolToString(false)
|
|
if result != "false" {
|
|
t.Errorf("Expected 'false', got '%s'", result)
|
|
}
|
|
}
|