From 57bd0aa56a005d52e7f18d09e957ce88348bd179 Mon Sep 17 00:00:00 2001 From: Ang Hou Fu Date: Thu, 14 May 2026 22:54:31 +0800 Subject: [PATCH] feat: pass license, license_url, source, source_url through to per-resource table metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multi-source projects (e.g. a db collecting from 8 different agencies) need per-table licensing — the project-level license can only hold one value. Datasette's metadata format supports these fields at the table level; zeeker's datasette_fields allowlist simply didn't include them. Co-Authored-By: Claude Sonnet 4.6 --- packages/zeeker/tests/test_project.py | 48 +++++++++++++++++++++++++++ packages/zeeker/zeeker/core/types.py | 4 +++ 2 files changed, 52 insertions(+) diff --git a/packages/zeeker/tests/test_project.py b/packages/zeeker/tests/test_project.py index 67dd5d7..6b74ec2 100644 --- a/packages/zeeker/tests/test_project.py +++ b/packages/zeeker/tests/test_project.py @@ -731,4 +731,52 @@ def test_schema_conflict_error_message(self): assert "Schema conflict detected" in error_msg assert "Added columns: age, email" in error_msg assert "migrate_schema() function" in error_msg + + +class TestZeekerProjectToDatasette: + """Tests for ZeekerProject.to_datasette_metadata() table-level field pass-through.""" + + def test_per_resource_license_fields_in_table_metadata(self): + """Per-resource license and license_url must appear in the generated table metadata.""" + from zeeker.core.types import ZeekerProject + + project = ZeekerProject( + name="test", + database="test.db", + resources={ + "decisions": { + "description": "Enforcement decisions", + "license": "All rights reserved", + "license_url": "https://www.example.gov.sg/terms-of-use/", + "source": "Example Agency", + "source_url": "https://www.example.gov.sg/decisions/", + } + }, + ) + + metadata = project.to_datasette_metadata() + table = metadata["databases"]["test"]["tables"]["decisions"] + + assert table["license"] == "All rights reserved" + assert table["license_url"] == "https://www.example.gov.sg/terms-of-use/" + assert table["source"] == "Example Agency" + assert table["source_url"] == "https://www.example.gov.sg/decisions/" + + def test_per_resource_license_fields_optional(self): + """Resources without license fields should produce table metadata without them.""" + from zeeker.core.types import ZeekerProject + + project = ZeekerProject( + name="test", + database="test.db", + resources={"items": {"description": "Some items"}}, + ) + + metadata = project.to_datasette_metadata() + table = metadata["databases"]["test"]["tables"]["items"] + + assert "license" not in table + assert "license_url" not in table + assert "source" not in table + assert "source_url" not in table assert "--force-schema-reset" in error_msg diff --git a/packages/zeeker/zeeker/core/types.py b/packages/zeeker/zeeker/core/types.py index b109805..4996fa7 100644 --- a/packages/zeeker/zeeker/core/types.py +++ b/packages/zeeker/zeeker/core/types.py @@ -331,6 +331,10 @@ def to_datasette_metadata(self) -> dict[str, Any]: "label_column", "columns", "units", + "license", + "license_url", + "source", + "source_url", ] for field_name in datasette_fields: