mirror of
https://github.com/go-shiori/shiori.git
synced 2025-10-06 19:47:16 +08:00
* list account and create account * deleteaccount (wip) * remove old accounts code * fix from merge * remove serve method from makefile * ListAccounts, password hash on domain * make lint * more permissive assertion * rename test * update account * Authorization * updated api calls * apis, pointers, auth * swagger * stylecheck * domain validation * tests * swagger * error handling * fix system account changes * Cleanup database interface * test cleanup * fixed nil references * feat: Add logout endpoint to auth routes * feat: Add logoutHandler for stateless JWT token logout * fixed some bug catched in tests * auth/account patch * prettier * remove test logs * fixed incorrect number of parameters * fixed swagger docs * enable swagger in dev environment * errors.Wrap -> fmt.Errorf * test: Add comprehensive test cases for accounts API handlers * fix: Resolve test failures in accounts_test.go * test: Add tests for duplicate username handling in account creation and update * feat: Add username uniqueness checks for account creation and update refactor: Improve username existence checks in SQLite account methods * linted * test: Add comprehensive tests for auth domain token and credential validation * test: Add comprehensive test cases for auth domain token creation and validation * test: Add comprehensive error handling test cases for accounts domain * refactor: Remove `SaveAccountSettings` method from database implementations * test: Add test cases for password update functionality * test(e2e): auth login * lint * send regular context to domain * fixed e2e auth tests * test: Add auth_test.go for end-to-end authentication testing * feat: Add comprehensive authentication tests using Playwright and testcontainers * fix: Handle multiple return values in Playwright test methods * error message * e2e playwrigth tests * ci: setup playwrigth * refactor: Update Playwright tests to use locator-based API * refactor: Remove unnecessary alias for playwright-go expect import * refactor: Replace deprecated expect package with WaitFor() method in Playwright tests * fix: Resolve linting issues in e2e Playwright tests * remove npm ci from e2e ci * make playwright available in path * typo * re enabled ci * base e2e accounts test * more account e2e * feat: Add HTML test reporter with screenshots and detailed results * feat: Embed screenshots as base64 in HTML test report * refactor: Remove GitHub step summary functionality from test helper * refactor: Make reporter global to share test results across test helpers * refactor: Add HandleSuccess method to TestHelper for consistent test result reporting * feat: Add descriptive messages to all test assertions in TestHelper * test: Add descriptive messages to assertions in accounts_test.go * test: Add descriptive error messages to assertions in accounts_test.go * feat: Add descriptive messages to assertions in accounts_test.go * refactor: Update assertion functions to receive *testing.T as first argument * refactor: Update accounts_test.go assertions to pass *testing.T argument * refactor: Update accounts_test.go assertions to use *testing.T argument * refactor: Update `accounts_test.go` to use `*testing.T` argument in `Require()` calls * refactor: Update `th.Require()` calls with `t *testing.T` argument in accounts_test.go * assert helper * refactor: Refactor `False` test helper to use `Assert` function consistently * refactor: Refactor `Equal` test helper to use `Assert` function * refactor: Simplify Error test helper to use Assert function * refactor: Refactor `NoError` to use `Assert` function for consistent error handling * typo * refactor: Differentiate between test cases and assertions in reporter * refactor: Simplify AddResult method signature and use error message for assertion * refactor: Simplify test report with focused failure details and screenshots * refactor: Ensure assertions are always called in PlaywrightRequire helper methods * refactor: Update test error messages to be action-oriented * refactor: Update error messages to be more action-oriented in accounts_test.go * refactor: Update error messages to be action-oriented in accounts_test.go * refactor: Improve error messages in auth_test.go for better test readability * refactor: Improve screenshot handling and test result reporting in Playwright test helper * fix: Improve test reporting with detailed error messages and logging * refactor: Remove unused runningInCI field from TestHelper struct * fix: Improve message formatting in Assert method for better reporting * assertions * test: Add `Require()` calls to 007 test for improved error handling * refactor: Update test reporter to include error details and improve HTML rendering * fix: Properly escape and render base64 screenshot in HTML report * fix: Correct base64 screenshot rendering in test reporter * fixed tests + html report * feat: Add artifact upload for e2e test report * make lint * chore: use correct version in user agent * ci: run e2e after other checks * chore: remove pre-commit
138 lines
4.2 KiB
Go
138 lines
4.2 KiB
Go
package middleware
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/go-shiori/shiori/internal/http/response"
|
|
"github.com/go-shiori/shiori/internal/model"
|
|
"github.com/go-shiori/shiori/internal/testutil"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestAuthenticationRequiredMiddleware(t *testing.T) {
|
|
t.Run("test unauthorized", func(t *testing.T) {
|
|
g := testutil.NewGin()
|
|
g.Use(AuthenticationRequired())
|
|
g.Handle("GET", "/", func(c *gin.Context) {
|
|
response.Send(c, http.StatusOK, nil)
|
|
})
|
|
w := testutil.PerformRequest(g, "GET", "/")
|
|
require.Equal(t, http.StatusUnauthorized, w.Code)
|
|
// This ensures we are aborting the request and not sending more data
|
|
require.Equal(t, `{"ok":false,"message":null}`, w.Body.String())
|
|
})
|
|
|
|
t.Run("test authorized", func(t *testing.T) {
|
|
g := testutil.NewGin()
|
|
// Fake a logged in user in the context, which is the way the AuthMiddleware works.
|
|
g.Use(func(ctx *gin.Context) {
|
|
ctx.Set(model.ContextAccountKey, "test")
|
|
})
|
|
g.Use(AuthenticationRequired())
|
|
g.GET("/", func(c *gin.Context) {
|
|
c.Status(http.StatusOK)
|
|
})
|
|
w := testutil.PerformRequest(g, "GET", "/")
|
|
require.Equal(t, http.StatusOK, w.Code)
|
|
})
|
|
}
|
|
|
|
func TestAuthMiddleware(t *testing.T) {
|
|
ctx := context.TODO()
|
|
logger := logrus.New()
|
|
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
|
|
middleware := AuthMiddleware(deps)
|
|
|
|
t.Run("test no authorization method", func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
c, router := gin.CreateTestContext(w)
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
router.Use(middleware)
|
|
router.ServeHTTP(w, req)
|
|
|
|
_, exists := c.Get("account")
|
|
require.False(t, exists)
|
|
})
|
|
|
|
t.Run("test authorization header", func(t *testing.T) {
|
|
account := testutil.GetValidAccount().ToDTO()
|
|
token, err := deps.Domains.Auth.CreateTokenForAccount(&account, time.Now().Add(time.Minute))
|
|
require.NoError(t, err)
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request, _ = http.NewRequest("GET", "/", nil)
|
|
c.Request.Header.Set(model.AuthorizationHeader, model.AuthorizationTokenType+" "+token)
|
|
middleware(c)
|
|
_, exists := c.Get(model.ContextAccountKey)
|
|
require.True(t, exists)
|
|
})
|
|
|
|
t.Run("test authorization cookie", func(t *testing.T) {
|
|
account := model.AccountDTO{Username: "shiori"}
|
|
token, err := deps.Domains.Auth.CreateTokenForAccount(&account, time.Now().Add(time.Minute))
|
|
require.NoError(t, err)
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request, _ = http.NewRequest("GET", "/", nil)
|
|
c.Request.AddCookie(&http.Cookie{
|
|
Name: "token",
|
|
Value: token,
|
|
MaxAge: int(time.Now().Add(time.Minute).Unix()),
|
|
})
|
|
middleware(c)
|
|
_, exists := c.Get(model.ContextAccountKey)
|
|
require.True(t, exists)
|
|
})
|
|
}
|
|
|
|
func TestAdminRequiredMiddleware(t *testing.T) {
|
|
t.Run("test unauthorized", func(t *testing.T) {
|
|
g := testutil.NewGin()
|
|
g.Use(AdminRequired())
|
|
g.Handle("GET", "/", func(c *gin.Context) {
|
|
response.Send(c, http.StatusOK, nil)
|
|
})
|
|
w := testutil.PerformRequest(g, "GET", "/")
|
|
require.Equal(t, http.StatusForbidden, w.Code)
|
|
// This ensures we are aborting the request and not sending more data
|
|
require.Equal(t, `{"ok":false,"message":null}`, w.Body.String())
|
|
})
|
|
|
|
t.Run("test user but not admin", func(t *testing.T) {
|
|
g := testutil.NewGin()
|
|
// Fake a logged in admin in the context, which is the way the AuthMiddleware works.
|
|
g.Use(func(ctx *gin.Context) {
|
|
ctx.Set(model.ContextAccountKey, &model.AccountDTO{
|
|
Owner: model.Ptr(false),
|
|
})
|
|
})
|
|
g.Use(AdminRequired())
|
|
g.GET("/", func(c *gin.Context) {
|
|
c.Status(http.StatusOK)
|
|
})
|
|
w := testutil.PerformRequest(g, "GET", "/")
|
|
require.Equal(t, http.StatusForbidden, w.Code)
|
|
})
|
|
|
|
t.Run("test authorized", func(t *testing.T) {
|
|
g := testutil.NewGin()
|
|
// Fake a logged in admin in the context, which is the way the AuthMiddleware works.
|
|
g.Use(func(ctx *gin.Context) {
|
|
ctx.Set(model.ContextAccountKey, &model.AccountDTO{
|
|
Owner: model.Ptr(true),
|
|
})
|
|
})
|
|
g.Use(AdminRequired())
|
|
g.GET("/", func(c *gin.Context) {
|
|
c.Status(http.StatusOK)
|
|
})
|
|
w := testutil.PerformRequest(g, "GET", "/")
|
|
require.Equal(t, http.StatusOK, w.Code)
|
|
})
|
|
}
|