shiori/internal/http/handlers/api/v1/auth_test.go
Felipe Martin 876d27f337
refactor: remove gin and use stdlib http server (#1064)
* refactor: base http server stdlib

* refactor: swagger and frontend routes

* fix: use global middlewares

* refactor: removed gin from testutils

* fix: object references in legacy webserver

* refactor: legacy, swagger and system handlers

* fix: added verbs to handlers

* fix: server handlers ordering

* refactor: bookmarks handlers

* refactor: system api routes

* tests: bookmark handlers

* refactor: migrated api auth routes

* chore: remove unused middlewares

* docs: add swagger docs to refactored system api

* chore: remove old auth routes

* refactor: account apis

* chore: removed old handlers

* fix: api v1 handlers missing middlewares

* refactor: migrated tag list route

* refactor: bookmark routes

* refactor: remove gin

* chore: make styles

* test: fixed tests

* test: generate binary file without text

* fix: global middleware missing from system api handler

* fix: incorrect api handler

* chore: avoid logging screenshot contents

* tests: bookmarks domain

* tests: shortcuts

* test: missing tests

* tests: server tests

* test: remove test using syscall to avoid windows errors

* chore: added middlewares
2025-02-26 20:50:48 +01:00

222 lines
7.3 KiB
Go

package api_v1
import (
"context"
"net/http"
"testing"
"time"
"github.com/go-shiori/shiori/internal/model"
"github.com/go-shiori/shiori/internal/testutil"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
)
func noopLegacyLoginHandler(_ *model.AccountDTO, _ time.Duration) (string, error) {
return "test-session", nil
}
func TestHandleLogin(t *testing.T) {
logger := logrus.New()
// _, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger)
t.Run("invalid json payload", func(t *testing.T) {
ctx := context.Background()
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
body := `{"username":}`
w := testutil.PerformRequest(deps, func(deps model.Dependencies, c model.WebContext) {
HandleLogin(deps, c, noopLegacyLoginHandler)
}, "POST", "/login", testutil.WithBody(body))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("missing username", func(t *testing.T) {
ctx := context.Background()
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
body := `{"password": "test"}`
w := testutil.PerformRequest(deps, func(deps model.Dependencies, c model.WebContext) {
HandleLogin(deps, c, noopLegacyLoginHandler)
}, "POST", "/login", testutil.WithBody(body))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("missing password", func(t *testing.T) {
ctx := context.Background()
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
body := `{"username": "test"}`
w := testutil.PerformRequest(deps, func(deps model.Dependencies, c model.WebContext) {
HandleLogin(deps, c, noopLegacyLoginHandler)
}, "POST", "/login", testutil.WithBody(body))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("invalid credentials", func(t *testing.T) {
ctx := context.Background()
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
body := `{"username": "test", "password": "wrong"}`
w := testutil.PerformRequest(deps, func(deps model.Dependencies, c model.WebContext) {
HandleLogin(deps, c, noopLegacyLoginHandler)
}, "POST", "/login", testutil.WithBody(body))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("successful login", func(t *testing.T) {
ctx := context.Background()
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
account := testutil.GetValidAccount().ToDTO()
account.Password = "test"
_, err := deps.Domains().Accounts().CreateAccount(context.Background(), account)
require.NoError(t, err)
body := `{
"username": "test",
"password": "test",
"remember_me": true
}`
w := testutil.PerformRequest(deps, func(deps model.Dependencies, c model.WebContext) {
HandleLogin(deps, c, noopLegacyLoginHandler)
}, "POST", "/login", testutil.WithBody(body))
require.Equal(t, http.StatusOK, w.Code)
response, err := testutil.NewTestResponseFromReader(w.Body)
require.NoError(t, err)
response.AssertOk(t)
response.AssertMessageContains(t, "token")
response.AssertMessageContains(t, "session")
response.AssertMessageContains(t, "expires")
})
}
func TestHandleRefreshToken(t *testing.T) {
logger := logrus.New()
_, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger)
t.Run("requires authentication", func(t *testing.T) {
w := testutil.PerformRequest(deps, HandleRefreshToken, "POST", "/refresh")
require.Equal(t, http.StatusUnauthorized, w.Code)
})
t.Run("successful refresh", func(t *testing.T) {
account := testutil.GetValidAccount().ToDTO()
account.Password = "test"
_, err := deps.Domains().Accounts().CreateAccount(context.Background(), account)
require.NoError(t, err)
w := testutil.PerformRequest(deps, HandleRefreshToken, "POST", "/refresh", testutil.WithAccount(&account))
require.Equal(t, http.StatusAccepted, w.Code)
response, err := testutil.NewTestResponseFromReader(w.Body)
require.NoError(t, err)
response.AssertOk(t)
response.AssertMessageContains(t, "token")
})
}
func TestHandleGetMe(t *testing.T) {
logger := logrus.New()
_, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger)
t.Run("requires authentication", func(t *testing.T) {
c, w := testutil.NewTestWebContext()
HandleGetMe(deps, c)
require.Equal(t, http.StatusUnauthorized, w.Code)
})
t.Run("returns user info", func(t *testing.T) {
c, w := testutil.NewTestWebContext()
testutil.SetFakeUser(c)
HandleGetMe(deps, c)
require.Equal(t, http.StatusOK, w.Code)
response, err := testutil.NewTestResponseFromReader(w.Body)
require.NoError(t, err)
response.AssertOk(t)
response.AssertMessageContains(t, "username")
})
}
func TestHandleUpdateLoggedAccount(t *testing.T) {
logger := logrus.New()
_, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger)
account, err := deps.Domains().Accounts().CreateAccount(context.Background(), model.AccountDTO{
Username: "shiori",
Password: "gopher",
Owner: model.Ptr(true),
Config: model.Ptr(model.UserConfig{
ShowId: true,
ListMode: true,
HideThumbnail: true,
HideExcerpt: true,
KeepMetadata: true,
UseArchive: true,
CreateEbook: true,
MakePublic: true,
}),
})
require.NoError(t, err)
t.Run("requires authentication", func(t *testing.T) {
c, w := testutil.NewTestWebContext()
HandleUpdateLoggedAccount(deps, c)
require.Equal(t, http.StatusUnauthorized, w.Code)
})
t.Run("invalid json payload", func(t *testing.T) {
body := `invalid json`
w := testutil.PerformRequest(deps, HandleUpdateLoggedAccount, "PATCH", "/account", testutil.WithBody(body), testutil.WithAccount(account))
require.Equal(t, http.StatusInternalServerError, w.Code)
})
t.Run("missing old password", func(t *testing.T) {
body := `{"new_password": "newpass"}`
w := testutil.PerformRequest(deps, HandleUpdateLoggedAccount, "PATCH", "/account", testutil.WithBody(body), testutil.WithAccount(account))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("incorrect old password", func(t *testing.T) {
body := `{
"old_password": "wrong",
"new_password": "newpass"
}`
w := testutil.PerformRequest(deps, HandleUpdateLoggedAccount, "PATCH", "/account", testutil.WithBody(body), testutil.WithAccount(account))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("successful update", func(t *testing.T) {
body := `{
"old_password": "gopher",
"new_password": "newpass",
"config": {
"show_id": true,
"list_mode": true
}
}`
w := testutil.PerformRequest(deps, HandleUpdateLoggedAccount, "PATCH", "/account", testutil.WithBody(body), testutil.WithAccount(account))
require.Equal(t, http.StatusOK, w.Code)
response, err := testutil.NewTestResponseFromReader(w.Body)
require.NoError(t, err)
response.AssertOk(t)
response.AssertMessageContains(t, "config")
})
}
func TestHandleLogout(t *testing.T) {
logger := logrus.New()
_, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger)
t.Run("requires authentication", func(t *testing.T) {
c, w := testutil.NewTestWebContext()
HandleLogout(deps, c)
require.Equal(t, http.StatusUnauthorized, w.Code)
})
t.Run("successful logout", func(t *testing.T) {
c, w := testutil.NewTestWebContext()
testutil.SetFakeUser(c)
HandleLogout(deps, c)
require.Equal(t, http.StatusOK, w.Code)
})
}