diff --git a/api/membership.go b/api/membership.go index 111928e1..83fea92f 100644 --- a/api/membership.go +++ b/api/membership.go @@ -113,7 +113,14 @@ func ApplyForMembershipHandler(app *App) func(c echo.Context) error { return nil }) if err != nil { - return FailWith(http.StatusInternalServerError, err.Error(), c) + switch err.(type) { + case *models.ModelNotFoundError: + return FailWith(http.StatusBadRequest, err.Error(), c) + case *models.AlreadyHasValidMembershipError: + return FailWith(http.StatusConflict, err.Error(), c) + default: + return FailWith(http.StatusInternalServerError, err.Error(), c) + } } err = WithSegment("hook-dispatch", c, func() error { @@ -379,7 +386,14 @@ func ApproveOrDenyMembershipApplicationHandler(app *App) func(c echo.Context) er return nil }) if err != nil { - return err + switch err.(type) { + case *models.ModelNotFoundError: + return FailWith(http.StatusBadRequest, err.Error(), c) + case *models.CannotApproveOrDenyMembershipAlreadyProcessedError: + return FailWith(http.StatusConflict, err.Error(), c) + default: + return err + } } err = WithSegment("player-retrieve", c, func() error { diff --git a/api/membership_test.go b/api/membership_test.go index 045846b3..2a392c1c 100644 --- a/api/membership_test.go +++ b/api/membership_test.go @@ -117,6 +117,42 @@ var _ = Describe("Membership API Handler", func() { Expect(dbMembership.Message).To(Equal(payload["message"])) }) + It("Should conflict when player is already a member", func() { + _, clan, owner, players, memberships, err := models.GetClanWithMemberships(testDb, 0, 0, 0, 1, "", "") + Expect(err).NotTo(HaveOccurred()) + + memberships[0].RequestorID = memberships[0].PlayerID + _, err = testDb.Update(memberships[0]) + + gameID := clan.GameID + clanPublicID := clan.PublicID + + payload := map[string]interface{}{ + "playerPublicID": players[0].PublicID, + "requestorPublicID": owner.PublicID, + } + status, body := PostJSON(a, CreateMembershipRoute(gameID, clanPublicID, "application/approve"), payload) + + Expect(status).To(Equal(http.StatusOK)) + var result map[string]interface{} + json.Unmarshal([]byte(body), &result) + Expect(result["success"]).To(BeTrue()) + + dbMembership, err := models.GetValidMembershipByClanAndPlayerPublicID(a.Db, gameID, clanPublicID, players[0].PublicID) + Expect(err).NotTo(HaveOccurred()) + Expect(dbMembership.Approved).To(Equal(true)) + Expect(dbMembership.Denied).To(Equal(false)) + + payload = map[string]interface{}{ + "level": "Member", + "playerPublicID": players[0].PublicID, + "message": "Please accept me, I am nice", + } + status, body = PostJSON(a, CreateMembershipRoute(gameID, clanPublicID, "application"), payload) + + Expect(status).To(Equal(http.StatusConflict)) + }) + It("Should create membership application sending a message after player left clan", func() { _, clan, _, players, _, err := models.GetClanWithMemberships(testDb, 0, 0, 0, 1, "", "") Expect(err).NotTo(HaveOccurred()) @@ -229,7 +265,7 @@ var _ = Describe("Membership API Handler", func() { status, body := PostJSON(a, CreateMembershipRoute(gameID, clanPublicID, "application"), payload) - Expect(status).To(Equal(http.StatusInternalServerError)) + Expect(status).To(Equal(http.StatusBadRequest)) var result map[string]interface{} json.Unmarshal([]byte(body), &result) Expect(result["success"]).To(BeFalse()) @@ -581,6 +617,36 @@ var _ = Describe("Membership API Handler", func() { Expect(dbMembership.Denied).To(Equal(false)) }) + It("Should conflict when player is already a member", func() { + _, clan, owner, players, memberships, err := models.GetClanWithMemberships(testDb, 0, 0, 0, 1, "", "") + Expect(err).NotTo(HaveOccurred()) + + memberships[0].RequestorID = memberships[0].PlayerID + _, err = testDb.Update(memberships[0]) + + gameID := clan.GameID + clanPublicID := clan.PublicID + + payload := map[string]interface{}{ + "playerPublicID": players[0].PublicID, + "requestorPublicID": owner.PublicID, + } + status, body := PostJSON(a, CreateMembershipRoute(gameID, clanPublicID, "application/approve"), payload) + + Expect(status).To(Equal(http.StatusOK)) + var result map[string]interface{} + json.Unmarshal([]byte(body), &result) + Expect(result["success"]).To(BeTrue()) + + dbMembership, err := models.GetValidMembershipByClanAndPlayerPublicID(a.Db, gameID, clanPublicID, players[0].PublicID) + Expect(err).NotTo(HaveOccurred()) + Expect(dbMembership.Approved).To(Equal(true)) + Expect(dbMembership.Denied).To(Equal(false)) + + status, body = PostJSON(a, CreateMembershipRoute(gameID, clanPublicID, "application/approve"), payload) + Expect(status).To(Equal(http.StatusConflict)) + }) + It("Should deny membership application", func() { _, clan, owner, players, memberships, err := models.GetClanWithMemberships(testDb, 0, 0, 0, 1, "", "") Expect(err).NotTo(HaveOccurred()) @@ -646,7 +712,7 @@ var _ = Describe("Membership API Handler", func() { status, body := PostJSON(a, CreateMembershipRoute(gameID, clanPublicID, "application/approve"), payload) - Expect(status).To(Equal(http.StatusInternalServerError)) + Expect(status).To(Equal(http.StatusBadRequest)) var result map[string]interface{} json.Unmarshal([]byte(body), &result) Expect(result["success"]).To(BeFalse()) diff --git a/db/migrations.go b/db/migrations.go index 25a045b0..74f59802 100644 --- a/db/migrations.go +++ b/db/migrations.go @@ -99,7 +99,7 @@ func migrations20160608133902_creategametableSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "migrations/20160608133902_CreateGameTable.sql", size: 1193, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160608133902_CreateGameTable.sql", size: 1193, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -119,7 +119,7 @@ func migrations20160608150958_createplayertableSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "migrations/20160608150958_CreatePlayerTable.sql", size: 730, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160608150958_CreatePlayerTable.sql", size: 730, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -139,7 +139,7 @@ func migrations20160608174439_createclantableSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "migrations/20160608174439_CreateClanTable.sql", size: 906, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160608174439_CreateClanTable.sql", size: 906, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -159,7 +159,7 @@ func migrations20160608182307_createmembershiptableSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "migrations/20160608182307_CreateMembershipTable.sql", size: 1018, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160608182307_CreateMembershipTable.sql", size: 1018, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -179,7 +179,7 @@ func migrations20160621161411_createhookstableSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "migrations/20160621161411_CreateHooksTable.sql", size: 700, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160621161411_CreateHooksTable.sql", size: 700, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -199,7 +199,7 @@ func migrations20160627110742_loaduuidmoduleSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "migrations/20160627110742_LoadUUIDModule.sql", size: 113, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160627110742_LoadUUIDModule.sql", size: 113, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -219,7 +219,7 @@ func migrations20160627153918_createretrieveclanindexesSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "migrations/20160627153918_CreateRetrieveClanIndexes.sql", size: 674, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160627153918_CreateRetrieveClanIndexes.sql", size: 674, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -239,7 +239,7 @@ func migrations20160627155249_createplayermembershipandownershipcountSql() (*ass return nil, err } - info := bindataFileInfo{name: "migrations/20160627155249_CreatePlayerMembershipAndOwnershipCount.sql", size: 415, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160627155249_CreatePlayerMembershipAndOwnershipCount.sql", size: 415, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -259,7 +259,7 @@ func migrations20160628181530_createclanmembershipcountSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "migrations/20160628181530_CreateClanMembershipCount.sql", size: 287, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160628181530_CreateClanMembershipCount.sql", size: 287, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -279,7 +279,7 @@ func migrations20160708161944_createmembershipapproverfieldSql() (*asset, error) return nil, err } - info := bindataFileInfo{name: "migrations/20160708161944_CreateMembershipApproverField.sql", size: 409, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160708161944_CreateMembershipApproverField.sql", size: 409, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -299,7 +299,7 @@ func migrations20160708192007_createownerindexSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "migrations/20160708192007_CreateOwnerIndex.sql", size: 250, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160708192007_CreateOwnerIndex.sql", size: 250, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -319,7 +319,7 @@ func migrations20160713185332_creategamecooldownafterdenyanddeleteSql() (*asset, return nil, err } - info := bindataFileInfo{name: "migrations/20160713185332_CreateGameCooldownAfterDenyAndDelete.sql", size: 425, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160713185332_CreateGameCooldownAfterDenyAndDelete.sql", size: 425, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -339,7 +339,7 @@ func migrations20160713191703_createmembershipdenierfieldSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "migrations/20160713191703_CreateMembershipDenierField.sql", size: 401, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160713191703_CreateMembershipDenierField.sql", size: 401, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -359,7 +359,7 @@ func migrations20160728180524_createmaxpendinginvitesfieldSql() (*asset, error) return nil, err } - info := bindataFileInfo{name: "migrations/20160728180524_CreateMaxPendingInvitesField.sql", size: 336, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160728180524_CreateMaxPendingInvitesField.sql", size: 336, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -379,7 +379,7 @@ func migrations20160728195902_createmembershipmessagefieldSql() (*asset, error) return nil, err } - info := bindataFileInfo{name: "migrations/20160728195902_CreateMembershipMessageField.sql", size: 273, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160728195902_CreateMembershipMessageField.sql", size: 273, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -399,7 +399,7 @@ func migrations20160729184159_createcooldownafterinvitefieldSql() (*asset, error return nil, err } - info := bindataFileInfo{name: "migrations/20160729184159_CreateCooldownAfterInviteField.sql", size: 434, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160729184159_CreateCooldownAfterInviteField.sql", size: 434, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -419,7 +419,7 @@ func migrations20160819145352_createhooktriggerfieldsmetadataSql() (*asset, erro return nil, err } - info := bindataFileInfo{name: "migrations/20160819145352_CreateHookTriggerFieldsMetadata.sql", size: 464, mode: os.FileMode(420), modTime: time.Unix(1497552460, 0)} + info := bindataFileInfo{name: "migrations/20160819145352_CreateHookTriggerFieldsMetadata.sql", size: 464, mode: os.FileMode(420), modTime: time.Unix(1509726358, 0)} a := &asset{bytes: bytes, info: info} return a, nil }