Many changes

This commit is contained in:
2026-05-31 20:17:49 -05:00
parent 9e398957a9
commit 99d46ecd2a
28 changed files with 3729 additions and 594 deletions
+64 -82
View File
@@ -2,14 +2,13 @@ package httpapi
import (
"errors"
"html/template"
"io"
"log"
"net/http"
"net/http/httptest"
"os"
"net/netip"
"path/filepath"
"runtime"
"strings"
"testing"
"scratchbox/internal/config"
@@ -48,27 +47,7 @@ func TestWriteCreateErrorBranches(t *testing.T) {
}
}
func TestIsLikelyText(t *testing.T) {
t.Parallel()
if !isLikelyText("text/plain; charset=utf-8", []byte{0x00}) {
t.Fatalf("text/plain should be treated as text")
}
if !isLikelyText("application/json", []byte{0x00}) {
t.Fatalf("application/json should be treated as text")
}
if isLikelyText("application/octet-stream", []byte{0xff, 0xfe, 0xfd}) {
t.Fatalf("binary octet-stream should not be treated as text")
}
if !isLikelyText("", []byte("hello")) {
t.Fatalf("utf8 payload should be treated as text")
}
if !isLikelyText("", nil) {
t.Fatalf("empty payload should be treated as text")
}
}
func TestNewServerLoadsTemplates(t *testing.T) {
func TestNewServerInitializes(t *testing.T) {
tmp := t.TempDir()
store, err := storage.NewFilesystemStore(filepath.Join(tmp, "data"))
if err != nil {
@@ -81,32 +60,63 @@ func TestNewServerLoadsTemplates(t *testing.T) {
},
}
_, file, _, ok := runtime.Caller(0)
if !ok {
t.Fatal("runtime.Caller failed")
}
repoRoot := filepath.Clean(filepath.Join(filepath.Dir(file), "..", ".."))
wd, err := os.Getwd()
if err != nil {
t.Fatalf("Getwd() error = %v", err)
}
if err := os.Chdir(repoRoot); err != nil {
t.Fatalf("Chdir() error = %v", err)
}
defer func() {
_ = os.Chdir(wd)
}()
srv, err := NewServer(cfg, store, log.New(io.Discard, "", 0))
if err != nil {
t.Fatalf("NewServer() error = %v", err)
}
if srv == nil || srv.templates == nil {
t.Fatalf("expected initialized server with templates")
if srv == nil {
t.Fatalf("expected initialized server")
}
}
func TestNewServerTemplateErrorAndIndexError(t *testing.T) {
func TestGetUIConfig(t *testing.T) {
t.Parallel()
s := &Server{
cfg: config.Config{
Limits: config.LimitsConfig{
MaxUploadSizeBytes: 2048,
},
},
}
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/api/config", nil)
s.getUIConfig(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d, want %d", rec.Code, http.StatusOK)
}
if got := rec.Body.String(); got == "" || !containsAll(got, "max_upload_size_bytes", "2048", `"upload_allowed":true`) {
t.Fatalf("unexpected body: %q", got)
}
}
func TestGetUIConfigUploadDenied(t *testing.T) {
t.Parallel()
s := &Server{
cfg: config.Config{
Limits: config.LimitsConfig{
MaxUploadSizeBytes: 2048,
},
Security: config.SecurityConfig{
AllowedPrefixes: []netip.Prefix{
netip.MustParsePrefix("10.0.0.0/8"),
},
},
},
}
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/api/config", nil)
s.getUIConfig(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d, want %d", rec.Code, http.StatusOK)
}
if got := rec.Body.String(); got == "" || !containsAll(got, `"upload_allowed":false`) {
t.Fatalf("unexpected body: %q", got)
}
}
func TestWriteCreateErrorBranchesWithConfig(t *testing.T) {
tmp := t.TempDir()
store, err := storage.NewFilesystemStore(filepath.Join(tmp, "data"))
if err != nil {
@@ -118,44 +128,16 @@ func TestNewServerTemplateErrorAndIndexError(t *testing.T) {
RateLimit: config.RateLimitConfig{Enabled: false},
},
}
wd, err := os.Getwd()
if err != nil {
t.Fatalf("Getwd() error = %v", err)
}
if err := os.Chdir(tmp); err != nil {
t.Fatalf("Chdir() error = %v", err)
}
defer func() {
_ = os.Chdir(wd)
}()
if _, err := NewServer(cfg, store, log.New(io.Discard, "", 0)); err == nil {
t.Fatalf("expected NewServer() template parse error")
}
s := &Server{}
func() {
defer func() {
if recover() == nil {
t.Fatalf("expected panic when templates are nil")
}
}()
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/", nil)
s.index(rec, req)
}()
}
func TestIndexExecuteTemplateError(t *testing.T) {
t.Parallel()
s := &Server{
templates: template.New("empty"),
}
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/", nil)
s.index(rec, req)
if rec.Code != http.StatusInternalServerError {
t.Fatalf("index status = %d, want %d", rec.Code, http.StatusInternalServerError)
if _, err := NewServer(cfg, store, log.New(io.Discard, "", 0)); err != nil {
t.Fatalf("NewServer() error = %v", err)
}
}
func containsAll(haystack string, needles ...string) bool {
for _, needle := range needles {
if !strings.Contains(haystack, needle) {
return false
}
}
return true
}