feat(tags): merge repoints image_tag and tag_suggestion_rejection with dedup
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import pytest
|
||||
from sqlalchemy import select
|
||||
|
||||
from backend.app.models import Tag, TagKind, image_tag
|
||||
from backend.app.models.tag_allowlist import TagAllowlist
|
||||
@@ -129,3 +130,79 @@ async def test_merge_empty_tags_returns_result(db):
|
||||
assert result.alias_created is False
|
||||
assert result.source_deleted is True
|
||||
assert await db.get(Tag, a.id) is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_merge_moves_image_tags_and_counts(db):
|
||||
svc = TagService(db)
|
||||
a = await svc.find_or_create("SrcIT", TagKind.general)
|
||||
b = await svc.find_or_create("TgtIT", TagKind.general)
|
||||
i1, i2 = await _img(db), await _img(db)
|
||||
await svc.add_to_image(i1, a.id, source="manual")
|
||||
await svc.add_to_image(i2, a.id, source="manual")
|
||||
result = await svc.merge(a.id, b.id)
|
||||
assert result.merged_count == 2
|
||||
rows = (
|
||||
await db.execute(
|
||||
image_tag.select().where(image_tag.c.tag_id == b.id)
|
||||
)
|
||||
).all()
|
||||
assert {r.image_record_id for r in rows} == {i1, i2}
|
||||
assert (
|
||||
await db.execute(
|
||||
image_tag.select().where(image_tag.c.tag_id == a.id)
|
||||
)
|
||||
).first() is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_merge_dedups_image_tag_when_image_has_both(db):
|
||||
svc = TagService(db)
|
||||
a = await svc.find_or_create("SrcDup", TagKind.general)
|
||||
b = await svc.find_or_create("TgtDup", TagKind.general)
|
||||
img = await _img(db)
|
||||
await svc.add_to_image(img, a.id, source="manual")
|
||||
await svc.add_to_image(img, b.id, source="manual")
|
||||
result = await svc.merge(a.id, b.id)
|
||||
# The image already had the target → that source row is dropped, not moved.
|
||||
assert result.merged_count == 0
|
||||
rows = (
|
||||
await db.execute(
|
||||
image_tag.select().where(
|
||||
image_tag.c.image_record_id == img
|
||||
)
|
||||
)
|
||||
).all()
|
||||
assert [r.tag_id for r in rows] == [b.id]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_merge_dedups_suggestion_rejections(db):
|
||||
from backend.app.models.tag_suggestion_rejection import (
|
||||
TagSuggestionRejection,
|
||||
)
|
||||
|
||||
svc = TagService(db)
|
||||
a = await svc.find_or_create("SrcRej", TagKind.general)
|
||||
b = await svc.find_or_create("TgtRej", TagKind.general)
|
||||
i1, i2 = await _img(db), await _img(db)
|
||||
db.add(TagSuggestionRejection(image_record_id=i1, tag_id=a.id))
|
||||
db.add(TagSuggestionRejection(image_record_id=i2, tag_id=a.id))
|
||||
db.add(TagSuggestionRejection(image_record_id=i1, tag_id=b.id))
|
||||
await db.flush()
|
||||
await svc.merge(a.id, b.id)
|
||||
rej = (
|
||||
await db.execute(
|
||||
select(TagSuggestionRejection).where(
|
||||
TagSuggestionRejection.tag_id == b.id
|
||||
)
|
||||
)
|
||||
).scalars().all()
|
||||
assert {r.image_record_id for r in rej} == {i1, i2}
|
||||
assert (
|
||||
await db.execute(
|
||||
select(TagSuggestionRejection).where(
|
||||
TagSuggestionRejection.tag_id == a.id
|
||||
)
|
||||
)
|
||||
).first() is None
|
||||
|
||||
Reference in New Issue
Block a user