package api import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http" "net/http/httptest" "reflect" "testing" mockdb "git.nochill.in/nochill/naice_pos/db/mock" db "git.nochill.in/nochill/naice_pos/db/sqlc" "git.nochill.in/nochill/naice_pos/util" "github.com/gin-gonic/gin" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) type eqCreateUserMerchantParamsMatcher struct { arg db.UserMerchantTxParams password string } func (e eqCreateUserMerchantParamsMatcher) Matches(x interface{}) bool { arg, ok := x.(db.UserMerchantTxParams) if !ok { return false } err := util.CheckPassword(e.password, arg.Password) if err != nil { return false } e.arg.Password = arg.Password return reflect.DeepEqual(e.arg.Password, arg.Password) } func (e eqCreateUserMerchantParamsMatcher) String() string { return fmt.Sprintf("matches arg %v and password %v", e.arg, e.password) } func EqCreateUserMerchant(arg db.UserMerchantTxParams, password string) gomock.Matcher { return eqCreateUserMerchantParamsMatcher{arg, password} } func TestCreateUserMerchantAPI(t *testing.T) { userMerchant, password := randomUser(t) var userMerchantResult db.UserMerchantTxResult // var userMerchantResponse createUserMerchantResponse testCases := []struct { name string body gin.H buildStubs func(store *mockdb.MockStore) checkResponse func(recorder *httptest.ResponseRecorder) }{ { name: "OK", body: gin.H{ "email": userMerchant.Email, "fullname": userMerchant.Fullname, "password": password, "outlet_name": userMerchant.OutletName, }, buildStubs: func(store *mockdb.MockStore) { arg := db.UserMerchantTxParams{ Email: userMerchant.Email, Fullname: userMerchant.Fullname, OutletName: userMerchant.OutletName, } store.EXPECT(). CreateUserMerchantTx(gomock.Any(), EqCreateUserMerchant(arg, password)). Times(1). Return(userMerchantResult, nil) }, checkResponse: func(recorder *httptest.ResponseRecorder) { require.Equal(t, http.StatusOK, recorder.Code) // requireBodyMatchUserMerchant(t, recorder.Body, userMerchantResponse) }, }, } for i := range testCases { tc := testCases[i] t.Run(tc.name, func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() store := mockdb.NewMockStore(ctrl) tc.buildStubs(store) server := newTestServer(t, store) recorder := httptest.NewRecorder() data, err := json.Marshal(tc.body) require.NoError(t, err) url := "/user/merchants" request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(data)) require.NoError(t, err) server.router.ServeHTTP(recorder, request) tc.checkResponse(recorder) }) } } func TestUserLoginAPI(t *testing.T) { user, password := randomUser(t) var userProfile db.User var userOutletProfile db.Merchant testCases := []struct { name string body gin.H buildStubs func(store *mockdb.MockStore) checkResponse func(recorder *httptest.ResponseRecorder) }{ { name: "OK", body: gin.H{ "email": user.Email, "password": password, }, buildStubs: func(store *mockdb.MockStore) { store.EXPECT(). GetUserByEmail(gomock.Any(), gomock.Eq(user.Email)). Times(1). Return(userProfile, nil) store.EXPECT(). GetMerchantByUserId(gomock.Any(), gomock.Any()). Times(1). Return(userOutletProfile, nil) store.EXPECT(). CreateSession(gomock.Any(), gomock.Any()). Times(1) }, checkResponse: func(recorder *httptest.ResponseRecorder) { require.Equal(t, http.StatusOK, recorder.Code) }, }, } for i := range testCases { tc := testCases[i] t.Run(tc.name, func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() store := mockdb.NewMockStore(ctrl) tc.buildStubs(store) server := newTestServer(t, store) recorder := httptest.NewRecorder() data, err := json.Marshal(tc.body) require.NoError(t, err) url := "/user/login" request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(data)) require.NoError(t, err) server.router.ServeHTTP(recorder, request) tc.checkResponse(recorder) }) } } func randomUser(t *testing.T) (userMerchant db.UserMerchantTxParams, password string) { password = util.RandomString(6) hashedPassword, err := util.HashPassword(password) require.NoError(t, err) userMerchant = db.UserMerchantTxParams{ Email: util.RandomEmail(), Fullname: util.RandomString(5), Password: hashedPassword, OutletName: util.RandomString(10), } return } func requireBodyMatchUserMerchant(t *testing.T, body *bytes.Buffer, userMerchant userMerchantResponse) { data, err := ioutil.ReadAll(body) require.NoError(t, err) var gotUserMerchant db.UserMerchantTxParams err = json.Unmarshal(data, &gotUserMerchant) require.NoError(t, err) }