95 lines
3.4 KiB
Python
95 lines
3.4 KiB
Python
"""§22.2 registry parse + apply: validation, type-immutability, upsert."""
|
|
from __future__ import annotations
|
|
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app import db, registry
|
|
from app.config import Config
|
|
|
|
|
|
def _db():
|
|
cfg = Config(
|
|
gitea_url="x", gitea_bot_user="x", gitea_bot_token="x", gitea_org="x",
|
|
meta_repo="meta", registry_repo="registry", oauth_client_id="x",
|
|
oauth_client_secret="x", app_url="x", secret_key="x",
|
|
database_path=Path(tempfile.mkdtemp(prefix="reg-")) / "t.db",
|
|
owner_gitea_login="x", webhook_secret="x",
|
|
)
|
|
db.run_migrations(cfg)
|
|
if db._CONN is not None:
|
|
db._CONN.close()
|
|
db._CONN = None
|
|
db.init(cfg)
|
|
return cfg
|
|
|
|
|
|
VALID = """
|
|
deployment:
|
|
name: Open Human Model
|
|
tagline: A model of human flourishing
|
|
projects:
|
|
- id: default
|
|
name: Open Human Model
|
|
type: document
|
|
content_repo: meta
|
|
visibility: public
|
|
"""
|
|
|
|
|
|
def test_parse_valid_registry():
|
|
doc = registry.parse_registry(VALID)
|
|
assert doc.deployment_name == "Open Human Model"
|
|
assert doc.deployment_tagline == "A model of human flourishing"
|
|
assert len(doc.projects) == 1
|
|
p = doc.projects[0]
|
|
assert (p.id, p.type, p.content_repo, p.visibility) == ("default", "document", "meta", "public")
|
|
assert p.initial_state == "super-draft"
|
|
|
|
|
|
def test_parse_initial_state_defaults_per_type():
|
|
doc = registry.parse_registry(
|
|
"projects:\n - {id: a, name: A, type: bdd, content_repo: a}\n"
|
|
)
|
|
assert doc.projects[0].initial_state == "active" # bdd default
|
|
|
|
|
|
@pytest.mark.parametrize("bad,msg", [
|
|
("projects: []\n", "at least one"),
|
|
("projects:\n - {id: 'Bad Slug', name: A, type: document, content_repo: a}\n", "valid slug"),
|
|
("projects:\n - {id: a, name: A, type: nope, content_repo: a}\n", "invalid type"),
|
|
("projects:\n - {id: a, name: A, type: document}\n", "content_repo"),
|
|
("projects:\n - {id: a, name: A, type: document, content_repo: a, visibility: x}\n", "visibility"),
|
|
("projects:\n - {id: a, name: A, type: document, content_repo: a}\n - {id: a, name: B, type: document, content_repo: b}\n", "duplicate"),
|
|
])
|
|
def test_parse_rejects_invalid(bad, msg):
|
|
with pytest.raises(registry.RegistryError) as e:
|
|
registry.parse_registry(bad)
|
|
assert msg in str(e.value)
|
|
|
|
|
|
def test_apply_upserts_projects_and_deployment():
|
|
_db()
|
|
doc = registry.parse_registry(VALID)
|
|
registry.apply_registry(doc, registry_sha="regsha1")
|
|
prow = db.conn().execute(
|
|
"SELECT name, type, content_repo, visibility, initial_state, registry_sha FROM projects WHERE id='default'"
|
|
).fetchone()
|
|
assert prow["name"] == "Open Human Model"
|
|
assert prow["content_repo"] == "meta"
|
|
assert prow["registry_sha"] == "regsha1"
|
|
drow = db.conn().execute("SELECT name, tagline FROM deployment WHERE id=1").fetchone()
|
|
assert drow["name"] == "Open Human Model"
|
|
assert drow["tagline"] == "A model of human flourishing"
|
|
|
|
|
|
def test_apply_rejects_type_change_on_existing_project():
|
|
_db()
|
|
registry.apply_registry(registry.parse_registry(VALID), "s1")
|
|
changed = VALID.replace("type: document", "type: specification")
|
|
registry.apply_registry(registry.parse_registry(changed), "s2") # logged + skipped, no raise
|
|
t = db.conn().execute("SELECT type FROM projects WHERE id='default'").fetchone()["type"]
|
|
assert t == "document" # immutable — unchanged
|