conversation_by_slug_test.go

 1package server
 2
 3import (
 4	"encoding/json"
 5	"net/http"
 6	"net/http/httptest"
 7	"testing"
 8
 9	"shelley.exe.dev/db/generated"
10)
11
12func TestGetConversationBySlug(t *testing.T) {
13	h := NewTestHarness(t)
14	defer h.Close()
15
16	// Create a conversation with a slug
17	slug := "my-test-slug"
18	conv, err := h.db.CreateConversation(t.Context(), &slug, true, nil, nil)
19	if err != nil {
20		t.Fatalf("Failed to create conversation: %v", err)
21	}
22
23	mux := http.NewServeMux()
24	h.server.RegisterRoutes(mux)
25
26	// Test successful lookup
27	req := httptest.NewRequest("GET", "/api/conversation-by-slug/"+slug, nil)
28	rec := httptest.NewRecorder()
29	mux.ServeHTTP(rec, req)
30
31	if rec.Code != http.StatusOK {
32		t.Errorf("Expected status 200, got %d: %s", rec.Code, rec.Body.String())
33	}
34
35	var result generated.Conversation
36	if err := json.NewDecoder(rec.Body).Decode(&result); err != nil {
37		t.Fatalf("Failed to decode response: %v", err)
38	}
39
40	if result.ConversationID != conv.ConversationID {
41		t.Errorf("Expected conversation ID %s, got %s", conv.ConversationID, result.ConversationID)
42	}
43
44	// Test non-existent slug
45	req = httptest.NewRequest("GET", "/api/conversation-by-slug/non-existent-slug", nil)
46	rec = httptest.NewRecorder()
47	mux.ServeHTTP(rec, req)
48
49	if rec.Code != http.StatusNotFound {
50		t.Errorf("Expected status 404, got %d: %s", rec.Code, rec.Body.String())
51	}
52
53	// Test empty slug
54	req = httptest.NewRequest("GET", "/api/conversation-by-slug/", nil)
55	rec = httptest.NewRecorder()
56	mux.ServeHTTP(rec, req)
57
58	if rec.Code != http.StatusBadRequest {
59		t.Errorf("Expected status 400, got %d: %s", rec.Code, rec.Body.String())
60	}
61}
62
63func TestIsConversationSlugPath(t *testing.T) {
64	tests := []struct {
65		path   string
66		expect bool
67	}{
68		// Should NOT be treated as slugs
69		{"/", false},
70		{"/api/conversations", false},
71		{"/api/conversation/abc", false},
72		{"/debug/llm", false},
73		{"/main.js", false},
74		{"/styles.css", false},
75		{"/index.html", false},
76		{"/version", false},
77		{"/my-conversation", false}, // not in /c/ namespace
78		{"/hello-world", false},
79		// Should be treated as slugs (must be under /c/)
80		{"/c/my-conversation", true},
81		{"/c/hello-world", true},
82		{"/c/fix-the-bug", true},
83		{"/c/c123abc", true},
84	}
85
86	for _, tt := range tests {
87		got := isConversationSlugPath(tt.path)
88		if got != tt.expect {
89			t.Errorf("isConversationSlugPath(%q) = %v, want %v", tt.path, got, tt.expect)
90		}
91	}
92}