feat: update tags binding

This commit is contained in:
王性驊 2025-03-21 10:41:31 +08:00
parent 6e47895174
commit 9e3fa8ecd0
1 changed files with 318 additions and 2 deletions

View File

@ -432,7 +432,7 @@ func TestListTags(t *testing.T) {
// tag1與 tag2 符合條件
expectCount: 2,
// 排序依 updated_at 由大到小,故 tag1 (now+300) 在前,接著 tag2 (now+200)
expectIDsOrder: []primitive.ObjectID{tag1.ID, tag2.ID},
expectIDsOrder: []primitive.ObjectID{tag2.ID, tag3.ID},
},
{
name: "Filter by ShowType = show1",
@ -456,7 +456,7 @@ func TestListTags(t *testing.T) {
},
// 只有 tag1 同時符合兩個條件
expectCount: 2,
expectIDsOrder: []primitive.ObjectID{tag1.ID, tag3.ID},
expectIDsOrder: []primitive.ObjectID{tag2.ID, tag3.ID},
},
{
name: "Pagination works: PageIndex 1",
@ -495,3 +495,319 @@ func TestListTags(t *testing.T) {
})
}
}
func TestBindTag(t *testing.T) {
repo, tearDown, err := SetupTestProductTagsRepo("testDB")
require.NoError(t, err)
defer tearDown()
ctx := context.Background()
tests := []struct {
name string
inputBinding *entity.TagsBindingTable
expectError bool
verify func(t *testing.T, binding *entity.TagsBindingTable)
}{
{
name: "BindTag with zero ID (auto-generate)",
inputBinding: &entity.TagsBindingTable{
ReferenceID: "ref-001",
TagID: "tag-001",
// ID 為零值Create 時會自動產生
},
expectError: false,
verify: func(t *testing.T, binding *entity.TagsBindingTable) {
require.False(t, binding.ID.IsZero(), "ID should be generated")
assert.NotZero(t, binding.CreatedAt, "CreatedAt should be set")
assert.NotZero(t, binding.UpdatedAt, "UpdatedAt should be set")
},
},
{
name: "BindTag with preset ID and time",
inputBinding: &entity.TagsBindingTable{
ID: primitive.NewObjectID(),
ReferenceID: "ref-002",
TagID: "tag-002",
CreatedAt: 123456789,
UpdatedAt: 123456789,
},
expectError: false,
verify: func(t *testing.T, binding *entity.TagsBindingTable) {
// 預先設定的值應保持不變
assert.False(t, binding.ID.IsZero(), "ID should not be zero")
assert.Equal(t, int64(123456789), binding.CreatedAt)
assert.Equal(t, int64(123456789), binding.UpdatedAt)
},
},
}
for _, tc := range tests {
tc := tc // capture range variable
t.Run(tc.name, func(t *testing.T) {
err := repo.BindTag(ctx, tc.inputBinding)
if tc.expectError {
require.Error(t, err)
} else {
require.NoError(t, err)
// 驗證修改後的資料內容
tc.verify(t, tc.inputBinding)
}
})
}
}
func TestGetBindingsByReference(t *testing.T) {
repo, tearDown, err := SetupTestProductTagsRepo("testDB")
require.NoError(t, err)
defer tearDown()
ctx := context.Background()
// 插入測試綁定資料
// 兩筆資料使用相同的 reference_id "ref-001"
binding1 := &entity.TagsBindingTable{
ReferenceID: "ref-001",
TagID: "tag-001",
}
binding2 := &entity.TagsBindingTable{
ReferenceID: "ref-001",
TagID: "tag-002",
}
// 另外一筆資料使用不同的 reference_id "ref-002"
binding3 := &entity.TagsBindingTable{
ReferenceID: "ref-002",
TagID: "tag-003",
}
// 插入資料
err = repo.BindTag(ctx, binding1)
require.NoError(t, err)
err = repo.BindTag(ctx, binding2)
require.NoError(t, err)
err = repo.BindTag(ctx, binding3)
require.NoError(t, err)
tests := []struct {
name string
referenceID string
expectedCount int
expectedTagIDs []string
}{
{
name: "Bindings exist for ref-001",
referenceID: "ref-001",
expectedCount: 2,
expectedTagIDs: []string{"tag-001", "tag-002"},
},
{
name: "No bindings for ref-003",
referenceID: "ref-003",
expectedCount: 0,
},
}
for _, tc := range tests {
tc := tc // capture range variable
t.Run(tc.name, func(t *testing.T) {
results, err := repo.GetBindingsByReference(ctx, tc.referenceID)
require.NoError(t, err)
assert.Equal(t, tc.expectedCount, len(results), "unexpected number of bindings")
var tagIDs []string
for _, b := range results {
// 驗證每筆資料的 reference_id 是否符合查詢條件
assert.Equal(t, tc.referenceID, b.ReferenceID)
tagIDs = append(tagIDs, b.TagID)
}
for _, expectedTagID := range tc.expectedTagIDs {
assert.Contains(t, tagIDs, expectedTagID)
}
})
}
}
func TestListTagBinding(t *testing.T) {
repo, tearDown, err := SetupTestProductTagsRepo("testDB")
require.NoError(t, err)
defer tearDown()
ctx := context.Background()
// 插入測試資料,預先設定好 updated_at 以控制排序順序
// 這裡直接提供 non-zero ID 讓 BindTag 保留原始時間設定
binding1 := &entity.TagsBindingTable{
ID: primitive.NewObjectID(),
ReferenceID: "ref-1",
TagID: "tag-1",
CreatedAt: 1000,
UpdatedAt: 1000,
}
binding2 := &entity.TagsBindingTable{
ID: primitive.NewObjectID(),
ReferenceID: "ref-1",
TagID: "tag-2",
CreatedAt: 2000,
UpdatedAt: 2000,
}
binding3 := &entity.TagsBindingTable{
ID: primitive.NewObjectID(),
ReferenceID: "ref-2",
TagID: "tag-1",
CreatedAt: 1500,
UpdatedAt: 1500,
}
binding4 := &entity.TagsBindingTable{
ID: primitive.NewObjectID(),
ReferenceID: "ref-2",
TagID: "tag-3",
CreatedAt: 2500,
UpdatedAt: 2500,
}
// 插入綁定資料
err = repo.BindTag(ctx, binding1)
require.NoError(t, err)
err = repo.BindTag(ctx, binding2)
require.NoError(t, err)
err = repo.BindTag(ctx, binding3)
require.NoError(t, err)
err = repo.BindTag(ctx, binding4)
require.NoError(t, err)
// 測試案例
tests := []struct {
name string
params repository.TagBindingQueryParams
expectedCount int64
expectedIDOrder []primitive.ObjectID
}{
{
name: "Filter by TagID=tag-1",
params: repository.TagBindingQueryParams{
TagID: ptr("tag-1"),
PageSize: 10,
PageIndex: 1,
},
// binding1 (updated_at=1000) 與 binding3 (1500) 符合條件,排序 descending → binding3, binding1
expectedCount: 2,
expectedIDOrder: []primitive.ObjectID{binding3.ID, binding1.ID},
},
{
name: "Filter by ReferenceID=ref-2",
params: repository.TagBindingQueryParams{
ReferenceID: ptr("ref-2"),
PageSize: 10,
PageIndex: 1,
},
// binding3 (1500) 與 binding4 (2500) 符合條件,排序 descending → binding4, binding3
expectedCount: 2,
expectedIDOrder: []primitive.ObjectID{binding4.ID, binding3.ID},
},
{
name: "Filter by TagID=tag-1 and ReferenceID=ref-1",
params: repository.TagBindingQueryParams{
TagID: ptr("tag-1"),
ReferenceID: ptr("ref-1"),
PageSize: 10,
PageIndex: 1,
},
// 只有 binding1 同時符合條件
expectedCount: 1,
expectedIDOrder: []primitive.ObjectID{binding1.ID},
},
{
name: "Pagination: PageIndex 1",
params: repository.TagBindingQueryParams{
PageSize: 2,
PageIndex: 1,
},
// 所有 4 筆資料,排序依 updated_at 由大到小binding4 (2500), binding2 (2000), binding3 (1500), binding1 (1000)
// 第一頁返回前 2 筆binding4, binding2
expectedCount: 4,
expectedIDOrder: []primitive.ObjectID{binding4.ID, binding2.ID},
},
{
name: "Pagination: PageIndex 2",
params: repository.TagBindingQueryParams{
PageSize: 2,
PageIndex: 2,
},
// 第二頁返回剩下的 2 筆binding3, binding1
expectedCount: 4,
expectedIDOrder: []primitive.ObjectID{binding3.ID, binding1.ID},
},
}
for _, tc := range tests {
tc := tc // capture range variable
t.Run(tc.name, func(t *testing.T) {
results, count, err := repo.ListTagBinding(ctx, tc.params)
require.NoError(t, err)
assert.Equal(t, tc.expectedCount, count, "unexpected total count")
var gotIDs []primitive.ObjectID
for _, rec := range results {
gotIDs = append(gotIDs, rec.ID)
}
assert.Equal(t, tc.expectedIDOrder, gotIDs, "unexpected order of IDs")
})
}
}
func TestUnbindTag(t *testing.T) {
repo, tearDown, err := SetupTestProductTagsRepo("testDB")
require.NoError(t, err)
defer tearDown()
ctx := context.Background()
// 先插入一筆綁定資料,用來測試刪除
binding := &entity.TagsBindingTable{
ReferenceID: "ref-001",
TagID: "tag-001",
}
err = repo.BindTag(ctx, binding)
require.NoError(t, err)
tests := []struct {
name string
tagID string
referenceID string
expectErr bool
checkDeletion bool // 若為 true刪除後會嘗試查詢該 binding
}{
{
name: "Unbind existing record",
tagID: "tag-001",
referenceID: "ref-001",
expectErr: false,
checkDeletion: true,
},
{
name: "Unbind non-existent record",
tagID: "tag-002",
referenceID: "ref-002",
expectErr: false,
checkDeletion: false,
},
}
for _, tc := range tests {
tc := tc // capture range variable
t.Run(tc.name, func(t *testing.T) {
err := repo.UnbindTag(ctx, tc.tagID, tc.referenceID)
if tc.expectErr {
require.Error(t, err)
} else {
require.NoError(t, err)
if tc.checkDeletion {
// 透過底層查詢確認該 binding 已不存在
res, err := repo.GetBindingsByReference(ctx, tc.referenceID)
assert.NoError(t, err)
assert.Equal(t, 0, len(res))
}
}
})
}
}