diff --git a/README.md b/README.md index f4da31a3c3db23c6a22bd88a23461d1db605c580..fa2ea3c728019256a800bff1696aa1259404774d 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,7 @@ curl --location 'localhost:8080/bankaccounts' \ To increase or decrease the Accountbalance, this Function can be used. The Bankaccount will be detected by the username in the Token-String. ``` -curl --location --request PUT 'localhost:8080/bankaccounts' \ +curl --location --request PUT 'localhost:8080/bankaccounts/transfer' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer INSERT_TOKEN_HERE' \ --data '{ @@ -178,12 +178,15 @@ curl --location 'localhost:8080/shoppingcart/Product/1' \ #### PAY SHOPPINGCART (TOKEN REQUIRED) With this Function, all Products will be buyed. If the Balance is lesser than the Totalprice, the Payment process will be canceled. -If the Payment process is successfull, the Shoppingcart will be tranformed into the default version. +If the Payment process is successfull, the Shoppingcart will be deleted. The user will also be detected with the Token-String. ``` curl --location --request POST 'localhost:8080/shoppingcart/pay' \ --header 'Authorization: Bearer INSERT_TOKEN_HERE' ``` +### Testing the API-Calls +Because of the frequent specification of the JWT token, API calls with CURL can be bothersome. Therefore a postman collection can be imported with the file `go-mazon.postman_collection`. Import this to your Postman for more comfortable tests. + ## Troubleshooting If Docker doesn't detect a specific file, check if in VS-Code all Docker-related files has LF (Line Feed) and not CRLF (Carriage Return). \ No newline at end of file diff --git a/go-mazon.postman_collection.json b/go-mazon.postman_collection.json new file mode 100644 index 0000000000000000000000000000000000000000..998a104014349e3228d18aeddd0833e20d61d09b --- /dev/null +++ b/go-mazon.postman_collection.json @@ -0,0 +1,484 @@ +{ + "info": { + "_postman_id": "296ee443-995b-40b8-8d80-e20b0cce75e7", + "name": "go-mazon", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "27954253" + }, + "item": [ + { + "name": "Product", + "item": [ + { + "name": "New Product (Admin only)", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODkwNTU0NTEsImlzQWRtaW4iOnRydWUsInVzZXJuYW1lIjoiYWRtaW4ifQ.m_Ftfnb5ZHGV6fOCgY6-uIz19z1g-Ln976VdtfXHjJM", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"name\": \"IPhone\",\r\n \"description\": \"Smartphone\",\r\n \"price\": 1200.00\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8080/products", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "products" + ] + } + }, + "response": [] + }, + { + "name": "Get Product", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "localhost:8080/products", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "products" + ] + } + }, + "response": [] + }, + { + "name": "Get Single Product", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "localhost:8080/products/1", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "products", + "1" + ] + } + }, + "response": [] + }, + { + "name": "Update Product (Admin only)", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODkwNTU0NTEsImlzQWRtaW4iOnRydWUsInVzZXJuYW1lIjoiYWRtaW4ifQ.m_Ftfnb5ZHGV6fOCgY6-uIz19z1g-Ln976VdtfXHjJM", + "type": "string" + } + ] + }, + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"name\": \"AirPodsv2\",\r\n \"description\": \"bessere Akkuleistung\",\r\n \"price\": 150.00\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8080/products/1", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "products", + "1" + ] + } + }, + "response": [] + }, + { + "name": "Delete Product (Admin only)", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODkwNTU0NTEsImlzQWRtaW4iOnRydWUsInVzZXJuYW1lIjoiYWRtaW4ifQ.m_Ftfnb5ZHGV6fOCgY6-uIz19z1g-Ln976VdtfXHjJM", + "type": "string" + } + ] + }, + "method": "DELETE", + "header": [], + "url": { + "raw": "localhost:8080/products/1", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "products", + "1" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Shopping Cart", + "item": [ + { + "name": "Create Shopping Cart", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODkwNTU0MjgsImlzQWRtaW4iOmZhbHNlLCJ1c2VybmFtZSI6Imt1bmRlIn0.xhUq428zDHSbeVdENzo99Gy_FZ3KTdDArcHKcmHUUjA", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "url": { + "raw": "localhost:8080/shoppingcart", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "shoppingcart" + ] + } + }, + "response": [] + }, + { + "name": "Add Product to Shopping Cart", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODkwNTY4MTQsImlzQWRtaW4iOnRydWUsInVzZXJuYW1lIjoiYWRtaW4ifQ.hk1ZetULOkGLkYcPPVGidp5Y9w-Rzsxa-ja0WWC-CSA", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"amount\": 1\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8080/shoppingcart/product/1", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "shoppingcart", + "product", + "1" + ] + } + }, + "response": [] + }, + { + "name": "Pay", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODkwNTY4MTQsImlzQWRtaW4iOnRydWUsInVzZXJuYW1lIjoiYWRtaW4ifQ.hk1ZetULOkGLkYcPPVGidp5Y9w-Rzsxa-ja0WWC-CSA", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "url": { + "raw": "localhost:8080/shoppingcart/pay", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "shoppingcart", + "pay" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Bank", + "item": [ + { + "name": "Add Bankacc", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODkwNTY4MTQsImlzQWRtaW4iOnRydWUsInVzZXJuYW1lIjoiYWRtaW4ifQ.hk1ZetULOkGLkYcPPVGidp5Y9w-Rzsxa-ja0WWC-CSA", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"iban\": \"DE1234\",\r\n \"bankName\": \"Sparkasse\",\r\n \"balance\": -2000.00\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8080/bankaccounts", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "bankaccounts" + ] + } + }, + "response": [] + }, + { + "name": "Transaction", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODkwMTk5NjYsImlzQWRtaW4iOnRydWUsInVzZXJuYW1lIjoia3VuZGUifQ.eLJ0Bv50HcZT5zpEoKgnSo4AeildgHH_ABSr0AXxzkM", + "type": "string" + } + ] + }, + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"amount\": 5000.0\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8080/bankaccounts/transfer", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "bankaccounts", + "transfer" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Rating", + "item": [ + { + "name": "New Rating", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODkwNTU0MjgsImlzQWRtaW4iOmZhbHNlLCJ1c2VybmFtZSI6Imt1bmRlIn0.xhUq428zDHSbeVdENzo99Gy_FZ3KTdDArcHKcmHUUjA", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"Content\": \"Fantastic Product!\",\r\n \"Rating\": 0\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8080/products/1/rating", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "products", + "1", + "rating" + ] + } + }, + "response": [] + }, + { + "name": "Delete Rating", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODkwNTU0NTEsImlzQWRtaW4iOnRydWUsInVzZXJuYW1lIjoiYWRtaW4ifQ.m_Ftfnb5ZHGV6fOCgY6-uIz19z1g-Ln976VdtfXHjJM", + "type": "string" + } + ] + }, + "method": "DELETE", + "header": [], + "url": { + "raw": "localhost:8080/ratings/3", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "ratings", + "3" + ] + } + }, + "response": [] + }, + { + "name": "Read Ratings", + "request": { + "auth": { + "type": "noauth" + }, + "method": "GET", + "header": [], + "url": { + "raw": "localhost:8080/ratings", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "ratings" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Token", + "item": [ + { + "name": "Get JWT", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"username\": \"admin\",\r\n \"isAdmin\": true\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8080/createJWT", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "createJWT" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Health", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "localhost:8080/health", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "health" + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/src/gomazon/model/position.go b/src/gomazon/model/position.go index 0b26aec5da50037c46818b642197c94134fa6d30..e5fc5d5d7d61f817a811c007f807e2d9318c053e 100644 --- a/src/gomazon/model/position.go +++ b/src/gomazon/model/position.go @@ -4,9 +4,9 @@ import "gorm.io/gorm" type Position struct { gorm.Model - Amount int `gorm:"notNull"` - ProductId uint `gorm:"notNull"` - Price float64 `gorm:"notNull"` - Totalprice float64 `gorm:"notNull"` - ShoppingCartId uint `gorm:"notNull"` + Amount int `gorm:"notNull"` + ProductId uint `gorm:"notNull"` + Price float64 `gorm:"notNull"` + Totalprice float64 `gorm:"notNull"` + //ShoppingcartId uint `gorm:"notNull"` } diff --git a/src/gomazon/model/shopping_cart.go b/src/gomazon/model/shopping_cart.go index 4964177f8a1f45705cebbb9dad696de5aee176c8..2c9f1db0469cb6e6d74184006b3ff31484b32f87 100644 --- a/src/gomazon/model/shopping_cart.go +++ b/src/gomazon/model/shopping_cart.go @@ -6,5 +6,5 @@ type ShoppingCart struct { gorm.Model Positions []Position `gorm:"foreignKey:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` Totalprice float64 `gorm:"notNull;default:0.0"` - Username string `gorm:"unique"` + Username string `gorm:"notNull"` } diff --git a/src/gomazon/service/bank.go b/src/gomazon/service/bank.go index 7d4c4b631fc112328935aa9a0e8b7624a5a2672f..dae74b9d5691815795fdf5c88986b7fc1ab76a14 100644 --- a/src/gomazon/service/bank.go +++ b/src/gomazon/service/bank.go @@ -23,6 +23,11 @@ func (s *BankAccountService) CreateBankAccount(bankAccount model.BankAccount) (* return nil, result.Error } + if bankAccount.Balance < 0 { + log.Error("Balance must be a positive value") + return nil, fmt.Errorf("balance must be a positive value") + } + result = db.DB.Create(&bankAccount) if result.Error != nil { log.Error("Could not create Bankaccount") diff --git a/src/gomazon/service/product.go b/src/gomazon/service/product.go index 48a0b553e1e85d18a68ff71d6fbce9643dce6406..6f36cfb868a645373181103ae8c2633c1f29922e 100644 --- a/src/gomazon/service/product.go +++ b/src/gomazon/service/product.go @@ -10,6 +10,8 @@ type ProductService struct{} // Create Product func (s *ProductService) CreateProduct(Product model.Product) (*model.Product, error) { + var ratings []model.Rating + Product.Ratings = ratings result := db.DB.Create(&Product) if result.Error != nil { log.Error("Could not create Product") diff --git a/src/gomazon/service/rating.go b/src/gomazon/service/rating.go index e0b7a53f09e96b45e57856956196f249dd09f873..9b02d7b25cef2a99956e6450d76879a7f4e22f62 100644 --- a/src/gomazon/service/rating.go +++ b/src/gomazon/service/rating.go @@ -25,6 +25,15 @@ func (s *RatingService) CreateRating(ProductID uint, Rating *model.Rating) error log.Errorf("Error in CreateRating: GetProductByID failed") return nil } + + Product.Ratings = append(Product.Ratings, *Rating) + + result = db.DB.Save(&Product) + if result.Error != nil { + log.Error("Could not save Product") + return result.Error + } + // Recalculate Rating for this product err = RecalculateTotalratingForProduct(Product) if err != nil { diff --git a/src/gomazon/service/shopping_cart.go b/src/gomazon/service/shopping_cart.go index db8744596136aee51057dcca606b8043aa0c8ac7..f1139c9681621edb86ed4830d2b56292d98ee4d0 100644 --- a/src/gomazon/service/shopping_cart.go +++ b/src/gomazon/service/shopping_cart.go @@ -56,11 +56,11 @@ func (s *ShoppingCartService) AddProductToShoppingCart(username string, ProductI gesPrice := Product.Price * float64(amount) position := model.Position{ - Amount: amount, - ProductId: Product.ID, - Price: Product.Price, - Totalprice: gesPrice, - ShoppingCartId: ShoppingCart.ID, + Amount: amount, + ProductId: Product.ID, + Price: Product.Price, + Totalprice: gesPrice, + //ShoppingcartId: ShoppingCart.ID, } // Add position to shoppingcart