Fixing bug where items were allowed to be deleted when referenced by a character

This commit is contained in:
2023-08-15 19:22:07 -05:00
parent abce265ba5
commit 5b9e100028
4 changed files with 85 additions and 5 deletions

View File

@ -69,11 +69,13 @@ var _ = Service("front", func() {
Payload(String) Payload(String)
Result(Empty) Result(Empty)
Error("NotFound") Error("NotFound")
Error("BadRequest")
HTTP(func() { HTTP(func() {
DELETE("/item/{name}") DELETE("/item/{name}")
Response(StatusOK) Response(StatusOK)
Response("NotFound", StatusNotFound) Response("NotFound", StatusNotFound)
Response("BadRequest", StatusBadRequest)
}) })
}) })

View File

@ -10,6 +10,7 @@ import (
genItemClient "crossnokaye-interview-assignment/services/item/gen/grpc/item/client" genItemClient "crossnokaye-interview-assignment/services/item/gen/grpc/item/client"
genItem "crossnokaye-interview-assignment/services/item/gen/item" genItem "crossnokaye-interview-assignment/services/item/gen/item"
"errors" "errors"
"fmt"
"github.com/golang/protobuf/ptypes/empty" "github.com/golang/protobuf/ptypes/empty"
goa "goa.design/goa/v3/pkg" goa "goa.design/goa/v3/pkg"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -35,7 +36,9 @@ type characterClient struct {
type inventoryClient struct { type inventoryClient struct {
addItem goa.Endpoint addItem goa.Endpoint
removeItem goa.Endpoint removeItem goa.Endpoint
removeAll goa.Endpoint
listInventoryItems goa.Endpoint listInventoryItems goa.Endpoint
listCharactersWithItem goa.Endpoint
} }
// front service example implementation. // front service example implementation.
@ -71,7 +74,9 @@ func NewFront(logger *log.Logger, itemClientConnection *grpc.ClientConn, charact
inventoryClient: &inventoryClient{ inventoryClient: &inventoryClient{
icc.AddItem(), icc.AddItem(),
icc.RemoveItem(), icc.RemoveItem(),
icc.RemoveAll(),
icc.ListInventory(), icc.ListInventory(),
icc.ListCharactersWithItem(),
}} }}
} }
@ -130,6 +135,18 @@ func (s *frontsrvc) UpdateItem(ctx context.Context, p *front.Item) (res *front.I
// DeleteItem implements deleteItem. // DeleteItem implements deleteItem.
func (s *frontsrvc) DeleteItem(ctx context.Context, p string) (err error) { func (s *frontsrvc) DeleteItem(ctx context.Context, p string) (err error) {
s.logger.Print("front.deleteItem") s.logger.Print("front.deleteItem")
characterResponse, err := s.inventoryClient.listCharactersWithItem(ctx, &genInventory.ListCharactersWithItemPayload{ItemName: &p})
if err != nil {
return err
}
characters := characterResponse.([]string)
if len(characters) > 0 {
return front.MakeBadRequest(fmt.Errorf("item '%s' is referenced by character(s) %v", p, characters))
}
_, err = s.itemClient.deleteItem(ctx, &genItem.DeleteItemPayload{Name: &p}) _, err = s.itemClient.deleteItem(ctx, &genItem.DeleteItemPayload{Name: &p})
if err != nil { if err != nil {
return err return err
@ -200,6 +217,11 @@ func (s *frontsrvc) DeleteCharacter(ctx context.Context, name string) (err error
return err return err
} }
_, err = s.inventoryClient.removeAll(ctx, &genInventory.RemoveAllPayload{CharacterName: &name})
if err != nil {
return err
}
return return
} }
@ -245,7 +267,7 @@ func (s *frontsrvc) ListInventoryItems(ctx context.Context, payload *front.ListI
} }
itemNames := listInventoryResponse.([]string) itemNames := listInventoryResponse.([]string)
if itemNames == nil { if len(itemNames) == 0 {
return return
} }
itemResponse, err := s.itemClient.listItems(ctx, &genItem.ListItemsPayload{NameFilter: itemNames}) itemResponse, err := s.itemClient.listItems(ctx, &genItem.ListItemsPayload{NameFilter: itemNames})

View File

@ -21,9 +21,24 @@ var _ = Service("inventory", func() {
Field(1, "characterName", String) Field(1, "characterName", String)
}) })
Result(ArrayOf(String)) Result(ArrayOf(String))
Error("NotFound")
GRPC(func() { GRPC(func() {
Response(CodeOK) Response(CodeOK)
Response("NotFound", CodeNotFound)
})
})
Method("listCharactersWithItem", func() {
Payload(func() {
Field(1, "itemName", String)
})
Result(ArrayOf(String))
Error("NotFound")
GRPC(func() {
Response(CodeOK)
Response("NotFound", CodeNotFound)
}) })
}) })
@ -46,4 +61,17 @@ var _ = Service("inventory", func() {
Response("NotFound", CodeNotFound) Response("NotFound", CodeNotFound)
}) })
}) })
Method("removeAll", func() {
Payload(func() {
Field("1", "characterName", String)
})
Result(Empty)
Error("NotFound")
GRPC(func() {
Response(CodeOK)
Response("NotFound", CodeNotFound)
})
})
}) })

View File

@ -57,15 +57,43 @@ func (s *inventorysrvc) RemoveItem(ctx context.Context, p *inventory.InventoryRe
return return
} }
func (s *inventorysrvc) RemoveAll(ctx context.Context, payload *inventory.RemoveAllPayload) (err error) {
s.logger.Print("inventory.removeAll")
itemList := (*s.inventories)[*payload.CharacterName]
if itemList == nil {
s.logger.Printf("inventory for character with name '%s' not found", payload.CharacterName)
return inventory.MakeNotFound(fmt.Errorf("inventory for character with name '%s' not found",
*payload.CharacterName))
}
delete(*s.inventories, *payload.CharacterName)
return
}
func (s *inventorysrvc) ListInventory(ctx context.Context, payload *inventory.ListInventoryPayload) (res []string, err error) { func (s *inventorysrvc) ListInventory(ctx context.Context, payload *inventory.ListInventoryPayload) (res []string, err error) {
s.logger.Print("inventory.listInventory")
if (*s.inventories)[*payload.CharacterName] == nil { if (*s.inventories)[*payload.CharacterName] == nil {
return nil, nil s.logger.Printf("inventory for character with name '%s' not found", payload.CharacterName)
return nil, inventory.MakeNotFound(fmt.Errorf("inventory for character with name '%s' not found",
*payload.CharacterName))
} }
res = *((*s.inventories)[*payload.CharacterName]) res = *((*s.inventories)[*payload.CharacterName])
return return
} }
func (s *inventorysrvc) ListCharactersWithItem(ctx context.Context, payload *inventory.ListCharactersWithItemPayload) (res []string, err error) {
s.logger.Print("inventory.listCharactersWithItem")
for character := range *(s.inventories) {
idxOfItem := indexOf(*payload.ItemName, *(*s.inventories)[character])
if idxOfItem != -1 {
res = append(res, character)
}
}
return
}
func (s *inventorysrvc) initCharacterInventory(characterName string) (itemList *[]string) { func (s *inventorysrvc) initCharacterInventory(characterName string) (itemList *[]string) {
list := make([]string, 0) list := make([]string, 0)
itemList = &list itemList = &list