138 lines
4.2 KiB
Go
138 lines
4.2 KiB
Go
package reseed
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"boostai-backend/internal/config"
|
|
"boostai-backend/internal/seeddata"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
func TestPageRequiresEnableFlag(t *testing.T) {
|
|
t.Parallel()
|
|
h := &Handler{cfg: &config.Config{Environment: "production"}}
|
|
status, _ := performRequest(t, h, http.MethodGet, "/reseed", "", "")
|
|
if status != fiber.StatusNotFound {
|
|
t.Fatalf("expected 404, got %d", status)
|
|
}
|
|
}
|
|
|
|
func TestLoginSetsCookieAndRedirects(t *testing.T) {
|
|
t.Parallel()
|
|
h := newTestHandler(func(ctx context.Context, mockDataDir string) (seeddata.Summary, error) {
|
|
return seeddata.Summary{}, nil
|
|
})
|
|
status, resp := performRequest(t, h, http.MethodPost, "/reseed/login", "password=1588", "")
|
|
if status != fiber.StatusSeeOther {
|
|
t.Fatalf("expected 303, got %d", status)
|
|
}
|
|
if location := resp.Header.Get("Location"); location != "/reseed" {
|
|
t.Fatalf("expected redirect to /reseed, got %q", location)
|
|
}
|
|
if cookie := resp.Header.Get("Set-Cookie"); !strings.Contains(cookie, reseedCookieName+"=") {
|
|
t.Fatalf("expected auth cookie, got %q", cookie)
|
|
}
|
|
}
|
|
|
|
func TestRunRequiresAuthCookie(t *testing.T) {
|
|
t.Parallel()
|
|
h := newTestHandler(func(ctx context.Context, mockDataDir string) (seeddata.Summary, error) {
|
|
return seeddata.Summary{}, nil
|
|
})
|
|
status, body := performRequestBody(t, h, http.MethodPost, "/reseed/run", "", "")
|
|
if status != fiber.StatusUnauthorized {
|
|
t.Fatalf("expected 401, got %d", status)
|
|
}
|
|
if !strings.Contains(body, "Please unlock the reseed page first") {
|
|
t.Fatalf("expected unlock message, got %q", body)
|
|
}
|
|
}
|
|
|
|
func TestRunExecutesReseed(t *testing.T) {
|
|
t.Parallel()
|
|
h := newTestHandler(func(ctx context.Context, mockDataDir string) (seeddata.Summary, error) {
|
|
if mockDataDir != "/app/Mock-Data" {
|
|
t.Fatalf("expected mock data dir /app/Mock-Data, got %q", mockDataDir)
|
|
}
|
|
return seeddata.Summary{Users: 13, Assignments: 8, StudentAnswers: 588, MockDataDir: mockDataDir}, nil
|
|
})
|
|
status, body := performRequestBody(t, h, http.MethodPost, "/reseed/run", "", reseedCookieName+"="+h.authCookieValue())
|
|
if status != fiber.StatusOK {
|
|
t.Fatalf("expected 200, got %d", status)
|
|
}
|
|
if !strings.Contains(body, "Reseed completed") || !strings.Contains(body, "student_answers: 588") {
|
|
t.Fatalf("expected success summary, got %q", body)
|
|
}
|
|
}
|
|
|
|
func TestRunSurfacesRunnerError(t *testing.T) {
|
|
t.Parallel()
|
|
h := newTestHandler(func(ctx context.Context, mockDataDir string) (seeddata.Summary, error) {
|
|
return seeddata.Summary{}, errors.New("boom")
|
|
})
|
|
status, body := performRequestBody(t, h, http.MethodPost, "/reseed/run", "", reseedCookieName+"="+h.authCookieValue())
|
|
if status != fiber.StatusInternalServerError {
|
|
t.Fatalf("expected 500, got %d", status)
|
|
}
|
|
if !strings.Contains(body, "boom") {
|
|
t.Fatalf("expected error body, got %q", body)
|
|
}
|
|
}
|
|
|
|
func newTestHandler(fn func(context.Context, string) (seeddata.Summary, error)) *Handler {
|
|
return &Handler{
|
|
cfg: &config.Config{
|
|
Environment: "production",
|
|
AdminReseedEnabled: true,
|
|
MockDataDir: "/app/Mock-Data",
|
|
JWTSecret: "jwt-secret",
|
|
ReseedPagePassword: "1588",
|
|
},
|
|
runner: fn,
|
|
}
|
|
}
|
|
|
|
func performRequest(t *testing.T, handler *Handler, method, path, formBody, cookieHeader string) (int, *http.Response) {
|
|
t.Helper()
|
|
app := testApp(handler)
|
|
req := httptest.NewRequest(method, path, strings.NewReader(formBody))
|
|
if formBody != "" {
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
}
|
|
if cookieHeader != "" {
|
|
req.Header.Set("Cookie", cookieHeader)
|
|
}
|
|
resp, err := app.Test(req)
|
|
if err != nil {
|
|
t.Fatalf("app.Test: %v", err)
|
|
}
|
|
return resp.StatusCode, resp
|
|
}
|
|
|
|
func performRequestBody(t *testing.T, handler *Handler, method, path, formBody, cookieHeader string) (int, string) {
|
|
t.Helper()
|
|
status, resp := performRequest(t, handler, method, path, formBody, cookieHeader)
|
|
defer resp.Body.Close()
|
|
bodyBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
t.Fatalf("ReadAll: %v", err)
|
|
}
|
|
return status, string(bodyBytes)
|
|
}
|
|
|
|
func testApp(handler *Handler) *fiber.App {
|
|
app := fiber.New()
|
|
app.Get("/reseed", handler.Page)
|
|
app.Post("/reseed/login", handler.Login)
|
|
app.Post("/reseed/run", handler.Run)
|
|
app.Post("/reseed/logout", handler.Logout)
|
|
return app
|
|
}
|