from __future__ import annotations import sys from pathlib import Path import unittest from unittest.mock import patch from urllib.error import HTTPError sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts")) from project_sources import ( # noqa: E402 ProjectSourceError, RepositoryNotPublicError, append_fields, fetch_json, metadata_digest, parse_record, split_list, taxonomy_label_items, validate_image, validate_url, ) class ProjectSourceTests(unittest.TestCase): def test_registry_urls_must_be_public_https_without_credentials(self) -> None: self.assertEqual( validate_url("https://git.example.test/owner/repo.git", "repository"), "https://git.example.test/owner/repo.git", ) for value in ( "http://git.example.test/owner/repo.git", "https://token@git.example.test/owner/repo.git", "https://127.0.0.1/owner/repo.git", ): with self.subTest(value=value), self.assertRaises(ProjectSourceError): validate_url(value, "repository") def test_remote_comma_lists_become_lektor_multiline_values(self) -> None: fields = split_list("Tauri, React, Rust\nSQLite") rendered = append_fields(b"_model: project\n", {"technology_tags": fields}) self.assertIn(b"technology_tags:\n\nTauri\nReact\nRust\nSQLite\n", rendered) def test_metadata_digest_ignores_local_mirror_path(self) -> None: first = metadata_digest({"commit": "a" * 40, "mirror_path": "/one"}) second = metadata_digest({"commit": "a" * 40, "mirror_path": "/two"}) self.assertEqual(first, second) def test_image_extension_must_match_magic_bytes(self) -> None: with self.assertRaises(ProjectSourceError): validate_image("logo.png", b"not a png") def test_raw_html_is_rejected_from_remote_markdown(self) -> None: record = b"_model: devlog-entry\n---\nbody: \n" with self.assertRaises(ProjectSourceError): parse_record(record, ".labyricorn/devlog/example/contents.lr") def test_private_or_hidden_repository_response_is_fatal(self) -> None: error = HTTPError("https://git.example.test/api/repo", 404, "Not Found", {}, None) with patch("project_sources.urlopen", side_effect=error): with self.assertRaises(RepositoryNotPublicError): fetch_json("https://git.example.test/api/repo", require_public=True) def test_unapproved_labels_remain_visible_without_becoming_tags(self) -> None: items = taxonomy_label_items( ["TypeScript", "Unlisted Tool"], ["typescript"] ) self.assertEqual(items, ["typescript\tTypeScript", "-\tUnlisted Tool"]) if __name__ == "__main__": unittest.main()