syncPermsLogic_test.go 14 KB

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