add locations endpoint and fix some tests
This commit is contained in:
parent
a26328c412
commit
831c121983
120
api/location.go
Normal file
120
api/location.go
Normal 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)
|
||||||
|
}
|
@ -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
31
api/test/location_test.go
Normal 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
|
||||||
|
})
|
||||||
|
}
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
41
db/sqlc/test/locations_test.go
Normal file
41
db/sqlc/test/locations_test.go
Normal 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)
|
||||||
|
}
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user