"""Tests for the Commons reference-board helper (stdlib only, no network).""" import json import unittest from pathlib import Path from tempfile import TemporaryDirectory from unittest import mock import refboard as rb class LicenceGateTests(unittest.TestCase): def test_committable_licences_pass(self): for licence in ("Public domain", "CC0", "CC BY 2.0", "CC BY 3.0", "CC BY 4.0"): clean, review = rb.normalise_licence(licence) self.assertEqual(clean, licence, licence) self.assertIsNone(review, licence) def test_ccbysa_is_research_only_by_default(self): clean, review = rb.normalise_licence("CC BY-SA 4.0") self.assertIsNone(clean) self.assertEqual(review, "CC BY-SA 4.0 (review)") def test_ccbysa_becomes_committable_only_with_the_flag(self): clean, review = rb.normalise_licence("CC BY-SA 3.0", allow_ccbysa=True) self.assertEqual(clean, "CC BY-SA 3.0 (review)") self.assertIsNone(review) def test_unknown_licence_is_never_committable(self): clean, review = rb.normalise_licence("Fair use") self.assertIsNone(clean) self.assertEqual(review, "Fair use") class SearchFilterTests(unittest.TestCase): @staticmethod def _row(title, licence="CC0", date="2026-09-30", width=1600): clean, review = rb.normalise_licence(licence) return {"title": title, "licence": licence, "clean": clean, "review": review, "date": date, "url": "https://example/" + title, "width": width, "artist": "a", "page": "p", "height": 1000, "description": "d", "credit": "", "licence_url": ""} def test_recent_and_usable_selection(self): # `d` is small-width (skipped); `c` is old but CC0, so it is usable and # sorted after the recent one; only `b` is review-only. rows = [self._row("a"), self._row("b", licence="CC BY-SA 4.0"), self._row("c", date="2015-01-01"), self._row("d", width=800)] with mock.patch.object(rb.Commons, "meta_for_titles", return_value={ r["title"]: r for r in rows}), \ mock.patch.object(rb, "collect", return_value=[r["title"] for r in rows]): args = mock.Mock(source="geo", query="34.1,-118.3", limit=10, months=12, min_width=1200, json=True, allow_ccbysa=False) with mock.patch("builtins.print") as printed: rb.cmd_search(args) payload = json.loads(printed.call_args[0][0]) usable = [r["title"] for r in payload if r["usable"]] review = [r["title"] for r in payload if r.get("research_only")] self.assertEqual(usable, ["a", "c"]) self.assertEqual(review, ["b"]) def test_dates_pull_the_first_iso_component(self): text = rb.Commons().meta_for_titles # method exists self.assertEqual(rb._age_months("2026-09-30", "2026-11-03"), 2) self.assertIsNone(rb._age_months("", "2026-11-03")) class FetchTests(unittest.TestCase): def test_fetch_skips_review_rows_unless_flagged(self): rows = [{"title": "File:Good.jpg", "usable": True, "url": "u1", "clean": "CC0", "licence": "CC0", "date": "2026-01-01"}, {"title": "File:ShareAlike.jpg", "usable": False, "research_only": True, "url": "u2", "clean": None, "review": "CC BY-SA 3.0 (review)", "licence": "CC BY-SA 3.0", "date": "2026-01-01"}] with TemporaryDirectory() as tmp: manifest = Path(tmp) / "meta.json" manifest.write_text(json.dumps(rows)) args = mock.Mock(manifest=str(manifest), dir=str(Path(tmp) / "out"), max=10, only_recent=False, force=True, include_review=False) with mock.patch.object(rb.Commons, "_get", return_value=b"png"): rb.cmd_fetch(args) names = sorted(p.name for p in (Path(tmp) / "out").iterdir()) self.assertEqual(names, ["Good.jpg", "meta.json"]) def test_rows_write_sidecar_and_readme_lines(self): rows = [{"title": "File:Some Photo.jpg", "usable": True, "date": "2026-05-01", "clean": "CC0", "licence": "CC0", "artist": "An Author", "page": "https://commons/x", "description": "A photo", "url": "u", "width": 1600, "height": 900, "review": None, "credit": "", "licence_url": ""}] with TemporaryDirectory() as tmp: manifest = Path(tmp) / "meta.json" manifest.write_text(json.dumps(rows)) args = mock.Mock(manifest=str(manifest), append_sidecar="") with mock.patch("builtins.print") as printed: self.assertEqual(rb.cmd_rows(args), 0) output = "\n".join(str(c[0][0]) for c in printed.call_args_list) self.assertIn("| `some-photo-2026-05-01.jpg` |", output) self.assertIn("![File:Some Photo.jpg](some-photo-2026-05-01.jpg)", output) if __name__ == "__main__": unittest.main()