Skip to content

Commit

Permalink
Merge pull request #21 from topfreegames/gsso-833-get-chatlog-by-player
Browse files Browse the repository at this point in the history
Get chatlog by player_id [PS]
  • Loading branch information
mflilian committed Jun 6, 2022
2 parents 5456a5b + 11efa79 commit 82eaeff
Show file tree
Hide file tree
Showing 5 changed files with 282 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ func (app *App) configureApplication() {
a.Get("/v2/history/*", HistoryV2Handler(app))
a.Get("/v2/histories/*", HistoriesV2Handler(app))
a.Get("/:other", NotFoundHandler(app))
a.Get("/ps/v2/history*", HistoriesV2PSHandler(app))
}

// OnErrorHandler handles application panics
Expand Down
52 changes: 52 additions & 0 deletions app/history_v2_player_support.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package app

import (
"net/http"
"time"

"github.com/topfreegames/mqtt-history/logger"
"github.com/topfreegames/mqtt-history/mongoclient"

"github.com/labstack/echo"
"github.com/topfreegames/mqtt-history/models"
)

func HistoriesV2PSHandler(app *App) func(c echo.Context) error {
return func(c echo.Context) error {
c.Set("route", "HistoriesV2PlayerSupport")
userID, playerId, topic, limit, isBlocked := ParseHistoryPSQueryParams(c, app.Defaults.LimitOfMessages)

initialDateParamsFilter := c.QueryParam("initialDate")
from, err := transformDate(initialDateParamsFilter)
if err != nil {
logger.Logger.Warningf("Error: %s", err.Error())
return c.JSON(http.StatusUnprocessableEntity, "Error getting initialDate parameter.")
}

finalDateParamsFilter := c.QueryParam("finalDate")
to, err := transformDate(finalDateParamsFilter)
if err != nil {
logger.Logger.Warningf("Error: %s", err.Error())
return c.JSON(http.StatusUnprocessableEntity, "Error getting finalDate parameter.")
}

logger.Logger.Debugf(
"user %s is asking for history v2 for topic %s with date args from=%d to=%d and limit=%d",
userID, from, to, limit)

messages := make([]*models.MessageV2, 0)
collection := app.Defaults.MongoMessagesCollection
messages = mongoclient.GetMessagesPlayerSupportV2WithParameter(c, topic, from, to, limit, collection, isBlocked, playerId)

return c.JSON(http.StatusOK, messages)
}
}

func transformDate(dateParamsFilter string) (int64, error) {
utcFormat := "2006-01-02"
t, err := time.Parse(utcFormat, dateParamsFilter)
if err != nil {
return 0, err
}
return t.Unix(), err
}
142 changes: 142 additions & 0 deletions app/history_v2_player_support_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// mqtt-history
// https://github.com/topfreegames/mqtt-history
// Licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license
// Copyright © 2016 Top Free Games <backend@tfgco.com>

package app_test

import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"testing"
"time"

goblin "github.com/franela/goblin"
. "github.com/onsi/gomega"
uuid "github.com/satori/go.uuid"
"github.com/topfreegames/mqtt-history/models"
. "github.com/topfreegames/mqtt-history/testing"
)

func TestHistoryV2PSHandler(t *testing.T) {
g := goblin.Goblin(t)

// special hook for gomega
RegisterFailHandler(func(m string, _ ...int) { g.Fail(m) })

g.Describe("History2", func() {
ctx := context.Background()
a := GetDefaultTestApp()

g.Describe("HistoryV2PS Handler", func() {

g.It("It should return 200 and [] if there are no messages from the player on the informed topic", func() {
testID := strings.Replace(uuid.NewV4().String(), "-", "", -1)
topic := fmt.Sprintf("chat/test_%s", testID)
playerID := "test"

path := fmt.Sprintf("/ps/v2/history?topic=%s&playerId=%s&initialDate=2022-01-01&finalDate=2022-12-01", topic, playerID)
status, body := Get(a, path, t)
g.Assert(status).Equal(http.StatusOK)

var messages []models.Message
err := json.Unmarshal([]byte(body), &messages)
g.Assert(len(messages)).Equal(0)
Expect(err).To(BeNil())
})

g.It("It should return 200 and unblocked messages from the given player,topic and date.", func() {
testID := strings.Replace(uuid.NewV4().String(), "-", "", -1)
topic := fmt.Sprintf("chat/test_%s", testID)
playerID := "test"
finalDate := strings.Split(time.Now().AddDate(0, 0, 1).UTC().String(), " ")[0]

err := InsertMongoMessagesWithParameters(ctx, []string{topic}, false)
Expect(err).To(BeNil())

path := fmt.Sprintf("/ps/v2/history?topic=%s&playerId=%s&initialDate=2022-01-01&finalDate=%s", topic, playerID, finalDate)
status, body := Get(a, path, t)
g.Assert(status).Equal(http.StatusOK)

var messages []models.MessageV2

err = json.Unmarshal([]byte(body), &messages)
Expect(err).To(BeNil())

g.Assert(len(messages)).Equal(1)
g.Assert(messages[0].Blocked).Equal(false)

})

g.It("It should return 422 and an error message if the date parameter is being missed", func() {
testID := strings.Replace(uuid.NewV4().String(), "-", "", -1)
topic := fmt.Sprintf("chat/test_%s", testID)
playerID := "test"

err := InsertMongoMessagesWithParameters(ctx, []string{topic}, false)
Expect(err).To(BeNil())

path := fmt.Sprintf("/ps/v2/history?topic=%s&playerId=%s", topic, playerID)
status, _ := Get(a, path, t)
g.Assert(status).Equal(http.StatusUnprocessableEntity)

})

g.It("It should return 200 and the messages if the topic parameter is being missed", func() {
testID := strings.Replace(uuid.NewV4().String(), "-", "", -1)
topic := fmt.Sprintf("chat/test_%s", testID)
playerID := "test"
finalDate := strings.Split(time.Now().AddDate(0, 0, 1).UTC().String(), " ")[0]

err := InsertMongoMessagesWithParameters(ctx, []string{topic}, false)
Expect(err).To(BeNil())

path := fmt.Sprintf("/ps/v2/history?playerId=%s&initialDate=2022-01-01&finalDate=%s", playerID, finalDate)
status, body := Get(a, path, t)
g.Assert(status).Equal(http.StatusOK)

var messages []models.MessageV2

err = json.Unmarshal([]byte(body), &messages)
Expect(err).To(BeNil())

g.Assert(len(messages)).Equal(10)
g.Assert(messages[0].Blocked).Equal(false)

})

g.It("It should return 200 and only blocked messages from the given player,topic and date.", func() {
testID := strings.Replace(uuid.NewV4().String(), "-", "", -1)
topic := fmt.Sprintf("chat/test_%s", testID)
playerID := "test"
finalDate := strings.Split(time.Now().AddDate(0, 0, 1).UTC().String(), " ")[0]

err := AuthorizeTestUserInTopics(ctx, []string{topic})
Expect(err).To(BeNil())

err = InsertMongoMessagesWithParameters(ctx, []string{topic}, false)
Expect(err).To(BeNil())

err = InsertMongoMessagesWithParameters(ctx, []string{topic}, true)
Expect(err).To(BeNil())

path := fmt.Sprintf("/ps/v2/history?topic=%s&playerId=%s&initialDate=2022-01-01&finalDate=%s&isBlocked=true", topic, playerID, finalDate)
status, body := Get(a, path, t)
g.Assert(status).Equal(http.StatusOK)

var messages []models.MessageV2

err = json.Unmarshal([]byte(body), &messages)
Expect(err).To(BeNil())

g.Assert(len(messages)).Equal(1)
g.Assert(messages[0].Blocked).Equal(true)

})
})
})
}
20 changes: 20 additions & 0 deletions app/query_param.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,23 @@ func ParseHistoriesQueryParams(c echo.Context, defaultLimit int64) ([]string, st

return topicsSuffix, userID, from, limit
}

func ParseHistoryPSQueryParams(c echo.Context, defaultLimit int64) (string, string, string, int64, bool) {
userID := c.QueryParam("userid")
playerId := c.QueryParam("playerId")
topic := c.QueryParam("topic")
limit, err := strconv.ParseInt(c.QueryParam("limit"), 10, 64)
isBlocked, err := strconv.ParseBool(c.QueryParam("isBlocked"))

if limit == 0 {
limit = defaultLimit
}

if err != nil {
// If it returns error, it will assume the default behavior(e.g. isBlocked=false).
logger.Logger.Warningf("Error getting isBlocked parameter, assuming default behavior. Error: %s", err.Error())
return userID, playerId, topic, limit, false
}

return userID, playerId, topic, limit, isBlocked
}
67 changes: 67 additions & 0 deletions mongoclient/get_messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,70 @@ func convertPlayerIdToString(playerID interface{}) (string, error) {

return "", fmt.Errorf("error converting player id to float64 or string. player id raw value: %s", playerID)
}

func GetMessagesPlayerSupportV2WithParameter(ctx context.Context, topic string, from int64, to int64, limit int64,
collection string, isBlocked bool, playerId string) []*models.MessageV2 {
rawResults := make([]MongoMessage, 0)

callback := func(coll *mongo.Collection) error {
query := bson.M{
"timestamp": bson.M{
"$gte": from, //greather than or equal
"$lte": to, // less than or equal
},
"player_id": playerId,
"blocked": isBlocked,
"topic": topic,
}
sort := bson.D{
{"topic", 1},
{"timestamp", -1},
}

if topic == "" {
query = bson.M{
"timestamp": bson.M{
"$gte": from,
"$lte": to,
},
"player_id": playerId,
"blocked": isBlocked,
}
sort = bson.D{
{"topic", 1},
{"timestamp", -1},
}
}

opts := options.Find()
opts.SetSort(sort)
opts.SetLimit(limit)

cursor, err := coll.Find(ctx, query, opts)
if err != nil {
return err
}

return cursor.All(ctx, &rawResults)
}
// retrieve the collection data
err := GetCollection(collection, callback)
if err != nil {
logger.Logger.Warningf("Error getting messages from MongoDB: %s", err.Error())
return []*models.MessageV2{}
}

// convert the raw results to the MessageV2 model
searchResults := make([]*models.MessageV2, len(rawResults))

for i := 0; i < len(rawResults); i++ {
searchResults[i], err = convertRawMessageToModelMessage(rawResults[i])

if err != nil {
logger.Logger.Warningf("Error getting messages from MongoDB: %s", err.Error())
return []*models.MessageV2{}
}
}

return searchResults
}

0 comments on commit 82eaeff

Please sign in to comment.