Files
slack-sieve/tests/test_prepare_export.py
T
ilia 4b034d19f6
CI / skip-ci-check (push) Successful in 4s
CI / secret-scan (push) Failing after 2s
CI / python-ci (push) Successful in 25s
Add triage tests, prepare-export, and UI fixes for Levkin migration.
Cherry-pick heuristics, manifest merge, global file search, scrollbar styling, and pytest/Playwright coverage unblock review and filtered export for mmetl.
2026-06-03 15:42:48 -04:00

152 lines
4.5 KiB
Python

"""Tests that manifest selections produce a valid filtered Slack export."""
from __future__ import annotations
import json
import shutil
import sys
from pathlib import Path
import pytest
REPO = Path(__file__).resolve().parents[1]
def _load_prepare():
import importlib.util
path = REPO / "scripts" / "prepare-export.py"
spec = importlib.util.spec_from_file_location("prepare_export", path)
mod = importlib.util.module_from_spec(spec)
assert spec.loader
spec.loader.exec_module(mod)
return mod
@pytest.fixture
def prepare_mod():
return _load_prepare()
def test_channel_included_rules(prepare_mod):
assert prepare_mod.channel_included({"status": "import", "import_mode": "all"})
assert not prepare_mod.channel_included({"status": "skip"})
assert prepare_mod.channel_included(
{
"status": "partial",
"import_mode": "pick",
"messages": {"medical:1.0": {"action": "import", "checked": True}},
}
)
assert not prepare_mod.channel_included(
{"status": "partial", "import_mode": "pick", "messages": {}}
)
def test_message_and_files_filter(prepare_mod):
entry = {
"status": "partial",
"import_mode": "pick",
"messages": {
"ch:1000.1": {
"action": "import",
"files": {"F1": True, "F2": False},
}
},
}
assert prepare_mod.message_included(entry, "ch:1000.1")
assert not prepare_mod.message_included(entry, "ch:1000.2")
raw = {
"ts": "1000.1",
"text": "hi",
"files": [
{"id": "F1", "name": "a.pdf"},
{"id": "F2", "name": "b.pdf"},
],
}
out = prepare_mod.filter_files_on_message(entry, "ch:1000.1", raw)
assert len(out["files"]) == 1
assert out["files"][0]["id"] == "F1"
def test_prepare_export_writes_slack_shape(prepare_mod, fixture_export_path, tmp_path):
from slack_export import SlackExport
export = SlackExport(fixture_export_path)
msgs = export.iter_channel_messages("medical")
pick = msgs[0]
key = pick["id"]
manifest = {
"channels": {
"medical": {
"status": "partial",
"import_mode": "pick",
"import": True,
"messages": {key: {"action": "import", "checked": True, "files": {}}},
}
}
}
out = tmp_path / "prepared"
stats = prepare_mod.prepare_export(fixture_export_path, manifest, out, export_mod=export)
assert stats["medical"] == 1
assert (out / "channels.json").is_file()
assert (out / "users.json").is_file()
assert (out / "medical").is_dir()
day_files = list((out / "medical").glob("*.json"))
assert len(day_files) == 1
written = json.loads(day_files[0].read_text(encoding="utf-8"))
assert len(written) == 1
assert written[0]["ts"] == pick["ts"]
assert (out / "prepare-export-summary.json").is_file()
def test_prepare_whole_channel(prepare_mod, fixture_export_path, tmp_path):
from slack_export import SlackExport
export = SlackExport(fixture_export_path)
total = len(export.iter_channel_messages("medical"))
manifest = {
"channels": {
"medical": {
"status": "import",
"import_mode": "all",
"import": True,
"messages": {},
}
}
}
out = tmp_path / "prepared-all"
stats = prepare_mod.prepare_export(fixture_export_path, manifest, out, export_mod=export)
assert stats["medical"] == total
def test_prepare_skips_channel(prepare_mod, fixture_export_path, tmp_path):
from slack_export import SlackExport
export = SlackExport(fixture_export_path)
manifest = {
"channels": {
"medical": {"status": "skip", "import": False, "messages": {}},
"zoey": {
"status": "partial",
"import_mode": "pick",
"import": True,
"messages": {
export.iter_channel_messages("zoey")[0]["id"]: {
"action": "import",
"checked": True,
}
},
},
}
}
out = tmp_path / "prepared-skip"
stats = prepare_mod.prepare_export(fixture_export_path, manifest, out, export_mod=export)
assert "medical" not in stats
assert stats["zoey"] == 1
meta = json.loads((out / "channels.json").read_text(encoding="utf-8"))
names = {c["name"] for c in meta}
assert "medical" not in names
assert "zoey" in names