124 lines
4.5 KiB
Go
124 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/glebarez/sqlite"
|
|
"gorm.io/gorm"
|
|
businessbiz "kra/internal/biz/business"
|
|
"kra/internal/biz/system"
|
|
"kra/internal/config"
|
|
businessdata "kra/internal/data/business"
|
|
systemdata "kra/internal/data/system"
|
|
"kra/internal/server/handler"
|
|
"kra/internal/server/router"
|
|
businessservice "kra/internal/service/business"
|
|
systemservice "kra/internal/service/system"
|
|
)
|
|
|
|
type nativeUserHTTPData struct {
|
|
businessHTTPData
|
|
runtime *config.Store
|
|
}
|
|
|
|
func (d nativeUserHTTPData) Database(name string) (*gorm.DB, error) {
|
|
if name == "" {
|
|
return d.db, nil
|
|
}
|
|
return nil, fmt.Errorf("未配置")
|
|
}
|
|
func (d nativeUserHTTPData) DatabaseReady() bool { return true }
|
|
func (d nativeUserHTTPData) Runtime() *config.Store { return d.runtime }
|
|
|
|
func TestNativeUserEnableAndBusinessStatusOverHTTP(t *testing.T) {
|
|
db, err := gorm.Open(sqlite.Open(filepath.Join(t.TempDir(), "native-status.db")), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
pool, _ := db.DB()
|
|
t.Cleanup(func() { _ = pool.Close() })
|
|
for _, step := range append(systemdata.Migrations(), businessdata.Migrations()...) {
|
|
if err := step.Migrate(db); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if err := db.Exec("INSERT INTO sys_users(id,uuid,username,nick_name,authority_id,level,id_path,enable,business_status) VALUES(1,'root','root','root',888,0,'0',1,0),(2,'normal','normal','normal',901,1,'0',1,0),(3,'pending','pending','pending',903,3,'0,2',0,3),(4,'rejected','rejected','rejected',903,3,'0,2',0,2)").Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
provider := nativeUserHTTPData{businessHTTPData{db}, config.NewStore(&config.Config{Admin: &config.Admin{}})}
|
|
users := handler.NewUser(systemservice.NewUserService(system.NewUserUsecase(systemdata.NewUserRepo(provider)), nil), nil)
|
|
accounts := handler.NewBusiness(nil, businessservice.NewAccountService(businessbiz.NewAccountUsecase(businessdata.NewAccountRepo(provider))), nil)
|
|
engine := gin.New()
|
|
engine.Use(func(c *gin.Context) {
|
|
id := uint64(1)
|
|
if raw := c.GetHeader("X-Test-User"); raw != "" {
|
|
id, _ = strconv.ParseUint(raw, 10, 64)
|
|
}
|
|
aid := uint(903)
|
|
if id == 1 {
|
|
aid = 888
|
|
}
|
|
c.Set("admin_claims", &system.AuthClaims{ID: uint(id), AuthorityID: aid})
|
|
c.Request = c.Request.WithContext(system.NewActorContext(c.Request.Context(), system.Actor{UserID: uint(id), AuthorityID: aid}))
|
|
c.Next()
|
|
})
|
|
router.RegisterUser(engine.Group(""), users)
|
|
engine.GET("/sw/business/:userId", accounts.Account)
|
|
server := httptest.NewServer(engine)
|
|
defer server.Close()
|
|
call := func(user int, method, path, body string, expected int) map[string]any {
|
|
t.Helper()
|
|
req, _ := http.NewRequest(method, server.URL+path, strings.NewReader(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("X-Test-User", strconv.Itoa(user))
|
|
res, err := server.Client().Do(req)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer res.Body.Close()
|
|
var result map[string]any
|
|
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if result["code"] != float64(expected) {
|
|
t.Fatalf("%s %s 返回错误: %+v", method, path, result)
|
|
}
|
|
return result["data"].(map[string]any)
|
|
}
|
|
check := func(id int, status string, enable int) {
|
|
t.Helper()
|
|
data := call(1, "GET", fmt.Sprintf("/sw/business/%d", id), "", 0)
|
|
var actual int
|
|
db.Table("sys_users").Select("enable").Where("id = ?", id).Scan(&actual)
|
|
if data["status"] != status || actual != enable {
|
|
t.Fatalf("账号%d状态不同步: %+v enable=%d", id, data, actual)
|
|
}
|
|
}
|
|
call(1, "PUT", "/user/setUserInfo", `{"ID":2,"nickName":"停用后","enable":2}`, 0)
|
|
check(2, "1", 2)
|
|
call(1, "PUT", "/user/setUserInfo", `{"ID":2,"nickName":"启用后","enable":1}`, 0)
|
|
check(2, "0", 1)
|
|
call(1, "PUT", "/user/setUserInfo", `{"ID":3,"nickName":"修改待审资料","enable":0}`, 0)
|
|
check(3, "3", 0)
|
|
call(1, "PUT", "/user/setUserInfo", `{"ID":4,"nickName":"修改驳回资料","enable":2}`, 0)
|
|
check(4, "2", 2)
|
|
call(1, "PUT", "/user/setUserInfo", `{"ID":3,"nickName":"审核后启用","enable":1}`, 0)
|
|
check(3, "0", 1)
|
|
// 模拟鉴权之后管理员又修改状态的竞争,个人资料不能用 enable 绕过审核。
|
|
call(4, "PUT", "/user/setSelfInfo", `{"enable":1,"nickName":"试图自行启用"}`, 7)
|
|
check(4, "2", 2)
|
|
call(2, "PUT", "/user/setSelfInfo", `{"enable":2}`, 0)
|
|
check(2, "1", 2)
|
|
call(2, "PUT", "/user/setSelfInfo", `{"enable":1}`, 7)
|
|
check(2, "1", 2)
|
|
call(1, "PUT", "/user/setUserInfo", `{"ID":99999,"enable":1}`, 7)
|
|
}
|