Files
mixmaker/backend/internal/domain/bracket_test.go
lemintare a311b7761d
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / compose (push) Has been cancelled
Refactor bracket validation logic to support draft state
This commit updates the bracket validation process by introducing a new `ValidateDraft` method, allowing for incomplete edits in the draft state. The existing `Validate` method has been modified to enforce complete validation only upon confirmation. Additionally, new tests have been added to ensure that incomplete drafts are accepted until confirmation, while still rejecting invalid references. Documentation has been updated to reflect these changes in the API and architecture.
2026-07-19 13:43:25 +03:00

83 lines
3.0 KiB
Go

package domain
import "testing"
func TestThreeTeamBracketResolvesWinnerAndLoserFeeds(t *testing.T) {
draft, err := NewBracketDraft("event", []string{"a", "b", "c"})
if err != nil {
t.Fatal(err)
}
tournament, err := NewGraphTournament("cup", "event", "Cup", *draft)
if err != nil {
t.Fatal(err)
}
ready := tournament.ReadyMatches()
if len(ready) != 1 || ready[0].TeamAID != "a" || ready[0].TeamBID != "b" {
t.Fatalf("unexpected first match: %#v", ready)
}
if err = tournament.ApplySeries(Series{ID: ready[0].ID, TeamAID: "a", TeamBID: "b", WinnerTeamID: "a"}); err != nil {
t.Fatal(err)
}
ready = tournament.ReadyMatches()
if len(ready) != 1 || ready[0].TeamAID != "b" || ready[0].TeamBID != "c" {
t.Fatalf("loser feed was not resolved: %#v", ready)
}
if err = tournament.ApplySeries(Series{ID: ready[0].ID, TeamAID: "b", TeamBID: "c", WinnerTeamID: "c"}); err != nil {
t.Fatal(err)
}
ready = tournament.ReadyMatches()
if len(ready) != 1 || ready[0].TeamAID != "a" || ready[0].TeamBID != "c" {
t.Fatalf("final feed was not resolved: %#v", ready)
}
if err = tournament.ApplySeries(Series{ID: ready[0].ID, TeamAID: "a", TeamBID: "c", WinnerTeamID: "c"}); err != nil {
t.Fatal(err)
}
if !tournament.Complete() || tournament.WinnerTeamID != "c" {
t.Fatalf("unexpected champion: %q", tournament.WinnerTeamID)
}
}
func TestBracketRejectsForwardReferencesAndMultipleFinals(t *testing.T) {
draft := BracketDraft{
EventID: "event", TeamIDs: []string{"a", "b"},
Matches: []BracketMatch{
{ID: "m1", Round: 0, SlotA: SlotSource{Kind: SlotWinner, MatchID: "m2"}, SlotB: SlotSource{Kind: SlotTeam, TeamID: "a"}},
{ID: "m2", Round: 0, Order: 1, SlotA: SlotSource{Kind: SlotTeam, TeamID: "a"}, SlotB: SlotSource{Kind: SlotTeam, TeamID: "b"}},
},
}
if err := draft.Validate(); err == nil {
t.Fatal("expected invalid graph")
}
}
func TestBracketDraftAllowsIncompleteEditsUntilConfirmation(t *testing.T) {
draft := BracketDraft{
EventID: "event", TeamIDs: []string{"a", "b"},
Matches: []BracketMatch{
{ID: "m1", Round: 0, SlotA: SlotSource{Kind: SlotTeam, TeamID: "a"}, SlotB: SlotSource{Kind: SlotTeam, TeamID: "b"}},
{ID: "m2", Round: 1, SlotA: SlotSource{Kind: SlotWinner, MatchID: "m1"}, SlotB: SlotSource{Kind: SlotTeam}},
{ID: "m3", Round: 1, Order: 1, SlotA: SlotSource{Kind: SlotTeam, TeamID: "a"}, SlotB: SlotSource{Kind: SlotTeam, TeamID: "a"}},
},
}
if err := draft.ValidateDraft(); err != nil {
t.Fatalf("incomplete editable draft was rejected: %v", err)
}
if err := draft.Validate(); err == nil {
t.Fatal("expected incomplete bracket to be rejected at confirmation")
}
}
func TestBracketDraftStillRejectsInvalidReferences(t *testing.T) {
draft := BracketDraft{
EventID: "event", TeamIDs: []string{"a", "b"},
Matches: []BracketMatch{
{ID: "m1", Round: 0, SlotA: SlotSource{Kind: SlotWinner, MatchID: "missing"}, SlotB: SlotSource{Kind: SlotTeam}},
},
}
if err := draft.ValidateDraft(); err == nil {
t.Fatal("expected invalid match reference to be rejected")
}
}