diff --git a/web/alliance_selection.go b/web/alliance_selection.go index 9f817d7..765659f 100755 --- a/web/alliance_selection.go +++ b/web/alliance_selection.go @@ -137,8 +137,27 @@ func (web *Web) allianceSelectionResetHandler(w http.ResponseWriter, r *http.Req return } - if !web.canModifyAllianceSelection() { - web.renderAllianceSelection(w, r, "Alliance selection has already been finalized.") + if !web.canResetAllianceSelection() { + web.renderAllianceSelection(w, r, "Cannot reset alliance selection; playoff matches have already started.") + return + } + + // Delete any elimination matches that were already created (but not played since they would fail the above check). + matches, err := web.arena.Database.GetMatchesByType("elimination") + if err != nil { + handleWebErr(w, err) + return + } + for _, match := range matches { + if err = web.arena.Database.DeleteMatch(match.Id); err != nil { + handleWebErr(w, err) + return + } + } + + // Delete the saved alliances. + if err = web.arena.Database.TruncateAllianceTeams(); err != nil { + handleWebErr(w, err) return } @@ -233,8 +252,9 @@ func (web *Web) allianceSelectionPublishHandler(w http.ResponseWriter, r *http.R } func (web *Web) renderAllianceSelection(w http.ResponseWriter, r *http.Request, errorMessage string) { - if len(web.arena.AllianceSelectionAlliances) == 0 && !web.canModifyAllianceSelection() { - // The application was restarted since the alliance selection was conducted; reload the alliances from the DB. + if len(web.arena.AllianceSelectionAlliances) == 0 { + // The application may have been restarted since the alliance selection was conducted; try reloading the + // alliances from the DB. var err error web.arena.AllianceSelectionAlliances, err = web.arena.Database.GetAllAlliances() if err != nil { @@ -273,6 +293,20 @@ func (web *Web) canModifyAllianceSelection() bool { return true } +// Returns true if it is safe to reset the alliance selection (i.e. no elimination matches have been played yet). +func (web *Web) canResetAllianceSelection() bool { + matches, err := web.arena.Database.GetMatchesByType("elimination") + if err != nil { + return false + } + for _, match := range matches { + if match.Status != model.MatchNotPlayed { + return false + } + } + return true +} + // Returns the row and column of the next alliance selection spot that should have keyboard autofocus. func (web *Web) determineNextCell() (int, int) { // Check the first two columns. diff --git a/web/alliance_selection_test.go b/web/alliance_selection_test.go index 390da07..a4ea0a5 100644 --- a/web/alliance_selection_test.go +++ b/web/alliance_selection_test.go @@ -141,9 +141,6 @@ func TestAllianceSelectionErrors(t *testing.T) { recorder = web.postHttpResponse("/alliance_selection/finalize", "startTime=2014-01-01 01:00:00 PM") assert.Equal(t, 200, recorder.Code) assert.Contains(t, recorder.Body.String(), "already been finalized") - recorder = web.postHttpResponse("/alliance_selection/reset", "") - assert.Equal(t, 200, recorder.Code) - assert.Contains(t, recorder.Body.String(), "already been finalized") recorder = web.postHttpResponse("/alliance_selection", "selection0_0=asdf") assert.Equal(t, 200, recorder.Code) assert.Contains(t, recorder.Body.String(), "already been finalized") @@ -154,6 +151,62 @@ func TestAllianceSelectionErrors(t *testing.T) { assert.Contains(t, recorder.Body.String(), "already been finalized") } +func TestAllianceSelectionReset(t *testing.T) { + web := setupTestWeb(t) + + web.arena.AllianceSelectionAlliances = [][]model.AllianceTeam{} + cachedRankedTeams = []*RankedTeam{} + web.arena.EventSettings.NumElimAlliances = 2 + for i := 1; i <= 6; i++ { + web.arena.Database.CreateRanking(&game.Ranking{TeamId: 100 + i, Rank: i}) + } + + // Start, populate, and finalize the alliance selection. + recorder := web.postHttpResponse("/alliance_selection/start", "") + assert.Equal(t, 303, recorder.Code) + recorder = web.postHttpResponse("/alliance_selection", "selection0_0=101&selection0_1=102&selection0_2=103&"+ + "selection1_0=104&selection1_1=105&selection1_2=106") + assert.Equal(t, 303, recorder.Code) + recorder = web.postHttpResponse("/alliance_selection/finalize", "startTime=2014-01-01 01:00:00 PM") + assert.Equal(t, 303, recorder.Code) + alliances, _ := web.arena.Database.GetAllAlliances() + assert.NotEmpty(t, alliances) + matches, _ := web.arena.Database.GetMatchesByType("elimination") + assert.NotEmpty(t, matches) + + // Reset the alliance selection before any matches have been played. + recorder = web.postHttpResponse("/alliance_selection/reset", "") + assert.Equal(t, 303, recorder.Code) + alliances, _ = web.arena.Database.GetAllAlliances() + assert.Empty(t, alliances) + matches, _ = web.arena.Database.GetMatchesByType("elimination") + assert.Empty(t, matches) + + // Start, populate, and finalize the alliance selection again. + recorder = web.postHttpResponse("/alliance_selection/start", "") + assert.Equal(t, 303, recorder.Code) + recorder = web.postHttpResponse("/alliance_selection", "selection0_0=101&selection0_1=102&selection0_2=103&"+ + "selection1_0=104&selection1_1=105&selection1_2=106") + assert.Equal(t, 303, recorder.Code) + recorder = web.postHttpResponse("/alliance_selection/finalize", "startTime=2014-01-01 01:00:00 PM") + assert.Equal(t, 303, recorder.Code) + alliances, _ = web.arena.Database.GetAllAlliances() + assert.NotEmpty(t, alliances) + matches, _ = web.arena.Database.GetMatchesByType("elimination") + assert.NotEmpty(t, matches) + + // Mark a match as played and verify that the alliance selection can no longer be reset. + matches[0].Status = model.RedWonMatch + assert.Nil(t, web.arena.Database.UpdateMatch(&matches[0])) + recorder = web.postHttpResponse("/alliance_selection/reset", "") + assert.Equal(t, 200, recorder.Code) + assert.Contains(t, recorder.Body.String(), "matches have already started") + alliances, _ = web.arena.Database.GetAllAlliances() + assert.NotEmpty(t, alliances) + matches, _ = web.arena.Database.GetMatchesByType("elimination") + assert.NotEmpty(t, matches) +} + func TestAllianceSelectionAutofocus(t *testing.T) { web := setupTestWeb(t)