sysProductModel_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. package product
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "strings"
  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 newTestModel(t *testing.T) SysProductModel {
  16. t.Helper()
  17. return NewSysProductModel(
  18. testutil.GetTestSqlConn(),
  19. testutil.GetTestCacheConf(),
  20. testutil.GetTestCachePrefix(),
  21. )
  22. }
  23. func newSysProduct() *SysProduct {
  24. ts := time.Now().Unix()
  25. return &SysProduct{
  26. Code: testutil.UniqueId(),
  27. Name: "integration-product",
  28. AppKey: testutil.UniqueId(),
  29. AppSecret: "app-secret-" + testutil.UniqueId(),
  30. Remark: "remark",
  31. Status: 1,
  32. CreateTime: ts,
  33. UpdateTime: ts,
  34. }
  35. }
  36. // TC-0391: 正常分页
  37. func TestSysProductModel_Integration(t *testing.T) {
  38. ctx := context.Background()
  39. conn := testutil.GetTestSqlConn()
  40. m := newTestModel(t)
  41. t.Run("TableName", func(t *testing.T) {
  42. require.Equal(t, "`sys_product`", m.TableName())
  43. })
  44. t.Run("FindList_pagination", func(t *testing.T) {
  45. var beforeTotal int64
  46. _, beforeTotal, _ = m.FindList(ctx, 1, 1)
  47. const n = 5
  48. ids := make([]int64, 0, n)
  49. for i := 0; i < n; i++ {
  50. p := newSysProduct()
  51. p.Name = fmt.Sprintf("page-item-%d", i)
  52. res, err := m.Insert(ctx, p)
  53. require.NoError(t, err)
  54. id, err := res.LastInsertId()
  55. require.NoError(t, err)
  56. ids = append(ids, id)
  57. }
  58. defer func() {
  59. testutil.CleanTable(ctx, conn, "`sys_product`", ids...)
  60. }()
  61. expectedTotal := beforeTotal + int64(n)
  62. _, total, err := m.FindList(ctx, 1, 2)
  63. require.NoError(t, err)
  64. require.Equal(t, expectedTotal, total)
  65. var pageSize int64 = 2
  66. fullPages := expectedTotal / pageSize
  67. lastPageSize := expectedTotal % pageSize
  68. if lastPageSize > 0 {
  69. lastList, _, err := m.FindList(ctx, fullPages+1, pageSize)
  70. require.NoError(t, err)
  71. require.Len(t, lastList, int(lastPageSize))
  72. }
  73. })
  74. t.Run("CRUD_cycle", func(t *testing.T) {
  75. p := newSysProduct()
  76. p.Name = "crud-name"
  77. res, err := m.Insert(ctx, p)
  78. require.NoError(t, err)
  79. id, err := res.LastInsertId()
  80. require.NoError(t, err)
  81. defer testutil.CleanTable(ctx, conn, "`sys_product`", id)
  82. got, err := m.FindOne(ctx, id)
  83. require.NoError(t, err)
  84. require.Equal(t, id, got.Id)
  85. require.Equal(t, p.Code, got.Code)
  86. require.Equal(t, p.Name, got.Name)
  87. require.Equal(t, p.AppKey, got.AppKey)
  88. require.Equal(t, p.AppSecret, got.AppSecret)
  89. require.Equal(t, p.Remark, got.Remark)
  90. require.Equal(t, p.Status, got.Status)
  91. ts2 := time.Now().Unix()
  92. got.Name = "crud-name-updated"
  93. got.Remark = "updated-remark"
  94. got.Status = 2
  95. got.UpdateTime = ts2
  96. require.NoError(t, m.Update(ctx, got))
  97. after, err := m.FindOne(ctx, id)
  98. require.NoError(t, err)
  99. require.Equal(t, "crud-name-updated", after.Name)
  100. require.Equal(t, "updated-remark", after.Remark)
  101. require.Equal(t, int64(2), after.Status)
  102. require.Equal(t, ts2, after.UpdateTime)
  103. require.NoError(t, m.Delete(ctx, id))
  104. _, err = m.FindOne(ctx, id)
  105. require.ErrorIs(t, err, ErrNotFound)
  106. })
  107. t.Run("FindOneByAppKey_found_and_notFound", func(t *testing.T) {
  108. p := newSysProduct()
  109. res, err := m.Insert(ctx, p)
  110. require.NoError(t, err)
  111. id, err := res.LastInsertId()
  112. require.NoError(t, err)
  113. defer testutil.CleanTable(ctx, conn, "`sys_product`", id)
  114. got, err := m.FindOneByAppKey(ctx, p.AppKey)
  115. require.NoError(t, err)
  116. require.Equal(t, p.AppKey, got.AppKey)
  117. require.Equal(t, id, got.Id)
  118. _, err = m.FindOneByAppKey(ctx, "nonexistent-appkey-"+testutil.UniqueId())
  119. require.ErrorIs(t, err, ErrNotFound)
  120. })
  121. t.Run("FindOneByCode_found_and_notFound", func(t *testing.T) {
  122. p := newSysProduct()
  123. res, err := m.Insert(ctx, p)
  124. require.NoError(t, err)
  125. id, err := res.LastInsertId()
  126. require.NoError(t, err)
  127. defer testutil.CleanTable(ctx, conn, "`sys_product`", id)
  128. got, err := m.FindOneByCode(ctx, p.Code)
  129. require.NoError(t, err)
  130. require.Equal(t, p.Code, got.Code)
  131. require.Equal(t, id, got.Id)
  132. _, err = m.FindOneByCode(ctx, "nonexistent-code-"+testutil.UniqueId())
  133. require.ErrorIs(t, err, ErrNotFound)
  134. })
  135. t.Run("BatchInsert_and_BatchDelete", func(t *testing.T) {
  136. items := []*SysProduct{newSysProduct(), newSysProduct(), newSysProduct()}
  137. for i := range items {
  138. items[i].Name = fmt.Sprintf("batch-%d", i)
  139. }
  140. require.NoError(t, m.BatchInsert(ctx, items))
  141. var ids []int64
  142. for _, it := range items {
  143. row, err := m.FindOneByCode(ctx, it.Code)
  144. require.NoError(t, err)
  145. ids = append(ids, row.Id)
  146. }
  147. defer testutil.CleanTable(ctx, conn, "`sys_product`", ids...)
  148. require.NoError(t, m.BatchDelete(ctx, ids))
  149. for _, id := range ids {
  150. _, err := m.FindOne(ctx, id)
  151. require.ErrorIs(t, err, ErrNotFound)
  152. }
  153. })
  154. t.Run("TransactCtx_commit", func(t *testing.T) {
  155. p := newSysProduct()
  156. p.Name = "tx-commit"
  157. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  158. _, err := m.InsertWithTx(c, session, p)
  159. return err
  160. })
  161. require.NoError(t, err)
  162. row, err := m.FindOneByCode(ctx, p.Code)
  163. require.NoError(t, err)
  164. defer testutil.CleanTable(ctx, conn, "`sys_product`", row.Id)
  165. require.Equal(t, p.Code, row.Code)
  166. require.Equal(t, "tx-commit", row.Name)
  167. })
  168. t.Run("TransactCtx_rollback", func(t *testing.T) {
  169. p := newSysProduct()
  170. p.Name = "tx-rollback"
  171. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  172. if _, err := m.InsertWithTx(c, session, p); err != nil {
  173. return err
  174. }
  175. return fmt.Errorf("force rollback")
  176. })
  177. require.Error(t, err)
  178. _, err = m.FindOneByCode(ctx, p.Code)
  179. require.ErrorIs(t, err, ErrNotFound)
  180. })
  181. t.Run("Insert_duplicateCode", func(t *testing.T) {
  182. code := testutil.UniqueId()
  183. ts := time.Now().Unix()
  184. p1 := &SysProduct{
  185. Code: code,
  186. Name: "dup-a",
  187. AppKey: testutil.UniqueId(),
  188. AppSecret: "s1",
  189. Remark: "",
  190. Status: 1,
  191. CreateTime: ts,
  192. UpdateTime: ts,
  193. }
  194. res, err := m.Insert(ctx, p1)
  195. require.NoError(t, err)
  196. id1, err := res.LastInsertId()
  197. require.NoError(t, err)
  198. defer testutil.CleanTable(ctx, conn, "`sys_product`", id1)
  199. p2 := &SysProduct{
  200. Code: code,
  201. Name: "dup-b",
  202. AppKey: testutil.UniqueId(),
  203. AppSecret: "s2",
  204. Remark: "",
  205. Status: 1,
  206. CreateTime: ts,
  207. UpdateTime: ts,
  208. }
  209. _, err = m.Insert(ctx, p2)
  210. require.Error(t, err)
  211. var me *mysql.MySQLError
  212. require.True(t, errors.As(err, &me))
  213. require.Equal(t, uint16(1062), me.Number)
  214. })
  215. }
  216. // TC-0290: 记录不存在
  217. func TestSysProductModel_FindOne_NotFound(t *testing.T) {
  218. m := newTestModel(t)
  219. _, err := m.FindOne(context.Background(), 999999999999)
  220. require.ErrorIs(t, err, ErrNotFound)
  221. }
  222. // TC-0297: 记录不存在
  223. func TestSysProductModel_Update_NotFound(t *testing.T) {
  224. m := newTestModel(t)
  225. err := m.Update(context.Background(), &SysProduct{
  226. Id: 999999999999, Code: "x", Name: "n", AppKey: "k", AppSecret: "s",
  227. Status: 1, CreateTime: time.Now().Unix(), UpdateTime: time.Now().Unix(),
  228. })
  229. require.ErrorIs(t, err, ErrNotFound)
  230. }
  231. // TC-0300: 记录不存在
  232. func TestSysProductModel_Delete_NotFound(t *testing.T) {
  233. m := newTestModel(t)
  234. err := m.Delete(context.Background(), 999999999999)
  235. require.ErrorIs(t, err, ErrNotFound)
  236. }
  237. // TC-0305: 空列表
  238. func TestSysProductModel_BatchInsert_Empty(t *testing.T) {
  239. m := newTestModel(t)
  240. require.NoError(t, m.BatchInsert(context.Background(), nil))
  241. require.NoError(t, m.BatchInsert(context.Background(), []*SysProduct{}))
  242. }
  243. // TC-0324: 空ids
  244. func TestSysProductModel_BatchDelete_Empty(t *testing.T) {
  245. m := newTestModel(t)
  246. require.NoError(t, m.BatchDelete(context.Background(), nil))
  247. require.NoError(t, m.BatchDelete(context.Background(), []int64{}))
  248. }
  249. // TC-0298: 事务内更新
  250. func TestSysProductModel_UpdateWithTx(t *testing.T) {
  251. ctx := context.Background()
  252. conn := testutil.GetTestSqlConn()
  253. m := newTestModel(t)
  254. p := newSysProduct()
  255. res, err := m.Insert(ctx, p)
  256. require.NoError(t, err)
  257. id, err := res.LastInsertId()
  258. require.NoError(t, err)
  259. defer testutil.CleanTable(ctx, conn, m.TableName(), id)
  260. err = m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  261. p.Id = id
  262. p.Name = "tx_updated_name"
  263. p.UpdateTime = time.Now().Unix()
  264. return m.UpdateWithTx(c, session, p)
  265. })
  266. require.NoError(t, err)
  267. got, err := m.FindOne(ctx, id)
  268. require.NoError(t, err)
  269. require.Equal(t, "tx_updated_name", got.Name)
  270. }
  271. // TC-0301: 事务内删除
  272. func TestSysProductModel_DeleteWithTx(t *testing.T) {
  273. ctx := context.Background()
  274. conn := testutil.GetTestSqlConn()
  275. m := newTestModel(t)
  276. p := newSysProduct()
  277. res, err := m.Insert(ctx, p)
  278. require.NoError(t, err)
  279. id, err := res.LastInsertId()
  280. require.NoError(t, err)
  281. defer testutil.CleanTable(ctx, conn, m.TableName(), id)
  282. err = m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  283. return m.DeleteWithTx(c, session, id)
  284. })
  285. require.NoError(t, err)
  286. _, err = m.FindOne(ctx, id)
  287. require.ErrorIs(t, err, ErrNotFound)
  288. }
  289. // TC-0306: 单条记录
  290. func TestSysProductModel_BatchInsert_Single(t *testing.T) {
  291. ctx := context.Background()
  292. conn := testutil.GetTestSqlConn()
  293. m := newTestModel(t)
  294. p := newSysProduct()
  295. require.NoError(t, m.BatchInsert(ctx, []*SysProduct{p}))
  296. found, err := m.FindOneByCode(ctx, p.Code)
  297. require.NoError(t, err)
  298. defer testutil.CleanTable(ctx, conn, m.TableName(), found.Id)
  299. require.Equal(t, p.Code, found.Code)
  300. }
  301. // TC-0309: 唯一索引冲突
  302. func TestSysProductModel_BatchInsert_UniqueConflict(t *testing.T) {
  303. ctx := context.Background()
  304. conn := testutil.GetTestSqlConn()
  305. m := newTestModel(t)
  306. code := testutil.UniqueId()
  307. ts := time.Now().Unix()
  308. list := []*SysProduct{
  309. {Code: code, Name: "a", AppKey: testutil.UniqueId(), AppSecret: "s1", Status: 1, CreateTime: ts, UpdateTime: ts},
  310. {Code: code, Name: "b", AppKey: testutil.UniqueId(), AppSecret: "s2", Status: 1, CreateTime: ts, UpdateTime: ts},
  311. }
  312. err := m.BatchInsert(ctx, list)
  313. require.Error(t, err)
  314. t.Cleanup(func() {
  315. if found, e := m.FindOneByCode(ctx, code); e == nil {
  316. testutil.CleanTable(ctx, conn, m.TableName(), found.Id)
  317. }
  318. })
  319. var me *mysql.MySQLError
  320. require.True(t, errors.As(err, &me))
  321. require.Equal(t, uint16(1062), me.Number)
  322. }
  323. // TC-0314: 空列表
  324. func TestSysProductModel_BatchUpdate_Empty(t *testing.T) {
  325. m := newTestModel(t)
  326. require.NoError(t, m.BatchUpdate(context.Background(), nil))
  327. require.NoError(t, m.BatchUpdate(context.Background(), []*SysProduct{}))
  328. }
  329. // TC-0316: 多条记录(3条)
  330. func TestSysProductModel_BatchUpdate_Multi(t *testing.T) {
  331. ctx := context.Background()
  332. conn := testutil.GetTestSqlConn()
  333. m := newTestModel(t)
  334. p1 := newSysProduct()
  335. p2 := newSysProduct()
  336. r1, err := m.Insert(ctx, p1)
  337. require.NoError(t, err)
  338. id1, _ := r1.LastInsertId()
  339. r2, err := m.Insert(ctx, p2)
  340. require.NoError(t, err)
  341. id2, _ := r2.LastInsertId()
  342. defer testutil.CleanTable(ctx, conn, m.TableName(), id1, id2)
  343. now := time.Now().Unix()
  344. upd := []*SysProduct{
  345. {Id: id1, Code: p1.Code, Name: "upd1", AppKey: p1.AppKey, AppSecret: p1.AppSecret, Remark: "r1", Status: 1, CreateTime: p1.CreateTime, UpdateTime: now},
  346. {Id: id2, Code: p2.Code, Name: "upd2", AppKey: p2.AppKey, AppSecret: p2.AppSecret, Remark: "r2", Status: 2, CreateTime: p2.CreateTime, UpdateTime: now},
  347. }
  348. require.NoError(t, m.BatchUpdate(ctx, upd))
  349. g1, err := m.FindOne(ctx, id1)
  350. require.NoError(t, err)
  351. require.Equal(t, "upd1", g1.Name)
  352. g2, err := m.FindOne(ctx, id2)
  353. require.NoError(t, err)
  354. require.Equal(t, "upd2", g2.Name)
  355. require.Equal(t, int64(2), g2.Status)
  356. }
  357. // TC-0312: 正常多条
  358. func TestSysProductModel_BatchInsertWithTx_Normal(t *testing.T) {
  359. ctx := context.Background()
  360. conn := testutil.GetTestSqlConn()
  361. m := newTestModel(t)
  362. p1 := newSysProduct()
  363. p2 := newSysProduct()
  364. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  365. return m.BatchInsertWithTx(c, session, []*SysProduct{p1, p2})
  366. })
  367. require.NoError(t, err)
  368. f1, err := m.FindOneByCode(ctx, p1.Code)
  369. require.NoError(t, err)
  370. f2, err := m.FindOneByCode(ctx, p2.Code)
  371. require.NoError(t, err)
  372. defer testutil.CleanTable(ctx, conn, m.TableName(), f1.Id, f2.Id)
  373. require.Equal(t, p1.Code, f1.Code)
  374. require.Equal(t, p2.Code, f2.Code)
  375. }
  376. // TC-0311: 空列表
  377. func TestSysProductModel_BatchInsertWithTx_Empty(t *testing.T) {
  378. m := newTestModel(t)
  379. err := m.TransactCtx(context.Background(), func(c context.Context, session sqlx.Session) error {
  380. return m.BatchInsertWithTx(c, session, nil)
  381. })
  382. require.NoError(t, err)
  383. }
  384. // TC-0313: 事务回滚
  385. func TestSysProductModel_BatchInsertWithTx_Rollback(t *testing.T) {
  386. ctx := context.Background()
  387. m := newTestModel(t)
  388. p := newSysProduct()
  389. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  390. if e := m.BatchInsertWithTx(c, session, []*SysProduct{p}); e != nil {
  391. return e
  392. }
  393. return fmt.Errorf("force rollback")
  394. })
  395. require.Error(t, err)
  396. _, err = m.FindOneByCode(ctx, p.Code)
  397. require.ErrorIs(t, err, ErrNotFound)
  398. }
  399. // TC-0320: 正常多条
  400. func TestSysProductModel_BatchUpdateWithTx_Normal(t *testing.T) {
  401. ctx := context.Background()
  402. conn := testutil.GetTestSqlConn()
  403. m := newTestModel(t)
  404. p1 := newSysProduct()
  405. p2 := newSysProduct()
  406. r1, err := m.Insert(ctx, p1)
  407. require.NoError(t, err)
  408. id1, _ := r1.LastInsertId()
  409. r2, err := m.Insert(ctx, p2)
  410. require.NoError(t, err)
  411. id2, _ := r2.LastInsertId()
  412. defer testutil.CleanTable(ctx, conn, m.TableName(), id1, id2)
  413. now := time.Now().Unix()
  414. err = m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  415. return m.BatchUpdateWithTx(c, session, []*SysProduct{
  416. {Id: id1, Code: p1.Code, Name: "tx_upd1", AppKey: p1.AppKey, AppSecret: p1.AppSecret, Status: 1, CreateTime: p1.CreateTime, UpdateTime: now},
  417. {Id: id2, Code: p2.Code, Name: "tx_upd2", AppKey: p2.AppKey, AppSecret: p2.AppSecret, Status: 1, CreateTime: p2.CreateTime, UpdateTime: now},
  418. })
  419. })
  420. require.NoError(t, err)
  421. g1, err := m.FindOne(ctx, id1)
  422. require.NoError(t, err)
  423. require.Equal(t, "tx_upd1", g1.Name)
  424. g2, err := m.FindOne(ctx, id2)
  425. require.NoError(t, err)
  426. require.Equal(t, "tx_upd2", g2.Name)
  427. }
  428. // TC-0319: 空列表
  429. func TestSysProductModel_BatchUpdateWithTx_Empty(t *testing.T) {
  430. m := newTestModel(t)
  431. err := m.TransactCtx(context.Background(), func(c context.Context, session sqlx.Session) error {
  432. return m.BatchUpdateWithTx(c, session, nil)
  433. })
  434. require.NoError(t, err)
  435. }
  436. // TC-0325: 单个id
  437. func TestSysProductModel_BatchDelete_Single(t *testing.T) {
  438. ctx := context.Background()
  439. conn := testutil.GetTestSqlConn()
  440. m := newTestModel(t)
  441. p := newSysProduct()
  442. res, err := m.Insert(ctx, p)
  443. require.NoError(t, err)
  444. id, _ := res.LastInsertId()
  445. defer testutil.CleanTable(ctx, conn, m.TableName(), id)
  446. require.NoError(t, m.BatchDelete(ctx, []int64{id}))
  447. _, err = m.FindOne(ctx, id)
  448. require.ErrorIs(t, err, ErrNotFound)
  449. }
  450. // TC-0327: 包含不存在id
  451. func TestSysProductModel_BatchDelete_ContainsNonExist(t *testing.T) {
  452. ctx := context.Background()
  453. conn := testutil.GetTestSqlConn()
  454. m := newTestModel(t)
  455. p := newSysProduct()
  456. res, err := m.Insert(ctx, p)
  457. require.NoError(t, err)
  458. id, _ := res.LastInsertId()
  459. defer testutil.CleanTable(ctx, conn, m.TableName(), id)
  460. require.NoError(t, m.BatchDelete(ctx, []int64{id, 999999999}))
  461. _, err = m.FindOne(ctx, id)
  462. require.ErrorIs(t, err, ErrNotFound)
  463. }
  464. // TC-0329: 正常多条
  465. func TestSysProductModel_BatchDeleteWithTx_Normal(t *testing.T) {
  466. ctx := context.Background()
  467. conn := testutil.GetTestSqlConn()
  468. m := newTestModel(t)
  469. p1 := newSysProduct()
  470. p2 := newSysProduct()
  471. r1, err := m.Insert(ctx, p1)
  472. require.NoError(t, err)
  473. id1, _ := r1.LastInsertId()
  474. r2, err := m.Insert(ctx, p2)
  475. require.NoError(t, err)
  476. id2, _ := r2.LastInsertId()
  477. defer testutil.CleanTable(ctx, conn, m.TableName(), id1, id2)
  478. err = m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  479. return m.BatchDeleteWithTx(c, session, []int64{id1, id2})
  480. })
  481. require.NoError(t, err)
  482. _, err = m.FindOne(ctx, id1)
  483. require.ErrorIs(t, err, ErrNotFound)
  484. _, err = m.FindOne(ctx, id2)
  485. require.ErrorIs(t, err, ErrNotFound)
  486. }
  487. // TC-0328: 空ids
  488. func TestSysProductModel_BatchDeleteWithTx_Empty(t *testing.T) {
  489. m := newTestModel(t)
  490. err := m.TransactCtx(context.Background(), func(c context.Context, session sqlx.Session) error {
  491. return m.BatchDeleteWithTx(c, session, nil)
  492. })
  493. require.NoError(t, err)
  494. }
  495. // TC-0294: 事务内可见性
  496. func TestSysProductModel_FindOneWithTx_InsertThenFind(t *testing.T) {
  497. ctx := context.Background()
  498. conn := testutil.GetTestSqlConn()
  499. m := newTestModel(t)
  500. now := time.Now().Unix()
  501. var foundInTx *SysProduct
  502. var insertedId int64
  503. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  504. res, err := m.InsertWithTx(c, session, &SysProduct{
  505. Code: "ftx_code_" + testutil.UniqueId(),
  506. Name: "ftx_name_" + testutil.UniqueId(),
  507. AppKey: "ftx_ak_" + testutil.UniqueId(),
  508. AppSecret: "ftx_sec_" + testutil.UniqueId(),
  509. Remark: "",
  510. Status: 1,
  511. CreateTime: now,
  512. UpdateTime: now,
  513. })
  514. if err != nil {
  515. return err
  516. }
  517. insertedId, _ = res.LastInsertId()
  518. foundInTx, err = m.FindOneWithTx(c, session, insertedId)
  519. return err
  520. })
  521. require.NoError(t, err)
  522. t.Cleanup(func() { testutil.CleanTable(ctx, conn, m.TableName(), insertedId) })
  523. require.NotNil(t, foundInTx)
  524. assert.Equal(t, insertedId, foundInTx.Id)
  525. }
  526. // TC-0293: 事务内记录不存在
  527. func TestSysProductModel_FindOneWithTx_NotFound(t *testing.T) {
  528. ctx := context.Background()
  529. m := newTestModel(t)
  530. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  531. _, err := m.FindOneWithTx(c, session, 999999999999)
  532. return err
  533. })
  534. require.ErrorIs(t, err, ErrNotFound)
  535. }
  536. // TC-0336: FindOneByAppKeyWithTx
  537. func TestSysProductModel_FindOneByAppKeyWithTx_InsertThenFind(t *testing.T) {
  538. ctx := context.Background()
  539. conn := testutil.GetTestSqlConn()
  540. m := newTestModel(t)
  541. appKey := "ftx_ak_" + testutil.UniqueId()
  542. code := "ftx_code_" + testutil.UniqueId()
  543. now := time.Now().Unix()
  544. var foundByKey *SysProduct
  545. var insertedId int64
  546. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  547. res, err := m.InsertWithTx(c, session, &SysProduct{
  548. Code: code,
  549. Name: "ftx_name_" + testutil.UniqueId(),
  550. AppKey: appKey,
  551. AppSecret: "ftx_sec_" + testutil.UniqueId(),
  552. Remark: "",
  553. Status: 1,
  554. CreateTime: now,
  555. UpdateTime: now,
  556. })
  557. if err != nil {
  558. return err
  559. }
  560. insertedId, _ = res.LastInsertId()
  561. foundByKey, err = m.FindOneByAppKeyWithTx(c, session, appKey)
  562. return err
  563. })
  564. require.NoError(t, err)
  565. t.Cleanup(func() { testutil.CleanTable(ctx, conn, m.TableName(), insertedId) })
  566. require.NotNil(t, foundByKey)
  567. assert.Equal(t, insertedId, foundByKey.Id)
  568. assert.Equal(t, appKey, foundByKey.AppKey)
  569. }
  570. // TC-0337: FindOneByAppKeyWithTx
  571. func TestSysProductModel_FindOneByAppKeyWithTx_NotFound(t *testing.T) {
  572. ctx := context.Background()
  573. m := newTestModel(t)
  574. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  575. _, err := m.FindOneByAppKeyWithTx(c, session, "notexist_appkey_"+testutil.UniqueId())
  576. return err
  577. })
  578. require.ErrorIs(t, err, ErrNotFound)
  579. }
  580. // TC-0340: FindOneByCodeWithTx
  581. func TestSysProductModel_FindOneByCodeWithTx_InsertThenFind(t *testing.T) {
  582. ctx := context.Background()
  583. conn := testutil.GetTestSqlConn()
  584. m := newTestModel(t)
  585. code := "ftx_code_" + testutil.UniqueId()
  586. now := time.Now().Unix()
  587. var foundByCode *SysProduct
  588. var insertedId int64
  589. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  590. res, err := m.InsertWithTx(c, session, &SysProduct{
  591. Code: code,
  592. Name: "ftx_name_" + testutil.UniqueId(),
  593. AppKey: "ftx_ak_" + testutil.UniqueId(),
  594. AppSecret: "ftx_sec_" + testutil.UniqueId(),
  595. Remark: "",
  596. Status: 1,
  597. CreateTime: now,
  598. UpdateTime: now,
  599. })
  600. if err != nil {
  601. return err
  602. }
  603. insertedId, _ = res.LastInsertId()
  604. foundByCode, err = m.FindOneByCodeWithTx(c, session, code)
  605. return err
  606. })
  607. require.NoError(t, err)
  608. t.Cleanup(func() { testutil.CleanTable(ctx, conn, m.TableName(), insertedId) })
  609. require.NotNil(t, foundByCode)
  610. assert.Equal(t, insertedId, foundByCode.Id)
  611. assert.Equal(t, code, foundByCode.Code)
  612. }
  613. // TC-0341: FindOneByCodeWithTx
  614. func TestSysProductModel_FindOneByCodeWithTx_NotFound(t *testing.T) {
  615. ctx := context.Background()
  616. m := newTestModel(t)
  617. err := m.TransactCtx(ctx, func(c context.Context, session sqlx.Session) error {
  618. _, err := m.FindOneByCodeWithTx(c, session, "notexist_code_"+testutil.UniqueId())
  619. return err
  620. })
  621. require.ErrorIs(t, err, ErrNotFound)
  622. }
  623. // TC-0375: 多唯一索引前缀(SysProduct)
  624. func TestSysProductModel_CachePrefix_MultiUniqueIndex(t *testing.T) {
  625. oldId := cacheSysProductIdPrefix
  626. oldAppKey := cacheSysProductAppKeyPrefix
  627. oldCode := cacheSysProductCodePrefix
  628. defer func() {
  629. cacheSysProductIdPrefix = oldId
  630. cacheSysProductAppKeyPrefix = oldAppKey
  631. cacheSysProductCodePrefix = oldCode
  632. }()
  633. _ = newSysProductModel(testutil.GetTestSqlConn(), testutil.GetTestCacheConf(), "test")
  634. assert.True(t, strings.HasPrefix(cacheSysProductIdPrefix, "test:"))
  635. assert.True(t, strings.HasPrefix(cacheSysProductAppKeyPrefix, "test:"))
  636. assert.True(t, strings.HasPrefix(cacheSysProductCodePrefix, "test:"))
  637. }