class JamCreateTeamTests(unittest.IsolatedAsyncioTestCase): """Tests for `createteam` command.""" def setUp(self): self.bot = MockBot() self.admin_role = MockRole(name="Admins", id=Roles.admins) self.command_user = MockMember([self.admin_role]) self.guild = MockGuild([self.admin_role]) self.ctx = MockContext(bot=self.bot, author=self.command_user, guild=self.guild) self.cog = jams.CodeJams(self.bot) async def test_too_small_amount_of_team_members_passed(self): """Should `ctx.send` and exit early when too small amount of members.""" for case in (1, 2): with self.subTest(amount_of_members=case): self.cog.create_channels = AsyncMock() self.cog.add_roles = AsyncMock() self.ctx.reset_mock() members = (MockMember() for _ in range(case)) await self.cog.createteam(self.cog, self.ctx, "foo", members) self.ctx.send.assert_awaited_once() self.cog.create_channels.assert_not_awaited() self.cog.add_roles.assert_not_awaited() async def test_duplicate_members_provided(self): """Should `ctx.send` and exit early because duplicate members provided and total there is only 1 member.""" self.cog.create_channels = AsyncMock() self.cog.add_roles = AsyncMock() member = MockMember() await self.cog.createteam(self.cog, self.ctx, "foo", (member for _ in range(5))) self.ctx.send.assert_awaited_once() self.cog.create_channels.assert_not_awaited() self.cog.add_roles.assert_not_awaited() async def test_result_sending(self): """Should call `ctx.send` when everything goes right.""" self.cog.create_channels = AsyncMock() self.cog.add_roles = AsyncMock() members = [MockMember() for _ in range(5)] await self.cog.createteam(self.cog, self.ctx, "foo", members) self.cog.create_channels.assert_awaited_once() self.cog.add_roles.assert_awaited_once() self.ctx.send.assert_awaited_once() async def test_category_doesnt_exist(self): """Should create a new code jam category.""" subtests = ( [], [get_mock_category(jams.MAX_CHANNELS - 1, jams.CATEGORY_NAME)], [get_mock_category(jams.MAX_CHANNELS - 2, "other")], ) for categories in subtests: self.guild.reset_mock() self.guild.categories = categories with self.subTest(categories=categories): actual_category = await self.cog.get_category(self.guild) self.guild.create_category_channel.assert_awaited_once() category_overwrites = self.guild.create_category_channel.call_args[1]["overwrites"] self.assertFalse(category_overwrites[self.guild.default_role].read_messages) self.assertTrue(category_overwrites[self.guild.me].read_messages) self.assertEqual(self.guild.create_category_channel.return_value, actual_category) async def test_category_channel_exist(self): """Should not try to create category channel.""" expected_category = get_mock_category(jams.MAX_CHANNELS - 2, jams.CATEGORY_NAME) self.guild.categories = [ get_mock_category(jams.MAX_CHANNELS - 2, "other"), expected_category, get_mock_category(0, jams.CATEGORY_NAME), ] actual_category = await self.cog.get_category(self.guild) self.assertEqual(expected_category, actual_category) async def test_channel_overwrites(self): """Should have correct permission overwrites for users and roles.""" leader = MockMember() members = [leader] + [MockMember() for _ in range(4)] overwrites = self.cog.get_overwrites(members, self.guild) # Leader permission overwrites self.assertTrue(overwrites[leader].manage_messages) self.assertTrue(overwrites[leader].read_messages) self.assertTrue(overwrites[leader].manage_webhooks) self.assertTrue(overwrites[leader].connect) # Other members permission overwrites for member in members[1:]: self.assertTrue(overwrites[member].read_messages) self.assertTrue(overwrites[member].connect) # Everyone and verified role overwrite self.assertFalse(overwrites[self.guild.default_role].read_messages) self.assertFalse(overwrites[self.guild.default_role].connect) self.assertFalse(overwrites[self.guild.get_role(Roles.verified)].read_messages) self.assertFalse(overwrites[self.guild.get_role(Roles.verified)].connect) async def test_team_channels_creation(self): """Should create new voice and text channel for team.""" members = [MockMember() for _ in range(5)] self.cog.get_overwrites = MagicMock() self.cog.get_category = AsyncMock() self.ctx.guild.create_text_channel.return_value = MockTextChannel(mention="foobar-channel") actual = await self.cog.create_channels(self.guild, "my-team", members) self.assertEqual("foobar-channel", actual) self.cog.get_overwrites.assert_called_once_with(members, self.guild) self.cog.get_category.assert_awaited_once_with(self.guild) self.guild.create_text_channel.assert_awaited_once_with( "my-team", overwrites=self.cog.get_overwrites.return_value, category=self.cog.get_category.return_value ) self.guild.create_voice_channel.assert_awaited_once_with( "My Team", overwrites=self.cog.get_overwrites.return_value, category=self.cog.get_category.return_value ) async def test_jam_roles_adding(self): """Should add team leader role to leader and jam role to every team member.""" leader_role = MockRole(name="Team Leader") jam_role = MockRole(name="Jammer") self.guild.get_role.side_effect = [leader_role, jam_role] leader = MockMember() members = [leader] + [MockMember() for _ in range(4)] await self.cog.add_roles(self.guild, members) leader.add_roles.assert_any_await(leader_role) for member in members: member.add_roles.assert_any_await(jam_role)
class JamCodejamCreateTests(unittest.IsolatedAsyncioTestCase): """Tests for `codejam create` command.""" def setUp(self): self.bot = MockBot() self.admin_role = MockRole(name="Admins", id=Roles.admins) self.command_user = MockMember([self.admin_role]) self.guild = MockGuild([self.admin_role]) self.ctx = MockContext(bot=self.bot, author=self.command_user, guild=self.guild) self.cog = _cog.CodeJams(self.bot) async def test_message_without_attachments(self): """If no link or attachments are provided, commands.BadArgument should be raised.""" self.ctx.message.attachments = [] with self.assertRaises(BadArgument): await self.cog.create(self.cog, self.ctx, None) @patch.object(_channels, "create_team_channel") @patch.object(_channels, "create_team_leader_channel") async def test_result_sending(self, create_leader_channel, create_team_channel): """Should call `ctx.send` when everything goes right.""" self.ctx.message.attachments = [MockAttachment()] self.ctx.message.attachments[0].read = AsyncMock() self.ctx.message.attachments[0].read.return_value = TEST_CSV team_leaders = MockRole() self.guild.get_member.return_value = MockMember() self.ctx.guild.create_role = AsyncMock() self.ctx.guild.create_role.return_value = team_leaders self.cog.add_roles = AsyncMock() await self.cog.create(self.cog, self.ctx, None) create_team_channel.assert_awaited() create_leader_channel.assert_awaited_once_with( self.ctx.guild, team_leaders ) self.ctx.send.assert_awaited_once() async def test_link_returning_non_200_status(self): """When the URL passed returns a non 200 status, it should send a message informing them.""" self.bot.http_session.get.return_value = mock = MagicMock() mock.status = 404 await self.cog.create(self.cog, self.ctx, "https://not-a-real-link.com") self.ctx.send.assert_awaited_once() @patch.object(_channels, "_send_status_update") async def test_category_doesnt_exist(self, update): """Should create a new code jam category.""" subtests = ( [], [get_mock_category(_channels.MAX_CHANNELS, _channels.CATEGORY_NAME)], [get_mock_category(_channels.MAX_CHANNELS - 2, "other")], ) for categories in subtests: update.reset_mock() self.guild.reset_mock() self.guild.categories = categories with self.subTest(categories=categories): actual_category = await _channels._get_category(self.guild) update.assert_called_once() self.guild.create_category_channel.assert_awaited_once() category_overwrites = self.guild.create_category_channel.call_args[1]["overwrites"] self.assertFalse(category_overwrites[self.guild.default_role].read_messages) self.assertTrue(category_overwrites[self.guild.me].read_messages) self.assertEqual(self.guild.create_category_channel.return_value, actual_category) async def test_category_channel_exist(self): """Should not try to create category channel.""" expected_category = get_mock_category(_channels.MAX_CHANNELS - 2, _channels.CATEGORY_NAME) self.guild.categories = [ get_mock_category(_channels.MAX_CHANNELS - 2, "other"), expected_category, get_mock_category(0, _channels.CATEGORY_NAME), ] actual_category = await _channels._get_category(self.guild) self.assertEqual(expected_category, actual_category) async def test_channel_overwrites(self): """Should have correct permission overwrites for users and roles.""" leader = (MockMember(), True) members = [leader] + [(MockMember(), False) for _ in range(4)] overwrites = _channels._get_overwrites(members, self.guild) for member, _ in members: self.assertTrue(overwrites[member].read_messages) @patch.object(_channels, "_get_overwrites") @patch.object(_channels, "_get_category") @autospec(_channels, "_add_team_leader_roles", pass_mocks=False) async def test_team_channels_creation(self, get_category, get_overwrites): """Should create a text channel for a team.""" team_leaders = MockRole() members = [(MockMember(), True)] + [(MockMember(), False) for _ in range(5)] category = MockCategoryChannel() category.create_text_channel = AsyncMock() get_category.return_value = category await _channels.create_team_channel(self.guild, "my-team", members, team_leaders) category.create_text_channel.assert_awaited_once_with( "my-team", overwrites=get_overwrites.return_value ) async def test_jam_roles_adding(self): """Should add team leader role to leader and jam role to every team member.""" leader_role = MockRole(name="Team Leader") leader = MockMember() members = [(leader, True)] + [(MockMember(), False) for _ in range(4)] await _channels._add_team_leader_roles(members, leader_role) leader.add_roles.assert_awaited_once_with(leader_role) for member, is_leader in members: if not is_leader: member.add_roles.assert_not_awaited()