邹方成 2a89a1ab9d
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
feat(admin): 更新前端资源文件及修复相关功能
refactor(service): 修改banner和guild删除逻辑为软删除
fix(service): 修复删除操作使用软删除而非物理删除

build: 添加SQLite测试仓库实现
docs: 新增奖励管理字段拆分和批量抽奖UI改造文档

ci: 更新CI忽略文件
style: 清理无用资源文件
2025-11-19 01:35:55 +08:00

155 lines
5.5 KiB
Go

package interceptor
import (
"net/http"
"net/http/httptest"
"os"
"testing"
"time"
"bindbox-game/internal/pkg/core"
"bindbox-game/internal/pkg/jwtoken"
"bindbox-game/internal/pkg/logger"
"bindbox-game/internal/proposal"
"bindbox-game/internal/repository/mysql"
"bindbox-game/internal/repository/mysql/model"
)
func setupDB(t *testing.T) mysql.Repo {
repo, err := mysql.NewSQLiteRepoForTest()
if err != nil {
t.Fatal(err)
}
if err := repo.GetDbR().AutoMigrate(&model.Admin{}, &model.RoleUsers{}, &model.RoleActions{}, &model.MenuActions{}); err != nil {
t.Fatal(err)
}
return repo
}
func newLogger(t *testing.T) logger.CustomLogger {
l, err := logger.NewCustomLogger(nil, logger.WithOutputInConsole())
if err != nil {
t.Fatal(err)
}
return l
}
func signToken(secret string, info proposal.SessionUserInfo) string {
token, _ := jwtoken.New(secret).Sign(info, time.Hour)
return token
}
func TestRequireAdminRole_NoToken(t *testing.T) {
repo := setupDB(t)
l := newLogger(t)
intc := New(l, repo)
m, err := core.New(l)
if err != nil {
t.Fatal(err)
}
g := m.Group("/api/admin", core.WrapAuthHandler(intc.AdminTokenAuthVerify))
g.GET("/ping", intc.RequireAdminRole(), func(ctx core.Context) { ctx.Payload(map[string]string{"message": "ok"}) })
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/admin/ping", nil)
m.ServeHTTP(w, req)
if w.Code != http.StatusUnauthorized {
t.Fatalf("expect 401 got %d", w.Code)
}
}
func TestRequireAdminRole_NoRole(t *testing.T) {
repo := setupDB(t)
l := newLogger(t)
intc := New(l, repo)
secret := "testsecret"
os.Setenv("ADMIN_JWT_SECRET", secret)
info := proposal.SessionUserInfo{Id: 1, UserName: "u", IsSuper: 0}
token := signToken(secret, info)
h := token
if err := repo.GetDbR().Create(&model.Admin{ID: 1, Username: "u", Nickname: "n", Avatar: "a", Mobile: "m", Password: "p", IsSuper: 0, LoginStatus: 1, LastLoginTime: time.Now(), LastLoginIP: "0.0.0.0", LastLoginHash: h, CreatedUser: "t", UpdatedUser: "t"}).Error; err != nil {
t.Fatal(err)
}
m, err := core.New(l)
if err != nil {
t.Fatal(err)
}
g := m.Group("/api/admin", core.WrapAuthHandler(intc.AdminTokenAuthVerify))
g.GET("/ping", intc.RequireAdminRole(), func(ctx core.Context) { ctx.Payload(map[string]string{"message": "ok"}) })
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/admin/ping", nil)
req.Header.Set("Authorization", token)
m.ServeHTTP(w, req)
if w.Code != http.StatusForbidden {
t.Fatalf("expect 403 got %d", w.Code)
}
}
func TestRequireAdminAction_AllowedByRole(t *testing.T) {
repo := setupDB(t)
l := newLogger(t)
intc := New(l, repo)
secret := "testsecret"
os.Setenv("ADMIN_JWT_SECRET", secret)
info := proposal.SessionUserInfo{Id: 2, UserName: "u2", IsSuper: 0}
token := signToken(secret, info)
h := token
if err := repo.GetDbR().Create(&model.Admin{ID: 2, Username: "u2", Nickname: "n", Avatar: "a", Mobile: "m", Password: "p", IsSuper: 0, LoginStatus: 1, LastLoginTime: time.Now(), LastLoginIP: "0.0.0.0", LastLoginHash: h, CreatedUser: "t", UpdatedUser: "t"}).Error; err != nil {
t.Fatal(err)
}
if err := repo.GetDbR().Create(&model.RoleUsers{RoleID: 10, AdminID: 2, CreatedUser: "t", UpdatedUser: "t"}).Error; err != nil {
t.Fatal(err)
}
if err := repo.GetDbR().Create(&model.MenuActions{ID: 100, MenuID: 1, ActionMark: "guild:create", ActionName: "create", Status: true, CreatedUser: "t", UpdatedUser: "t"}).Error; err != nil {
t.Fatal(err)
}
if err := repo.GetDbR().Create(&model.RoleActions{RoleID: 10, ActionID: 100, CreatedUser: "t", UpdatedUser: "t"}).Error; err != nil {
t.Fatal(err)
}
m, err := core.New(l)
if err != nil {
t.Fatal(err)
}
g := m.Group("/api/admin", core.WrapAuthHandler(intc.AdminTokenAuthVerify))
g.POST("/guilds", intc.RequireAdminRole(), intc.RequireAdminAction("guild:create"), func(ctx core.Context) { ctx.Payload(map[string]string{"message": "ok"}) })
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/api/admin/guilds", nil)
req.Header.Set("Authorization", token)
m.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expect 200 got %d", w.Code)
}
}
func TestRequireAdminAction_Forbidden(t *testing.T) {
repo := setupDB(t)
l := newLogger(t)
intc := New(l, repo)
secret := "testsecret"
os.Setenv("ADMIN_JWT_SECRET", secret)
info := proposal.SessionUserInfo{Id: 3, UserName: "u3", IsSuper: 0}
token := signToken(secret, info)
h := token
if err := repo.GetDbR().Create(&model.Admin{ID: 3, Username: "u3", Nickname: "n", Avatar: "a", Mobile: "m", Password: "p", IsSuper: 0, LoginStatus: 1, LastLoginTime: time.Now(), LastLoginIP: "0.0.0.0", LastLoginHash: h, CreatedUser: "t", UpdatedUser: "t"}).Error; err != nil {
t.Fatal(err)
}
if err := repo.GetDbR().Create(&model.RoleUsers{RoleID: 11, AdminID: 3, CreatedUser: "t", UpdatedUser: "t"}).Error; err != nil {
t.Fatal(err)
}
if err := repo.GetDbR().Create(&model.MenuActions{ID: 101, MenuID: 1, ActionMark: "guild:delete", ActionName: "delete", Status: true, CreatedUser: "t", UpdatedUser: "t"}).Error; err != nil {
t.Fatal(err)
}
m, err := core.New(l)
if err != nil {
t.Fatal(err)
}
g := m.Group("/api/admin", core.WrapAuthHandler(intc.AdminTokenAuthVerify))
g.DELETE("/guilds/1", intc.RequireAdminRole(), intc.RequireAdminAction("guild:delete"), func(ctx core.Context) { ctx.Payload(map[string]string{"message": "ok"}) })
w := httptest.NewRecorder()
req, _ := http.NewRequest("DELETE", "/api/admin/guilds/1", nil)
req.Header.Set("Authorization", token)
m.ServeHTTP(w, req)
if w.Code != http.StatusForbidden {
t.Fatalf("expect 403 got %d", w.Code)
}
}