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%)
114 lines
3.2 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|