web コンテナの土台を追加(HTTP サーバー、TVer API クライアント、htmx の画面枠、Dockerfile・compose.yaml)

This commit is contained in:
2026-10-03 17:01:50 +09:00
parent 4ad0d621e1
commit 5125614b93
15 changed files with 677 additions and 5 deletions
+63
View File
@@ -0,0 +1,63 @@
package web
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestHealthz(t *testing.T) {
response := httptest.NewRecorder()
NewHandler().ServeHTTP(response, httptest.NewRequest(http.MethodGet, "/healthz", nil))
if response.Code != http.StatusOK || response.Body.String() != "ok\n" {
t.Errorf("healthz: status=%d body=%q", response.Code, response.Body.String())
}
}
func TestPagesAndEmbeddedAssets(t *testing.T) {
handler := NewHandler()
for _, tt := range []struct{ path, title string }{
{"/", "新着"}, {"/queue", "待ち行列"}, {"/subscriptions", "登録番組"}, {"/library", "ライブラリ"},
} {
t.Run(tt.path, func(t *testing.T) {
response := httptest.NewRecorder()
handler.ServeHTTP(response, httptest.NewRequest(http.MethodGet, tt.path, nil))
body := response.Body.String()
if response.Code != http.StatusOK || !strings.Contains(response.Header().Get("Content-Type"), "text/html") {
t.Fatalf("status=%d Content-Type=%q", response.Code, response.Header().Get("Content-Type"))
}
for _, want := range []string{"<h1>" + tt.title + "</h1>", "新着", "待ち行列", "登録番組", "ライブラリ", `hx-boost="true"`, "/static/htmx-2.0.11.min.js"} {
if !strings.Contains(body, want) {
t.Errorf("page missing %q", want)
}
}
})
}
response := httptest.NewRecorder()
handler.ServeHTTP(response, httptest.NewRequest(http.MethodGet, "/static/htmx-2.0.11.min.js", nil))
if response.Code != http.StatusOK || !strings.Contains(response.Header().Get("Content-Type"), "javascript") || response.Body.Len() < 1000 || !strings.Contains(response.Body.String(), "htmx") {
t.Errorf("embedded htmx: status=%d Content-Type=%q bytes=%d", response.Code, response.Header().Get("Content-Type"), response.Body.Len())
}
}
func TestUnknownPathsAndMethods(t *testing.T) {
handler := NewHandler()
for _, tt := range []struct {
name, method, path string
wantStatus int
}{
{"unknown page", http.MethodGet, "/missing", http.StatusNotFound},
{"root prefix", http.MethodGet, "/missing/nested", http.StatusNotFound},
{"missing static asset", http.MethodGet, "/static/missing.js", http.StatusNotFound},
{"unsupported page method", http.MethodPost, "/queue", http.StatusMethodNotAllowed},
} {
t.Run(tt.name, func(t *testing.T) {
response := httptest.NewRecorder()
handler.ServeHTTP(response, httptest.NewRequest(tt.method, tt.path, nil))
if response.Code != tt.wantStatus {
t.Errorf("%s %s: status=%d; want %d", tt.method, tt.path, response.Code, tt.wantStatus)
}
})
}
}