Pulse/internal/api/license_handlers_test.go
rcourtman d3eb6a7148 test: improve test coverage for AI, license, config, and monitoring packages
New test files:
- internal/ai/providers/gemini_test.go: Comprehensive Gemini provider tests
- internal/api/ai_intelligence_handlers_test.go: AI intelligence endpoint tests
- internal/api/ai_patrol_handlers_test.go: AI patrol endpoint tests
- internal/api/license_handlers_test.go: License API handler tests
- internal/api/security_oidc_response_test.go: OIDC response formatting tests
- internal/config/ai_config_test.go: AI configuration function tests
- internal/config/persistence_ai_test.go: AI config persistence tests
- internal/config/persistence_extended_test.go: Extended persistence tests
- internal/license/persistence_test.go: License persistence tests
- internal/license/pubkey_test.go: Public key handling tests
- internal/monitoring/host_agent_temps_test.go: Temperature processing tests

Enhanced existing files:
- internal/api/updates_test.go: Added update handler tests
- internal/license/license_test.go: Added Service method tests

Coverage improvements:
- ai/providers: 57.3% -> 73.0% (+15.7%)
- license: 78.3% -> 85.9% (+7.6%)
- config: 49.7% -> 53.9% (+4.2%)
- monitoring: 49.8% -> 50.8% (+1.0%)
- api: 28.4% -> 29.8% (+1.4%)
2025-12-19 22:49:30 +00:00

114 lines
3.2 KiB
Go

package api
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/rcourtman/pulse-go-rewrite/internal/license"
)
type licenseFeaturesResponse struct {
LicenseStatus string `json:"license_status"`
Features map[string]bool `json:"features"`
UpgradeURL string `json:"upgrade_url"`
}
func TestHandleLicenseFeatures_MethodNotAllowed(t *testing.T) {
handler := NewLicenseHandlers(t.TempDir())
req := httptest.NewRequest(http.MethodPost, "/api/license/features", nil)
rec := httptest.NewRecorder()
handler.HandleLicenseFeatures(rec, req)
if rec.Code != http.StatusMethodNotAllowed {
t.Fatalf("expected status %d, got %d", http.StatusMethodNotAllowed, rec.Code)
}
}
func TestHandleLicenseFeatures_NoLicense(t *testing.T) {
handler := NewLicenseHandlers(t.TempDir())
req := httptest.NewRequest(http.MethodGet, "/api/license/features", nil)
rec := httptest.NewRecorder()
handler.HandleLicenseFeatures(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected status %d, got %d", http.StatusOK, rec.Code)
}
var resp licenseFeaturesResponse
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
t.Fatalf("failed to unmarshal response: %v", err)
}
if resp.LicenseStatus != string(license.LicenseStateNone) {
t.Fatalf("expected license_status %q, got %q", license.LicenseStateNone, resp.LicenseStatus)
}
if resp.UpgradeURL == "" {
t.Fatalf("expected upgrade_url to be set")
}
expectedFeatures := []string{
license.FeatureAIPatrol,
license.FeatureAIAlerts,
license.FeatureAIAutoFix,
license.FeatureKubernetesAI,
}
for _, feature := range expectedFeatures {
if value, ok := resp.Features[feature]; !ok {
t.Fatalf("expected feature %q in response", feature)
} else if value {
t.Fatalf("expected feature %q to be false without a license", feature)
}
}
}
func TestHandleLicenseFeatures_WithActiveLicense(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "true")
handler := NewLicenseHandlers(t.TempDir())
licenseKey, err := license.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}
if _, err := handler.Service().Activate(licenseKey); err != nil {
t.Fatalf("failed to activate test license: %v", err)
}
req := httptest.NewRequest(http.MethodGet, "/api/license/features", nil)
rec := httptest.NewRecorder()
handler.HandleLicenseFeatures(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected status %d, got %d", http.StatusOK, rec.Code)
}
var resp licenseFeaturesResponse
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
t.Fatalf("failed to unmarshal response: %v", err)
}
if resp.LicenseStatus != string(license.LicenseStateActive) {
t.Fatalf("expected license_status %q, got %q", license.LicenseStateActive, resp.LicenseStatus)
}
expectedFeatures := []string{
license.FeatureAIPatrol,
license.FeatureAIAlerts,
license.FeatureAIAutoFix,
license.FeatureKubernetesAI,
}
for _, feature := range expectedFeatures {
if value, ok := resp.Features[feature]; !ok {
t.Fatalf("expected feature %q in response", feature)
} else if !value {
t.Fatalf("expected feature %q to be true with active license", feature)
}
}
}