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:
2026-05-16 13:36:13 -04:00
parent e0a455466d
commit 003181ed41
2 changed files with 114 additions and 2 deletions
+77
View File
@@ -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