-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain_test.go
142 lines (116 loc) · 4.8 KB
/
main_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package main
import (
"context"
"encoding/json"
"io/ioutil"
"math/rand"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/gamezop/interview-assignment-sc-rewards/repo"
"github.com/gamezop/jinbe/pkg/db_psql"
"github.com/gamezop/jinbe/pkg/errr"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/joho/godotenv"
"github.com/kelseyhightower/envconfig"
"github.com/stretchr/testify/require"
"gopkg.in/h2non/gock.v1"
)
func wireApp(testClient *http.Client) (*gin.Engine, *repo.Queries, func()) {
err := godotenv.Load("scratch-cards-rewards.e2e-test.env")
errr.FatalIfNotNil(err, "failed to load e2e env")
err = envconfig.Process("", &Env)
errr.PanicIfNotNil(err, "failed to load env")
rand.Seed(time.Now().Unix())
dbRewards := db_psql.DBConnectURL("test-db", Env.DB.RewardPayoutsURI)
runMigrate(dbRewards)
repository := repo.New(dbRewards)
return Router(repository, testClient), repository, func() {
dbRewards.Close()
}
}
func makePayoutRewardAPICall(t *testing.T, r *gin.Engine, path string, ScId uuid.UUID, headers map[string]string) ResponseRewardPayout {
body := RequestBodyRewardPayout{
ScId: ScId,
}
bodyStr, err := json.Marshal(body)
require.Nil(t, err, "failed to marshal")
req, err := http.NewRequest("POST", path, strings.NewReader(string(bodyStr)))
require.Nil(t, err, "failed to create request")
for k, v := range headers {
req.Header.Add(k, v)
}
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
responseData, err := ioutil.ReadAll(w.Body)
require.Nil(t, err, "failed to read response")
var response struct {
Data ResponseRewardPayout `json:"data"`
}
err = json.Unmarshal(responseData, &response)
require.Nil(t, err, "failed to unmarshal response")
return response.Data
}
func TestPayoutRewardR1(t *testing.T) {
r, repo, close := wireApp(&http.Client{})
ctxBack := context.Background()
defer close()
ScId := uuid.New()
response := makePayoutRewardAPICall(t, r, "/r1/payout", ScId, nil)
// test data
rewardPayoutDetails, err := repo.GetRewardPayoutByScratchId(ctxBack, ScId)
require.Nil(t, err, "failed read scCard DB")
require.Equal(t, rewardPayoutDetails.OrderID, response.OrderId, "failed to match orderId", rewardPayoutDetails.OrderID.String(), response.OrderId.String())
require.Equal(t, rewardPayoutDetails.Status, response.Status, "failed to match status")
}
func TestPayoutRewardR2(t *testing.T) {
r, repository, close := wireApp(&http.Client{})
ctxBack := context.Background()
defer close()
ScId := uuid.New()
response := makePayoutRewardAPICall(t, r, "/r2/payout", ScId, nil)
// initial require the status to be in pending
rewardPayoutDetails, err := repository.GetRewardPayoutByScratchId(ctxBack, ScId)
require.Nil(t, err, "expected no error")
require.Equal(t, repo.OrderStatusPending, response.Status, "require the r2 to be in pending initially")
require.Equal(t, rewardPayoutDetails.OrderID, response.OrderId, "failed to match orderId")
time.Sleep(time.Duration(maxOrderStatusInPendingStateSeconds+1) * time.Second)
rewardPayoutDetails, err = repository.GetRewardPayoutByScratchId(ctxBack, ScId)
require.Nil(t, err, "failed read scCard DB")
require.NotEqual(t, rewardPayoutDetails.Status, repo.OrderStatusPending, "didn't expect the order to be in pending")
require.Equal(t, rewardPayoutDetails.ScID, ScId, "failed to match sc-card-id")
require.NotEqual(t, rewardPayoutDetails.Status, repo.OrderStatusPending, "didn't expect the order to be in pending")
}
func TestPayoutRewardR3(t *testing.T) {
defer gock.Off()
var testClient *http.Client = &http.Client{}
r, repository, close := wireApp(testClient)
gock.InterceptClient(testClient)
ctxBack := context.Background()
defer close()
ScId := uuid.New()
mockServerAddr := "https://local.testing"
mockServerPath := "/completedOrder"
response := makePayoutRewardAPICall(t, r, "/r3/payout", ScId, map[string]string{
"x-callback-url": mockServerAddr + mockServerPath,
})
// initial require the status to be in pending
rewardPayoutDetails, err := repository.GetRewardPayoutByScratchId(ctxBack, ScId)
require.Nil(t, err, "expected no error")
require.Equal(t, repo.OrderStatusPending, response.Status, "require the r2 to be in pending initially")
require.Equal(t, rewardPayoutDetails.OrderID, response.OrderId, "failed to match orderId")
// expecting a callback on the api
gock.New(mockServerAddr).
Put(mockServerPath).
Times(1).
Reply(http.StatusOK).
BodyString(`{"status": "SUCCESS"}`)
time.Sleep(time.Duration(maxOrderStatusInPendingStateSeconds+1) * time.Second)
rewardPayoutDetails, err = repository.GetRewardPayoutByScratchId(ctxBack, ScId)
require.Nil(t, err, "failed read scCard DB")
require.Equal(t, rewardPayoutDetails.ScID, ScId, "failed to match sc-card-id")
require.NotEqual(t, rewardPayoutDetails.Status, repo.OrderStatusPending, "didn't expect the order to be in pending")
}