"""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