Avatar shapes (circle, flower, rounded square, hexagon, heart, triangle): the own shape everywhere and, through the members service, the shapes other members published after proving the account with the code in the bio. Own accent colour and AMOLED, compact bottom bar, Material 3 profile and plus button, save menu (quality, audio only, photo posts without the watermark), fixed comment cards, "Luna (pre-release)" in the mod screen. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
166 lines
6.9 KiB
Python
166 lines
6.9 KiB
Python
import importlib.util
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
SPEC = importlib.util.spec_from_file_location("members_server", Path(__file__).resolve().parents[1] / "services" / "members" / "server.py")
|
|
server = importlib.util.module_from_spec(SPEC)
|
|
SPEC.loader.exec_module(server)
|
|
|
|
UID = "6812345678901234"
|
|
|
|
|
|
class ClaimTest(unittest.TestCase):
|
|
def setUp(self):
|
|
self.tmp = tempfile.TemporaryDirectory()
|
|
self.addCleanup(self.tmp.cleanup)
|
|
self.now = 1_790_000_000
|
|
self.bio = ""
|
|
self.found = UID
|
|
self.registry = server.Registry(Path(self.tmp.name) / "r.sqlite3", clock=lambda: self.now, fetcher=self.fetch)
|
|
|
|
def fetch(self, unique_id):
|
|
return (self.found, self.bio)
|
|
|
|
def test_code_is_stable_and_per_account(self):
|
|
code = self.registry.code(UID)
|
|
self.assertEqual(code, self.registry.code(UID))
|
|
self.assertNotEqual(code, self.registry.code("6812345678901235"))
|
|
self.assertRegex(code, r"^LT-[A-Z2-7]{8}$")
|
|
|
|
def test_bio_with_the_code_gets_the_badge(self):
|
|
self.assertFalse(self.registry.lookup([UID])["niche"][UID])
|
|
self.assertEqual("code_missing", self.registry.claim(UID, "someone")["reason"])
|
|
self.bio = "hello " + self.registry.code(UID) + " bye"
|
|
self.assertTrue(self.registry.claim(UID, "someone")["granted"])
|
|
self.assertTrue(self.registry.lookup([UID])["niche"][UID])
|
|
|
|
def test_someone_elses_profile_is_refused(self):
|
|
self.found = "999999999"
|
|
self.bio = self.registry.code(UID)
|
|
with self.assertRaises(ValueError):
|
|
self.registry.claim(UID, "someone")
|
|
|
|
def test_nothing_is_issued_after_the_deadline_but_holders_stay(self):
|
|
self.bio = self.registry.code(UID)
|
|
self.registry.claim(UID, "someone")
|
|
self.now = server.CLAIM_DEADLINE + 1
|
|
other = "6812345678901299"
|
|
self.found, self.bio = other, self.registry.code(other)
|
|
with self.assertRaises(ValueError):
|
|
self.registry.claim(other, "other")
|
|
self.assertTrue(self.registry.lookup([UID, other])["niche"][UID])
|
|
self.assertFalse(self.registry.lookup([UID, other])["niche"][other])
|
|
|
|
def test_blocked_accounts_get_nothing(self):
|
|
with self.registry.connect() as db:
|
|
db.execute("INSERT INTO blocked(uid) VALUES(?)", (UID,))
|
|
self.bio = self.registry.code(UID)
|
|
with self.assertRaises(ValueError):
|
|
self.registry.claim(UID, "someone")
|
|
|
|
def test_bad_input_and_unreadable_profiles(self):
|
|
with self.assertRaises(ValueError):
|
|
self.registry.claim("abc", "someone")
|
|
with self.assertRaises(ValueError):
|
|
self.registry.claim(UID, "bad name!")
|
|
self.registry.fetcher = lambda u: (_ for _ in ()).throw(OSError("blocked"))
|
|
with self.assertRaises(ValueError):
|
|
self.registry.claim(UID, "someone")
|
|
|
|
|
|
INSTALLATION = "a" * 64
|
|
OTHER_INSTALLATION = "b" * 64
|
|
|
|
|
|
class ShapeTest(unittest.TestCase):
|
|
def setUp(self):
|
|
self.tmp = tempfile.TemporaryDirectory()
|
|
self.addCleanup(self.tmp.cleanup)
|
|
self.now = 1_790_000_000
|
|
self.bio = ""
|
|
self.found = UID
|
|
self.fetches = 0
|
|
self.registry = server.Registry(Path(self.tmp.name) / "r.sqlite3", clock=lambda: self.now, fetcher=self.fetch)
|
|
|
|
def fetch(self, unique_id):
|
|
self.fetches += 1
|
|
return (self.found, self.bio)
|
|
|
|
def publish(self, shape, installation=INSTALLATION, unique_id="someone", uid=UID):
|
|
return self.registry.shape(uid, installation, shape, unique_id)
|
|
|
|
def test_nothing_is_published_without_the_code_in_the_bio(self):
|
|
self.assertEqual("code_missing", self.publish("flower")["reason"])
|
|
self.assertEqual({}, self.registry.lookup([UID])["shapes"])
|
|
self.assertEqual("proof_needed", self.registry.shape(UID, INSTALLATION, "flower")["reason"])
|
|
|
|
def test_the_code_in_the_bio_publishes_the_shape(self):
|
|
self.bio = "me " + self.registry.code(UID)
|
|
self.assertTrue(self.publish("flower")["published"])
|
|
self.assertEqual({UID: "flower"}, self.registry.lookup([UID])["shapes"])
|
|
|
|
def test_the_proven_installation_changes_it_without_another_proof(self):
|
|
self.bio = self.registry.code(UID)
|
|
self.publish("flower")
|
|
fetched = self.fetches
|
|
self.bio = ""
|
|
self.assertTrue(self.registry.shape(UID, INSTALLATION, "heart")["published"])
|
|
self.assertEqual(fetched, self.fetches)
|
|
self.assertEqual({UID: "heart"}, self.registry.lookup([UID])["shapes"])
|
|
|
|
def test_another_installation_must_prove_the_account_itself(self):
|
|
self.bio = self.registry.code(UID)
|
|
self.publish("flower")
|
|
self.bio = ""
|
|
self.assertFalse(self.publish("hexagon", OTHER_INSTALLATION)["published"])
|
|
self.assertEqual({UID: "flower"}, self.registry.lookup([UID])["shapes"])
|
|
self.bio = self.registry.code(UID)
|
|
self.assertTrue(self.publish("hexagon", OTHER_INSTALLATION)["published"])
|
|
self.assertEqual({UID: "hexagon"}, self.registry.lookup([UID])["shapes"])
|
|
# the first installation lost its right with that
|
|
self.bio = ""
|
|
self.assertFalse(self.publish("heart", INSTALLATION)["published"])
|
|
|
|
def test_circle_withdraws_the_shape(self):
|
|
self.bio = self.registry.code(UID)
|
|
self.publish("triangle")
|
|
self.assertTrue(self.registry.shape(UID, INSTALLATION, "circle")["published"])
|
|
self.assertEqual({}, self.registry.lookup([UID])["shapes"])
|
|
|
|
def test_circle_for_an_account_without_a_shape_needs_nothing(self):
|
|
self.assertTrue(self.publish("circle")["published"])
|
|
self.assertEqual(0, self.fetches)
|
|
|
|
def test_someone_elses_profile_and_blocked_accounts_are_refused(self):
|
|
self.found = "999999999"
|
|
self.bio = self.registry.code(UID)
|
|
with self.assertRaises(ValueError):
|
|
self.publish("flower")
|
|
self.found = UID
|
|
with self.registry.connect() as db:
|
|
db.execute("INSERT INTO blocked(uid) VALUES(?)", (UID,))
|
|
with self.assertRaises(ValueError):
|
|
self.publish("flower")
|
|
|
|
def test_a_blocked_account_loses_its_shape_in_lookups(self):
|
|
self.bio = self.registry.code(UID)
|
|
self.publish("flower")
|
|
with self.registry.connect() as db:
|
|
db.execute("INSERT INTO blocked(uid) VALUES(?)", (UID,))
|
|
self.assertEqual({}, self.registry.lookup([UID])["shapes"])
|
|
|
|
def test_bad_input(self):
|
|
for shape in ("blob", "", None, 5):
|
|
with self.assertRaises(ValueError):
|
|
self.publish(shape)
|
|
with self.assertRaises(ValueError):
|
|
self.registry.shape("abc", INSTALLATION, "flower", "someone")
|
|
with self.assertRaises(ValueError):
|
|
self.registry.shape(UID, "short", "flower", "someone")
|
|
self.assertEqual("proof_needed", self.registry.shape(UID, INSTALLATION, "flower", "bad name!")["reason"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|