mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 13:46:44 -04:00
Add awards management and automatic lower third creation.
This commit is contained in:
2
TODO.md
2
TODO.md
@@ -3,7 +3,6 @@ Cheesy Arena To-Do List
|
||||
|
||||
### Features for FRC parity
|
||||
* Event wizard to guide scorekeeper through running an event
|
||||
* Awards tracking and publishing
|
||||
* Elimination bracket report and audience screen
|
||||
* Interface for viewing logs (right now it's CSV files in Excel)
|
||||
|
||||
@@ -15,7 +14,6 @@ Cheesy Arena To-Do List
|
||||
### Scorekeeper-facing features
|
||||
* Ability to unscore a match and reset it to non-played status
|
||||
* Allow reordering of sponsor slides in the setup page
|
||||
* Automatic creation of lower thirds for awards
|
||||
|
||||
### Features for other volunteers
|
||||
* Referee interface: add timer starting at field reset to track time limit for calling timeouts/backups
|
||||
|
||||
@@ -3,7 +3,8 @@ CREATE TABLE lower_thirds (
|
||||
id INTEGER PRIMARY KEY,
|
||||
toptext VARCHAR(255),
|
||||
bottomtext VARCHAR(255),
|
||||
displayorder int
|
||||
displayorder int,
|
||||
awardid int
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
|
||||
11
db/migrations/20190809204907_CreateAwards.sql
Normal file
11
db/migrations/20190809204907_CreateAwards.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE awards (
|
||||
id INTEGER PRIMARY KEY,
|
||||
type int,
|
||||
awardname VARCHAR(255),
|
||||
teamid int,
|
||||
personname VARCHAR(255)
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE awards;
|
||||
62
model/award.go
Normal file
62
model/award.go
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2019 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Model and datastore CRUD methods for an award.
|
||||
|
||||
package model
|
||||
|
||||
type Award struct {
|
||||
Id int
|
||||
Type AwardType
|
||||
AwardName string
|
||||
TeamId int
|
||||
PersonName string
|
||||
}
|
||||
|
||||
type AwardType int
|
||||
|
||||
const (
|
||||
JudgedAward AwardType = iota
|
||||
FinalistAward
|
||||
WinnerAward
|
||||
)
|
||||
|
||||
func (database *Database) CreateAward(award *Award) error {
|
||||
return database.awardMap.Insert(award)
|
||||
}
|
||||
|
||||
func (database *Database) GetAwardById(id int) (*Award, error) {
|
||||
award := new(Award)
|
||||
err := database.awardMap.Get(award, id)
|
||||
if err != nil && err.Error() == "sql: no rows in result set" {
|
||||
award = nil
|
||||
err = nil
|
||||
}
|
||||
return award, err
|
||||
}
|
||||
|
||||
func (database *Database) SaveAward(award *Award) error {
|
||||
_, err := database.awardMap.Update(award)
|
||||
return err
|
||||
}
|
||||
|
||||
func (database *Database) DeleteAward(award *Award) error {
|
||||
_, err := database.awardMap.Delete(award)
|
||||
return err
|
||||
}
|
||||
|
||||
func (database *Database) TruncateAwards() error {
|
||||
return database.awardMap.TruncateTables()
|
||||
}
|
||||
|
||||
func (database *Database) GetAllAwards() ([]Award, error) {
|
||||
var awards []Award
|
||||
err := database.awardMap.Select(&awards, "SELECT * FROM awards ORDER BY id")
|
||||
return awards, err
|
||||
}
|
||||
|
||||
func (database *Database) GetAwardsByType(awardType AwardType) ([]Award, error) {
|
||||
var awards []Award
|
||||
err := database.awardMap.Select(&awards, "SELECT * FROM awards WHERE type = ? ORDER BY id", awardType)
|
||||
return awards, err
|
||||
}
|
||||
90
model/award_test.go
Normal file
90
model/award_test.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright 2019 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetNonexistentAward(t *testing.T) {
|
||||
db := setupTestDb(t)
|
||||
|
||||
award, err := db.GetAwardById(1114)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, award)
|
||||
}
|
||||
|
||||
func TestAwardCrud(t *testing.T) {
|
||||
db := setupTestDb(t)
|
||||
|
||||
award := Award{0, JudgedAward, "Saftey Award", 254, ""}
|
||||
db.CreateAward(&award)
|
||||
award2, err := db.GetAwardById(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, award, *award2)
|
||||
|
||||
award2.AwardName = "Spirit Award"
|
||||
db.CreateAward(award2)
|
||||
awards, err := db.GetAllAwards()
|
||||
assert.Nil(t, err)
|
||||
if assert.Equal(t, 2, len(awards)) {
|
||||
assert.Equal(t, award, awards[0])
|
||||
assert.Equal(t, *award2, awards[1])
|
||||
}
|
||||
|
||||
award.TeamId = 0
|
||||
award.PersonName = "Travus Cubington"
|
||||
db.SaveAward(&award)
|
||||
award2, err = db.GetAwardById(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, award.TeamId, award2.TeamId)
|
||||
assert.Equal(t, award.PersonName, award2.PersonName)
|
||||
|
||||
db.DeleteAward(&award)
|
||||
award2, err = db.GetAwardById(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, award2)
|
||||
}
|
||||
|
||||
func TestTruncateAwards(t *testing.T) {
|
||||
db := setupTestDb(t)
|
||||
|
||||
award := Award{0, JudgedAward, "Saftey Award", 254, ""}
|
||||
db.CreateAward(&award)
|
||||
db.TruncateAwards()
|
||||
award2, err := db.GetAwardById(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, award2)
|
||||
}
|
||||
|
||||
func TestGetAwardsByType(t *testing.T) {
|
||||
db := setupTestDb(t)
|
||||
|
||||
award1 := Award{0, WinnerAward, "Event Winner", 1114, ""}
|
||||
db.CreateAward(&award1)
|
||||
award2 := Award{0, FinalistAward, "Event Finalist", 2056, ""}
|
||||
db.CreateAward(&award2)
|
||||
award3 := Award{0, JudgedAward, "Saftey Award", 254, ""}
|
||||
db.CreateAward(&award3)
|
||||
award4 := Award{0, WinnerAward, "Event Winner", 254, ""}
|
||||
db.CreateAward(&award4)
|
||||
|
||||
awards, err := db.GetAwardsByType(JudgedAward)
|
||||
assert.Nil(t, err)
|
||||
if assert.Equal(t, 1, len(awards)) {
|
||||
assert.Equal(t, award3, awards[0])
|
||||
}
|
||||
awards, err = db.GetAwardsByType(FinalistAward)
|
||||
assert.Nil(t, err)
|
||||
if assert.Equal(t, 1, len(awards)) {
|
||||
assert.Equal(t, award2, awards[0])
|
||||
}
|
||||
awards, err = db.GetAwardsByType(WinnerAward)
|
||||
assert.Nil(t, err)
|
||||
if assert.Equal(t, 2, len(awards)) {
|
||||
assert.Equal(t, award1, awards[0])
|
||||
assert.Equal(t, award4, awards[1])
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ type Database struct {
|
||||
lowerThirdMap *modl.DbMap
|
||||
sponsorSlideMap *modl.DbMap
|
||||
scheduleBlockMap *modl.DbMap
|
||||
awardMap *modl.DbMap
|
||||
}
|
||||
|
||||
// Opens the SQLite database at the given path, creating it if it doesn't exist, and runs any pending
|
||||
@@ -124,6 +125,9 @@ func (database *Database) mapTables() {
|
||||
|
||||
database.scheduleBlockMap = modl.NewDbMap(database.db, dialect)
|
||||
database.scheduleBlockMap.AddTableWithName(ScheduleBlock{}, "schedule_blocks").SetKeys(true, "Id")
|
||||
|
||||
database.awardMap = modl.NewDbMap(database.db, dialect)
|
||||
database.awardMap.AddTableWithName(Award{}, "awards").SetKeys(true, "Id")
|
||||
}
|
||||
|
||||
func serializeHelper(target *string, source interface{}) error {
|
||||
|
||||
@@ -10,6 +10,7 @@ type LowerThird struct {
|
||||
TopText string
|
||||
BottomText string
|
||||
DisplayOrder int
|
||||
AwardId int
|
||||
}
|
||||
|
||||
func (database *Database) CreateLowerThird(lowerThird *LowerThird) error {
|
||||
@@ -45,3 +46,16 @@ func (database *Database) GetAllLowerThirds() ([]LowerThird, error) {
|
||||
err := database.lowerThirdMap.Select(&lowerThirds, "SELECT * FROM lower_thirds ORDER BY displayorder")
|
||||
return lowerThirds, err
|
||||
}
|
||||
|
||||
func (database *Database) GetLowerThirdsByAwardId(awardId int) ([]LowerThird, error) {
|
||||
var lowerThirds []LowerThird
|
||||
err := database.lowerThirdMap.Select(&lowerThirds, "SELECT * FROM lower_thirds WHERE awardid = ? ORDER BY id",
|
||||
awardId)
|
||||
return lowerThirds, err
|
||||
}
|
||||
|
||||
func (database *Database) GetNextLowerThirdDisplayOrder() int {
|
||||
var count int
|
||||
_ = database.lowerThirdMap.SelectOne(&count, "SELECT MAX(displayorder) + 1 FROM lower_thirds")
|
||||
return count
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func TestGetNonexistentLowerThird(t *testing.T) {
|
||||
func TestLowerThirdCrud(t *testing.T) {
|
||||
db := setupTestDb(t)
|
||||
|
||||
lowerThird := LowerThird{0, "Top Text", "Bottom Text", 0}
|
||||
lowerThird := LowerThird{0, "Top Text", "Bottom Text", 0, 0}
|
||||
db.CreateLowerThird(&lowerThird)
|
||||
lowerThird2, err := db.GetLowerThirdById(1)
|
||||
assert.Nil(t, err)
|
||||
@@ -40,10 +40,36 @@ func TestLowerThirdCrud(t *testing.T) {
|
||||
func TestTruncateLowerThirds(t *testing.T) {
|
||||
db := setupTestDb(t)
|
||||
|
||||
lowerThird := LowerThird{0, "Top Text", "Bottom Text", 0}
|
||||
lowerThird := LowerThird{0, "Top Text", "Bottom Text", 0, 0}
|
||||
db.CreateLowerThird(&lowerThird)
|
||||
db.TruncateLowerThirds()
|
||||
lowerThird2, err := db.GetLowerThirdById(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, lowerThird2)
|
||||
}
|
||||
|
||||
func TestGetLowerThirdsByAwardId(t *testing.T) {
|
||||
db := setupTestDb(t)
|
||||
lowerThird1 := LowerThird{0, "Top Text", "Bottom Text", 0, 0}
|
||||
db.CreateLowerThird(&lowerThird1)
|
||||
lowerThird2 := LowerThird{0, "Award 1", "", 1, 5}
|
||||
db.CreateLowerThird(&lowerThird2)
|
||||
lowerThird3 := LowerThird{0, "Award 2", "", 2, 2}
|
||||
db.CreateLowerThird(&lowerThird3)
|
||||
lowerThird4 := LowerThird{0, "Award 1", "Award 1 Winner", 3, 5}
|
||||
db.CreateLowerThird(&lowerThird4)
|
||||
nextDisplayOrder := db.GetNextLowerThirdDisplayOrder()
|
||||
assert.Equal(t, 4, nextDisplayOrder)
|
||||
|
||||
lowerThirds, err := db.GetLowerThirdsByAwardId(5)
|
||||
assert.Nil(t, err)
|
||||
if assert.Equal(t, 2, len(lowerThirds)) {
|
||||
assert.Equal(t, lowerThird2, lowerThirds[0])
|
||||
assert.Equal(t, lowerThird4, lowerThirds[1])
|
||||
}
|
||||
lowerThirds, err = db.GetLowerThirdsByAwardId(2)
|
||||
assert.Nil(t, err)
|
||||
if assert.Equal(t, 1, len(lowerThirds)) {
|
||||
assert.Equal(t, lowerThird3, lowerThirds[0])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<li><a href="/setup/settings">Settings</a></li>
|
||||
<li><a href="/setup/teams">Team List</a></li>
|
||||
<li><a href="/setup/schedule">Match Scheduling</a></li>
|
||||
<li><a href="/setup/awards">Awards</a></li>
|
||||
<li><a href="/setup/lower_thirds">Lower Thirds</a></li>
|
||||
<li><a href="/setup/sponsor_slides">Sponsor Slides</a></li>
|
||||
<li><a href="/setup/displays">Display Configuration</a></li>
|
||||
|
||||
62
templates/setup_awards.html
Normal file
62
templates/setup_awards.html
Normal file
@@ -0,0 +1,62 @@
|
||||
{{/*
|
||||
Copyright 2019 Team 254. All Rights Reserved.
|
||||
Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
UI for configuring the awards.
|
||||
*/}}
|
||||
{{define "title"}}Awards Configuration{{end}}
|
||||
{{define "body"}}
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-lg-offset-2">
|
||||
<div class="well">
|
||||
<legend>Awards Configuration</legend>
|
||||
{{range $award := .Awards}}
|
||||
<form class="form-horizontal existing" method="POST">
|
||||
<div class="form-group">
|
||||
<div class="col-lg-8">
|
||||
<input type="hidden" name="id" value="{{$award.Id}}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">Award Name</label>
|
||||
<div class="col-sm-7">
|
||||
<input type="text" class="form-control" name="awardName" value="{{$award.AwardName}}"
|
||||
placeholder="Safety Award">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">Team Awarded</label>
|
||||
<div class="col-sm-7">
|
||||
<select class="form-control" name="teamId">
|
||||
<option value="0">No Team</option>
|
||||
{{range $team := $.Teams}}
|
||||
<option value="{{$team.Id}}"{{if eq $award.TeamId $team.Id}}}} selected{{end}}>
|
||||
{{$team.Id}} - {{$team.Nickname}}
|
||||
</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label">Person Awarded</label>
|
||||
<div class="col-sm-7">
|
||||
<input type="text" class="form-control" name="personName" value="{{$award.PersonName}}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<button type="submit" class="btn btn-info btn-lower-third" name="action" value="save">Save</button>
|
||||
{{if gt $award.Id 0}}
|
||||
<button type="submit" class="btn btn-primary btn-lower-third" name="action" value="delete">
|
||||
Delete
|
||||
</button>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{end}}
|
||||
Winner and Finalist awards will be automatically generated once the playoff tournament is complete.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{define "script"}}
|
||||
{{end}}
|
||||
168
tournament/awards.go
Normal file
168
tournament/awards.go
Normal file
@@ -0,0 +1,168 @@
|
||||
// Copyright 2019 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Functions for managing awards and their associated lower thirds.
|
||||
|
||||
package tournament
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Team254/cheesy-arena/model"
|
||||
)
|
||||
|
||||
// Creates or updates the given award, depending on whether or not it already exists.
|
||||
func CreateOrUpdateAward(database *model.Database, award *model.Award, createIntroLowerThird bool) error {
|
||||
// Validate the award data.
|
||||
if award.AwardName == "" {
|
||||
return fmt.Errorf("Award name cannot be blank.")
|
||||
}
|
||||
var team *model.Team
|
||||
if award.TeamId > 0 {
|
||||
team, _ = database.GetTeamById(award.TeamId)
|
||||
if team == nil {
|
||||
return fmt.Errorf("Team %d is not present at this event.", award.TeamId)
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
if award.Id == 0 {
|
||||
err = database.CreateAward(award)
|
||||
} else {
|
||||
err = database.SaveAward(award)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create or update associated lower thirds.
|
||||
awardIntroLowerThird := model.LowerThird{TopText: award.AwardName, AwardId: award.Id}
|
||||
awardWinnerLowerThird := model.LowerThird{TopText: award.AwardName, BottomText: award.PersonName,
|
||||
AwardId: award.Id}
|
||||
if team != nil {
|
||||
if award.PersonName == "" {
|
||||
awardWinnerLowerThird.BottomText = fmt.Sprintf("Team %d, %s", team.Id, team.Nickname)
|
||||
} else {
|
||||
awardWinnerLowerThird.BottomText = fmt.Sprintf("%s – Team %d, %s", award.PersonName, team.Id,
|
||||
team.Nickname)
|
||||
}
|
||||
}
|
||||
if awardWinnerLowerThird.BottomText == "" {
|
||||
awardWinnerLowerThird.BottomText = "(No awardee assigned yet)"
|
||||
}
|
||||
lowerThirds, err := database.GetLowerThirdsByAwardId(award.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bottomIndex := 0
|
||||
if createIntroLowerThird {
|
||||
if err = createOrUpdateAwardLowerThird(database, &awardIntroLowerThird, lowerThirds, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
bottomIndex++
|
||||
}
|
||||
if err = createOrUpdateAwardLowerThird(database, &awardWinnerLowerThird, lowerThirds, bottomIndex); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deletes the given award and any associated lower thirds.
|
||||
func DeleteAward(database *model.Database, awardId int) error {
|
||||
var award *model.Award
|
||||
award, err := database.GetAwardById(awardId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if award == nil {
|
||||
return fmt.Errorf("Award with ID %d does not exist.", awardId)
|
||||
}
|
||||
if err = database.DeleteAward(award); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete lower thirds.
|
||||
lowerThirds, err := database.GetLowerThirdsByAwardId(award.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, lowerThird := range lowerThirds {
|
||||
if err = database.DeleteLowerThird(&lowerThird); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generates awards and lower thirds for the tournament winners and finalists.
|
||||
func CreateOrUpdateWinnerAndFinalistAwards(database *model.Database, winnerAllianceId, finalistAllianceId int) error {
|
||||
var winnerAllianceTeams, finalistAllianceTeams []model.AllianceTeam
|
||||
var err error
|
||||
if winnerAllianceTeams, err = database.GetTeamsByAlliance(winnerAllianceId); err != nil {
|
||||
return err
|
||||
}
|
||||
if finalistAllianceTeams, err = database.GetTeamsByAlliance(finalistAllianceId); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(winnerAllianceTeams) == 0 || len(finalistAllianceTeams) == 0 {
|
||||
return fmt.Errorf("Input alliances do not contain any teams.")
|
||||
}
|
||||
|
||||
// Clear out any awards that may exist if the final match was scored more than once.
|
||||
winnerAwards, err := database.GetAwardsByType(model.WinnerAward)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
finalistAwards, err := database.GetAwardsByType(model.FinalistAward)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, award := range append(winnerAwards, finalistAwards...) {
|
||||
if err = DeleteAward(database, award.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Create the finalist awards first since they're usually presented first.
|
||||
finalistAward := model.Award{AwardName: "Event Finalist", Type: model.FinalistAward,
|
||||
TeamId: finalistAllianceTeams[0].TeamId}
|
||||
if err = CreateOrUpdateAward(database, &finalistAward, true); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, allianceTeam := range finalistAllianceTeams[1:] {
|
||||
finalistAward.Id = 0
|
||||
finalistAward.TeamId = allianceTeam.TeamId
|
||||
if err = CreateOrUpdateAward(database, &finalistAward, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Create the winner awards.
|
||||
winnerAward := model.Award{AwardName: "Event Winner", Type: model.WinnerAward,
|
||||
TeamId: winnerAllianceTeams[0].TeamId}
|
||||
if err = CreateOrUpdateAward(database, &winnerAward, true); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, allianceTeam := range winnerAllianceTeams[1:] {
|
||||
winnerAward.Id = 0
|
||||
winnerAward.TeamId = allianceTeam.TeamId
|
||||
if err = CreateOrUpdateAward(database, &winnerAward, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createOrUpdateAwardLowerThird(database *model.Database, lowerThird *model.LowerThird,
|
||||
existingLowerThirds []model.LowerThird, index int) error {
|
||||
if index < len(existingLowerThirds) {
|
||||
lowerThird.Id = existingLowerThirds[index].Id
|
||||
lowerThird.DisplayOrder = existingLowerThirds[index].DisplayOrder
|
||||
return database.SaveLowerThird(lowerThird)
|
||||
} else {
|
||||
lowerThird.DisplayOrder = database.GetNextLowerThirdDisplayOrder()
|
||||
return database.CreateLowerThird(lowerThird)
|
||||
}
|
||||
}
|
||||
146
tournament/awards_test.go
Normal file
146
tournament/awards_test.go
Normal file
@@ -0,0 +1,146 @@
|
||||
// Copyright 2019 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package tournament
|
||||
|
||||
import (
|
||||
"github.com/Team254/cheesy-arena/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCreateOrUpdateAwardWithIntro(t *testing.T) {
|
||||
database := setupTestDb(t)
|
||||
database.CreateTeam(&model.Team{Id: 254, Nickname: "Teh Chezy Pofs"})
|
||||
|
||||
award := model.Award{0, model.JudgedAward, "Safety Award", 0, ""}
|
||||
err := CreateOrUpdateAward(database, &award, true)
|
||||
assert.Nil(t, err)
|
||||
award2, _ := database.GetAwardById(award.Id)
|
||||
assert.Equal(t, award, *award2)
|
||||
lowerThirds, _ := database.GetAllLowerThirds()
|
||||
if assert.Equal(t, 2, len(lowerThirds)) {
|
||||
assert.Equal(t, "Safety Award", lowerThirds[0].TopText)
|
||||
assert.Equal(t, "", lowerThirds[0].BottomText)
|
||||
assert.Equal(t, "Safety Award", lowerThirds[1].TopText)
|
||||
assert.Equal(t, "(No awardee assigned yet)", lowerThirds[1].BottomText)
|
||||
}
|
||||
|
||||
award.AwardName = "Saftey Award"
|
||||
award.TeamId = 254
|
||||
err = CreateOrUpdateAward(database, &award, true)
|
||||
assert.Nil(t, err)
|
||||
award2, _ = database.GetAwardById(award.Id)
|
||||
assert.Equal(t, award, *award2)
|
||||
lowerThirds, _ = database.GetAllLowerThirds()
|
||||
if assert.Equal(t, 2, len(lowerThirds)) {
|
||||
assert.Equal(t, "Saftey Award", lowerThirds[0].TopText)
|
||||
assert.Equal(t, "", lowerThirds[0].BottomText)
|
||||
assert.Equal(t, "Saftey Award", lowerThirds[1].TopText)
|
||||
assert.Equal(t, "Team 254, Teh Chezy Pofs", lowerThirds[1].BottomText)
|
||||
}
|
||||
|
||||
err = DeleteAward(database, award.Id)
|
||||
assert.Nil(t, err)
|
||||
award2, _ = database.GetAwardById(award.Id)
|
||||
assert.Nil(t, award2)
|
||||
lowerThirds, _ = database.GetAllLowerThirds()
|
||||
assert.Empty(t, lowerThirds)
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateAwardWithoutIntro(t *testing.T) {
|
||||
database := setupTestDb(t)
|
||||
database.CreateTeam(&model.Team{Id: 254, Nickname: "Teh Chezy Pofs"})
|
||||
otherLowerThird := model.LowerThird{TopText: "Marco", BottomText: "Polo"}
|
||||
database.CreateLowerThird(&otherLowerThird)
|
||||
|
||||
award := model.Award{0, model.WinnerAward, "Event Winner", 0, "Bob Dorough"}
|
||||
err := CreateOrUpdateAward(database, &award, false)
|
||||
assert.Nil(t, err)
|
||||
award2, _ := database.GetAwardById(award.Id)
|
||||
assert.Equal(t, award, *award2)
|
||||
lowerThirds, _ := database.GetAllLowerThirds()
|
||||
if assert.Equal(t, 2, len(lowerThirds)) {
|
||||
assert.Equal(t, otherLowerThird, lowerThirds[0])
|
||||
assert.Equal(t, "Event Winner", lowerThirds[1].TopText)
|
||||
assert.Equal(t, "Bob Dorough", lowerThirds[1].BottomText)
|
||||
}
|
||||
|
||||
award.TeamId = 254
|
||||
err = CreateOrUpdateAward(database, &award, false)
|
||||
assert.Nil(t, err)
|
||||
award2, _ = database.GetAwardById(award.Id)
|
||||
assert.Equal(t, award, *award2)
|
||||
lowerThirds, _ = database.GetAllLowerThirds()
|
||||
if assert.Equal(t, 2, len(lowerThirds)) {
|
||||
assert.Equal(t, otherLowerThird, lowerThirds[0])
|
||||
assert.Equal(t, "Event Winner", lowerThirds[1].TopText)
|
||||
assert.Equal(t, "Bob Dorough – Team 254, Teh Chezy Pofs", lowerThirds[1].BottomText)
|
||||
}
|
||||
|
||||
err = DeleteAward(database, award.Id)
|
||||
assert.Nil(t, err)
|
||||
award2, _ = database.GetAwardById(award.Id)
|
||||
assert.Nil(t, award2)
|
||||
lowerThirds, _ = database.GetAllLowerThirds()
|
||||
if assert.Equal(t, 1, len(lowerThirds)) {
|
||||
assert.Equal(t, otherLowerThird, lowerThirds[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateWinnerAndFinalistAwards(t *testing.T) {
|
||||
database := setupTestDb(t)
|
||||
CreateTestAlliances(database, 2)
|
||||
database.CreateTeam(&model.Team{Id: 1})
|
||||
database.CreateTeam(&model.Team{Id: 10})
|
||||
database.CreateTeam(&model.Team{Id: 100})
|
||||
database.CreateTeam(&model.Team{Id: 2})
|
||||
database.CreateTeam(&model.Team{Id: 20})
|
||||
database.CreateTeam(&model.Team{Id: 200})
|
||||
|
||||
err := CreateOrUpdateWinnerAndFinalistAwards(database, 2, 1)
|
||||
assert.Nil(t, err)
|
||||
awards, _ := database.GetAllAwards()
|
||||
if assert.Equal(t, 6, len(awards)) {
|
||||
assert.Equal(t, model.Award{1, model.FinalistAward, "Event Finalist", 1, ""}, awards[0])
|
||||
assert.Equal(t, model.Award{2, model.FinalistAward, "Event Finalist", 10, ""}, awards[1])
|
||||
assert.Equal(t, model.Award{3, model.FinalistAward, "Event Finalist", 100, ""}, awards[2])
|
||||
assert.Equal(t, model.Award{4, model.WinnerAward, "Event Winner", 2, ""}, awards[3])
|
||||
assert.Equal(t, model.Award{5, model.WinnerAward, "Event Winner", 20, ""}, awards[4])
|
||||
assert.Equal(t, model.Award{6, model.WinnerAward, "Event Winner", 200, ""}, awards[5])
|
||||
}
|
||||
lowerThirds, _ := database.GetAllLowerThirds()
|
||||
if assert.Equal(t, 8, len(lowerThirds)) {
|
||||
assert.Equal(t, "Event Finalist", lowerThirds[0].TopText)
|
||||
assert.Equal(t, "", lowerThirds[0].BottomText)
|
||||
assert.Equal(t, "Event Finalist", lowerThirds[1].TopText)
|
||||
assert.Equal(t, "Team 1, ", lowerThirds[1].BottomText)
|
||||
assert.Equal(t, "Event Winner", lowerThirds[4].TopText)
|
||||
assert.Equal(t, "", lowerThirds[4].BottomText)
|
||||
assert.Equal(t, "Event Winner", lowerThirds[5].TopText)
|
||||
assert.Equal(t, "Team 2, ", lowerThirds[5].BottomText)
|
||||
}
|
||||
|
||||
err = CreateOrUpdateWinnerAndFinalistAwards(database, 1, 2)
|
||||
assert.Nil(t, err)
|
||||
awards, _ = database.GetAllAwards()
|
||||
if assert.Equal(t, 6, len(awards)) {
|
||||
assert.Equal(t, model.Award{1, model.FinalistAward, "Event Finalist", 2, ""}, awards[0])
|
||||
assert.Equal(t, model.Award{2, model.FinalistAward, "Event Finalist", 20, ""}, awards[1])
|
||||
assert.Equal(t, model.Award{3, model.FinalistAward, "Event Finalist", 200, ""}, awards[2])
|
||||
assert.Equal(t, model.Award{4, model.WinnerAward, "Event Winner", 1, ""}, awards[3])
|
||||
assert.Equal(t, model.Award{5, model.WinnerAward, "Event Winner", 10, ""}, awards[4])
|
||||
assert.Equal(t, model.Award{6, model.WinnerAward, "Event Winner", 100, ""}, awards[5])
|
||||
}
|
||||
lowerThirds, _ = database.GetAllLowerThirds()
|
||||
if assert.Equal(t, 8, len(lowerThirds)) {
|
||||
assert.Equal(t, "Event Finalist", lowerThirds[0].TopText)
|
||||
assert.Equal(t, "", lowerThirds[0].BottomText)
|
||||
assert.Equal(t, "Event Finalist", lowerThirds[1].TopText)
|
||||
assert.Equal(t, "Team 2, ", lowerThirds[1].BottomText)
|
||||
assert.Equal(t, "Event Winner", lowerThirds[4].TopText)
|
||||
assert.Equal(t, "", lowerThirds[4].BottomText)
|
||||
assert.Equal(t, "Event Winner", lowerThirds[5].TopText)
|
||||
assert.Equal(t, "Team 1, ", lowerThirds[5].BottomText)
|
||||
}
|
||||
}
|
||||
@@ -377,11 +377,27 @@ func (web *Web) commitMatchScore(match *model.Match, matchResult *model.MatchRes
|
||||
|
||||
if match.ShouldUpdateEliminationMatches() {
|
||||
// Generate any subsequent elimination matches.
|
||||
_, err = tournament.UpdateEliminationSchedule(web.arena.Database,
|
||||
isTournamentWon, err := tournament.UpdateEliminationSchedule(web.arena.Database,
|
||||
time.Now().Add(time.Second*tournament.ElimMatchSpacingSec))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate awards if the tournament is over.
|
||||
if isTournamentWon {
|
||||
var winnerAllianceId, finalistAllianceId int
|
||||
if match.Winner == "R" {
|
||||
winnerAllianceId = match.ElimRedAlliance
|
||||
finalistAllianceId = match.ElimBlueAlliance
|
||||
} else if match.Winner == "B" {
|
||||
winnerAllianceId = match.ElimBlueAlliance
|
||||
finalistAllianceId = match.ElimRedAlliance
|
||||
}
|
||||
if err = tournament.CreateOrUpdateWinnerAndFinalistAwards(web.arena.Database, winnerAllianceId,
|
||||
finalistAllianceId); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if web.arena.EventSettings.TbaPublishingEnabled && match.Type != "practice" {
|
||||
|
||||
75
web/setup_awards.go
Normal file
75
web/setup_awards.go
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright 2019 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Web routes for managing awards.
|
||||
|
||||
package web
|
||||
|
||||
import (
|
||||
"github.com/Team254/cheesy-arena/model"
|
||||
"github.com/Team254/cheesy-arena/tournament"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Shows the awards configuration page.
|
||||
func (web *Web) awardsGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !web.userIsAdmin(w, r) {
|
||||
return
|
||||
}
|
||||
|
||||
template, err := web.parseFiles("templates/setup_awards.html", "templates/base.html")
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
awards, err := web.arena.Database.GetAllAwards()
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
teams, err := web.arena.Database.GetAllTeams()
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Append a blank award to the end that can be used to add a new one.
|
||||
awards = append(awards, model.Award{})
|
||||
|
||||
data := struct {
|
||||
*model.EventSettings
|
||||
Awards []model.Award
|
||||
Teams []model.Team
|
||||
}{web.arena.EventSettings, awards, teams}
|
||||
err = template.ExecuteTemplate(w, "base", data)
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Saves the new or modified awards to the database.
|
||||
func (web *Web) awardsPostHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !web.userIsAdmin(w, r) {
|
||||
return
|
||||
}
|
||||
|
||||
awardId, _ := strconv.Atoi(r.PostFormValue("id"))
|
||||
if r.PostFormValue("action") == "delete" {
|
||||
if err := tournament.DeleteAward(web.arena.Database, awardId); err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
teamId, _ := strconv.Atoi(r.PostFormValue("teamId"))
|
||||
award := model.Award{Id: awardId, Type: model.JudgedAward, AwardName: r.PostFormValue("awardName"),
|
||||
TeamId: teamId, PersonName: r.PostFormValue("personName")}
|
||||
if err := tournament.CreateOrUpdateAward(web.arena.Database, &award, true); err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/setup/awards", 303)
|
||||
}
|
||||
35
web/setup_awards_test.go
Normal file
35
web/setup_awards_test.go
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2019 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package web
|
||||
|
||||
import (
|
||||
"github.com/Team254/cheesy-arena/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSetupAwards(t *testing.T) {
|
||||
web := setupTestWeb(t)
|
||||
|
||||
web.arena.Database.CreateAward(&model.Award{0, model.JudgedAward, "Spirit Award", 0, ""})
|
||||
web.arena.Database.CreateAward(&model.Award{0, model.JudgedAward, "Saftey Award", 0, ""})
|
||||
|
||||
recorder := web.getHttpResponse("/setup/awards")
|
||||
assert.Equal(t, 200, recorder.Code)
|
||||
assert.Contains(t, recorder.Body.String(), "Spirit Award")
|
||||
assert.Contains(t, recorder.Body.String(), "Saftey Award")
|
||||
|
||||
recorder = web.postHttpResponse("/setup/awards", "action=delete&id=1")
|
||||
assert.Equal(t, 303, recorder.Code)
|
||||
recorder = web.getHttpResponse("/setup/awards")
|
||||
assert.Equal(t, 200, recorder.Code)
|
||||
assert.NotContains(t, recorder.Body.String(), "Spirit Award")
|
||||
assert.Contains(t, recorder.Body.String(), "Saftey Award")
|
||||
|
||||
recorder = web.postHttpResponse("/setup/awards", "awardId=2&awardName=Saftey+Award&personName=Englebert")
|
||||
assert.Equal(t, 303, recorder.Code)
|
||||
recorder = web.getHttpResponse("/setup/awards")
|
||||
assert.Equal(t, 200, recorder.Code)
|
||||
assert.Contains(t, recorder.Body.String(), "Englebert")
|
||||
}
|
||||
@@ -149,6 +149,7 @@ func (web *Web) saveLowerThird(lowerThird *model.LowerThird) error {
|
||||
|
||||
// Create or update lower third.
|
||||
if oldLowerThird == nil {
|
||||
lowerThird.DisplayOrder = web.arena.Database.GetNextLowerThirdDisplayOrder()
|
||||
err = web.arena.Database.CreateLowerThird(lowerThird)
|
||||
} else {
|
||||
err = web.arena.Database.SaveLowerThird(lowerThird)
|
||||
|
||||
@@ -15,9 +15,9 @@ import (
|
||||
func TestSetupLowerThirds(t *testing.T) {
|
||||
web := setupTestWeb(t)
|
||||
|
||||
web.arena.Database.CreateLowerThird(&model.LowerThird{0, "Top Text 1", "Bottom Text 1", 0})
|
||||
web.arena.Database.CreateLowerThird(&model.LowerThird{0, "Top Text 2", "Bottom Text 2", 1})
|
||||
web.arena.Database.CreateLowerThird(&model.LowerThird{0, "Top Text 3", "Bottom Text 3", 2})
|
||||
web.arena.Database.CreateLowerThird(&model.LowerThird{0, "Top Text 1", "Bottom Text 1", 0, 0})
|
||||
web.arena.Database.CreateLowerThird(&model.LowerThird{0, "Top Text 2", "Bottom Text 2", 1, 0})
|
||||
web.arena.Database.CreateLowerThird(&model.LowerThird{0, "Top Text 3", "Bottom Text 3", 2, 0})
|
||||
|
||||
recorder := web.getHttpResponse("/setup/lower_thirds")
|
||||
assert.Equal(t, 200, recorder.Code)
|
||||
@@ -31,24 +31,24 @@ func TestSetupLowerThirds(t *testing.T) {
|
||||
defer conn.Close()
|
||||
ws := websocket.NewTestWebsocket(conn)
|
||||
|
||||
ws.Write("saveLowerThird", model.LowerThird{1, "Top Text 4", "Bottom Text 1", 0})
|
||||
ws.Write("saveLowerThird", model.LowerThird{1, "Top Text 4", "Bottom Text 1", 0, 0})
|
||||
time.Sleep(time.Millisecond * 10) // Allow some time for the command to be processed.
|
||||
lowerThird, _ := web.arena.Database.GetLowerThirdById(1)
|
||||
assert.Equal(t, "Top Text 4", lowerThird.TopText)
|
||||
|
||||
ws.Write("deleteLowerThird", model.LowerThird{1, "Top Text 4", "Bottom Text 1", 0})
|
||||
ws.Write("deleteLowerThird", model.LowerThird{1, "Top Text 4", "Bottom Text 1", 0, 0})
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
lowerThird, _ = web.arena.Database.GetLowerThirdById(1)
|
||||
assert.Nil(t, lowerThird)
|
||||
|
||||
assert.Equal(t, "blank", web.arena.AudienceDisplayMode)
|
||||
ws.Write("showLowerThird", model.LowerThird{2, "Top Text 5", "Bottom Text 1", 0})
|
||||
ws.Write("showLowerThird", model.LowerThird{2, "Top Text 5", "Bottom Text 1", 0, 0})
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
lowerThird, _ = web.arena.Database.GetLowerThirdById(2)
|
||||
assert.Equal(t, "Top Text 5", lowerThird.TopText)
|
||||
assert.Equal(t, "lowerThird", web.arena.AudienceDisplayMode)
|
||||
|
||||
ws.Write("hideLowerThird", model.LowerThird{2, "Top Text 6", "Bottom Text 1", 0})
|
||||
ws.Write("hideLowerThird", model.LowerThird{2, "Top Text 6", "Bottom Text 1", 0, 0})
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
lowerThird, _ = web.arena.Database.GetLowerThirdById(2)
|
||||
assert.Equal(t, "Top Text 6", lowerThird.TopText)
|
||||
|
||||
@@ -183,6 +183,8 @@ func (web *Web) newHandler() http.Handler {
|
||||
router.HandleFunc("/reports/csv/teams", web.teamsCsvReportHandler).Methods("GET")
|
||||
router.HandleFunc("/reports/pdf/teams", web.teamsPdfReportHandler).Methods("GET")
|
||||
router.HandleFunc("/reports/csv/wpa_keys", web.wpaKeysCsvReportHandler).Methods("GET")
|
||||
router.HandleFunc("/setup/awards", web.awardsGetHandler).Methods("GET")
|
||||
router.HandleFunc("/setup/awards", web.awardsPostHandler).Methods("POST")
|
||||
router.HandleFunc("/setup/db/clear", web.clearDbHandler).Methods("POST")
|
||||
router.HandleFunc("/setup/db/restore", web.restoreDbHandler).Methods("POST")
|
||||
router.HandleFunc("/setup/db/save", web.saveDbHandler).Methods("GET")
|
||||
|
||||
Reference in New Issue
Block a user