sysUserPermModel_test.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975
  1. package userperm
  2. import (
  3. "context"
  4. "errors"
  5. "math/rand"
  6. "sort"
  7. "testing"
  8. "time"
  9. "perms-system-server/internal/testutil"
  10. "github.com/go-sql-driver/mysql"
  11. "github.com/stretchr/testify/assert"
  12. "github.com/stretchr/testify/require"
  13. "github.com/zeromicro/go-zero/core/stores/sqlx"
  14. )
  15. func randUserPermId() int64 {
  16. return int64(900000 + rand.Intn(100000))
  17. }
  18. func sortedInt64Copy(a []int64) []int64 {
  19. b := append([]int64(nil), a...)
  20. sort.Slice(b, func(i, j int) bool { return b[i] < b[j] })
  21. return b
  22. }
  23. func int64SliceEqualIgnoreOrder(a, b []int64) bool {
  24. if len(a) != len(b) {
  25. return false
  26. }
  27. aa, bb := sortedInt64Copy(a), sortedInt64Copy(b)
  28. for i := range aa {
  29. if aa[i] != bb[i] {
  30. return false
  31. }
  32. }
  33. return true
  34. }
  35. func insertTestPerm(t *testing.T, ctx context.Context, conn sqlx.SqlConn, productCode, code string) int64 {
  36. t.Helper()
  37. ts := time.Now().Unix()
  38. q := "INSERT INTO `sys_perm` (`productCode`, `name`, `code`, `status`, `createTime`, `updateTime`) VALUES (?, ?, ?, 1, ?, ?)"
  39. res, err := conn.ExecCtx(ctx, q, productCode, "t", code, ts, ts)
  40. if err != nil {
  41. t.Fatalf("insert sys_perm: %v", err)
  42. }
  43. id, err := res.LastInsertId()
  44. if err != nil {
  45. t.Fatalf("perm LastInsertId: %v", err)
  46. }
  47. return id
  48. }
  49. // TC-0310: 正常插入
  50. func TestSysUserPermModel_CRUD(t *testing.T) {
  51. ctx := context.Background()
  52. conn := testutil.GetTestSqlConn()
  53. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  54. userId := randUserPermId()
  55. permId := randUserPermId()
  56. ts := time.Now().Unix()
  57. data := &SysUserPerm{
  58. UserId: userId,
  59. PermId: permId,
  60. Effect: "ALLOW",
  61. CreateTime: ts,
  62. UpdateTime: ts,
  63. }
  64. res, err := m.Insert(ctx, data)
  65. if err != nil {
  66. t.Fatalf("Insert: %v", err)
  67. }
  68. id, err := res.LastInsertId()
  69. if err != nil {
  70. t.Fatalf("LastInsertId: %v", err)
  71. }
  72. defer testutil.CleanTable(ctx, conn, "sys_user_perm", id)
  73. got, err := m.FindOne(ctx, id)
  74. if err != nil {
  75. t.Fatalf("FindOne: %v", err)
  76. }
  77. if got.UserId != userId || got.PermId != permId || got.Effect != "ALLOW" {
  78. t.Fatalf("FindOne mismatch: %+v", got)
  79. }
  80. byPair, err := m.FindOneByUserIdPermId(ctx, userId, permId)
  81. if err != nil {
  82. t.Fatalf("FindOneByUserIdPermId: %v", err)
  83. }
  84. if byPair.Id != id {
  85. t.Fatalf("FindOneByUserIdPermId id want %d got %d", id, byPair.Id)
  86. }
  87. newTs := ts + 1
  88. got.Effect = "DENY"
  89. got.UpdateTime = newTs
  90. if err := m.Update(ctx, got); err != nil {
  91. t.Fatalf("Update: %v", err)
  92. }
  93. updated, err := m.FindOne(ctx, id)
  94. if err != nil {
  95. t.Fatalf("FindOne after update: %v", err)
  96. }
  97. if updated.Effect != "DENY" || updated.UpdateTime != newTs {
  98. t.Fatalf("after Update: %+v", updated)
  99. }
  100. if err := m.Delete(ctx, id); err != nil {
  101. t.Fatalf("Delete: %v", err)
  102. }
  103. if _, err := m.FindOne(ctx, id); err != ErrNotFound {
  104. t.Fatalf("after Delete want ErrNotFound got %v", err)
  105. }
  106. }
  107. // TC-0462: FindPermIdsByUserIdAndEffectForProduct ALLOW/DENY
  108. func TestSysUserPermModel_FindPermIdsByUserIdAndEffectForProduct(t *testing.T) {
  109. ctx := context.Background()
  110. conn := testutil.GetTestSqlConn()
  111. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  112. productCode := "t_upe_" + testutil.UniqueId()
  113. codeAllow := "c_allow_" + testutil.UniqueId()
  114. codeDeny := "c_deny_" + testutil.UniqueId()
  115. pAllow := insertTestPerm(t, ctx, conn, productCode, codeAllow)
  116. pDeny := insertTestPerm(t, ctx, conn, productCode, codeDeny)
  117. defer testutil.CleanTable(ctx, conn, "sys_perm", pAllow, pDeny)
  118. userId := randUserPermId()
  119. ts := time.Now().Unix()
  120. resA, err := m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: pAllow, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  121. require.NoError(t, err)
  122. idA, _ := resA.LastInsertId()
  123. resD, err := m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: pDeny, Effect: "DENY", CreateTime: ts, UpdateTime: ts})
  124. require.NoError(t, err)
  125. idD, _ := resD.LastInsertId()
  126. defer testutil.CleanTable(ctx, conn, "sys_user_perm", idA, idD)
  127. allowIds, err := m.FindPermIdsByUserIdAndEffectForProduct(ctx, userId, "ALLOW", productCode)
  128. require.NoError(t, err)
  129. require.True(t, int64SliceEqualIgnoreOrder(allowIds, []int64{pAllow}), "ALLOW ids got %v", allowIds)
  130. denyIds, err := m.FindPermIdsByUserIdAndEffectForProduct(ctx, userId, "DENY", productCode)
  131. require.NoError(t, err)
  132. require.True(t, int64SliceEqualIgnoreOrder(denyIds, []int64{pDeny}), "DENY ids got %v", denyIds)
  133. other, err := m.FindPermIdsByUserIdAndEffectForProduct(ctx, userId, "ALLOW", "not_"+productCode)
  134. require.NoError(t, err)
  135. require.Empty(t, other)
  136. }
  137. // TC-0319: 记录不存在
  138. func TestSysUserPermModel_FindOne_NotFound(t *testing.T) {
  139. conn := testutil.GetTestSqlConn()
  140. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  141. _, err := m.FindOne(context.Background(), 999999999999)
  142. if err != ErrNotFound {
  143. t.Fatalf("want ErrNotFound got %v", err)
  144. }
  145. }
  146. // TC-0384: FindOneByUserIdPermId
  147. func TestSysUserPermModel_FindOneByUserIdPermId_NotFound(t *testing.T) {
  148. conn := testutil.GetTestSqlConn()
  149. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  150. _, err := m.FindOneByUserIdPermId(context.Background(), 999999999, 999999999)
  151. if err != ErrNotFound {
  152. t.Fatalf("want ErrNotFound got %v", err)
  153. }
  154. }
  155. // TC-0464: FindPermIdsByUserIdAndEffectForProduct 无记录
  156. func TestSysUserPermModel_FindPermIdsByUserIdAndEffectForProduct_Empty(t *testing.T) {
  157. conn := testutil.GetTestSqlConn()
  158. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  159. ids, err := m.FindPermIdsByUserIdAndEffectForProduct(context.Background(), 999999999, "ALLOW", "nonexist_pc")
  160. if err != nil {
  161. t.Fatalf("err: %v", err)
  162. }
  163. if len(ids) != 0 {
  164. t.Fatalf("want empty got %v", ids)
  165. }
  166. }
  167. // TC-0465: 事务内跨产品删除
  168. func TestSysUserPermModel_DeleteByUserIdForProductTx(t *testing.T) {
  169. ctx := context.Background()
  170. conn := testutil.GetTestSqlConn()
  171. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  172. pcA := "t_upt_a_" + testutil.UniqueId()
  173. pcB := "t_upt_b_" + testutil.UniqueId()
  174. codeA := "c_ta_" + testutil.UniqueId()
  175. codeB := "c_tb_" + testutil.UniqueId()
  176. permA := insertTestPerm(t, ctx, conn, pcA, codeA)
  177. permB := insertTestPerm(t, ctx, conn, pcB, codeB)
  178. defer testutil.CleanTable(ctx, conn, "sys_perm", permA, permB)
  179. userId := randUserPermId()
  180. ts := time.Now().Unix()
  181. resA, err := m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: permA, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  182. if err != nil {
  183. t.Fatalf("Insert A: %v", err)
  184. }
  185. idA, _ := resA.LastInsertId()
  186. resB, err := m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: permB, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  187. if err != nil {
  188. t.Fatalf("Insert B: %v", err)
  189. }
  190. idB, _ := resB.LastInsertId()
  191. defer testutil.CleanTable(ctx, conn, "sys_user_perm", idA, idB)
  192. err = m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  193. return m.DeleteByUserIdForProductTx(c, session, userId, pcA)
  194. })
  195. if err != nil {
  196. t.Fatalf("DeleteByUserIdForProductTx: %v", err)
  197. }
  198. if _, err := m.FindOne(ctx, idA); err != ErrNotFound {
  199. t.Fatalf("pcA row should delete: %v", err)
  200. }
  201. if _, err := m.FindOne(ctx, idB); err != nil {
  202. t.Fatalf("pcB row should remain: %v", err)
  203. }
  204. }
  205. // TC-0334: 空列表
  206. func TestSysUserPermModel_BatchInsert_Empty(t *testing.T) {
  207. conn := testutil.GetTestSqlConn()
  208. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  209. if err := m.BatchInsert(context.Background(), nil); err != nil {
  210. t.Fatalf("nil: %v", err)
  211. }
  212. if err := m.BatchInsert(context.Background(), []*SysUserPerm{}); err != nil {
  213. t.Fatalf("empty: %v", err)
  214. }
  215. }
  216. // TC-0353: 空ids
  217. func TestSysUserPermModel_BatchDelete_Empty(t *testing.T) {
  218. conn := testutil.GetTestSqlConn()
  219. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  220. if err := m.BatchDelete(context.Background(), nil); err != nil {
  221. t.Fatalf("nil: %v", err)
  222. }
  223. if err := m.BatchDelete(context.Background(), []int64{}); err != nil {
  224. t.Fatalf("empty: %v", err)
  225. }
  226. }
  227. // TC-0312: 唯一索引冲突
  228. func TestSysUserPermModel_Insert_UniqueConflict(t *testing.T) {
  229. ctx := context.Background()
  230. conn := testutil.GetTestSqlConn()
  231. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  232. userId := randUserPermId()
  233. permId := randUserPermId()
  234. ts := time.Now().Unix()
  235. res, err := m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  236. if err != nil {
  237. t.Fatalf("Insert: %v", err)
  238. }
  239. id, _ := res.LastInsertId()
  240. defer testutil.CleanTable(ctx, conn, "sys_user_perm", id)
  241. _, err = m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: permId, Effect: "DENY", CreateTime: ts, UpdateTime: ts})
  242. if err == nil {
  243. t.Fatal("second Insert want error")
  244. }
  245. var me *mysql.MySQLError
  246. if !errors.As(err, &me) || me.Number != 1062 {
  247. t.Fatalf("want duplicate key 1062, got %v", err)
  248. }
  249. }
  250. // TC-0314: 事务内插入
  251. func TestSysUserPermModel_InsertWithTx_Normal(t *testing.T) {
  252. ctx := context.Background()
  253. conn := testutil.GetTestSqlConn()
  254. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  255. userId := randUserPermId()
  256. permId := randUserPermId()
  257. ts := time.Now().Unix()
  258. var insertedId int64
  259. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  260. res, err := m.InsertWithTx(c, session, &SysUserPerm{UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  261. if err != nil {
  262. return err
  263. }
  264. insertedId, _ = res.LastInsertId()
  265. return nil
  266. })
  267. if err != nil {
  268. t.Fatalf("TransactCtx: %v", err)
  269. }
  270. defer testutil.CleanTable(ctx, conn, "sys_user_perm", insertedId)
  271. got, err := m.FindOne(ctx, insertedId)
  272. if err != nil {
  273. t.Fatalf("FindOne: %v", err)
  274. }
  275. if got.UserId != userId || got.PermId != permId || got.Effect != "ALLOW" {
  276. t.Fatalf("mismatch: %+v", got)
  277. }
  278. }
  279. // TC-0316: 事务回滚后无数据
  280. func TestSysUserPermModel_InsertWithTx_Rollback(t *testing.T) {
  281. ctx := context.Background()
  282. conn := testutil.GetTestSqlConn()
  283. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  284. userId := randUserPermId()
  285. permId := randUserPermId()
  286. ts := time.Now().Unix()
  287. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  288. _, err := m.InsertWithTx(c, session, &SysUserPerm{UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  289. if err != nil {
  290. return err
  291. }
  292. return errors.New("rollback")
  293. })
  294. if err == nil || err.Error() != "rollback" {
  295. t.Fatalf("want rollback error got %v", err)
  296. }
  297. _, err = m.FindOneByUserIdPermId(ctx, userId, permId)
  298. if err != ErrNotFound {
  299. t.Fatalf("after rollback want ErrNotFound got %v", err)
  300. }
  301. }
  302. // TC-0326: 记录不存在
  303. func TestSysUserPermModel_Update_NotFound(t *testing.T) {
  304. conn := testutil.GetTestSqlConn()
  305. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  306. ts := time.Now().Unix()
  307. err := m.Update(context.Background(), &SysUserPerm{
  308. Id: 999999999, UserId: 1, PermId: 1, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts,
  309. })
  310. if err != ErrNotFound {
  311. t.Fatalf("want ErrNotFound got %v", err)
  312. }
  313. }
  314. // TC-0327: 事务内更新
  315. func TestSysUserPermModel_UpdateWithTx(t *testing.T) {
  316. ctx := context.Background()
  317. conn := testutil.GetTestSqlConn()
  318. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  319. userId := randUserPermId()
  320. permId := randUserPermId()
  321. ts := time.Now().Unix()
  322. res, err := m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  323. if err != nil {
  324. t.Fatalf("Insert: %v", err)
  325. }
  326. id, _ := res.LastInsertId()
  327. defer testutil.CleanTable(ctx, conn, "sys_user_perm", id)
  328. newTs := ts + 100
  329. err = m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  330. return m.UpdateWithTx(c, session, &SysUserPerm{
  331. Id: id, UserId: userId, PermId: permId, Effect: "DENY", CreateTime: ts, UpdateTime: newTs,
  332. })
  333. })
  334. if err != nil {
  335. t.Fatalf("UpdateWithTx: %v", err)
  336. }
  337. got, err := m.FindOne(ctx, id)
  338. if err != nil {
  339. t.Fatalf("FindOne: %v", err)
  340. }
  341. if got.Effect != "DENY" || got.UpdateTime != newTs {
  342. t.Fatalf("mismatch: %+v", got)
  343. }
  344. }
  345. // TC-0329: 记录不存在
  346. func TestSysUserPermModel_Delete_NotFound(t *testing.T) {
  347. conn := testutil.GetTestSqlConn()
  348. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  349. err := m.Delete(context.Background(), 999999999)
  350. if err != ErrNotFound {
  351. t.Fatalf("want ErrNotFound got %v", err)
  352. }
  353. }
  354. // TC-0330: 事务内删除
  355. func TestSysUserPermModel_DeleteWithTx(t *testing.T) {
  356. ctx := context.Background()
  357. conn := testutil.GetTestSqlConn()
  358. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  359. userId := randUserPermId()
  360. permId := randUserPermId()
  361. ts := time.Now().Unix()
  362. res, err := m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  363. if err != nil {
  364. t.Fatalf("Insert: %v", err)
  365. }
  366. id, _ := res.LastInsertId()
  367. defer testutil.CleanTable(ctx, conn, "sys_user_perm", id)
  368. err = m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  369. return m.DeleteWithTx(c, session, id)
  370. })
  371. if err != nil {
  372. t.Fatalf("DeleteWithTx: %v", err)
  373. }
  374. if _, err := m.FindOne(ctx, id); err != ErrNotFound {
  375. t.Fatalf("after DeleteWithTx want ErrNotFound got %v", err)
  376. }
  377. }
  378. // TC-0332: fn返回错误
  379. func TestSysUserPermModel_TransactCtx_Rollback(t *testing.T) {
  380. ctx := context.Background()
  381. conn := testutil.GetTestSqlConn()
  382. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  383. userId := randUserPermId()
  384. permId := randUserPermId()
  385. ts := time.Now().Unix()
  386. res, err := m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  387. if err != nil {
  388. t.Fatalf("Insert: %v", err)
  389. }
  390. id, _ := res.LastInsertId()
  391. defer testutil.CleanTable(ctx, conn, "sys_user_perm", id)
  392. err = m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  393. if err := m.DeleteWithTx(c, session, id); err != nil {
  394. return err
  395. }
  396. return errors.New("rollback")
  397. })
  398. if err == nil || err.Error() != "rollback" {
  399. t.Fatalf("want rollback error got %v", err)
  400. }
  401. got, err := m.FindOne(ctx, id)
  402. if err != nil {
  403. t.Fatalf("after rollback FindOne: %v", err)
  404. }
  405. if got.Id != id {
  406. t.Fatalf("row should still exist")
  407. }
  408. }
  409. // TC-0333: 获取表名
  410. func TestSysUserPermModel_TableName(t *testing.T) {
  411. conn := testutil.GetTestSqlConn()
  412. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  413. if m.TableName() != "`sys_user_perm`" {
  414. t.Fatalf("want `sys_user_perm` got %s", m.TableName())
  415. }
  416. }
  417. // TC-0335: 单条记录
  418. func TestSysUserPermModel_BatchInsert_Single(t *testing.T) {
  419. ctx := context.Background()
  420. conn := testutil.GetTestSqlConn()
  421. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  422. userId := randUserPermId()
  423. permId := randUserPermId()
  424. ts := time.Now().Unix()
  425. if err := m.BatchInsert(ctx, []*SysUserPerm{
  426. {UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts},
  427. }); err != nil {
  428. t.Fatalf("BatchInsert: %v", err)
  429. }
  430. got, err := m.FindOneByUserIdPermId(ctx, userId, permId)
  431. if err != nil {
  432. t.Fatalf("FindOneByUserIdPermId: %v", err)
  433. }
  434. defer testutil.CleanTable(ctx, conn, "sys_user_perm", got.Id)
  435. if got.Effect != "ALLOW" {
  436. t.Fatalf("mismatch: %+v", got)
  437. }
  438. }
  439. // TC-0336: 多条记录(3条)
  440. func TestSysUserPermModel_BatchInsert_Multi(t *testing.T) {
  441. ctx := context.Background()
  442. conn := testutil.GetTestSqlConn()
  443. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  444. u1, u2, u3 := randUserPermId(), randUserPermId(), randUserPermId()
  445. p1, p2, p3 := randUserPermId(), randUserPermId(), randUserPermId()
  446. ts := time.Now().Unix()
  447. if err := m.BatchInsert(ctx, []*SysUserPerm{
  448. {UserId: u1, PermId: p1, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts},
  449. {UserId: u2, PermId: p2, Effect: "DENY", CreateTime: ts, UpdateTime: ts},
  450. {UserId: u3, PermId: p3, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts},
  451. }); err != nil {
  452. t.Fatalf("BatchInsert: %v", err)
  453. }
  454. var ids []int64
  455. for _, pair := range [][2]int64{{u1, p1}, {u2, p2}, {u3, p3}} {
  456. got, err := m.FindOneByUserIdPermId(ctx, pair[0], pair[1])
  457. if err != nil {
  458. t.Fatalf("FindOneByUserIdPermId(%d,%d): %v", pair[0], pair[1], err)
  459. }
  460. ids = append(ids, got.Id)
  461. }
  462. defer func() {
  463. for _, id := range ids {
  464. testutil.CleanTable(ctx, conn, "sys_user_perm", id)
  465. }
  466. }()
  467. if len(ids) != 3 {
  468. t.Fatalf("want 3 rows got %d", len(ids))
  469. }
  470. }
  471. // TC-0338: 唯一索引冲突
  472. func TestSysUserPermModel_BatchInsert_UniqueConflict(t *testing.T) {
  473. ctx := context.Background()
  474. conn := testutil.GetTestSqlConn()
  475. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  476. userId := randUserPermId()
  477. permId := randUserPermId()
  478. ts := time.Now().Unix()
  479. err := m.BatchInsert(ctx, []*SysUserPerm{
  480. {UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts},
  481. {UserId: userId, PermId: permId, Effect: "DENY", CreateTime: ts, UpdateTime: ts},
  482. })
  483. if err == nil {
  484. t.Fatal("want error for duplicate")
  485. }
  486. var me *mysql.MySQLError
  487. if !errors.As(err, &me) || me.Number != 1062 {
  488. t.Fatalf("want duplicate key 1062, got %v", err)
  489. }
  490. }
  491. // TC-0343: 空列表
  492. func TestSysUserPermModel_BatchUpdate_Empty(t *testing.T) {
  493. conn := testutil.GetTestSqlConn()
  494. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  495. if err := m.BatchUpdate(context.Background(), nil); err != nil {
  496. t.Fatalf("nil: %v", err)
  497. }
  498. if err := m.BatchUpdate(context.Background(), []*SysUserPerm{}); err != nil {
  499. t.Fatalf("empty: %v", err)
  500. }
  501. }
  502. // TC-0345: 多条记录(3条)
  503. func TestSysUserPermModel_BatchUpdate_Multi(t *testing.T) {
  504. ctx := context.Background()
  505. conn := testutil.GetTestSqlConn()
  506. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  507. u1, u2 := randUserPermId(), randUserPermId()
  508. p1, p2 := randUserPermId(), randUserPermId()
  509. ts := time.Now().Unix()
  510. res1, err := m.Insert(ctx, &SysUserPerm{UserId: u1, PermId: p1, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  511. if err != nil {
  512. t.Fatalf("Insert1: %v", err)
  513. }
  514. id1, _ := res1.LastInsertId()
  515. res2, err := m.Insert(ctx, &SysUserPerm{UserId: u2, PermId: p2, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  516. if err != nil {
  517. t.Fatalf("Insert2: %v", err)
  518. }
  519. id2, _ := res2.LastInsertId()
  520. defer testutil.CleanTable(ctx, conn, "sys_user_perm", id1, id2)
  521. newTs := ts + 100
  522. err = m.BatchUpdate(ctx, []*SysUserPerm{
  523. {Id: id1, UserId: u1, PermId: p1, Effect: "DENY", CreateTime: ts, UpdateTime: newTs},
  524. {Id: id2, UserId: u2, PermId: p2, Effect: "DENY", CreateTime: ts, UpdateTime: newTs},
  525. })
  526. if err != nil {
  527. t.Fatalf("BatchUpdate: %v", err)
  528. }
  529. got1, err := m.FindOne(ctx, id1)
  530. if err != nil {
  531. t.Fatalf("FindOne1: %v", err)
  532. }
  533. if got1.Effect != "DENY" || got1.UpdateTime != newTs {
  534. t.Fatalf("got1 mismatch: %+v", got1)
  535. }
  536. got2, err := m.FindOne(ctx, id2)
  537. if err != nil {
  538. t.Fatalf("FindOne2: %v", err)
  539. }
  540. if got2.Effect != "DENY" || got2.UpdateTime != newTs {
  541. t.Fatalf("got2 mismatch: %+v", got2)
  542. }
  543. }
  544. // TC-0355: 多个id(3个)
  545. func TestSysUserPermModel_BatchDelete_Multi(t *testing.T) {
  546. ctx := context.Background()
  547. conn := testutil.GetTestSqlConn()
  548. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  549. ts := time.Now().Unix()
  550. var ids []int64
  551. for i := 0; i < 3; i++ {
  552. res, err := m.Insert(ctx, &SysUserPerm{
  553. UserId: randUserPermId(), PermId: randUserPermId(), Effect: "ALLOW", CreateTime: ts, UpdateTime: ts,
  554. })
  555. if err != nil {
  556. t.Fatalf("Insert: %v", err)
  557. }
  558. id, _ := res.LastInsertId()
  559. ids = append(ids, id)
  560. }
  561. defer func() {
  562. for _, id := range ids {
  563. testutil.CleanTable(ctx, conn, "sys_user_perm", id)
  564. }
  565. }()
  566. if err := m.BatchDelete(ctx, ids); err != nil {
  567. t.Fatalf("BatchDelete: %v", err)
  568. }
  569. for _, id := range ids {
  570. if _, err := m.FindOne(ctx, id); err != ErrNotFound {
  571. t.Fatalf("id %d should be deleted: %v", id, err)
  572. }
  573. }
  574. }
  575. // TC-0354: 单个id
  576. func TestSysUserPermModel_BatchDelete_Single(t *testing.T) {
  577. ctx := context.Background()
  578. conn := testutil.GetTestSqlConn()
  579. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  580. userId := randUserPermId()
  581. permId := randUserPermId()
  582. ts := time.Now().Unix()
  583. res, err := m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  584. if err != nil {
  585. t.Fatalf("Insert: %v", err)
  586. }
  587. id, _ := res.LastInsertId()
  588. defer testutil.CleanTable(ctx, conn, "sys_user_perm", id)
  589. if err := m.BatchDelete(ctx, []int64{id}); err != nil {
  590. t.Fatalf("BatchDelete: %v", err)
  591. }
  592. if _, err := m.FindOne(ctx, id); err != ErrNotFound {
  593. t.Fatalf("want ErrNotFound got %v", err)
  594. }
  595. }
  596. // TC-0356: 包含不存在id
  597. func TestSysUserPermModel_BatchDelete_ContainsNonExist(t *testing.T) {
  598. ctx := context.Background()
  599. conn := testutil.GetTestSqlConn()
  600. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  601. userId := randUserPermId()
  602. permId := randUserPermId()
  603. ts := time.Now().Unix()
  604. res, err := m.Insert(ctx, &SysUserPerm{UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  605. if err != nil {
  606. t.Fatalf("Insert: %v", err)
  607. }
  608. id, _ := res.LastInsertId()
  609. defer testutil.CleanTable(ctx, conn, "sys_user_perm", id)
  610. if err := m.BatchDelete(ctx, []int64{id, 999999999}); err != nil {
  611. t.Fatalf("BatchDelete: %v", err)
  612. }
  613. if _, err := m.FindOne(ctx, id); err != ErrNotFound {
  614. t.Fatalf("want ErrNotFound got %v", err)
  615. }
  616. }
  617. // TC-0341: 正常多条
  618. func TestSysUserPermModel_BatchInsertWithTx_Normal(t *testing.T) {
  619. ctx := context.Background()
  620. conn := testutil.GetTestSqlConn()
  621. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  622. u1, u2 := randUserPermId(), randUserPermId()
  623. p1, p2 := randUserPermId(), randUserPermId()
  624. ts := time.Now().Unix()
  625. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  626. return m.BatchInsertWithTx(c, session, []*SysUserPerm{
  627. {UserId: u1, PermId: p1, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts},
  628. {UserId: u2, PermId: p2, Effect: "DENY", CreateTime: ts, UpdateTime: ts},
  629. })
  630. })
  631. if err != nil {
  632. t.Fatalf("BatchInsertWithTx: %v", err)
  633. }
  634. got1, err := m.FindOneByUserIdPermId(ctx, u1, p1)
  635. if err != nil {
  636. t.Fatalf("FindOne u1p1: %v", err)
  637. }
  638. got2, err := m.FindOneByUserIdPermId(ctx, u2, p2)
  639. if err != nil {
  640. t.Fatalf("FindOne u2p2: %v", err)
  641. }
  642. defer testutil.CleanTable(ctx, conn, "sys_user_perm", got1.Id, got2.Id)
  643. }
  644. // TC-0340: 空列表
  645. func TestSysUserPermModel_BatchInsertWithTx_Empty(t *testing.T) {
  646. ctx := context.Background()
  647. conn := testutil.GetTestSqlConn()
  648. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  649. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  650. if err := m.BatchInsertWithTx(c, session, nil); err != nil {
  651. return err
  652. }
  653. return m.BatchInsertWithTx(c, session, []*SysUserPerm{})
  654. })
  655. if err != nil {
  656. t.Fatalf("BatchInsertWithTx empty: %v", err)
  657. }
  658. }
  659. // TC-0342: 事务回滚
  660. func TestSysUserPermModel_BatchInsertWithTx_Rollback(t *testing.T) {
  661. ctx := context.Background()
  662. conn := testutil.GetTestSqlConn()
  663. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  664. userId := randUserPermId()
  665. permId := randUserPermId()
  666. ts := time.Now().Unix()
  667. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  668. if err := m.BatchInsertWithTx(c, session, []*SysUserPerm{
  669. {UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts},
  670. }); err != nil {
  671. return err
  672. }
  673. return errors.New("rollback")
  674. })
  675. if err == nil || err.Error() != "rollback" {
  676. t.Fatalf("want rollback error got %v", err)
  677. }
  678. _, err = m.FindOneByUserIdPermId(ctx, userId, permId)
  679. if err != ErrNotFound {
  680. t.Fatalf("after rollback want ErrNotFound got %v", err)
  681. }
  682. }
  683. // TC-0349: 正常多条
  684. func TestSysUserPermModel_BatchUpdateWithTx_Normal(t *testing.T) {
  685. ctx := context.Background()
  686. conn := testutil.GetTestSqlConn()
  687. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  688. u1, u2 := randUserPermId(), randUserPermId()
  689. p1, p2 := randUserPermId(), randUserPermId()
  690. ts := time.Now().Unix()
  691. res1, err := m.Insert(ctx, &SysUserPerm{UserId: u1, PermId: p1, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  692. if err != nil {
  693. t.Fatalf("Insert1: %v", err)
  694. }
  695. id1, _ := res1.LastInsertId()
  696. res2, err := m.Insert(ctx, &SysUserPerm{UserId: u2, PermId: p2, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  697. if err != nil {
  698. t.Fatalf("Insert2: %v", err)
  699. }
  700. id2, _ := res2.LastInsertId()
  701. defer testutil.CleanTable(ctx, conn, "sys_user_perm", id1, id2)
  702. newTs := ts + 200
  703. err = m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  704. return m.BatchUpdateWithTx(c, session, []*SysUserPerm{
  705. {Id: id1, UserId: u1, PermId: p1, Effect: "DENY", CreateTime: ts, UpdateTime: newTs},
  706. {Id: id2, UserId: u2, PermId: p2, Effect: "DENY", CreateTime: ts, UpdateTime: newTs},
  707. })
  708. })
  709. if err != nil {
  710. t.Fatalf("BatchUpdateWithTx: %v", err)
  711. }
  712. got1, err := m.FindOne(ctx, id1)
  713. if err != nil {
  714. t.Fatalf("FindOne1: %v", err)
  715. }
  716. if got1.Effect != "DENY" || got1.UpdateTime != newTs {
  717. t.Fatalf("got1 mismatch: %+v", got1)
  718. }
  719. }
  720. // TC-0348: 空列表
  721. func TestSysUserPermModel_BatchUpdateWithTx_Empty(t *testing.T) {
  722. ctx := context.Background()
  723. conn := testutil.GetTestSqlConn()
  724. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  725. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  726. if err := m.BatchUpdateWithTx(c, session, nil); err != nil {
  727. return err
  728. }
  729. return m.BatchUpdateWithTx(c, session, []*SysUserPerm{})
  730. })
  731. if err != nil {
  732. t.Fatalf("BatchUpdateWithTx empty: %v", err)
  733. }
  734. }
  735. // TC-0358: 正常多条
  736. func TestSysUserPermModel_BatchDeleteWithTx_Normal(t *testing.T) {
  737. ctx := context.Background()
  738. conn := testutil.GetTestSqlConn()
  739. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  740. ts := time.Now().Unix()
  741. var ids []int64
  742. for i := 0; i < 2; i++ {
  743. res, err := m.Insert(ctx, &SysUserPerm{
  744. UserId: randUserPermId(), PermId: randUserPermId(), Effect: "ALLOW", CreateTime: ts, UpdateTime: ts,
  745. })
  746. if err != nil {
  747. t.Fatalf("Insert: %v", err)
  748. }
  749. id, _ := res.LastInsertId()
  750. ids = append(ids, id)
  751. }
  752. defer func() {
  753. for _, id := range ids {
  754. testutil.CleanTable(ctx, conn, "sys_user_perm", id)
  755. }
  756. }()
  757. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  758. return m.BatchDeleteWithTx(c, session, ids)
  759. })
  760. if err != nil {
  761. t.Fatalf("BatchDeleteWithTx: %v", err)
  762. }
  763. for _, id := range ids {
  764. if _, err := m.FindOne(ctx, id); err != ErrNotFound {
  765. t.Fatalf("id %d should be deleted: %v", id, err)
  766. }
  767. }
  768. }
  769. // TC-0357: 空ids
  770. func TestSysUserPermModel_BatchDeleteWithTx_Empty(t *testing.T) {
  771. ctx := context.Background()
  772. conn := testutil.GetTestSqlConn()
  773. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  774. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  775. if err := m.BatchDeleteWithTx(c, session, nil); err != nil {
  776. return err
  777. }
  778. return m.BatchDeleteWithTx(c, session, []int64{})
  779. })
  780. if err != nil {
  781. t.Fatalf("BatchDeleteWithTx empty: %v", err)
  782. }
  783. }
  784. // TC-0323: 事务内可见性
  785. func TestSysUserPermModel_FindOneWithTx_InsertThenFind(t *testing.T) {
  786. ctx := context.Background()
  787. conn := testutil.GetTestSqlConn()
  788. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  789. userId := randUserPermId()
  790. permId := randUserPermId()
  791. ts := time.Now().Unix()
  792. var insertedId int64
  793. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  794. res, err := m.InsertWithTx(c, session, &SysUserPerm{UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  795. if err != nil {
  796. return err
  797. }
  798. insertedId, err = res.LastInsertId()
  799. if err != nil {
  800. return err
  801. }
  802. got, err := m.FindOneWithTx(c, session, insertedId)
  803. require.NoError(t, err)
  804. assert.Equal(t, insertedId, got.Id)
  805. assert.Equal(t, userId, got.UserId)
  806. assert.Equal(t, permId, got.PermId)
  807. assert.Equal(t, "ALLOW", got.Effect)
  808. return nil
  809. })
  810. require.NoError(t, err)
  811. defer testutil.CleanTable(ctx, conn, "sys_user_perm", insertedId)
  812. }
  813. // TC-0322: 事务内记录不存在
  814. func TestSysUserPermModel_FindOneWithTx_NotFound(t *testing.T) {
  815. ctx := context.Background()
  816. m := NewSysUserPermModel(testutil.GetTestSqlConn(), testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  817. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  818. _, err := m.FindOneWithTx(c, session, 999999999999)
  819. require.ErrorIs(t, err, ErrNotFound)
  820. return nil
  821. })
  822. require.NoError(t, err)
  823. }
  824. // TC-0385: FindOneByUserIdPermIdWithTx
  825. func TestSysUserPermModel_FindOneByUserIdPermIdWithTx_InsertThenFind(t *testing.T) {
  826. ctx := context.Background()
  827. conn := testutil.GetTestSqlConn()
  828. m := NewSysUserPermModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  829. userId := randUserPermId()
  830. permId := randUserPermId()
  831. ts := time.Now().Unix()
  832. var insertedId int64
  833. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  834. res, err := m.InsertWithTx(c, session, &SysUserPerm{UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: ts, UpdateTime: ts})
  835. if err != nil {
  836. return err
  837. }
  838. insertedId, err = res.LastInsertId()
  839. if err != nil {
  840. return err
  841. }
  842. got, err := m.FindOneByUserIdPermIdWithTx(c, session, userId, permId)
  843. require.NoError(t, err)
  844. assert.Equal(t, insertedId, got.Id)
  845. assert.Equal(t, userId, got.UserId)
  846. assert.Equal(t, permId, got.PermId)
  847. return nil
  848. })
  849. require.NoError(t, err)
  850. defer testutil.CleanTable(ctx, conn, "sys_user_perm", insertedId)
  851. }
  852. // TC-0386: FindOneByUserIdPermIdWithTx
  853. func TestSysUserPermModel_FindOneByUserIdPermIdWithTx_NotFound(t *testing.T) {
  854. ctx := context.Background()
  855. m := NewSysUserPermModel(testutil.GetTestSqlConn(), testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
  856. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  857. _, err := m.FindOneByUserIdPermIdWithTx(c, session, 999999999, 999999999)
  858. require.ErrorIs(t, err, ErrNotFound)
  859. return nil
  860. })
  861. require.NoError(t, err)
  862. }