Add import_content_tree management command and import_tree helper for ADR-0004 sample trees. Document reichelag rehearsal lossiness; mark T02/T04 and the bubble exit workplan finished.
121 lines
3.9 KiB
Python
121 lines
3.9 KiB
Python
"""Import ADR-0004 tree into content plane (CSOC-WP-0001-T04 rehearsal path)."""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from django.core.management import call_command
|
|
|
|
from coulomb_social.apps.members.models import Member, User
|
|
from coulomb_social.apps.spaces import pageops
|
|
from coulomb_social.apps.spaces.content import load_space_page
|
|
from coulomb_social.apps.spaces.import_tree import import_space_tree
|
|
from coulomb_social.apps.spaces.models import Space, SpaceMembership
|
|
|
|
|
|
@pytest.fixture
|
|
def content_root(tmp_path, settings):
|
|
root = tmp_path / "content"
|
|
settings.CONTENT_ROOT = str(root)
|
|
return root
|
|
|
|
|
|
def _write_sample_tree(root: Path) -> Path:
|
|
tree = root / "sample-space"
|
|
pages = tree / "pages"
|
|
assets = tree / "assets"
|
|
pages.mkdir(parents=True)
|
|
assets.mkdir(parents=True)
|
|
(pages / "index.md").write_text(
|
|
"---\n"
|
|
'title: "Sample Space"\n'
|
|
'abstractor: "From export"\n'
|
|
'visual: ""\n'
|
|
'space: "sample-space"\n'
|
|
"bubble_type: space\n"
|
|
"---\n\n"
|
|
"# Sample Space\n\nLanding.\n",
|
|
encoding="utf-8",
|
|
)
|
|
(pages / "notes.md").write_text(
|
|
"---\n"
|
|
'title: "Notes"\n'
|
|
'abstractor: "Scratch"\n'
|
|
'visual: "assets/notes-visual.png"\n'
|
|
'space: "sample-space"\n'
|
|
"bubble_type: article\n"
|
|
"---\n\n"
|
|
"# Notes\n\nBody text.\n",
|
|
encoding="utf-8",
|
|
)
|
|
(assets / "notes-visual.png").write_bytes(b"\x89PNG\r\n")
|
|
return tree
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_import_space_tree(content_root, tmp_path):
|
|
tree = _write_sample_tree(tmp_path / "export")
|
|
user = User.objects.create_user(username="imp")
|
|
member = Member.objects.create(
|
|
tenant_id="tenant:a",
|
|
user=user,
|
|
user_engine_user_id="usr_imp",
|
|
issuer="https://local.dev/issuer",
|
|
subject="imp-sub",
|
|
display_name="Importer",
|
|
)
|
|
report = import_space_tree(
|
|
tree,
|
|
tenant_id="tenant:a",
|
|
member=member,
|
|
)
|
|
assert report.pages_copied == 2
|
|
assert report.assets_copied == 1
|
|
assert report.space_created
|
|
|
|
space = Space.objects.get(tenant_id="tenant:a", slug="sample-space")
|
|
assert space.title == "Sample Space"
|
|
assert space.description == "From export"
|
|
assert SpaceMembership.objects.filter(space=space, member=member).exists()
|
|
|
|
notes = pageops.read_page("sample-space", "notes")
|
|
assert notes.exists
|
|
assert notes.title == "Notes"
|
|
assert "Body text" in notes.body
|
|
assert (pageops.space_dir("sample-space") / "assets" / "notes-visual.png").is_file()
|
|
|
|
rendered = load_space_page(space, "notes")
|
|
assert rendered.error is None
|
|
assert rendered.source == "content-plane"
|
|
assert "Body text" in rendered.html
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_import_refuses_overwrite_without_replace(content_root, tmp_path):
|
|
tree = _write_sample_tree(tmp_path / "export")
|
|
import_space_tree(tree, tenant_id="tenant:a")
|
|
with pytest.raises(pageops.PageOpsError):
|
|
import_space_tree(tree, tenant_id="tenant:a", replace=False)
|
|
report = import_space_tree(tree, tenant_id="tenant:a", replace=True)
|
|
assert report.space_updated or report.space_created
|
|
assert report.pages_copied == 2
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_import_content_tree_command(content_root, tmp_path, capsys):
|
|
tree = _write_sample_tree(tmp_path / "export")
|
|
call_command("import_content_tree", str(tree), "--tenant", "tenant:cmd", "--dry-run")
|
|
out = capsys.readouterr().out
|
|
assert "Dry run" in out
|
|
assert not Space.objects.filter(slug="sample-space").exists()
|
|
|
|
call_command(
|
|
"import_content_tree",
|
|
str(tree),
|
|
"--tenant",
|
|
"tenant:cmd",
|
|
"--slug",
|
|
"cmd-space",
|
|
)
|
|
space = Space.objects.get(slug="cmd-space", tenant_id="tenant:cmd")
|
|
assert space.title == "Sample Space"
|
|
assert pageops.read_page("cmd-space", "index").exists
|