"""The airport_hours table and its migration: one head, the chain, the shape the brief fixed.

The migration is schema only and was rehearsed up, down and up on `dfp_g` (a copy of the 11 Sep
nightly dump). This pins what a later edit could break without noticing: that the chain still has
one head, that the hours migration revises migration #4, and that the model carries exactly the
columns the airport page and the CLI rely on (`location_id`, `source_kind`, `entered_by_id`,
`observed_at`, `source_url`, `text`, `detail`, `created_at`).
"""

import pathlib

from alembic.config import Config
from alembic.script import ScriptDirectory

from app.models.hours import SOURCE_KINDS, AirportHours

MAIN = pathlib.Path(__file__).resolve().parents[1]
HOURS_REVISION = "c7d8e9f0a1b2"


def test_one_head_and_the_hours_migration_revises_the_accounts_one():
    script = ScriptDirectory.from_config(Config(str(MAIN / "alembic.ini")))
    assert len(script.get_heads()) == 1, script.get_heads()
    hours = script.get_revision(HOURS_REVISION)
    assert hours.down_revision == "b5c6d7e8f9a0"
    # The head is this revision or something that descends from it.
    lineage = {rev.revision for rev in script.iterate_revisions(script.get_heads()[0], "base")}
    assert HOURS_REVISION in lineage


def test_the_model_matches_the_migration():
    columns = {c.name: c for c in AirportHours.__table__.columns}
    assert set(columns) == {"id", "location_id", "source_kind", "entered_by_id", "observed_at", "source_url", "text", "detail", "created_at"}
    assert not columns["location_id"].nullable and columns["entered_by_id"].nullable
    assert not columns["observed_at"].nullable and not columns["text"].nullable
    assert columns["source_url"].nullable and columns["detail"].nullable
    assert {fk.target_fullname for fk in AirportHours.__table__.foreign_keys} == {"locations.id", "accounts.id"}
    assert SOURCE_KINDS == ("collected", "hand")
