mirror of
https://github.com/Such-Software/adaptive-multi-protocol-gateway.git
synced 2026-10-17 15:41:41 +02:00
Add Gemini renderer and semantic audit
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from ampg.audit import audit_gateway
|
||||
from ampg.config import load_config
|
||||
|
||||
|
||||
class AuditTest(unittest.TestCase):
|
||||
def test_reports_semantic_html_warnings(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
source = root / "source"
|
||||
source.mkdir()
|
||||
(source / "index.html").write_text(
|
||||
'<h1>Title</h1><h3>Skipped</h3><img src="x.png"><a href="page.html"></a>',
|
||||
encoding="utf-8",
|
||||
)
|
||||
config_path = root / "gateway.toml"
|
||||
config_path.write_text(
|
||||
"""
|
||||
[[site]]
|
||||
id = "example"
|
||||
domain = "example.test"
|
||||
|
||||
[site.source]
|
||||
kind = "static-html"
|
||||
path = "./source"
|
||||
|
||||
[site.outputs]
|
||||
root = "./out"
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
issues = audit_gateway(load_config(config_path))
|
||||
codes = {issue.code for issue in issues}
|
||||
|
||||
self.assertIn("heading_level_skip", codes)
|
||||
self.assertIn("missing_alt", codes)
|
||||
self.assertIn("empty_link_text", codes)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,70 @@
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from ampg.build import build_gateway
|
||||
from ampg.config import load_config
|
||||
from ampg.plan import plan_gateway, write_plan_artifacts
|
||||
|
||||
|
||||
class GeminiBuildTest(unittest.TestCase):
|
||||
def test_existing_html_source_can_build_only_gemini(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
source = root / "source"
|
||||
source.mkdir()
|
||||
(source / "index.html").write_text(
|
||||
'<h1>Home</h1><p><a href="about.html">About</a></p><script>bad()</script>',
|
||||
encoding="utf-8",
|
||||
)
|
||||
(source / "about.html").write_text("<h1>About</h1>", encoding="utf-8")
|
||||
(source / "app.js").write_text("bad()", encoding="utf-8")
|
||||
config_path = root / "gateway.toml"
|
||||
config_path.write_text(
|
||||
"""
|
||||
[[site]]
|
||||
id = "gemini_only"
|
||||
domain = "example.test"
|
||||
|
||||
[site.source]
|
||||
kind = "static-html"
|
||||
path = "./source"
|
||||
|
||||
[site.outputs]
|
||||
root = "./out"
|
||||
plan_root = "./plan"
|
||||
|
||||
[site.protocols.gemini]
|
||||
enabled = true
|
||||
renderer = "gemtext"
|
||||
daemon = "agate"
|
||||
daemon_policy = "auto"
|
||||
port = 1965
|
||||
max_asset_bytes = 1024
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
config = load_config(config_path)
|
||||
plan = plan_gateway(config)
|
||||
artifacts = write_plan_artifacts(config)
|
||||
results = build_gateway(config)
|
||||
|
||||
self.assertEqual([line.protocol for line in plan], ["gemini"])
|
||||
self.assertEqual([result.protocol for result in results], ["gemini"])
|
||||
self.assertEqual(len(artifacts), 1)
|
||||
self.assertTrue((root / "out/gemini/index.gmi").exists())
|
||||
self.assertTrue((root / "out/gemini/about.gmi").exists())
|
||||
self.assertFalse((root / "out/gemini/app.js").exists())
|
||||
self.assertFalse((root / "out/clearnet").exists())
|
||||
gemtext = (root / "out/gemini/index.gmi").read_text(encoding="utf-8")
|
||||
self.assertIn("# Home", gemtext)
|
||||
self.assertIn("=> about.gmi About", gemtext)
|
||||
self.assertNotIn("bad", gemtext)
|
||||
agate_plan = (root / "plan/gemini_only/gemini/agate-plan.txt").read_text()
|
||||
self.assertIn("daemon = agate", agate_plan)
|
||||
self.assertIn("content_root =", agate_plan)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,36 @@
|
||||
import unittest
|
||||
|
||||
from ampg.renderers import render_gemtext
|
||||
|
||||
|
||||
class GemtextRendererTest(unittest.TestCase):
|
||||
def test_converts_basic_html_to_gemtext(self):
|
||||
html = """
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head><script>ignored()</script></head>
|
||||
<body>
|
||||
<h1>Hello</h1>
|
||||
<p>Read the <a href="about.html">about page</a>.</p>
|
||||
<ul><li>One</li><li>Two</li></ul>
|
||||
<img src="logo.png" alt="Logo">
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
gemtext = render_gemtext(
|
||||
html,
|
||||
rewrite_link=lambda href: href.replace(".html", ".gmi"),
|
||||
)
|
||||
|
||||
self.assertIn("# Hello", gemtext)
|
||||
self.assertIn("Read the about page.", gemtext)
|
||||
self.assertIn("=> about.gmi about page", gemtext)
|
||||
self.assertIn("- One", gemtext)
|
||||
self.assertIn("- Two", gemtext)
|
||||
self.assertIn("=> logo.png Image: Logo", gemtext)
|
||||
self.assertNotIn("ignored", gemtext)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -44,6 +44,13 @@ daemon_policy = "auto"
|
||||
local_port = 19081
|
||||
keys_file = "example-web.dat"
|
||||
tunnel_name = "example-web"
|
||||
|
||||
[site.protocols.gemini]
|
||||
enabled = true
|
||||
renderer = "gemtext"
|
||||
daemon = "agate"
|
||||
daemon_policy = "auto"
|
||||
port = 1965
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
@@ -52,19 +59,21 @@ tunnel_name = "example-web"
|
||||
lines = plan_gateway(config)
|
||||
artifacts = write_plan_artifacts(config)
|
||||
|
||||
self.assertEqual(len(lines), 2)
|
||||
self.assertEqual(len(artifacts), 4)
|
||||
self.assertEqual(len(lines), 3)
|
||||
self.assertEqual(len(artifacts), 5)
|
||||
|
||||
torrc = root / "plan/example/tor/torrc-snippet.conf"
|
||||
tor_nginx = root / "plan/example/tor/nginx-loopback.conf"
|
||||
i2p_tunnel = root / "plan/example/i2p/i2pd-tunnel.conf"
|
||||
i2p_nginx = root / "plan/example/i2p/nginx-loopback.conf"
|
||||
agate_plan = root / "plan/example/gemini/agate-plan.txt"
|
||||
|
||||
self.assertIn("HiddenServicePort 80 127.0.0.1:19080", torrc.read_text())
|
||||
self.assertIn("listen 127.0.0.1:19080;", tor_nginx.read_text())
|
||||
self.assertIn("[example-web]", i2p_tunnel.read_text())
|
||||
self.assertIn("keys = example-web.dat", i2p_tunnel.read_text())
|
||||
self.assertIn("listen 127.0.0.1:19081;", i2p_nginx.read_text())
|
||||
self.assertIn("daemon = agate", agate_plan.read_text())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user