112 lines
5.2 KiB
Go
112 lines
5.2 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
"testing"
|
|
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/contexts"
|
|
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model"
|
|
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/do"
|
|
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/entity"
|
|
)
|
|
|
|
func TestWarningPreferenceIsolationAndBinding(t *testing.T) {
|
|
ctx := context.Background()
|
|
db := g.DB()
|
|
statements := []string{
|
|
"CREATE TABLE sys_user (user_id INTEGER PRIMARY KEY, tenant_id TEXT, user_name TEXT, password TEXT, deleted_at DATETIME)",
|
|
"CREATE TABLE sys_social (id INTEGER PRIMARY KEY, tenant_id TEXT, user_id INTEGER, source TEXT, open_id TEXT, deleted_at DATETIME)",
|
|
"CREATE TABLE sys_config (config_id INTEGER PRIMARY KEY AUTOINCREMENT, tenant_id TEXT, config_key TEXT, config_value TEXT, config_name TEXT, config_type TEXT, created_dept INTEGER, created_by INTEGER, updated_by INTEGER, created_at DATETIME, updated_at DATETIME)",
|
|
}
|
|
for _, table := range []string{"sys_user", "sys_social", "sys_config"} {
|
|
_, _ = db.Exec(ctx, "DROP TABLE IF EXISTS "+table)
|
|
}
|
|
t.Cleanup(func() {
|
|
for _, table := range []string{"sys_user", "sys_social", "sys_config"} {
|
|
_, _ = db.Exec(ctx, "DROP TABLE IF EXISTS "+table)
|
|
}
|
|
_ = db.GetCore().ClearCacheAll(ctx)
|
|
})
|
|
for _, statement := range statements {
|
|
if _, err := db.Exec(ctx, statement); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
for _, userID := range []int64{101, 102} {
|
|
if _, err := db.Model("sys_user").Data(do.SysUser{UserId: userID, TenantId: "tenant", UserName: "account", Password: "hash"}).Insert(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if _, err := db.Model("sys_social").Data(do.SysSocial{Id: 1, TenantId: "tenant", UserId: 101, Source: "wechat_mp", OpenId: "openid"}).Insert(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
userCtx := contexts.Set(ctx, &model.Context{User: &model.Identity{BaseClaims: model.BaseClaims{ID: 101, TenantId: "tenant"}}})
|
|
service := NewAppUser()
|
|
preference, err := service.WarningPreference(userCtx)
|
|
if err != nil || !preference.Enabled {
|
|
t.Fatalf("legacy bound user should remain enabled: %v %v", preference, err)
|
|
}
|
|
enabled := false
|
|
preference, err = service.SaveWarningPreference(userCtx, &model.AppWarningPreferenceParam{Enabled: &enabled})
|
|
if err != nil || preference.Enabled || !preference.WechatBound {
|
|
t.Fatalf("disable must preserve binding: %v %v", preference, err)
|
|
}
|
|
enabled = true
|
|
preference, err = service.SaveWarningPreference(userCtx, &model.AppWarningPreferenceParam{Enabled: &enabled})
|
|
if err != nil || !preference.Enabled {
|
|
t.Fatalf("enable failed: %v %v", preference, err)
|
|
}
|
|
otherCtx := contexts.Set(ctx, &model.Context{User: &model.Identity{BaseClaims: model.BaseClaims{ID: 102, TenantId: "tenant"}}})
|
|
if _, err := service.SaveWarningPreference(otherCtx, &model.AppWarningPreferenceParam{Enabled: &enabled}); err == nil {
|
|
t.Fatal("unbound account must not enable")
|
|
}
|
|
if _, err := service.SaveWarningPreference(userCtx, &model.AppWarningPreferenceParam{}); err == nil {
|
|
t.Fatal("missing enabled must be rejected")
|
|
}
|
|
if _, err := service.WarningPreference(context.Background()); err == nil {
|
|
t.Fatal("anonymous access must fail")
|
|
}
|
|
count, err := db.Model("sys_config").Where("tenant_id", "tenant").Where("config_key", warningPreferenceKey(101)).Count()
|
|
if err != nil || count != 1 {
|
|
t.Fatalf("expected one persisted preference: %d %v", count, err)
|
|
}
|
|
if _, err := db.Model("sys_social").Data(do.SysSocial{Id: 2, TenantId: "other", UserId: 101, Source: "wechat_mp", OpenId: "other"}).Insert(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := db.Exec(ctx, "ALTER TABLE sys_social RENAME TO sys_social_unavailable"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := unbindWechatBindings(userCtx, &entity.SysUser{UserId: 101, TenantId: "tenant"}); err == nil {
|
|
t.Fatal("failed binding deletion must fail transaction")
|
|
}
|
|
persisted, err := db.Model("sys_config").Where("tenant_id", "tenant").Where("config_key", warningPreferenceKey(101)).Value("config_value")
|
|
if err != nil || persisted.String() != "1" {
|
|
t.Fatalf("failed unbind changed preference: %v %v", persisted, err)
|
|
}
|
|
if _, err := db.Exec(ctx, "ALTER TABLE sys_social_unavailable RENAME TO sys_social"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := unbindWechatBindings(userCtx, &entity.SysUser{UserId: 101, TenantId: "tenant"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
remaining, err := db.Model("sys_social").Where("tenant_id", "tenant").Count()
|
|
if err != nil || remaining != 0 {
|
|
t.Fatalf("unbind did not delete current binding: %d %v", remaining, err)
|
|
}
|
|
remaining, err = db.Model("sys_social").Where("tenant_id", "other").Count()
|
|
if err != nil || remaining != 1 {
|
|
t.Fatalf("unbind changed other tenant: %d %v", remaining, err)
|
|
}
|
|
preference, err = service.WarningPreference(userCtx)
|
|
if err != nil || preference.Enabled || preference.WechatBound {
|
|
t.Fatalf("unbind must disable notifications: %v %v", preference, err)
|
|
}
|
|
if _, err := db.Model("sys_social").Data(do.SysSocial{Id: 3, TenantId: "tenant", UserId: 101, Source: "wechat_mp", OpenId: "new"}).Insert(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
preference, err = service.WarningPreference(userCtx)
|
|
if err != nil || preference.Enabled || !preference.WechatBound {
|
|
t.Fatalf("rebind must not silently enable: %v %v", preference, err)
|
|
}
|
|
}
|