diff --git a/internal/services/result/eval.go b/internal/services/result/eval.go index 6874036..3adec6b 100644 --- a/internal/services/result/eval.go +++ b/internal/services/result/eval.go @@ -126,11 +126,12 @@ func evaluateAsianHandicap(outcome domain.BetOutcome, score struct{ Home, Away i fmt.Printf("multi outcome check error") return domain.OUTCOME_STATUS_PENDING, err } - } - newOutcome, err = checkMultiOutcome(newOutcome, domain.OUTCOME_STATUS_LOSS) - if err != nil { - fmt.Printf("multi outcome check error") - return domain.OUTCOME_STATUS_PENDING, err + } else { + newOutcome, err = checkMultiOutcome(newOutcome, domain.OUTCOME_STATUS_LOSS) + if err != nil { + fmt.Printf("multi outcome check error") + return domain.OUTCOME_STATUS_PENDING, err + } } } else if adjustedHomeScore < adjustedAwayScore { if outcome.OddHeader == "2" { @@ -139,18 +140,21 @@ func evaluateAsianHandicap(outcome domain.BetOutcome, score struct{ Home, Away i fmt.Printf("multi outcome check error") return domain.OUTCOME_STATUS_PENDING, err } + } else { + newOutcome, err = checkMultiOutcome(newOutcome, domain.OUTCOME_STATUS_LOSS) + if err != nil { + fmt.Printf("multi outcome check error") + return domain.OUTCOME_STATUS_PENDING, err + } } - newOutcome, err = checkMultiOutcome(newOutcome, domain.OUTCOME_STATUS_LOSS) + } + if newOutcome == domain.OUTCOME_STATUS_PENDING { + newOutcome, err = checkMultiOutcome(newOutcome, domain.OUTCOME_STATUS_VOID) if err != nil { fmt.Printf("multi outcome check error") return domain.OUTCOME_STATUS_PENDING, err } } - newOutcome, err = checkMultiOutcome(newOutcome, domain.OUTCOME_STATUS_VOID) - if err != nil { - fmt.Printf("multi outcome check error") - return domain.OUTCOME_STATUS_PENDING, err - } } return newOutcome, nil } @@ -434,6 +438,10 @@ func evaluateResultAndBTTSX(outcome domain.BetOutcome, score struct{ Home, Away return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid threshold: %s", outcome.OddHeader) } + // above code removes any space from team name, so do the same for outcome.HomeTeamName and outcome.AwayTeamName + outcome.HomeTeamName = strings.Join(strings.Split(outcome.HomeTeamName, " "), "") + outcome.AwayTeamName = strings.Join(strings.Split(outcome.AwayTeamName, " "), "") + switch teamName { case outcome.HomeTeamName: if score.Home > score.Away { @@ -505,18 +513,18 @@ func evaluateMoneyLine3Way(outcome domain.BetOutcome, score struct{ Home, Away i } } -func evaluateDoubleResult(outcome domain.BetOutcome, firstHalfScore struct{ Home, Away int }, secondHalfScore struct{ Home, Away int }) (domain.OutcomeStatus, error) { +func evaluateDoubleResult(outcome domain.BetOutcome, firstHalfScore struct{ Home, Away int }, fullTimeScore struct{ Home, Away int }) (domain.OutcomeStatus, error) { halfWins := strings.Split(outcome.OddName, "-") if len(halfWins) != 2 { return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd name: %s", outcome.OddName) } firstHalfWinner := strings.TrimSpace(halfWins[0]) - secondHalfWinner := strings.TrimSpace(halfWins[1]) + fullTimeWinner := strings.TrimSpace(halfWins[1]) if firstHalfWinner != outcome.HomeTeamName && firstHalfWinner != outcome.AwayTeamName && firstHalfWinner != "Tie" { return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", firstHalfWinner) } - if secondHalfWinner != outcome.HomeTeamName && secondHalfWinner != outcome.AwayTeamName && secondHalfWinner != "Tie" { + if fullTimeWinner != outcome.HomeTeamName && fullTimeWinner != outcome.AwayTeamName && fullTimeWinner != "Tie" { return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", firstHalfWinner) } @@ -530,11 +538,11 @@ func evaluateDoubleResult(outcome domain.BetOutcome, firstHalfScore struct{ Home } switch { - case secondHalfWinner == outcome.HomeTeamName && firstHalfScore.Home < firstHalfScore.Away: + case fullTimeWinner == outcome.HomeTeamName && fullTimeScore.Home < fullTimeScore.Away: return domain.OUTCOME_STATUS_LOSS, nil - case secondHalfWinner == outcome.AwayTeamName && firstHalfScore.Away < firstHalfScore.Home: + case fullTimeWinner == outcome.AwayTeamName && fullTimeScore.Away < fullTimeScore.Home: return domain.OUTCOME_STATUS_LOSS, nil - case secondHalfWinner == "Tie" && firstHalfScore.Home != firstHalfScore.Away: + case fullTimeWinner == "Tie" && fullTimeScore.Home != fullTimeScore.Away: return domain.OUTCOME_STATUS_LOSS, nil } @@ -624,10 +632,12 @@ func evaluateHandicapAndTotal(outcome domain.BetOutcome, score struct{ Home, Awa } teamName := strings.TrimSpace(strings.Join(nameSplit[:len(nameSplit)-4], "")) - adjustedHomeScore := float64(score.Home) adjustedAwayScore := float64(score.Away) + outcome.HomeTeamName = strings.Join(strings.Split(outcome.HomeTeamName, " "), "") + outcome.AwayTeamName = strings.Join(strings.Split(outcome.AwayTeamName, " "), "") + switch teamName { case outcome.HomeTeamName: adjustedHomeScore += handicap @@ -648,21 +658,22 @@ func evaluateHandicapAndTotal(outcome domain.BetOutcome, score struct{ Home, Awa } func evaluateWinningMargin(outcome domain.BetOutcome, score struct{ Home, Away int }) (domain.OutcomeStatus, error) { - - marginSplit := strings.Split(outcome.OddName, "") - if len(marginSplit) < 1 { - return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", outcome.OddName) - } - - margin, err := strconv.ParseInt(marginSplit[0], 10, 64) - if err != nil { + if len(outcome.OddName) < 1 { return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", outcome.OddName) } isGtr := false - if len(marginSplit) == 2 { - isGtr = marginSplit[1] == "+" + idx := len(outcome.OddName) + if outcome.OddName[idx-1] == '+' { + isGtr = true + idx-- } + + margin, err := strconv.ParseInt(outcome.OddName[:idx], 10, 64) + if err != nil { + return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", outcome.OddName) + } + switch outcome.OddHeader { case "1": if score.Home == (score.Away + int(margin)) { @@ -672,9 +683,9 @@ func evaluateWinningMargin(outcome domain.BetOutcome, score struct{ Home, Away i } return domain.OUTCOME_STATUS_LOSS, nil case "2": - if (score.Home + int(margin)) == score.Away { + if score.Away == (score.Home + int(margin)) { return domain.OUTCOME_STATUS_WIN, nil - } else if isGtr && (score.Home+int(margin)) > score.Away { + } else if isGtr && score.Away > (score.Home+int(margin)) { return domain.OUTCOME_STATUS_WIN, nil } return domain.OUTCOME_STATUS_LOSS, nil diff --git a/internal/services/result/service_test.go b/internal/services/result/service_test.go index 915559f..2c0e34b 100644 --- a/internal/services/result/service_test.go +++ b/internal/services/result/service_test.go @@ -31,7 +31,7 @@ func TestEvaluateFullTimeResult(t *testing.T) { func TestEvaluateTotalLegs(t *testing.T) { tests := []struct { - Name string + name string outcome domain.BetOutcome score struct{ Home, Away int } expected domain.OutcomeStatus @@ -42,7 +42,7 @@ func TestEvaluateTotalLegs(t *testing.T) { } for _, tt := range tests { - t.Run(tt.Name, func(t *testing.T) { + t.Run(tt.name, func(t *testing.T) { status, _ := evaluateTotalLegs(tt.outcome, tt.score) if status != tt.expected { t.Errorf("expected %d, got %d", tt.expected, status) @@ -53,7 +53,7 @@ func TestEvaluateTotalLegs(t *testing.T) { func TestEvaluateGameLines(t *testing.T) { tests := []struct { - Name string + name string outcome domain.BetOutcome score struct{ Home, Away int } expected domain.OutcomeStatus @@ -65,7 +65,7 @@ func TestEvaluateGameLines(t *testing.T) { } for _, tt := range tests { - t.Run(tt.Name, func(t *testing.T) { + t.Run(tt.name, func(t *testing.T) { status, _ := evaluateGameLines(tt.outcome, tt.score) if status != tt.expected { t.Errorf("expected %d, got %d", tt.expected, status) @@ -74,9 +74,9 @@ func TestEvaluateGameLines(t *testing.T) { } } -func TestFirstTeamToScore(t *testing.T) { +func TestEvaluateFirstTeamToScore(t *testing.T) { tests := []struct { - Name string + name string outcome domain.BetOutcome events []map[string]string expected domain.OutcomeStatus @@ -93,7 +93,7 @@ func TestFirstTeamToScore(t *testing.T) { } for _, tt := range tests { - t.Run(tt.Name, func(t *testing.T) { + t.Run(tt.name, func(t *testing.T) { status, _ := evaluateFirstTeamToScore(tt.outcome, tt.events) if status != tt.expected { t.Errorf("expected %d, got %d", tt.expected, status) @@ -101,3 +101,566 @@ func TestFirstTeamToScore(t *testing.T) { }) } } + +func TestEvaluateGoalsOverUnder(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"LosingGoalsOver", domain.BetOutcome{OddHeader: "Over", OddName: "13"}, struct{ Home, Away int }{7, 5}, domain.OUTCOME_STATUS_LOSS}, + {"WinningGoalsOver", domain.BetOutcome{OddHeader: "Over", OddName: "11"}, struct{ Home, Away int }{7, 5}, domain.OUTCOME_STATUS_WIN}, + {"WinningGoalsUnder", domain.BetOutcome{OddHeader: "Under", OddName: "12"}, struct{ Home, Away int }{6, 5}, domain.OUTCOME_STATUS_WIN}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateGoalsOverUnder(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateGoalsOddEven(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningOddGoals", domain.BetOutcome{OddName: "Odd"}, struct{ Home, Away int }{7, 4}, domain.OUTCOME_STATUS_WIN}, + {"LosingEvenGoals", domain.BetOutcome{OddName: "Even"}, struct{ Home, Away int }{7, 4}, domain.OUTCOME_STATUS_LOSS}, + {"WinningEvenGoals", domain.BetOutcome{OddName: "Even"}, struct{ Home, Away int }{6, 6}, domain.OUTCOME_STATUS_WIN}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateGoalsOddEven(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateCorrectScore(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"CorrectScore", domain.BetOutcome{OddName: "7-4"}, struct{ Home, Away int }{7, 4}, domain.OUTCOME_STATUS_WIN}, + {"CorrectScore", domain.BetOutcome{OddName: "6-6"}, struct{ Home, Away int }{6, 6}, domain.OUTCOME_STATUS_WIN}, + {"IncorrectScore", domain.BetOutcome{OddName: "2-3"}, struct{ Home, Away int }{7, 4}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateCorrectScore(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateHighestScoringHalf(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + firstScore struct{ Home, Away int } + secondScore struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"Winning1stHalf", domain.BetOutcome{OddName: "1st Half"}, struct{ Home, Away int }{1, 1}, struct{ Home, Away int }{0, 0}, domain.OUTCOME_STATUS_WIN}, + {"Losing1stHalf", domain.BetOutcome{OddName: "1st Half"}, struct{ Home, Away int }{1, 1}, struct{ Home, Away int }{2, 2}, domain.OUTCOME_STATUS_LOSS}, + {"Losing2ndHalf", domain.BetOutcome{OddName: "2nd Half"}, struct{ Home, Away int }{0, 0}, struct{ Home, Away int }{0, 0}, domain.OUTCOME_STATUS_LOSS}, + {"Winning2ndHalf", domain.BetOutcome{OddName: "2nd Half"}, struct{ Home, Away int }{1, 1}, struct{ Home, Away int }{2, 2}, domain.OUTCOME_STATUS_WIN}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateHighestScoringHalf(tt.outcome, tt.firstScore, tt.secondScore) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } + +} + +func TestEvaluateHighestScoringQuarter(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + firstScore struct{ Home, Away int } + secondScore struct{ Home, Away int } + thirdScore struct{ Home, Away int } + fourthScore struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"Winning1stQuarter", domain.BetOutcome{OddName: "1st Quarter"}, + struct{ Home, Away int }{1, 1}, + struct{ Home, Away int }{0, 0}, + struct{ Home, Away int }{1, 0}, + struct{ Home, Away int }{0, 0}, + domain.OUTCOME_STATUS_WIN}, + {"Losing1stQuarter", domain.BetOutcome{OddName: "1st Quarter"}, + struct{ Home, Away int }{1, 1}, + struct{ Home, Away int }{0, 0}, + struct{ Home, Away int }{1, 1}, + struct{ Home, Away int }{0, 0}, + domain.OUTCOME_STATUS_LOSS}, + {"Losing2ndQuarter", domain.BetOutcome{OddName: "2nd Quarter"}, + struct{ Home, Away int }{1, 1}, + struct{ Home, Away int }{0, 0}, + struct{ Home, Away int }{1, 1}, + struct{ Home, Away int }{0, 0}, + domain.OUTCOME_STATUS_LOSS}, + {"Winning3rdQuarter", domain.BetOutcome{OddName: "3rd Quarter"}, + struct{ Home, Away int }{1, 0}, + struct{ Home, Away int }{0, 0}, + struct{ Home, Away int }{1, 1}, + struct{ Home, Away int }{0, 0}, + domain.OUTCOME_STATUS_WIN}, + {"Wining4thQuarter", domain.BetOutcome{OddName: "4th Quarter"}, + struct{ Home, Away int }{1, 1}, + struct{ Home, Away int }{0, 0}, + struct{ Home, Away int }{1, 1}, + struct{ Home, Away int }{2, 2}, + domain.OUTCOME_STATUS_WIN}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateHighestScoringQuarter(tt.outcome, tt.firstScore, tt.secondScore, tt.thirdScore, tt.fourthScore) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } + +} + +func TestEvaluateWinningMargin(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningMargin", domain.BetOutcome{OddHeader: "1", OddName: "12"}, struct{ Home, Away int }{12, 0}, domain.OUTCOME_STATUS_WIN}, + {"WinningMargin", domain.BetOutcome{OddHeader: "2", OddName: "3"}, struct{ Home, Away int }{1, 4}, domain.OUTCOME_STATUS_WIN}, + {"WinningMargin", domain.BetOutcome{OddHeader: "1", OddName: "3+"}, struct{ Home, Away int }{4, 0}, domain.OUTCOME_STATUS_WIN}, + {"WinningMargin", domain.BetOutcome{OddHeader: "2", OddName: "12+"}, struct{ Home, Away int }{0, 13}, domain.OUTCOME_STATUS_WIN}, + {"LosingMargin", domain.BetOutcome{OddHeader: "2", OddName: "3"}, struct{ Home, Away int }{0, 4}, domain.OUTCOME_STATUS_LOSS}, + {"LosingMargin", domain.BetOutcome{OddHeader: "2", OddName: "3+"}, struct{ Home, Away int }{1, 3}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateWinningMargin(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateDoubleResult(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + firstHalfScore struct{ Home, Away int } + fullTimeScore struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningHomeAway", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team A - Team B"}, struct{ Home, Away int }{1, 0}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_WIN}, + {"WinningAwayHome", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team B - Team A"}, struct{ Home, Away int }{0, 1}, struct{ Home, Away int }{2, 1}, domain.OUTCOME_STATUS_WIN}, + {"WinningTie", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Tie - Tie"}, struct{ Home, Away int }{1, 1}, struct{ Home, Away int }{2, 2}, domain.OUTCOME_STATUS_WIN}, + {"WinningTieAway", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Tie - Team B"}, struct{ Home, Away int }{1, 1}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_WIN}, + {"LosingHomeAway", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team A - Team B"}, struct{ Home, Away int }{1, 0}, struct{ Home, Away int }{2, 0}, domain.OUTCOME_STATUS_LOSS}, + {"LosingTie", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Tie - Tie"}, struct{ Home, Away int }{1, 0}, struct{ Home, Away int }{1, 1}, domain.OUTCOME_STATUS_LOSS}, + {"LosingTieAway", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Tie - Team A"}, struct{ Home, Away int }{1, 1}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_LOSS}, + {"BadInput", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team A - "}, struct{ Home, Away int }{1, 1}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_PENDING}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateDoubleResult(tt.outcome, tt.firstHalfScore, tt.fullTimeScore) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateHighestScoringPeriod(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + firstScore struct{ Home, Away int } + secondScore struct{ Home, Away int } + thirdScore struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"Winning1stPeriod", domain.BetOutcome{OddName: "Period 1"}, struct{ Home, Away int }{2, 2}, struct{ Home, Away int }{1, 1}, struct{ Home, Away int }{0, 0}, domain.OUTCOME_STATUS_WIN}, + {"Winning2ndPeriod", domain.BetOutcome{OddName: "Period 2"}, struct{ Home, Away int }{2, 2}, struct{ Home, Away int }{2, 3}, struct{ Home, Away int }{0, 0}, domain.OUTCOME_STATUS_WIN}, + {"Winning3rdPeriod", domain.BetOutcome{OddName: "Period 3"}, struct{ Home, Away int }{2, 2}, struct{ Home, Away int }{2, 3}, struct{ Home, Away int }{3, 3}, domain.OUTCOME_STATUS_WIN}, + {"WinningTie", domain.BetOutcome{OddName: "Tie"}, struct{ Home, Away int }{2, 2}, struct{ Home, Away int }{2, 2}, struct{ Home, Away int }{0, 0}, domain.OUTCOME_STATUS_WIN}, + {"Losing1stPeriod", domain.BetOutcome{OddName: "Period 1"}, struct{ Home, Away int }{2, 2}, struct{ Home, Away int }{2, 3}, struct{ Home, Away int }{0, 0}, domain.OUTCOME_STATUS_LOSS}, + {"Losing3rdPeriod", domain.BetOutcome{OddName: "Period 3"}, struct{ Home, Away int }{2, 2}, struct{ Home, Away int }{2, 3}, struct{ Home, Away int }{0, 0}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateHighestScoringPeriod(tt.outcome, tt.firstScore, tt.secondScore, tt.thirdScore) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvalauteTiedAfterRegulation(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score []struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningTied", domain.BetOutcome{OddName: "Yes"}, []struct{ Home, Away int }{{1, 0}, {0, 1}, {2, 2}}, domain.OUTCOME_STATUS_WIN}, + {"WinningTied", domain.BetOutcome{OddName: "Yes"}, []struct{ Home, Away int }{{1, 1}, {0, 1}, {2, 2}, {2, 1}}, domain.OUTCOME_STATUS_WIN}, + {"WinningNotTied", domain.BetOutcome{OddName: "No"}, []struct{ Home, Away int }{{0, 0}, {0, 0}, {0, 0}, {1, 0}}, domain.OUTCOME_STATUS_WIN}, + {"LosingTied", domain.BetOutcome{OddName: "Yes"}, []struct{ Home, Away int }{{0, 2}, {0, 0}, {0, 0}, {0, 0}}, domain.OUTCOME_STATUS_LOSS}, + {"LosingNotTied", domain.BetOutcome{OddName: "No"}, []struct{ Home, Away int }{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateTiedAfterRegulation(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateTeamTotal(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningHomeUnder", domain.BetOutcome{OddHandicap: "Under 3", OddHeader: "1"}, struct{ Home, Away int }{2, 0}, domain.OUTCOME_STATUS_WIN}, + {"WinningHomeOver", domain.BetOutcome{OddHandicap: "Over 2", OddHeader: "1"}, struct{ Home, Away int }{3, 1}, domain.OUTCOME_STATUS_WIN}, + {"WinningAwayOver", domain.BetOutcome{OddHandicap: "Over 2", OddHeader: "2"}, struct{ Home, Away int }{1, 3}, domain.OUTCOME_STATUS_WIN}, + {"LosingHomeOver", domain.BetOutcome{OddHandicap: "Over 2", OddHeader: "1"}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_LOSS}, + {"LosingAwayOver", domain.BetOutcome{OddHandicap: "Over 2", OddHeader: "2"}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateTeamTotal(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestDrawNoBet(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningHome", domain.BetOutcome{OddName: "1"}, struct{ Home, Away int }{1, 0}, domain.OUTCOME_STATUS_WIN}, + {"WinningAway", domain.BetOutcome{OddName: "2"}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_WIN}, + {"LosingHome", domain.BetOutcome{OddName: "1"}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_LOSS}, + {"Tie", domain.BetOutcome{OddName: "1"}, struct{ Home, Away int }{1, 1}, domain.OUTCOME_STATUS_VOID}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateDrawNoBet(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateMoneyLine(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningHome", domain.BetOutcome{OddHeader: "1"}, struct{ Home, Away int }{1, 0}, domain.OUTCOME_STATUS_WIN}, + {"WinningAway", domain.BetOutcome{OddHeader: "2"}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_WIN}, + {"WinningTie", domain.BetOutcome{OddHeader: "Tie"}, struct{ Home, Away int }{2, 2}, domain.OUTCOME_STATUS_WIN}, + {"LosingTie", domain.BetOutcome{OddHeader: "1"}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_LOSS}, + {"LosingAway", domain.BetOutcome{OddHeader: "2"}, struct{ Home, Away int }{3, 2}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateMoneyLine(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateDoubleChance(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningHomeOrDraw", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "1 or Draw"}, struct{ Home, Away int }{1, 0}, domain.OUTCOME_STATUS_WIN}, + {"WinningHomeOrDraw", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team A or Draw"}, struct{ Home, Away int }{1, 0}, domain.OUTCOME_STATUS_WIN}, + {"WinningAwayOrDraw", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Draw or Team B"}, struct{ Home, Away int }{0, 1}, domain.OUTCOME_STATUS_WIN}, + {"LosingHomeorAway", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "1 or 2"}, struct{ Home, Away int }{1, 1}, domain.OUTCOME_STATUS_LOSS}, + {"LosingAwayOrDraw", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Draw or 2"}, struct{ Home, Away int }{2, 1}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateDoubleChance(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvalateResultAndTotal(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningHomeOver", domain.BetOutcome{OddHeader: "1", OddHandicap: "Over 4"}, struct{ Home, Away int }{2, 3}, domain.OUTCOME_STATUS_WIN}, + {"WinningHomeUnder", domain.BetOutcome{OddHeader: "1", OddHandicap: "Under 4"}, struct{ Home, Away int }{2, 1}, domain.OUTCOME_STATUS_WIN}, + {"WinningAwayUnder", domain.BetOutcome{OddHeader: "2", OddHandicap: "Under 4"}, struct{ Home, Away int }{2, 1}, domain.OUTCOME_STATUS_WIN}, + {"LosingHomeOver", domain.BetOutcome{OddHeader: "1", OddHandicap: "Under 4"}, struct{ Home, Away int }{2, 2}, domain.OUTCOME_STATUS_LOSS}, + {"LosingAwayUnder", domain.BetOutcome{OddHeader: "2", OddHandicap: "Under 4"}, struct{ Home, Away int }{2, 2}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateResultAndTotal(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestCheckMultiOutcome(t *testing.T) { + tests := []struct { + name string + outcome domain.OutcomeStatus + secondOutcome domain.OutcomeStatus + expected domain.OutcomeStatus + }{ + {"Win-Win", domain.OUTCOME_STATUS_WIN, domain.OUTCOME_STATUS_WIN, domain.OUTCOME_STATUS_WIN}, + {"Win-Void", domain.OUTCOME_STATUS_WIN, domain.OUTCOME_STATUS_VOID, domain.OUTCOME_STATUS_HALF}, + {"Win-Loss", domain.OUTCOME_STATUS_WIN, domain.OUTCOME_STATUS_LOSS, domain.OUTCOME_STATUS_PENDING}, + {"Loss-Loss", domain.OUTCOME_STATUS_LOSS, domain.OUTCOME_STATUS_LOSS, domain.OUTCOME_STATUS_LOSS}, + {"Loss-Void", domain.OUTCOME_STATUS_LOSS, domain.OUTCOME_STATUS_VOID, domain.OUTCOME_STATUS_HALF}, + {"Loss-Win", domain.OUTCOME_STATUS_LOSS, domain.OUTCOME_STATUS_WIN, domain.OUTCOME_STATUS_PENDING}, + {"Void-Win", domain.OUTCOME_STATUS_VOID, domain.OUTCOME_STATUS_WIN, domain.OUTCOME_STATUS_HALF}, + {"Void-Loss", domain.OUTCOME_STATUS_VOID, domain.OUTCOME_STATUS_LOSS, domain.OUTCOME_STATUS_HALF}, + {"Void-Void", domain.OUTCOME_STATUS_VOID, domain.OUTCOME_STATUS_VOID, domain.OUTCOME_STATUS_PENDING}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := checkMultiOutcome(tt.outcome, tt.secondOutcome) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateBTTSX(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningBothScoreX", domain.BetOutcome{OddName: "3", OddHeader: "Yes"}, struct{ Home, Away int }{3, 4}, domain.OUTCOME_STATUS_WIN}, + {"WinningBothScoreLess", domain.BetOutcome{OddName: "3", OddHeader: "No"}, struct{ Home, Away int }{2, 1}, domain.OUTCOME_STATUS_WIN}, + {"LosingBothScoreX", domain.BetOutcome{OddName: "3", OddHeader: "Yes"}, struct{ Home, Away int }{2, 4}, domain.OUTCOME_STATUS_LOSS}, + {"LosingBothScoreLess", domain.BetOutcome{OddName: "3", OddHeader: "No"}, struct{ Home, Away int }{2, 4}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateBTTSX(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateResultAndBTTSX(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningHomeAndBothScoreX", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team A and Yes", OddHeader: "3"}, struct{ Home, Away int }{4, 3}, domain.OUTCOME_STATUS_WIN}, + {"WinningHomeAndBothScoreLess", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team A and No", OddHeader: "3"}, struct{ Home, Away int }{2, 1}, domain.OUTCOME_STATUS_WIN}, + {"WinningAwayAndBothScoreX", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team B and Yes", OddHeader: "3"}, struct{ Home, Away int }{3, 4}, domain.OUTCOME_STATUS_WIN}, + {"WinningAwayAndBothScoreLess", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team B and No", OddHeader: "3"}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_WIN}, + {"LosingHomeAndBothScoreX", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team A and Yes", OddHeader: "3"}, struct{ Home, Away int }{3, 4}, domain.OUTCOME_STATUS_LOSS}, + {"LosingHomeAndBothScoreX", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team B and Yes", OddHeader: "3"}, struct{ Home, Away int }{4, 2}, domain.OUTCOME_STATUS_LOSS}, + {"LosingAwayAndBothScoreX", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team B and Yes", OddHeader: "3"}, struct{ Home, Away int }{2, 4}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateResultAndBTTSX(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateMoneyLine3Way(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"WinningHome", domain.BetOutcome{OddName: "1"}, struct{ Home, Away int }{1, 0}, domain.OUTCOME_STATUS_WIN}, + {"WinningAway", domain.BetOutcome{OddName: "2"}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_WIN}, + {"WinningTie", domain.BetOutcome{OddName: "Tie"}, struct{ Home, Away int }{2, 2}, domain.OUTCOME_STATUS_WIN}, + {"LosingTie", domain.BetOutcome{OddName: "1"}, struct{ Home, Away int }{1, 2}, domain.OUTCOME_STATUS_LOSS}, + {"LosingAway", domain.BetOutcome{OddName: "2"}, struct{ Home, Away int }{3, 2}, domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateMoneyLine3Way(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateAsianHandicap(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + { + name: "Home -1 Win", + outcome: domain.BetOutcome{OddHeader: "1", OddHandicap: "-1"}, + score: struct{ Home, Away int }{Home: 2, Away: 0}, + expected: domain.OUTCOME_STATUS_WIN, + }, + { + name: "Home -0.5 Win", + outcome: domain.BetOutcome{OddHeader: "1", OddHandicap: "-0.5"}, + score: struct{ Home, Away int }{Home: 1, Away: 0}, + expected: domain.OUTCOME_STATUS_WIN, + }, + { + name: "Home -1 Void", + outcome: domain.BetOutcome{OddHeader: "1", OddHandicap: "-1"}, + score: struct{ Home, Away int }{Home: 1, Away: 0}, + expected: domain.OUTCOME_STATUS_VOID, + }, + { + name: "Away +3 Win", + outcome: domain.BetOutcome{OddHeader: "2", OddHandicap: "3"}, + score: struct{ Home, Away int }{Home: 1, Away: 2}, + expected: domain.OUTCOME_STATUS_WIN, + }, + { + name: "Split Handicap Home -0.5,-1 Win/Win", + outcome: domain.BetOutcome{OddHeader: "1", OddHandicap: "-0.5,-1"}, + score: struct{ Home, Away int }{Home: 2, Away: 0}, + expected: domain.OUTCOME_STATUS_WIN, + }, + { + name: "Split Handicap Home -0.5,-1 Win/Void", + outcome: domain.BetOutcome{OddHeader: "1", OddHandicap: "-0.5,-1"}, + score: struct{ Home, Away int }{Home: 1, Away: 0}, + expected: domain.OUTCOME_STATUS_WIN, + }, + { + name: "Invalid Handicap", + outcome: domain.BetOutcome{OddHeader: "1", OddHandicap: "invalid"}, + score: struct{ Home, Away int }{Home: 1, Away: 0}, + expected: domain.OUTCOME_STATUS_PENDING, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateAsianHandicap(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +} + +func TestEvaluateHandicapAndTotal(t *testing.T) { + tests := []struct { + name string + outcome domain.BetOutcome + score struct{ Home, Away int } + expected domain.OutcomeStatus + }{ + {"Home +2.5 Over 3", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team A +2.5 & Over 3"}, + struct{ Home, Away int }{4, 0}, + domain.OUTCOME_STATUS_WIN}, + {"Away +2.5 Over 4", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team B +2.5 & Over 4"}, + struct{ Home, Away int }{1, 5}, + domain.OUTCOME_STATUS_WIN}, + {"Home +2.5 Over 3", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team A +2.5 & Over 3"}, + struct{ Home, Away int }{2, 0}, + domain.OUTCOME_STATUS_LOSS}, + {"Home -3.5 Over 3", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team A -2.5 & Over 3"}, + struct{ Home, Away int }{4, 3}, + domain.OUTCOME_STATUS_LOSS}, + {"Away -3 Over 4", domain.BetOutcome{HomeTeamName: "Team A", AwayTeamName: "Team B", OddName: "Team B -3 & Over 4"}, + struct{ Home, Away int }{3, 5}, + domain.OUTCOME_STATUS_LOSS}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + status, _ := evaluateHandicapAndTotal(tt.outcome, tt.score) + if status != tt.expected { + t.Errorf("expected %d, got %d", tt.expected, status) + } + }) + } +}