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}