diff --git a/api/BaseResponse.go b/api/BaseResponse.go index 516ada9..2444442 100644 --- a/api/BaseResponse.go +++ b/api/BaseResponse.go @@ -2,14 +2,14 @@ package api import "github.com/gin-gonic/gin" -func errorResponse(err error, msg string) gin.H { +func ErrorResponse(err error, msg string) gin.H { return gin.H{ "error": err.Error(), "message": msg, } } -func validResponse(data interface{}, msg string) gin.H { +func ValidResponse(data interface{}, msg string) gin.H { return gin.H{ "message": msg, "data": data, diff --git a/api/test/main_test.go b/api/test/main_test.go new file mode 100644 index 0000000..02b32a2 --- /dev/null +++ b/api/test/main_test.go @@ -0,0 +1,32 @@ +package api_test + +import ( + "os" + "testing" + "time" + + api "git.nochill.in/nochill/hiling_go/api" + db "git.nochill.in/nochill/hiling_go/db/sqlc" + "git.nochill.in/nochill/hiling_go/util" + "github.com/gin-gonic/gin" + _ "github.com/lib/pq" + "github.com/stretchr/testify/require" +) + +func newTestServer(t *testing.T, store db.Store) *api.Server { + config := util.Config{ + TokenSymmetricKey: util.RandomString(32), + TokenDuration: time.Minute, + } + + server, err := api.NewServer(config, store) + require.NoError(t, err) + + return server +} + +func TestMain(m *testing.M) { + gin.SetMode(gin.TestMode) + + os.Exit(m.Run()) +} diff --git a/api/test/user_test.go b/api/test/user_test.go new file mode 100644 index 0000000..81689c2 --- /dev/null +++ b/api/test/user_test.go @@ -0,0 +1,60 @@ +package api_test + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + mockdb "git.nochill.in/nochill/hiling_go/db/mock" + db "git.nochill.in/nochill/hiling_go/db/sqlc" + "git.nochill.in/nochill/hiling_go/util" + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" +) + +func TestSignupAPI(t *testing.T) { + user, pass := createUser(t) + t.Run("OK", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + store := mockdb.NewMockStore(ctrl) + store.EXPECT(). + CreateUser(gomock.Any(), gomock.Any()). + Times(1). + Return(user, nil) + + server := newTestServer(t, store) + recorder := httptest.NewRecorder() + + data, err := json.Marshal(gin.H{ + "username": user.Username, + "password": pass, + }) + require.NoError(t, err) + + url := "/user/signup" + request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(data)) + require.NoError(t, err) + + server.Router.ServeHTTP(recorder, request) + require.Equal(t, http.StatusOK, recorder.Code) + + }) +} + +func createUser(t *testing.T) (user db.User, password string) { + passw := util.RandomString(10) + hashedPassword, err := util.HashPassword(passw) + require.NoError(t, err) + + user = db.User{ + Username: util.RandomString(10), + Password: hashedPassword, + } + + return +} diff --git a/db/mock/store.go b/db/mock/store.go new file mode 100644 index 0000000..8bc1c5d --- /dev/null +++ b/db/mock/store.go @@ -0,0 +1,80 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: git.nochill.in/nochill/hiling_go/db/sqlc (interfaces: Store) + +// Package mockdb is a generated GoMock package. +package mockdb + +import ( + context "context" + reflect "reflect" + + db "git.nochill.in/nochill/hiling_go/db/sqlc" + gomock "go.uber.org/mock/gomock" +) + +// MockStore is a mock of Store interface. +type MockStore struct { + ctrl *gomock.Controller + recorder *MockStoreMockRecorder +} + +// MockStoreMockRecorder is the mock recorder for MockStore. +type MockStoreMockRecorder struct { + mock *MockStore +} + +// NewMockStore creates a new mock instance. +func NewMockStore(ctrl *gomock.Controller) *MockStore { + mock := &MockStore{ctrl: ctrl} + mock.recorder = &MockStoreMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockStore) EXPECT() *MockStoreMockRecorder { + return m.recorder +} + +// CreateUser mocks base method. +func (m *MockStore) CreateUser(arg0 context.Context, arg1 db.CreateUserParams) (db.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateUser", arg0, arg1) + ret0, _ := ret[0].(db.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateUser indicates an expected call of CreateUser. +func (mr *MockStoreMockRecorder) CreateUser(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockStore)(nil).CreateUser), arg0, arg1) +} + +// UpdatePassword mocks base method. +func (m *MockStore) UpdatePassword(arg0 context.Context, arg1 db.UpdatePasswordParams) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdatePassword", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdatePassword indicates an expected call of UpdatePassword. +func (mr *MockStoreMockRecorder) UpdatePassword(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatePassword", reflect.TypeOf((*MockStore)(nil).UpdatePassword), arg0, arg1) +} + +// UpdateUser mocks base method. +func (m *MockStore) UpdateUser(arg0 context.Context, arg1 db.UpdateUserParams) (db.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateUser", arg0, arg1) + ret0, _ := ret[0].(db.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateUser indicates an expected call of UpdateUser. +func (mr *MockStoreMockRecorder) UpdateUser(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUser", reflect.TypeOf((*MockStore)(nil).UpdateUser), arg0, arg1) +} diff --git a/db/sqlc/test/main_test.go b/db/sqlc/test/main_test.go new file mode 100644 index 0000000..f360d97 --- /dev/null +++ b/db/sqlc/test/main_test.go @@ -0,0 +1,32 @@ +package db_test + +import ( + "database/sql" + "log" + "os" + "testing" + + db "git.nochill.in/nochill/hiling_go/db/sqlc" + "git.nochill.in/nochill/hiling_go/util" + _ "github.com/lib/pq" +) + +var testQueries *db.Queries +var testDB *sql.DB + +func TestMain(m *testing.M) { + var err error + config, err := util.LoadConfig("../../..") + if err != nil { + log.Fatal("cannot load config: ", err) + } + + testDB, err = sql.Open(config.DBDriver, config.DBSourceTest) + if err != nil { + log.Fatal("cannot connect db: ", err) + } + + testQueries = db.New(testDB) + + os.Exit(m.Run()) +} diff --git a/db/sqlc/test/users_test.go b/db/sqlc/test/users_test.go new file mode 100644 index 0000000..c5fc044 --- /dev/null +++ b/db/sqlc/test/users_test.go @@ -0,0 +1,23 @@ +package db_test + +import ( + "context" + "testing" + + db "git.nochill.in/nochill/hiling_go/db/sqlc" + "git.nochill.in/nochill/hiling_go/util" + "github.com/stretchr/testify/require" +) + +func TestCreateUser(t *testing.T) { + arg := db.CreateUserParams{ + Username: util.RandomString(10), + Password: util.RandomString(10), + } + + user, err := testQueries.CreateUser(context.Background(), arg) + + require.NoError(t, err) + require.Equal(t, user.Username, arg.Username) + require.Equal(t, user.Password, arg.Password) +} diff --git a/go.mod b/go.mod index 1b552d4..d190f2e 100644 --- a/go.mod +++ b/go.mod @@ -45,6 +45,7 @@ require ( github.com/subosito/gotenv v1.4.2 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect + go.uber.org/mock v0.2.0 // indirect golang.org/x/arch v0.5.0 // indirect golang.org/x/crypto v0.13.0 // indirect golang.org/x/net v0.15.0 // indirect diff --git a/go.sum b/go.sum index 9296814..8d63038 100644 --- a/go.sum +++ b/go.sum @@ -241,6 +241,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= +go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y= golang.org/x/arch v0.5.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= diff --git a/notes b/notes index 6bcbc59..00c8bea 100644 --- a/notes +++ b/notes @@ -32,4 +32,15 @@ ex: select message where commented_id = ... and where comment_type = (stories, r https://en.wikipedia.org/wiki/Provinces_of_Indonesia +########################################################################################## + + + +######################### CUSTOM GIN VALIDATION ERR MESSAGE ############################## + +make custom err message, and get all the type, the err message sucks now +https://github.com/gin-gonic/gin/issues/430 (using middleware) +tbh i'd raher use like a wrapper instead of middleware but we'll see + + ########################################################################################## \ No newline at end of file