Skip to content

Commit

Permalink
Delete an expense via the casheer client
Browse files Browse the repository at this point in the history
This change adds a method to the casheer client to allow deleting
an expense, given an entry id. It also tests the functionality end
to end.
  • Loading branch information
Ozoniuss committed Feb 7, 2024
1 parent b032c43 commit 235f4f4
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 30 deletions.
2 changes: 1 addition & 1 deletion client/httpclient/calls/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ import (

// MakeDELETE makes a simple DELETE request to the target url, and returns
// either a typed response or an error response.
func MakeDELETE[T casheerapi.DeleteDebtResponse](client *http.Client, url string) (T, error) {
func MakeDELETE[T casheerapi.DeleteDebtResponse | casheerapi.DeleteExpenseResponse](client *http.Client, url string) (T, error) {
return makeRequest[T]("DELETE", client, url, nil, nil)
}
5 changes: 5 additions & 0 deletions client/httpclient/expenses.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,8 @@ func (c *CasheerHTTPClient) CreateBasicExpenseWithoutId(category string, subcate
}
return c.CreateBasicExpense(entryId, name, description, paymentMethod, amount, currency)
}

func (c *CasheerHTTPClient) DeleteExpenseForEntry(entryId, expenseId int) (public.DeleteExpenseResponse, error) {
requestURL := c.entriesURL.JoinPath(strconv.Itoa(entryId), "expenses/", strconv.Itoa(expenseId)).String()
return calls.MakeDELETE[public.DeleteExpenseResponse](c.httpClient, requestURL)
}
103 changes: 74 additions & 29 deletions e2e/expenses_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,56 +20,101 @@ func setupEntry(t *testing.T) int {
return id
}

func Test_CreateBasicExpense_ExpenseIsCreated_and_ReturnedValuesAreCorrect(t *testing.T) {

t.Cleanup(func() {
store.DeleteAllData(conn)
})
entid := setupEntry(t)
type basicExpenseInfo struct {
name string
description string
paymentMethod string
amount int
currency string
}

var name = "expense 1"
var description = "description"
var paymentMethod = "card"
var amount = 1500
var ccurrency = "RON"
expenseResponse, err := casheerClient.CreateBasicExpense(entid, name, description, paymentMethod, amount, ccurrency)
if err != nil {
t.Fatalf("Did not expect error when creating expense, but got error: %s\n", err.Error())
func getDummyExpenseInfo() basicExpenseInfo {
return basicExpenseInfo{
name: "name",
description: "description",
paymentMethod: "card",
amount: 1500,
currency: "RON",
}
}

if expenseResponse.Data.Type != "expense" {
t.Errorf("Invalid return type, expected \"expense\" but got \"%s\"\n", expenseResponse.Data.Type)
func compareExpenseWithResponse(t *testing.T, expenseInfo basicExpenseInfo, responseData casheerapi.ExpenseData) {
if responseData.Type != "expense" {
t.Errorf("Invalid return type, expected \"expense\" but got \"%s\"\n", responseData.Type)
}

// Check attributes
if expenseResponse.Data.Attributes.Name != name {
t.Errorf("Expense name doesn't match; expected %s but got %s\n", name, expenseResponse.Data.Attributes.Name)
if responseData.Attributes.Name != expenseInfo.name {
t.Errorf("Expense name doesn't match; expected %s but got %s\n", expenseInfo.name, responseData.Attributes.Name)
}
if expenseResponse.Data.Attributes.Description != description {
t.Errorf("Expense description doesn't match; expected %s but got %s\n", description, expenseResponse.Data.Attributes.Description)
if responseData.Attributes.Description != expenseInfo.description {
t.Errorf("Expense description doesn't match; expected %s but got %s\n", expenseInfo.description, responseData.Attributes.Description)
}
if expenseResponse.Data.Attributes.PaymentMethod != paymentMethod {
t.Errorf("Expense payment method doesn't match; expected %s but got %s\n", paymentMethod, expenseResponse.Data.Attributes.PaymentMethod)
if responseData.Attributes.PaymentMethod != expenseInfo.paymentMethod {
t.Errorf("Expense payment method doesn't match; expected %s but got %s\n", expenseInfo.paymentMethod, responseData.Attributes.PaymentMethod)
}
val := currency.NewRONValue(1500)
if expenseResponse.Data.Attributes.Value != (casheerapi.MonetaryValueAttributes{

val := currency.NewRONValue(expenseInfo.amount)
if responseData.Attributes.Value != (casheerapi.MonetaryValueAttributes{
Amount: val.Amount,
Exponent: val.Exponent,
Currency: val.Currency,
}) {
t.Errorf("Expense value doesn't match; expected %v but got %v\n", expenseResponse.Data.Attributes.Value, casheerapi.MonetaryValueAttributes{
t.Errorf("Expense value doesn't match; expected %v but got %v\n", responseData.Attributes.Value, casheerapi.MonetaryValueAttributes{
Amount: val.Amount,
Exponent: val.Exponent,
Currency: val.Currency,
})
}
}

if !strings.Contains(expenseResponse.Data.Links.Self, fmt.Sprintf("%d/expenses/%s", entid, expenseResponse.Data.Id)) {
t.Errorf("Invalid related link format; got %s\n", expenseResponse.Data.Links.Self)
func checkExpenseLinks(t *testing.T, entid int, responseData casheerapi.ExpenseData) {
if !strings.Contains(responseData.Links.Self, fmt.Sprintf("%d/expenses/%s", entid, responseData.Id)) {
t.Errorf("Invalid related link format; got %s\n", responseData.Links.Self)
}

// Check related resources
if !strings.Contains(expenseResponse.Data.Relationships.Entries.Links.Related, strconv.Itoa(entid)) {
t.Errorf("Expected related link (%s) to include expense id (%d)\n", expenseResponse.Data.Relationships.Entries.Links.Related, entid)
if !strings.Contains(responseData.Relationships.Entries.Links.Related, strconv.Itoa(entid)) {
t.Errorf("Expected related link (%s) to include expense id (%d)\n", responseData.Relationships.Entries.Links.Related, entid)
}
}

func Test_CreateBasicExpense_ExpenseIsCreated_and_ReturnedValuesAreCorrect(t *testing.T) {

t.Cleanup(func() {
store.DeleteAllData(conn)
})
entid := setupEntry(t)

expenseInfo := getDummyExpenseInfo()
expenseResponse, err := casheerClient.CreateBasicExpense(entid, expenseInfo.name, expenseInfo.description, expenseInfo.paymentMethod, expenseInfo.amount, expenseInfo.currency)
if err != nil {
t.Fatalf("Did not expect error when creating expense, but got error: %s\n", err.Error())
}

compareExpenseWithResponse(t, expenseInfo, expenseResponse.Data)
checkExpenseLinks(t, entid, expenseResponse.Data)
}

func Test_DeleteExpense_ExistingExpenseIsDeleted(t *testing.T) {

t.Cleanup(func() {
store.DeleteAllData(conn)
})
entid := setupEntry(t)

expenseInfo := getDummyExpenseInfo()
expenseResponseCreate, err := casheerClient.CreateBasicExpense(entid, expenseInfo.name, expenseInfo.description, expenseInfo.paymentMethod, expenseInfo.amount, expenseInfo.currency)
if err != nil {
t.Fatalf("Did not expect error when creating expense, but got error: %s\n", err.Error())
}

expid, _ := strconv.Atoi(expenseResponseCreate.Data.Id)
expenseResponseDelete, err := casheerClient.DeleteExpenseForEntry(entid, expid)
if err != nil {
t.Fatalf("Did not expect error when deleting existing expense, but got error: %s\n", err.Error())
}
// Do not check links because a deleted expense should not have links.
compareExpenseWithResponse(t, expenseInfo, expenseResponseDelete.Data)

}

0 comments on commit 235f4f4

Please sign in to comment.