Add transfer allowance functionality with error handling
This commit is contained in:
parent
b93f71aaf7
commit
8e2e5e6f71
@ -1039,7 +1039,7 @@ func TestTransferInsufficientFunds(t *testing.T) {
|
|||||||
transfer := map[string]interface{}{"from": 1, "to": 2, "amount": 10}
|
transfer := map[string]interface{}{"from": 1, "to": 2, "amount": 10}
|
||||||
resp := e.POST("/transfer").WithJSON(transfer).Expect().Status(400).JSON().Object()
|
resp := e.POST("/transfer").WithJSON(transfer).Expect().Status(400).JSON().Object()
|
||||||
// Error text should mention insufficient funds
|
// Error text should mention insufficient funds
|
||||||
resp.Value("error").String().Contains("insufficient")
|
resp.Value("error").String().ContainsFold("insufficient")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTransferNotFound(t *testing.T) {
|
func TestTransferNotFound(t *testing.T) {
|
||||||
|
@ -746,7 +746,7 @@ func (db *Db) TransferAllowance(fromId int, toId int, amount float64) error {
|
|||||||
|
|
||||||
// Ensure same owner
|
// Ensure same owner
|
||||||
if fromUserId != toUserId {
|
if fromUserId != toUserId {
|
||||||
return fmt.Errorf("allowances do not belong to the same user")
|
return fmt.Errorf(ErrDifferentUsers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate how much the 'to' goal still needs
|
// Calculate how much the 'to' goal still needs
|
||||||
@ -764,7 +764,7 @@ func (db *Db) TransferAllowance(fromId int, toId int, amount float64) error {
|
|||||||
|
|
||||||
// Ensure 'from' has enough balance
|
// Ensure 'from' has enough balance
|
||||||
if fromBalance < transfer {
|
if fromBalance < transfer {
|
||||||
return fmt.Errorf("insufficient funds in source allowance")
|
return fmt.Errorf(ErrInsufficientFunds)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform updates
|
// Perform updates
|
||||||
|
@ -25,6 +25,8 @@ const (
|
|||||||
ErrInvalidUserID = "Invalid user ID"
|
ErrInvalidUserID = "Invalid user ID"
|
||||||
ErrUserNotFound = "User not found"
|
ErrUserNotFound = "User not found"
|
||||||
ErrCheckingUserExist = "Error checking user existence: %v"
|
ErrCheckingUserExist = "Error checking user existence: %v"
|
||||||
|
ErrInsufficientFunds = "Insufficient funds in source allowance"
|
||||||
|
ErrDifferentUsers = "Allowances do not belong to the same user"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServerConfig holds configuration for the server.
|
// ServerConfig holds configuration for the server.
|
||||||
@ -644,6 +646,32 @@ func getHistory(c *gin.Context) {
|
|||||||
c.IndentedJSON(http.StatusOK, history)
|
c.IndentedJSON(http.StatusOK, history)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func transfer(c *gin.Context) {
|
||||||
|
var transferRequest TransferRequest
|
||||||
|
if err := c.ShouldBindJSON(&transferRequest); err != nil {
|
||||||
|
log.Printf("Error parsing request body: %v", err)
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := db.TransferAllowance(transferRequest.From, transferRequest.To, transferRequest.Amount)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, mysqlite.ErrNoRows) {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "Allowance not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err.Error() == ErrInsufficientFunds || err.Error() == ErrDifferentUsers {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("Error transferring allowance: %v", err)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": ErrInternalServerError})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{"message": "Transfer successful"})
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initialises the database, and then starts the server.
|
Initialises the database, and then starts the server.
|
||||||
If the context gets cancelled, the server is shutdown and the database is closed.
|
If the context gets cancelled, the server is shutdown and the database is closed.
|
||||||
@ -679,6 +707,7 @@ func start(ctx context.Context, config *ServerConfig) {
|
|||||||
router.PUT("/api/task/:taskId", putTask)
|
router.PUT("/api/task/:taskId", putTask)
|
||||||
router.DELETE("/api/task/:taskId", deleteTask)
|
router.DELETE("/api/task/:taskId", deleteTask)
|
||||||
router.POST("/api/task/:taskId/complete", completeTask)
|
router.POST("/api/task/:taskId/complete", completeTask)
|
||||||
|
router.POST("/api/transfer", transfer)
|
||||||
|
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: config.Addr,
|
Addr: config.Addr,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user