diff --git a/litecord/blueprints/admin_api/voice.py b/litecord/blueprints/admin_api/voice.py index e2b87d5..0c7670b 100644 --- a/litecord/blueprints/admin_api/voice.py +++ b/litecord/blueprints/admin_api/voice.py @@ -74,6 +74,7 @@ async def insert_new_region(): log.info("updating guilds to first voice region: {}", res) + await app.voice.lvsp.refresh_regions() return jsonify(regions) diff --git a/litecord/voice/lvsp_manager.py b/litecord/voice/lvsp_manager.py index 2cc0e76..e3d15c2 100644 --- a/litecord/voice/lvsp_manager.py +++ b/litecord/voice/lvsp_manager.py @@ -58,17 +58,16 @@ class LVSPManager: # quick storage for Region dataclass instances. self.regions = {} - self.app.sched.spawn(self._spawn()) + self.app.sched.spawn(self.refresh_regions()) - async def _spawn(self): + async def refresh_regions(self): """Spawn LVSPConnection for each region.""" - regions = await self.app.db.fetch( """ - SELECT id, vip - FROM voice_regions - WHERE deprecated = false - """ + SELECT id, vip + FROM voice_regions + WHERE deprecated = false + """ ) regions = [Region(r["id"], r["vip"]) for r in regions] @@ -78,9 +77,13 @@ class LVSPManager: return for region in regions: - # store it locally for region() function - self.regions[region.id] = region + # this function can be run multiple times, and so we ignore + # regions that are already in self.regions, since they already have + # their lvsp connections spawned. + if region.id in self.regions: + continue + self.regions[region.id] = region self.app.loop.create_task(self._spawn_region(region)) async def _spawn_region(self, region: Region): diff --git a/tests/test_admin_api/test_guilds.py b/tests/test_admin_api/test_guilds.py index 6ca61cb..3ff45fc 100644 --- a/tests/test_admin_api/test_guilds.py +++ b/tests/test_admin_api/test_guilds.py @@ -25,11 +25,11 @@ from litecord.blueprints.guilds import delete_guild from litecord.errors import GuildNotFound -async def _create_guild(test_cli_staff): +async def _create_guild(test_cli_staff, *, region=None) -> dict: genned_name = secrets.token_hex(6) resp = await test_cli_staff.post( - "/api/v6/guilds", json={"name": genned_name, "region": None} + "/api/v6/guilds", json={"name": genned_name, "region": region} ) assert resp.status_code == 200 @@ -119,3 +119,31 @@ async def test_guild_delete(test_cli_staff): assert rjson["code"] == GuildNotFound.error_code finally: await _delete_guild(test_cli_staff, int(guild_id)) + + +@pytest.mark.asyncio +async def test_guild_create_voice(test_cli_staff): + region_id = secrets.token_hex(6) + region_name = secrets.token_hex(6) + resp = await test_cli_staff.put( + "/api/v6/admin/voice/regions", json={"id": region_id, "name": region_name} + ) + assert resp.status_code == 200 + guild_id = None + + try: + rjson = await resp.json + assert isinstance(rjson, list) + assert region_id in [r["id"] for r in rjson] + guild_id = await _create_guild(test_cli_staff, region=region_id) + finally: + if guild_id: + await _delete_guild(test_cli_staff, int(guild_id["id"])) + + await test_cli_staff.app.db.execute( + """ + DELETE FROM voice_regions + WHERE id = $1 + """, + region_id, + )