package ucxi import ( "bytes" "context" "encoding/json" "fmt" "net/http" "net/http/httptest" "strings" "testing" "chorus/pkg/ucxl" ) // Mock implementations for testing type MockCollaborativeResolver struct { resolveResults map[string]*ResolvedContent announcements []string discoveries map[string][]*ResolvedContent } func NewMockCollaborativeResolver() *MockCollaborativeResolver { return &MockCollaborativeResolver{ resolveResults: make(map[string]*ResolvedContent), announcements: make([]string, 0), discoveries: make(map[string][]*ResolvedContent), } } func (m *MockCollaborativeResolver) Resolve(ctx context.Context, addr *ucxl.Address) (*ResolvedContent, error) { key := addr.String() if result, exists := m.resolveResults[key]; exists { return result, nil } return nil, fmt.Errorf("not found: %s", key) } func (m *MockCollaborativeResolver) Announce(ctx context.Context, addr *ucxl.Address, content *Content) error { m.announcements = append(m.announcements, addr.String()) return nil } func (m *MockCollaborativeResolver) Discover(ctx context.Context, pattern *ucxl.Address) ([]*ResolvedContent, error) { key := pattern.String() if results, exists := m.discoveries[key]; exists { return results, nil } return []*ResolvedContent{}, nil } type MockCollaborativeStorage struct { contents map[string]*Content } func NewMockCollaborativeStorage() *MockCollaborativeStorage { return &MockCollaborativeStorage{ contents: make(map[string]*Content), } } func (m *MockCollaborativeStorage) Store(ctx context.Context, key string, content *Content) error { m.contents[key] = content return nil } func (m *MockCollaborativeStorage) Retrieve(ctx context.Context, key string) (*Content, error) { if content, exists := m.contents[key]; exists { return content, nil } return nil, fmt.Errorf("not found: %s", key) } func (m *MockCollaborativeStorage) Delete(ctx context.Context, key string) error { delete(m.contents, key) return nil } func (m *MockCollaborativeStorage) List(ctx context.Context, prefix string) ([]string, error) { keys := make([]string, 0) for key := range m.contents { if strings.HasPrefix(key, prefix) { keys = append(keys, key) } } return keys, nil } type MockCollaborativeLogger struct{} func (l MockCollaborativeLogger) Info(msg string, fields ...interface{}) {} func (l MockCollaborativeLogger) Warn(msg string, fields ...interface{}) {} func (l MockCollaborativeLogger) Error(msg string, fields ...interface{}) {} func (l MockCollaborativeLogger) Debug(msg string, fields ...interface{}) {} // Integration tests for role-based collaboration features func TestCollaborationStatusEndpoint(t *testing.T) { // Setup server with mock dependencies resolver := NewMockCollaborativeResolver() storage := NewMockCollaborativeStorage() logger := MockCollaborativeLogger{} config := ServerConfig{ Port: 8080, BasePath: "/api", Resolver: resolver, Storage: storage, Logger: logger, } server := NewServer(config) // Test GET /collaboration endpoint req := httptest.NewRequest(http.MethodGet, "/api/ucxi/v1/collaboration", nil) w := httptest.NewRecorder() server.handleCollaboration(w, req) // Verify response if w.Code != http.StatusOK { t.Errorf("Expected status 200, got %d", w.Code) } var response struct { Response struct { Code string `json:"code"` Data struct { System struct { Enabled bool `json:"enabled"` } `json:"system"` ActiveSessions []map[string]interface{} `json:"active_sessions"` } `json:"data"` } `json:"response"` } if err := json.NewDecoder(w.Body).Decode(&response); err != nil { t.Fatalf("Failed to decode response: %v", err) } if response.Response.Code != "UCXL-200-SUCCESS" { t.Errorf("Expected code UCXL-200-SUCCESS, got %s", response.Response.Code) } if !response.Response.Data.System.Enabled { t.Error("Expected collaboration system to be enabled") } if len(response.Response.Data.ActiveSessions) == 0 { t.Error("Expected at least one active collaboration session") } } func TestCollaborationInitiation(t *testing.T) { // Setup server resolver := NewMockCollaborativeResolver() storage := NewMockCollaborativeStorage() logger := MockCollaborativeLogger{} config := ServerConfig{ Port: 8080, BasePath: "/api", Resolver: resolver, Storage: storage, Logger: logger, } server := NewServer(config) // Test POST /collaboration endpoint requestBody := map[string]interface{}{ "type": "expertise_request", "from_role": "junior_developer", "to_roles": []string{"senior_developer", "tech_lead"}, "required_expertise": []string{"api_design", "error_handling"}, "project_id": "CHORUS", "priority": "medium", "data": map[string]interface{}{ "context": "Working on UCXI API standardization", "specific_question": "How to handle nested error chains in UCXL responses?", }, } reqBody, _ := json.Marshal(requestBody) req := httptest.NewRequest(http.MethodPost, "/api/ucxi/v1/collaboration", bytes.NewReader(reqBody)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() server.handleCollaboration(w, req) // Verify response if w.Code != http.StatusCreated { t.Errorf("Expected status 201, got %d", w.Code) } var response struct { Response struct { Code string `json:"code"` Data struct { CollaborationInitiated bool `json:"collaboration_initiated"` ThreadID string `json:"thread_id"` Type string `json:"type"` FromRole string `json:"from_role"` Status string `json:"status"` ExpectedResponseTime string `json:"expected_response_time"` Routing string `json:"routing"` } `json:"data"` } `json:"response"` } if err := json.NewDecoder(w.Body).Decode(&response); err != nil { t.Fatalf("Failed to decode response: %v", err) } if response.Response.Code != "UCXL-201-CREATED" { t.Errorf("Expected code UCXL-201-CREATED, got %s", response.Response.Code) } if !response.Response.Data.CollaborationInitiated { t.Error("Expected collaboration to be initiated") } if response.Response.Data.Type != "expertise_request" { t.Errorf("Expected type expertise_request, got %s", response.Response.Data.Type) } if response.Response.Data.FromRole != "junior_developer" { t.Errorf("Expected from_role junior_developer, got %s", response.Response.Data.FromRole) } if response.Response.Data.Status != "initiated" { t.Errorf("Expected status initiated, got %s", response.Response.Data.Status) } if !strings.HasPrefix(response.Response.Data.ThreadID, "thread-expertise_request-") { t.Errorf("Expected thread ID to start with 'thread-expertise_request-', got %s", response.Response.Data.ThreadID) } if response.Response.Data.ExpectedResponseTime != "15m" { t.Errorf("Expected expected_response_time 15m, got %s", response.Response.Data.ExpectedResponseTime) } if response.Response.Data.Routing != "expertise_based" { t.Errorf("Expected routing expertise_based, got %s", response.Response.Data.Routing) } } func TestCollaborationValidationErrors(t *testing.T) { // Setup server resolver := NewMockCollaborativeResolver() storage := NewMockCollaborativeStorage() logger := MockCollaborativeLogger{} config := ServerConfig{ Port: 8080, BasePath: "/api", Resolver: resolver, Storage: storage, Logger: logger, } server := NewServer(config) tests := []struct { name string requestBody map[string]interface{} expectedStatus int expectedCode string }{ { name: "Missing type", requestBody: map[string]interface{}{"from_role": "junior_developer"}, expectedStatus: http.StatusBadRequest, expectedCode: "UCXL-400-INVALID_PAYLOAD", }, { name: "Missing from_role", requestBody: map[string]interface{}{"type": "expertise_request"}, expectedStatus: http.StatusBadRequest, expectedCode: "UCXL-400-INVALID_PAYLOAD", }, { name: "Invalid JSON", requestBody: nil, // Will send invalid JSON expectedStatus: http.StatusBadRequest, expectedCode: "UCXL-400-BAD_REQUEST", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var reqBody []byte var err error if tt.requestBody != nil { reqBody, err = json.Marshal(tt.requestBody) if err != nil { t.Fatalf("Failed to marshal request body: %v", err) } } else { reqBody = []byte("invalid json") } req := httptest.NewRequest(http.MethodPost, "/api/ucxi/v1/collaboration", bytes.NewReader(reqBody)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() server.handleCollaboration(w, req) if w.Code != tt.expectedStatus { t.Errorf("Expected status %d, got %d", tt.expectedStatus, w.Code) } var response struct { Error struct { Code string `json:"code"` } `json:"error"` } if err := json.NewDecoder(w.Body).Decode(&response); err != nil { t.Fatalf("Failed to decode error response: %v", err) } if response.Error.Code != tt.expectedCode { t.Errorf("Expected code %s, got %s", tt.expectedCode, response.Error.Code) } }) } } func TestEnhancedStatusEndpoint(t *testing.T) { // Setup server resolver := NewMockCollaborativeResolver() storage := NewMockCollaborativeStorage() logger := MockCollaborativeLogger{} config := ServerConfig{ Port: 8080, BasePath: "/api", Resolver: resolver, Storage: storage, Logger: logger, } server := NewServer(config) req := httptest.NewRequest(http.MethodGet, "/api/ucxi/v1/status", nil) w := httptest.NewRecorder() server.handleStatus(w, req) if w.Code != http.StatusOK { t.Errorf("Expected status 200, got %d", w.Code) } var response struct { Response struct { Code string `json:"code"` Data struct { Server map[string]interface{} `json:"server"` Collaboration map[string]interface{} `json:"collaboration"` HmmmIntegration map[string]interface{} `json:"hmmm_integration"` } `json:"data"` } `json:"response"` } if err := json.NewDecoder(w.Body).Decode(&response); err != nil { t.Fatalf("Failed to decode response: %v", err) } if response.Response.Code != "UCXL-200-SUCCESS" { t.Errorf("Expected code UCXL-200-SUCCESS, got %s", response.Response.Code) } // Verify server version is updated if version, ok := response.Response.Data.Server["version"].(string); ok { if version != "2.1.0" { t.Errorf("Expected server version 2.1.0, got %s", version) } } else { t.Error("Expected server version to be present") } // Verify collaboration status if enabled, ok := response.Response.Data.Collaboration["enabled"].(bool); ok { if !enabled { t.Error("Expected collaboration to be enabled") } } else { t.Error("Expected collaboration enabled status to be present") } // Verify HMMM integration status if enabled, ok := response.Response.Data.HmmmIntegration["enabled"].(bool); ok { if !enabled { t.Error("Expected HMMM integration to be enabled") } } else { t.Error("Expected HMMM integration enabled status to be present") } } func TestCollaborationFiltering(t *testing.T) { // Setup server resolver := NewMockCollaborativeResolver() storage := NewMockCollaborativeStorage() logger := MockCollaborativeLogger{} config := ServerConfig{ Port: 8080, BasePath: "/api", Resolver: resolver, Storage: storage, Logger: logger, } server := NewServer(config) // Test with role filter req := httptest.NewRequest(http.MethodGet, "/api/ucxi/v1/collaboration?role=senior_developer", nil) w := httptest.NewRecorder() server.handleCollaboration(w, req) if w.Code != http.StatusOK { t.Errorf("Expected status 200, got %d", w.Code) } var response struct { Response struct { Code string `json:"code"` Data struct { FiltersApplied struct { Role string `json:"role"` } `json:"filters_applied"` FilteredResults map[string]interface{} `json:"filtered_results"` } `json:"data"` } `json:"response"` } if err := json.NewDecoder(w.Body).Decode(&response); err != nil { t.Fatalf("Failed to decode response: %v", err) } if response.Response.Data.FiltersApplied.Role != "senior_developer" { t.Errorf("Expected role filter senior_developer, got %s", response.Response.Data.FiltersApplied.Role) } if response.Response.Data.FilteredResults == nil { t.Error("Expected filtered results to be present when filters are applied") } } func TestMethodNotAllowedHandling(t *testing.T) { // Setup server resolver := NewMockCollaborativeResolver() storage := NewMockCollaborativeStorage() logger := MockCollaborativeLogger{} config := ServerConfig{ Port: 8080, BasePath: "/api", Resolver: resolver, Storage: storage, Logger: logger, } server := NewServer(config) // Test unsupported method req := httptest.NewRequest(http.MethodPut, "/api/ucxi/v1/collaboration", nil) w := httptest.NewRecorder() server.handleCollaboration(w, req) if w.Code != http.StatusMethodNotAllowed { t.Errorf("Expected status 405, got %d", w.Code) } var response struct { Error struct { Code string `json:"code"` Details struct { AllowedMethods []string `json:"allowed_methods"` } `json:"details"` } `json:"error"` } if err := json.NewDecoder(w.Body).Decode(&response); err != nil { t.Fatalf("Failed to decode response: %v", err) } if response.Error.Code != "UCXL-405-METHOD_NOT_ALLOWED" { t.Errorf("Expected code UCXL-405-METHOD_NOT_ALLOWED, got %s", response.Error.Code) } expectedMethods := []string{"GET", "POST"} if len(response.Error.Details.AllowedMethods) != len(expectedMethods) { t.Errorf("Expected %d allowed methods, got %d", len(expectedMethods), len(response.Error.Details.AllowedMethods)) } } func TestRequestIDHandling(t *testing.T) { // Setup server resolver := NewMockCollaborativeResolver() storage := NewMockCollaborativeStorage() logger := MockCollaborativeLogger{} config := ServerConfig{ Port: 8080, BasePath: "/api", Resolver: resolver, Storage: storage, Logger: logger, } server := NewServer(config) // Test with custom request ID customRequestID := "test-request-123" req := httptest.NewRequest(http.MethodGet, "/api/ucxi/v1/collaboration", nil) req.Header.Set("X-Request-ID", customRequestID) w := httptest.NewRecorder() server.handleCollaboration(w, req) var response struct { Response struct { RequestID string `json:"request_id"` } `json:"response"` } if err := json.NewDecoder(w.Body).Decode(&response); err != nil { t.Fatalf("Failed to decode response: %v", err) } if response.Response.RequestID != customRequestID { t.Errorf("Expected request ID %s, got %s", customRequestID, response.Response.RequestID) } } // Benchmark tests func BenchmarkCollaborationStatusEndpoint(b *testing.B) { resolver := NewMockCollaborativeResolver() storage := NewMockCollaborativeStorage() logger := MockCollaborativeLogger{} config := ServerConfig{ Port: 8080, BasePath: "/api", Resolver: resolver, Storage: storage, Logger: logger, } server := NewServer(config) b.ResetTimer() for i := 0; i < b.N; i++ { req := httptest.NewRequest(http.MethodGet, "/api/ucxi/v1/collaboration", nil) w := httptest.NewRecorder() server.handleCollaboration(w, req) } } func BenchmarkCollaborationInitiation(b *testing.B) { resolver := NewMockCollaborativeResolver() storage := NewMockCollaborativeStorage() logger := MockCollaborativeLogger{} config := ServerConfig{ Port: 8080, BasePath: "/api", Resolver: resolver, Storage: storage, Logger: logger, } server := NewServer(config) requestBody := map[string]interface{}{ "type": "expertise_request", "from_role": "junior_developer", "to_roles": []string{"senior_developer"}, "data": map[string]interface{}{"context": "test"}, } reqBodyBytes, _ := json.Marshal(requestBody) b.ResetTimer() for i := 0; i < b.N; i++ { req := httptest.NewRequest(http.MethodPost, "/api/ucxi/v1/collaboration", bytes.NewReader(reqBodyBytes)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() server.handleCollaboration(w, req) } }