async def test_load_from_dict(self, create_bot): test_data = { "cache": "MemoryCache", "options": asdict(Options()), "guilds": [ { "id": 1, "options": asdict(Options()), "members": [ { "id": 1, "guild_id": 2, "is_in_guild": True, "warn_count": 5, "kick_count": 6, "duplicate_count": 7, "duplicate_channel_counter_dict": {}, "messages": [ { "id": 1, "content": "Hello World!", "guild_id": 2, "author_id": 3, "channel_id": 4, "is_duplicate": True, "creation_time": "225596:21:8:3:12:5:2021", } ], } ], } ], } await AntiSpamHandler.load_from_dict(create_bot, test_data)
def test_library_inits(self, create_bot): hikari = AntiSpamHandler(create_bot, library=Library.HIKARI) assert isinstance(hikari.lib_handler, Hikari) pincer = AntiSpamHandler( create_bot, library=Library.PINCER, options=Options(use_timeouts=False) ) assert isinstance(pincer.lib_handler, Pincer) with pytest.raises(UnsupportedAction): AntiSpamHandler(create_bot, library=Library.PINCER) with pytest.raises(UnsupportedAction): AntiSpamHandler( create_bot, library=Library.PINCER, options=Options(use_timeouts=True) ) disnake = AntiSpamHandler(create_bot, library=Library.DISNAKE) assert isinstance(disnake.lib_handler, Disnake) enhanced_dpy = AntiSpamHandler(create_bot, library=Library.ENHANCED_DPY) assert isinstance(enhanced_dpy.lib_handler, EnhancedDPY) nextcord = AntiSpamHandler(create_bot, library=Library.NEXTCORD) assert isinstance(nextcord.lib_handler, Nextcord) with pytest.raises(UnsupportedAction): AntiSpamHandler(create_bot, library=Library.PYCORD) dpy = AntiSpamHandler(create_bot, library=Library.DPY) assert isinstance(dpy.lib_handler, DPY)
async def test_remove_custom_options(self, create_handler: AntiSpamHandler): await create_handler.remove_guild_options(1) # Shouldn't raise or anything await create_handler.add_guild_options(1, Options(no_punish=False)) assert create_handler.cache.cache.get(1).options == Options(no_punish=False) await create_handler.remove_guild_options(1) assert create_handler.cache.cache.get(1).options == Options()
def test_custom_options(self, create_bot): """Tests custom options get set correct""" handler = AntiSpamHandler( create_bot, Library.DPY, options=Options(no_punish=True) ) assert handler.options != Options() assert handler.options == Options(no_punish=True)
async def test_get_guild_options(self, create_handler: AntiSpamHandler): with pytest.raises(GuildNotFound): await create_handler.get_guild_options(1) await create_handler.add_guild_options(1, Options(no_punish=False)) await create_handler.get_guild_options(1) assert create_handler.cache.cache.get(1).options == Options(no_punish=False)
async def test_add_guild_options(self, create_handler: AntiSpamHandler): assert len(create_handler.cache.cache) == 0 await create_handler.add_guild_options(1, Options(no_punish=True)) assert len(create_handler.cache.cache) == 1 assert create_handler.cache.cache.get(1) is not None await create_handler.add_guild_options(1, Options(no_punish=False)) assert create_handler.cache.cache.get(1).options == Options(no_punish=False)
async def test_get_all_guilds(self, create_redis_cache): guilds = await FactoryBuilder.get_all_guilds_as_list(create_redis_cache) assert len(guilds) == 0 await create_redis_cache.set_guild(Guild(1, Options())) guilds = await FactoryBuilder.get_all_guilds_as_list(create_redis_cache) assert len(guilds) == 1 await create_redis_cache.set_guild(Guild(2, Options())) guilds = await FactoryBuilder.get_all_guilds_as_list(create_redis_cache) assert len(guilds) == 2 assert guilds == [Guild(1, Options()), Guild(2, Options())]
def test_remove_duplicate_count(self, create_core): member = Member(1, 1) member.duplicate_counter = 5 member.duplicate_channel_counter_dict = {15: 2} assert member.duplicate_counter == 5 assert member.duplicate_channel_counter_dict == {15: 2} create_core._remove_duplicate_count(member, 1) assert member.duplicate_counter == 4 assert member.duplicate_channel_counter_dict == {15: 2} create_core._remove_duplicate_count(member, 1, 2) assert member.duplicate_counter == 2 assert member.duplicate_channel_counter_dict == {15: 2} create_core.options = Options(per_channel_spam=True) create_core._remove_duplicate_count(member, 15) assert member.duplicate_counter == 2 assert member.duplicate_channel_counter_dict == {15: 1} create_core._remove_duplicate_count(member, 1) assert member.duplicate_counter == 2 assert member.duplicate_channel_counter_dict == {15: 1}
def create_handler(): """Create a simple handler for usage""" mock = MockedMember(mock_type="bot").to_mock() mock.get_guild = Mock() return AntiSpamHandler(mock, library=Library.DPY, options=Options(use_timeouts=False))
async def test_get_guild_data_fails_on_guild_addon( self, create_plugin_cache: PluginCache, create_handler): """Test the cache raises GuildAddonNotFound""" await create_handler.cache.set_guild(Guild(1, Options())) with pytest.raises(GuildAddonNotFound): await create_plugin_cache.get_guild_data(1)
async def test_set_get_guild_valid_interval(self, create_anti_spam_tracker): await create_anti_spam_tracker.anti_spam_handler.cache.set_guild( Guild(1, Options())) result = await create_anti_spam_tracker.anti_spam_handler.cache.get_guild( 1) assert len(result.addons) == 0 await create_anti_spam_tracker._set_guild_valid_interval(1, 15) result = await create_anti_spam_tracker.anti_spam_handler.cache.get_guild( 1) assert len(result.addons) == 1 get_result = await create_anti_spam_tracker._get_guild_valid_interval(1 ) assert get_result == 15 # Code coverage to ensure it works within try await create_anti_spam_tracker._set_guild_valid_interval(1, 25) result = await create_anti_spam_tracker.anti_spam_handler.cache.get_guild( 1) assert len(result.addons) == 1 get_result = await create_anti_spam_tracker._get_guild_valid_interval(1 ) assert get_result == 25
async def test_load_from_dict_fails(self, create_bot): test_data = { "cache": "MemoryCache", "options": asdict(Options()), "XD": 1, "guilds": [ { "id": 1, "options": asdict(Options()), "log_channel": MockClass, "members": [ { "id": 1, "guild_id": 2, "is_in_guild": True, "warn_count": 5, "kick_count": 6, "duplicate_count": 7, "duplicate_channel_counter_dict": {}, "messages": [ { "id": 1, "content": "Hello World!", "guild_id": 2, "author_id": 3, "channel_id": 4, "is_duplicate": True, "creation_time": "225596:21:8:3:12:5:2021", } ], }, ], "Random_data": "LOL", } ], } await AntiSpamHandler.load_from_dict( MagicMock(side_effect=discord.HTTPException), test_data, Library.DPY ) await AntiSpamHandler.load_from_dict( create_bot, 1, Library.DPY, raise_on_exception=False ) with pytest.raises(TypeError): await AntiSpamHandler.load_from_dict(create_bot, 1, Library.DPY)
async def test_add_message_filled_guild(self, create_redis_cache): """Test with an existing guild""" await create_redis_cache.set_guild(Guild(3, Options())) await create_redis_cache.add_message(Message(1, 2, 3, 4, "Content")) r_1 = await create_redis_cache.get_member(4, 3) r_2 = await create_redis_cache.get_guild(3) assert len(r_2.members) == 1 assert len(r_1.messages) == 1
async def test_get_member(self, create_memory_cache): await create_memory_cache.set_guild(Guild(1, Options())) with pytest.raises(MemberNotFound): await create_memory_cache.get_member(1, 1) create_memory_cache.cache[1].members[1] = 2 val = await create_memory_cache.get_member(1, 1) assert val == 2
async def test_save_to_dict(self, create_handler: AntiSpamHandler): await create_handler.save_to_dict() await create_handler.cache.set_guild(Guild(1, Options())) data = await create_handler.save_to_dict() with open("tests/raw.json", "r") as file: stored_data = json.load(file) assert data == stored_data
async def test_conflicting_init_args(self, create_bot): options = Options( no_punish=True, delete_spam=True, warn_only=True, per_channel_spam=True, use_timeouts=False, ) AntiSpamHandler(create_bot, Library.DPY, options=options)
async def test_get_member(self, create_redis_cache): await create_redis_cache.set_guild(Guild(1, Options())) with pytest.raises(MemberNotFound): await create_redis_cache.get_member(1, 1) await create_redis_cache.set_member(Member(1, 1)) val = await create_redis_cache.get_member(1, 1) assert val assert isinstance(val, Member)
async def test_punish_member(self, create_dpy_lib_handler): """Adds test coverage""" await create_dpy_lib_handler.punish_member( MockedMessage(author_id=1, guild_id=1).to_mock(), Member(1, 1), Guild(1, Options()), "test user", "test guild", True, )
async def test_propagate_exits(self): bot = AsyncMock() bot.user.id = 9 create_handler = AntiSpamHandler(bot) # TODO Until files get stubbed, we cant check this. """ with pytest.raises(ValueError): await create_handler.propagate(1) with pytest.raises(ValueError): await create_handler.propagate("2") with pytest.raises(ValueError): await create_handler.propagate(MockClass) """ return_data = await create_handler.propagate( MockedMessage(is_in_guild=False).to_mock() ) assert return_data["status"] == "Ignoring messages from dm's" return_data = await create_handler.propagate( MockedMessage(author_id=9).to_mock() ) assert return_data["status"] == "Ignoring messages from myself (the bot)" create_handler.options = Options(ignore_bots=True) return_data = await create_handler.propagate( MockedMessage(author_is_bot=True).to_mock() ) assert return_data["status"] == "Ignoring messages from bots" create_handler.options = Options() create_handler.options.ignored_members.add(12345) return_data = await create_handler.propagate(MockedMessage().to_mock()) assert return_data["status"] == "Ignoring this member: 12345" create_handler.options.ignored_members.discard(12345) create_handler.options.ignored_channels.add(98987) return_data = await create_handler.propagate(MockedMessage().to_mock()) assert return_data["status"] == "Ignoring this channel: 98987" create_handler.options.ignored_channels.discard(98987)
async def test_remove_guild_log_channel(self, create_handler: AntiSpamHandler): await create_handler.remove_guild_log_channel(1) # shouldnt raise await create_handler.cache.set_guild(Guild(1, Options(), log_channel_id=1)) result = await create_handler.cache.get_guild(1) assert result.log_channel_id == 1 await create_handler.remove_guild_log_channel(1) result = await create_handler.cache.get_guild(1) assert result.log_channel_id is None
async def test_set_member(self, create_memory_cache): await create_memory_cache.set_member(Member(1, 1)) await create_memory_cache.set_member(Member(2, 1)) assert len(create_memory_cache.cache[1].members) == 2 await create_memory_cache.set_guild(Guild(1, Options())) assert len(create_memory_cache.cache[1].members) == 0 await create_memory_cache.set_member(Member(1, 1)) assert len(create_memory_cache.cache[1].members) == 1
async def test_basic_timeout_func(self, create_core): create_core.handler.lib_handler = Nextcord(create_core.handler) g = Guild(1, options=Options(use_timeouts=True)) member = Member(1, 1, duplicate_counter=5) # Force a punishment g.members[member.id] = member await create_core.cache.set_guild(g) r_1 = await create_core.propagate( MockedMessage(author_id=1, guild_id=1).to_mock(), g) assert r_1.member_was_timed_out is True assert r_1.member_should_be_punished_this_message is True
def test_get_duplicate_count(self, create_core): member = Member(1, 1) member.duplicate_counter = 5 member.duplicate_channel_counter_dict = {15: 2} assert create_core._get_duplicate_count(member, 1) == 5 create_core.options = Options(per_channel_spam=True) assert create_core._get_duplicate_count(member) == 1 assert create_core._get_duplicate_count(member, 5) == 1 assert create_core._get_duplicate_count(member, 15) == 2
async def test_punish_member_raises(self, create_dpy_lib_handler): with pytest.raises(MissingGuildPermissions): # Test kick has kick perms message = MockedMessage(author_id=1, guild_id=1).to_mock() message.guild.me.guild_permissions.kick_members = False await create_dpy_lib_handler.punish_member( message, Member(1, 1), Guild(1, Options()), "test user", "test guild", True, ) with pytest.raises(MissingGuildPermissions): # Test ban has ban perms message = MockedMessage(author_id=1, guild_id=1).to_mock() message.guild.me.guild_permissions.ban_members = False await create_dpy_lib_handler.punish_member( message, Member(1, 1), Guild(1, Options()), "test user", "test guild", False, ) with pytest.raises(MissingGuildPermissions): # Check errors on guild owner message = MockedMessage(author_id=1, guild_id=1).to_mock() message.guild.owner_id = 1 await create_dpy_lib_handler.punish_member( message, Member(1, 1), Guild(1, Options()), "test user", "test guild", True, )
async def test_clean_cache_strict_guild(self, create_handler): """Tests clean_cache on guilds with strict mode""" await create_handler.cache.set_guild(Guild(1)) assert bool(create_handler.cache.cache) await create_handler.clean_cache(strict=True) assert not bool(create_handler.cache.cache) await create_handler.cache.set_guild(Guild(1, Options(no_punish=True))) assert bool(create_handler.cache.cache) await create_handler.clean_cache(strict=True) assert bool(create_handler.cache.cache)
async def test_unsupported_timeouts(self, create_core): g = Guild(1, options=Options(use_timeouts=True)) member = Member(1, 1, duplicate_counter=5) # Force a punishment g.members[member.id] = member await create_core.cache.set_guild(g) mock = MockedMessage(author_id=1, guild_id=1).to_mock() # Also cover raises on attempted sends mock.author.send = AsyncMock( side_effect=Exception("Cannot send messages to this person.")) with pytest.raises(UnsupportedAction): await create_core.propagate(mock, g)
def test_calculate_ratios_per_channel(self, create_core): member = Member(1, 1) member.messages = [ Message(1, 1, 1, 1, "Hello world", datetime.datetime.now()) ] message = Message(2, 2, 1, 1, "Hello world", datetime.datetime.now()) guild = Guild(1, options=Options(per_channel_spam=True)) assert member.duplicate_counter == 1 create_core._calculate_ratios(message, member, guild) assert member.duplicate_counter == 1 assert message.is_duplicate is False
def test_increment_duplicate_count(self, create_core): member = Member(1, 1) assert member.duplicate_counter == 1 create_core._increment_duplicate_count(member, 1) assert member.duplicate_counter == 2 create_core._increment_duplicate_count(member, 1, 3) assert member.duplicate_counter == 5 create_core.options = Options(per_channel_spam=True) create_core._increment_duplicate_count(member, 1, 1) assert member.duplicate_channel_counter_dict == {1: 2}
async def test_propagate_no_punish(self, create_core): g = Guild(1, Options(no_punish=True)) await create_core.cache.set_guild(g) member = Member(1, 1) await create_core.cache.set_member(member) create_core._increment_duplicate_count(member, g, 1, 15) guild = await create_core.cache.get_guild(1) return_data = await create_core.propagate_user( MockedMessage(guild_id=1, author_id=1).to_mock(), guild) assert return_data == CorePayload( member_should_be_punished_this_message=True, member_status= "Member should be punished, however, was not due to no_punish being True", )
async def test_set_member(self, create_redis_cache): await create_redis_cache.set_member(Member(1, 1)) await create_redis_cache.set_member(Member(2, 1)) r_1 = await create_redis_cache.get_guild(1) assert len(r_1.members) == 2 await create_redis_cache.set_guild(Guild(1, Options())) r_2 = await create_redis_cache.get_guild(1) assert len(r_2.members) == 0 await create_redis_cache.set_member(Member(1, 1)) r_3 = await create_redis_cache.get_guild(1) assert len(r_3.members) == 1