Files
FabledCurator/tests/test_redate_images_migration.py
T
bvandeusenandClaude Opus 5.5 efcb548ebf
CI and images / lint (push) Successful in 3s
CI and images / extension-version (push) Successful in 3s
CI and images / extension-test (push) Successful in 19s
CI and images / frontend-build (push) Successful in 22s
CI and images / backend-lint-and-test (push) Successful in 33s
CI and images / integration (push) Successful in 2m22s
CI and images / sign-extension (push) Successful in 3s
CI and images / build-agent (push) Successful in 6s
CI and images / build-web (push) Successful in 1m40s
CI and images / smoke-web (push) Successful in 55s
CI and images / promote (push) Successful in 2s
fix: natively downloaded images take their post's date, not their download time (#4431)
The native ingesters (Discord, Patreon, SubscribeStar) import a post's
media before its record. Only the record (`_post.json`) carries the
date: the Discord message timestamp, or the Patreon/SubscribeStar
published_at. So each image was linked to a post with no date yet, and
it kept its download time in both gallery date columns. The post itself
was dated correctly once the record landed, but nothing went back to
update its images.

- upsert_post_record now re-dates the images already linked to the
  post. `effective_date` becomes the primary post's date, and
  `earliest_post_date` the earliest dated post the image is in, which
  are the same rules _attach_provenance applies.
- Migration 0113 repairs the library from the posts. It writes only
  rows that differ.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVjrnpQjRgHdvq95rASoiR
2026-09-25 09:30:17 -04:00

71 lines
2.4 KiB
Python

"""Migration 0113 (#4431): images linked to a post before its date arrived get
the post's date back. Runs the migration's data step against real rows."""
import importlib.util
from datetime import UTC, datetime
from pathlib import Path
import pytest
from backend.app.models import Artist, ImageProvenance, ImageRecord, Post
from tests.factories import make_image as _img
pytestmark = pytest.mark.integration
_MIGRATION = (
Path(__file__).resolve().parents[1]
/ "alembic" / "versions" / "0113_redate_native_images.py"
)
def _redate():
spec = importlib.util.spec_from_file_location("m0113", _MIGRATION)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod.redate_images
def _post(db, artist, epid, when):
p = Post(artist_id=artist.id, external_post_id=epid, post_date=when)
db.add(p)
db.flush()
return p
def _link(db, img, post, *, primary):
db.add(ImageProvenance(image_record_id=img.id, post_id=post.id))
if primary:
img.primary_post_id = post.id
db.flush()
def test_redate_images_from_their_posts(db_sync):
sent = datetime(2024, 3, 1, 18, 30, tzinfo=UTC)
earlier = datetime(2023, 1, 5, tzinfo=UTC)
artist = Artist(name="Alice", slug="alice")
db_sync.add(artist)
db_sync.flush()
undated = _post(db_sync, artist, "u1", None)
dated = _post(db_sync, artist, "d1", sent)
repost = _post(db_sync, artist, "r1", earlier)
stale = _img(db_sync, "a" * 64) # primary post dated, image not
reposted = _img(db_sync, "b" * 64) # also in an earlier post
orphan = _img(db_sync, "c" * 64) # only an undated post
_link(db_sync, stale, dated, primary=True)
_link(db_sync, reposted, dated, primary=True)
_link(db_sync, reposted, repost, primary=False)
_link(db_sync, orphan, undated, primary=True)
orphan_before = orphan.effective_date
_redate()(db_sync.connection())
db_sync.expire_all()
stale = db_sync.get(ImageRecord, stale.id)
reposted = db_sync.get(ImageRecord, reposted.id)
orphan = db_sync.get(ImageRecord, orphan.id)
assert stale.effective_date == sent
assert stale.earliest_post_date == sent
assert reposted.effective_date == sent # the primary post's date
assert reposted.earliest_post_date == earlier # the earliest post's date
assert orphan.effective_date == orphan_before # no date to take