Skip to content

Commit 031c86d

Browse files
committed
fix: check parent for transaction
1 parent 4de528b commit 031c86d

File tree

3 files changed

+64
-3
lines changed

3 files changed

+64
-3
lines changed

internal/controllers/helper.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,34 @@ func getEnvelope(c *gin.Context) (models.Envelope, error) {
165165
return envelope, nil
166166
}
167167

168+
// getTransaction verifies that the request URI is valid for the transaction and returns it.
169+
func getTransaction(c *gin.Context) (models.Transaction, error) {
170+
var transaction models.Transaction
171+
172+
budget, err := getBudget(c)
173+
if err != nil {
174+
return models.Transaction{}, err
175+
}
176+
177+
accountID, err := parseID(c, "transactionId")
178+
if err != nil {
179+
return models.Transaction{}, err
180+
}
181+
182+
err = models.DB.First(&transaction, &models.Transaction{
183+
BudgetID: budget.ID,
184+
Model: models.Model{
185+
ID: accountID,
186+
},
187+
}).Error
188+
if err != nil {
189+
FetchErrorHandler(c, err)
190+
return models.Transaction{}, err
191+
}
192+
193+
return transaction, nil
194+
}
195+
168196
// FetchErrorHandler handles errors for fetching data from the database.
169197
func FetchErrorHandler(c *gin.Context, err error) {
170198
if errors.Is(err, gorm.ErrRecordNotFound) {

internal/controllers/transaction.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,8 @@ func GetTransactions(c *gin.Context) {
7272

7373
// GetTransaction retrieves an transaction by its ID.
7474
func GetTransaction(c *gin.Context) {
75-
var transaction models.Transaction
76-
err := models.DB.First(&transaction, c.Param("transactionId")).Error
75+
transaction, err := getTransaction(c)
7776
if err != nil {
78-
FetchErrorHandler(c, err)
7977
return
8078
}
8179

internal/controllers/transaction_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,22 @@ func TestNoTransactionNotFound(t *testing.T) {
8181
test.AssertHTTPStatus(t, http.StatusNotFound, &recorder)
8282
}
8383

84+
// TestTransactionInvalidIDs verifies that on non-number requests for transaction IDs,
85+
// the API returs a Bad Request status code.
86+
func TestTransactionInvalidIDs(t *testing.T) {
87+
r := test.Request(t, "GET", "/v1/budgets/1/transactions/-56", "")
88+
test.AssertHTTPStatus(t, http.StatusBadRequest, &r)
89+
90+
r = test.Request(t, "GET", "/v1/budgets/1/transactions/notANumber", "")
91+
test.AssertHTTPStatus(t, http.StatusBadRequest, &r)
92+
93+
r = test.Request(t, "GET", "/v1/budgets/-61/transactions/56", "")
94+
test.AssertHTTPStatus(t, http.StatusBadRequest, &r)
95+
96+
r = test.Request(t, "GET", "/v1/budgets/RandomStringThatIsNotAUint64/transactions/1", "")
97+
test.AssertHTTPStatus(t, http.StatusBadRequest, &r)
98+
}
99+
84100
// TestNonexistingBudgetTransactions404 is a regression test for https://github.com/envelope-zero/backend/issues/89.
85101
//
86102
// It verifies that for a non-existing budget, the accounts endpoint raises a 404
@@ -90,6 +106,25 @@ func TestNonexistingBudgetTransactions404(t *testing.T) {
90106
test.AssertHTTPStatus(t, http.StatusNotFound, &recorder)
91107
}
92108

109+
// TestTransactionParentChecked is a regression test for https://github.com/envelope-zero/backend/issues/90.
110+
//
111+
// It verifies that the transaction details endpoint for a budget only returns transactions that belong to the
112+
// budget.
113+
func TestTransactionParentChecked(t *testing.T) {
114+
r := test.Request(t, "POST", "/v1/budgets", `{ "name": "New Budget", "note": "More tests something something" }`)
115+
test.AssertHTTPStatus(t, http.StatusCreated, &r)
116+
117+
var budget BudgetDetailResponse
118+
test.DecodeResponse(t, &r, &budget)
119+
120+
path := fmt.Sprintf("/v1/budgets/%v", budget.Data.ID)
121+
r = test.Request(t, "GET", path+"/transactions/1", "")
122+
test.AssertHTTPStatus(t, http.StatusNotFound, &r)
123+
124+
r = test.Request(t, "DELETE", path, "")
125+
test.AssertHTTPStatus(t, http.StatusNoContent, &r)
126+
}
127+
93128
func TestCreateTransaction(t *testing.T) {
94129
recorder := test.Request(t, "POST", "/v1/budgets/1/transactions", `{ "note": "More tests something something", "amount": 1253.17 }`)
95130
test.AssertHTTPStatus(t, http.StatusCreated, &recorder)

0 commit comments

Comments
 (0)