Neale Pickett
·
2023-10-03
httpd_test.go
1package main
2
3import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "net/http/httptest"
8 "net/url"
9 "testing"
10
11 "github.com/spf13/afero"
12)
13
14func (hs *HTTPServer) TestRequest(path string, args map[string]string) *httptest.ResponseRecorder {
15 vals := url.Values{}
16 vals.Set("id", TestTeamID)
17 for k, v := range args {
18 vals.Set(k, v)
19 }
20
21 recorder := httptest.NewRecorder()
22 request := httptest.NewRequest(
23 "GET",
24 fmt.Sprintf("%s?%s", path, vals.Encode()),
25 bytes.NewReader([]byte{}),
26 )
27 hs.ServeHTTP(recorder, request)
28 return recorder
29}
30
31func TestHttpd(t *testing.T) {
32 server := NewTestServer()
33 hs := NewHTTPServer("/", server.MothServer)
34
35 if r := hs.TestRequest("/", nil); r.Result().StatusCode != 200 {
36 t.Error(r.Result())
37 }
38
39 if r := hs.TestRequest("/index.html", nil); r.Result().StatusCode != 200 {
40 t.Error(r.Result())
41 }
42 if r := hs.TestRequest("/rolodex.html", nil); r.Result().StatusCode != 404 {
43 t.Error(r.Result())
44 }
45
46 if r := hs.TestRequest("/state", nil); r.Result().StatusCode != 200 {
47 t.Error(r.Result())
48 } else if r.Body.String() != `{"Config":{"Devel":false},"Enabled":true,"TeamNames":{},"PointsLog":[],"Puzzles":{}}` {
49 t.Error("Unexpected state", r.Body.String())
50 }
51
52 if r := hs.TestRequest("/register", map[string]string{"id": "bad team id", "name": "GoTeam"}); r.Result().StatusCode != 200 {
53 t.Error(r.Result())
54 } else if r.Body.String() != `{"status":"fail","data":{"short":"not registered","description":"team ID not found in list of valid team IDs"}}` {
55 t.Error("Register bad team ID failed")
56 }
57
58 if r := hs.TestRequest("/register", map[string]string{"name": "GoTeam"}); r.Result().StatusCode != 200 {
59 t.Error(r.Result())
60 } else if r.Body.String() != `{"status":"success","data":{"short":"registered","description":"team ID registered"}}` {
61 t.Error("Register failed")
62 }
63
64 if r := hs.TestRequest("/register", map[string]string{"name": "GoTeam"}); r.Result().StatusCode != 200 {
65 t.Error(r.Result())
66 } else if r.Body.String() != `{"status":"success","data":{"short":"already registered","description":"team ID has already been registered"}}` {
67 t.Error("Register failed", r.Body.String())
68 }
69
70 server.refresh()
71
72 if r := hs.TestRequest("/state", nil); r.Result().StatusCode != 200 {
73 t.Error(r.Result())
74 } else if r.Body.String() != `{"Config":{"Devel":false},"Enabled":true,"TeamNames":{"self":"GoTeam"},"PointsLog":[],"Puzzles":{"pategory":[1]}}` {
75 t.Error("Unexpected state", r.Body.String())
76 }
77
78 if r := hs.TestRequest("/content/pategory", nil); r.Result().StatusCode != 404 {
79 t.Error(r.Result())
80 }
81
82 if r := hs.TestRequest("/content/pategory/1/not-here", nil); r.Result().StatusCode != 404 {
83 t.Error(r.Result())
84 }
85
86 if r := hs.TestRequest("/content/pategory/2/moo.txt", nil); r.Result().StatusCode != 404 {
87 t.Error(r.Result())
88 }
89
90 if r := hs.TestRequest("/content/pategory/1/", nil); r.Result().StatusCode != 200 {
91 t.Error(r.Result())
92 }
93
94 if r := hs.TestRequest("/content/pategory/1/moo.txt", nil); r.Result().StatusCode != 200 {
95 t.Error(r.Result())
96 } else if r.Body.String() != `moo` {
97 t.Error("Unexpected body", r.Body.String())
98 }
99
100 if r := hs.TestRequest("/answer", map[string]string{"cat": "pategory", "points": "1", "answer": "moo"}); r.Result().StatusCode != 200 {
101 t.Error(r.Result())
102 } else if r.Body.String() != `{"status":"fail","data":{"short":"not accepted","description":"incorrect answer"}}` {
103 t.Error("Unexpected body", r.Body.String())
104 }
105
106 if r := hs.TestRequest("/answer", map[string]string{"cat": "pategory", "points": "1", "answer": "answer123"}); r.Result().StatusCode != 200 {
107 t.Error(r.Result())
108 } else if r.Body.String() != `{"status":"success","data":{"short":"accepted","description":"1 points awarded in pategory"}}` {
109 t.Error("Unexpected body", r.Body.String())
110 }
111
112 server.refresh()
113
114 if r := hs.TestRequest("/content/pategory/2/puzzle.json", nil); r.Result().StatusCode != 200 {
115 t.Error(r.Result())
116 }
117
118 state := StateExport{}
119 if r := hs.TestRequest("/state", nil); r.Result().StatusCode != 200 {
120 t.Error(r.Result())
121 } else if err := json.Unmarshal(r.Body.Bytes(), &state); err != nil {
122 t.Error(err)
123 } else if len(state.PointsLog) != 1 {
124 t.Errorf("Points log wrong length. Wanted 1, got %v (length %d)", state.PointsLog, len(state.PointsLog))
125 } else if len(state.Puzzles["pategory"]) != 2 {
126 t.Error("Didn't unlock next puzzle")
127 }
128
129 if r := hs.TestRequest("/answer", map[string]string{"cat": "pategory", "points": "1", "answer": "answer123"}); r.Result().StatusCode != 200 {
130 t.Error(r.Result())
131 } else if r.Body.String() != `{"status":"fail","data":{"short":"not accepted","description":"points already awarded to this team in this category"}}` {
132 t.Error("Unexpected body", r.Body.String())
133 }
134}
135
136func TestDevelMemHttpd(t *testing.T) {
137 srv := NewTestServer()
138
139 {
140 hs := NewHTTPServer("/", srv.MothServer)
141
142 if r := hs.TestRequest("/mothballer/pategory.md", nil); r.Result().StatusCode != 404 {
143 t.Error("Should have gotten a 404 for mothballer in prod mode")
144 }
145 }
146
147 {
148 srv.Config.Devel = true
149 hs := NewHTTPServer("/", srv.MothServer)
150
151 if r := hs.TestRequest("/mothballer/pategory.md", nil); r.Result().StatusCode != 500 {
152 t.Log(r.Body.String())
153 t.Log(r.Result())
154 t.Error("Should have given us an internal server error, since category is a mothball")
155 }
156 }
157}
158
159func TestDevelFsHttps(t *testing.T) {
160 fs := afero.NewBasePathFs(afero.NewOsFs(), "testdata")
161 transpilerProvider := NewTranspilerProvider(fs)
162 srv := NewMothServer(Configuration{Devel: true}, NewTestTheme(), NewTestState(), transpilerProvider)
163 hs := NewHTTPServer("/", srv)
164
165 if r := hs.TestRequest("/mothballer/cat0.mb", nil); r.Result().StatusCode != 200 {
166 t.Log(r.Body.String())
167 t.Log(r.Result())
168 t.Error("Didn't get a Mothball")
169 }
170}