Skip to content

Commit

Permalink
Item verification in donation requests
Browse files Browse the repository at this point in the history
  • Loading branch information
heynemann committed Nov 17, 2016
1 parent 9e27751 commit 38e4660
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 31 deletions.
2 changes: 1 addition & 1 deletion api/donation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ var _ = Describe("Game Handler", func() {
Expect(err).NotTo(HaveOccurred())

playerID := uuid.NewV4().String()
itemID := uuid.NewV4().String()
itemID := GetFirstItem(game).Key
clanID := uuid.NewV4().String()
payload := &api.CreateDonationRequestPayload{
Player: playerID,
Expand Down
22 changes: 22 additions & 0 deletions errors/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,25 @@ func NewDocumentNotFoundError(collection string, id string) *DocumentNotFoundErr
func (err DocumentNotFoundError) Error() string {
return fmt.Sprintf("Document with id %s was not found in collection %s.", err.ID, err.Collection)
}

//ParameterIsRequiredError happens when a parameter for a given instance to be saved is required but is empty
type ParameterIsRequiredError struct {
Parameter string
Model string
}

//Error string
func (err ParameterIsRequiredError) Error() string {
return fmt.Sprintf("%s is required to create a new %s", err.Parameter, err.Model)
}

//ItemNotFoundInGameError happens when a donation happens for an item that's not in the game
type ItemNotFoundInGameError struct {
ItemKey string
GameID string
}

//Error string
func (err ItemNotFoundInGameError) Error() string {
return fmt.Sprintf("Item %s was not found in game %s", err.ItemKey, err.GameID)
}
21 changes: 21 additions & 0 deletions models/donation.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@ func (d *DonationRequest) Create(db *mgo.Database, logger zap.Logger) error {
zap.String("operation", "Save"),
)

if d.Game == nil {
return &errors.ParameterIsRequiredError{
Parameter: "Game",
Model: "DonationRequest",
}
}

if d.Item == "" {
return &errors.ParameterIsRequiredError{
Parameter: "Item",
Model: "DonationRequest",
}
}

if _, ok := d.Game.Items[d.Item]; !ok {
return &errors.ItemNotFoundInGameError{
ItemKey: d.Item,
GameID: d.Game.ID,
}
}

d.ID = bson.NewObjectId().Hex()
d.CreatedAt = time.Now().UTC()
d.UpdatedAt = time.Now().UTC()
Expand Down
76 changes: 48 additions & 28 deletions models/donation_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package models_test

import (
"fmt"
"time"

mgo "gopkg.in/mgo.v2"
Expand Down Expand Up @@ -39,12 +40,12 @@ var _ = Describe("Donation Model", func() {
game, err := GetTestGame(db, logger, true)
Expect(err).NotTo(HaveOccurred())

itemID := uuid.NewV4().String()
itemKey := GetFirstItem(game).Key
playerID := uuid.NewV4().String()
clanID := uuid.NewV4().String()
donationRequest := models.NewDonationRequest(
game,
itemID,
itemKey,
playerID,
clanID,
)
Expand All @@ -55,37 +56,67 @@ var _ = Describe("Donation Model", func() {
c := models.GetDonationRequestsCollection(db)
err = c.FindId(donationRequest.ID).One(&dbDonationRequest)
Expect(err).NotTo(HaveOccurred())
Expect(dbDonationRequest.Item).To(Equal(itemID))
Expect(dbDonationRequest.Item).To(Equal(itemKey))
Expect(dbDonationRequest.Player).To(Equal(playerID))
Expect(dbDonationRequest.Clan).To(Equal(clanID))
Expect(dbDonationRequest.Game).NotTo(BeNil())
Expect(dbDonationRequest.Game.ID).To(Equal(game.ID))
Expect(dbDonationRequest.CreatedAt.Unix()).To(BeNumerically(">", start.Unix()-10))
Expect(dbDonationRequest.UpdatedAt.Unix()).To(BeNumerically(">", start.Unix()-10))
})

It("Should fail to create a new donation request without a game", func() {
itemID := uuid.NewV4().String()
playerID := uuid.NewV4().String()
clanID := uuid.NewV4().String()
donationRequest := models.NewDonationRequest(
nil,
itemID,
playerID,
clanID,
)
err := donationRequest.Create(db, logger)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("Game is required to create a new DonationRequest"))
})

It("Should fail to create a new donation request with invalid item", func() {
game, err := GetTestGame(db, logger, true)
Expect(err).NotTo(HaveOccurred())

itemID := uuid.NewV4().String()
playerID := uuid.NewV4().String()
clanID := uuid.NewV4().String()
donationRequest := models.NewDonationRequest(
game,
itemID,
playerID,
clanID,
)
err = donationRequest.Create(db, logger)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring(
fmt.Sprintf("Item %s was not found in game %s", itemID, game.ID),
))
})
})

Describe("Measure", func() {
var game *models.Game
var err error
BeforeOnce(func() {
game = models.NewGame(
uuid.NewV4().String(),
uuid.NewV4().String(),
1,
2,
)
err := game.Save(db, logger)
game, err = GetTestGame(db, logger, true)
Expect(err).NotTo(HaveOccurred())
})

Measure("it should create donation requests fast", func(b Benchmarker) {
runtime := b.Time("runtime", func() {
itemID := uuid.NewV4().String()
itemKey := GetFirstItem(game).Key
playerID := uuid.NewV4().String()
clanID := uuid.NewV4().String()
donationRequest := models.NewDonationRequest(
game,
itemID,
itemKey,
playerID,
clanID,
)
Expand All @@ -101,16 +132,10 @@ var _ = Describe("Donation Model", func() {
Describe("Donating an item", func() {
Describe("Feature", func() {
It("Should append a new donation", func() {
game := models.NewGame(
uuid.NewV4().String(),
uuid.NewV4().String(),
1,
2,
)
err := game.Save(db, logger)
game, err := GetTestGame(db, logger, true)
Expect(err).NotTo(HaveOccurred())

itemID := uuid.NewV4().String()
itemID := GetFirstItem(game).Key
playerID := uuid.NewV4().String()
clanID := uuid.NewV4().String()
donationRequest := models.NewDonationRequest(
Expand Down Expand Up @@ -140,18 +165,13 @@ var _ = Describe("Donation Model", func() {
Describe("Measure", func() {
var game *models.Game
var donationRequest *models.DonationRequest
var err error

BeforeOnce(func() {
game = models.NewGame(
uuid.NewV4().String(),
uuid.NewV4().String(),
1,
2,
)
err := game.Save(db, logger)
game, err = GetTestGame(db, logger, true)
Expect(err).NotTo(HaveOccurred())

itemID := uuid.NewV4().String()
itemID := GetFirstItem(game).Key
playerID := uuid.NewV4().String()
clanID := uuid.NewV4().String()
donationRequest = models.NewDonationRequest(
Expand Down
2 changes: 1 addition & 1 deletion models/game_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ var _ = Describe("Game Model", func() {
Expect(err).NotTo(HaveOccurred())
})

Expect(runtime.Seconds()).Should(BeNumerically("<", 0.2), "Operation shouldn't take this long.")
Expect(runtime.Seconds()).Should(BeNumerically("<", 0.5), "Operation shouldn't take this long.")
}, 500)
})
})
Expand Down
11 changes: 10 additions & 1 deletion testing/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,23 @@ func GetTestGame(db *mgo.Database, logger zap.Logger, withItems bool) (*models.G
func GetTestDonationRequest(game *models.Game, db *mgo.Database, logger zap.Logger) (*models.DonationRequest, error) {
donationRequest := models.NewDonationRequest(
game,
uuid.NewV4().String(),
GetFirstItem(game).Key,
uuid.NewV4().String(),
uuid.NewV4().String(),
)
err := donationRequest.Create(db, logger)
return donationRequest, err
}

//GetFirstItemInGame
func GetFirstItem(g *models.Game) *models.Item {
for _, v := range g.Items {
return &v
}

return nil
}

//ToNullInt64 returns valid if int > 0
func ToNullInt64(v int64) sql.NullInt64 {
return sql.NullInt64{Int64: v, Valid: v > 0}
Expand Down

0 comments on commit 38e4660

Please sign in to comment.