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 "bytes"
5 "net/http"
6 "net/url"
7 "strings"
8 "testing"
9)
10
11func TestAppSettingsSectionRoutes(t *testing.T) {
12 fx, _ := instanceFixture(t, "code-settings-sections")
13 c := newBrowser(t)
14 signUp(t, fx, c, "code-settings-sections-browser")
15
16 for _, section := range []string{"general", "domains", "storage", "email", "features", "advanced", "delete"} {
17 status, _, body := get(t, c, fx.u("/apps/titogo/settings/"+section))
18 if status != http.StatusOK {
19 t.Errorf("GET settings/%s = %d, want 200: %s", section, status, body)
20 }
21 }
22 _, _, general := get(t, c, fx.u("/apps/titogo/settings"))
23 for _, want := range []string{
24 `aria-label="Settings sections"`, ">General</a>", ">Domains</a>",
25 ">Release pipeline</a>", ">Storage</a>", ">Email</a>",
26 ">Feature flags</a>", ">Advanced</a>", ">Delete</a>",
27 } {
28 if !strings.Contains(general, want) {
29 t.Errorf("Settings navigation missing %q", want)
30 }
31 }
32 if strings.Contains(general, "Domains &amp; TLS") {
33 t.Fatal("General still renders the Domains section")
34 }
35 _, _, domains := get(t, c, fx.u("/apps/titogo/settings/domains"))
36 if !strings.Contains(domains, "Domains &amp; TLS") || strings.Contains(domains, "<h2>Identity</h2>") {
37 t.Fatal("Domains does not render as an isolated section")
38 }
39 status, _, _ := get(t, c, fx.u("/apps/titogo/settings/not-a-section"))
40 if status != http.StatusNotFound {
41 t.Errorf("GET unknown settings section = %d, want 404", status)
42 }
43 assertNonMember404(t, fx, "/apps/titogo/settings/domains")
44}
45
46func TestAppSettingsURL(t *testing.T) {
47 if got := appSettingsURL("a b", "an/app", "general"); got != "/a/a%20b/apps/an%2Fapp/settings" {
48 t.Errorf("general URL = %q", got)
49 }
50 if got := appSettingsURL("bab", "kass", "storage"); got != "/a/bab/apps/kass/settings/storage" {
51 t.Errorf("storage URL = %q", got)
52 }
53}
54
55func TestPipelineSettingsCanonicalSectionURL(t *testing.T) {
56 fx, _ := instanceFixture(t, "code-settings-pipeline-section")
57 c := newBrowser(t)
58 signUp(t, fx, c, "code-settings-pipeline-section-browser")
59
60 status, _, body := get(t, c, fx.u("/apps/titogo/settings/pipeline"))
61 if status != http.StatusOK || !strings.Contains(body, "Release pipeline") {
62 t.Fatalf("GET settings/pipeline = %d: %s", status, body)
63 }
64 status, _, body = get(t, c, fx.u("/apps/titogo/pipeline"))
65 if status != http.StatusOK || !strings.Contains(body, "Release pipeline") {
66 t.Fatalf("legacy GET pipeline = %d: %s", status, body)
67 }
68 csrf := sessionToken(t, fx, c)
69 status, _, body = postForm(t, c, fx.u("/apps/titogo/pipeline"), url.Values{
70 "csrf": {csrf}, "action": {"add"}, "ch.0.name": {"edge"},
71 })
72 if status != http.StatusOK || !strings.Contains(body, `aria-label="Settings sections"`) ||
73 !strings.Contains(body, `aria-current="page">Release pipeline</a>`) {
74 t.Fatalf("pipeline draft rerender lost Settings navigation = %d: %s", status, body)
75 }
76}
77
78func TestSettingsValidationRetainsTypedValues(t *testing.T) {
79 fx := newConsoleFixture(t)
80 freshApp(t, fx, "sprout")
81 c := signInPaul(t, fx)
82 csrf := sessionToken(t, fx, c)
83
84 status, _, body := postForm(t, c, fx.u("/apps/sprout/rename"), url.Values{
85 "csrf": {csrf}, "to": {"Still Typing"},
86 })
87 if status != http.StatusUnprocessableEntity || !strings.Contains(body, `value="Still Typing"`) {
88 t.Fatalf("rename refusal did not retain the typed name = %d: %s", status, body)
89 }
90
91 status, _, body = postForm(t, c, fx.u("/apps/sprout/domains/attach"), url.Values{
92 "csrf": {csrf}, "host": {"not a host"}, "channel": {"canary/draft"},
93 })
94 if status != http.StatusUnprocessableEntity || !strings.Contains(body, `value="not a host"`) ||
95 !strings.Contains(body, `value="canary/draft"`) {
96 t.Fatalf("domain refusal did not retain host and channel = %d: %s", status, body)
97 }
98}
99
100func TestBucketlessSettingsSectionsExplainConfiguration(t *testing.T) {
101 for section, want := range map[string]string{
102 "storage": "no deployment bucket on this host — this console cannot serve object storage",
103 "email": "no deployment bucket on this host — this console cannot serve email",
104 "features": "no deployment bucket on this host — this console cannot read features",
105 } {
106 p := page{
107 Title: "Settings", AppName: "sprout", ActiveTab: "settings", SettingsSection: section,
108 Account: &Account{Name: "paul@example.com", Sqid: "bab"},
109 Detail: &AppView{App: "sprout"}, Settings: &SettingsView{NoBucket: true},
110 }
111 var buf bytes.Buffer
112 if err := templates.ExecuteTemplate(&buf, "app_settings", p); err != nil {
113 t.Fatalf("render %s: %v", section, err)
114 }
115 body := buf.String()
116 if !strings.Contains(body, want) || strings.Contains(body, "Please try again") {
117 t.Fatalf("bucketless %s section is not explicit: %s", section, body)
118 }
119 }
120}
121