Passed
Push — main ( 2d22a4...4648c5 )
by Acho
01:50
created

smobilpay.TestClient_VerifyEmpty   A

Complexity

Conditions 1

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 16
nop 1
dl 0
loc 27
rs 9.6
c 0
b 0
f 0
1
package smobilpay
2
3
import (
4
	"context"
5
	"crypto/hmac"
6
	"crypto/sha1"
7
	"encoding/base64"
8
	"net/http"
9
	"net/url"
10
	"testing"
11
	"time"
12
13
	"github.com/NdoleStudio/smobilpay-go/internal/helpers"
14
	"github.com/NdoleStudio/smobilpay-go/internal/stubs"
15
	"github.com/stretchr/testify/assert"
16
)
17
18
func TestClient_PingOk(t *testing.T) {
19
	// Setup
20
	t.Parallel()
21
22
	// Arrange
23
	server := helpers.MakeTestServer(http.StatusOK, stubs.PingOk())
24
	accessToken := "6B352110-4716-11ED-963F-0800200C9A66"
25
	client := New(
26
		WithBaseURL(server.URL),
27
		WithAccessToken(accessToken),
28
		WithAccessSecret("1B875FB0-4717-11ED-963F-0800200C9A66"),
29
	)
30
	nonce := "95cdf110-4614-4d95-b6c2-f14fe01c4995"
31
32
	// Act
33
	status, response, err := client.Ping(
34
		context.Background(),
35
		WithRequestTimestamp(time.Now()),
36
		WithRequestNonce(nonce),
37
	)
38
39
	// Assert
40
	assert.Nil(t, err)
41
	assert.Equal(t, http.StatusOK, response.HTTPResponse.StatusCode)
42
	assert.Equal(t, nonce, status.Nonce)
43
	assert.Equal(t, accessToken, status.Key)
44
45
	// Teardown
46
	server.Close()
47
}
48
49
func TestClient_PingError(t *testing.T) {
50
	// Setup
51
	t.Parallel()
52
53
	// Arrange
54
	server := helpers.MakeTestServer(http.StatusBadRequest, stubs.PingError())
55
	accessToken := "6B352110-4716-11ED-963F-0800200C9A66"
56
	client := New(
57
		WithBaseURL(server.URL),
58
		WithAccessToken(accessToken),
59
		WithAccessSecret("1B875FB0-4717-11ED-963F-0800200C9A66"),
60
	)
61
	nonce := "95cdf110-4614-4d95-b6c2-f14fe01c4995"
62
63
	// Act
64
	status, response, err := client.Ping(
65
		context.Background(),
66
		WithRequestTimestamp(time.Now()),
67
		WithRequestNonce(nonce),
68
	)
69
70
	// Assert
71
	assert.NotNil(t, err)
72
	assert.Nil(t, status)
73
	assert.Equal(t, http.StatusBadRequest, response.HTTPResponse.StatusCode)
74
75
	// Teardown
76
	server.Close()
77
}
78
79
func TestClient_PingRequest(t *testing.T) {
80
	// Setup
81
	t.Parallel()
82
83
	// Arrange
84
	request := new(http.Request)
85
	server := helpers.MakeRequestCapturingTestServer(http.StatusOK, stubs.PingOk(), request)
86
	accessToken := "6B352110-4716-11ED-963F-0800200C9A66"
87
	accessSecret := "1B875FB0-4717-11ED-963F-0800200C9A66"
88
	client := New(
89
		WithBaseURL(server.URL),
90
		WithAccessToken(accessToken),
91
		WithAccessSecret(accessSecret),
92
	)
93
	nonce := "95cdf110-4614-4d95-b6c2-f14fe01c4995"
94
	signature := computeHmac(
95
		"GET&"+url.QueryEscape(server.URL)+"%2Fping&s3pAuth_nonce%3D95cdf110-4614-4d95-b6c2-f14fe01c4995%26s3pAuth_signature_method%3DHMAC-SHA1%26s3pAuth_timestamp%3D1613869830%26s3pAuth_token%3D6B352110-4716-11ED-963F-0800200C9A66",
96
		accessSecret,
97
	)
98
99
	// Act
100
	_, _, err := client.Ping(
101
		context.Background(),
102
		WithRequestTimestamp(time.Date(2021, time.Month(2), 21, 1, 10, 30, 0, time.UTC)),
103
		WithRequestNonce(nonce),
104
	)
105
106
	// Assert
107
	assert.Nil(t, err)
108
	assert.Equal(
109
		t,
110
		"s3pAuth,s3pAuth_nonce=\"95cdf110-4614-4d95-b6c2-f14fe01c4995\",s3pAuth_signature=\""+signature+"\",s3pAuth_signature_method=\"HMAC-SHA1\",s3pAuth_timestamp=\"1613869830\",s3pAuth_token=\"6B352110-4716-11ED-963F-0800200C9A66\"",
111
		request.Header.Get("Authorization"),
112
	)
113
114
	// Teardown
115
	server.Close()
116
}
117
118
func TestClient_Quote(t *testing.T) {
119
	// Setup
120
	t.Parallel()
121
122
	// Arrange
123
	server := helpers.MakeTestServer(http.StatusOK, stubs.QuoteOk())
124
	accessToken := "6B352110-4716-11ED-963F-0800200C9A66"
125
	client := New(
126
		WithBaseURL(server.URL),
127
		WithAccessToken(accessToken),
128
		WithAccessSecret("1B875FB0-4717-11ED-963F-0800200C9A66"),
129
	)
130
	nonce := "95cdf110-4614-4d95-b6c2-f14fe01c4995"
131
	payItemID := "S-112-951-CMORANGE-20062-CM_ORANGE_VTU_CUSTOM-1"
132
133
	// Act
134
	quote, response, err := client.Quote(
135
		context.Background(),
136
		&QuoteParams{
137
			PayItemID: payItemID,
138
			Amount:    "100",
139
		},
140
		WithRequestNonce(nonce),
141
	)
142
143
	// Assert
144
	assert.Nil(t, err)
145
	assert.Equal(t, http.StatusOK, response.HTTPResponse.StatusCode)
146
	assert.Equal(t, payItemID, quote.PayItemID)
147
	assert.Equal(t, 100, quote.PriceSystemCurrency)
148
149
	// Teardown
150
	server.Close()
151
}
152
153
func TestClient_Collect(t *testing.T) {
154
	// Setup
155
	t.Parallel()
156
157
	// Arrange
158
	server := helpers.MakeTestServer(http.StatusOK, stubs.CollectOk())
159
	accessToken := "6B352110-4716-11ED-963F-0800200C9A66"
160
	client := New(
161
		WithBaseURL(server.URL),
162
		WithAccessToken(accessToken),
163
		WithAccessSecret("1B875FB0-4717-11ED-963F-0800200C9A66"),
164
	)
165
	nonce := "95cdf110-4614-4d95-b6c2-f14fe01c4995"
166
	params := &CollectParams{
167
		QuoteID:               "15380e55-6227-4a25-8e1f-23c8735ce242",
168
		CustomerPhoneNumber:   "697777777",
169
		CustomerEmailAddress:  "[email protected]",
170
		ServiceNumber:         "697777777",
171
		ExternalTransactionID: "999992624813740205",
172
	}
173
174
	// Act
175
	transaction, response, err := client.Collect(
176
		context.Background(),
177
		params,
178
		WithRequestNonce(nonce),
179
	)
180
181
	// Assert
182
	assert.Nil(t, err)
183
	assert.Equal(t, http.StatusOK, response.HTTPResponse.StatusCode)
184
	assert.Equal(t, params.ExternalTransactionID, *transaction.ExternalTransactionID)
185
	assert.False(t, transaction.IsFailed())
186
	assert.Equal(t, "SUCCESS", transaction.Status)
187
188
	// Teardown
189
	server.Close()
190
}
191
192
func TestClient_Verify(t *testing.T) {
193
	// Setup
194
	t.Parallel()
195
196
	// Arrange
197
	server := helpers.MakeTestServer(http.StatusOK, stubs.VerifyOk())
198
	accessToken := "6B352110-4716-11ED-963F-0800200C9A66"
199
	client := New(
200
		WithBaseURL(server.URL),
201
		WithAccessToken(accessToken),
202
		WithAccessSecret("1B875FB0-4717-11ED-963F-0800200C9A66"),
203
	)
204
	nonce := "95cdf110-4614-4d95-b6c2-f14fe01c4995"
205
	paymentTransactionNumber := "99999166542651400095315364801168"
206
207
	// Act
208
	transaction, response, err := client.Verify(
209
		context.Background(),
210
		paymentTransactionNumber,
211
		WithRequestNonce(nonce),
212
	)
213
214
	// Assert
215
	assert.Nil(t, err)
216
	assert.Equal(t, http.StatusOK, response.HTTPResponse.StatusCode)
217
	assert.Equal(t, paymentTransactionNumber, transaction.PaymentTransactionNumber)
218
	assert.False(t, transaction.IsFailed())
219
	assert.Equal(t, "SUCCESS", transaction.Status)
220
221
	// Teardown
222
	server.Close()
223
}
224
225
func TestClient_TransactionHistory(t *testing.T) {
226
	// Setup
227
	t.Parallel()
228
229
	// Arrange
230
	server := helpers.MakeTestServer(http.StatusOK, stubs.VerifyOk())
231
	accessToken := "6B352110-4716-11ED-963F-0800200C9A66"
232
	client := New(
233
		WithBaseURL(server.URL),
234
		WithAccessToken(accessToken),
235
		WithAccessSecret("1B875FB0-4717-11ED-963F-0800200C9A66"),
236
	)
237
	paymentTransactionNumber := "99999166542651400095315364801168"
238
239
	// Act
240
	transactions, response, err := client.TransactionHistory(context.Background(), time.Now(), time.Now())
241
242
	// Assert
243
	assert.Nil(t, err)
244
	assert.Equal(t, http.StatusOK, response.HTTPResponse.StatusCode)
245
	assert.Equal(t, 1, len(transactions))
246
	assert.Equal(t, paymentTransactionNumber, transactions[0].PaymentTransactionNumber)
247
	assert.False(t, transactions[0].IsFailed())
248
	assert.Equal(t, "SUCCESS", transactions[0].Status)
249
250
	// Teardown
251
	server.Close()
252
}
253
254
func TestClient_VerifyEmpty(t *testing.T) {
255
	// Setup
256
	t.Parallel()
257
258
	// Arrange
259
	server := helpers.MakeTestServer(http.StatusOK, stubs.VerifyEmpty())
260
	accessToken := "6B352110-4716-11ED-963F-0800200C9A66"
261
	client := New(
262
		WithBaseURL(server.URL),
263
		WithAccessToken(accessToken),
264
		WithAccessSecret("1B875FB0-4717-11ED-963F-0800200C9A66"),
265
	)
266
	nonce := "95cdf110-4614-4d95-b6c2-f14fe01c4995"
267
	paymentTransactionNumber := "99999166542651400095315364801168"
268
269
	// Act
270
	_, _, err := client.Verify(
271
		context.Background(),
272
		paymentTransactionNumber,
273
		WithRequestNonce(nonce),
274
	)
275
276
	// Assert
277
	assert.NotNil(t, err)
278
279
	// Teardown
280
	server.Close()
281
}
282
283
func computeHmac(message string, secret string) string {
284
	key := []byte(secret)
285
	h := hmac.New(sha1.New, key)
286
	_, _ = h.Write([]byte(message))
287
	return base64.StdEncoding.EncodeToString(h.Sum(nil))
288
}
289