mirror of https://github.com/dirtbags/moth.git
Server tests
This commit is contained in:
parent
f8556dd2e5
commit
f49d1c3801
|
@ -38,7 +38,9 @@ func (h *HTTPServer) HandleMothFunc(
|
|||
mothHandler func(MothRequestHandler, http.ResponseWriter, *http.Request),
|
||||
) {
|
||||
handler := func(w http.ResponseWriter, req *http.Request) {
|
||||
mh := h.server.NewHandler(req.FormValue("id"))
|
||||
participantID := req.FormValue("pid")
|
||||
teamID := req.FormValue("id")
|
||||
mh := h.server.NewHandler(participantID, teamID)
|
||||
mothHandler(mh, w, req)
|
||||
}
|
||||
h.HandleFunc(h.base+pattern, handler)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHttpd(t *testing.T) {
|
||||
//emptyBody := bytes.NewReader([]byte{})
|
||||
//request := httptest.NewRequest("GET", "/", emptyBody)
|
||||
}
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"mime"
|
||||
"time"
|
||||
|
||||
|
@ -10,8 +9,6 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
log.Print("Started")
|
||||
|
||||
themePath := flag.String(
|
||||
"theme",
|
||||
"theme",
|
||||
|
@ -59,5 +56,6 @@ func main() {
|
|||
|
||||
server := NewMothServer(puzzles, theme, state)
|
||||
httpd := NewHTTPServer(*base, server)
|
||||
|
||||
httpd.Run(*bindStr)
|
||||
}
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEverything(t *testing.T) {
|
||||
state := NewTestState()
|
||||
t.Error("No test")
|
||||
|
||||
state.refresh()
|
||||
}
|
|
@ -12,8 +12,9 @@ var testFiles = []struct {
|
|||
Name, Body string
|
||||
}{
|
||||
{"puzzles.txt", "1"},
|
||||
{"answers.txt", "1 answer123\n1 answer456\n"},
|
||||
{"content/1/puzzle.json", `{"name": "moo"}`},
|
||||
{"content/1/moo.txt", `My cow goes "moo"`},
|
||||
{"content/1/moo.txt", `moo`},
|
||||
}
|
||||
|
||||
func (m *Mothballs) createMothball(cat string) {
|
||||
|
@ -29,11 +30,16 @@ func (m *Mothballs) createMothball(cat string) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMothballs(t *testing.T) {
|
||||
func NewTestMothballs() *Mothballs {
|
||||
m := NewMothballs(new(afero.MemMapFs))
|
||||
m.createMothball("test1")
|
||||
m.createMothball("pategory")
|
||||
m.refresh()
|
||||
if _, ok := m.categories["test1"]; !ok {
|
||||
return m
|
||||
}
|
||||
|
||||
func TestMothballs(t *testing.T) {
|
||||
m := NewTestMothballs()
|
||||
if _, ok := m.categories["pategory"]; !ok {
|
||||
t.Error("Didn't create a new category")
|
||||
}
|
||||
|
||||
|
@ -52,11 +58,22 @@ func TestMothballs(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
if err := m.CheckAnswer("pategory", 1, "answer"); err == nil {
|
||||
t.Error("Wrong answer marked right")
|
||||
}
|
||||
if err := m.CheckAnswer("pategory", 1, "answer123"); err != nil {
|
||||
t.Error("Right answer marked wrong", err)
|
||||
}
|
||||
if err := m.CheckAnswer("pategory", 1, "answer456"); err != nil {
|
||||
t.Error("Right answer marked wrong", err)
|
||||
}
|
||||
|
||||
m.createMothball("test2")
|
||||
m.Fs.Remove("test1.mb")
|
||||
m.Fs.Remove("pategory.mb")
|
||||
m.refresh()
|
||||
inv = m.Inventory()
|
||||
if len(inv) != 1 {
|
||||
t.Error("Deleted mothball is still around", inv)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ type StateProvider interface {
|
|||
TeamName(teamID string) (string, error)
|
||||
SetTeamName(teamID, teamName string) error
|
||||
AwardPoints(teamID string, cat string, points int) error
|
||||
LogEvent(msg string)
|
||||
Maintainer
|
||||
}
|
||||
|
||||
|
@ -82,17 +83,19 @@ func NewMothServer(puzzles PuzzleProvider, theme ThemeProvider, state StateProvi
|
|||
}
|
||||
|
||||
// NewHandler returns a new http.RequestHandler for the provided teamID.
|
||||
func (s *MothServer) NewHandler(teamID string) MothRequestHandler {
|
||||
func (s *MothServer) NewHandler(participantID, teamID string) MothRequestHandler {
|
||||
return MothRequestHandler{
|
||||
MothServer: s,
|
||||
teamID: teamID,
|
||||
MothServer: s,
|
||||
participantID: participantID,
|
||||
teamID: teamID,
|
||||
}
|
||||
}
|
||||
|
||||
// MothRequestHandler provides http.RequestHandler for a MothServer.
|
||||
type MothRequestHandler struct {
|
||||
*MothServer
|
||||
teamID string
|
||||
participantID string
|
||||
teamID string
|
||||
}
|
||||
|
||||
// PuzzlesOpen opens a file associated with a puzzle.
|
||||
|
@ -126,10 +129,14 @@ func (mh *MothRequestHandler) Register(teamName string) error {
|
|||
// CheckAnswer returns an error if answer is not a correct answer for puzzle points in category cat
|
||||
func (mh *MothRequestHandler) CheckAnswer(cat string, points int, answer string) error {
|
||||
if err := mh.Puzzles.CheckAnswer(cat, points, answer); err != nil {
|
||||
msg := fmt.Sprintf("BAD %s %s %s %d %s", mh.participantID, mh.teamID, cat, points, err.Error())
|
||||
mh.State.LogEvent(msg)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := mh.State.AwardPoints(mh.teamID, cat, points); err != nil {
|
||||
msg := fmt.Sprintf("GOOD %s %s %s %d", mh.participantID, mh.teamID, cat, points)
|
||||
mh.State.LogEvent(msg)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
const TestMaintenanceInterval = time.Millisecond * 1
|
||||
const TestTeamID = "teamID"
|
||||
|
||||
func NewTestServer() *MothServer {
|
||||
puzzles := NewTestMothballs()
|
||||
go puzzles.Maintain(TestMaintenanceInterval)
|
||||
|
||||
state := NewTestState()
|
||||
afero.WriteFile(state, "teamids.txt", []byte("teamID\n"), 0644)
|
||||
afero.WriteFile(state, "messages.html", []byte("messages.html"), 0644)
|
||||
go state.Maintain(TestMaintenanceInterval)
|
||||
|
||||
theme := NewTestTheme()
|
||||
afero.WriteFile(theme.Fs, "index.html", []byte("index.html"), 0644)
|
||||
go theme.Maintain(TestMaintenanceInterval)
|
||||
|
||||
return NewMothServer(puzzles, theme, state)
|
||||
}
|
||||
|
||||
func TestServer(t *testing.T) {
|
||||
teamName := "OurTeam"
|
||||
participantID := "participantID"
|
||||
teamID := TestTeamID
|
||||
|
||||
server := NewTestServer()
|
||||
handler := server.NewHandler(participantID, teamID)
|
||||
if err := handler.Register(teamName); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if r, _, err := handler.ThemeOpen("index.html"); err != nil {
|
||||
t.Error(err)
|
||||
} else if contents, err := ioutil.ReadAll(r); err != nil {
|
||||
t.Error(err)
|
||||
} else if string(contents) != "index.html" {
|
||||
t.Error("index.html wrong contents", contents)
|
||||
}
|
||||
|
||||
es := handler.ExportState()
|
||||
if es.Config.Devel {
|
||||
t.Error("Marked as development server")
|
||||
}
|
||||
if len(es.Puzzles) != 1 {
|
||||
t.Error("Puzzle categories wrong length")
|
||||
}
|
||||
if es.Messages != "messages.html" {
|
||||
t.Error("Messages has wrong contents")
|
||||
}
|
||||
if len(es.PointsLog) != 0 {
|
||||
t.Error("Points log not empty")
|
||||
}
|
||||
if len(es.TeamNames) != 1 {
|
||||
t.Error("Wrong number of team names")
|
||||
}
|
||||
if es.TeamNames["self"] != teamName {
|
||||
t.Error("TeamNames['self'] wrong")
|
||||
}
|
||||
|
||||
if r, _, err := handler.PuzzlesOpen("pategory", 1, "moo.txt"); err != nil {
|
||||
t.Error(err)
|
||||
} else if contents, err := ioutil.ReadAll(r); err != nil {
|
||||
t.Error(err)
|
||||
} else if string(contents) != "moo" {
|
||||
t.Error("moo.txt has wrong contents", contents)
|
||||
}
|
||||
|
||||
if err := handler.CheckAnswer("pategory", 1, "answer123"); err != nil {
|
||||
t.Error("Right answer marked wrong", err)
|
||||
}
|
||||
|
||||
time.Sleep(TestMaintenanceInterval)
|
||||
|
||||
es = handler.ExportState()
|
||||
if len(es.PointsLog) != 1 {
|
||||
t.Error("I didn't get my points!")
|
||||
}
|
||||
}
|
|
@ -204,7 +204,9 @@ func (s *State) AwardPoints(teamID, category string, points int) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// BUG(neale): When points are awarded, state should be updated immediately
|
||||
// State should be updated immediately
|
||||
s.refreshNow <- true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -342,12 +344,6 @@ func (s *State) LogEvent(msg string) {
|
|||
s.eventStream <- msg
|
||||
}
|
||||
|
||||
// LogEventf writes a formatted message to the event log
|
||||
func (s *State) LogEventf(format string, a ...interface{}) {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
s.LogEvent(msg)
|
||||
}
|
||||
|
||||
func (s *State) reopenEventLog() error {
|
||||
if s.eventWriter != nil {
|
||||
if err := s.eventWriter.Close(); err != nil {
|
||||
|
|
|
@ -78,7 +78,7 @@ func TestState(t *testing.T) {
|
|||
func TestStateEvents(t *testing.T) {
|
||||
s := NewTestState()
|
||||
s.LogEvent("moo")
|
||||
s.LogEventf("moo %d", 2)
|
||||
s.LogEvent("moo 2")
|
||||
|
||||
if msg := <-s.eventStream; msg != "moo" {
|
||||
t.Error("Wrong message from event stream", msg)
|
||||
|
|
Loading…
Reference in New Issue