Commit 47d7405f authored by Julien Schröter's avatar Julien Schröter Committed by Julien Schröter

Check that the next player field changed before sending a notification

parent 494a2c82
Pipeline #2023 passed with stage
in 11 minutes and 14 seconds
......@@ -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)
......
......@@ -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
......
......@@ -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 {
......
......@@ -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) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment