Passed
Push — main ( 45ba15...7eb0bd )
by Acho
01:25
created

mobilenig.TestBillsService_PayDStv   F

Complexity

Conditions 18

Size

Total Lines 178
Code Lines 104

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
eloc 104
nop 1
dl 0
loc 178
rs 0.84
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like mobilenig.TestBillsService_PayDStv often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package mobilenig
2
3
import (
4
	"context"
5
	"errors"
6
	"net/http"
7
	"net/url"
8
	"testing"
9
	"time"
10
11
	"github.com/NdoleStudio/mobilenig-go/internal/helpers"
12
	"github.com/NdoleStudio/mobilenig-go/internal/stubs"
13
	"github.com/stretchr/testify/assert"
14
)
15
16
const (
17
	testUsername = "test_username"
18
	testAPIKey   = "test_api_key"
19
)
20
21
//nolint:funlen
22
func TestBillsService_CheckDStvUser(t *testing.T) {
23
	t.Parallel()
24
	t.Run("it returns the dstv user with a valid smartcard", func(t *testing.T) {
25
		// Setup
26
		t.Parallel()
27
		server := helpers.MakeTestServer(http.StatusOK, stubs.CheckDstvUserResponse())
28
29
		// Arrange
30
		baseURL, _ := url.Parse(server.URL)
31
		client := New(WithBaseURL(baseURL))
32
		date, _ := time.Parse("2006-01-02T15:04:05-07:00", "2018-11-13T00:00:00+01:00")
33
34
		// Act
35
		user, _, err := client.Bills.CheckDStvUser(context.Background(), "4131953321")
36
37
		// Assert
38
		assert.NoError(t, err)
39
40
		assert.Equal(t, "OPEN", user.Details.AccountStatus)
41
		assert.Equal(t, "ESU", user.Details.Firstname)
42
		assert.Equal(t, "INI OBONG BASSEY", user.Details.Lastname)
43
		assert.Equal(t, "SUD", user.Details.CustomerType)
44
		assert.Equal(t, 1, user.Details.InvoicePeriod)
45
		assert.Equal(t, date, user.Details.DueDate)
46
		assert.Equal(t, int64(275953782), user.Details.CustomerNumber)
47
48
		// Teardown
49
		server.Close()
50
	})
51
52
	t.Run("it constructs the request correctly", func(t *testing.T) {
53
		// Setup
54
		t.Parallel()
55
56
		environments := []Environment{LiveEnvironment, TestEnvironment}
57
		for _, environment := range environments {
58
			t.Run(environment.String(), func(t *testing.T) {
59
				// Setup
60
				t.Parallel()
61
62
				// Arrange
63
				request := new(http.Request)
64
				server := helpers.MakeRequestCapturingTestServer(http.StatusOK, stubs.CheckDstvUserResponse(), request)
65
66
				baseURL, _ := url.Parse(server.URL)
67
				username := testUsername
68
				apiKey := testAPIKey
69
				smartcardNumber := "4131953321"
70
71
				client := New(WithBaseURL(baseURL), WithAPIKey(apiKey), WithUsername(username), WithEnvironment(environment))
72
73
				// Act
74
				_, _, _ = client.Bills.CheckDStvUser(context.Background(), smartcardNumber)
75
76
				// Assert
77
				assert.Equal(t, "/bills/user_check", request.URL.Path)
78
				assert.Equal(t, username, request.URL.Query().Get("username"))
79
				assert.Equal(t, apiKey, request.URL.Query().Get("api_key"))
80
				assert.Equal(t, "DSTV", request.URL.Query().Get("service"))
81
				assert.Equal(t, smartcardNumber, request.URL.Query().Get("number"))
82
83
				// Teardown
84
				server.Close()
85
			})
86
		}
87
	})
88
89
	t.Run("it returns an error when the api responds with an error", func(t *testing.T) {
90
		t.Parallel()
91
92
		environments := []Environment{LiveEnvironment, TestEnvironment}
93
		for _, environment := range environments {
94
			t.Run(environment.String(), func(t *testing.T) {
95
				// Setup
96
				t.Parallel()
97
98
				// Arrange
99
				server := helpers.MakeTestServer(http.StatusOK, stubs.ErrorResponse())
100
				baseURL, _ := url.Parse(server.URL)
101
				smartcardNumber := "4131953321"
102
103
				client := New(WithBaseURL(baseURL), WithEnvironment(environment))
104
105
				// Act
106
				_, resp, err := client.Bills.CheckDStvUser(context.Background(), smartcardNumber)
107
108
				// Assert
109
				assert.Error(t, err)
110
111
				assert.Equal(t, "ERR101", resp.Error.Code)
112
				assert.Equal(t, "Invalid username or api_key", resp.Error.Description)
113
114
				// Teardown
115
				server.Close()
116
			})
117
		}
118
	})
119
120
	t.Run("it returns an error when the context is cancelled", func(t *testing.T) {
121
		t.Parallel()
122
123
		environments := []Environment{LiveEnvironment, TestEnvironment}
124
		for _, environment := range environments {
125
			t.Run(environment.String(), func(t *testing.T) {
126
				t.Parallel()
127
128
				// Arrange
129
				server := helpers.MakeTestServer(http.StatusOK, stubs.CheckDstvUserResponse())
130
				baseURL, _ := url.Parse(server.URL)
131
				client := New(WithBaseURL(baseURL), WithEnvironment(environment))
132
				ctx, cancel := context.WithCancel(context.Background())
133
				cancel()
134
135
				// Act
136
				_, _, err := client.Bills.CheckDStvUser(ctx, "")
137
138
				// Assert
139
				assert.True(t, errors.Is(err, context.Canceled))
140
				server.Close()
141
			})
142
		}
143
	})
144
145
	t.Run("it returns an error when the response cannot be decoded", func(t *testing.T) {
146
		t.Parallel()
147
148
		environments := []Environment{LiveEnvironment, TestEnvironment}
149
		for _, environment := range environments {
150
			t.Run(environment.String(), func(t *testing.T) {
151
				t.Parallel()
152
153
				// Arrange
154
				server := helpers.MakeTestServer(http.StatusOK, "<not-a-json></not-a-json>")
155
				baseURL, _ := url.Parse(server.URL)
156
				client := New(WithBaseURL(baseURL), WithEnvironment(environment))
157
158
				// Act
159
				_, _, err := client.Bills.CheckDStvUser(context.Background(), "")
160
161
				// Assert
162
				assert.Error(t, err)
163
164
				// Teardown
165
				server.Close()
166
			})
167
		}
168
	})
169
}
170
171
//nolint:funlen
172
func TestBillsService_PayDStv(t *testing.T) {
173
	t.Parallel()
174
	t.Run("it returns the dstv transaction response with a valid payment", func(t *testing.T) {
175
		t.Parallel()
176
177
		// Arrange
178
		server := helpers.MakeTestServer(http.StatusOK, stubs.PayDstvBillResponse())
179
		baseURL, _ := url.Parse(server.URL)
180
		client := New(WithBaseURL(baseURL))
181
182
		// Act
183
		transaction, _, err := client.Bills.PayDStv(context.Background(), &PayDstvOptions{})
184
185
		// Assert
186
		assert.NoError(t, err)
187
188
		assert.Equal(t, "122790223", transaction.TransactionID)
189
		assert.Equal(t, "DSTV", transaction.Details.Service)
190
		assert.Equal(t, "DStv Mobile MAXI", transaction.Details.Package)
191
		assert.Equal(t, "4131953321", transaction.Details.SmartcardNumber)
192
		assert.Equal(t, "790", transaction.Details.Price)
193
		assert.Equal(t, "SUCCESSFUL", transaction.Details.Status)
194
		assert.Equal(t, "7931", transaction.Details.Balance)
195
196
		// Teardown
197
		server.Close()
198
	})
199
200
	t.Run("it constructs the request correctly", func(t *testing.T) {
201
		t.Parallel()
202
203
		environments := []Environment{LiveEnvironment, TestEnvironment}
204
		for _, environment := range environments {
205
			t.Run(environment.String(), func(t *testing.T) {
206
				// Arrange
207
				request := new(http.Request)
208
				server := helpers.MakeRequestCapturingTestServer(http.StatusOK, stubs.CheckDstvUserResponse(), request)
209
210
				baseURL, _ := url.Parse(server.URL)
211
				username := testUsername
212
				apiKey := testAPIKey
213
				smartcardNumber := "4131953321"
214
				customerNumber := "275953782"
215
				customerName := "ESU INI OBONG BASSEY"
216
				price := "790"
217
				transactionID := "122790223"
218
219
				client := New(WithBaseURL(baseURL), WithAPIKey(apiKey), WithUsername(username), WithEnvironment(environment))
220
221
				// Act
222
				_, _, _ = client.Bills.PayDStv(context.Background(), &PayDstvOptions{
223
					TransactionID:   transactionID,
224
					Price:           price,
225
					ProductCode:     DstvProductCodePremium,
226
					CustomerName:    customerName,
227
					CustomerNumber:  customerNumber,
228
					SmartcardNumber: smartcardNumber,
229
				})
230
231
				// Assert
232
				uri := "/bills/dstv"
233
				if environment == TestEnvironment {
234
					uri += "_test"
235
				}
236
237
				assert.Equal(t, uri, request.URL.Path)
238
				assert.Equal(t, username, request.URL.Query().Get("username"))
239
				assert.Equal(t, apiKey, request.URL.Query().Get("api_key"))
240
				assert.Equal(t, smartcardNumber, request.URL.Query().Get("smartno"))
241
				assert.Equal(t, string(DstvProductCodePremium), request.URL.Query().Get("product_code"))
242
				assert.Equal(t, customerName, request.URL.Query().Get("customer_name"))
243
				assert.Equal(t, customerNumber, request.URL.Query().Get("customer_number"))
244
				assert.Equal(t, price, request.URL.Query().Get("price"))
245
				assert.Equal(t, transactionID, request.URL.Query().Get("trans_id"))
246
247
				// Teardown
248
				server.Close()
249
			})
250
		}
251
	})
252
253
	t.Run("it returns an error when the api responds with an error", func(t *testing.T) {
254
		t.Parallel()
255
256
		environments := []Environment{LiveEnvironment, TestEnvironment}
257
		for _, environment := range environments {
258
			t.Run(environment.String(), func(t *testing.T) {
259
				// Arrange
260
				server := helpers.MakeTestServer(http.StatusOK, stubs.ErrorResponse())
261
				baseURL, _ := url.Parse(server.URL)
262
263
				client := New(WithBaseURL(baseURL), WithEnvironment(environment))
264
265
				// Act
266
				_, resp, err := client.Bills.PayDStv(context.Background(), &PayDstvOptions{})
267
268
				// Assert
269
				assert.Error(t, err)
270
271
				assert.Equal(t, "ERR101", resp.Error.Code)
272
				assert.Equal(t, "Invalid username or api_key", resp.Error.Description)
273
274
				server.Close()
275
			})
276
		}
277
	})
278
279
	t.Run("it returns an error when the context is cancelled", func(t *testing.T) {
280
		t.Parallel()
281
282
		environments := []Environment{LiveEnvironment, TestEnvironment}
283
		for _, environment := range environments {
284
			t.Run(environment.String(), func(t *testing.T) {
285
				// Arrange
286
				server := helpers.MakeTestServer(http.StatusOK, stubs.CheckDstvUserResponse())
287
				baseURL, _ := url.Parse(server.URL)
288
				client := New(WithBaseURL(baseURL), WithEnvironment(environment))
289
				ctx, cancel := context.WithCancel(context.Background())
290
				cancel()
291
292
				// Act
293
				_, _, err := client.Bills.PayDStv(ctx, &PayDstvOptions{})
294
295
				// Assert
296
				assert.True(t, errors.Is(err, context.Canceled))
297
298
				// Teardown
299
				server.Close()
300
			})
301
		}
302
	})
303
304
	t.Run("it returns an error if the options is nil", func(t *testing.T) {
305
		t.Parallel()
306
307
		environments := []Environment{LiveEnvironment, TestEnvironment}
308
		for _, environment := range environments {
309
			t.Run(environment.String(), func(t *testing.T) {
310
				// Arrange
311
				server := helpers.MakeTestServer(http.StatusOK, stubs.CheckDstvUserResponse())
312
				baseURL, _ := url.Parse(server.URL)
313
				client := New(WithBaseURL(baseURL), WithEnvironment(environment))
314
				ctx, cancel := context.WithCancel(context.Background())
315
				cancel()
316
317
				// Act
318
				_, _, err := client.Bills.PayDStv(ctx, nil)
319
320
				// Assert
321
				assert.Error(t, err)
322
323
				// Teardown
324
				server.Close()
325
			})
326
		}
327
	})
328
329
	t.Run("it returns an error when the response cannot be decoded", func(t *testing.T) {
330
		t.Parallel()
331
332
		environments := []Environment{LiveEnvironment, TestEnvironment}
333
		for _, environment := range environments {
334
			t.Run(environment.String(), func(t *testing.T) {
335
				t.Parallel()
336
337
				// Arrange
338
				server := helpers.MakeTestServer(http.StatusOK, "<not-a-json></not-a-json>")
339
				baseURL, _ := url.Parse(server.URL)
340
				client := New(WithBaseURL(baseURL), WithEnvironment(environment))
341
342
				// Act
343
				_, _, err := client.Bills.PayDStv(context.Background(), &PayDstvOptions{})
344
345
				// Assert
346
				assert.Error(t, err)
347
348
				// Teardown
349
				server.Close()
350
			})
351
		}
352
	})
353
}
354
355
//nolint:funlen
356
func TestBillsService_QueryDStv(t *testing.T) {
357
	t.Parallel()
358
	t.Run("it returns the dstv transaction response with a valid transaction ID", func(t *testing.T) {
359
		t.Parallel()
360
361
		// Arrange
362
		server := helpers.MakeTestServer(http.StatusOK, stubs.PayDstvBillResponse())
363
		baseURL, _ := url.Parse(server.URL)
364
		client := New(WithBaseURL(baseURL))
365
366
		// Act
367
		transaction, _, err := client.Bills.QueryDStv(context.Background(), "122790223")
368
369
		// Assert
370
		assert.NoError(t, err)
371
372
		assert.Equal(t, "122790223", transaction.TransactionID)
373
		assert.Equal(t, "DSTV", transaction.Details.Service)
374
		assert.Equal(t, "DStv Mobile MAXI", transaction.Details.Package)
375
		assert.Equal(t, "4131953321", transaction.Details.SmartcardNumber)
376
		assert.Equal(t, "790", transaction.Details.Price)
377
		assert.Equal(t, "SUCCESSFUL", transaction.Details.Status)
378
		assert.Equal(t, "7931", transaction.Details.Balance)
379
380
		// Teardown
381
		server.Close()
382
	})
383
384
	t.Run("it constructs the request correctly", func(t *testing.T) {
385
		t.Parallel()
386
387
		environments := []Environment{LiveEnvironment, TestEnvironment}
388
		for _, environment := range environments {
389
			t.Run(environment.String(), func(t *testing.T) {
390
				// Arrange
391
				request := new(http.Request)
392
				server := helpers.MakeRequestCapturingTestServer(http.StatusOK, stubs.CheckDstvUserResponse(), request)
393
394
				baseURL, _ := url.Parse(server.URL)
395
				username := testUsername
396
				apiKey := testAPIKey
397
				transactionID := "122790223"
398
399
				client := New(WithBaseURL(baseURL), WithAPIKey(apiKey), WithUsername(username), WithEnvironment(environment))
400
401
				// Act
402
				_, _, _ = client.Bills.QueryDStv(context.Background(), transactionID)
403
404
				// Assert
405
				assert.Equal(t, "/bills/query", request.URL.Path)
406
				assert.Equal(t, username, request.URL.Query().Get("username"))
407
				assert.Equal(t, apiKey, request.URL.Query().Get("api_key"))
408
				assert.Equal(t, transactionID, request.URL.Query().Get("trans_id"))
409
410
				// Teardown
411
				server.Close()
412
			})
413
		}
414
	})
415
416
	t.Run("it returns an error when the api responds with an error", func(t *testing.T) {
417
		t.Parallel()
418
419
		environments := []Environment{LiveEnvironment, TestEnvironment}
420
		for _, environment := range environments {
421
			t.Run(environment.String(), func(t *testing.T) {
422
				// Arrange
423
				server := helpers.MakeTestServer(http.StatusOK, stubs.ErrorResponse())
424
				baseURL, _ := url.Parse(server.URL)
425
426
				client := New(WithBaseURL(baseURL), WithEnvironment(environment))
427
428
				// Act
429
				_, resp, err := client.Bills.QueryDStv(context.Background(), "122790223")
430
431
				// Assert
432
				assert.Error(t, err)
433
434
				assert.Equal(t, "ERR101", resp.Error.Code)
435
				assert.Equal(t, "Invalid username or api_key", resp.Error.Description)
436
437
				server.Close()
438
			})
439
		}
440
	})
441
442
	t.Run("it returns an error when the context is cancelled", func(t *testing.T) {
443
		t.Parallel()
444
445
		environments := []Environment{LiveEnvironment, TestEnvironment}
446
		for _, environment := range environments {
447
			t.Run(environment.String(), func(t *testing.T) {
448
				t.Parallel()
449
450
				// Arrange
451
				server := helpers.MakeTestServer(http.StatusOK, stubs.CheckDstvUserResponse())
452
				baseURL, _ := url.Parse(server.URL)
453
				client := New(WithBaseURL(baseURL), WithEnvironment(environment))
454
				ctx, cancel := context.WithCancel(context.Background())
455
				cancel()
456
457
				// Act
458
				_, _, err := client.Bills.QueryDStv(ctx, "122790223")
459
460
				// Assert
461
				assert.True(t, errors.Is(err, context.Canceled))
462
463
				// Teardown
464
				server.Close()
465
			})
466
		}
467
	})
468
469
	t.Run("it returns an error when the response cannot be decoded", func(t *testing.T) {
470
		t.Parallel()
471
472
		environments := []Environment{LiveEnvironment, TestEnvironment}
473
		for _, environment := range environments {
474
			t.Run(environment.String(), func(t *testing.T) {
475
				t.Parallel()
476
477
				// Arrange
478
				server := helpers.MakeTestServer(http.StatusOK, "<not-a-json></not-a-json>")
479
				baseURL, _ := url.Parse(server.URL)
480
				client := New(WithBaseURL(baseURL), WithEnvironment(environment))
481
482
				// Act
483
				_, _, err := client.Bills.QueryDStv(context.Background(), "122790223")
484
485
				// Assert
486
				assert.Error(t, err)
487
488
				// Teardown
489
				server.Close()
490
			})
491
		}
492
	})
493
}
494