moth

Monarch Of The Hill game server
git clone https://git.woozle.org/neale/moth.git

moth / cmd / mothd
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}