Commit d5008d33 authored by Jeremy Pallats's avatar Jeremy Pallats 💬
Browse files

Merge branch 'whois_update' into 'master'

FIX #93 Update !whois command

See merge request !31
parents b3eb3146 24db26ff
Loading
Loading
Loading
Loading
Loading
+49 −2
Original line number Diff line number Diff line
@@ -1111,7 +1111,9 @@ class KOS(Action):
        reason = ' '.join(self.args.reason) + " -{}".format(self.msg.author.name)
        is_friendly = self.args.is_friendly
        await self.msg.channel.send('CMDR {} has been reported for moderation.'.format(cmdr))
        await self.send_to_moderation(cmdr, faction, reason, is_friendly)

    async def send_to_moderation(self, cmdr, faction, reason, is_friendly):
        # Request approval
        chan = self.msg.guild.get_channel(cog.util.get_config("carrier_channel"))
        sent = await chan.send(
@@ -1128,6 +1130,7 @@ class KOS(Action):
                return cogdb.query.get_admin(self.session, user)
            except cog.exc.NoMatch:
                return False

        react, _ = await self.bot.wait_for('reaction_add', check=check)

        # Approved update
@@ -1834,10 +1837,54 @@ class WhoIs(Action):
    """
    Who is request to Inara for CMDR info.
    """
    async def send_to_moderation(self, cmdr, faction, reason, is_friendly):
        # Request approval
        chan = self.msg.guild.get_channel(cog.util.get_config("carrier_channel"))
        reason, _ = reason
        sent = await chan.send(
            embed=cog.inara.kos_report_cmdr_embed(
                self.msg.author.name, cmdr, faction, reason, is_friendly,
            )
        )
        yes_emoji = cog.util.get_config('emojis', '_yes')
        await sent.add_reaction(yes_emoji)
        await sent.add_reaction(cog.util.get_config('emojis', '_no'))

        def check(_, user):
            try:
                return cogdb.query.get_admin(self.session, user)
            except cog.exc.NoMatch:
                return False

        react, _ = await self.bot.wait_for('reaction_add', check=check)

        # Approved update
        response = "No change to KOS made."
        if str(react) == yes_emoji:
            scanner = get_scanner('hudson_kos')
            await scanner.update_cells()
            payload = scanner.add_report_dict(
                cmdr, faction, reason, is_friendly
            )
            await scanner.send_batch(payload)
            cogdb.query.kos_add_cmdr(self.session, cmdr, faction, reason, is_friendly)
            self.session.commit()
            response = "CMDR has been added to KOS."

        await chan.send(response)

    async def execute(self):
        cmdr = await cog.inara.api.search_with_api(' '.join(self.args.cmdr), self.msg)
        if cmdr:
            await cog.inara.api.reply_with_api_result(cmdr["req_id"], cmdr["event_data"], self.msg)
        if cmdr and cmdr != (None, None):
            returned_from_api = False
            squad = "Unknown"
            if "req_id" in cmdr:
                returned_from_api, squad = await cog.inara.api.reply_with_api_result(cmdr["req_id"], cmdr["event_data"], self.msg)
                cmdr = "Manual report after a !whois in {channel} by cmdr {reported_by}" \
                    .format(channel=self.msg.channel, reported_by=self.msg.author), True
            if returned_from_api is not None:
                await self.send_to_moderation(self.args.cmdr[0], squad, cmdr, returned_from_api)
                return None


def is_near_tick():
+53 −3
Original line number Diff line number Diff line
@@ -211,7 +211,6 @@ class InaraApi():
            if event["eventStatus"] == API_RESPONSE_CODES["no result"]:
                response = "__Inara__ Could not find CMDR **{}**".format(cmdr_name)
                futs = []

                # Even if not on inara.cz, lookup in kos
                with cogdb.session_scope(cogdb.Session) as session:
                    embeds = kos_lookup_cmdr_embeds(session, cmdr_name)
@@ -224,7 +223,10 @@ class InaraApi():
                futs = [cog.util.BOT.send_message(msg.channel, response)] + futs
                for fut in futs:
                    await fut
                return None  # No reason to go further
                if not embeds:
                    cmdr = {"name": cmdr_name}
                    return await self.adding_to_kos(cmdr, msg)  # No reason to go further
                return None

            event_data = event["eventData"]

@@ -397,10 +399,12 @@ class InaraApi():

        embeds = []

        with_squad = True
        try:
            cmdr["squad"] = event_data["commanderSquadron"].get("squadronName", cmdr["squad"])
            embeds += [await self.squad_details(event_data, cmdr)]
        except KeyError:
            with_squad = False
            pass

        cmdr_embed = discord.Embed.from_dict({
@@ -429,12 +433,58 @@ class InaraApi():
        embeds = [cmdr_embed] + embeds

        with cogdb.session_scope(cogdb.Session) as session:
            embeds += kos_lookup_cmdr_embeds(session, cmdr['name'], cmdr['profile_picture'])
            returned_embed = kos_lookup_cmdr_embeds(session, cmdr['name'], cmdr['profile_picture'])
            embeds += returned_embed

        futs = [cog.util.BOT.send_message(msg.channel, embed=embed) for embed in embeds]
        futs += [self.delete_waiting_message(req_id)]
        for fut in futs:
            await fut

        return await self.friendly_detector(cmdr, with_squad, returned_embed, msg)

    async def friendly_detector(self, cmdr, with_squad, returned_embed, msg):
        if not returned_embed:
            returned_addition, is_friendly = await self.adding_to_kos(cmdr, msg)
            if returned_addition is None:
                return None, None
            cmdr_squad = "Unknown"
            if with_squad:
                cmdr_squad = cmdr["squad"]
            return is_friendly, cmdr_squad
        return None, None

    async def adding_to_kos(self, cmdr, msg):
        req_id = self.req_counter
        sent = [await cog.util.BOT.send_message(
            msg.channel,
            "Should the CMDR {} be added as friendly or hostile? Use reactions below to select. Use X to ignore."
                .format(cmdr["name"]))]

        self.waiting_messages[req_id] = sent[0]
        friendly_emote = cog.util.get_config('emojis', '_friendly')
        canceled_emote = cog.util.get_config('emojis', '_no')
        await sent[0].add_reaction(friendly_emote)
        await sent[0].add_reaction(cog.util.get_config('emojis', '_hostile'))
        await sent[0].add_reaction(canceled_emote)

        def check(_, user):
            return user == msg.author

        react, _ = await cog.util.BOT.wait_for('reaction_add', check=check)

        # Approved update
        response = "Command ignored."
        reason, is_friendly = None, None
        if str(react) != canceled_emote:
            is_friendly = str(react) == friendly_emote
            reason = "Manual report after a !whois in {channel} by cmdr {reported_by}" \
                .format(channel=msg.channel, reported_by=msg.author)
            response = "CMDR has been reported to Leadership."
        await cog.util.BOT.send_message(msg.channel, response)
        await self.delete_waiting_message(req_id)
        return reason, is_friendly


def check_reply(msg, prefix='!'):
    """
+38 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ from cogdb.schema import (DiscordUser, FortSystem, FortDrop, FortUser,

from tests.conftest import fake_msg_gears, fake_msg_newuser
import tests.conftest as tc
from tests.cog.test_inara import INARA_TEST


# Important, any fixtures in here get auto run
@@ -40,6 +41,9 @@ def patch_scanners():
    async def get_batch_(*args):
        return scanner._values

    async def update_cells_():
        return True

    mock_cls = aiomock.Mock()
    mock_cls.update_sheet_user_dict.return_value = [
        {'range': 'A20:B20', 'values': [['test cry', 'test name']]},
@@ -47,6 +51,7 @@ def patch_scanners():
    scanner.__class__ = mock_cls
    scanner.send_batch = send_batch_
    scanner.get_batch = get_batch_
    scanner.update_cells = update_cells_
    cog.actions.SCANNERS = {
        'hudson_cattle': scanner,
        'hudson_kos': scanner,
@@ -1613,6 +1618,39 @@ async def test_cmd_vote_display(f_bot, f_admins, f_dusers, f_global_testbed, f_v
    f_bot.send_message.assert_called_with(msg.channel, 'Will now SHOW the vote goal.')


@INARA_TEST
@pytest.mark.asyncio
async def test_cmd_whois_canceled(f_bot, f_asheet_kos, f_kos):
    emoji_no = "\u274C"
    msg = fake_msg_gears("!whois Prozer")
    f_bot.wait_for.async_return_value = emoji_no, None

    await action_map(msg, f_bot).execute()
    f_bot.send_message.assert_called_with(msg.channel, 'Command ignored.')


@INARA_TEST
@pytest.mark.asyncio
async def test_cmd_whois_friendly(f_bot, f_asheet_kos, f_kos):
    emoji_friendly = "\u1F7E2"
    f_bot.wait_for.async_return_value = emoji_friendly, None
    msg = fake_msg_gears("!whois Prozer")

    await action_map(msg, f_bot).execute()
    f_bot.send_message.assert_called_with(msg.channel, 'CMDR has been reported to Leadership.')


@INARA_TEST
@pytest.mark.asyncio
async def test_cmd_whois_hostile(f_bot, f_asheet_kos, f_kos):
    emoji_hostile = "\u1F534"
    f_bot.wait_for.async_return_value = emoji_hostile, None
    msg = fake_msg_gears("!whois Prozer")

    await action_map(msg, f_bot).execute()
    f_bot.send_message.assert_called_with(msg.channel, 'CMDR has been reported to Leadership.')


def test_process_system_args():
    args = ['This  ,  ', 'is ,   ', '   an,', ' example.']
    results = cog.actions.process_system_args(args)
+51 −2
Original line number Diff line number Diff line
@@ -67,14 +67,63 @@ async def test_search_with_api(f_bot):
@pytest.mark.asyncio
async def test_reply_with_api_result(f_bot):
    api = cog.inara.InaraApi()
    f_bot.wait_for.async_return_value = fake_msg_gears('stop')
    f_bot.wait_for.async_return_value = (fake_msg_gears('stop'), None)
    f_bot.send_message.async_return_value = fake_msg_gears("A message to send.")
    cog.util.BOT = f_bot
    f_msg = fake_msg_gears('!whois gearsandcogs')
    cmdr = await api.search_with_api('gearsandcogs', f_msg)
    await api.reply_with_api_result(cmdr["req_id"], cmdr["event_data"], f_msg)

    # TODO: Very lazy check :/
    assert 'embed=<discord.embeds.Embed' in str(f_bot.send_message.call_args)
    assert "CMDR has been reported to Leadership." in str(f_bot.send_message.call_args)


@pytest.mark.asyncio
async def test_friendly_detector_already_in_kos(f_bot):
    api = cog.inara.InaraApi()
    f_msg = fake_msg_gears('!whois Prozer')
    f_bot.wait_for.async_return_value = True, None
    is_friendly_returned, squad_returned = await api.friendly_detector(None, False, ["test embed"], f_msg)

    assert is_friendly_returned is None and squad_returned is None


@pytest.mark.asyncio
async def test_friendly_detector_canceled(f_bot):
    api = cog.inara.InaraApi()
    f_msg = fake_msg_gears('!whois Prozer')
    emoji_cancel = "\u274C"
    f_bot.wait_for.async_return_value = emoji_cancel, None
    cmdr = {"name": "Prozer", "allegiance": "Federation"}
    is_friendly_returned, squad_returned = await api.friendly_detector(cmdr, False, [], f_msg)

    assert is_friendly_returned is None and squad_returned is None


@pytest.mark.asyncio
async def test_friendly_detector_friendly_no_squad(f_bot):
    api = cog.inara.InaraApi()
    f_msg = fake_msg_gears('!whois Prozer')
    emoji_friendly = "\U0001F7E2"
    f_bot.wait_for.async_return_value = emoji_friendly, None
    cmdr = {"name": "Prozer", "allegiance": "Federation"}
    is_friendly_returned, squad_returned = await api.friendly_detector(cmdr, False, [], f_msg)

    assert is_friendly_returned
    assert squad_returned == "Unknown"


@pytest.mark.asyncio
async def test_friendly_detector_hostile_with_squad(f_bot):
    api = cog.inara.InaraApi()
    emoji_hostile = "\U0001F534"
    f_bot.wait_for.async_return_value = emoji_hostile, None
    f_msg = fake_msg_gears('!whois Akeno')
    cmdr = {"name": "Akeno", "allegiance": "Empire", "squad": "Test"}
    is_friendly_returned, squad_returned = await api.friendly_detector(cmdr, True, [], f_msg)

    assert not is_friendly_returned
    assert squad_returned == "Test"


@INARA_TEST
+22 −6
Original line number Diff line number Diff line
@@ -411,6 +411,9 @@ class Guild(FakeObject):
    def members(self):
        return list(self.mapped.values())

    def get_channel(self, channel):
        return [guild_channel for guild_channel in self.channels if guild_channel.id == channel][0]

    # def __repr__(self):
        # channels = "\n  Channels: " + ", ".join([cha.name for cha in self.channels])
        # return super().__repr__() + channels
@@ -429,6 +432,7 @@ class Channel(FakeObject):
        super().__init__(name, id)
        self.guild = srv
        self.all_delete_messages = []
        self.send_messages = None

    # def __repr__(self):
        # return super().__repr__() + ", Server: {}".format(self.server.name)
@@ -438,6 +442,9 @@ class Channel(FakeObject):
            msg.is_deleted = True
        self.all_delete_messages += messages

    async def send(self, embed):
        return Message(embed, None, self.guild, None)


class Member(FakeObject):
    def __init__(self, name, roles, *, id=None):
@@ -475,6 +482,7 @@ class Message(FakeObject):
        self.role_mentions = role_mentions
        self.guild = srv
        self.is_deleted = False
        self.reaction = []

    # def __repr__(self):
        # return super().__repr__() + "\n  Content: {}\n  Author: {}\n  Channel: {}\n  Server: {}".format(
@@ -491,6 +499,9 @@ class Message(FakeObject):
    async def delete(self):
        self.is_deleted = True

    async def add_reaction(self, emote):
        self.reaction.append(emote)


def fake_servers():
    """ Generate fake discord servers for testing. """
@@ -498,7 +509,8 @@ def fake_servers():
    channels = [
        Channel("feedback", srv=srv, id=10),
        Channel("live_hudson", srv=srv, id=11),
        Channel("private_dev", srv=srv, id=12)
        Channel("private_dev", srv=srv, id=12),
        Channel("carrier_channel", srv=srv, id=13)
    ]
    for cha in channels:
        srv.add(cha)
@@ -550,7 +562,7 @@ def f_bot():
    fake_bot.guilds = fake_servers()
    fake_bot.get_channel_by_name.return_value = 'private_dev'
    # fake_bot.msgs = []

    #
    # async def send_message_(_, msg):
    #     fake_bot.msgs += msg
    # fake_bot.send_message.async_side_effect = send_message_
@@ -603,6 +615,9 @@ def f_asheet():
        async with aiofiles.open(asheet.filename, 'r') as fin:
            return eval(await fin.read())

    async def update_cells_():
        return True

    asheet.batch_get.async_return_value = None
    asheet.batch_update = batch_update_send_
    asheet.batch_get = batch_update_get_
@@ -612,6 +627,7 @@ def f_asheet():
    asheet.values_col = values_col_
    asheet.values_row = values_row_
    asheet.whole_sheet = whole_sheet_
    asheet.update_cells = update_cells_

    yield asheet

Loading