carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package console
2
3import (
4 "net/http"
5 "net/url"
6 "testing"
7
8 "github.com/carlosframework/platform/internal/registry"
9 "github.com/carlosframework/platform/internal/release"
10)
11
12func TestBrowserAppRestartUsesSharedGeneration(t *testing.T) {
13 fx := newConsoleFixture(t)
14 c := signInPaul(t, fx)
15 csrf := sessionToken(t, fx, c)
16 status, _, _ := postForm(t, c, fx.u("/apps/kass/restart"), url.Values{"csrf": {csrf}})
17 if status != http.StatusOK {
18 t.Fatalf("confirm = %d", status)
19 }
20 if restartGenEtag(t, fx, "kass") != "" || len(scopeLog(t, fx, "kass").Requests) != 0 {
21 t.Fatal("confirmation page wrote restart state")
22 }
23 status, loc, _ := postGated(t, fx, c, fx.u("/apps/kass/restart"), url.Values{"csrf": {csrf}, "confirmed": {"1"}})
24 if status != http.StatusSeeOther || loc != fx.path("/apps/kass/instances") {
25 t.Fatalf("restart = %d -> %q", status, loc)
26 }
27 if restartGenEtag(t, fx, "kass") == "" {
28 t.Fatal("browser restart did not touch app generation")
29 }
30 if got := serial(t, fx); got != 1 {
31 t.Fatalf("serial = %d", got)
32 }
33}
34
35func TestBrowserInstanceRestartIsExactAndNeverWidens(t *testing.T) {
36 fx := newConsoleFixture(t)
37 fx.addRoute(t, registry.Route{Host: "sleep.kass.test", App: "kass", Account: "bab", Kind: "instance", Status: "ready", Hibernate: true})
38 c := signInPaul(t, fx)
39 csrf := sessionToken(t, fx, c)
40 endpoint := fx.u("/apps/kass/instances/sleep.kass.test/restart")
41 status, _, _ := postGated(t, fx, c, endpoint, url.Values{"csrf": {csrf}, "confirmed": {"1"}})
42 if status != http.StatusSeeOther {
43 t.Fatalf("restart = %d", status)
44 }
45 if restartGenEtag(t, fx, "kass") != "" {
46 t.Fatal("instance restart widened into app generation")
47 }
48 log := scopeLog(t, fx, "kass")
49 if len(log.Requests) != 1 || log.Requests[0].Scope.Kind != release.RestartScopeHost || log.Requests[0].Scope.Value != "sleep.kass.test" {
50 t.Fatalf("scope log = %+v", log)
51 }
52 reg, _ := registry.Open(fx.regPath)
53 routes, _ := reg.List()
54 for _, rt := range routes {
55 if rt.Host == "sleep.kass.test" && !rt.Hibernate {
56 t.Fatal("restart request woke sleeping route")
57 }
58 }
59}
60
61func TestBrowserInstanceRestartRefusesUnaddressableHosts(t *testing.T) {
62 fx := newConsoleFixture(t)
63 fx.addRoute(t, registry.Route{Host: "foreign.test", App: "kass", Account: "elsewhere", Kind: "instance", Status: "ready"})
64 c := signInPaul(t, fx)
65 csrf := sessionToken(t, fx, c)
66 for _, host := range []string{"missing.test", "foreign.test", "docs.kass.carlosapp.dev", "%20", "%09", "%20%20"} {
67 status, _, body := postGated(t, fx, c, fx.u("/apps/kass/instances/"+host+"/restart"), url.Values{"csrf": {csrf}, "confirmed": {"1"}})
68 if status != http.StatusNotFound || body != "404 page not found\n" {
69 t.Errorf("%s = %d %q", host, status, body)
70 }
71 }
72 if restartGenEtag(t, fx, "kass") != "" || len(scopeLog(t, fx, "kass").Requests) != 0 {
73 t.Fatal("refusal wrote restart state")
74 }
75}
76
77func TestBrowserRestartRequiresCSRF(t *testing.T) {
78 fx := newConsoleFixture(t)
79 c := signInPaul(t, fx)
80 status, _, _ := postForm(t, c, fx.u("/apps/kass/restart"), url.Values{"csrf": {"wrong"}})
81 if status != http.StatusForbidden {
82 t.Fatalf("csrf = %d", status)
83 }
84 status, _, _ = postForm(t, c, fx.u("/apps/no-such-app/restart"), url.Values{"csrf": {"wrong"}})
85 if status != http.StatusForbidden {
86 t.Fatalf("csrf before app membership = %d", status)
87 }
88}
89