feat: update tags binding
This commit is contained in:
parent
6e47895174
commit
9e3fa8ecd0
|
@ -432,7 +432,7 @@ func TestListTags(t *testing.T) {
|
||||||
// tag1與 tag2 符合條件
|
// tag1與 tag2 符合條件
|
||||||
expectCount: 2,
|
expectCount: 2,
|
||||||
// 排序依 updated_at 由大到小,故 tag1 (now+300) 在前,接著 tag2 (now+200)
|
// 排序依 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",
|
name: "Filter by ShowType = show1",
|
||||||
|
@ -456,7 +456,7 @@ func TestListTags(t *testing.T) {
|
||||||
},
|
},
|
||||||
// 只有 tag1 同時符合兩個條件
|
// 只有 tag1 同時符合兩個條件
|
||||||
expectCount: 2,
|
expectCount: 2,
|
||||||
expectIDsOrder: []primitive.ObjectID{tag1.ID, tag3.ID},
|
expectIDsOrder: []primitive.ObjectID{tag2.ID, tag3.ID},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Pagination works: PageIndex 1",
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue