Skip to content

Commit

Permalink
refactor: Return struct, accept interface
Browse files Browse the repository at this point in the history
Signed-off-by: Vincent Boutour <[email protected]>
  • Loading branch information
ViBiOh committed Aug 8, 2021
1 parent 8c03086 commit 02aad89
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 36 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ style:
.PHONY: mocks
mocks:
find . -name "mocks" -type d -exec rm -r "{}" \+
mockgen -destination pkg/mocks/user_service.go -mock_names UserService=UserService -package mocks github.com/ViBiOh/ketchup/pkg/middleware UserService
mockgen -destination pkg/mocks/mailer.go -mock_names Mailer=Mailer -package mocks github.com/ViBiOh/ketchup/pkg/notifier Mailer
mockgen -destination pkg/mocks/auth.go -mock_names AuthService=Auth -package mocks github.com/ViBiOh/ketchup/pkg/service/user AuthService

Expand Down
17 changes: 5 additions & 12 deletions pkg/ketchup/ketchup.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,17 @@ var (
)

// App of package
type App interface {
Handler() http.Handler
Signup() http.Handler
PublicTemplateFunc(http.ResponseWriter, *http.Request) (string, int, map[string]interface{}, error)
AppTemplateFunc(http.ResponseWriter, *http.Request) (string, int, map[string]interface{}, error)
}

type app struct {
rendererApp renderer.App
ketchupService ketchup.App
type App struct {
userService user.App
ketchupService ketchup.App
repositoryService repository.App
redisApp redis.App
rendererApp renderer.App
}

// New creates new App from Config
func New(rendererApp renderer.App, ketchupService ketchup.App, userService user.App, repositoryService repository.App, redisApp redis.App) App {
return app{
return App{
rendererApp: rendererApp,
ketchupService: ketchupService,
userService: userService,
Expand All @@ -62,7 +55,7 @@ func New(rendererApp renderer.App, ketchupService ketchup.App, userService user.
}

// Handler for request. Should be use with net/http
func (a app) Handler() http.Handler {
func (a App) Handler() http.Handler {
rendererHandler := a.rendererApp.Handler(a.AppTemplateFunc)
ketchupHandler := http.StripPrefix(ketchupsPath, a.ketchups())

Expand Down
8 changes: 4 additions & 4 deletions pkg/ketchup/ketchups.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/ViBiOh/ketchup/pkg/model"
)

func (a app) ketchups() http.Handler {
func (a App) ketchups() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
a.rendererApp.Error(w, httpModel.WrapMethodNotAllowed(fmt.Errorf("invalid method %s", r.Method)))
Expand All @@ -38,7 +38,7 @@ func (a app) ketchups() http.Handler {
})
}

func (a app) handleCreate(w http.ResponseWriter, r *http.Request) {
func (a App) handleCreate(w http.ResponseWriter, r *http.Request) {
repositoryKind, err := model.ParseRepositoryKind(r.FormValue("kind"))
if err != nil {
a.rendererApp.Error(w, httpModel.WrapInvalid(err))
Expand Down Expand Up @@ -74,7 +74,7 @@ func (a app) handleCreate(w http.ResponseWriter, r *http.Request) {
a.rendererApp.Redirect(w, r, fmt.Sprintf("%s/", appPath), renderer.NewSuccessMessage(fmt.Sprintf("%s created with success!", created.Repository.Name)))
}

func (a app) handleUpdate(w http.ResponseWriter, r *http.Request) {
func (a App) handleUpdate(w http.ResponseWriter, r *http.Request) {
rawID := strings.Trim(r.URL.Path, "/")
if rawID == "all" {
if err := a.ketchupService.UpdateAll(r.Context()); err != nil {
Expand Down Expand Up @@ -109,7 +109,7 @@ func (a app) handleUpdate(w http.ResponseWriter, r *http.Request) {
a.rendererApp.Redirect(w, r, fmt.Sprintf("%s/", appPath), renderer.NewSuccessMessage(fmt.Sprintf("Updated %s with success!", updated.Version)))
}

func (a app) handleDelete(w http.ResponseWriter, r *http.Request) {
func (a App) handleDelete(w http.ResponseWriter, r *http.Request) {
id, err := strconv.ParseUint(strings.Trim(r.URL.Path, "/"), 10, 64)
if err != nil {
a.rendererApp.Error(w, httpModel.WrapInvalid(err))
Expand Down
6 changes: 4 additions & 2 deletions pkg/ketchup/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ const (
suggestThresold = uint64(5)
)

func (a app) PublicTemplateFunc(_ http.ResponseWriter, r *http.Request) (string, int, map[string]interface{}, error) {
// PublicTemplateFunc rendering public GUI
func (a App) PublicTemplateFunc(_ http.ResponseWriter, r *http.Request) (string, int, map[string]interface{}, error) {
securityPayload, err := a.generateToken(r.Context())
if err != nil {
return "", http.StatusInternalServerError, nil, err
Expand All @@ -36,7 +37,8 @@ func min(a, b uint64) uint64 {
return b
}

func (a app) AppTemplateFunc(_ http.ResponseWriter, r *http.Request) (string, int, map[string]interface{}, error) {
// AppTemplateFunc rendering private GUI
func (a App) AppTemplateFunc(_ http.ResponseWriter, r *http.Request) (string, int, map[string]interface{}, error) {
pagination, err := query.ParsePagination(r, 100, 100)
if err != nil {
return "", http.StatusBadRequest, nil, err
Expand Down
6 changes: 3 additions & 3 deletions pkg/ketchup/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func uuid() string {
return fmt.Sprintf("%x-%x-%x-%x-%x", raw[0:4], raw[4:6], raw[6:8], raw[8:10], raw[10:])
}

func (a app) generateToken(ctx context.Context) (SecurityPayload, error) {
func (a App) generateToken(ctx context.Context) (SecurityPayload, error) {
questionID, err := rand.Int(rand.Reader, big.NewInt(int64(len(colors))))
if err != nil {
return SecurityPayload{}, fmt.Errorf("unable to generate random int: %w", err)
Expand All @@ -72,7 +72,7 @@ func (a app) generateToken(ctx context.Context) (SecurityPayload, error) {
}, nil
}

func (a app) validateToken(ctx context.Context, token, answer string) bool {
func (a App) validateToken(ctx context.Context, token, answer string) bool {
questionIDString, err := a.redisApp.Load(ctx, token)
if err != nil {
logger.Warn("unable to retrieve captcha token: %s", err)
Expand All @@ -93,7 +93,7 @@ func (a app) validateToken(ctx context.Context, token, answer string) bool {
return true
}

func (a app) cleanToken(ctx context.Context, token string) {
func (a App) cleanToken(ctx context.Context, token string) {
if err := a.redisApp.Delete(ctx, token); err != nil {
logger.WithField("token", token).Error("unable to delete token: %s", err)
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/ketchup/signup.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import (
"github.com/ViBiOh/ketchup/pkg/model"
)

func (a app) Signup() http.Handler {
// Signup handler
func (a App) Signup() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
a.rendererApp.Error(w, httpModel.WrapMethodNotAllowed(fmt.Errorf("invalid method %s", r.Method)))
Expand Down
21 changes: 11 additions & 10 deletions pkg/middleware/middleware.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
package middleware

import (
"context"
"net/http"

"github.com/ViBiOh/ketchup/pkg/service/user"
)

// App of package
type App interface {
Middleware(next http.Handler) http.Handler
// UserService for storing user in context
type UserService interface {
StoreInContext(context.Context) context.Context
}

type app struct {
userService user.App
// App of package
type App struct {
userService UserService
}

// New creates new App from Config
func New(userService user.App) App {
return app{
func New(userService UserService) App {
return App{
userService: userService,
}
}

func (a app) Middleware(next http.Handler) http.Handler {
// Middleware for use with net/http
func (a App) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if next != nil {
next.ServeHTTP(w, r.WithContext(a.userService.StoreInContext(r.Context())))
Expand Down
15 changes: 11 additions & 4 deletions pkg/middleware/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (

authModel "github.com/ViBiOh/auth/v2/pkg/model"
"github.com/ViBiOh/httputils/v4/pkg/request"
"github.com/ViBiOh/ketchup/pkg/mocks"
"github.com/ViBiOh/ketchup/pkg/model"
"github.com/ViBiOh/ketchup/pkg/service/user"
"github.com/ViBiOh/ketchup/pkg/store/user/usertest"
"github.com/golang/mock/gomock"
)

func TestMiddleware(t *testing.T) {
Expand All @@ -29,7 +29,7 @@ func TestMiddleware(t *testing.T) {
t.Errorf("unable to write: %s", err)
}
}),
httptest.NewRequest(http.MethodGet, "/", nil).WithContext(authModel.StoreUser(context.Background(), authModel.NewUser(8000, "test"))),
httptest.NewRequest(http.MethodGet, "/", nil).WithContext(authModel.StoreUser(context.Background(), authModel.NewUser(1, "test"))),
"nobody@localhost",
http.StatusOK,
http.Header{},
Expand All @@ -46,8 +46,15 @@ func TestMiddleware(t *testing.T) {

for _, tc := range cases {
t.Run(tc.intention, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

userService := mocks.NewUserService(ctrl)
if tc.intention == "simple" {
userService.EXPECT().StoreInContext(gomock.Any()).Return(model.StoreUser(context.Background(), model.NewUser(1, "nobody@localhost", authModel.NewUser(1, "test"))))
}

writer := httptest.NewRecorder()
userService := user.New(usertest.New().SetGetByLoginID(model.NewUser(1, "nobody@localhost", authModel.NewUser(8000, "test")), nil), nil)
New(userService).Middleware(tc.next).ServeHTTP(writer, tc.request)

if got := writer.Code; got != tc.wantStatus {
Expand Down

0 comments on commit 02aad89

Please sign in to comment.