diff --git a/api/src/controller/controller.go b/api/src/controller/controller.go index 901cc2c..a49025e 100644 --- a/api/src/controller/controller.go +++ b/api/src/controller/controller.go @@ -191,5 +191,57 @@ func (pg *PgController) Serve() *gin.Engine { c.JSON(http.StatusNoContent, "Deleted Gift") }) + // Add Gift to Gift Collection + r.POST("/addGiftCollection/:id", func(c *gin.Context) { + var input model.Gift + + // Get Gift Collection Id + id := c.Param("id") + intId, err := strconv.Atoi(id) + if err != nil { + panic(err) + } + + if err := c.BindJSON(&input); err != nil { + c.JSON(http.StatusBadRequest, "Failed to unmarshal collection") + fmt.Print(err) + return + } + + giftAddedCollection, err := pg.AddGiftToGiftCollection(input, int64(intId)) + + if err != nil { + c.JSON(http.StatusBadRequest, input) + panic(err) + } + + c.JSON(http.StatusOK, giftAddedCollection) + }) + + // Delete Gift to Gift Collection + r.DELETE("/removeGiftFromGiftCollection/:giftID/:giftCollectionID", func(c *gin.Context) { + var input model.Gift + + // Get Gift Collection Id + collectionID, err := strconv.Atoi(c.Param("giftCollectionID")) + if err != nil { + panic(err) + } + + giftID, err := strconv.Atoi(c.Param("giftID")) + if err != nil { + panic(err) + } + + giftRemovedCollection, err := pg.DeleteGiftFromGiftCollection(int64(giftID), int64(collectionID)) + + if err != nil { + c.JSON(http.StatusBadRequest, input) + panic(err) + } + + c.JSON(http.StatusOK, giftRemovedCollection) + }) + return r } diff --git a/api/src/model/model.go b/api/src/model/model.go index b35bd9b..389e602 100644 --- a/api/src/model/model.go +++ b/api/src/model/model.go @@ -14,6 +14,7 @@ type Model interface { AddCollection(GiftCollection) (GiftCollection, error) IncompleteRequests() ([]GiftRequest, error) CompleteRequests() ([]GiftRequest, error) + GetGift(int64) (Gift, error) GetAllGifts() ([]Gift, error) AddGift(Gift) (Gift, error) @@ -21,6 +22,8 @@ type Model interface { DeleteGift(int64) error AllGiftResponses() ([]GiftResponse, error) AllCollections() ([]GiftCollection, error) + AddGiftToGiftCollection(Gift, int64) (GiftCollection, error) + DeleteGiftFromGiftCollection(int64, int64) (GiftCollection, error) } func (m *PgModel) AddRequest(inputRequest GiftRequest) (GiftRequest, error) { @@ -75,7 +78,6 @@ func (m *PgModel) GetGift(id int64) (Gift, error) { return createdGift, nil } - func (m *PgModel) GetAllGifts() ([]Gift, error) { createdGifts, err := GetAllGiftsFromDB(m.Conn) @@ -118,7 +120,6 @@ func (m *PgModel) DeleteGift(id int64) error { return nil } - func (m *PgModel) AllCollections() ([]GiftCollection, error) { collections, err := GetAllCollectionsFromDB(m.Conn) @@ -146,4 +147,24 @@ func (m *PgModel) CompleteRequests() ([]GiftRequest, error) { return gifts, nil } +func (m *PgModel) AddGiftToGiftCollection(inputGift Gift, id int64) (GiftCollection, error) { + giftAddedCollection, err := AddGiftToCollectionFromDB(m.Conn, inputGift, id) + + if err != nil { + return GiftCollection{}, err + } + + return giftAddedCollection, nil +} + +func (m *PgModel) DeleteGiftFromGiftCollection(giftID int64, giftCollectionID int64) (GiftCollection, error) { + + giftDeletedCollection, err := DeleteGiftFromCollectionFromDB(m.Conn, giftID, giftCollectionID) + + if err != nil { + return GiftCollection{}, err + } + + return giftDeletedCollection, nil +} diff --git a/api/src/model/transactions.go b/api/src/model/transactions.go index cae98e4..0176b30 100644 --- a/api/src/model/transactions.go +++ b/api/src/model/transactions.go @@ -40,13 +40,26 @@ func UpdateGiftToDb(db *gorm.DB, id int64, inputGift Gift) (Gift, error) { } // Update Gift Record - updates := map[string]interface{}{ - "Name": inputGift.Name, - "Price": inputGift.Price, - "Link": inputGift.Link, - "Description": inputGift.Description, - "Demographic": inputGift.Demographic, - "GiftCollections": inputGift.GiftCollections, + updates := make(map[string]interface{}) + + // Check each field in inputGift and add it to the updates map if it is non-zero + if inputGift.Name != "" { + updates["Name"] = inputGift.Name + } + if inputGift.Price != 0 { + updates["Price"] = inputGift.Price + } + if inputGift.Link != "" { + updates["Link"] = inputGift.Link + } + if inputGift.Description != "" { + updates["Description"] = inputGift.Description + } + if inputGift.Demographic != "" { + updates["Demographic"] = inputGift.Demographic + } + if inputGift.GiftCollections != nil && len(inputGift.GiftCollections) > 0 { + updates["GiftCollections"] = inputGift.GiftCollections } if err := db.Model(&updatedGift).Updates(updates).Error; err != nil { @@ -122,3 +135,38 @@ func GetAllCollectionsFromDB(db *gorm.DB) ([]GiftCollection, error) { } return collections, nil } + +func AddGiftToCollectionFromDB(db *gorm.DB, inputGift Gift, id int64) (GiftCollection, error) { + var collection GiftCollection + if err := db.Where("id = ?", id).First(&collection).Error; err != nil { + return GiftCollection{}, err + } + + collection.Gifts = append(collection.Gifts, &inputGift) + + if err := db.Save(&collection).Error; err != nil { + return GiftCollection{}, err + } + + return collection, nil +} + +func DeleteGiftFromCollectionFromDB(db *gorm.DB, giftID int64, giftCollectionID int64) (GiftCollection, error) { + var collection GiftCollection + if err := db.Preload("Gifts").First(&collection, giftCollectionID).Error; err != nil { + return GiftCollection{}, err + } + + // Create a new GiftCollection array without the inputGift + var giftRemovedCollection []*Gift + for _, gift := range collection.Gifts { + if gift.ID != uint(giftID) { + giftRemovedCollection = append(giftRemovedCollection, gift) + } + } + if err := db.Model(&collection).Association("Gifts").Replace(giftRemovedCollection); err != nil { + return GiftCollection{}, err + } + + return collection, nil +} diff --git a/api/tests/api_test.go b/api/tests/api_test.go index d5756aa..0d70c1f 100644 --- a/api/tests/api_test.go +++ b/api/tests/api_test.go @@ -601,7 +601,6 @@ func TestUpdateGift(t *testing.T) { updatedTestGift := model.Gift{ Name: "updatedgift1", Price: 100, - Link: "updatedlink1", Description: "updateddescription1", Demographic: "updateddemogrpahic1", GiftCollections: nil, @@ -624,15 +623,17 @@ func TestUpdateGift(t *testing.T) { if e := json.Unmarshal(w.Body.Bytes(), &updatedGiftRetrieved); e != nil { t.Fatalf("Error unmarshaling JSON: %v", e) } + fmt.Print(updatedGiftRetrieved.ID) var fetchedUpdatedGift model.Gift err = tx.First(&fetchedUpdatedGift, updatedGiftRetrieved.ID).Error + assert.NoError(t, err) err = tx.First(&updatedGiftRetrieved, fetchedUpdatedGift.ID).Error assert.NoError(t, err) assert.Equal(t, fetchedUpdatedGift.ID, updatedGiftRetrieved.ID) assert.Equal(t, fetchedUpdatedGift.Name, updatedGiftRetrieved.Name) assert.Equal(t, fetchedUpdatedGift.Price, updatedGiftRetrieved.Price) - assert.Equal(t, fetchedUpdatedGift.Link, updatedGiftRetrieved.Link) + assert.Equal(t, "link1", updatedGiftRetrieved.Link) assert.Equal(t, fetchedUpdatedGift.Description, updatedGiftRetrieved.Description) assert.Equal(t, fetchedUpdatedGift.Demographic, updatedGiftRetrieved.Demographic) assert.Equal(t, fetchedUpdatedGift.Link, updatedGiftRetrieved.Link) @@ -641,7 +642,7 @@ func TestUpdateGift(t *testing.T) { // Check that there's only 1 Gift var count int64 - db.Model(&model.Gift{}).Where("id = ?", updatedGiftRetrieved.ID).Count(&count) + tx.Model(&model.Gift{}).Where("id = ?", fetchedUpdatedGift.ID).Count(&count) assert.Equal(t, int64(1), count) } @@ -716,7 +717,6 @@ func TestDeleteGift(t *testing.T) { assert.Equal(t, int64(0), deletedCount) } - func TestGetAllGift(t *testing.T) { // Database setup dsn := "user=testuser password=testpwd host=localhost port=5433 dbname=testdb sslmode=disable" @@ -744,20 +744,20 @@ func TestGetAllGift(t *testing.T) { // Test code w := httptest.NewRecorder() gift := model.Gift{ - Name: "nice sweater", - Price: 50, - Link: "https://something", - Description: "sample description", - Demographic: "sample demographic", + Name: "nice sweater", + Price: 50, + Link: "https://something", + Description: "sample description", + Demographic: "sample demographic", GiftCollections: []*model.GiftCollection{}, } gift_two := model.Gift{ - Name: "nice sweater 2", - Price: 20, - Link: "https://something 2", - Description: "sample description 2", - Demographic: "sample demographic 2", + Name: "nice sweater 2", + Price: 20, + Link: "https://something 2", + Description: "sample description 2", + Demographic: "sample demographic 2", GiftCollections: []*model.GiftCollection{}, } err = tx.Create(&gift).Error @@ -820,15 +820,15 @@ func TestGetAllGiftCollection(t *testing.T) { uintValue := uint(5) collection := model.GiftCollection{ - CustomerID: &uintValue, + CustomerID: &uintValue, CollectionName: "sample name", - Gifts: []*model.Gift{}, + Gifts: []*model.Gift{}, } - + uintValue = uint(6) collection_two := model.GiftCollection{ - CustomerID: &uintValue, + CustomerID: &uintValue, CollectionName: "sample name 2", - Gifts: []*model.Gift{}, + Gifts: []*model.Gift{}, } err = db.Create(&collection).Error @@ -888,13 +888,12 @@ func TestGetAllGiftResponse(t *testing.T) { response := model.GiftResponse{ GiftCollection: collection, - CustomMessage: "sample custom message", + CustomMessage: "sample custom message", } - response_two := model.GiftResponse{ GiftCollection: collection, - CustomMessage: "sample custom message 2", + CustomMessage: "sample custom message 2", } err = tx.Create(&response).Error @@ -922,3 +921,166 @@ func TestGetAllGiftResponse(t *testing.T) { } +func TestAddGiftToCollection(t *testing.T) { + // Database setup + dsn := "user=testuser password=testpwd host=localhost port=5433 dbname=testdb sslmode=disable" + if dbURL, exists := os.LookupEnv("TEST_DATABASE_URL"); exists { + dsn = dbURL + } + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + if err != nil { + t.Fatalf("Unable to connect to database: %v", err) + } + // Put auto migrations here + err = db.AutoMigrate(&model.GiftCollection{}, &model.Gift{}) + if err != nil { + panic("failed to migrate test database schema") + } + // Wrap the DB connection in a transaction + tx := db.Begin() + defer tx.Rollback() + + // Create Model and Controller + m := &model.PgModel{Conn: tx} + c := &c.PgController{Model: m} + router := c.Serve() + + // Test code + w1 := httptest.NewRecorder() + w2 := httptest.NewRecorder() + + // Create a new Gift Collection + collection := model.GiftCollection{ + Gifts: []*model.Gift{}, + CollectionName: "collection", + } + + collectionJSON, err := json.Marshal(collection) + if err != nil { + t.Fatalf("Error marshaling JSON: %v", err) + } + assert.NoError(t, err) + req1, err := http.NewRequest("POST", fmt.Sprintf("/addGiftCollection"), bytes.NewBuffer(collectionJSON)) + router.ServeHTTP(w1, req1) + assert.Equal(t, 200, w1.Code) + + var addedCollection model.GiftCollection + if e := json.Unmarshal(w1.Body.Bytes(), &addedCollection); e != nil { + t.Fatalf("Error unmarshaling JSON: %v", e) + } + var retrievedCollection model.GiftCollection + err = tx.Preload("Gifts").First(&retrievedCollection, "id = ?", addedCollection.ID).Error + assert.NoError(t, err) + assert.Equal(t, retrievedCollection.CollectionName, addedCollection.CollectionName) + + // Add Gift to Gift Collection + gift := model.Gift{ + Name: "Gift1", + } + giftJSON, err := json.Marshal(gift) + if err != nil { + t.Fatalf("Error marshaling JSON: %v", err) + } + assert.NoError(t, err) + req2, err := http.NewRequest("POST", fmt.Sprintf("/addGiftCollection/%d", addedCollection.ID), bytes.NewBuffer(giftJSON)) + router.ServeHTTP(w2, req2) + assert.Equal(t, 200, w2.Code) + + var giftAddedCollection model.GiftCollection + if e := json.Unmarshal(w2.Body.Bytes(), &giftAddedCollection); e != nil { + t.Fatalf("Error unmarshaling JSON: %v", e) + } + var giftAddedRetrievedCollection model.GiftCollection + err = tx.Preload("Gifts").First(&giftAddedRetrievedCollection, "id = ?", giftAddedCollection.ID).Error + assert.NoError(t, err) + assert.Equal(t, giftAddedRetrievedCollection.CollectionName, giftAddedCollection.CollectionName) + assert.Equal(t, giftAddedRetrievedCollection.Gifts[0].Name, giftAddedCollection.Gifts[0].Name) +} + +func TestGiftDeleteFromCollection(t *testing.T) { + // Database setup + dsn := "user=testuser password=testpwd host=localhost port=5433 dbname=testdb sslmode=disable" + if dbURL, exists := os.LookupEnv("TEST_DATABASE_URL"); exists { + dsn = dbURL + } + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + if err != nil { + t.Fatalf("Unable to connect to database: %v", err) + } + // Put auto migrations here + err = db.AutoMigrate(&model.GiftCollection{}, &model.Gift{}) + if err != nil { + panic("failed to migrate test database schema") + } + // Wrap the DB connection in a transaction + tx := db.Begin() + defer tx.Rollback() + + // Create Model and Controller + m := &model.PgModel{Conn: tx} + c := &c.PgController{Model: m} + router := c.Serve() + + // Test code + w1 := httptest.NewRecorder() + w2 := httptest.NewRecorder() + + gift := model.Gift{ + Name: "Gift1", + } + err = tx.Create(&gift).Error + assert.NoError(t, err) + + collection := model.GiftCollection{ + Gifts: []*model.Gift{&gift}, + CollectionName: "collection", + } + + collectionJSON, err := json.Marshal(collection) + if err != nil { + t.Fatalf("Error marshaling JSON: %v", err) + } + + assert.NoError(t, err) + req1, err := http.NewRequest("POST", fmt.Sprintf("/addGiftCollection"), bytes.NewBuffer(collectionJSON)) + router.ServeHTTP(w1, req1) + assert.Equal(t, 200, w1.Code) + + var addedCollection model.GiftCollection + if e := json.Unmarshal(w1.Body.Bytes(), &addedCollection); e != nil { + t.Fatalf("Error unmarshaling JSON: %v", e) + } + + var retrievedCollection model.GiftCollection + err = tx.Preload("Gifts").First(&retrievedCollection, "id = ?", addedCollection.ID).Error + assert.NoError(t, err) + assert.Equal(t, retrievedCollection.Gifts[0].ID, addedCollection.Gifts[0].ID) + assert.Equal(t, retrievedCollection.CollectionName, addedCollection.CollectionName) + assert.Equal(t, retrievedCollection.Gifts[0].Name, addedCollection.Gifts[0].Name) + + var count1 int64 + count1 = int64(len(retrievedCollection.Gifts)) + assert.Equal(t, int64(1), count1) + + // Delete Gift from Gift Collection + assert.NoError(t, err) + fmt.Print(retrievedCollection.Gifts[0].ID) + fmt.Print(retrievedCollection.ID) + fmt.Print(addedCollection.ID) + req2, err := http.NewRequest("DELETE", fmt.Sprintf("/removeGiftFromGiftCollection/%d/%d", retrievedCollection.Gifts[0].ID, addedCollection.ID), nil) + router.ServeHTTP(w2, req2) + assert.Equal(t, 200, w2.Code) + + var giftDeletedCollection model.GiftCollection + if e := json.Unmarshal(w2.Body.Bytes(), &giftDeletedCollection); e != nil { + t.Fatalf("Error unmarshaling JSON: %v", e) + } + var giftDeletedRetrievedCollection model.GiftCollection + err = tx.Preload("Gifts").First(&giftDeletedRetrievedCollection, "id = ?", giftDeletedCollection.ID).Error + assert.NoError(t, err) + assert.Equal(t, giftDeletedRetrievedCollection.CollectionName, giftDeletedCollection.CollectionName) + + var count2 int64 + count2 = int64(len(giftDeletedRetrievedCollection.Gifts)) + assert.Equal(t, int64(0), count2) +}