Skip to content

Commit 531dfe9

Browse files
committed
feat: topup returns data
1 parent e1e4105 commit 531dfe9

15 files changed

Lines changed: 150 additions & 76 deletions

File tree

openapiv2/arjuna.swagger.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,11 @@ definitions:
355355
- amount
356356
v1TopupWalletResponse:
357357
type: object
358+
properties:
359+
data:
360+
$ref: '#/definitions/v1Wallet'
361+
description: data represents wallet.
362+
readOnly: true
358363
description: TopupWalletResponse represents response from topup wallet.
359364
v1Transaction:
360365
type: object

proto/api/v1/wallet.pb.go

Lines changed: 27 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

service/wallet/api/v1/wallet.proto

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,10 @@ message TopupWalletRequest {
111111
}
112112

113113
// TopupWalletResponse represents response from topup wallet.
114-
message TopupWalletResponse {}
114+
message TopupWalletResponse {
115+
// data represents wallet.
116+
Wallet data = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
117+
}
115118

116119
// TransferBalanceRequest represents request for transfer balance.
117120
message TransferBalanceRequest {

service/wallet/db/queries/queries.sql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ VALUES ($1, $2, $3, $4, $5, $6, $7);
55
-- name: GetUserWalletForUpdate :one
66
SELECT * FROM wallets WHERE id = $1 AND user_id = $2 LIMIT 1 FOR NO KEY UPDATE; --noqa
77

8-
-- name: AddWalletBalance :exec
9-
UPDATE wallets SET balance = balance + @amount WHERE id = $1; --noqa
8+
-- name: AddWalletBalance :one
9+
UPDATE wallets SET balance = balance + @amount WHERE id = $1 --noqa
10+
RETURNING *;

service/wallet/internal/grpc/handler/wallet_command.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ func (wc *WalletCommand) TopupWallet(ctx context.Context, request *apiv1.TopupWa
7070
amount, _ := decimal.NewFromString(request.GetTopup().GetAmount())
7171
req := createTopupWalletFromTopupWalletRequest(request, userID, amount, key[0])
7272

73-
err := wc.topup.Topup(ctx, req)
73+
wallet, err := wc.topup.Topup(ctx, req)
7474
if err != nil {
7575
slog.ErrorContext(ctx, "[WalletCommand-TopupWallet] fail topup wallet", "error", err)
7676
return nil, err
7777
}
78-
return &apiv1.TopupWalletResponse{}, nil
78+
return &apiv1.TopupWalletResponse{Data: createWalletProto(wallet)}, nil
7979
}
8080

8181
// TransferBalance handles HTTP/2 gRPC request similar to POST in HTTP/1.1.
@@ -121,3 +121,11 @@ func createTransferWalletFromTransferBalanceRequest(request *apiv1.TransferBalan
121121
Amount: amount,
122122
}
123123
}
124+
125+
func createWalletProto(wallet *entity.Wallet) *apiv1.Wallet {
126+
return &apiv1.Wallet{
127+
Id: wallet.ID.String(),
128+
UserId: wallet.UserID.String(),
129+
Balance: wallet.Balance.String(),
130+
}
131+
}

service/wallet/internal/grpc/handler/wallet_command_test.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"testing"
66

77
"github.com/google/uuid"
8+
"github.com/shopspring/decimal"
89
"github.com/stretchr/testify/assert"
910
"go.uber.org/mock/gomock"
1011
"google.golang.org/grpc/metadata"
@@ -171,7 +172,7 @@ func TestWalletCommand_TopupWallet(t *testing.T) {
171172
entity.ErrInternal("error"),
172173
}
173174
for _, errRet := range errors {
174-
st.topup.EXPECT().Topup(testCtxWithValidKey, gomock.Any()).Return(errRet)
175+
st.topup.EXPECT().Topup(testCtxWithValidKey, gomock.Any()).Return(nil, errRet)
175176

176177
res, err := st.handler.TopupWallet(testCtxWithValidKey, request)
177178

@@ -182,11 +183,18 @@ func TestWalletCommand_TopupWallet(t *testing.T) {
182183
})
183184

184185
t.Run("success topup wallet", func(t *testing.T) {
186+
walletID := uuid.Must(uuid.NewV7())
187+
userID := uuid.Must(uuid.NewV7())
188+
185189
st := createWalletCommandSuite(ctrl)
186-
st.topup.EXPECT().Topup(testCtxWithValidKey, gomock.Any()).Return(nil)
190+
st.topup.EXPECT().Topup(testCtxWithValidKey, gomock.Any()).Return(&entity.Wallet{
191+
ID: walletID,
192+
UserID: userID,
193+
Balance: decimal.NewFromFloat(10.23),
194+
}, nil)
187195
request := &apiv1.TopupWalletRequest{
188196
Topup: &apiv1.Topup{
189-
WalletId: uuid.Must(uuid.NewV7()).String(),
197+
WalletId: walletID.String(),
190198
Amount: "10.23",
191199
},
192200
}

service/wallet/internal/repository/db/queries.sql.go

Lines changed: 18 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

service/wallet/internal/repository/postgres/wallet.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,18 @@ func (w *Wallet) Insert(ctx context.Context, wallet *entity.Wallet) error {
5151
}
5252

5353
// AddWalletBalance adds some amount to specific user's wallet.
54-
func (w *Wallet) AddWalletBalance(ctx context.Context, id uuid.UUID, amount decimal.Decimal) error {
54+
func (w *Wallet) AddWalletBalance(ctx context.Context, id uuid.UUID, amount decimal.Decimal) (*entity.Wallet, error) {
5555
param := db.AddWalletBalanceParams{ID: id, Amount: amount}
56-
err := w.queries.AddWalletBalance(ctx, param)
56+
res, err := w.queries.AddWalletBalance(ctx, param)
5757
if err != nil {
5858
slog.ErrorContext(ctx, "[WalletPostgres-addWalletBalance] internal error", "error", err)
59-
return entity.ErrInternal(err.Error())
59+
return nil, entity.ErrInternal(err.Error())
6060
}
61-
return nil
61+
return &entity.Wallet{
62+
ID: res.ID,
63+
UserID: res.UserID,
64+
Balance: res.Balance,
65+
}, nil
6266
}
6367

6468
// GetUserWalletForUpdate gets user's wallet for update.

service/wallet/internal/repository/postgres/wallet_test.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package postgres_test
33
import (
44
"context"
55
"testing"
6+
"time"
67

78
"github.com/google/uuid"
89
"github.com/jackc/pgx/v5"
@@ -106,27 +107,36 @@ func TestWallet_AddWalletBalance(t *testing.T) {
106107
id := uuid.Must(uuid.NewV7())
107108
amount, _ := decimal.NewFromString("4.56")
108109
st.getter.EXPECT().DefaultTrOrDB(testCtx, st.db).Return(st.db)
109-
st.db.ExpectExec(query).
110+
st.db.ExpectQuery(query).
110111
WithArgs(id, amount).
111112
WillReturnError(assert.AnError)
112113

113-
err := st.wallet.AddWalletBalance(testCtx, id, amount)
114+
res, err := st.wallet.AddWalletBalance(testCtx, id, amount)
114115

115116
assert.Error(t, err)
117+
assert.Nil(t, res)
116118
})
117119

118120
t.Run("add account balance returns success", func(t *testing.T) {
119121
st := createWalletSuite(t, ctrl)
120122
id := uuid.Must(uuid.NewV7())
123+
userID := uuid.Must(uuid.NewV7())
121124
amount, _ := decimal.NewFromString("4.56")
125+
newBalance, _ := decimal.NewFromString("14.56")
126+
122127
st.getter.EXPECT().DefaultTrOrDB(testCtx, st.db).Return(st.db)
123-
st.db.ExpectExec(query).
128+
st.db.ExpectQuery(query).
124129
WithArgs(id, amount).
125-
WillReturnResult(pgxmock.NewResult("UPDATE", 1))
130+
WillReturnRows(pgxmock.NewRows([]string{"id", "user_id", "balance", "created_at", "updated_at", "deleted_at", "created_by", "updated_by", "deleted_by"}).
131+
AddRow(id, userID, newBalance, time.Now(), time.Now(), nil, uuid.Nil, uuid.Nil, nil))
126132

127-
err := st.wallet.AddWalletBalance(testCtx, id, amount)
133+
res, err := st.wallet.AddWalletBalance(testCtx, id, amount)
128134

129135
assert.NoError(t, err)
136+
assert.NotNil(t, res)
137+
assert.Equal(t, id, res.ID)
138+
assert.Equal(t, userID, res.UserID)
139+
assert.Equal(t, newBalance, res.Balance)
130140
})
131141
}
132142

service/wallet/internal/service/wallet_topup.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ import (
1414
type TopupWallet interface {
1515
// Topup topups a wallet's balance.
1616
// It needs idempotency key.
17-
Topup(ctx context.Context, topup *entity.TopupWallet) error
17+
Topup(ctx context.Context, topup *entity.TopupWallet) (*entity.Wallet, error)
1818
}
1919

2020
// TopupWalletRepository defines the interface to update wallet in repository.
2121
type TopupWalletRepository interface {
2222
// AddWalletBalance adds certain amount (can be negative) to certain wallet.
23-
AddWalletBalance(ctx context.Context, id uuid.UUID, amount decimal.Decimal) error
23+
AddWalletBalance(ctx context.Context, id uuid.UUID, amount decimal.Decimal) (*entity.Wallet, error)
2424
}
2525

2626
// IdempotencyKeyRepository defines interface for idempotency check flow and repository.
@@ -42,27 +42,27 @@ func NewWalletTopup(t TopupWalletRepository, k IdempotencyKeyRepository) *Wallet
4242

4343
// Topup topups wallet's balance.
4444
// It needs idempotency key.
45-
func (wt *WalletTopup) Topup(ctx context.Context, topup *entity.TopupWallet) error {
45+
func (wt *WalletTopup) Topup(ctx context.Context, topup *entity.TopupWallet) (*entity.Wallet, error) {
4646
if topup == nil {
47-
return entity.ErrEmptyWallet()
47+
return nil, entity.ErrEmptyWallet()
4848
}
4949

5050
if err := wt.validateIdempotencyKey(ctx, topup.IdempotencyKey); err != nil {
5151
slog.ErrorContext(ctx, "[WalletTopup-Topup] fail check idempotency key", "idempotency_key", topup.IdempotencyKey, "error", err)
52-
return err
52+
return nil, err
5353
}
5454

5555
if err := validateTopupWallet(topup); err != nil {
5656
slog.ErrorContext(ctx, "[WalletTopup-Topup] wallet is invalid", "error", err)
57-
return err
57+
return nil, err
5858
}
5959

60-
err := wt.walletRepo.AddWalletBalance(ctx, topup.WalletID, topup.Amount)
60+
wallet, err := wt.walletRepo.AddWalletBalance(ctx, topup.WalletID, topup.Amount)
6161
if err != nil {
6262
slog.ErrorContext(ctx, "[WalletTopup-Topup] fail update wallet balance", "error", err)
63-
return err
63+
return nil, err
6464
}
65-
return nil
65+
return wallet, nil
6666
}
6767

6868
func (wt *WalletTopup) validateIdempotencyKey(ctx context.Context, key string) error {

0 commit comments

Comments
 (0)