handler_test.go
1package routing
2
3import (
4 "fmt"
5 "net/http"
6 "net/http/httptest"
7 "os"
8 "path/filepath"
9 "testing"
10)
11
12func TestRouteFileHandler_Success(t *testing.T) {
13 // Create temp directory structure
14 tempDir := t.TempDir()
15 routeDir := filepath.Join(tempDir, "ab")
16 if err := os.MkdirAll(routeDir, 0755); err != nil {
17 t.Fatalf("failed to create directory: %v", err)
18 }
19
20 // Create test file (64 character hex hash)
21 hash := "abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab"
22 content := "test_polyline_content"
23 filePath := filepath.Join(routeDir, "cd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab.polyline6")
24 if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
25 t.Fatalf("failed to write test file: %v", err)
26 }
27
28 // Create handler
29 handler := RouteFileHandler(tempDir)
30
31 // Test polyline6 request
32 req := httptest.NewRequest(http.MethodGet, "/route/"+hash+".polyline6", nil)
33 rr := httptest.NewRecorder()
34
35 handler.ServeHTTP(rr, req)
36
37 if rr.Code != http.StatusOK {
38 t.Errorf("expected status %d, got %d", http.StatusOK, rr.Code)
39 }
40
41 if contentType := rr.Header().Get("Content-Type"); contentType != "text/plain" {
42 t.Errorf("expected Content-Type 'text/plain', got '%s'", contentType)
43 }
44
45 if body := rr.Body.String(); body != content {
46 t.Errorf("expected body '%s', got '%s'", content, body)
47 }
48}
49
50func TestRouteFileHandler_GeoJSON(t *testing.T) {
51 // Create temp directory structure
52 tempDir := t.TempDir()
53 routeDir := filepath.Join(tempDir, "ab")
54 if err := os.MkdirAll(routeDir, 0755); err != nil {
55 t.Fatalf("failed to create directory: %v", err)
56 }
57
58 // Create test file (64 character hex hash)
59 hash := "abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab"
60 content := `{"type":"Feature"}`
61 filePath := filepath.Join(routeDir, "cd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab.geojson")
62 if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
63 t.Fatalf("failed to write test file: %v", err)
64 }
65
66 // Create handler
67 handler := RouteFileHandler(tempDir)
68
69 // Test geojson request
70 req := httptest.NewRequest(http.MethodGet, "/route/"+hash+".geojson", nil)
71 rr := httptest.NewRecorder()
72
73 handler.ServeHTTP(rr, req)
74
75 if rr.Code != http.StatusOK {
76 t.Errorf("expected status %d, got %d", http.StatusOK, rr.Code)
77 }
78
79 if contentType := rr.Header().Get("Content-Type"); contentType != "application/geo+json" {
80 t.Errorf("expected Content-Type 'application/geo+json', got '%s'", contentType)
81 }
82}
83
84func TestRouteFileHandler_NotFound(t *testing.T) {
85 tempDir := t.TempDir()
86 handler := RouteFileHandler(tempDir)
87
88 // Request non-existent file
89 hash := "abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab"
90 req := httptest.NewRequest(http.MethodGet, "/route/"+hash+".polyline6", nil)
91 rr := httptest.NewRecorder()
92
93 handler.ServeHTTP(rr, req)
94
95 if rr.Code != http.StatusNotFound {
96 t.Errorf("expected status %d, got %d", http.StatusNotFound, rr.Code)
97 }
98}
99
100func TestRouteFileHandler_InvalidHash(t *testing.T) {
101 tempDir := t.TempDir()
102 handler := RouteFileHandler(tempDir)
103
104 // Request with invalid hash (too short)
105 req := httptest.NewRequest(http.MethodGet, "/route/abc123.polyline6", nil)
106 rr := httptest.NewRecorder()
107
108 handler.ServeHTTP(rr, req)
109
110 if rr.Code != http.StatusBadRequest {
111 t.Errorf("expected status %d, got %d", http.StatusBadRequest, rr.Code)
112 }
113}
114
115func TestRouteFileHandler_InvalidExtension(t *testing.T) {
116 tempDir := t.TempDir()
117 handler := RouteFileHandler(tempDir)
118
119 // Request with invalid extension
120 hash := "abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab"
121 req := httptest.NewRequest(http.MethodGet, "/route/"+hash+".json", nil)
122 rr := httptest.NewRecorder()
123
124 handler.ServeHTTP(rr, req)
125
126 if rr.Code != http.StatusBadRequest {
127 t.Errorf("expected status %d, got %d", http.StatusBadRequest, rr.Code)
128 }
129}
130
131func TestRouteFileHandler_InvalidFormat(t *testing.T) {
132 tempDir := t.TempDir()
133 handler := RouteFileHandler(tempDir)
134
135 // Request without extension
136 req := httptest.NewRequest(http.MethodGet, "/route/abc123", nil)
137 rr := httptest.NewRecorder()
138
139 handler.ServeHTTP(rr, req)
140
141 if rr.Code != http.StatusBadRequest {
142 t.Errorf("expected status %d, got %d", http.StatusBadRequest, rr.Code)
143 }
144}
145
146func TestRouteFileHandler_CacheControl(t *testing.T) {
147 // Create temp directory structure
148 tempDir := t.TempDir()
149 routeDir := filepath.Join(tempDir, "ab")
150 if err := os.MkdirAll(routeDir, 0755); err != nil {
151 t.Fatalf("failed to create directory: %v", err)
152 }
153
154 // Create test file
155 hash := "abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab"
156 filePath := filepath.Join(routeDir, "cd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab.polyline6")
157 if err := os.WriteFile(filePath, []byte("test"), 0644); err != nil {
158 t.Fatalf("failed to write test file: %v", err)
159 }
160
161 handler := RouteFileHandler(tempDir)
162 req := httptest.NewRequest(http.MethodGet, "/route/"+hash+".polyline6", nil)
163 rr := httptest.NewRecorder()
164
165 handler.ServeHTTP(rr, req)
166
167 cacheControl := rr.Header().Get("Cache-Control")
168 expected := "public, max-age=31536000, immutable"
169 if cacheControl != expected {
170 t.Errorf("expected Cache-Control '%s', got '%s'", expected, cacheControl)
171 }
172}
173
174func TestRouteFileHandler_ContentLength(t *testing.T) {
175 // Create temp directory structure
176 tempDir := t.TempDir()
177 routeDir := filepath.Join(tempDir, "ab")
178 if err := os.MkdirAll(routeDir, 0755); err != nil {
179 t.Fatalf("failed to create directory: %v", err)
180 }
181
182 // Create test file with known content
183 hash := "abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab"
184 content := "test content for length check"
185 filePath := filepath.Join(routeDir, "cd1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab.polyline6")
186 if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
187 t.Fatalf("failed to write test file: %v", err)
188 }
189
190 handler := RouteFileHandler(tempDir)
191 req := httptest.NewRequest(http.MethodGet, "/route/"+hash+".polyline6", nil)
192 rr := httptest.NewRecorder()
193
194 handler.ServeHTTP(rr, req)
195
196 expectedLength := fmt.Sprintf("%d", len(content))
197 if contentLength := rr.Header().Get("Content-Length"); contentLength != expectedLength {
198 t.Errorf("expected Content-Length '%s', got '%s'", expectedLength, contentLength)
199 }
200}