package surf import ( "bytes" "os" "path/filepath" "slices" "strings" "testing" "git.golem15.com/golem15/summercms/modules/backpack" "git.golem15.com/golem15/summercms/modules/bonfire" "git.golem15.com/golem15/summercms/modules/compass" "gocloud.dev/blob" ) func TestPublishUploadsRequiresURL(t *testing.T) { app := serveTestApp(t, "uploads:\n bucket_url: \"\"\n") _, err := publishUploads(t.Context(), app) if err == nil || !strings.Contains(err.Error(), "bucket_url") { t.Fatalf("got %v, want bucket_url error", err) } } func TestPublishUploadsStoresBucket(t *testing.T) { app := serveTestApp(t, "uploads:\n bucket_url: \"mem://\"\n public_path_prefix: \"/storage/uploads\"\n") bucket, err := publishUploads(t.Context(), app) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = bucket.Close() }) got, ok := app.Lookup[*blob.Bucket]() if !ok || got != bucket { t.Fatal("publishUploads must store the opened *blob.Bucket") } } func serveTestApp(t *testing.T, storageYAML string) *backpack.App { t.Helper() dir := t.TempDir() if err := os.WriteFile(filepath.Join(dir, "app.yaml"), []byte("name: serve-uploads\n"), 0o644); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, "storage.yaml"), []byte(storageYAML), 0o644); err != nil { t.Fatal(err) } cfg, err := compass.Open(compass.Options{ Dir: dir, Env: "development", Environ: []string{"SUMMER_ENV=development"}, }) if err != nil { t.Fatal(err) } return backpack.New(cfg) } func TestServeURL(t *testing.T) { for _, tc := range []struct{ addr, want string }{ {":8123", "http://127.0.0.1:8123/"}, {"127.0.0.1:9000", "http://127.0.0.1:9000/"}, {"[::1]:8080", "http://[::1]:8080/"}, {"0.0.0.0:80", "http://127.0.0.1/"}, {"[::]:8080", "http://127.0.0.1:8080/"}, {"localhost:3000", "http://localhost:3000/"}, {"8080", ""}, {"", ""}, {"127.0.0.1:", ""}, } { if got := serveURL(tc.addr); got != tc.want { t.Errorf("serveURL(%q) = %q, want %q", tc.addr, got, tc.want) } } } func TestServeBanner(t *testing.T) { listen := bannerLine{text: "listening on :8123, open http://127.0.0.1:8123/"} mounted := bannerLine{text: "admin: http://127.0.0.1:8123/backend"} create := "summer admin:create --email you@example.com --superuser" for _, tc := range []struct { name string addr string prefix string mounted bool admins adminPresence want []bannerLine }{ {"present", ":8123", "/backend", true, adminsPresent, []bannerLine{listen, mounted}}, {"none", ":8123", "/backend", true, adminsNone, []bannerLine{listen, mounted, {warn: true, text: "no administrators yet; create one with " + create}}}, {"missing table", ":8123", "/backend", true, adminsMissingTable, []bannerLine{listen, mounted, {warn: true, text: "the admin tables do not exist yet; run summer migrate, then " + create}}}, {"unknown", ":8123", "/backend", true, adminsUnknown, []bannerLine{listen, mounted, {text: "sign in with an administrator; " + create + " creates one"}}}, {"off", ":8123", "", false, adminsUnknown, []bannerLine{listen, {text: "admin: off — no plugin registers an admin controller"}, {text: "to add one, run summer make:admin-controller , then summer build, summer migrate and " + create + "; the admin needs SUMMER_ADMIN__JWT__SECRET, which summer new writes to .env"}}}, {"unparsable address", "8080", "/backend", true, adminsPresent, []bannerLine{ {text: "listening on 8080"}, {text: "admin: mounted at /backend"}}}, } { t.Run(tc.name, func(t *testing.T) { got := serveBanner(tc.addr, tc.prefix, tc.mounted, tc.admins) if !slices.Equal(got, tc.want) { t.Fatalf("serveBanner:\n got %#v\nwant %#v", got, tc.want) } }) } } func TestPrintBanner(t *testing.T) { var buf bytes.Buffer out := bonfire.NewOutput(strings.NewReader(""), &buf, &buf) printBanner(out, []bannerLine{{text: "plain"}, {warn: true, text: "careful"}}) got := buf.String() if !strings.Contains(got, "ℹ plain") || !strings.Contains(got, "⚠ careful") { t.Fatalf("printBanner output = %q", got) } } func TestCountAdminsNilDB(t *testing.T) { if got := countAdmins(t.Context(), nil); got != adminsUnknown { t.Fatalf("countAdmins(nil) = %v, want adminsUnknown", got) } }