"""ยง22.13 / migration 028 โ€” the slug-keyed PK/UNIQUE rebuild that activates project #2. Proves two projects can hold the same slug, that (project_id, slug) is still unique within a project, that the rebuilt FK is composite + enforced, and that the no-foreign-keys migration runner left no dangling references.""" from __future__ import annotations import sqlite3 import tempfile from pathlib import Path import pytest from app import db class _Cfg: def __init__(self, path): self.database_path = path def _fresh_db(): d = tempfile.mkdtemp() path = Path(d) / "t.db" db.run_migrations(_Cfg(str(path))) return db.connect(str(path)) def _seed_two_projects(conn): for pid in ("default", "ecomm"): conn.execute( "INSERT OR IGNORE INTO projects (id, name, type, content_repo, visibility, initial_state) " "VALUES (?, ?, 'document', ?, 'public', 'super-draft')", (pid, pid.title(), pid + "-content"), ) def test_same_slug_coexists_across_projects(): conn = _fresh_db() _seed_two_projects(conn) for pid in ("default", "ecomm"): conn.execute( "INSERT INTO cached_rfcs (slug, title, state, project_id) " "VALUES ('intro', 'Intro', 'active', ?)", (pid,), ) rows = conn.execute( "SELECT project_id FROM cached_rfcs WHERE slug = 'intro' ORDER BY project_id" ).fetchall() assert [r["project_id"] for r in rows] == ["default", "ecomm"] def test_slug_still_unique_within_a_project(): conn = _fresh_db() _seed_two_projects(conn) conn.execute( "INSERT INTO cached_rfcs (slug, title, state, project_id) " "VALUES ('intro', 'Intro', 'active', 'default')" ) with pytest.raises(sqlite3.IntegrityError): conn.execute( "INSERT INTO cached_rfcs (slug, title, state, project_id) " "VALUES ('intro', 'Dup', 'active', 'default')" ) def test_rfc_collaborators_composite_fk_enforced(): conn = _fresh_db() _seed_two_projects(conn) conn.execute("INSERT INTO users (id, gitea_login, display_name, role) VALUES (1, 'a', 'A', 'contributor')") conn.execute( "INSERT INTO cached_rfcs (slug, title, state, project_id) " "VALUES ('intro', 'Intro', 'active', 'ecomm')" ) # Matching (project_id, slug) โ€” FK holds. conn.execute( "INSERT INTO rfc_collaborators (rfc_slug, user_id, role_in_rfc, project_id) " "VALUES ('intro', 1, 'contributor', 'ecomm')" ) # Same slug but a project with no such entry โ€” composite FK must reject. with pytest.raises(sqlite3.IntegrityError): conn.execute( "INSERT INTO rfc_collaborators (rfc_slug, user_id, role_in_rfc, project_id) " "VALUES ('intro', 1, 'contributor', 'default')" ) def test_stars_unique_now_scoped_by_project(): conn = _fresh_db() _seed_two_projects(conn) conn.execute("INSERT INTO users (id, gitea_login, display_name, role) VALUES (1, 'a', 'A', 'contributor')") # Same (user, slug) under two projects coexist; a duplicate within one rejects. conn.execute("INSERT INTO stars (user_id, rfc_slug, project_id) VALUES (1, 'intro', 'default')") conn.execute("INSERT INTO stars (user_id, rfc_slug, project_id) VALUES (1, 'intro', 'ecomm')") with pytest.raises(sqlite3.IntegrityError): conn.execute("INSERT INTO stars (user_id, rfc_slug, project_id) VALUES (1, 'intro', 'default')")