[RELEASE] RexiMemo: Open Source Edition
This commit is contained in:
1 parent
5e2acc31c5
commit
a438dfc231
45 files changed
+8516
-169
No files matched your search
@@ -0,0 +1,42 @@
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from database import DatabaseBackend
|
||||
|
||||
|
||||
class DatabaseTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.temp = tempfile.TemporaryDirectory()
|
||||
self.db = DatabaseBackend(Path(self.temp.name) / "test.sqlite3")
|
||||
|
||||
def tearDown(self):
|
||||
self.db.close()
|
||||
self.temp.cleanup()
|
||||
|
||||
def test_default_admin(self):
|
||||
account = self.db.verify_account("reximemo", "alpine")
|
||||
self.assertIsNotNone(account)
|
||||
self.assertEqual(account["is_admin"], 1)
|
||||
|
||||
def test_ip_login_and_logout(self):
|
||||
aid = self.db.create_account("tester", "pass")
|
||||
self.db.login_ip("192.0.2.10", aid)
|
||||
self.assertEqual(self.db.account_for_ip("192.0.2.10")["username"], "tester")
|
||||
self.db.logout_ip("192.0.2.10")
|
||||
self.assertIsNone(self.db.account_for_ip("192.0.2.10"))
|
||||
|
||||
def test_guest_room_is_stable_per_ip(self):
|
||||
first = self.db.get_or_create_creator("192.0.2.20", fsid="A000000000000010", display_name="Guest")
|
||||
second = self.db.get_or_create_creator("192.0.2.20", fsid="A000000000000011", display_name="Other")
|
||||
self.assertEqual(first["id"], second["id"])
|
||||
|
||||
def test_ip_ban(self):
|
||||
self.db.ban_ip("192.0.2.30", "test")
|
||||
self.assertTrue(self.db.is_ip_banned("192.0.2.30"))
|
||||
self.db.unban_ip("192.0.2.30")
|
||||
self.assertFalse(self.db.is_ip_banned("192.0.2.30"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,46 @@
|
||||
import os
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class ReleaseShapeTests(unittest.TestCase):
|
||||
def test_no_secret_or_font_files(self):
|
||||
blocked_ext = {".pem", ".key", ".crt", ".p12", ".pfx", ".ttf", ".otf", ".woff", ".woff2"}
|
||||
bad = []
|
||||
for path in ROOT.rglob("*"):
|
||||
if path.is_file() and path.suffix.lower() in blocked_ext:
|
||||
bad.append(str(path.relative_to(ROOT)))
|
||||
self.assertEqual(bad, [])
|
||||
|
||||
def test_removed_production_components_are_absent(self):
|
||||
for name in ["discord_bot.py", "network_services.py", "ssl3_compat.py", "packet_capture.py", "ppmverify.py", "fnkey.pem", "token.txt"]:
|
||||
self.assertFalse((ROOT / name).exists(), name)
|
||||
|
||||
def test_exactly_three_sample_flipnotes(self):
|
||||
samples = list((ROOT / "database" / "Creators").glob("*/*.ppm"))
|
||||
self.assertEqual(len(samples), 3)
|
||||
|
||||
def test_github_docs_copy_and_connection_guidance(self):
|
||||
docs = (ROOT / "DOCS.md").read_text()
|
||||
self.assertIn("official RexiMemo DNS service", docs)
|
||||
self.assertIn("Proxy Server", docs)
|
||||
self.assertIn("port to `8080`", docs)
|
||||
self.assertIn("release-safety boundary", docs)
|
||||
self.assertIn("Account security notice", docs)
|
||||
self.assertIn("IP login notice", docs)
|
||||
|
||||
def test_ose_web_branding(self):
|
||||
logo = ROOT / "web" / "static" / "RexiMemo_OSE_Logo.png"
|
||||
self.assertTrue(logo.is_file())
|
||||
css = (ROOT / "web" / "static" / "site.css").read_text().lower()
|
||||
self.assertIn("#b13b29", css)
|
||||
self.assertNotIn("#ae301f", css)
|
||||
webapp = (ROOT / "webapp.py").read_text()
|
||||
self.assertIn("OSE login state is tied to your IP address.", webapp)
|
||||
self.assertNotIn("It is intentionally not a production session system.", webapp)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,189 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def install_twisted_stub():
|
||||
if "twisted" in sys.modules:
|
||||
return
|
||||
if importlib.util.find_spec("twisted") is not None:
|
||||
return
|
||||
twisted = types.ModuleType("twisted")
|
||||
web = types.ModuleType("twisted.web")
|
||||
resource_mod = types.ModuleType("twisted.web.resource")
|
||||
static_mod = types.ModuleType("twisted.web.static")
|
||||
|
||||
class Resource:
|
||||
isLeaf = False
|
||||
def __init__(self):
|
||||
self.children = {}
|
||||
def putChild(self, name, child):
|
||||
if not isinstance(name, bytes):
|
||||
raise TypeError("child names must be bytes")
|
||||
self.children[name] = child
|
||||
def getChild(self, name, request):
|
||||
return self
|
||||
|
||||
class File(Resource):
|
||||
def __init__(self, path):
|
||||
super().__init__(); self.path = path
|
||||
def render(self, request):
|
||||
p = Path(self.path)
|
||||
return p.read_bytes() if p.is_file() else b""
|
||||
|
||||
resource_mod.Resource = Resource
|
||||
static_mod.File = File
|
||||
web.resource = resource_mod
|
||||
web.static = static_mod
|
||||
twisted.web = web
|
||||
sys.modules.update({
|
||||
"twisted": twisted,
|
||||
"twisted.web": web,
|
||||
"twisted.web.resource": resource_mod,
|
||||
"twisted.web.static": static_mod,
|
||||
})
|
||||
|
||||
|
||||
class ResourceTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
install_twisted_stub()
|
||||
cls.old_cwd = Path.cwd()
|
||||
os.chdir(ROOT)
|
||||
import hatena
|
||||
cls.root = hatena.Setup()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
os.chdir(cls.old_cwd)
|
||||
|
||||
def test_dsi_tree_loads(self):
|
||||
region = self.root.dsResource.region
|
||||
for key in [b"index.ugo", b"index.uls", b"allflipnotes.ugo", b"allflipnotes.uls", b"movie", b"creator", b"comment", b"ch", b"sa"]:
|
||||
self.assertIn(key, region.children)
|
||||
|
||||
def test_generated_icons_are_dsi_sized(self):
|
||||
image_dir = ROOT / "hatenadir" / "images" / "ds"
|
||||
for name in ["browse.ntft", "account.ntft", "room.ntft"]:
|
||||
self.assertEqual((image_dir / name).stat().st_size, 2048)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
|
||||
class ServerFlagTests(unittest.TestCase):
|
||||
def test_docs_flag_is_exact(self):
|
||||
import server
|
||||
old = list(sys.argv)
|
||||
try:
|
||||
sys.argv = ["server.py"]
|
||||
self.assertFalse(server.docs_enabled_from_args())
|
||||
sys.argv = ["server.py", "docs:enabled"]
|
||||
self.assertTrue(server.docs_enabled_from_args())
|
||||
sys.argv = ["server.py", "docs"]
|
||||
self.assertFalse(server.docs_enabled_from_args())
|
||||
finally:
|
||||
sys.argv = old
|
||||
|
||||
class FakeRequest:
|
||||
def __init__(self, path=b"/ds/v2-xx/index.ugo", ip="192.0.2.55", headers=None, args=None, body=b""):
|
||||
import io
|
||||
self.path = path
|
||||
self.args = args or {}
|
||||
self.content = io.BytesIO(body)
|
||||
self._ip = ip
|
||||
self._headers = headers or {b"host": b"flipnote.hatena.com", b"x-dsi-sid": b"test"}
|
||||
self.response_code = 200
|
||||
self.response_headers = {}
|
||||
def getClientIP(self): return self._ip
|
||||
def getAllHeaders(self): return self._headers
|
||||
def setHeader(self, k, v): self.response_headers[k] = v
|
||||
def setResponseCode(self, c): self.response_code = c
|
||||
|
||||
|
||||
class RenderTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
install_twisted_stub()
|
||||
cls.old_cwd = Path.cwd()
|
||||
os.chdir(ROOT)
|
||||
import hatena
|
||||
cls.root = hatena.Setup()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
os.chdir(cls.old_cwd)
|
||||
|
||||
def test_index_menu_renders_ugar(self):
|
||||
req = FakeRequest()
|
||||
data = self.root.dsResource.region.children[b"index.ugo"].render_GET(req)
|
||||
self.assertTrue(data.startswith(b"UGAR"))
|
||||
|
||||
def test_browse_menu_renders_ugar(self):
|
||||
req = FakeRequest(path=b"/ds/v2-xx/allflipnotes.ugo")
|
||||
data = self.root.dsResource.region.children[b"allflipnotes.ugo"].render_GET(req)
|
||||
self.assertTrue(data.startswith(b"UGAR"))
|
||||
|
||||
class WebRenderTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
install_twisted_stub()
|
||||
cls.old_cwd = Path.cwd()
|
||||
os.chdir(ROOT)
|
||||
import hatena
|
||||
cls.root = hatena.Setup()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
os.chdir(cls.old_cwd)
|
||||
|
||||
def web_request(self, path):
|
||||
return FakeRequest(path=path.encode(), headers={b"host": b"localhost:8080"})
|
||||
|
||||
def test_home_and_browse_render(self):
|
||||
for path in ["/", "/browse", "/about", "/watch/f_sample1", "/creator/r_sample1"]:
|
||||
req = self.web_request(path)
|
||||
data = self.root.webResource.render_GET(req)
|
||||
self.assertIn(b"RexiMemo", data)
|
||||
self.assertEqual(req.response_code, 200)
|
||||
|
||||
def test_watch_page_has_fuller_details(self):
|
||||
req = self.web_request("/watch/f_sample1")
|
||||
data = self.root.webResource.render_GET(req)
|
||||
self.assertIn(b"First-frame preview", data)
|
||||
self.assertIn(b"File size", data)
|
||||
self.assertIn(b"Public ID", data)
|
||||
self.assertIn(b"Comments", data)
|
||||
|
||||
def test_docs_are_disabled_by_default(self):
|
||||
req = self.web_request("/docs")
|
||||
data = self.root.webResource.render_GET(req)
|
||||
self.assertEqual(req.response_code, 404)
|
||||
self.assertNotIn(b"RexiMemo OSE documentation", data)
|
||||
|
||||
def test_docs_can_be_enabled(self):
|
||||
from webapp import WebRoot
|
||||
root = WebRoot(docs_enabled=True)
|
||||
req = self.web_request("/docs")
|
||||
data = root.render_GET(req)
|
||||
self.assertEqual(req.response_code, 200)
|
||||
self.assertIn(b"RexiMemo OSE documentation", data)
|
||||
self.assertIn(b"docs:enabled", data)
|
||||
self.assertIn(b"Behaviour", data)
|
||||
self.assertIn(b"official RexiMemo DNS service", data)
|
||||
self.assertIn(b"Proxy Server", data)
|
||||
self.assertIn(b"8080", data)
|
||||
self.assertIn(b"release-safety boundary", data)
|
||||
|
||||
def test_thumbnail_render(self):
|
||||
req = self.web_request("/thumb/f_sample1.png")
|
||||
data = self.root.webResource.render_GET(req)
|
||||
self.assertTrue(data.startswith(b"\x89PNG"))
|
||||
Reference in new issue
Block a user
