package feed import ( "encoding/json" "testing" "time" "github.com/steveyegge/gastown/internal/mrqueue" ) func TestParseMQEventLine(t *testing.T) { tests := []struct { name string event mrqueue.Event wantType string wantTarget string wantContains string // Substring in message }{ { name: "merge_started", event: mrqueue.Event{ Timestamp: time.Now(), Type: mrqueue.EventMergeStarted, MRID: "mr-123", Branch: "polecat/nux", Target: "main", Worker: "nux", Rig: "gastown", }, wantType: "merge_started", wantTarget: "mr-123", wantContains: "Merge started", }, { name: "merged", event: mrqueue.Event{ Timestamp: time.Now(), Type: mrqueue.EventMerged, MRID: "mr-456", Branch: "polecat/toast", Target: "main", Worker: "toast", Rig: "gastown", MergeCommit: "abc123def456789", }, wantType: "merged", wantTarget: "mr-456", wantContains: "abc123de", // Short SHA }, { name: "merge_failed", event: mrqueue.Event{ Timestamp: time.Now(), Type: mrqueue.EventMergeFailed, MRID: "mr-789", Branch: "polecat/capable", Target: "main", Worker: "capable", Rig: "gastown", Reason: "conflict in main.go", }, wantType: "merge_failed", wantTarget: "mr-789", wantContains: "conflict in main.go", }, { name: "merge_skipped", event: mrqueue.Event{ Timestamp: time.Now(), Type: mrqueue.EventMergeSkipped, MRID: "mr-999", Branch: "polecat/skip", Target: "main", Reason: "already merged", }, wantType: "merge_skipped", wantTarget: "mr-999", wantContains: "already merged", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Marshal to JSON line data, err := json.Marshal(tt.event) if err != nil { t.Fatalf("Failed to marshal event: %v", err) } // Parse the line result := parseMQEventLine(string(data)) if result == nil { t.Fatal("parseMQEventLine returned nil") } if result.Type != tt.wantType { t.Errorf("Type = %q, want %q", result.Type, tt.wantType) } if result.Target != tt.wantTarget { t.Errorf("Target = %q, want %q", result.Target, tt.wantTarget) } if tt.wantContains != "" && !contains(result.Message, tt.wantContains) { t.Errorf("Message = %q, want to contain %q", result.Message, tt.wantContains) } // Actor should be refinery if result.Actor != "refinery" { t.Errorf("Actor = %q, want %q", result.Actor, "refinery") } if result.Role != "refinery" { t.Errorf("Role = %q, want %q", result.Role, "refinery") } }) } } func TestParseMQEventLineEmpty(t *testing.T) { result := parseMQEventLine("") if result != nil { t.Error("Expected nil for empty line") } result = parseMQEventLine(" ") if result != nil { t.Error("Expected nil for whitespace-only line") } result = parseMQEventLine("not valid json") if result != nil { t.Error("Expected nil for invalid JSON") } } func contains(s, substr string) bool { for i := 0; i <= len(s)-len(substr); i++ { if s[i:i+len(substr)] == substr { return true } } return false }