feat: support one Gitea organization per series
This commit is contained in:
@@ -175,6 +175,128 @@ class StemctlContractTests(unittest.TestCase):
|
||||
self.assertIn("runtime\tFAIL\tdocker is not supported", rendered)
|
||||
self.assertIn("rootless\tFAIL\trootless Podman is required", rendered)
|
||||
|
||||
def test_manifest_is_authoritative_and_maps_logical_series_directory(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = Path(temporary)
|
||||
workspace = root / "workspace"
|
||||
info = workspace / "meta" / "workspace-info"
|
||||
(info / "series").mkdir(parents=True)
|
||||
physical_series = workspace / "series" / "freertos"
|
||||
(physical_series / "card-one").mkdir(parents=True)
|
||||
(physical_series / "unregistered-extra").mkdir()
|
||||
(workspace / "series" / ".hidden").mkdir()
|
||||
source_series = root / "original" / "series" / "freertos"
|
||||
(source_series / "card-one").mkdir(parents=True)
|
||||
(info / "series" / "freertos-c.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"id": "freertos-c",
|
||||
"source_org": "edu-freertos-c",
|
||||
"workspace_dir": "freertos",
|
||||
"source_dir": "freertos",
|
||||
"cards": [{"id": "FC01", "repo": "card-one", "title": "First card"}],
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
(info / "workspace.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"organizations": [
|
||||
{"id": "edu", "role": "control-plane"},
|
||||
{"id": "edu-freertos-c", "role": "series", "series": ["freertos-c"]},
|
||||
],
|
||||
"series": [{"id": "freertos-c", "file": "series/freertos-c.json"}],
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
config_path = root / "config.json"
|
||||
config_path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"workspace_root": str(workspace),
|
||||
"original_root": str(root / "original"),
|
||||
"original_series_root": str(root / "original" / "series"),
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
config = rvctl.load_config(config_path)
|
||||
|
||||
series_output = io.StringIO()
|
||||
cards_output = io.StringIO()
|
||||
with redirect_stdout(series_output):
|
||||
rvctl.print_series(config)
|
||||
with redirect_stdout(cards_output):
|
||||
rvctl.print_cards(config, "freertos-c")
|
||||
|
||||
self.assertIn("freertos-c\t1\t1", series_output.getvalue())
|
||||
self.assertNotIn(".hidden", series_output.getvalue())
|
||||
self.assertIn("FC01\tcard-one\tworkspace\tFirst card", cards_output.getvalue())
|
||||
self.assertNotIn("unregistered-extra", cards_output.getvalue())
|
||||
self.assertEqual(rvctl.workspace_series_path(config, "freertos-c"), physical_series)
|
||||
self.assertEqual(rvctl.source_series_path(config, "freertos-c"), source_series)
|
||||
self.assertEqual(rvctl.resolve_card_info(config, "freertos-c", "FC01").repo, "card-one")
|
||||
|
||||
def test_workspace_catalog_audit_accepts_registered_series_org(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = Path(temporary)
|
||||
workspace = root / "workspace"
|
||||
info = workspace / "meta" / "workspace-info"
|
||||
info.mkdir(parents=True)
|
||||
(info / "workspace.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"organizations": [
|
||||
{"id": "edu", "role": "control-plane"},
|
||||
{"id": "edu-freertos-c", "role": "series", "series": ["freertos-c"]},
|
||||
],
|
||||
"series": [
|
||||
{
|
||||
"id": "freertos-c",
|
||||
"source_org": "edu-freertos-c",
|
||||
"cards": [{"id": "FC01", "repo": "card-one"}],
|
||||
}
|
||||
],
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
config_path = root / "config.json"
|
||||
config_path.write_text(
|
||||
json.dumps({"workspace_root": str(workspace), "original_root": str(root / "original")}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
config = rvctl.load_config(config_path)
|
||||
checks = rvctl.audit_workspace_catalog(config)
|
||||
self.assertFalse(any(status == "FAIL" for _, status, _ in checks), checks)
|
||||
self.assertIn(("series:freertos-c", "ok", "source_org=edu-freertos-c"), checks)
|
||||
|
||||
def test_workspace_catalog_audit_rejects_implicit_source_org(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = Path(temporary)
|
||||
workspace = root / "workspace"
|
||||
info = workspace / "meta" / "workspace-info"
|
||||
info.mkdir(parents=True)
|
||||
(info / "workspace.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"organizations": [{"id": "edu", "role": "control-plane"}],
|
||||
"series": [{"id": "freertos-c", "cards": [{"id": "FC01", "repo": "card-one"}]}],
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
config_path = root / "config.json"
|
||||
config_path.write_text(
|
||||
json.dumps({"workspace_root": str(workspace), "original_root": str(root / "original")}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
config = rvctl.load_config(config_path)
|
||||
checks = rvctl.audit_workspace_catalog(config)
|
||||
self.assertIn(("series:freertos-c", "FAIL", "missing explicit source_org"), checks)
|
||||
|
||||
def test_existing_legacy_workspace_is_detected(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = Path(temporary)
|
||||
|
||||
Reference in New Issue
Block a user