mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-03-13 02:02:04 +00:00
Compare commits
1 Commits
v5.0.3-bet
...
refactor/t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c8a9e93ff |
@@ -2,77 +2,77 @@ package controller_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http/httptest"
|
"io"
|
||||||
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/steveiliop56/tinyauth/internal/config"
|
|
||||||
"github.com/steveiliop56/tinyauth/internal/controller"
|
|
||||||
"github.com/steveiliop56/tinyauth/internal/utils/tlog"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/steveiliop56/tinyauth/internal/controller"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
var contextControllerCfg = controller.ContextControllerConfig{
|
func TestUserContextController(t *testing.T) {
|
||||||
Providers: []controller.Provider{
|
// Controller setup
|
||||||
{
|
suite := NewControllerTest(func(router *gin.RouterGroup) *controller.ContextController {
|
||||||
Name: "Local",
|
ctrl := controller.NewContextController(contextControllerCfg, router)
|
||||||
ID: "local",
|
|
||||||
OAuth: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Google",
|
|
||||||
ID: "google",
|
|
||||||
OAuth: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Title: "Test App",
|
|
||||||
AppURL: "http://localhost:8080",
|
|
||||||
CookieDomain: "localhost",
|
|
||||||
ForgotPasswordMessage: "Contact admin to reset your password.",
|
|
||||||
BackgroundImage: "/assets/bg.jpg",
|
|
||||||
OAuthAutoRedirect: "google",
|
|
||||||
WarningsEnabled: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
var contextCtrlTestContext = config.UserContext{
|
|
||||||
Username: "testuser",
|
|
||||||
Name: "testuser",
|
|
||||||
Email: "test@example.com",
|
|
||||||
IsLoggedIn: true,
|
|
||||||
IsBasicAuth: false,
|
|
||||||
OAuth: false,
|
|
||||||
Provider: "local",
|
|
||||||
TotpPending: false,
|
|
||||||
OAuthGroups: "",
|
|
||||||
TotpEnabled: false,
|
|
||||||
OAuthSub: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupContextController(middlewares *[]gin.HandlerFunc) (*gin.Engine, *httptest.ResponseRecorder) {
|
|
||||||
tlog.NewSimpleLogger().Init()
|
|
||||||
|
|
||||||
// Setup
|
|
||||||
gin.SetMode(gin.TestMode)
|
|
||||||
router := gin.Default()
|
|
||||||
recorder := httptest.NewRecorder()
|
|
||||||
|
|
||||||
if middlewares != nil {
|
|
||||||
for _, m := range *middlewares {
|
|
||||||
router.Use(m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
group := router.Group("/api")
|
|
||||||
|
|
||||||
ctrl := controller.NewContextController(contextControllerCfg, group)
|
|
||||||
ctrl.SetupRoutes()
|
ctrl.SetupRoutes()
|
||||||
|
return ctrl
|
||||||
|
})
|
||||||
|
|
||||||
return router, recorder
|
// Test user context
|
||||||
}
|
req, err := http.NewRequest("GET", "/api/context/user", nil)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
func TestAppContextHandler(t *testing.T) {
|
ctx := testContext
|
||||||
expectedRes := controller.AppContextResponse{
|
ctx.IsLoggedIn = true
|
||||||
|
ctx.Provider = "local"
|
||||||
|
|
||||||
|
expected, err := json.Marshal(controller.UserContextResponse{
|
||||||
|
Status: 200,
|
||||||
|
Message: "Success",
|
||||||
|
IsLoggedIn: ctx.IsLoggedIn,
|
||||||
|
Username: ctx.Username,
|
||||||
|
Name: ctx.Name,
|
||||||
|
Email: ctx.Email,
|
||||||
|
Provider: ctx.Provider,
|
||||||
|
OAuth: ctx.OAuth,
|
||||||
|
TotpPending: ctx.TotpPending,
|
||||||
|
OAuthName: ctx.OAuthName,
|
||||||
|
})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
resp := suite.RequestWithMiddleware(req, []gin.HandlerFunc{
|
||||||
|
func(c *gin.Context) {
|
||||||
|
c.Set("context", &ctx)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusOK, resp.Code)
|
||||||
|
bytes, err := io.ReadAll(resp.Body)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.DeepEqual(t, expected, bytes)
|
||||||
|
|
||||||
|
// Ensure user context is not available when not logged in
|
||||||
|
req, err = http.NewRequest("GET", "/api/context/user", nil)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
expected, err = json.Marshal(controller.UserContextResponse{
|
||||||
|
Status: http.StatusUnauthorized,
|
||||||
|
Message: "Unauthorized",
|
||||||
|
})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
resp = suite.RequestWithMiddleware(req, nil)
|
||||||
|
assert.Equal(t, 200, resp.Code)
|
||||||
|
bytes, err = io.ReadAll(resp.Body)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.DeepEqual(t, expected, bytes)
|
||||||
|
|
||||||
|
// Test app context
|
||||||
|
req, err = http.NewRequest("GET", "/api/context/app", nil)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
expected, err = json.Marshal(controller.AppContextResponse{
|
||||||
Status: 200,
|
Status: 200,
|
||||||
Message: "Success",
|
Message: "Success",
|
||||||
Providers: contextControllerCfg.Providers,
|
Providers: contextControllerCfg.Providers,
|
||||||
@@ -83,71 +83,13 @@ func TestAppContextHandler(t *testing.T) {
|
|||||||
BackgroundImage: contextControllerCfg.BackgroundImage,
|
BackgroundImage: contextControllerCfg.BackgroundImage,
|
||||||
OAuthAutoRedirect: contextControllerCfg.OAuthAutoRedirect,
|
OAuthAutoRedirect: contextControllerCfg.OAuthAutoRedirect,
|
||||||
WarningsEnabled: contextControllerCfg.WarningsEnabled,
|
WarningsEnabled: contextControllerCfg.WarningsEnabled,
|
||||||
}
|
|
||||||
|
|
||||||
router, recorder := setupContextController(nil)
|
|
||||||
req := httptest.NewRequest("GET", "/api/context/app", nil)
|
|
||||||
router.ServeHTTP(recorder, req)
|
|
||||||
|
|
||||||
assert.Equal(t, 200, recorder.Code)
|
|
||||||
|
|
||||||
var ctrlRes controller.AppContextResponse
|
|
||||||
|
|
||||||
err := json.Unmarshal(recorder.Body.Bytes(), &ctrlRes)
|
|
||||||
|
|
||||||
assert.NilError(t, err)
|
|
||||||
assert.DeepEqual(t, expectedRes, ctrlRes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUserContextHandler(t *testing.T) {
|
|
||||||
expectedRes := controller.UserContextResponse{
|
|
||||||
Status: 200,
|
|
||||||
Message: "Success",
|
|
||||||
IsLoggedIn: contextCtrlTestContext.IsLoggedIn,
|
|
||||||
Username: contextCtrlTestContext.Username,
|
|
||||||
Name: contextCtrlTestContext.Name,
|
|
||||||
Email: contextCtrlTestContext.Email,
|
|
||||||
Provider: contextCtrlTestContext.Provider,
|
|
||||||
OAuth: contextCtrlTestContext.OAuth,
|
|
||||||
TotpPending: contextCtrlTestContext.TotpPending,
|
|
||||||
OAuthName: contextCtrlTestContext.OAuthName,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test with context
|
|
||||||
router, recorder := setupContextController(&[]gin.HandlerFunc{
|
|
||||||
func(c *gin.Context) {
|
|
||||||
c.Set("context", &contextCtrlTestContext)
|
|
||||||
c.Next()
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
req := httptest.NewRequest("GET", "/api/context/user", nil)
|
|
||||||
router.ServeHTTP(recorder, req)
|
|
||||||
|
|
||||||
assert.Equal(t, 200, recorder.Code)
|
|
||||||
|
|
||||||
var ctrlRes controller.UserContextResponse
|
|
||||||
|
|
||||||
err := json.Unmarshal(recorder.Body.Bytes(), &ctrlRes)
|
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.DeepEqual(t, expectedRes, ctrlRes)
|
|
||||||
|
|
||||||
// Test no context
|
resp = suite.RequestWithMiddleware(req, nil)
|
||||||
expectedRes = controller.UserContextResponse{
|
|
||||||
Status: 401,
|
|
||||||
Message: "Unauthorized",
|
|
||||||
IsLoggedIn: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
router, recorder = setupContextController(nil)
|
|
||||||
req = httptest.NewRequest("GET", "/api/context/user", nil)
|
|
||||||
router.ServeHTTP(recorder, req)
|
|
||||||
|
|
||||||
assert.Equal(t, 200, recorder.Code)
|
|
||||||
|
|
||||||
err = json.Unmarshal(recorder.Body.Bytes(), &ctrlRes)
|
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusOK, resp.Code)
|
||||||
|
bytes, err = io.ReadAll(resp.Body)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.DeepEqual(t, expectedRes, ctrlRes)
|
assert.DeepEqual(t, expected, bytes)
|
||||||
}
|
}
|
||||||
|
|||||||
89
internal/controller/controller_test.go
Normal file
89
internal/controller/controller_test.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package controller_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/steveiliop56/tinyauth/internal/config"
|
||||||
|
"github.com/steveiliop56/tinyauth/internal/controller"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Testing suite
|
||||||
|
|
||||||
|
type ControllerTest[T any] struct {
|
||||||
|
ctrlSetup func(router *gin.RouterGroup) T
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewControllerTest[T any](setup func(router *gin.RouterGroup) T) *ControllerTest[T] {
|
||||||
|
return &ControllerTest[T]{ctrlSetup: setup}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctrlt *ControllerTest[T]) newEngine(middlewares []gin.HandlerFunc) *gin.Engine {
|
||||||
|
gin.SetMode(gin.TestMode)
|
||||||
|
|
||||||
|
engine := gin.New()
|
||||||
|
|
||||||
|
for _, mw := range middlewares {
|
||||||
|
engine.Use(mw)
|
||||||
|
}
|
||||||
|
|
||||||
|
return engine
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctrlrt *ControllerTest[T]) newControllerInstance(engine *gin.Engine) T {
|
||||||
|
ctrl := ctrlrt.ctrlSetup(engine.Group("/api"))
|
||||||
|
return ctrl
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctrlt *ControllerTest[T]) RequestWithMiddleware(http *http.Request, middlewares []gin.HandlerFunc) *httptest.ResponseRecorder {
|
||||||
|
engine := ctrlt.newEngine(middlewares)
|
||||||
|
ctrlt.newControllerInstance(engine)
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
engine.ServeHTTP(recorder, http)
|
||||||
|
return recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctrlt *ControllerTest[T]) Request(http *http.Request) *httptest.ResponseRecorder {
|
||||||
|
return ctrlt.RequestWithMiddleware(http, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controller configs
|
||||||
|
|
||||||
|
var contextControllerCfg = controller.ContextControllerConfig{
|
||||||
|
Providers: []controller.Provider{
|
||||||
|
{
|
||||||
|
Name: "Local",
|
||||||
|
ID: "local",
|
||||||
|
OAuth: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Google",
|
||||||
|
ID: "google",
|
||||||
|
OAuth: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Title: "Tinyauth Testing",
|
||||||
|
AppURL: "http://tinyauth.example.com:3000",
|
||||||
|
CookieDomain: "example.com",
|
||||||
|
ForgotPasswordMessage: "Foo bar",
|
||||||
|
BackgroundImage: "/background.jpg",
|
||||||
|
OAuthAutoRedirect: "google",
|
||||||
|
WarningsEnabled: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
var testContext = config.UserContext{
|
||||||
|
Username: "user",
|
||||||
|
Name: "User",
|
||||||
|
Email: "user@example.com",
|
||||||
|
IsLoggedIn: false,
|
||||||
|
IsBasicAuth: false,
|
||||||
|
OAuth: false,
|
||||||
|
Provider: "",
|
||||||
|
TotpPending: false,
|
||||||
|
OAuthGroups: "group1,group2",
|
||||||
|
TotpEnabled: false,
|
||||||
|
OAuthName: "test",
|
||||||
|
OAuthSub: "test",
|
||||||
|
LdapGroups: "group1,group2",
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ func (controller *HealthController) SetupRoutes() {
|
|||||||
|
|
||||||
func (controller *HealthController) healthHandler(c *gin.Context) {
|
func (controller *HealthController) healthHandler(c *gin.Context) {
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"status": "ok",
|
"status": 200,
|
||||||
"message": "Healthy",
|
"message": "Healthy",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
49
internal/controller/health_controller_test.go
Normal file
49
internal/controller/health_controller_test.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package controller_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/steveiliop56/tinyauth/internal/controller"
|
||||||
|
"gotest.tools/v3/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHealthController(t *testing.T) {
|
||||||
|
// Controller setup
|
||||||
|
suite := NewControllerTest(func(router *gin.RouterGroup) *controller.HealthController {
|
||||||
|
ctrl := controller.NewHealthController(router)
|
||||||
|
ctrl.SetupRoutes()
|
||||||
|
return ctrl
|
||||||
|
})
|
||||||
|
|
||||||
|
expected, err := json.Marshal(map[string]any{
|
||||||
|
"status": 200,
|
||||||
|
"message": "Healthy",
|
||||||
|
})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
// Test we are healthy with GET
|
||||||
|
req, err := http.NewRequest("GET", "/api/healthz", nil)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
resp := suite.Request(req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusOK, resp.Code)
|
||||||
|
bytes, err := io.ReadAll(resp.Body)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.DeepEqual(t, bytes, expected)
|
||||||
|
|
||||||
|
// Test we are healthy with HEAD
|
||||||
|
req, err = http.NewRequest("HEAD", "/api/healthz", nil)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
resp = suite.Request(req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusOK, resp.Code)
|
||||||
|
bytes, err = io.ReadAll(resp.Body)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.DeepEqual(t, expected, bytes)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user