syncPermsLogic_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. package pub
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "testing"
  7. "time"
  8. permModel "perms-system-server/internal/model/perm"
  9. productModel "perms-system-server/internal/model/product"
  10. "perms-system-server/internal/response"
  11. "perms-system-server/internal/testutil"
  12. "perms-system-server/internal/types"
  13. "github.com/stretchr/testify/assert"
  14. "github.com/stretchr/testify/require"
  15. )
  16. func insertSyncTestProduct(t *testing.T, ctx context.Context, code, appKey, appSecret string, status int64) (int64, func()) {
  17. t.Helper()
  18. svcCtx := newTestSvcCtx()
  19. conn := testutil.GetTestSqlConn()
  20. now := time.Now().Unix()
  21. res, err := svcCtx.SysProductModel.Insert(ctx, &productModel.SysProduct{
  22. Code: code,
  23. Name: code,
  24. AppKey: appKey,
  25. AppSecret: appSecret,
  26. Status: status,
  27. CreateTime: now,
  28. UpdateTime: now,
  29. })
  30. require.NoError(t, err)
  31. id, _ := res.LastInsertId()
  32. cleanup := func() {
  33. testutil.CleanTable(ctx, conn, "`sys_product`", id)
  34. }
  35. return id, cleanup
  36. }
  37. // TC-0019: 全部新增
  38. func TestSyncPerms_AllNew(t *testing.T) {
  39. ctx := context.Background()
  40. svcCtx := newTestSvcCtx()
  41. conn := testutil.GetTestSqlConn()
  42. pc := testutil.UniqueId()
  43. appKey := testutil.UniqueId()
  44. appSecret := testutil.UniqueId()
  45. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 1)
  46. t.Cleanup(cleanProduct)
  47. t.Cleanup(func() { testutil.CleanTableByField(ctx, conn, "`sys_perm`", "productCode", pc) })
  48. logic := NewSyncPermsLogic(ctx, svcCtx)
  49. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  50. AppKey: appKey,
  51. AppSecret: appSecret,
  52. Perms: []types.SyncPermItem{
  53. {Code: "perm_a", Name: "Perm A", Remark: "remark a"},
  54. {Code: "perm_b", Name: "Perm B"},
  55. {Code: "perm_c", Name: "Perm C"},
  56. },
  57. })
  58. require.NoError(t, err)
  59. require.NotNil(t, resp)
  60. assert.Equal(t, int64(3), resp.Added)
  61. assert.Equal(t, int64(0), resp.Updated)
  62. assert.Equal(t, int64(0), resp.Disabled)
  63. }
  64. // TC-0020: 更新已有(名称变更)
  65. func TestSyncPerms_UpdateExisting(t *testing.T) {
  66. ctx := context.Background()
  67. svcCtx := newTestSvcCtx()
  68. conn := testutil.GetTestSqlConn()
  69. pc := testutil.UniqueId()
  70. appKey := testutil.UniqueId()
  71. appSecret := testutil.UniqueId()
  72. now := time.Now().Unix()
  73. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 1)
  74. t.Cleanup(cleanProduct)
  75. permRes, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
  76. ProductCode: pc, Name: "Old Name", Code: "upd_code", Remark: "old remark", Status: 1, CreateTime: now, UpdateTime: now,
  77. })
  78. require.NoError(t, err)
  79. permId, _ := permRes.LastInsertId()
  80. t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", permId) })
  81. logic := NewSyncPermsLogic(ctx, svcCtx)
  82. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  83. AppKey: appKey,
  84. AppSecret: appSecret,
  85. Perms: []types.SyncPermItem{
  86. {Code: "upd_code", Name: "New Name", Remark: "new remark"},
  87. },
  88. })
  89. require.NoError(t, err)
  90. require.NotNil(t, resp)
  91. assert.Equal(t, int64(0), resp.Added)
  92. assert.Equal(t, int64(1), resp.Updated)
  93. assert.Equal(t, int64(0), resp.Disabled)
  94. updated, err := svcCtx.SysPermModel.FindOne(ctx, permId)
  95. require.NoError(t, err)
  96. assert.Equal(t, "New Name", updated.Name)
  97. assert.Equal(t, "new remark", updated.Remark)
  98. assert.Equal(t, int64(1), updated.Status)
  99. }
  100. // TC-0021: 无变化
  101. func TestSyncPerms_NoChanges(t *testing.T) {
  102. ctx := context.Background()
  103. svcCtx := newTestSvcCtx()
  104. conn := testutil.GetTestSqlConn()
  105. pc := testutil.UniqueId()
  106. appKey := testutil.UniqueId()
  107. appSecret := testutil.UniqueId()
  108. now := time.Now().Unix()
  109. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 1)
  110. t.Cleanup(cleanProduct)
  111. permRes, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
  112. ProductCode: pc, Name: "Same Name", Code: "same_code", Remark: "same remark", Status: 1, CreateTime: now, UpdateTime: now,
  113. })
  114. require.NoError(t, err)
  115. permId, _ := permRes.LastInsertId()
  116. t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", permId) })
  117. logic := NewSyncPermsLogic(ctx, svcCtx)
  118. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  119. AppKey: appKey,
  120. AppSecret: appSecret,
  121. Perms: []types.SyncPermItem{
  122. {Code: "same_code", Name: "Same Name", Remark: "same remark"},
  123. },
  124. })
  125. require.NoError(t, err)
  126. require.NotNil(t, resp)
  127. assert.Equal(t, int64(0), resp.Added)
  128. assert.Equal(t, int64(0), resp.Updated)
  129. assert.Equal(t, int64(0), resp.Disabled)
  130. }
  131. // TC-0022: 禁用权限重启
  132. func TestSyncPerms_ReEnableDisabled(t *testing.T) {
  133. ctx := context.Background()
  134. svcCtx := newTestSvcCtx()
  135. conn := testutil.GetTestSqlConn()
  136. pc := testutil.UniqueId()
  137. appKey := testutil.UniqueId()
  138. appSecret := testutil.UniqueId()
  139. now := time.Now().Unix()
  140. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 1)
  141. t.Cleanup(cleanProduct)
  142. permRes, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
  143. ProductCode: pc, Name: "Disabled Perm", Code: "dis_code", Remark: "", Status: 2, CreateTime: now, UpdateTime: now,
  144. })
  145. require.NoError(t, err)
  146. permId, _ := permRes.LastInsertId()
  147. t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", permId) })
  148. logic := NewSyncPermsLogic(ctx, svcCtx)
  149. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  150. AppKey: appKey,
  151. AppSecret: appSecret,
  152. Perms: []types.SyncPermItem{
  153. {Code: "dis_code", Name: "Disabled Perm"},
  154. },
  155. })
  156. require.NoError(t, err)
  157. require.NotNil(t, resp)
  158. assert.Equal(t, int64(0), resp.Added)
  159. assert.Equal(t, int64(1), resp.Updated)
  160. reEnabled, err := svcCtx.SysPermModel.FindOne(ctx, permId)
  161. require.NoError(t, err)
  162. assert.Equal(t, int64(1), reEnabled.Status)
  163. }
  164. // TC-0023: 移除不在列表的权限
  165. func TestSyncPerms_DisableNotInList(t *testing.T) {
  166. ctx := context.Background()
  167. svcCtx := newTestSvcCtx()
  168. conn := testutil.GetTestSqlConn()
  169. pc := testutil.UniqueId()
  170. appKey := testutil.UniqueId()
  171. appSecret := testutil.UniqueId()
  172. now := time.Now().Unix()
  173. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 1)
  174. t.Cleanup(cleanProduct)
  175. keepCode := testutil.UniqueId()
  176. removeCode := testutil.UniqueId()
  177. keepRes, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
  178. ProductCode: pc, Name: "Keep", Code: keepCode, Status: 1, CreateTime: now, UpdateTime: now,
  179. })
  180. require.NoError(t, err)
  181. keepId, _ := keepRes.LastInsertId()
  182. removeRes, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
  183. ProductCode: pc, Name: "Remove", Code: removeCode, Status: 1, CreateTime: now, UpdateTime: now,
  184. })
  185. require.NoError(t, err)
  186. removeId, _ := removeRes.LastInsertId()
  187. t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", keepId, removeId) })
  188. logic := NewSyncPermsLogic(ctx, svcCtx)
  189. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  190. AppKey: appKey,
  191. AppSecret: appSecret,
  192. Perms: []types.SyncPermItem{
  193. {Code: keepCode, Name: "Keep"},
  194. },
  195. })
  196. require.NoError(t, err)
  197. require.NotNil(t, resp)
  198. assert.Equal(t, int64(0), resp.Added)
  199. assert.Equal(t, int64(1), resp.Disabled)
  200. disabled, err := svcCtx.SysPermModel.FindOne(ctx, removeId)
  201. require.NoError(t, err)
  202. assert.Equal(t, int64(2), disabled.Status)
  203. kept, err := svcCtx.SysPermModel.FindOne(ctx, keepId)
  204. require.NoError(t, err)
  205. assert.Equal(t, int64(1), kept.Status)
  206. }
  207. // TC-0024: 空perms数组
  208. func TestSyncPerms_EmptyPermsDisablesAll(t *testing.T) {
  209. ctx := context.Background()
  210. svcCtx := newTestSvcCtx()
  211. conn := testutil.GetTestSqlConn()
  212. pc := testutil.UniqueId()
  213. appKey := testutil.UniqueId()
  214. appSecret := testutil.UniqueId()
  215. now := time.Now().Unix()
  216. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 1)
  217. t.Cleanup(cleanProduct)
  218. p1Res, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
  219. ProductCode: pc, Name: "P1", Code: testutil.UniqueId(), Status: 1, CreateTime: now, UpdateTime: now,
  220. })
  221. require.NoError(t, err)
  222. p1Id, _ := p1Res.LastInsertId()
  223. p2Res, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
  224. ProductCode: pc, Name: "P2", Code: testutil.UniqueId(), Status: 1, CreateTime: now, UpdateTime: now,
  225. })
  226. require.NoError(t, err)
  227. p2Id, _ := p2Res.LastInsertId()
  228. t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id, p2Id) })
  229. logic := NewSyncPermsLogic(ctx, svcCtx)
  230. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  231. AppKey: appKey,
  232. AppSecret: appSecret,
  233. Perms: []types.SyncPermItem{},
  234. })
  235. require.NoError(t, err)
  236. require.NotNil(t, resp)
  237. assert.Equal(t, int64(0), resp.Added)
  238. assert.Equal(t, int64(0), resp.Updated)
  239. assert.Equal(t, int64(2), resp.Disabled)
  240. d1, err := svcCtx.SysPermModel.FindOne(ctx, p1Id)
  241. require.NoError(t, err)
  242. assert.Equal(t, int64(2), d1.Status)
  243. d2, err := svcCtx.SysPermModel.FindOne(ctx, p2Id)
  244. require.NoError(t, err)
  245. assert.Equal(t, int64(2), d2.Status)
  246. }
  247. // TC-0026: appKey无效
  248. func TestSyncPerms_InvalidAppKey(t *testing.T) {
  249. ctx := context.Background()
  250. svcCtx := newTestSvcCtx()
  251. logic := NewSyncPermsLogic(ctx, svcCtx)
  252. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  253. AppKey: "nonexistent_key_" + testutil.UniqueId(),
  254. AppSecret: "whatever",
  255. Perms: []types.SyncPermItem{{Code: "x", Name: "x"}},
  256. })
  257. require.Nil(t, resp)
  258. require.Error(t, err)
  259. var codeErr *response.CodeError
  260. require.True(t, errors.As(err, &codeErr))
  261. assert.Equal(t, 401, codeErr.Code())
  262. assert.Equal(t, "无效的appKey", codeErr.Error())
  263. }
  264. // TC-0027: appSecret错误
  265. func TestSyncPerms_WrongAppSecret(t *testing.T) {
  266. ctx := context.Background()
  267. svcCtx := newTestSvcCtx()
  268. pc := testutil.UniqueId()
  269. appKey := testutil.UniqueId()
  270. appSecret := testutil.UniqueId()
  271. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 1)
  272. t.Cleanup(cleanProduct)
  273. logic := NewSyncPermsLogic(ctx, svcCtx)
  274. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  275. AppKey: appKey,
  276. AppSecret: "wrong_secret",
  277. Perms: []types.SyncPermItem{{Code: "x", Name: "x"}},
  278. })
  279. require.Nil(t, resp)
  280. require.Error(t, err)
  281. var codeErr *response.CodeError
  282. require.True(t, errors.As(err, &codeErr))
  283. assert.Equal(t, 401, codeErr.Code())
  284. assert.Equal(t, "appSecret验证失败", codeErr.Error())
  285. }
  286. // TC-0028: 产品已禁用
  287. func TestSyncPerms_ProductDisabled(t *testing.T) {
  288. ctx := context.Background()
  289. svcCtx := newTestSvcCtx()
  290. pc := testutil.UniqueId()
  291. appKey := testutil.UniqueId()
  292. appSecret := testutil.UniqueId()
  293. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 2)
  294. t.Cleanup(cleanProduct)
  295. logic := NewSyncPermsLogic(ctx, svcCtx)
  296. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  297. AppKey: appKey,
  298. AppSecret: appSecret,
  299. Perms: []types.SyncPermItem{{Code: "x", Name: "x"}},
  300. })
  301. require.Nil(t, resp)
  302. require.Error(t, err)
  303. var codeErr *response.CodeError
  304. require.True(t, errors.As(err, &codeErr))
  305. assert.Equal(t, 403, codeErr.Code())
  306. assert.Equal(t, "产品已被禁用", codeErr.Error())
  307. }
  308. // TC-0029: 大批量(1000条)
  309. func TestSyncPerms_LargeBatch1000(t *testing.T) {
  310. ctx := context.Background()
  311. svcCtx := newTestSvcCtx()
  312. conn := testutil.GetTestSqlConn()
  313. pc := testutil.UniqueId()
  314. appKey := testutil.UniqueId()
  315. appSecret := testutil.UniqueId()
  316. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 1)
  317. t.Cleanup(cleanProduct)
  318. t.Cleanup(func() { testutil.CleanTableByField(ctx, conn, "`sys_perm`", "productCode", pc) })
  319. perms := make([]types.SyncPermItem, 1000)
  320. for i := 0; i < 1000; i++ {
  321. perms[i] = types.SyncPermItem{
  322. Code: fmt.Sprintf("batch_%s_%d", pc, i),
  323. Name: fmt.Sprintf("Perm_%d", i),
  324. }
  325. }
  326. logic := NewSyncPermsLogic(ctx, svcCtx)
  327. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  328. AppKey: appKey,
  329. AppSecret: appSecret,
  330. Perms: perms,
  331. })
  332. require.NoError(t, err)
  333. require.NotNil(t, resp)
  334. assert.Equal(t, int64(1000), resp.Added)
  335. assert.Equal(t, int64(0), resp.Updated)
  336. assert.Equal(t, int64(0), resp.Disabled)
  337. }
  338. // TC-0532: 重复code去重
  339. func TestSyncPerms_DeduplicateCodes(t *testing.T) {
  340. ctx := context.Background()
  341. svcCtx := newTestSvcCtx()
  342. conn := testutil.GetTestSqlConn()
  343. pc := testutil.UniqueId()
  344. appKey := testutil.UniqueId()
  345. appSecret := testutil.UniqueId()
  346. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 1)
  347. t.Cleanup(cleanProduct)
  348. t.Cleanup(func() { testutil.CleanTableByField(ctx, conn, "`sys_perm`", "productCode", pc) })
  349. logic := NewSyncPermsLogic(ctx, svcCtx)
  350. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  351. AppKey: appKey,
  352. AppSecret: appSecret,
  353. Perms: []types.SyncPermItem{
  354. {Code: "dup_code", Name: "Perm First"},
  355. {Code: "dup_code", Name: "Perm Duplicate"},
  356. {Code: "unique_code", Name: "Unique"},
  357. },
  358. })
  359. require.NoError(t, err)
  360. require.NotNil(t, resp)
  361. assert.Equal(t, int64(2), resp.Added, "重复code应被去重,只添加2条")
  362. }
  363. // TC-0025: 验证disabled返回值
  364. func TestSyncPerms_VerifyDisabledCount(t *testing.T) {
  365. ctx := context.Background()
  366. svcCtx := newTestSvcCtx()
  367. conn := testutil.GetTestSqlConn()
  368. pc := testutil.UniqueId()
  369. appKey := testutil.UniqueId()
  370. appSecret := testutil.UniqueId()
  371. now := time.Now().Unix()
  372. _, cleanProduct := insertSyncTestProduct(t, ctx, pc, appKey, appSecret, 1)
  373. t.Cleanup(cleanProduct)
  374. var permIds []int64
  375. for i := 0; i < 5; i++ {
  376. res, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
  377. ProductCode: pc, Name: fmt.Sprintf("p%d", i), Code: fmt.Sprintf("code_%s_%d", pc, i),
  378. Status: 1, CreateTime: now, UpdateTime: now,
  379. })
  380. require.NoError(t, err)
  381. id, _ := res.LastInsertId()
  382. permIds = append(permIds, id)
  383. }
  384. t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", permIds...) })
  385. logic := NewSyncPermsLogic(ctx, svcCtx)
  386. resp, err := logic.SyncPerms(&types.SyncPermsReq{
  387. AppKey: appKey,
  388. AppSecret: appSecret,
  389. Perms: []types.SyncPermItem{
  390. {Code: fmt.Sprintf("code_%s_0", pc), Name: "p0"},
  391. {Code: fmt.Sprintf("code_%s_1", pc), Name: "p1"},
  392. },
  393. })
  394. require.NoError(t, err)
  395. require.NotNil(t, resp)
  396. assert.Equal(t, int64(0), resp.Added)
  397. assert.Equal(t, int64(3), resp.Disabled)
  398. }