| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766 |
- package dept
- import (
- "context"
- "errors"
- "math"
- "testing"
- "time"
- "perms-system-server/internal/testutil"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "github.com/zeromicro/go-zero/core/stores/sqlx"
- )
- // TC-0310: 正常插入
- func TestSysDeptModel_CRUD(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- data := &SysDept{
- ParentId: 0,
- Name: "dept_crud_" + testutil.UniqueId(),
- Path: "/crud/" + testutil.UniqueId() + "/",
- Sort: 10,
- Remark: "r",
- Status: 1,
- CreateTime: now,
- UpdateTime: now,
- }
- res, err := m.Insert(ctx, data)
- require.NoError(t, err)
- id, err := res.LastInsertId()
- require.NoError(t, err)
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, id) })
- found, err := m.FindOne(ctx, id)
- require.NoError(t, err)
- require.NotNil(t, found)
- assert.Equal(t, id, found.Id)
- assert.Equal(t, data.Name, found.Name)
- found.Remark = "updated"
- found.UpdateTime = now + 1
- require.NoError(t, m.Update(ctx, found))
- after, err := m.FindOne(ctx, id)
- require.NoError(t, err)
- assert.Equal(t, "updated", after.Remark)
- require.NoError(t, m.Delete(ctx, id))
- _, err = m.FindOne(ctx, id)
- require.Error(t, err)
- assert.True(t, errors.Is(err, ErrNotFound))
- }
- // TC-0442: 正常查询
- func TestSysDeptModel_FindAll_OrderBySortAscIdAsc(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- base := testutil.UniqueId()
- now := time.Now().Unix()
- rows := []*SysDept{
- {ParentId: 0, Name: "a_" + base, Path: "/fa/" + base + "/a/", Sort: 30, Remark: "", Status: 1, CreateTime: now, UpdateTime: now},
- {ParentId: 0, Name: "b_" + base, Path: "/fa/" + base + "/b/", Sort: 10, Remark: "", Status: 1, CreateTime: now, UpdateTime: now},
- {ParentId: 0, Name: "c_" + base, Path: "/fa/" + base + "/c/", Sort: 20, Remark: "", Status: 1, CreateTime: now, UpdateTime: now},
- }
- require.NoError(t, m.BatchInsert(ctx, rows))
- prefix := "/fa/" + base
- byPath, err := m.FindByPathPrefix(ctx, prefix)
- require.NoError(t, err)
- require.Len(t, byPath, 3)
- ids := []int64{byPath[0].Id, byPath[1].Id, byPath[2].Id}
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, ids...) })
- all, err := m.FindAll(ctx)
- require.NoError(t, err)
- idSet := map[int64]struct{}{ids[0]: {}, ids[1]: {}, ids[2]: {}}
- var picked []*SysDept
- for i := range all {
- if _, ok := idSet[all[i].Id]; ok {
- picked = append(picked, all[i])
- }
- }
- require.Len(t, picked, 3)
- for i := 1; i < len(picked); i++ {
- prev, cur := picked[i-1], picked[i]
- if prev.Sort == cur.Sort {
- assert.Less(t, prev.Id, cur.Id)
- } else {
- assert.Less(t, prev.Sort, cur.Sort)
- }
- }
- assert.Equal(t, int64(10), picked[0].Sort)
- assert.Equal(t, int64(20), picked[1].Sort)
- assert.Equal(t, int64(30), picked[2].Sort)
- }
- // TC-0444: 正常查询
- func TestSysDeptModel_FindByParentId_FoundAndNotFound(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- parent := &SysDept{
- ParentId: 0,
- Name: "p_" + testutil.UniqueId(),
- Path: "/fp/" + testutil.UniqueId() + "/",
- Sort: 1,
- Remark: "",
- Status: 1,
- CreateTime: now,
- UpdateTime: now,
- }
- res, err := m.Insert(ctx, parent)
- require.NoError(t, err)
- pid, err := res.LastInsertId()
- require.NoError(t, err)
- child := &SysDept{
- ParentId: pid,
- Name: "c_" + testutil.UniqueId(),
- Path: parent.Path + "sub/",
- Sort: 1,
- Remark: "",
- Status: 1,
- CreateTime: now,
- UpdateTime: now,
- }
- cres, err := m.Insert(ctx, child)
- require.NoError(t, err)
- cid, err := cres.LastInsertId()
- require.NoError(t, err)
- tbl := m.TableName()
- t.Cleanup(func() {
- testutil.CleanTable(ctx, conn, tbl, cid, pid)
- })
- list, err := m.FindByParentId(ctx, pid)
- require.NoError(t, err)
- require.Len(t, list, 1)
- assert.Equal(t, cid, list[0].Id)
- empty, err := m.FindByParentId(ctx, math.MaxInt64)
- require.NoError(t, err)
- assert.Len(t, empty, 0)
- }
- // TC-0446: 正常查询
- func TestSysDeptModel_FindByPathPrefix_LikePrefix(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- pfx := "/pfx/" + testutil.UniqueId()
- d1 := &SysDept{ParentId: 0, Name: "n1_" + testutil.UniqueId(), Path: pfx + "/a/", Sort: 1, Remark: "", Status: 1, CreateTime: now, UpdateTime: now}
- d2 := &SysDept{ParentId: 0, Name: "n2_" + testutil.UniqueId(), Path: pfx + "/b/", Sort: 2, Remark: "", Status: 1, CreateTime: now, UpdateTime: now}
- other := &SysDept{ParentId: 0, Name: "o_" + testutil.UniqueId(), Path: "/other/" + testutil.UniqueId() + "/", Sort: 1, Remark: "", Status: 1, CreateTime: now, UpdateTime: now}
- r1, err := m.Insert(ctx, d1)
- require.NoError(t, err)
- id1, _ := r1.LastInsertId()
- r2, err := m.Insert(ctx, d2)
- require.NoError(t, err)
- id2, _ := r2.LastInsertId()
- r3, err := m.Insert(ctx, other)
- require.NoError(t, err)
- id3, _ := r3.LastInsertId()
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, id1, id2, id3) })
- list, err := m.FindByPathPrefix(ctx, pfx)
- require.NoError(t, err)
- require.Len(t, list, 2)
- names := map[string]struct{}{list[0].Name: {}, list[1].Name: {}}
- assert.Contains(t, names, d1.Name)
- assert.Contains(t, names, d2.Name)
- }
- // TC-0336: 多条记录(3条)
- func TestSysDeptModel_BatchInsert_BatchDelete(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- tag := testutil.UniqueId()
- batch := []*SysDept{
- {ParentId: 0, Name: "b1_" + tag, Path: "/bi/" + tag + "/1/", Sort: 1, Remark: "", Status: 1, CreateTime: now, UpdateTime: now},
- {ParentId: 0, Name: "b2_" + tag, Path: "/bi/" + tag + "/2/", Sort: 2, Remark: "", Status: 1, CreateTime: now, UpdateTime: now},
- }
- require.NoError(t, m.BatchInsert(ctx, batch))
- got, err := m.FindByPathPrefix(ctx, "/bi/"+tag)
- require.NoError(t, err)
- require.Len(t, got, 2)
- ids := []int64{got[0].Id, got[1].Id}
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, ids...) })
- require.NoError(t, m.BatchDelete(ctx, ids))
- for _, id := range ids {
- _, err := m.FindOne(ctx, id)
- require.Error(t, err)
- assert.True(t, errors.Is(err, ErrNotFound))
- }
- }
- // TC-0327: 事务内更新
- func TestSysDeptModel_TransactCtx_InsertWithTx_UpdateWithTx(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- d := &SysDept{
- ParentId: 0,
- Name: "tx_" + testutil.UniqueId(),
- Path: "/tx/" + testutil.UniqueId() + "/",
- Sort: 1,
- Remark: "before",
- Status: 1,
- CreateTime: now,
- UpdateTime: now,
- }
- var finalId int64
- err := m.TransactCtx(ctx, func(c context.Context, s sqlx.Session) error {
- res, err := m.InsertWithTx(c, s, d)
- if err != nil {
- return err
- }
- lid, err := res.LastInsertId()
- if err != nil {
- return err
- }
- finalId = lid
- d.Id = finalId
- d.Remark = "after_tx"
- d.UpdateTime = now + 2
- return m.UpdateWithTx(c, s, d)
- })
- require.NoError(t, err)
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, finalId) })
- out, err := m.FindOne(ctx, finalId)
- require.NoError(t, err)
- assert.Equal(t, "after_tx", out.Remark)
- }
- // TC-0333: 获取表名
- func TestSysDeptModel_TableName(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- assert.Equal(t, "`sys_dept`", m.TableName())
- }
- // TC-0319: 记录不存在
- func TestSysDeptModel_FindOne_NotFound(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- _, err := m.FindOne(context.Background(), 999999999999)
- require.ErrorIs(t, err, ErrNotFound)
- }
- // TC-0326: 记录不存在
- func TestSysDeptModel_Update_NonExistentRow_NoError(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- err := m.Update(context.Background(), &SysDept{
- Id: 999999999999, Name: "ghost", Path: "/x/", Status: 1,
- CreateTime: time.Now().Unix(), UpdateTime: time.Now().Unix(),
- })
- require.NoError(t, err)
- }
- // TC-0329: 记录不存在
- func TestSysDeptModel_Delete_NonExistentRow_NoError(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- err := m.Delete(context.Background(), 999999999999)
- require.NoError(t, err)
- }
- // TC-0334: 空列表
- func TestSysDeptModel_BatchInsert_Empty(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- require.NoError(t, m.BatchInsert(context.Background(), nil))
- require.NoError(t, m.BatchInsert(context.Background(), []*SysDept{}))
- }
- // TC-0353: 空ids
- func TestSysDeptModel_BatchDelete_Empty(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- require.NoError(t, m.BatchDelete(context.Background(), nil))
- require.NoError(t, m.BatchDelete(context.Background(), []int64{}))
- }
- // TC-0448: 无匹配
- func TestSysDeptModel_FindByPathPrefix_NoMatch(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- list, err := m.FindByPathPrefix(context.Background(), "/notexist_"+testutil.UniqueId())
- require.NoError(t, err)
- assert.Empty(t, list)
- }
- // TC-0316: 事务回滚后无数据
- func TestSysDeptModel_InsertWithTx_Rollback(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- path := "/txrb/" + testutil.UniqueId() + "/"
- d := &SysDept{
- ParentId: 0,
- Name: "txrb_" + testutil.UniqueId(),
- Path: path,
- Sort: 1,
- Status: 1,
- CreateTime: now,
- UpdateTime: now,
- }
- err := m.TransactCtx(ctx, func(c context.Context, s sqlx.Session) error {
- if _, e := m.InsertWithTx(c, s, d); e != nil {
- return e
- }
- return errors.New("force rollback")
- })
- require.Error(t, err)
- list, err := m.FindByPathPrefix(ctx, path)
- require.NoError(t, err)
- assert.Empty(t, list)
- }
- // TC-0330: 事务内删除
- func TestSysDeptModel_DeleteWithTx(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- d := &SysDept{
- ParentId: 0,
- Name: "deltx_" + testutil.UniqueId(),
- Path: "/deltx/" + testutil.UniqueId() + "/",
- Sort: 1,
- Status: 1,
- CreateTime: now,
- UpdateTime: now,
- }
- res, err := m.Insert(ctx, d)
- require.NoError(t, err)
- id, _ := res.LastInsertId()
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, id) })
- err = m.TransactCtx(ctx, func(c context.Context, s sqlx.Session) error {
- return m.DeleteWithTx(c, s, id)
- })
- require.NoError(t, err)
- _, err = m.FindOne(ctx, id)
- require.ErrorIs(t, err, ErrNotFound)
- }
- // TC-0332: fn返回错误
- func TestSysDeptModel_TransactCtx_Rollback(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- path := "/txrb2/" + testutil.UniqueId() + "/"
- d := &SysDept{
- ParentId: 0,
- Name: "txrb2_" + testutil.UniqueId(),
- Path: path,
- Sort: 1,
- Status: 1,
- CreateTime: now,
- UpdateTime: now,
- }
- err := m.TransactCtx(ctx, func(c context.Context, s sqlx.Session) error {
- if _, e := m.InsertWithTx(c, s, d); e != nil {
- return e
- }
- return errors.New("force rollback")
- })
- require.Error(t, err)
- require.Contains(t, err.Error(), "force rollback")
- list, err := m.FindByPathPrefix(ctx, path)
- require.NoError(t, err)
- assert.Empty(t, list)
- }
- // TC-0343: 空列表
- func TestSysDeptModel_BatchUpdate_Empty(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- require.NoError(t, m.BatchUpdate(context.Background(), nil))
- require.NoError(t, m.BatchUpdate(context.Background(), []*SysDept{}))
- }
- // TC-0345: 多条记录(3条)
- func TestSysDeptModel_BatchUpdate_Multi(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- tag := testutil.UniqueId()
- d1 := &SysDept{ParentId: 0, Name: "bu1_" + tag, Path: "/bu/" + tag + "/1/", Sort: 1, Remark: "r1", Status: 1, CreateTime: now, UpdateTime: now}
- d2 := &SysDept{ParentId: 0, Name: "bu2_" + tag, Path: "/bu/" + tag + "/2/", Sort: 2, Remark: "r2", Status: 1, CreateTime: now, UpdateTime: now}
- r1, err := m.Insert(ctx, d1)
- require.NoError(t, err)
- id1, _ := r1.LastInsertId()
- r2, err := m.Insert(ctx, d2)
- require.NoError(t, err)
- id2, _ := r2.LastInsertId()
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, id1, id2) })
- now2 := time.Now().Unix()
- upd := []*SysDept{
- {Id: id1, ParentId: 0, Name: "bu1_upd", Path: d1.Path, Sort: 10, Remark: "updated", Status: 1, CreateTime: now, UpdateTime: now2},
- {Id: id2, ParentId: 0, Name: "bu2_upd", Path: d2.Path, Sort: 20, Remark: "updated", Status: 2, CreateTime: now, UpdateTime: now2},
- }
- require.NoError(t, m.BatchUpdate(ctx, upd))
- g1, err := m.FindOne(ctx, id1)
- require.NoError(t, err)
- assert.Equal(t, "bu1_upd", g1.Name)
- assert.Equal(t, int64(10), g1.Sort)
- g2, err := m.FindOne(ctx, id2)
- require.NoError(t, err)
- assert.Equal(t, "bu2_upd", g2.Name)
- assert.Equal(t, int64(2), g2.Status)
- }
- // TC-0335: 单条记录
- func TestSysDeptModel_BatchInsert_Single(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- path := "/bis/" + testutil.UniqueId() + "/"
- d := &SysDept{ParentId: 0, Name: "bis_" + testutil.UniqueId(), Path: path, Sort: 1, Status: 1, CreateTime: now, UpdateTime: now}
- require.NoError(t, m.BatchInsert(ctx, []*SysDept{d}))
- list, err := m.FindByPathPrefix(ctx, path)
- require.NoError(t, err)
- require.Len(t, list, 1)
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, list[0].Id) })
- assert.Equal(t, d.Name, list[0].Name)
- }
- // TC-0341: 正常多条
- func TestSysDeptModel_BatchInsertWithTx_Normal(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- tag := testutil.UniqueId()
- batch := []*SysDept{
- {ParentId: 0, Name: "bitx1_" + tag, Path: "/bitx/" + tag + "/1/", Sort: 1, Status: 1, CreateTime: now, UpdateTime: now},
- {ParentId: 0, Name: "bitx2_" + tag, Path: "/bitx/" + tag + "/2/", Sort: 2, Status: 1, CreateTime: now, UpdateTime: now},
- }
- err := m.TransactCtx(ctx, func(c context.Context, s sqlx.Session) error {
- return m.BatchInsertWithTx(c, s, batch)
- })
- require.NoError(t, err)
- list, err := m.FindByPathPrefix(ctx, "/bitx/"+tag)
- require.NoError(t, err)
- require.Len(t, list, 2)
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, list[0].Id, list[1].Id) })
- }
- // TC-0340: 空列表
- func TestSysDeptModel_BatchInsertWithTx_Empty(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- err := m.TransactCtx(context.Background(), func(c context.Context, s sqlx.Session) error {
- return m.BatchInsertWithTx(c, s, nil)
- })
- require.NoError(t, err)
- }
- // TC-0342: 事务回滚
- func TestSysDeptModel_BatchInsertWithTx_Rollback(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- path := "/bitxrb/" + testutil.UniqueId() + "/"
- batch := []*SysDept{
- {ParentId: 0, Name: "rbn_" + testutil.UniqueId(), Path: path + "1/", Sort: 1, Status: 1, CreateTime: now, UpdateTime: now},
- }
- err := m.TransactCtx(ctx, func(c context.Context, s sqlx.Session) error {
- if e := m.BatchInsertWithTx(c, s, batch); e != nil {
- return e
- }
- return errors.New("force rollback")
- })
- require.Error(t, err)
- list, err := m.FindByPathPrefix(ctx, path)
- require.NoError(t, err)
- assert.Empty(t, list)
- }
- // TC-0349: 正常多条
- func TestSysDeptModel_BatchUpdateWithTx_Normal(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- tag := testutil.UniqueId()
- d1 := &SysDept{ParentId: 0, Name: "butx1_" + tag, Path: "/butx/" + tag + "/1/", Sort: 1, Remark: "old", Status: 1, CreateTime: now, UpdateTime: now}
- d2 := &SysDept{ParentId: 0, Name: "butx2_" + tag, Path: "/butx/" + tag + "/2/", Sort: 2, Remark: "old", Status: 1, CreateTime: now, UpdateTime: now}
- r1, err := m.Insert(ctx, d1)
- require.NoError(t, err)
- id1, _ := r1.LastInsertId()
- r2, err := m.Insert(ctx, d2)
- require.NoError(t, err)
- id2, _ := r2.LastInsertId()
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, id1, id2) })
- now2 := time.Now().Unix()
- err = m.TransactCtx(ctx, func(c context.Context, s sqlx.Session) error {
- return m.BatchUpdateWithTx(c, s, []*SysDept{
- {Id: id1, ParentId: 0, Name: "butx1_new", Path: d1.Path, Sort: 10, Remark: "new", Status: 1, CreateTime: now, UpdateTime: now2},
- {Id: id2, ParentId: 0, Name: "butx2_new", Path: d2.Path, Sort: 20, Remark: "new", Status: 1, CreateTime: now, UpdateTime: now2},
- })
- })
- require.NoError(t, err)
- g1, err := m.FindOne(ctx, id1)
- require.NoError(t, err)
- assert.Equal(t, "butx1_new", g1.Name)
- assert.Equal(t, int64(10), g1.Sort)
- g2, err := m.FindOne(ctx, id2)
- require.NoError(t, err)
- assert.Equal(t, "butx2_new", g2.Name)
- }
- // TC-0348: 空列表
- func TestSysDeptModel_BatchUpdateWithTx_Empty(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- err := m.TransactCtx(context.Background(), func(c context.Context, s sqlx.Session) error {
- return m.BatchUpdateWithTx(c, s, nil)
- })
- require.NoError(t, err)
- }
- // TC-0354: 单个id
- func TestSysDeptModel_BatchDelete_Single(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- d := &SysDept{ParentId: 0, Name: "bds_" + testutil.UniqueId(), Path: "/bds/" + testutil.UniqueId() + "/", Sort: 1, Status: 1, CreateTime: now, UpdateTime: now}
- res, err := m.Insert(ctx, d)
- require.NoError(t, err)
- id, _ := res.LastInsertId()
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, id) })
- require.NoError(t, m.BatchDelete(ctx, []int64{id}))
- _, err = m.FindOne(ctx, id)
- require.ErrorIs(t, err, ErrNotFound)
- }
- // TC-0356: 包含不存在id
- func TestSysDeptModel_BatchDelete_ContainsNonExist(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- d := &SysDept{ParentId: 0, Name: "bdne_" + testutil.UniqueId(), Path: "/bdne/" + testutil.UniqueId() + "/", Sort: 1, Status: 1, CreateTime: now, UpdateTime: now}
- res, err := m.Insert(ctx, d)
- require.NoError(t, err)
- id, _ := res.LastInsertId()
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, id) })
- require.NoError(t, m.BatchDelete(ctx, []int64{id, 999999999}))
- _, err = m.FindOne(ctx, id)
- require.ErrorIs(t, err, ErrNotFound)
- }
- // TC-0358: 正常多条
- func TestSysDeptModel_BatchDeleteWithTx_Normal(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- tag := testutil.UniqueId()
- d1 := &SysDept{ParentId: 0, Name: "bdtx1_" + tag, Path: "/bdtx/" + tag + "/1/", Sort: 1, Status: 1, CreateTime: now, UpdateTime: now}
- d2 := &SysDept{ParentId: 0, Name: "bdtx2_" + tag, Path: "/bdtx/" + tag + "/2/", Sort: 2, Status: 1, CreateTime: now, UpdateTime: now}
- r1, err := m.Insert(ctx, d1)
- require.NoError(t, err)
- id1, _ := r1.LastInsertId()
- r2, err := m.Insert(ctx, d2)
- require.NoError(t, err)
- id2, _ := r2.LastInsertId()
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, id1, id2) })
- err = m.TransactCtx(ctx, func(c context.Context, s sqlx.Session) error {
- return m.BatchDeleteWithTx(c, s, []int64{id1, id2})
- })
- require.NoError(t, err)
- _, err = m.FindOne(ctx, id1)
- require.ErrorIs(t, err, ErrNotFound)
- _, err = m.FindOne(ctx, id2)
- require.ErrorIs(t, err, ErrNotFound)
- }
- // TC-0357: 空ids
- func TestSysDeptModel_BatchDeleteWithTx_Empty(t *testing.T) {
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- err := m.TransactCtx(context.Background(), func(c context.Context, s sqlx.Session) error {
- return m.BatchDeleteWithTx(c, s, nil)
- })
- require.NoError(t, err)
- }
- // TC-0447: LIKE注入已修复 — % 和 _ 被转义,不再作为通配符
- func TestSysDeptModel_FindByPathPrefix_LikeInjection(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- d := &SysDept{ParentId: 0, Name: "li_" + testutil.UniqueId(), Path: "/test/", Sort: 1, Status: 1, CreateTime: now, UpdateTime: now}
- res, err := m.Insert(ctx, d)
- require.NoError(t, err)
- id, _ := res.LastInsertId()
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, id) })
- list, err := m.FindByPathPrefix(ctx, "%")
- require.NoError(t, err)
- assert.Empty(t, list, "% 不应再作为通配符匹配所有记录")
- list2, err := m.FindByPathPrefix(ctx, "/test/")
- require.NoError(t, err)
- assert.GreaterOrEqual(t, len(list2), 1, "正常前缀仍应匹配")
- }
- // TC-0323: 事务内可见性
- func TestSysDeptModel_FindOneWithTx_InsertThenFind(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- var foundInTx *SysDept
- var insertedId int64
- err := m.TransactCtx(ctx, func(c context.Context, s sqlx.Session) error {
- res, err := m.InsertWithTx(c, s, &SysDept{
- ParentId: 0, Name: "ftx_" + testutil.UniqueId(), Path: "/ftx/" + testutil.UniqueId() + "/",
- Sort: 1, DeptType: "NORMAL", Status: 1, CreateTime: now, UpdateTime: now,
- })
- if err != nil {
- return err
- }
- insertedId, _ = res.LastInsertId()
- foundInTx, err = m.FindOneWithTx(c, s, insertedId)
- return err
- })
- require.NoError(t, err)
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, insertedId) })
- require.NotNil(t, foundInTx)
- assert.Equal(t, insertedId, foundInTx.Id)
- }
- // TC-0322: 事务内记录不存在
- func TestSysDeptModel_FindOneWithTx_NotFound(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- err := m.TransactCtx(ctx, func(c context.Context, s sqlx.Session) error {
- _, err := m.FindOneWithTx(c, s, 999999999999)
- return err
- })
- require.ErrorIs(t, err, ErrNotFound)
- }
- // TC-0445: FindByParentId 无子部门
- func TestSysDeptModel_FindByParentId_NoChildren(t *testing.T) {
- ctx := context.Background()
- conn := testutil.GetTestSqlConn()
- m := NewSysDeptModel(conn, testutil.GetTestCacheConf(), testutil.GetTestCachePrefix())
- now := time.Now().Unix()
- parent := &SysDept{
- ParentId: 0,
- Name: "nochild_" + testutil.UniqueId(),
- Path: "/nochild/" + testutil.UniqueId() + "/",
- Sort: 1,
- Status: 1,
- CreateTime: now,
- UpdateTime: now,
- }
- res, err := m.Insert(ctx, parent)
- require.NoError(t, err)
- pid, err := res.LastInsertId()
- require.NoError(t, err)
- tbl := m.TableName()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, tbl, pid) })
- list, err := m.FindByParentId(ctx, pid)
- require.NoError(t, err)
- require.Empty(t, list)
- }
|