package devserver
import (
"context"
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"time"
)
func writeFile(t *testing.T, path, body string) {
t.Helper()
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(path, []byte(body), 0o644); err != nil {
t.Fatal(err)
}
}
func TestServeStatic(t *testing.T) {
t.Parallel()
dir := t.TempDir()
writeFile(t, filepath.Join(dir, "index.html"), "<h1>home</h1>")
writeFile(t, filepath.Join(dir, "posts", "a.html"), "<h1>post a</h1>")
cfg := DefaultConfig(dir)
rr := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/", nil)
serveStatic(rr, r, cfg)
if rr.Code != http.StatusOK {
t.Errorf("code = %d", rr.Code)
}
body, _ := io.ReadAll(rr.Body)
if string(body) != "<h1>home</h1>" {
t.Errorf("body = %q", body)
}
}
func TestServeStaticNotFound(t *testing.T) {
t.Parallel()
cfg := DefaultConfig(t.TempDir())
rr := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/missing.html", nil)
serveStatic(rr, r, cfg)
if rr.Code != http.StatusNotFound {
t.Errorf("code = %d", rr.Code)
}
}
func TestServerRunAndShutdown(t *testing.T) {
t.Parallel()
dir := t.TempDir()
writeFile(t, filepath.Join(dir, "index.html"), "ok")
cfg := DefaultConfig(dir)
cfg.Addr = "127.0.0.1:0"
s := New(cfg)
ctx, cancel := context.WithCancel(context.Background())
done := make(chan error, 1)
go func() { done <- s.Run(ctx) }()
time.Sleep(10 * time.Millisecond)
cancel()
select {
case err := <-done:
if err != nil {
t.Errorf("Run returned: %v", err)
}
case <-time.After(2 * time.Second):
t.Fatal("server did not shut down in time")
}
}
func TestMimeTypeMapping(t *testing.T) {
t.Parallel()
t.Helper()
if got := MimeType(".html"); got != "text/html; charset=utf-8" {
t.Errorf(".html = %q", got)
}
}