From 47d7405f917d2993968de01a8c3b31e4241098e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Schro=CC=88ter?= Date: Mon, 5 Oct 2020 18:40:57 +0200 Subject: [PATCH] Check that the next player field changed before sending a notification --- endpoint/duel/endpoint.go | 29 ++++++++++++++++------------- endpoint/duel/query.go | 11 ++++++----- schemas/duel.go | 9 +++++---- test/duel_test.go | 2 +- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/endpoint/duel/endpoint.go b/endpoint/duel/endpoint.go index afa101d..60d562f 100644 --- a/endpoint/duel/endpoint.go +++ b/endpoint/duel/endpoint.go @@ -345,7 +345,7 @@ func postAnswer(repository DuelQuery, titleRepository title.TitleQuery, sessionR awards.Titles = newTitles // prepare and send notifications - status, err := repository.GetDuelEndStatusByRoundID(reqParams.RoundID) + status, err := repository.GetDuelStatusByRoundID(reqParams.RoundID) if err != nil { raven.CaptureError(fmt.Errorf("failed to send push notification: %v", err), nil) } else { @@ -355,24 +355,15 @@ func postAnswer(repository DuelQuery, titleRepository title.TitleQuery, sessionR raven.CaptureError(fmt.Errorf("failed to retrieve user id from session: %v", errUserID), nil) } else if errUsername != nil { raven.CaptureError(fmt.Errorf("failed to retrieve username from session: %v", err), nil) - } else { + } else if status.Finished || userID != status.NextPlayer { + // Don't send notification if current user has to answer + // additional questions before the other user can play. var notificationType notifications.NotificationType var receiver uint32 var notification *messaging.Notification data := make(map[string]string) data["duel"] = strconv.FormatUint(uint64(status.ID), 10) - // Duel has been finished. Send opponent whether he won. - var scoreOpponent, scorePlayer uint32 - for id, score := range status.Scores { - if id == userID { - scorePlayer = score - } else { - scoreOpponent = score - receiver = id - } - } - if !status.Finished { notificationType = notifications.DuelResponseNotificationType notification = &messaging.Notification{ @@ -380,6 +371,17 @@ func postAnswer(repository DuelQuery, titleRepository title.TitleQuery, sessionR Body: "Spiele jetzt die nächste Runde!"} data["type"] = string(notifications.DuelResponseNotificationType) } else { + // Duel has been finished. Send opponent whether he won. + var scoreOpponent, scorePlayer uint32 + for id, score := range status.Scores { + if id == userID { + scorePlayer = score + } else { + scoreOpponent = score + receiver = id + } + } + switch { case scoreOpponent > scorePlayer: notificationType = notifications.DuelWonNotificationType @@ -401,6 +403,7 @@ func postAnswer(repository DuelQuery, titleRepository title.TitleQuery, sessionR data["type"] = string(notifications.DuelTieNotificationType) } } + // send notification if err := notifyUser(notificationType, sessionRepository, receiver, notification, data); err != nil && err != errUserForbidsNotifications { raven.CaptureError(fmt.Errorf("failed to send notification: %v", err), nil) diff --git a/endpoint/duel/query.go b/endpoint/duel/query.go index 9ebd6fa..80f541c 100644 --- a/endpoint/duel/query.go +++ b/endpoint/duel/query.go @@ -274,7 +274,7 @@ type DuelQuery interface { GetPools(duelID, userID uint32) ([]schemas.PoolSchema, error) SetPool(duelID, poolID, userID uint32) (*schemas.DuelSchema, error) GetRoundByID(roundID, userID uint32) (*schemas.FullRoundSchema, error) - GetDuelEndStatusByRoundID(roundID uint32) (*schemas.DuelEndStatus, error) + GetDuelStatusByRoundID(roundID uint32) (*schemas.DuelStatus, error) InsertOptionUserAnswer(roundID, questionID, userID uint32, answer []uint32) (*UserAwards, error) InsertTextUserAnswer(roundID, questionID, userID uint32, answer string) (*UserAwards, error) IsPlayerOfRound(userID, roundID uint32) (bool, error) @@ -1172,7 +1172,7 @@ func (m *MySQLDuelQuery) updateNextTransaction(tx *sql.Tx, roundID uint32) error // GetDuelEndStatusByRoundID returns the duelID of a round including whether or not the duel has // been finished and the duel's participants with their scores. -func (m *MySQLDuelQuery) GetDuelEndStatusByRoundID(roundID uint32) (*schemas.DuelEndStatus, error) { +func (m *MySQLDuelQuery) GetDuelStatusByRoundID(roundID uint32) (*schemas.DuelStatus, error) { db, err := dbhandler.GetDBConnection() if err != nil { return nil, fmt.Errorf("failed to get database connection: %v", err) @@ -1182,11 +1182,12 @@ func (m *MySQLDuelQuery) GetDuelEndStatusByRoundID(roundID uint32) (*schemas.Due return nil, fmt.Errorf("failed to connect to database: %v", err) } - rowDuelStatus := db.QueryRow("SELECT `duel`, `running` FROM `round` INNER JOIN `duel` ON (`round`.`duel`=`duel`.`idduel`) WHERE `idround`=?", roundID) + rowDuelStatus := db.QueryRow("SELECT `duel`, `running`, `next` FROM `round` INNER JOIN `duel` ON (`round`.`duel`=`duel`.`idduel`) WHERE `idround`=?", roundID) var duelID uint32 var running bool - if err := rowDuelStatus.Scan(&duelID, &running); err != nil { + var nextPlayer uint32 + if err := rowDuelStatus.Scan(&duelID, &running, &nextPlayer); err != nil { return nil, fmt.Errorf("failed fetching duel data: %v", err) } @@ -1196,7 +1197,7 @@ func (m *MySQLDuelQuery) GetDuelEndStatusByRoundID(roundID uint32) (*schemas.Due return nil, fmt.Errorf("failed to fetch player scores: %v", err) } - result := &schemas.DuelEndStatus{ID: duelID, Finished: !running, Scores: make(map[uint32]uint32)} + result := &schemas.DuelStatus{ID: duelID, Finished: !running, NextPlayer: nextPlayer, Scores: make(map[uint32]uint32)} for rowUserScores.Next() { var userID uint32 diff --git a/schemas/duel.go b/schemas/duel.go index 0fb2268..f6de2e3 100644 --- a/schemas/duel.go +++ b/schemas/duel.go @@ -27,10 +27,11 @@ type Participant struct { Score uint32 `json:"score"` } -type DuelEndStatus struct { - ID uint32 - Finished bool - Scores map[uint32]uint32 +type DuelStatus struct { + ID uint32 + Finished bool + NextPlayer uint32 + Scores map[uint32]uint32 } type DuelSchema struct { diff --git a/test/duel_test.go b/test/duel_test.go index cd16ade..ea874ad 100644 --- a/test/duel_test.go +++ b/test/duel_test.go @@ -147,7 +147,7 @@ func (m *mockDuel) SetPool(duelID, poolID, userID uint32) (*schemas.DuelSchema, func (m *mockDuel) GetRoundByID(roundID, userID uint32) (*schemas.FullRoundSchema, error) { return nil, errors.New("query not mocked") } -func (mockDuel) GetDuelEndStatusByRoundID(roundID uint32) (*schemas.DuelEndStatus, error) { +func (mockDuel) GetDuelStatusByRoundID(roundID uint32) (*schemas.DuelStatus, error) { return nil, errors.New("query not mocked") } func (m *mockDuel) InsertOptionUserAnswer(roundID, questionID, userID uint32, answer []uint32) (*duel.UserAwards, error) { -- GitLab