add locations endpoint and fix some tests

This commit is contained in:
nochill 2023-09-13 21:42:31 +07:00
parent a26328c412
commit 831c121983
7 changed files with 210 additions and 13 deletions

120
api/location.go Normal file
View File

@ -0,0 +1,120 @@
package api
import (
"database/sql"
"fmt"
"net/http"
"os"
"path/filepath"
"time"
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"
)
type createLocationReq struct {
Address string `form:"address" binding:"required"`
Name string `form:"name" binding:"required"`
SubmittedBy int32 `form:"submitted_by" binding:"required,number"`
RegencyID int16 `form:"regency_id" binding:"required,number"`
GoogleMapsLink string `form:"google_maps_link"`
}
func (server *Server) createLocation(ctx *gin.Context) {
var req createLocationReq
var imgPath string
var thumbnail, _ = ctx.FormFile("thumbnail")
if err := ctx.Bind(&req); err != nil {
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
return
}
if thumbnail != nil {
img := thumbnail
fileExt := filepath.Ext(img.Filename)
now := time.Now()
dir := fmt.Sprintf("public/upload/images/locations/%s/thumbnail", req.Name)
osFilename := fmt.Sprintf("%s%s%s", util.RandomString(5), fmt.Sprintf("%v", now.Unix()), fileExt)
imgPath = fmt.Sprintf("%s%s", dir, osFilename)
if _, err := os.Stat(dir); os.IsNotExist(err) {
os.Mkdir(dir, 0775)
}
if err := ctx.SaveUploadedFile(img, imgPath); err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Error while try to save thumbnail image"))
return
}
}
arg := db.CreateLocationParams{
Address: req.Address,
Name: req.Name,
SubmittedBy: req.SubmittedBy,
RegencyID: req.RegencyID,
GoogleMapsLink: sql.NullString{Valid: len(req.GoogleMapsLink) > 0, String: req.GoogleMapsLink},
}
err := server.Store.CreateLocation(ctx, arg)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
ctx.JSON(http.StatusConflict, ErrorResponse(err, fmt.Sprintf("Something went wrong, code: %s", pqErr.Code.Name())))
return
}
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong"))
return
}
ctx.Writer.WriteHeader(http.StatusOK)
}
type getListLocationsReq struct {
Page int32 `form:"page" binding:"required,min=1"`
PageSize int32 `form:"page_size" binding:"required,min=5"`
}
func (server *Server) getListLocations(ctx *gin.Context) {
var req getListLocationsReq
if err := ctx.ShouldBindQuery(&req); err != nil {
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
return
}
arg := db.GetListLocationsParams{
Limit: req.PageSize,
Offset: (req.Page - 1) * req.PageSize,
}
locations, err := server.Store.GetListLocations(ctx, arg)
if err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong"))
return
}
ctx.JSON(http.StatusOK, locations)
}
type getLocationReq struct {
ID int32 `uri:"location_id" binding:"required"`
}
func (server *Server) getLocation(ctx *gin.Context) {
var req getLocationReq
if err := ctx.ShouldBindUri(&req); err != nil {
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
return
}
location, err := server.Store.GetLocation(ctx, req.ID)
if err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong"))
return
}
ctx.JSON(http.StatusOK, location)
}

View File

@ -10,9 +10,9 @@ import (
) )
type Server struct { type Server struct {
config util.Config Config util.Config
store db.Store Store db.Store
tokenMaker token.Maker TokenMaker token.Maker
Router *gin.Engine Router *gin.Engine
} }
@ -23,9 +23,9 @@ func NewServer(config util.Config, store db.Store) (*Server, error) {
} }
server := &Server{ server := &Server{
config: config, Config: config,
store: store, Store: store,
tokenMaker: tokenMaker, TokenMaker: tokenMaker,
} }
server.getRoutes() server.getRoutes()
@ -37,6 +37,11 @@ func (server *Server) getRoutes() {
router.POST("/user/signup", server.createUser) router.POST("/user/signup", server.createUser)
// LOCATION
router.POST("/locations", server.createLocation)
router.GET("/locations", server.getListLocations)
router.GET("/location/:location_id", server.getLocation)
server.Router = router server.Router = router
} }

31
api/test/location_test.go Normal file
View File

@ -0,0 +1,31 @@
package api_test
import (
"database/sql"
"testing"
db "git.nochill.in/nochill/hiling_go/db/sqlc"
"git.nochill.in/nochill/hiling_go/util"
"go.uber.org/mock/gomock"
)
func TestGetListLocationsAPI(t *testing.T) {
}
func TestCreateLocationAPI(t *testing.T) {
_ = db.CreateLocationParams{
Address: util.RandomString(10),
Name: util.RandomString(10),
SubmittedBy: int32(util.RandomInt(0, 10)),
RegencyID: 1305,
GoogleMapsLink: sql.NullString{Valid: true, String: util.RandomString(10)},
}
t.Run("OK", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
// store := mockdb.MockStore
})
}

View File

@ -22,10 +22,10 @@ func TestSignupAPI(t *testing.T) {
defer ctrl.Finish() defer ctrl.Finish()
store := mockdb.NewMockStore(ctrl) store := mockdb.NewMockStore(ctrl)
store.EXPECT(). // store.EXPECT().
CreateUser(gomock.Any(), gomock.Any()). // CreateUser(gomock.Any(), gomock.Any()).
Times(1). // Times(1).
Return(user, nil) // Return(user, nil)
server := newTestServer(t, store) server := newTestServer(t, store)
recorder := httptest.NewRecorder() recorder := httptest.NewRecorder()
@ -56,5 +56,5 @@ func createUser(t *testing.T) (user db.User, password string) {
Password: hashedPassword, Password: hashedPassword,
} }
return return user, passw
} }

View File

@ -51,7 +51,7 @@ func (server *Server) createUser(ctx *gin.Context) {
Password: hashedPassword, Password: hashedPassword,
} }
user, err := server.store.CreateUser(ctx, arg) user, err := server.Store.CreateUser(ctx, arg)
if err != nil { if err != nil {
if pqErr, ok := err.(*pq.Error); ok { if pqErr, ok := err.(*pq.Error); ok {
switch pqErr.Code.Name() { switch pqErr.Code.Name() {

View File

@ -0,0 +1,41 @@
package db_test
import (
"context"
"database/sql"
"testing"
db "git.nochill.in/nochill/hiling_go/db/sqlc"
"git.nochill.in/nochill/hiling_go/util"
"github.com/stretchr/testify/require"
)
func TestGetLocationsList(t *testing.T) {
arg := db.GetListLocationsParams{
Limit: 10,
Offset: 0,
}
locations, err := testQueries.GetListLocations(context.Background(), arg)
require.NoError(t, err)
require.NotEmpty(t, locations)
}
func TestGetLocation(t *testing.T) {
location, err := testQueries.GetLocation(context.Background(), 1)
require.NoError(t, err)
require.NotEmpty(t, location)
}
func TestCreateLocation(t *testing.T) {
arg := db.CreateLocationParams{
Address: util.RandomString(12),
Name: util.RandomString(10),
SubmittedBy: 1,
RegencyID: 1305,
GoogleMapsLink: sql.NullString{Valid: true, String: util.RandomString(10)},
}
err := testQueries.CreateLocation(context.Background(), arg)
require.NoError(t, err)
}

View File

@ -11,7 +11,7 @@ import (
func TestCreateUser(t *testing.T) { func TestCreateUser(t *testing.T) {
arg := db.CreateUserParams{ arg := db.CreateUserParams{
Username: util.RandomString(10), Username: util.RandomString(7),
Password: util.RandomString(10), Password: util.RandomString(10),
} }