2019-12-01 18:58:09 -07:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2019-12-01 20:53:13 -07:00
|
|
|
"bytes"
|
2020-08-21 17:02:38 -06:00
|
|
|
"fmt"
|
2019-12-01 18:58:09 -07:00
|
|
|
"os"
|
2020-08-19 15:38:13 -06:00
|
|
|
"strings"
|
2019-12-01 18:58:09 -07:00
|
|
|
"testing"
|
2020-08-18 17:04:23 -06:00
|
|
|
"time"
|
2020-08-14 20:26:04 -06:00
|
|
|
|
2022-05-18 09:19:21 -06:00
|
|
|
|
|
|
|
"github.com/dirtbags/moth/pkg/award"
|
2020-08-14 20:26:04 -06:00
|
|
|
"github.com/spf13/afero"
|
2019-12-01 18:58:09 -07:00
|
|
|
)
|
|
|
|
|
2020-08-17 17:43:57 -06:00
|
|
|
func NewTestState() *State {
|
|
|
|
s := NewState(new(afero.MemMapFs))
|
2020-08-18 17:04:23 -06:00
|
|
|
s.refresh()
|
2020-08-17 17:43:57 -06:00
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2019-12-01 18:58:09 -07:00
|
|
|
func TestState(t *testing.T) {
|
2020-08-17 17:43:57 -06:00
|
|
|
s := NewTestState()
|
2019-12-01 18:58:09 -07:00
|
|
|
|
|
|
|
mustExist := func(path string) {
|
2020-08-17 17:43:57 -06:00
|
|
|
_, err := s.Fs.Stat(path)
|
2019-12-01 18:58:09 -07:00
|
|
|
if os.IsNotExist(err) {
|
|
|
|
t.Errorf("File %s does not exist", path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-01 20:53:13 -07:00
|
|
|
pl := s.PointsLog()
|
|
|
|
if len(pl) != 0 {
|
|
|
|
t.Errorf("Empty points log is not empty")
|
|
|
|
}
|
2019-12-01 20:47:46 -07:00
|
|
|
|
2019-12-01 18:58:09 -07:00
|
|
|
mustExist("initialized")
|
|
|
|
mustExist("enabled")
|
2020-09-11 20:16:58 -06:00
|
|
|
mustExist("hours.txt")
|
2019-12-01 20:53:13 -07:00
|
|
|
|
2020-08-17 17:43:57 -06:00
|
|
|
teamIDsBuf, err := afero.ReadFile(s.Fs, "teamids.txt")
|
2019-12-01 20:47:46 -07:00
|
|
|
if err != nil {
|
2019-12-01 20:53:13 -07:00
|
|
|
t.Errorf("Reading teamids.txt: %v", err)
|
2019-12-01 20:47:46 -07:00
|
|
|
}
|
2019-12-01 20:53:13 -07:00
|
|
|
|
2020-08-17 17:43:57 -06:00
|
|
|
teamIDs := bytes.Split(teamIDsBuf, []byte("\n"))
|
|
|
|
if (len(teamIDs) != 101) || (len(teamIDs[100]) > 0) {
|
|
|
|
t.Errorf("There weren't 100 teamIDs, there were %d", len(teamIDs))
|
2019-12-01 20:47:46 -07:00
|
|
|
}
|
2020-08-17 17:43:57 -06:00
|
|
|
teamID := string(teamIDs[0])
|
2019-12-01 20:53:13 -07:00
|
|
|
|
2020-08-21 17:02:38 -06:00
|
|
|
if _, err := s.TeamName(teamID); err == nil {
|
|
|
|
t.Errorf("Bad team ID lookup didn't return error")
|
|
|
|
}
|
|
|
|
|
2019-12-01 20:47:46 -07:00
|
|
|
if err := s.SetTeamName("bad team ID", "bad team name"); err == nil {
|
2019-12-01 20:53:13 -07:00
|
|
|
t.Errorf("Setting bad team ID didn't raise an error")
|
2019-12-01 20:47:46 -07:00
|
|
|
}
|
2019-12-01 20:53:13 -07:00
|
|
|
|
2020-10-13 19:48:37 -06:00
|
|
|
teamName := "My Team"
|
|
|
|
if err := s.SetTeamName(teamID, teamName); err != nil {
|
2021-10-13 16:43:51 -06:00
|
|
|
t.Errorf("Setting team name: %v", err)
|
2019-12-01 20:47:46 -07:00
|
|
|
}
|
2020-08-21 17:02:38 -06:00
|
|
|
if err := s.SetTeamName(teamID, "wat"); err == nil {
|
|
|
|
t.Errorf("Registering team a second time didn't fail")
|
|
|
|
}
|
2021-10-26 12:48:23 -06:00
|
|
|
s.refresh()
|
2020-10-13 19:48:37 -06:00
|
|
|
if name, err := s.TeamName(teamID); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
} else if name != teamName {
|
|
|
|
t.Error("Incorrect team name:", name)
|
|
|
|
}
|
2019-12-07 21:17:13 -07:00
|
|
|
|
2019-12-05 21:50:43 -07:00
|
|
|
category := "poot"
|
|
|
|
points := 3928
|
2020-08-21 17:02:38 -06:00
|
|
|
if err := s.AwardPoints(teamID, category, points); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
// Flex duplicate detection with different timestamp
|
|
|
|
if f, err := s.Create("points.new/moo"); err != nil {
|
|
|
|
t.Error("Creating duplicate points file:", err)
|
|
|
|
} else {
|
|
|
|
fmt.Fprintln(f, time.Now().Unix()+1, teamID, category, points)
|
|
|
|
f.Close()
|
|
|
|
}
|
2021-10-26 12:48:23 -06:00
|
|
|
|
|
|
|
s.AwardPoints(teamID, category, points)
|
2020-08-18 17:04:23 -06:00
|
|
|
s.refresh()
|
2022-05-17 15:58:45 -06:00
|
|
|
|
|
|
|
if (! s.PointExists(teamID, category, points)) {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Unable to find points %s/%d for team %s", category, points, teamID)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
2021-10-26 12:48:23 -06:00
|
|
|
pl = s.PointsLog()
|
|
|
|
if len(pl) != 1 {
|
|
|
|
for i, award := range pl {
|
|
|
|
t.Logf("pl[%d] == %s", i, award.String())
|
|
|
|
}
|
|
|
|
t.Errorf("After awarding duplicate points, points log has length %d", len(pl))
|
|
|
|
} else if (pl[0].TeamID != teamID) || (pl[0].Category != category) || (pl[0].Points != points) {
|
|
|
|
t.Errorf("Incorrect logged award %v", pl)
|
|
|
|
}
|
2019-12-07 21:17:13 -07:00
|
|
|
|
2020-08-21 17:02:38 -06:00
|
|
|
if err := s.AwardPoints(teamID, category, points); err == nil {
|
2021-10-26 12:48:23 -06:00
|
|
|
t.Error("Duplicate points award after refresh didn't fail")
|
2020-08-21 17:02:38 -06:00
|
|
|
}
|
|
|
|
|
2020-10-14 09:46:51 -06:00
|
|
|
if err := s.AwardPoints(teamID, category, points+1); err != nil {
|
|
|
|
t.Error("Awarding more points:", err)
|
|
|
|
}
|
|
|
|
|
2021-10-26 12:48:23 -06:00
|
|
|
s.refresh()
|
|
|
|
if len(s.PointsLog()) != 2 {
|
|
|
|
t.Errorf("There should be two awards")
|
2019-12-05 21:50:43 -07:00
|
|
|
}
|
2019-12-07 21:17:13 -07:00
|
|
|
|
2020-08-21 17:02:38 -06:00
|
|
|
afero.WriteFile(s, "points.log", []byte("intentional parse error\n"), 0644)
|
2021-10-26 12:48:23 -06:00
|
|
|
s.refresh()
|
2020-08-21 17:02:38 -06:00
|
|
|
if len(s.PointsLog()) != 0 {
|
|
|
|
t.Errorf("Intentional parse error breaks pointslog")
|
|
|
|
}
|
|
|
|
if err := s.AwardPoints(teamID, category, points); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
s.refresh()
|
2021-10-26 12:48:23 -06:00
|
|
|
if len(s.PointsLog()) != 1 {
|
|
|
|
t.Log(s.PointsLog())
|
2020-08-21 17:02:38 -06:00
|
|
|
t.Error("Intentional parse error screws up all parsing")
|
|
|
|
}
|
|
|
|
|
2020-08-17 17:43:57 -06:00
|
|
|
s.Fs.Remove("initialized")
|
2020-08-18 17:04:23 -06:00
|
|
|
s.refresh()
|
2019-12-07 21:17:13 -07:00
|
|
|
|
2019-12-05 21:54:32 -07:00
|
|
|
pl = s.PointsLog()
|
|
|
|
if len(pl) != 0 {
|
|
|
|
t.Errorf("After reinitialization, points log has length %d", len(pl))
|
|
|
|
}
|
2020-08-21 17:02:38 -06:00
|
|
|
|
2019-12-01 18:58:09 -07:00
|
|
|
}
|
2020-08-18 17:04:23 -06:00
|
|
|
|
2022-05-17 15:58:45 -06:00
|
|
|
func TestStatePointsRemoval(t *testing.T) {
|
|
|
|
s := NewTestState()
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
team := "team1"
|
|
|
|
category := "meow"
|
|
|
|
points1 := 100
|
|
|
|
points2 := points1 + 1
|
|
|
|
|
2022-05-18 08:44:01 -06:00
|
|
|
// Add points into our log
|
2022-05-17 16:08:21 -06:00
|
|
|
if err := s.AwardPoints(team, category, points1); err != nil {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Received unexpected error when awarding points: %s", err)
|
2022-05-17 16:08:21 -06:00
|
|
|
}
|
2022-05-17 15:58:45 -06:00
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLogLength := len(s.PointsLog())
|
|
|
|
if pointsLogLength != 1 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 1 point in the log after awarding, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
2022-05-17 16:08:21 -06:00
|
|
|
if err := s.AwardPoints(team, category, points2); err != nil {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Received unexpected error when awarding points: %s", err)
|
2022-05-17 16:08:21 -06:00
|
|
|
}
|
2022-05-17 15:58:45 -06:00
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLogLength = len(s.PointsLog())
|
|
|
|
if pointsLogLength != 2 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 2 points in the log after awarding, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
2022-05-18 08:44:01 -06:00
|
|
|
// Remove a point
|
2022-05-17 16:08:21 -06:00
|
|
|
if err := s.RemovePoints(team, category, points1); err != nil {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Received unexpected error when removing points1: %s", err)
|
2022-05-17 16:08:21 -06:00
|
|
|
}
|
2022-05-17 15:58:45 -06:00
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLog := s.PointsLog()
|
|
|
|
pointsLogLength = len(pointsLog)
|
|
|
|
if pointsLogLength != 1 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 1 point in the log after removal, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
2022-05-18 08:44:01 -06:00
|
|
|
if ((pointsLog[0].TeamID != team) || (pointsLog[0].Category != category) || (pointsLog[0].Points != points2)) {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Found unexpected points log entry after removal: %s", pointsLog[0])
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
2022-05-18 08:44:01 -06:00
|
|
|
// Remove a duplicate point
|
|
|
|
if err := s.RemovePoints(team, category, points1); err != NoMatchingPointEntry {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected to receive NoMatchingPointEntry, received error '%s', instead", err)
|
2022-05-17 16:08:21 -06:00
|
|
|
}
|
2022-05-17 15:58:45 -06:00
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLog = s.PointsLog()
|
|
|
|
pointsLogLength = len(pointsLog)
|
|
|
|
if pointsLogLength != 1 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 1 point in the log after duplicate removal, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
2022-05-18 08:44:01 -06:00
|
|
|
// Remove the second point
|
2022-05-17 16:08:21 -06:00
|
|
|
if err := s.RemovePoints(team, category, points2); err != nil {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Received unexpected error when removing points2: %s", err)
|
2022-05-17 16:08:21 -06:00
|
|
|
}
|
2022-05-17 15:58:45 -06:00
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLog = s.PointsLog()
|
|
|
|
pointsLogLength = len(pointsLog)
|
|
|
|
if pointsLogLength != 0 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 0 point in the log after last removal, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStatePointsRemovalAtTime(t *testing.T) {
|
|
|
|
s := NewTestState()
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
team := "team1"
|
|
|
|
category := "meow"
|
|
|
|
points1 := 100
|
|
|
|
points2 := points1 + 1
|
|
|
|
now := time.Now().Unix()
|
|
|
|
time1 := now
|
|
|
|
time2 := now+10
|
|
|
|
|
|
|
|
|
|
|
|
s.AwardPointsAtTime(team, category, points1, time1)
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLogLength := len(s.PointsLog())
|
|
|
|
if pointsLogLength != 1 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 1 point in the log, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
pointsLog := s.PointsLog()
|
|
|
|
if ((pointsLog[0].When != time1) || (pointsLog[0].TeamID != team) || (pointsLog[0].Category != category) || (pointsLog[0].Points != points1)) {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Received unexpected points entry: %s", pointsLog[0])
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
s.AwardPointsAtTime(team, category, points2, time2)
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLogLength = len(s.PointsLog())
|
|
|
|
if pointsLogLength != 2 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 2 point in the log, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Remove valid points, but at wrong time
|
|
|
|
s.RemovePointsAtTime(team, category, points1, time2)
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLogLength = len(s.PointsLog())
|
|
|
|
if pointsLogLength != 2 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 2 point in the log, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
s.RemovePointsAtTime(team, category, points1, time1)
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLog = s.PointsLog()
|
|
|
|
pointsLogLength = len(pointsLog)
|
|
|
|
if pointsLogLength != 1 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 1 point in the log, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((pointsLog[0].When != time2) || (pointsLog[0].TeamID != team) || (pointsLog[0].Category != category) || (pointsLog[0].Points != points2)) {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Found unexpected points log entry: %s", pointsLog[0])
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
s.RemovePointsAtTime(team, category, points1, time1)
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLog = s.PointsLog()
|
|
|
|
pointsLogLength = len(pointsLog)
|
|
|
|
if pointsLogLength != 1 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 1 point in the log, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
s.RemovePointsAtTime(team, category, points2, time2)
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLog = s.PointsLog()
|
|
|
|
pointsLogLength = len(pointsLog)
|
|
|
|
if pointsLogLength != 0 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 0 point in the log, got %d", pointsLogLength)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
2022-05-18 09:19:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestStateSetPoints(t *testing.T) {
|
|
|
|
s := NewTestState()
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
team := "team1"
|
|
|
|
category := "meow"
|
|
|
|
points := 100
|
|
|
|
time := time.Now().Unix()
|
|
|
|
|
|
|
|
|
|
|
|
// Add points into our log
|
|
|
|
if err := s.AwardPointsAtTime(team, category, points, time); err != nil {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Received unexpected error when awarding points: %s", err)
|
2022-05-18 09:19:21 -06:00
|
|
|
}
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLog := s.PointsLog()
|
|
|
|
pointsLogLength := len(pointsLog)
|
|
|
|
if pointsLogLength != 1 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 1 point in the log after awarding, got %d", pointsLogLength)
|
2022-05-18 09:19:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
expectedPoints := make(award.List, pointsLogLength)
|
|
|
|
copy( expectedPoints, pointsLog)
|
2022-05-17 15:58:45 -06:00
|
|
|
|
2022-05-18 09:19:21 -06:00
|
|
|
s.SetPoints(make(award.List, 0))
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLog = s.PointsLog()
|
|
|
|
pointsLogLength = len(pointsLog)
|
|
|
|
if pointsLogLength != 0 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 0 point in the log after awarding, got %d", pointsLogLength)
|
2022-05-18 09:19:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := s.SetPoints(expectedPoints); err != nil {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Received unexpected error when awarding points: %s", err)
|
2022-05-18 09:19:21 -06:00
|
|
|
}
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
pointsLog = s.PointsLog()
|
|
|
|
pointsLogLength = len(pointsLog)
|
|
|
|
if pointsLogLength != 1 {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected 1 point in the log after awarding, got %d", pointsLogLength)
|
2022-05-18 09:19:21 -06:00
|
|
|
} else if (expectedPoints[0] != pointsLog[0]) {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected first point '%s', received '%s', instead", expectedPoints[0], pointsLog[0])
|
2022-05-18 09:19:21 -06:00
|
|
|
}
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
2021-10-14 19:01:12 -06:00
|
|
|
// Out of order points insertion, issue #168
|
|
|
|
func TestStateOutOfOrderAward(t *testing.T) {
|
|
|
|
s := NewTestState()
|
|
|
|
|
|
|
|
category := "meow"
|
|
|
|
points := 100
|
|
|
|
|
|
|
|
now := time.Now().Unix()
|
2022-05-17 15:58:45 -06:00
|
|
|
if err := s.AwardPointsAtTime("AA", category, points, now+20); err != nil {
|
2021-10-14 19:01:12 -06:00
|
|
|
t.Error("Awarding points to team ZZ:", err)
|
|
|
|
}
|
2022-05-17 15:58:45 -06:00
|
|
|
if err := s.AwardPointsAtTime("ZZ", category, points, now+10); err != nil {
|
2021-10-14 19:01:12 -06:00
|
|
|
t.Error("Awarding points to team AA:", err)
|
|
|
|
}
|
|
|
|
s.refresh()
|
2022-05-17 15:58:45 -06:00
|
|
|
|
|
|
|
if (! s.PointExistsAtTime("AA", category, points, now+20)) {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Unable to find points awarded to team AA for %s/%d at %d", category, points, now+20)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
if (! s.PointExistsAtTime("ZZ", category, points, now+10)) {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Unable to find points awarded to team ZZ for %s/%d at %d", category, points, now+10)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
|
2021-10-14 19:01:12 -06:00
|
|
|
pl := s.PointsLog()
|
|
|
|
if len(pl) != 2 {
|
|
|
|
t.Error("Wrong length for points log")
|
|
|
|
}
|
|
|
|
if pl[0].TeamID != "ZZ" {
|
|
|
|
t.Error("Out of order points insertion not properly sorted in points log")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-18 17:04:23 -06:00
|
|
|
func TestStateEvents(t *testing.T) {
|
|
|
|
s := NewTestState()
|
2020-10-14 18:20:49 -06:00
|
|
|
s.LogEvent("moo", "", "", "", 0)
|
|
|
|
s.LogEvent("moo 2", "", "", "", 0)
|
2020-08-18 17:04:23 -06:00
|
|
|
|
2020-12-02 17:57:10 -07:00
|
|
|
if msg := <-s.eventStream; strings.Join(msg[1:], ":") != "init::::0" {
|
2020-10-14 18:20:49 -06:00
|
|
|
t.Error("Wrong message from event stream:", msg)
|
2020-08-18 17:04:23 -06:00
|
|
|
}
|
2020-12-02 17:57:10 -07:00
|
|
|
if msg := <-s.eventStream; strings.Join(msg[1:], ":") != "moo::::0" {
|
2020-10-14 18:20:49 -06:00
|
|
|
t.Error("Wrong message from event stream:", msg)
|
|
|
|
}
|
2020-12-02 17:57:10 -07:00
|
|
|
if msg := <-s.eventStream; strings.Join(msg[1:], ":") != "moo 2::::0" {
|
2020-10-14 18:20:49 -06:00
|
|
|
t.Error("Wrong message from event stream:", msg)
|
2020-08-18 17:04:23 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-21 17:02:38 -06:00
|
|
|
func TestStateDisabled(t *testing.T) {
|
|
|
|
s := NewTestState()
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
if !s.Enabled {
|
|
|
|
t.Error("Brand new state is disabled")
|
|
|
|
}
|
|
|
|
|
2020-09-11 20:16:58 -06:00
|
|
|
hoursFile, err := s.Create("hours.txt")
|
2020-08-21 17:02:38 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
defer hoursFile.Close()
|
|
|
|
|
|
|
|
fmt.Fprintln(hoursFile, "- 1970-01-01T01:01:01Z")
|
|
|
|
hoursFile.Sync()
|
|
|
|
s.refresh()
|
|
|
|
if s.Enabled {
|
|
|
|
t.Error("Disabling 1970-01-01")
|
|
|
|
}
|
|
|
|
|
2020-09-11 20:16:58 -06:00
|
|
|
fmt.Fprintln(hoursFile, "+ 1970-01-01 01:01:01+05:00")
|
2020-08-21 17:02:38 -06:00
|
|
|
hoursFile.Sync()
|
|
|
|
s.refresh()
|
|
|
|
if !s.Enabled {
|
|
|
|
t.Error("Enabling 1970-01-02")
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Fprintln(hoursFile, "")
|
|
|
|
fmt.Fprintln(hoursFile, "# Comment")
|
|
|
|
hoursFile.Sync()
|
|
|
|
s.refresh()
|
|
|
|
if !s.Enabled {
|
|
|
|
t.Error("Comments")
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Fprintln(hoursFile, "intentional parse error")
|
|
|
|
hoursFile.Sync()
|
|
|
|
s.refresh()
|
|
|
|
if !s.Enabled {
|
|
|
|
t.Error("intentional parse error")
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Fprintln(hoursFile, "- 1980-01-01T01:01:01Z")
|
|
|
|
hoursFile.Sync()
|
|
|
|
s.refresh()
|
|
|
|
if s.Enabled {
|
|
|
|
t.Error("Disabling 1980-01-01")
|
|
|
|
}
|
|
|
|
|
2020-09-11 20:16:58 -06:00
|
|
|
if err := s.Remove("hours.txt"); err != nil {
|
2020-08-21 17:02:38 -06:00
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
s.refresh()
|
|
|
|
if !s.Enabled {
|
2020-09-11 20:16:58 -06:00
|
|
|
t.Error("Removing `hours.txt` disabled event")
|
2020-08-21 17:02:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := s.Remove("enabled"); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
s.refresh()
|
|
|
|
if s.Enabled {
|
|
|
|
t.Error("Removing `enabled` didn't disable")
|
|
|
|
}
|
|
|
|
|
|
|
|
s.Remove("initialized")
|
|
|
|
s.refresh()
|
|
|
|
if !s.Enabled {
|
2020-09-17 19:48:17 -06:00
|
|
|
t.Error("Re-initializing didn't start event")
|
2020-08-21 17:02:38 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-18 17:04:23 -06:00
|
|
|
func TestStateMaintainer(t *testing.T) {
|
2020-08-19 15:38:13 -06:00
|
|
|
updateInterval := 10 * time.Millisecond
|
|
|
|
|
2020-08-18 17:04:23 -06:00
|
|
|
s := NewTestState()
|
2020-08-19 15:38:13 -06:00
|
|
|
go s.Maintain(updateInterval)
|
|
|
|
|
|
|
|
if _, err := s.Stat("initialized"); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
teamIDLines, err := afero.ReadFile(s, "teamids.txt")
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
teamIDList := strings.Split(string(teamIDLines), "\n")
|
|
|
|
if len(teamIDList) != 101 {
|
|
|
|
t.Error("TeamIDList length is", len(teamIDList))
|
|
|
|
}
|
|
|
|
teamID := teamIDList[0]
|
|
|
|
if len(teamID) < 6 {
|
|
|
|
t.Error("Team ID too short:", teamID)
|
|
|
|
}
|
2020-08-18 17:04:23 -06:00
|
|
|
|
2020-10-14 18:20:49 -06:00
|
|
|
s.LogEvent("Hello!", "", "", "", 0)
|
2020-08-19 15:38:13 -06:00
|
|
|
|
|
|
|
if len(s.PointsLog()) != 0 {
|
|
|
|
t.Error("Points log is not empty")
|
|
|
|
}
|
|
|
|
if err := s.SetTeamName(teamID, "The Patricks"); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if err := s.AwardPoints(teamID, "pategory", 31337); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
time.Sleep(updateInterval)
|
|
|
|
pl := s.PointsLog()
|
|
|
|
if len(pl) != 1 {
|
|
|
|
t.Error("Points log should have one entry")
|
|
|
|
}
|
|
|
|
if (pl[0].Category != "pategory") || (pl[0].TeamID != teamID) {
|
|
|
|
t.Error("Wrong points event was recorded")
|
|
|
|
}
|
|
|
|
|
|
|
|
time.Sleep(updateInterval)
|
|
|
|
|
2020-12-02 17:57:10 -07:00
|
|
|
eventLog, err := afero.ReadFile(s.Fs, "events.csv")
|
2020-08-19 15:38:13 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
2020-10-14 18:20:49 -06:00
|
|
|
} else if events := strings.Split(string(eventLog), "\n"); len(events) != 3 {
|
|
|
|
t.Log("Events:", events)
|
|
|
|
t.Error("Wrong event log length:", len(events))
|
|
|
|
} else if events[2] != "" {
|
|
|
|
t.Error("Event log didn't end with newline")
|
2020-08-18 17:04:23 -06:00
|
|
|
}
|
|
|
|
}
|
2020-12-02 19:31:34 -07:00
|
|
|
|
2022-05-17 15:58:45 -06:00
|
|
|
func TestMessage(t *testing.T) {
|
|
|
|
s := NewTestState()
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
message := "foobar"
|
|
|
|
|
|
|
|
if err:= s.SetMessages(message); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
s.refresh()
|
|
|
|
|
2022-05-17 16:08:21 -06:00
|
|
|
retrievedMessage := s.Messages()
|
2022-05-17 15:58:45 -06:00
|
|
|
|
|
|
|
if (retrievedMessage != message) {
|
2022-05-18 11:19:53 -06:00
|
|
|
t.Errorf("Expected message '%s', received '%s', instead", message, retrievedMessage)
|
2022-05-17 15:58:45 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-18 11:19:53 -06:00
|
|
|
func TestStateTeamIDs(t *testing.T) {
|
|
|
|
s := NewTestState()
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
emptyTeams := make([]string, 0)
|
|
|
|
teamID1 := "foobar"
|
|
|
|
teamID2 := "foobaz"
|
|
|
|
|
|
|
|
// Verify we can pull the initial list without error
|
|
|
|
if _, err := s.TeamIDs(); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can we set team IDs to an empty list?
|
|
|
|
if err := s.SetTeamIDs(emptyTeams); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if teamIDs, err := s.TeamIDs(); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
} else {
|
|
|
|
if len(teamIDs) != 0 {
|
|
|
|
t.Errorf("Expected to find 0 team IDs, found %d (%s), instead", len(teamIDs), teamIDs)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add a team ID
|
|
|
|
if err := s.AddTeamID(teamID1); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
}
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
if teamIDs, err := s.TeamIDs(); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
} else {
|
|
|
|
if len(teamIDs) != 1 {
|
|
|
|
t.Errorf("Expected to find 1 team ID, found %d (%s), instead", len(teamIDs), teamIDs)
|
|
|
|
} else {
|
|
|
|
if teamIDs[0] != teamID1 {
|
|
|
|
t.Errorf("Expected to find team ID '%s', found '%s', instead", teamID1, teamIDs[0])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add another team ID
|
|
|
|
if err := s.AddTeamID(teamID2); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
}
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
if teamIDs, err := s.TeamIDs(); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
} else {
|
|
|
|
if len(teamIDs) != 2 {
|
|
|
|
t.Errorf("Expected to find 2 team IDs, found %d (%s), instead", len(teamIDs), teamIDs)
|
|
|
|
} else {
|
|
|
|
if exists1, err1 := s.TeamIDExists(teamID1); err1 != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
} else {
|
|
|
|
if ! exists1 {
|
|
|
|
t.Errorf("Expected to find team ID '%s', but didn't find it", teamID1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove a team ID
|
|
|
|
if err := s.RemoveTeamID(teamID1); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
}
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
if teamIDs, err := s.TeamIDs(); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
} else {
|
|
|
|
if len(teamIDs) != 1 {
|
|
|
|
t.Errorf("Expected to find 1 team ID, found %d (%s), instead", len(teamIDs), teamIDs)
|
|
|
|
} else {
|
|
|
|
if exists2, err2 := s.TeamIDExists(teamID2); err2 != nil {
|
|
|
|
t.Errorf("Received unexpected error: %s", err2)
|
|
|
|
} else if (! exists2) {
|
|
|
|
t.Errorf("Expected to find team ID '%s', but didn't find it", teamID2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove the last team ID
|
|
|
|
if err := s.RemoveTeamID(teamID2); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
}
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
if teamIDs, err := s.TeamIDs(); err != nil {
|
|
|
|
t.Errorf("Received unexpected error %s", err)
|
|
|
|
} else {
|
|
|
|
if len(teamIDs) != 0 {
|
|
|
|
t.Errorf("Expected to find 0 team ID, found %d (%s), instead", len(teamIDs), teamIDs)
|
|
|
|
}
|
|
|
|
}
|
2022-10-21 16:08:28 -06:00
|
|
|
}
|
2022-05-18 11:19:53 -06:00
|
|
|
|
2022-10-21 16:08:28 -06:00
|
|
|
func TestStateDeleteTeamIDList(t *testing.T) {
|
|
|
|
s := NewTestState()
|
|
|
|
s.refresh()
|
|
|
|
|
2022-10-21 16:12:47 -06:00
|
|
|
s.Fs.Remove("teamids.txt")
|
2022-10-21 16:08:28 -06:00
|
|
|
|
|
|
|
teamIDs, err := s.TeamIDs()
|
|
|
|
|
|
|
|
if len(teamIDs) != 0 {
|
|
|
|
t.Errorf("Expected to find 0 team IDs, found %d (%s), instead", len(teamIDs), teamIDs)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Errorf("Did not receive expected error for non-existent teamids.txt")
|
|
|
|
}
|
2022-05-18 11:19:53 -06:00
|
|
|
}
|
|
|
|
|
2022-10-21 15:41:59 -06:00
|
|
|
func TestStateTeamNames(t *testing.T) {
|
|
|
|
s := NewTestState()
|
|
|
|
s.refresh()
|
|
|
|
|
|
|
|
if teamNames := s.TeamNames(); len(teamNames) != 0 {
|
|
|
|
t.Errorf("Expected to find 0 registered teams, found %d (%s), instead", len(teamNames), teamNames)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-02 19:31:34 -07:00
|
|
|
func TestDevelState(t *testing.T) {
|
|
|
|
s := NewTestState()
|
|
|
|
ds := NewDevelState(s)
|
2021-02-01 16:53:38 -07:00
|
|
|
if err := ds.SetTeamName("boog", "The Boog Team"); err != ErrAlreadyRegistered {
|
|
|
|
t.Error("Registering a team that doesn't exist", err)
|
|
|
|
} else if err == nil {
|
|
|
|
t.Error("Registering a team that doesn't exist didn't return ErrAlreadyRegistered")
|
|
|
|
}
|
2020-12-02 19:31:34 -07:00
|
|
|
if n, err := ds.TeamName("boog"); err != nil {
|
|
|
|
t.Error("Devel State returned error on team name lookup")
|
2020-12-02 19:49:06 -07:00
|
|
|
} else if n != "«devel:boog»" {
|
2020-12-02 19:31:34 -07:00
|
|
|
t.Error("Wrong team name", n)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := ds.AwardPoints("blerg", "dog", 82); err != nil {
|
|
|
|
t.Error("Devel State AwardPoints returned an error", err)
|
|
|
|
}
|
|
|
|
}
|