Skip to content

Commit 83ede14

Browse files
committed
refactor: sanitize input values for qris, merchant and payment fee category
1 parent c47c30d commit 83ede14

File tree

5 files changed

+94
-13
lines changed

5 files changed

+94
-13
lines changed

api/routes/route.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ func Setup(env *bootstrap.Env, ginEngine *gin.Engine) {
1717
Message: "Made with love by Alvriyanto Azis",
1818
Data: map[string]any{
1919
"1_Title": "Go-QRIS",
20-
"2_Description": "Go-QRIS is a Go-based project designed to convert QRIS code into dynamic ones. QRIS (Quick Response Code Indonesian Standard) is widely used for payments, but QR code have limitations in flexibility. This tool enhances QRIS transactions by enabling dynamic data like payment amounts, merchant details, and fees, making payments more adaptable and efficient. Go-QRIS simplifies the process of generating dynamic QRIS code, improving payment flexibility for businesses and providing a seamless experience for customers.",
21-
"3_Resources": [3]any{
20+
"2_Description": "Go-QRIS is a Go-based project designed to convert QRIS code into dynamic ones. QRIS (Quick Response Code Indonesian Standard) is widely used for payments, but QR code has limitations in flexibility. This tool enhances QRIS transactions by enabling dynamic data like payment amounts, merchant details, and fees, making payments more adaptable and efficient. Go-QRIS simplifies the process of generating dynamic QRIS code, improving payment flexibility for businesses and providing a seamless experience for customers.",
21+
"3_Related URLs": [4]any{
2222
"https://github.com/fyvri/go-qris",
2323
"https://pkg.go.dev/github.com/fyvri/go-qris",
2424
"https://hub.docker.com/r/azisalvriyanto/go-qris",
25+
"https://documenter.getpostman.com/view/6937269/2sAYJ1jMc7",
2526
},
2627
"4_API_Endpoints": [3]any{
2728
map[string]any{

internal/interface/controllers/qris.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,15 @@ func (c *QRIS) Convert(qrisString string, merchantCityValue string, merchantPost
4747
merchantCityValue = c.inputUtil.Sanitize(merchantCityValue)
4848
merchantPostalCodeValue = c.inputUtil.Sanitize(merchantPostalCodeValue)
4949
paymentFeeCategoryValue = strings.ToUpper(c.inputUtil.Sanitize(paymentFeeCategoryValue))
50-
qrDynamic := c.qrisUsecase.Modify(qris, merchantCityValue, merchantPostalCodeValue, paymentAmountValue, paymentFeeCategoryValue, paymentFeeValue)
51-
qrDynamicString := c.qrisUsecase.ToString(qrDynamic)
50+
qris = c.qrisUsecase.Modify(qris, merchantCityValue, merchantPostalCodeValue, paymentAmountValue, paymentFeeCategoryValue, paymentFeeValue)
51+
qrisString = c.qrisUsecase.ToString(qris)
5252

53-
qrCode, err := c.qrCodeUtil.StringToImageBase64(qrDynamicString, c.qrCodeSize)
53+
qrCode, err := c.qrCodeUtil.StringToImageBase64(qrisString, c.qrCodeSize)
5454
if err != nil {
55-
return qrDynamicString, "", err, nil
55+
return qrisString, "", err, nil
5656
}
5757

58-
return qrDynamicString, qrCode, nil, nil
58+
return qrisString, qrCode, nil, nil
5959
}
6060

6161
func (c *QRIS) IsValid(qrisString string) (error, *[]string) {

pkg/services/qris.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
package services
22

33
import (
4+
"strings"
5+
46
"github.com/fyvri/go-qris/internal/config"
57
"github.com/fyvri/go-qris/internal/usecases"
68
"github.com/fyvri/go-qris/pkg/models"
9+
"github.com/fyvri/go-qris/pkg/utils"
710
)
811

912
type QRIS struct {
1013
crc16CCITTUsecase usecases.CRC16CCITTInterface
1114
qrisUsecase usecases.QRISInterface
15+
inputUtil utils.InputInterface
1216
}
1317

1418
type QRISInterface interface {
1519
Parse(qrisString string) (*models.QRIS, error, *[]string)
1620
IsValid(qris *models.QRIS) bool
17-
Modify(qris *models.QRIS, merchantCityValue string, merchantPostalCode string, paymentAmountValue int, paymentFeeCategoryValue string, paymentFeeValue int) *models.QRIS
21+
Modify(qris *models.QRIS, merchantCityValue string, merchantPostalCodeValue string, paymentAmountValue int, paymentFeeCategoryValue string, paymentFeeValue int) *models.QRIS
1822
ToString(qris *models.QRIS) string
19-
Convert(qrisString string, merchantCityValue string, merchantPostalCode string, paymentAmountValue int, paymentFeeCategoryValue string, paymentFeeValue int) (string, error, *[]string)
23+
Convert(qrisString string, merchantCityValue string, merchantPostalCodeValue string, paymentAmountValue int, paymentFeeCategoryValue string, paymentFeeValue int) (string, error, *[]string)
2024
}
2125

2226
func NewQRIS() QRISInterface {
@@ -72,14 +76,17 @@ func NewQRIS() QRISInterface {
7276
qrisCategoryContents,
7377
qrisPaymentFeeCategoryContents,
7478
)
79+
inputUtil := utils.NewInput()
7580

7681
return &QRIS{
7782
crc16CCITTUsecase: crc16CCITTUsecase,
7883
qrisUsecase: qrisUsecase,
84+
inputUtil: inputUtil,
7985
}
8086
}
8187

8288
func (s *QRIS) Parse(qrisString string) (*models.QRIS, error, *[]string) {
89+
qrisString = s.inputUtil.Sanitize(qrisString)
8390
qris, err, errs := s.qrisUsecase.Parse(qrisString)
8491
if err != nil {
8592
return nil, err, errs
@@ -94,9 +101,13 @@ func (s *QRIS) IsValid(qris *models.QRIS) bool {
94101
return s.qrisUsecase.IsValid(qrisEntity)
95102
}
96103

97-
func (s *QRIS) Modify(qris *models.QRIS, merchantCityValue string, merchantPostalCode string, paymentAmountValue int, paymentFeeCategoryValue string, paymentFeeValue int) *models.QRIS {
104+
func (s *QRIS) Modify(qris *models.QRIS, merchantCityValue string, merchantPostalCodeValue string, paymentAmountValue int, paymentFeeCategoryValue string, paymentFeeValue int) *models.QRIS {
98105
qrisEntity := mapQRISModelToEntity(qris)
99-
qrisModel := s.qrisUsecase.Modify(qrisEntity, merchantCityValue, merchantPostalCode, uint32(paymentAmountValue), paymentFeeCategoryValue, uint32(paymentFeeValue))
106+
107+
merchantCityValue = s.inputUtil.Sanitize(merchantCityValue)
108+
merchantPostalCodeValue = s.inputUtil.Sanitize(merchantPostalCodeValue)
109+
paymentFeeCategoryValue = strings.ToUpper(s.inputUtil.Sanitize(paymentFeeCategoryValue))
110+
qrisModel := s.qrisUsecase.Modify(qrisEntity, merchantCityValue, merchantPostalCodeValue, uint32(paymentAmountValue), paymentFeeCategoryValue, uint32(paymentFeeValue))
100111

101112
return mapQRISEntityToModel(qrisModel)
102113
}
@@ -121,12 +132,17 @@ func (s *QRIS) ToString(qris *models.QRIS) string {
121132
return qrisString + s.crc16CCITTUsecase.GenerateCode(qrisString)
122133
}
123134

124-
func (s *QRIS) Convert(qrisString string, merchantCityValue string, merchantPostalCode string, paymentAmountValue int, paymentFeeCategoryValue string, paymentFeeValue int) (string, error, *[]string) {
135+
func (s *QRIS) Convert(qrisString string, merchantCityValue string, merchantPostalCodeValue string, paymentAmountValue int, paymentFeeCategoryValue string, paymentFeeValue int) (string, error, *[]string) {
136+
qrisString = s.inputUtil.Sanitize(qrisString)
125137
qrisEntity, err, errs := s.qrisUsecase.Parse(qrisString)
126138
if err != nil {
127139
return "", err, errs
128140
}
129-
qrisEntity = s.qrisUsecase.Modify(qrisEntity, merchantCityValue, merchantPostalCode, uint32(paymentAmountValue), paymentFeeCategoryValue, uint32(paymentFeeValue))
141+
142+
merchantCityValue = s.inputUtil.Sanitize(merchantCityValue)
143+
merchantPostalCodeValue = s.inputUtil.Sanitize(merchantPostalCodeValue)
144+
paymentFeeCategoryValue = strings.ToUpper(s.inputUtil.Sanitize(paymentFeeCategoryValue))
145+
qrisEntity = s.qrisUsecase.Modify(qrisEntity, merchantCityValue, merchantPostalCodeValue, uint32(paymentAmountValue), paymentFeeCategoryValue, uint32(paymentFeeValue))
130146

131147
return s.qrisUsecase.ToString(qrisEntity), nil, nil
132148
}

pkg/services/qris_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/fyvri/go-qris/internal/domain/entities"
1010
"github.com/fyvri/go-qris/internal/usecases"
1111
"github.com/fyvri/go-qris/pkg/models"
12+
"github.com/fyvri/go-qris/pkg/utils"
1213
)
1314

1415
func TestNewQRIS(t *testing.T) {
@@ -53,6 +54,7 @@ func TestNewQRIS(t *testing.T) {
5354
qrisCategoryContents,
5455
qrisPaymentFeeCategoryContents,
5556
)
57+
inputUtil := utils.NewInput()
5658

5759
tests := []struct {
5860
name string
@@ -63,6 +65,7 @@ func TestNewQRIS(t *testing.T) {
6365
want: &QRIS{
6466
crc16CCITTUsecase: crc16CCITTUsecase,
6567
qrisUsecase: qrisUsecase,
68+
inputUtil: inputUtil,
6669
},
6770
},
6871
}
@@ -102,6 +105,11 @@ func TestQRISParse(t *testing.T) {
102105
{
103106
name: "Error: s.qrisUsecase.Parse()",
104107
fields: QRIS{
108+
inputUtil: &mockInputUtil{
109+
SanitizeFunc: func(input string) string {
110+
return testQRISEntityString
111+
},
112+
},
105113
qrisUsecase: &mockQRISUsecase{
106114
ParseFunc: func(qrString string) (*entities.QRIS, error, *[]string) {
107115
return nil, fmt.Errorf("invalid format code"), nil
@@ -117,6 +125,11 @@ func TestQRISParse(t *testing.T) {
117125
{
118126
name: "Success",
119127
fields: QRIS{
128+
inputUtil: &mockInputUtil{
129+
SanitizeFunc: func(input string) string {
130+
return testQRISEntityString
131+
},
132+
},
120133
qrisUsecase: &mockQRISUsecase{
121134
ParseFunc: func(qrString string) (*entities.QRIS, error, *[]string) {
122135
return &testQRISEntity, nil, nil
@@ -136,6 +149,7 @@ func TestQRISParse(t *testing.T) {
136149
uc := &QRIS{
137150
crc16CCITTUsecase: test.fields.crc16CCITTUsecase,
138151
qrisUsecase: test.fields.qrisUsecase,
152+
inputUtil: test.fields.inputUtil,
139153
}
140154

141155
got, err, _ := uc.Parse(test.args.qrString)
@@ -181,6 +195,7 @@ func TestQRISIsValid(t *testing.T) {
181195
uc := &QRIS{
182196
crc16CCITTUsecase: test.fields.crc16CCITTUsecase,
183197
qrisUsecase: test.fields.qrisUsecase,
198+
inputUtil: test.fields.inputUtil,
184199
}
185200

186201
got := uc.IsValid(test.args.qris)
@@ -205,6 +220,20 @@ func TestQRISModify(t *testing.T) {
205220
{
206221
name: "Success: Fixed Payment Fee",
207222
fields: QRIS{
223+
inputUtil: &mockInputUtil{
224+
SanitizeFunc: func(input string) string {
225+
switch input {
226+
case testMerchantCityContent:
227+
return testMerchantCityContent
228+
case testMerchantPostalCodeContent:
229+
return testMerchantPostalCodeContent
230+
case testPaymentFeeCategoryFixedContent:
231+
return testPaymentFeeCategoryFixedContent
232+
default:
233+
return ""
234+
}
235+
},
236+
},
208237
qrisUsecase: &mockQRISUsecase{
209238
ModifyFunc: func(qris *entities.QRIS, merchantCityValue string, merchantPostalCodeValue string, paymentAmountValue uint32, paymentFeeCategoryValue string, paymentFeeValue uint32) *entities.QRIS {
210239
return &testQRISEntityModified
@@ -223,6 +252,7 @@ func TestQRISModify(t *testing.T) {
223252
uc := &QRIS{
224253
crc16CCITTUsecase: test.fields.crc16CCITTUsecase,
225254
qrisUsecase: test.fields.qrisUsecase,
255+
inputUtil: test.fields.inputUtil,
226256
}
227257

228258
got := uc.Modify(test.args.qris, testMerchantCityContent, testMerchantPostalCodeContent, testPaymentAmountValue, testPaymentFeeCategoryFixedContent, testPaymentFeeValue)
@@ -279,6 +309,7 @@ func TestQRISToString(t *testing.T) {
279309
uc := &QRIS{
280310
crc16CCITTUsecase: test.fields.crc16CCITTUsecase,
281311
qrisUsecase: test.fields.qrisUsecase,
312+
inputUtil: test.fields.inputUtil,
282313
}
283314

284315
got := uc.ToString(test.args.qris)
@@ -304,6 +335,11 @@ func TestQRISConvert(t *testing.T) {
304335
{
305336
name: "Error: s.qrisUsecase.Parse()",
306337
fields: QRIS{
338+
inputUtil: &mockInputUtil{
339+
SanitizeFunc: func(input string) string {
340+
return testQRISEntityString
341+
},
342+
},
307343
qrisUsecase: &mockQRISUsecase{
308344
ParseFunc: func(qrString string) (*entities.QRIS, error, *[]string) {
309345
return nil, fmt.Errorf("invalid extract acquirer for content %s", testQRISEntity.Acquirer.Content), nil
@@ -319,6 +355,22 @@ func TestQRISConvert(t *testing.T) {
319355
{
320356
name: "Success",
321357
fields: QRIS{
358+
inputUtil: &mockInputUtil{
359+
SanitizeFunc: func(input string) string {
360+
switch input {
361+
case testQRISEntityString:
362+
return testQRISEntityString
363+
case testMerchantCityContent:
364+
return testMerchantCityContent
365+
case testMerchantPostalCodeContent:
366+
return testMerchantPostalCodeContent
367+
case testPaymentFeeCategoryFixedContent:
368+
return testPaymentFeeCategoryFixedContent
369+
default:
370+
return ""
371+
}
372+
},
373+
},
322374
qrisUsecase: &mockQRISUsecase{
323375
ParseFunc: func(qrString string) (*entities.QRIS, error, *[]string) {
324376
return &testQRISEntity, nil, nil
@@ -344,6 +396,7 @@ func TestQRISConvert(t *testing.T) {
344396
uc := &QRIS{
345397
crc16CCITTUsecase: test.fields.crc16CCITTUsecase,
346398
qrisUsecase: test.fields.qrisUsecase,
399+
inputUtil: test.fields.inputUtil,
347400
}
348401

349402
got, err, _ := uc.Convert(test.args.qrString, testMerchantCityContent, testMerchantPostalCodeContent, testPaymentAmountValue, testPaymentFeeCategoryFixedContent, testPaymentFeeValue)

pkg/services/service_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,14 @@ func (m *mockQRISUsecase) ToString(qris *entities.QRIS) string {
559559
}
560560
return ""
561561
}
562+
563+
type mockInputUtil struct {
564+
SanitizeFunc func(input string) string
565+
}
566+
567+
func (m *mockInputUtil) Sanitize(input string) string {
568+
if m.SanitizeFunc != nil {
569+
return m.SanitizeFunc(input)
570+
}
571+
return ""
572+
}

0 commit comments

Comments
 (0)