package routing import ( "os" "testing" ) func getKBPath() string { // Try direct name (when running from this directory) if _, err := os.Stat("activity_knowledge_base.json"); err == nil { return "activity_knowledge_base.json" } // Try relative path if _, err := os.Stat("./internal/routing/activity_knowledge_base.json"); err == nil { return "./internal/routing/activity_knowledge_base.json" } return "" } func TestLoadKnowledgeBase(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } if kb == nil { t.Error("Knowledge base is nil") } if kb.Version == "" { t.Error("Knowledge base version is empty") } if len(kb.Activities) == 0 { t.Error("Knowledge base has no activities") } if len(kb.byName) != len(kb.Activities) { t.Errorf("Index size (%d) doesn't match activities (%d)", len(kb.byName), len(kb.Activities)) } } func TestGetActivity(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } activity := kb.GetActivity("CloneRepoActivity") if activity == nil { t.Error("CloneRepoActivity not found") } else { if activity.Name != "CloneRepoActivity" { t.Errorf("Activity name mismatch: %s", activity.Name) } if activity.Description == "" { t.Error("Activity description is empty") } } missing := kb.GetActivity("NonExistentActivity") if missing != nil { t.Error("NonExistentActivity should be nil") } } func TestHasActivity(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } if !kb.HasActivity("CloneRepoActivity") { t.Error("CloneRepoActivity should exist") } if kb.HasActivity("NonExistentActivity") { t.Error("NonExistentActivity should not exist") } } func TestListActivities(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } activities := kb.ListActivities() if len(activities) == 0 { t.Error("ListActivities returned empty list") } for _, activity := range activities { if activity.Name == "" { t.Error("Activity name is empty") } } } func TestListActivitiesByCategory(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } repoActivities := kb.ListActivitiesByCategory("repository") if len(repoActivities) == 0 { t.Error("No repository activities found") } for _, activity := range repoActivities { if activity.Category != "repository" { t.Errorf("Activity %s has wrong category: %s", activity.Name, activity.Category) } } unknown := kb.ListActivitiesByCategory("unknown") if len(unknown) != 0 { t.Error("Unknown category should return empty list") } } func TestGetActivityNames(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } names := kb.GetActivityNames() if len(names) == 0 { t.Error("GetActivityNames returned empty list") } found := false for _, name := range names { if name == "CloneRepoActivity" { found = true break } } if !found { t.Error("CloneRepoActivity not found in activity names") } } func TestGetDependencies(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } deps := kb.GetDependencies("AnalyzeCodeActivity") if len(deps) == 0 { t.Error("AnalyzeCodeActivity should have dependencies") } found := false for _, dep := range deps { if dep == "CloneRepoActivity" { found = true break } } if !found { t.Error("CloneRepoActivity should be a dependency of AnalyzeCodeActivity") } noDeps := kb.GetDependencies("CloneRepoActivity") if len(noDeps) != 0 { t.Error("CloneRepoActivity should have no dependencies") } } func TestGetTimeout(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } timeout := kb.GetTimeoutForActivity("CloneRepoActivity") if timeout == "" { t.Error("Timeout should not be empty") } defaultTimeout := kb.GetTimeoutForActivity("NonExistent") if defaultTimeout != "5m" { t.Errorf("Default timeout should be 5m, got %s", defaultTimeout) } } func TestGetRetryPolicy(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } policy := kb.GetRetryPolicyForActivity("AnalyzeCodeActivity") if policy == nil { t.Error("Retry policy should not be nil") } else { if policy.MaxAttempts < 2 { t.Errorf("Flaky activity should have multiple retries, got %d", policy.MaxAttempts) } if policy.BackoffRate == 0 { t.Error("Backoff rate should be set") } } stablePolicy := kb.GetRetryPolicyForActivity("CloneRepoActivity") if stablePolicy == nil { t.Error("Retry policy should not be nil") } } func TestIsFlaky(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } if !kb.IsFlaky("AnalyzeCodeActivity") { t.Error("AnalyzeCodeActivity should be marked as flaky") } if kb.IsFlaky("CloneRepoActivity") { t.Error("CloneRepoActivity should not be marked as flaky") } } func TestGetNotes(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } notes := kb.GetNotes("AnalyzeCodeActivity") if notes == "" { t.Error("Notes should not be empty") } missingNotes := kb.GetNotes("NonExistent") if missingNotes != "" { t.Error("Non-existent activity should have empty notes") } } func TestValidate(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } if err := kb.Validate(); err != nil { t.Fatalf("Knowledge base validation failed: %v", err) } } func TestString(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } str := kb.String() if str == "" { t.Error("String() returned empty string") } if !contains(str, "KnowledgeBase") { t.Error("String should contain 'KnowledgeBase'") } } func TestPrintSummary(t *testing.T) { kbPath := getKBPath() if kbPath == "" { t.Skip("Knowledge base file not found, skipping test") } kb, err := LoadKnowledgeBase(kbPath) if err != nil { t.Fatalf("Failed to load knowledge base: %v", err) } summary := kb.PrintSummary() if summary == "" { t.Error("PrintSummary() returned empty string") } if !contains(summary, "Activity Knowledge Base") { t.Error("Summary should contain 'Activity Knowledge Base'") } if !contains(summary, "CloneRepoActivity") { t.Error("Summary should list activities") } } func contains(str, substr string) bool { for i := 0; i < len(str)-len(substr)+1; i++ { if str[i:i+len(substr)] == substr { return true } } return false }