async def test_add_remove(self): topic = "@players(min: 8)" lobby = Lobby(bot(), channel(topic=topic)) lobby = Lobby(bot(), channel()) await lobby.add(player_one := member()) assert len(lobby.players) == 1 await lobby.add(player_two := member(), player_one) assert len(lobby.players) == 2 await lobby.remove(player_one) assert len(lobby.players) == 1 await lobby.remove(player_two) assert len(lobby.players) == 0
async def test_ranking_order(self, get_games): games = [] get_games.return_value = (future := asyncio.Future()) future.set_result(games) ids = [id for id in range(8)] [_add_game(games, ids) for _ in range(5)] topic = "@SuperCashBrosLeftForDead(history: 'patched')" lobby = Lobby(bot(), channel(topic=topic)) for id in range(8): await lobby.ready(member(id)) inactive_rank = get_ranks(games, Season.all_time()) active_rank = get_ranks(games, Season.current()) def get_player_rank(p) -> int: if active_rank and p in active_rank: return active_rank[p] if p in inactive_rank: return inactive_rank[p] return 2000 matches = lobby.get_matches() await rank(matches, get_player_rank) last_diff = -1 for m in matches: m = list(m) mean_1 = mean([get_player_rank(p.member.id) for p in list(m[0])]) mean_2 = mean([get_player_rank(p.member.id) for p in list(m[1])]) next_diff = abs(mean_1 - mean_2) assert next_diff >= last_diff last_diff = next_diff
async def test_cache(self): topic = """ @teams([2, 2]) """ lobby = Lobby(bot(), channel(topic=topic)) for _ in range(8): await lobby.ready(member()) assert not lobby._cache await lobby.show_next_shuffle() shuffles_cache = lobby._cache["shuffles"] assert shuffles_cache await lobby.add(p_joined := member()) assert lobby._cache["shuffles"] == shuffles_cache await lobby.ready(p_ready := member()) assert not lobby._cache await lobby.show_next_shuffle() assert lobby._cache["shuffles"] assert lobby._cache["shuffles"] != shuffles_cache await lobby.remove(p_joined) assert lobby._cache await lobby.remove(p_ready) assert not lobby._cache
async def test_leavers(self): topic = "@players(min: 8)" lobby = Lobby(bot(), channel(topic=topic)) lobby = Lobby(bot(), channel()) await lobby.add(author := member()) await lobby.add(leaver := member(), author) # Removal by others does not prevent re-add await lobby.remove(leaver, author) assert not lobby.has_left_before(leaver) await lobby.add(leaver, author) # Leaving prevents re-add await lobby.remove(leaver) with self.assertRaises(UsageException): await lobby.add(leaver, author) await lobby.add(leaver)
async def test_config(self): topic = """ @name({}) @broadcast(4) @players("dog") @teams() @overflow([]) @foo() """ lobby = Lobby(bot(), ctx := channel(topic=topic)) await lobby.show_config() assert ctx.send.await_count == 1 embed = ctx.send.await_args.kwargs["embed"] assert embed.title == "Lobby Config" assert len(embed.fields) == 2 assert embed.fields[0].name == "Settings" assert embed.fields[0].value.count("\n") == 5 assert embed.fields[1].name == "Issues" assert embed.fields[1].value.count("\n") == 12 lobby.c.install("@name('Game night!')") embed = lobby.c.describe() assert embed.fields[1].name == "Issues" assert embed.fields[1].value.count("\n") == 10 lobby.c.install("@teams([2, 2])") embed = lobby.c.describe() assert embed.fields[1].name == "Issues" assert embed.fields[1].value.count("\n") == 8 lobby.c.install("@overflow(False)") embed = lobby.c.describe() assert embed.fields[1].name == "Issues" assert embed.fields[1].value.count("\n") == 6 lobby.c.install("@broadcast([])") embed = lobby.c.describe() assert embed.fields[1].name == "Issues" assert embed.fields[1].value.count("\n") == 4 lobby.c.install("@players(min: 3)") embed = lobby.c.describe() assert embed.fields[1].name == "Issues" assert embed.fields[1].value.count("\n") == 2 ctx.topic = """ @name("Game Night!") @broadcast([]) @players(min: 3) @teams([2, 2]) @overflow(False) """ lobby = Lobby(bot(), ctx) embed = lobby.c.describe() assert len(embed.fields) == 1
async def test_with_ordering(order: Callable): lobby = Lobby(bot(), channel()) for _ in range(8): await lobby.ready(member()) seen = set() for _ in range(35): # 35 times: (8 choose 4) / 2 (_, (one, two)) = await lobby.get_next_match(order) assert (one, two) not in seen assert (two, one) not in seen seen.add((one, two)) seen.add((two, one)) final = await lobby.get_next_match(order) assert final is None
async def janitor(self): now = datetime.datetime.now().time() reset_range_start = datetime.time(13) reset_range_end = datetime.time(13, 1) if reset_range_start <= now <= reset_range_end: for index in list(self.lobbies.keys()): if len(self.lobbies[index].players) == 0: continue channel = self.lobbies[index].channel del self.lobbies[index] embed = Lobby(self.bot, channel).c.describe() embed.color = Colour.orange() embed.title = "Lobby has been Cleared" embed.set_footer(text=EmptyEmbed) await channel.send(embed=embed)
async def test_get_matches(self): topic = "@teams([4, 4])" lobby = Lobby(bot(), channel(topic=topic)) for _ in range(8): await lobby.ready(member()) seen = set() matches = iter(lobby.get_matches()) for _ in range(35): # 35 times: (8 choose 4) / 2 match = next(matches) assert len(match) == 2 assert match not in seen seen.add(match) final = next(matches, None) assert final is None
async def test_full_lobby(self): lobby = Lobby(bot(), channel()) await lobby.ready(first := member()) assert not lobby.is_ready() for _ in range(7): await lobby.ready(member()) assert lobby.is_ready() await lobby.add(alternate := member()) with self.assertRaises(UsageException): await lobby.ready(alternate) await lobby.remove(first) assert not lobby.is_ready() await lobby.ready(alternate) assert lobby.is_ready() with self.assertRaises(UsageException): await lobby.ready(first)
async def test_ready_unready(self): lobby = Lobby(bot(), channel()) await lobby.add(player := member()) await lobby.ready(player) assert lobby.ready_count() == 1 await lobby.unready(player) assert lobby.ready_count() == 0 await lobby.remove(player) await lobby.ready(player) assert lobby.ready_count() == 1 await lobby.unready(player) assert lobby.ready_count() == 0 await lobby.ready(player) assert lobby.ready_count() == 1
async def test_ready_unready(self): topic = "@players(min: 8)" lobby = Lobby(bot(), channel(topic=topic)) await lobby.add(player := member()) await lobby.ready(player) assert lobby.ready_count() == 1 await lobby.unready(player) assert lobby.ready_count() == 0 await lobby.remove(player) await lobby.ready(player) assert lobby.ready_count() == 1 await lobby.unready(player) assert lobby.ready_count() == 0 await lobby.ready(player) assert lobby.ready_count() == 1
async def janitor(self): now = datetime.datetime.now().time() reset_range_start = datetime.time(13) reset_range_end = datetime.time(13, 1) if reset_range_start <= now <= reset_range_end: daily_fact = self.get_todays_useless_fact() for index in self.lobbies: if len(self.lobbies[index].players) == 0: continue channel = self.lobbies[index].channel self.lobbies[index] = Lobby(self.bot, channel) embed = Embed(colour=Colour.orange()) embed.set_author( name=f"Daily Update - {str(datetime.date.today())}") embed.add_field( name="Lobby has been cleared!", value=daily_fact, inline=False, ) await channel.send(embed=embed)
def post(self): """ User creates a lobby. Request uid - user_id lid - name of lobby """ data = json.loads(self.request.body) response = {} try: uid = data['uid'] except KeyError: self.error(400) response['status'] = 'error' response['msg'] = 'Missing uid (User id)' return self.response.out.write(json.dumps(response)) try: lobby_id = data['lid'] except KeyError: self.error(400) response['status'] = 'error' response['msg'] = 'Missing lid (Lobby id)' return self.response.out.write(json.dumps(response)) user = User.query(User.uuid == uid).get() # New User if user is None: logging.info("New user (" + str(uid) + ") has joined RouteRunner.") user = User(uuid=uid, nickname=uid) user.put() # TODO: Make sure this user is actually who we think it is lobby = Lobby(lobby_id=lobby_id, users=[uid]) # Check if this lobby already exists exists = Lobby.query(Lobby.lobby_id == lobby_id).get() if exists is None: lobby.put() response['status'] = 'success' self.response.out.write(json.dumps(response))
async def test_numbers(self): discord_bot = bot() discord_bot.get_all_channels.return_value = [ vchannel(participants=[member(), member()]), vchannel(participants=[member()]), ] lobby_channel = channel() online = [member() for _ in range(7)] offline = [member(status=Status.offline) for _ in range(5)] lobby_channel.guild.members = online + offline lobby = Lobby(discord_bot, lobby_channel) await lobby.add(member()) lobby_channel.reset_mock() await lobby.show_numbers() assert len(lobby_channel.send.call_args_list) == 1 embed: Embed = lobby_channel.send.call_args_list[0].kwargs["embed"] assert embed.title == "These are some numbers for sure." assert len(embed.fields) == 4 fields = embed.fields assert fields[0].name == "Online" and fields[0].value == "7" assert fields[1].name == "In Voice" and fields[1].value == "3" assert fields[2].name == "Joined" and fields[2].value == "1" assert fields[3].name == "Ready" and fields[3].value == "0"
async def clear(self, ctx: Context): if ctx.channel.id in self.lobbies: self.lobbies[ctx.channel.id] = Lobby(self.bot, ctx.channel) await self.lobbies[ctx.channel.id].show()
async def test_lobby_embed(self): lobby = Lobby(bot(), channel()) embed = lobby.get_lobby_message() assert embed.title == "Lobby (0)" assert embed.footer.text == "There are 8 spots remaining!" assert embed.colour == Colour.orange() await lobby.add(player := member()) embed = lobby.get_lobby_message() assert embed.title == "Lobby (1)" assert embed.footer.text == "There are 8 spots remaining!" assert embed.colour == Colour.orange() assert len(embed.fields) == 1 assert embed.fields[0].name == "Alternates (1)" assert str(player.display_name) in embed.fields[0].value embed = lobby.get_lobby_message(mention=True) assert str(player.display_name) in embed.fields[0].value await lobby.ready(player) embed = lobby.get_lobby_message() assert embed.title == "Lobby (1)" assert embed.footer.text == "There are 7 spots remaining!" assert embed.colour == Colour.orange() assert len(embed.fields) == 1 assert embed.fields[0].name == "Players (1)" assert str(player.display_name) in embed.fields[0].value embed = lobby.get_lobby_message(mention=True) assert str(player.mention) in embed.fields[0].value for _ in range(7): await lobby.ready(member()) embed = lobby.get_lobby_message() assert embed.title == "Lobby (8)" assert "Use `?shuffle` or `?ranked`" in embed.footer.text assert embed.colour == Colour.green() assert len(embed.fields) == 1 assert embed.fields[0].name == "Players (8)" await lobby.unready(player) embed = lobby.get_lobby_message() assert embed.title == "Lobby (8)" assert embed.footer.text == "There's one spot remaining!" assert embed.colour == Colour.orange() assert len(embed.fields) == 2 assert embed.fields[0].name == "Players (7)" assert embed.fields[1].name == "Alternates (1)" await lobby.remove(player) embed = lobby.get_lobby_message() assert embed.title == "Lobby (7)" assert embed.footer.text == "There's one spot remaining!" assert embed.colour == Colour.orange() assert len(embed.fields) == 1 assert embed.fields[0].name == "Players (7)" for _ in range(100): await lobby.add(member()) embed = lobby.get_lobby_message() assert embed.title == "Lobby (107)" assert embed.footer.text == "There's one spot remaining!" assert embed.colour == Colour.orange() assert len(embed.fields) == 2 assert embed.fields[1].name == "Alternates (100)" await lobby.ready(member()) embed = lobby.get_lobby_message() assert embed.title == "Lobby (108)" assert "Use `?shuffle` or `?ranked`" in embed.footer.text assert embed.colour == Colour.green() assert len(embed.fields) == 2 assert embed.fields[0].name == "Players (8)" assert embed.fields[1].name == "Alternates (100)"
seen = set() for _ in range(35): # 35 times: (8 choose 4) / 2 (_, (one, two)) = await lobby.get_next_match(order) assert (one, two) not in seen assert (two, one) not in seen seen.add((one, two)) seen.add((two, one)) final = await lobby.get_next_match(order) assert final is None await test_with_ordering(get_shuffler()) await test_with_ordering(get_ranker(channel())) async def test_broadcast(self): discord_bot = bot() discord_bot.get_all_channels.return_value = [ lobby_channel := channel(name="lobby", topic="@broadcast(#dest1)\n@broadcast(#dest2)"), dest_one := channel(name="dest1"), dest_two := channel(name="dest2"), misc_channel := channel(name="misc"), ] lobby = Lobby(discord_bot, lobby_channel) await lobby.broadcast_game_almost_full() assert dest_one.send.call_count == 1 assert dest_two.send.call_count == 1 assert misc_channel.send.call_count == 0
def get_lobby(self, ctx: Context) -> Lobby: if ctx.channel.id not in self.lobbies: self.lobbies[ctx.channel.id] = Lobby(self.bot, ctx.channel) self.lobbies[ctx.channel.id].channel = ctx.channel return self.lobbies[ctx.channel.id]
async def clear(self, ctx: Context): """Remove all players from the lobby""" if ctx.channel.id in self.lobbies: self.lobbies[ctx.channel.id] = Lobby(self.bot, ctx.channel) await self.lobbies[ctx.channel.id].show()
def create_lobbies(lid_list, started=False): """Creates a list of lobbies.""" lobby_list = [Lobby(lobby_id=name, users=[name], started=started) for name in lid_list] ndb.put_multi(lobby_list)
def create_lobby(lid, started=False): """Creates a lobby with lid that has the user lid in it.""" lobby = Lobby(lobby_id=lid, users=[lid], started=started) lobby.put()
def lobby(*names: Set[str]) -> Lobby: topic = f"@SuperCashBrosLeftForDead(history: {SHEETS})" lobby = Lobby(bot(), channel(topic)) lobby.players = [Player(real_member(name, IDS[name])) for name in names] [p.set_ready() for p in lobby.players] return lobby
async def test_lobby_embed(self): topic = """ @name(foo) @players(min: 8) """ lobby = Lobby(bot(), channel(topic=topic)) embed = lobby.get_lobby_message() assert embed.author.name == "foo" assert embed.footer.text == "More players can join." assert embed.colour == Colour.orange() await lobby.add(player := member()) embed = lobby.get_lobby_message() assert embed.author.name == "foo" assert embed.footer.text == "More players can join." assert embed.colour == Colour.orange() assert len(embed.fields) == 1 assert embed.fields[0].name == "Alternates (1)" assert embed.fields[0].value.count("\n") == 1 assert str(player.display_name) in embed.fields[0].value embed = lobby.get_lobby_message(mention=True) assert str(player.display_name) in embed.fields[0].value await lobby.ready(player) embed = lobby.get_lobby_message() assert embed.author.name == "foo" assert embed.footer.text == "More players can join." assert embed.colour == Colour.orange() assert len(embed.fields) == 1 assert embed.fields[0].name == "Players (1)" assert str(player.display_name) in embed.fields[0].value assert embed.fields[0].value.count("\n") == 1 embed = lobby.get_lobby_message(mention=True) assert str(player.mention) in embed.fields[0].value for _ in range(7): await lobby.ready(member()) embed = lobby.get_lobby_message() assert embed.author.name == "foo" assert embed.footer.text == "Game ready. More players can join." assert embed.colour == Colour.green() assert len(embed.fields) == 1 assert embed.fields[0].name == "Players (8)" assert embed.fields[0].value.count("\n") == 8 await lobby.unready(player) embed = lobby.get_lobby_message() assert embed.author.name == "foo" assert embed.footer.text == "More players can join." assert embed.colour == Colour.orange() assert len(embed.fields) == 2 assert embed.fields[0].name == "Players (7)" assert embed.fields[0].value.count("\n") == 7 assert embed.fields[1].name == "Alternates (1)" assert embed.fields[1].value.count("\n") == 1 await lobby.remove(player) embed = lobby.get_lobby_message() assert embed.author.name == "foo" assert embed.footer.text == "More players can join." assert embed.colour == Colour.orange() assert len(embed.fields) == 1 assert embed.fields[0].name == "Players (7)" assert embed.fields[0].value.count("\n") == 7 for _ in range(100): await lobby.add(member()) embed = lobby.get_lobby_message() assert embed.author.name == "foo" assert embed.footer.text == "More players can join." assert embed.colour == Colour.orange() assert len(embed.fields) == 2 assert embed.fields[1].name == "Alternates (100)" assert embed.fields[1].value.count("\n") == 100 await lobby.ready(member()) embed = lobby.get_lobby_message() assert embed.author.name == "foo" assert embed.footer.text == "Game ready. More players can join." assert embed.colour == Colour.green() assert len(embed.fields) == 2 assert embed.fields[0].name == "Players (8)" assert embed.fields[0].value.count("\n") == 8 assert embed.fields[1].name == "Alternates (100)" assert embed.fields[1].value.count("\n") == 100 lobby.c.vLaunch = "foo.com" embed = lobby.get_lobby_message() assert embed.fields[0].value.count("\n") == 9 lobby.c.vMax = 8 embed = lobby.get_lobby_message() assert embed.footer.text == "Game ready. More alternates can join." lobby.c.vMax = 9 embed = lobby.get_lobby_message() assert embed.footer.text == "Game ready. More players can join." lobby.c.vMax = 8 lobby.c.vOverflow = False embed = lobby.get_lobby_message() assert embed.footer.text == "Game ready. " assert embed.fields[1].name == "Not Ready (100)"