def setUp(self):
        self.username = '******'
        self.gh_uid = 4738549
        self.default_payload = org_default_payload(self.username, self.gh_uid)
        self.add_payload = org_default_payload(self.username, self.gh_uid)
        self.rm_payload = org_default_payload(self.username, self.gh_uid)
        self.invite_payload = org_default_payload(self.username, self.gh_uid)
        self.empty_payload = org_default_payload(self.username, self.gh_uid)

        self.add_payload['action'] = 'member_added'
        self.rm_payload['action'] = 'member_removed'
        self.invite_payload['action'] = 'member_invited'
        self.empty_payload['action'] = ''

        self.u0 = User('U01234954')
        self.u0.github_id = str(self.gh_uid)
        self.u0.github_username = self.username
        self.team_all = Team('1', 'all', 'Team all')
        self.db = MemoryDB(users=[self.u0], teams=[self.team_all])

        self.gh = mock.Mock()
        self.conf = mock.Mock()
        self.conf.github_team_all = 'all'
        self.webhook_handler = OrganizationEventHandler(self.db, self.gh,
                                                        self.conf)
Exemple #2
0
    def setUp(self):
        self.team = 'rocket'
        self.teamid = 4934950
        self.newteam = 'someteam'
        self.newteamid = 4028940
        self.created_payload = team_default_payload(self.newteam,
                                                    self.newteamid)
        self.deleted_payload = team_default_payload(self.team, self.teamid)
        self.edited_payload = team_default_payload(self.team, self.teamid)
        self.added_to_repo_payload = team_default_payload(
            self.team, self.teamid)
        self.rm_from_repo_payload = team_default_payload(
            self.team, self.teamid)
        self.empty_payload = team_default_payload(self.team, self.teamid)
        self.created_payload['action'] = 'created'
        self.deleted_payload['action'] = 'deleted'
        self.edited_payload['action'] = 'edited'
        self.added_to_repo_payload['action'] = 'added_to_repository'
        self.rm_from_repo_payload['action'] = 'removed_from_repository'
        self.empty_payload['action'] = ''

        self.t = Team(str(self.teamid), self.team, self.team.capitalize())
        self.db = MemoryDB(teams=[self.t])

        self.gh = mock.Mock()
        self.conf = mock.Mock()
        self.webhook_handler = TeamEventHandler(self.db, self.gh, self.conf)
Exemple #3
0
 def setUp(self):
     self.u_id = 'U012A3CDE'
     self.db = MemoryDB()
     self.bot = mock.Mock()
     self.handler = SlackEventsHandler(self.db, self.bot)
     self.event = {
         'token': 'XXYYZZ',
         'team_id': 'TXXXXXXXX',
         'api_app_id': 'AXXXXXXXXX',
         'event': {
             'type': 'team_join',
             'user': {
                 'id': self.u_id,
                 'team_id': 'T012AB3C4',
                 'name': 'spengler',
                 'deleted': False,
                 'color': '9f69e7',
                 'real_name': 'Egon Spengler',
                 'tz': 'America/Los_Angeles',
                 'tz_label': 'Pacific Daylight Time',
                 'tz_offset': -25200,
                 'profile': {
                     'avatar_hash': 'ge3b51ca72de',
                     'status_text': 'Print is dead',
                     'status_emoji': ':books:',
                     'status_expiration': 1502138999,
                     'real_name': 'Egon Spengler',
                     'display_name': 'spengler',
                     'real_name_normalized': 'Egon Spengler',
                     'display_name_normalized': 'spengler',
                     'email': '*****@*****.**',
                     'image_24': 'https://.../avatar/hello.jpg',
                     'image_32': 'https://.../avatar/hello.jpg',
                     'image_48': 'https://.../avatar/hello.jpg',
                     'image_72': 'https://.../avatar/hello.jpg',
                     'image_192': 'https://.../avatar/hello.jpg',
                     'image_512': 'https://.../avatar/hello.jpg',
                     'team': 'T012AB3C4'
                 },
                 'is_admin': True,
                 'is_owner': False,
                 'is_primary_owner': False,
                 'is_restricted': False,
                 'is_ultra_restricted': False,
                 'is_bot': False,
                 'is_stranger': False,
                 'updated': 1502138686,
                 'is_app_user': False,
                 'has_2fa': False,
                 'locale': 'en-US'
             }
         },
         'type': 'app_mention',
         'authed_users': ['UXXXXXXX1', 'UXXXXXXX2'],
         'event_id': 'Ev08MFMKH6',
         'event_time': 1234567890
     }
Exemple #4
0
    def setUp(self):
        self.app = Flask(__name__)

        self.u0 = User('U0G9QF9C6')
        self.u1 = User('Utheomadude')
        self.admin = create_test_admin('Uadmin')
        self.db = MemoryDB(users=[self.u0, self.u1, self.admin])

        self.mock_github = mock.MagicMock(GithubInterface)
        self.testcommand = UserCommand(self.db, self.mock_github, None)
        self.maxDiff = None
Exemple #5
0
    def setUp(self):
        self.app = Flask(__name__)

        self.u0 = User('U0G9QF9C6')
        self.u1 = User('Utheomadude')
        self.t0 = Team("BRS", "brs", "web")
        self.t1 = Team("OTEAM", "other team", "android")
        self.admin = create_test_admin('Uadmin')
        self.db = MemoryDB(users=[self.u0, self.u1, self.admin],
                           teams=[self.t0, self.t1])

        self.mock_github = mock.MagicMock(GithubInterface)
        self.testcommand = UserCommand(self.db, self.mock_github, None)
        self.maxDiff = None
    def setUp(self):
        self.team = 'rocket'
        self.teamid = 395830
        self.member = 'theflatearth'
        self.memberid = 3058493
        self.add_payload = mem_default_payload(self.team, self.teamid,
                                               self.member, self.memberid)
        self.rm_payload = mem_default_payload(self.team, self.teamid,
                                              self.member, self.memberid)
        self.empty_payload = mem_default_payload(self.team, self.teamid,
                                                 self.member, self.memberid)

        self.add_payload['action'] = 'added'
        self.rm_payload['action'] = 'removed'
        self.empty_payload['action'] = ''

        self.u = User('U4058409')
        self.u.github_id = str(self.memberid)
        self.u.github_username = self.member
        self.t = Team(str(self.teamid), self.team, self.team.capitalize())
        self.db = MemoryDB(users=[self.u], teams=[self.t])

        self.gh = mock.Mock()
        self.conf = mock.Mock()
        self.conf.github_team_all = 'all'
        self.webhook_handler = MembershipEventHandler(self.db, self.gh,
                                                      self.conf)
Exemple #7
0
    def setUp(self):
        self.u = User('U12345')
        self.admin = create_test_admin('Uadmin')
        self.db = MemoryDB(users=[self.u, self.admin])

        self.testcommand = TokenCommand(
            self.db, TokenCommandConfig(timedelta(days=7), 'secret'))
Exemple #8
0
    def setUp(self):
        self.u0 = User('U0G9QF9C6')
        self.u0.email = '*****@*****.**'
        self.u0.github_id = '305834954'

        self.u1 = User('Utheomadude')
        self.u1.email = '*****@*****.**'
        self.u1.github_id = '349850564'

        self.admin = create_test_admin('Uadmin')

        self.lead = User('Ualley')
        self.lead.email = '*****@*****.**'
        self.lead.github_id = '2384858'
        self.lead.permissions_level = Permissions.team_lead

        self.t0 = Team('305849', 'butter-batter', 'Butter Batters')
        self.t0.add_member(self.u0.github_id)
        self.t0.add_member(self.lead.github_id)
        self.t0.add_team_lead(self.lead.github_id)

        self.t1 = Team('320484', 'aqua-scepter', 'Aqua Scepter')
        self.t1.add_member(self.u1.github_id)

        self.t2 = Team('22234', 'tiger-dear', 'Shakespearean')

        self.db = MemoryDB(users=[self.u0, self.u1, self.admin, self.lead],
                           teams=[self.t0, self.t1, self.t2])

        self.cmd = ExportCommand(self.db)
Exemple #9
0
    def setUp(self):
        self.app = Flask(__name__)

        self.u0 = User('U03548940')
        self.u0.github_username = '******'
        self.u0.github_id = '534593'
        self.admin = create_test_admin('Uadmin')
        self.p0 = create_test_project(
            'GTID', ['https://github.com/ubclaunchpad/rocket2'])
        self.p1 = create_test_project(
            '', ['https://github.com/ubclaunchpad/rocket2'])
        self.t0 = Team('GTID', 'team-name', 'name')
        self.db = MemoryDB(users=[self.u0, self.admin],
                           teams=[self.t0],
                           projs=[self.p0, self.p1])

        self.testcommand = ProjectCommand(self.db)
Exemple #10
0
    def setUp(self):
        self.app = Flask(__name__)

        self.u0 = User('UFJ42EU67')
        self.u0.name = 'steve'
        self.u1 = User('U12346456')
        self.u1.name = 'maria'
        self.db = MemoryDB(users=[self.u0, self.u1])

        self.testcommand = MentionCommand(self.db)
Exemple #11
0
    def setUp(self):
        self.app = Flask(__name__)

        self.u0 = User('U0G9QF9C6')
        self.u0.karma = KarmaCommand.karma_default_amount
        self.u1 = User('UFJ42EU67')
        self.u0.karma = KarmaCommand.karma_default_amount
        self.admin = create_test_admin('Uadmin')
        self.db = MemoryDB(users=[self.u0, self.u1, self.admin])

        self.testcommand = KarmaCommand(self.db)
        self.maxDiff = None
Exemple #12
0
 def setUp(self):
     self.u0 = User('U395474')
     self.u0.github_id = '321132'
     self.u1 = User('U85739')
     self.u1.github_id = '000584'
     self.u2 = User('U3048485')
     self.u2.github_id = '11121'
     self.t0 = Team('305738', 'some-team', 'Some Team')
     self.t0.add_member(self.u0.github_id)
     self.t0.add_member(self.u1.github_id)
     self.t1 = Team('305849', 'some-team', 'Some Team')
     self.db = MemoryDB(users=[self.u0, self.u1, self.u2], teams=[self.t0])
    def setUp(self):
        self.u0 = User('U93758')
        self.u0.github_id = '22343'
        self.u0.github_username = '******'
        self.u0.email = '*****@*****.**'

        self.t0 = Team('465884', 'team-plasma', 'Team Plasma')
        self.t0.add_member(self.u0.github_id)
        self.t0.folder = 'oieasotbokneawsoieomieaomiewrsdoie'

        self.t1 = Team('394783', 'team-rocket', 'Team Rocket')
        self.t1.add_member(self.u0.github_id)

        self.db = MemoryDB(users=[self.u0], teams=[self.t0, self.t1])

        self.gcp = mock.MagicMock(GCPInterface)
Exemple #14
0
 def setUp(self):
     self.users = {
         'u1': make_user('u1', 'g1', 'G1', Permissions.admin),
         'u2': make_user('u2', 'g2', 'G2', Permissions.member),
         'u3': make_user('u3', 'g3', 'G3', Permissions.team_lead),
         'u4': make_user('u4', 'g4', 'G4', Permissions.team_lead),
         'u5': make_user('u5', 'g5', 'G5', Permissions.member),
         'u6': make_user('u6', 'g6', 'G6', Permissions.member)
     }
     self.teams = {
         't1': make_team('t1', [], []),
         't2': make_team('t2', ['g1', 'g3'], ['g1', 'g2', 'g3']),
         't3': make_team('t3', ['g1'], ['g1', 'g4', 'g2', 'g5', 'g6']),
         't4': make_team('t4', [], ['g6']),
         't5': make_team('t5', ['g4'], ['g5', 'g3']),
         't6': make_team('t6', ['g3', 'g4'], ['g3', 'g4']),
         't7': make_team('t7', ['g3'], ['abacus', 'g3'])
     }
     self.facade = MemoryDB(users=self.users.values(),
                            teams=self.teams.values())
     self.cmd = IQuitCommand(self.facade)
Exemple #15
0
    def setUp(self):
        self.app = Flask(__name__)
        self.config = mock.MagicMock()
        self.gh = mock.MagicMock()

        self.u0 = User('U123456789')
        self.u1 = User('U234567891')
        self.admin = create_test_admin('Uadmin')
        self.t0 = Team("BRS", "brs", "web")
        self.t1 = Team("OTEAM", "other team", "android")
        self.t2 = Team("LEADS", "leads", "")
        self.t3 = Team("ADMIN", "admin", "")
        self.db = MemoryDB(users=[self.u0, self.u1, self.admin],
                           teams=[self.t0, self.t1, self.t2, self.t3])

        self.sc = mock.MagicMock()
        self.testcommand = TeamCommand(self.config, self.db, self.gh, self.sc)
        self.help_text = self.testcommand.help
        self.maxDiff = None

        self.config.github_team_all = 'all'
        self.config.github_team_leads = 'leads'
        self.config.github_team_admin = 'admin'
Exemple #16
0
class TestProjectCommand(TestCase):
    def setUp(self):
        self.app = Flask(__name__)

        self.u0 = User('U03548940')
        self.u0.github_username = '******'
        self.u0.github_id = '534593'
        self.admin = create_test_admin('Uadmin')
        self.p0 = create_test_project(
            'GTID', ['https://github.com/ubclaunchpad/rocket2'])
        self.p1 = create_test_project(
            '', ['https://github.com/ubclaunchpad/rocket2'])
        self.t0 = Team('GTID', 'team-name', 'name')
        self.db = MemoryDB(users=[self.u0, self.admin],
                           teams=[self.t0],
                           projs=[self.p0, self.p1])

        self.testcommand = ProjectCommand(self.db)

    def test_get_help(self):
        subcommands = list(self.testcommand.subparser.choices.keys())
        help_message = self.testcommand.get_help()
        self.assertEqual(len(subcommands), help_message.count("usage"))

    def test_get_subcommand_help(self):
        """Test project command get_help method for specific subcommands."""
        subcommands = list(self.testcommand.subparser.choices.keys())
        for subcommand in subcommands:
            help_message = self.testcommand.get_help(subcommand=subcommand)
            self.assertEqual(1, help_message.count("usage"))

    def test_get_invalid_subcommand_help(self):
        self.assertEqual(self.testcommand.get_help(),
                         self.testcommand.get_help(subcommand="foo"))

    def test_handle_help(self):
        ret, code = self.testcommand.handle("project help", self.u0.slack_id)
        self.assertEqual(ret, self.testcommand.get_help())
        self.assertEqual(code, 200)

    def test_handle_multiple_subcommands(self):
        """Test handling multiple observed subcommands."""
        ret, code = self.testcommand.handle("project list edit",
                                            self.u0.slack_id)
        self.assertEqual(ret, self.testcommand.get_help())
        self.assertEqual(code, 200)

    def test_handle_subcommand_help(self):
        """Test project subcommand help text."""
        subcommands = list(self.testcommand.subparser.choices.keys())
        for subcommand in subcommands:
            for arg in ['--help', '-h', '--invalid argument']:
                command = f'project {subcommand} {arg}'
                ret, code = self.testcommand.handle(command, self.u0.slack_id)
                self.assertEqual(1, ret.count('usage'))
                self.assertEqual(code, 200)

    def test_handle_view(self):
        with self.app.app_context():
            resp, code = self.testcommand.handle(
                f'project view {self.p0.project_id}', self.u0.slack_id)
            expect = {'attachments': [self.p0.get_attachment()]}
            self.assertDictEqual(resp, expect)
            self.assertEqual(code, 200)

    def test_handle_view_lookup_error(self):
        self.assertTupleEqual(
            self.testcommand.handle('project view rand.proj',
                                    self.u0.slack_id),
            ('Project(id=rand.proj) not found', 200))

    def test_handle_edit_lookup_error(self):
        self.assertTupleEqual(
            self.testcommand.handle('project edit rand.proj',
                                    self.u0.slack_id),
            ('Project(id=rand.proj) not found', 200))

    def test_handle_edit_name(self):
        other_name = 'other_name'
        self.assertNotEqual(self.p0.display_name, other_name)
        with self.app.app_context():
            _, code = self.testcommand.handle(
                f'project edit {self.p0.project_id} --name {other_name}',
                self.u0.slack_id)
            self.assertEqual(code, 200)
            self.assertEqual(self.p0.display_name, other_name)

    @mock.patch('app.model.project.uuid')
    def test_handle_create_as_team_lead(self, mock_uuid):
        mock_uuid.uuid4.return_value = '1'
        self.t0.add_team_lead(self.u0.github_id)
        with self.app.app_context():
            cmd = f'project create repo-link {self.t0.github_team_name}'
            _, code = self.testcommand.handle(cmd, self.u0.slack_id)
            self.assertEqual(code, 200)

        proj = self.db.retrieve(Project, '1')
        self.assertEqual(proj.github_team_id, self.t0.github_team_id)
        self.assertEqual(proj.github_urls, ['repo-link'])

    @mock.patch('app.model.project.uuid')
    def test_handle_create_as_admin(self, mock_uuid):
        mock_uuid.uuid4.return_value = '1'
        with self.app.app_context():
            cmd = f'project create repo-link {self.t0.github_team_name}'
            _, code = self.testcommand.handle(cmd, self.admin.slack_id)
            self.assertEqual(code, 200)

        proj = self.db.retrieve(Project, '1')
        self.assertEqual(proj.github_team_id, self.t0.github_team_id)
        self.assertEqual(proj.github_urls, ['repo-link'])

    def test_handle_create_multiple_team_lookup_error(self):
        team1 = Team('GTID1', 'team-name', 'name1')
        self.db.teams['GTID1'] = team1
        self.assertTupleEqual(
            self.testcommand.handle(
                f'project create repo-link {self.t0.github_team_name}',
                self.admin.slack_id),
            ('2 teams found with GitHub team name team-name', 200))

    def test_handle_create_permission_error(self):
        """Test project command create parser with permission error."""
        self.assertTupleEqual(
            self.testcommand.handle(
                f'project create repo-link {self.t0.github_team_name}',
                self.u0.slack_id), (self.testcommand.permission_error, 200))

    def test_handle_create_user_lookup_error(self):
        self.assertTupleEqual(
            self.testcommand.handle(
                f'project create repo-link {self.t0.github_team_name}',
                'rando.user'), ('User(id=rando.user) not found', 200))

    @mock.patch('app.model.project.uuid')
    def test_handle_create_with_display_name(self, mock_uuid):
        mock_uuid.uuid4.return_value = '1'
        with self.app.app_context():
            _, code = \
                self.testcommand.handle(
                    f'project create repo-link {self.t0.github_team_name}'
                    ' --name display-name',
                    self.admin.slack_id)
            self.assertEqual(code, 200)

        proj = self.db.retrieve(Project, '1')
        self.assertEqual(proj.github_team_id, self.t0.github_team_id)
        self.assertEqual(proj.github_urls, ['repo-link'])
        self.assertEqual(proj.display_name, 'display-name')

    def test_handle_list(self):
        with self.app.app_context():
            resp, code = self.testcommand.handle('project list', user)
            self.assertIn(self.p0.project_id, resp)
            self.assertIn(self.p1.project_id, resp)
            self.assertEqual(code, 200)

    def test_handle_list_no_projects(self):
        self.db.projs = {}
        self.assertTupleEqual(
            self.testcommand.handle('project list', self.u0.slack_id),
            ('No Projects Exist!', 200))

    def test_handle_unassign_team_lead(self):
        self.t0.add_team_lead(self.u0.github_id)
        with self.app.app_context():
            cmd = f'project unassign {self.p0.project_id}'
            resp = self.testcommand.handle(cmd, self.u0.slack_id)
            self.assertEqual(resp, ('Project successfully unassigned!', 200))

    def test_handle_unassign_as_admin(self):
        with self.app.app_context():
            cmd = f'project unassign {self.p0.project_id}'
            resp = self.testcommand.handle(cmd, self.admin.slack_id)
            self.assertEqual(resp, ('Project successfully unassigned!', 200))

    def test_handle_unassign_project_lookup_error(self):
        self.assertEqual(
            self.testcommand.handle('project unassign rand.proj',
                                    self.admin.slack_id),
            ('Project(id=rand.proj) not found', 200))

    def test_handle_unassign_team_lookup_error(self):
        proj = Project('rando', [])
        self.db.projs[proj.project_id] = proj
        self.assertEqual(
            self.testcommand.handle(f'project unassign {proj.project_id}',
                                    self.admin.slack_id),
            ('Team(id=rando) not found', 200))

    def test_handle_unassign_user_lookup_error(self):
        cmd = f'project unassign {self.p0.project_id}'
        self.assertEqual(self.testcommand.handle(cmd, 'rando.user'),
                         ('User(id=rando.user) not found', 200))

    def test_handle_unassign_permission_error(self):
        cmd = f'project unassign {self.p0.project_id}'
        self.assertEqual(self.testcommand.handle(cmd, self.u0.slack_id),
                         (self.testcommand.permission_error, 200))

    def test_handle_assign_as_team_lead(self):
        self.t0.add_team_lead(self.u0.github_id)
        cmd = f'project assign {self.p1.project_id} {self.t0.github_team_name}'
        self.assertTupleEqual(self.testcommand.handle(cmd, self.u0.slack_id),
                              ('Project successfully assigned!', 200))

    def test_handle_assign_as_admin(self):
        cmd = f'project assign {self.p1.project_id} {self.t0.github_team_name}'
        self.assertTupleEqual(
            self.testcommand.handle(cmd, self.admin.slack_id),
            ('Project successfully assigned!', 200))

    def test_handle_assign_project_lookup_error(self):
        cmd = f'project assign arst {self.t0.github_team_name}'
        self.assertTupleEqual(
            self.testcommand.handle(cmd, self.admin.slack_id),
            ('Project(id=arst) not found', 200))

    def test_handle_assign_project_team_lookup_error(self):
        cmd = f'project assign {self.p0.project_id} rando.id'
        self.assertTupleEqual(
            self.testcommand.handle(cmd, self.admin.slack_id),
            ('0 teams found with GitHub team name rando.id', 200))

    def test_handle_assign_permission_error(self):
        cmd = f'project assign {self.p0.project_id} {self.t0.github_team_name}'
        self.assertTupleEqual(self.testcommand.handle(cmd, self.u0.slack_id),
                              (self.testcommand.permission_error, 200))

    def test_handle_assign_assign_error(self):
        cmd = f'project assign {self.p0.project_id} {self.t0.github_team_name}'
        self.assertTupleEqual(
            self.testcommand.handle(cmd, self.admin.slack_id),
            (self.testcommand.assigned_error, 200))

    def test_handle_force_assign(self):
        cmd = 'project assign %s %s -f' % (self.p0.project_id,
                                           self.t0.github_team_name)
        self.assertTupleEqual(
            self.testcommand.handle(cmd, self.admin.slack_id),
            ('Project successfully assigned!', 200))

    def test_handle_delete_as_admin(self):
        cmd = f'project delete {self.p1.project_id}'
        self.assertTupleEqual(
            self.testcommand.handle(cmd, self.admin.slack_id),
            ('Project successfully deleted!', 200))

    def test_handle_delete_project_lookup_error(self):
        cmd = 'project delete rando.id'
        self.assertTupleEqual(
            self.testcommand.handle(cmd, self.admin.slack_id),
            ('Project(id=rando.id) not found', 200))

    def test_handle_delete_user_lookup_error(self):
        cmd = f'project delete {self.p0.project_id}'
        self.assertTupleEqual(self.testcommand.handle(cmd, 'rando.id'),
                              ('User(id=rando.id) not found', 200))

    def test_handle_delete_assign_error(self):
        cmd = f'project delete {self.p0.project_id}'
        self.assertTupleEqual(
            self.testcommand.handle(cmd, self.admin.slack_id),
            (self.testcommand.assigned_error, 200))

    def test_handle_force_delete(self):
        cmd = f'project delete {self.p0.project_id} -f'
        self.assertTupleEqual(
            self.testcommand.handle(cmd, self.admin.slack_id),
            ('Project successfully deleted!', 200))
Exemple #17
0
 def setUp(self):
     self.db = MemoryDB(users=list(self.users.values()),
                        teams=list(self.teams.values()))
Exemple #18
0
class TestMemoryDB(TestCase):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.admin = util.create_test_admin('Uadmin')
        self.users = {u.slack_id: u for u in makeUsers(20)}
        self.users['Uadmin'] = self.admin
        self.teams = {t.github_team_id: t for t in makeTeams()}

    def setUp(self):
        self.db = MemoryDB(users=list(self.users.values()),
                           teams=list(self.teams.values()))

    def test_get_db_lookup_error(self):
        with self.assertRaises(LookupError):
            self.db.get_db(TestMemoryDB)

    def test_users_dont_affect_DB(self):
        """
        DB modifications shouldn't affect dict outside.

        Models themselves being modified are okay. But modifying the
        composition of the DB (which objects are in it) is not. This test makes
        sure that deleting a user from the DB does not delete it from the user
        dictionary.
        """
        slack_id = random.choice(list(self.users.keys()))
        self.db.users.pop(slack_id)
        self.assertIn(slack_id, self.users)

    def test_store_valid_user(self):
        u = User('u3')
        self.assertTrue(self.db.store(u))

    def test_store_invalid_user(self):
        u = User('')
        self.assertFalse(self.db.store(u))

    def test_retrieve_users_randomly(self):
        ks = list(self.users.keys())
        for _ in range(10):
            slack_id = random.choice(ks)
            u = self.db.retrieve(User, slack_id)
            self.assertEqual(u.github_username,
                             self.users[slack_id].github_username)

    def test_retrieve_nonexistant_user(self):
        with self.assertRaises(LookupError):
            self.db.retrieve(User, 'bad user bad bad')

    def test_bulk_retrieve(self):
        selection = random.sample(list(self.users.keys()), k=10)
        us = self.db.bulk_retrieve(User, selection)
        self.assertEqual(len(us), 10)
        for u in us:
            self.assertEqual(u.github_username,
                             self.users[u.slack_id].github_username)

    def test_bulk_retrieve_nothing(self):
        selection = [str(i) for i in range(100)]
        us = self.db.bulk_retrieve(User, selection)
        self.assertEqual(us, [])

    def test_query_team_name(self):
        ts = self.db.query(Team, [('github_team_name', 'T1')])
        self.assertEqual(len(ts), 1)
        self.assertEqual(ts[0], self.teams['t1'])

    def test_query_multi_params(self):
        ts = self.db.query(
            Team,
            [('members', 'u0'), ('team_leads', 'u1')])
        self.assertEqual(len(ts), 1)
        self.assertEqual(ts[0], self.teams['t0'])

    def test_query_multi_teams(self):
        ts = self.db.query(Team, [('members', 'u0')])
        self.assertCountEqual(ts, [self.teams['t0'], self.teams['t1']])

    def test_scan_query(self):
        us = self.db.query(User)
        self.assertCountEqual(us, list(self.users.values()))

    def test_query_all_admins(self):
        admins = self.db.query(User, [('permission_level', 'admin')])
        self.assertIn(self.admin, admins)

    def test_scan_teams(self):
        ts = self.db.query_or(Team)
        self.assertCountEqual(ts, list(self.teams.values()))

    def test_bulk_retrieve_using_query(self):
        selection = random.sample(list(self.users.items()), k=10)
        rand_vals = [v for _, v in selection]
        q_string = [('slack_id', k) for k, _ in selection]
        us = self.db.query_or(User, q_string)
        self.assertCountEqual(us, rand_vals)
        self.assertEqual(len(us), 10)

    def test_delete_user(self):
        slack_id = random.choice(list(self.users.keys()))
        self.db.delete(User, slack_id)
        with self.assertRaises(LookupError):
            self.db.retrieve(User, slack_id)

    def test_displayname(self):
        ts = self.db.query(Team, [('displayname', 'T Zero Blasters')])
        self.assertEqual(len(ts), 1)
        self.assertEqual(ts[0], self.teams['t0'])
class TestOrganizationHandles(TestCase):
    def setUp(self):
        self.username = '******'
        self.gh_uid = 4738549
        self.default_payload = org_default_payload(self.username, self.gh_uid)
        self.add_payload = org_default_payload(self.username, self.gh_uid)
        self.rm_payload = org_default_payload(self.username, self.gh_uid)
        self.invite_payload = org_default_payload(self.username, self.gh_uid)
        self.empty_payload = org_default_payload(self.username, self.gh_uid)

        self.add_payload['action'] = 'member_added'
        self.rm_payload['action'] = 'member_removed'
        self.invite_payload['action'] = 'member_invited'
        self.empty_payload['action'] = ''

        self.u0 = User('U01234954')
        self.u0.github_id = str(self.gh_uid)
        self.u0.github_username = self.username
        self.team_all = Team('1', 'all', 'Team all')
        self.db = MemoryDB(users=[self.u0], teams=[self.team_all])

        self.gh = mock.Mock()
        self.conf = mock.Mock()
        self.conf.github_team_all = 'all'
        self.webhook_handler = OrganizationEventHandler(self.db, self.gh,
                                                        self.conf)

    def test_org_handle_invite(self):
        resp, code = self.webhook_handler.handle(self.invite_payload)
        self.assertIn(self.username, resp)
        self.assertEqual(code, 200)

    def test_handle_org_event_add_member(self):
        rsp, code = self.webhook_handler.handle(self.add_payload)
        self.assertEqual(rsp, f'user {self.username} added to Octocoders')
        self.assertEqual(code, 200)
        self.assertIn(str(self.gh_uid), self.team_all.members)

    def test_handle_org_event_add_no_all_team(self):
        self.db.teams = {}
        self.gh.org_create_team.return_value = 305938
        rsp, code = self.webhook_handler.handle(self.add_payload)
        self.assertEqual(rsp, f'user {self.username} added to Octocoders')
        self.assertEqual(code, 200)

        team = self.db.retrieve(Team, '305938')
        self.assertEqual(team.github_team_name, self.conf.github_team_all)
        self.assertIn(str(self.gh_uid), team.members)

    def test_handle_org_event_rm_single_member(self):
        rsp, code = self.webhook_handler.handle(self.rm_payload)
        self.assertEqual(rsp, f'deleted slack ID {self.u0.slack_id}')
        self.assertEqual(code, 200)
        with self.assertRaises(LookupError):
            self.db.retrieve(User, self.u0.slack_id)

    def test_handle_org_event_rm_member_missing(self):
        self.db.users = {}
        rsp, code = self.webhook_handler.handle(self.rm_payload)
        self.assertEqual(rsp, f'could not find user {self.username}')
        self.assertEqual(code, 200)

    def test_handle_org_event_rm_multiple_members_cause_error(self):
        clone0 = User('Ustreisand')
        clone0.github_username = self.username
        clone0.github_id = str(self.gh_uid)
        self.db.users['Ustreisand'] = clone0
        rsp, code = self.webhook_handler.handle(self.rm_payload)
        self.assertEqual(
            rsp,
            'Error: found github ID connected to multiple slack IDs'
        )
        self.assertEqual(code, 200)

    def test_handle_org_event_empty_action(self):
        rsp, code = self.webhook_handler.handle(self.empty_payload)
        self.assertEqual(rsp, 'Unsupported action triggered, ignoring.')
        self.assertEqual(code, 202)
Exemple #20
0
class TestUserCommand(TestCase):
    def setUp(self):
        self.app = Flask(__name__)

        self.u0 = User('U0G9QF9C6')
        self.u1 = User('Utheomadude')
        self.admin = create_test_admin('Uadmin')
        self.db = MemoryDB(users=[self.u0, self.u1, self.admin])

        self.mock_github = mock.MagicMock(GithubInterface)
        self.testcommand = UserCommand(self.db, self.mock_github, None)
        self.maxDiff = None

    def test_get_help(self):
        """Test user command get_help method."""
        subcommands = list(self.testcommand.subparser.choices.keys())
        help_message = self.testcommand.get_help()
        self.assertEqual(len(subcommands), help_message.count("usage"))

    def test_get_subcommand_help(self):
        """Test user command get_help method for specific subcommands."""
        subcommands = list(self.testcommand.subparser.choices.keys())
        for subcommand in subcommands:
            help_message = self.testcommand.get_help(subcommand=subcommand)
            self.assertEqual(1, help_message.count("usage"))

    def test_get_invalid_subcommand_help(self):
        """Test user command get_help method for invalid subcommands."""
        self.assertEqual(self.testcommand.get_help(),
                         self.testcommand.get_help(subcommand="foo"))

    def test_handle_nosubs(self):
        """Test user with no sub-parsers."""
        self.assertEqual(self.testcommand.handle('user', self.u0.slack_id),
                         (self.testcommand.help, 200))

    def test_handle_bad_args(self):
        """Test user with invalid arguments."""
        self.assertEqual(
            self.testcommand.handle('user geese', self.u0.slack_id),
            (self.testcommand.help, 200))

    def test_handle_add(self):
        """Test user command add method."""
        user_id = "U0G9QF9C7"
        user = User(user_id)
        self.assertTupleEqual(self.testcommand.handle('user add', user_id),
                              ('User added!', 200))
        retr = self.db.retrieve(User, user_id)
        self.assertEqual(user, retr)

    def test_handle_add_no_overwriting(self):
        """Test user command add method when user exists in db."""
        user = User(self.u0.slack_id)
        err_msg = 'User already exists; to overwrite user, add `-f`'
        resp = self.testcommand.handle('user add', user.slack_id)
        self.assertTupleEqual(resp, (err_msg, 200))

    def test_handle_add_with_force(self):
        ret = self.testcommand.handle('user add -f', self.u0.slack_id)
        self.assertEqual(ret, ('User added!', 200))

    def test_handle_view(self):
        user_attaches = [self.u0.get_attachment()]
        with self.app.app_context():
            # jsonify requires translating the byte-string
            resp, code = self.testcommand.handle('user view', self.u0.slack_id)
            expect = {'attachments': user_attaches}
            self.assertDictEqual(resp, expect)
            self.assertEqual(code, 200)

    def test_handle_view_other_user(self):
        user = User("ABCDE8FA9")
        self.db.store(user)
        command = 'user view --username ' + user.slack_id
        user_attaches = [user.get_attachment()]
        with self.app.app_context():
            # jsonify requires translating the byte-string
            resp, code = self.testcommand.handle(command, self.u0.slack_id)
            expect = {'attachments': user_attaches}
            self.assertDictEqual(resp, expect)
            self.assertEqual(code, 200)

    def test_handle_view_lookup_error(self):
        command = 'user view --username ABCDE8FA9'
        self.assertTupleEqual(
            self.testcommand.handle(command, self.u0.slack_id),
            (UserCommand.lookup_error, 200))

    def test_handle_help(self):
        self.assertEqual(
            self.testcommand.handle('user help', self.u0.slack_id),
            (self.testcommand.help, 200))

    def test_handle_delete(self):
        message = f'Deleted user with Slack ID: {self.u0.slack_id}'
        cmd = f'user delete {self.u0.slack_id}'
        self.assertEqual(self.testcommand.handle(cmd, self.admin.slack_id),
                         (message, 200))
        with self.assertRaises(LookupError):
            self.db.retrieve(User, self.u0.slack_id)

    def test_handle_delete_not_admin(self):
        cmd = f'user delete {self.u1.slack_id}'
        self.assertEqual(self.testcommand.handle(cmd, self.u0.slack_id),
                         (UserCommand.permission_error, 200))

    def test_handle_delete_callinguser_lookup_error(self):
        cmd = f'user delete {self.u1.slack_id}'
        self.assertEqual(self.testcommand.handle(cmd, 'rando.id'),
                         (UserCommand.lookup_error, 200))

    def test_handle_edit_name(self):
        with self.app.app_context():
            resp, code = self.testcommand.handle('user edit --name rob',
                                                 self.u0.slack_id)
            expect = {'title': 'Name', 'value': 'rob', 'short': True}
            self.assertIn(expect, resp['attachments'][0]['fields'])
            self.assertEqual(code, 200)

    def test_handle_edit_github(self):
        """Test that editing github username sends request to interface."""
        self.mock_github.org_add_member.return_value = "123"
        with self.app.app_context():
            resp, code = self.testcommand.handle("user edit --github rob",
                                                 self.u0.slack_id)
            expect0 = {
                'title': 'Github Username',
                'value': 'rob',
                'short': True
            }
            expect1 = {'title': 'Github ID', 'value': '123', 'short': True}
            self.assertIn(expect0, resp['attachments'][0]['fields'])
            self.assertIn(expect1, resp['attachments'][0]['fields'])
            self.assertEqual(code, 200)
        self.mock_github.org_add_member.assert_called_once_with("rob")

    def test_handle_edit_github_error(self):
        self.mock_github.org_add_member.side_effect = GithubAPIException("")

        with self.app.app_context():
            resp, code = self.testcommand.handle('user edit --github rob',
                                                 self.u0.slack_id)
            expect = {
                'attachments': [self.u0.get_attachment()],
                'text': '\nError adding user rob to GitHub organization'
            }

            self.assertDictEqual(resp, expect)
            self.assertEqual(code, 200)

    def test_handle_edit_all_fields(self):
        user = User(self.u0.slack_id)
        user.name = 'rob'
        user.email = '*****@*****.**'
        user.position = 'dev'
        user.github_username = '******'
        user.github_id = '123'
        user.major = 'Computer Science'
        user.biography = 'Im a human lol'
        user.permissions_level = Permissions.member
        expect = {'attachments': [user.get_attachment()]}
        self.mock_github.org_add_member.return_value = "123"
        with self.app.app_context():
            resp, code = self.testcommand.handle(
                "user edit "
                "--name rob "
                "--email <mailto:[email protected]|[email protected]> --pos dev --github"
                " rob --major 'Computer Science'"
                " --bio 'Im a human lol'", self.u0.slack_id)
            self.assertDictEqual(resp, expect)
            self.assertEqual(code, 200)

    def test_handle_edit_not_admin(self):
        """Test user command with editor user that is not admin."""
        self.assertEqual(
            self.testcommand.handle(
                'user edit --username ' + self.u1.slack_id + ' '
                '--name rob '
                '--email <mailto:[email protected]|[email protected]> --pos dev --github'
                ' [email protected] --major \'Computer Science\''
                ' --bio \'Im a human\'', self.u0.slack_id),
            (UserCommand.permission_error, 200))

    def test_handle_edit_make_admin(self):
        with self.app.app_context():
            resp, code = self.testcommand.handle(
                f"user edit --username {self.u0.slack_id} "
                "--permission admin", self.admin.slack_id)
            expect = {
                'title': 'Permissions Level',
                'value': 'admin',
                'short': True
            }
            self.assertIn(expect, resp['attachments'][0]['fields'])
            self.assertEqual(code, 200)

    def test_handle_edit_make_self_admin_no_perms(self):
        with self.app.app_context():
            resp, code = self.testcommand.handle(
                "user edit --permission admin", self.u0.slack_id)
            expect = {
                'attachments': [self.u0.get_attachment()],
                'text': "\nCannot change own permission: user isn't admin."
            }
            self.assertDictEqual(resp, expect)
            self.assertEqual(code, 200)

    def test_handle_edit_lookup_error_editee(self):
        self.assertEqual(
            self.testcommand.handle(
                "user edit --username random.something "
                "--name rob "
                "--email <mailto:[email protected]|[email protected]> --pos dev --github"
                " [email protected] --major 'Computer Science'"
                " --bio 'Im a human'", self.admin.slack_id),
            (UserCommand.lookup_error, 200))

    def test_handle_edit_lookup_error(self):
        """Test user command where user is not in database."""
        self.assertEqual(
            self.testcommand.handle('user edit --name rob', 'rando'),
            (UserCommand.lookup_error, 200))

    def test_handle_command_help(self):
        ret, code = self.testcommand.handle('user help', self.u0.slack_id)
        self.assertEqual(ret, self.testcommand.get_help())
        self.assertEqual(code, 200)

    def test_handle_multiple_subcommands(self):
        """Test handling multiple observed subcommands."""
        ret, code = self.testcommand.handle('user edit view', self.u0.slack_id)
        self.assertEqual(ret, self.testcommand.get_help())
        self.assertEqual(code, 200)

    def test_handle_subcommand_help(self):
        subcommands = list(self.testcommand.subparser.choices.keys())
        for subcommand in subcommands:
            cmd_args = ['--help', '-h', '--invalid argument']
            for arg in cmd_args:
                command = f'user {subcommand} {arg}'
                ret, code = self.testcommand.handle(command, self.u0.slack_id)
                self.assertEqual(1, ret.count("usage"))
                self.assertIn(subcommand, ret)
                self.assertEqual(code, 200)
Exemple #21
0
class TestSlackWebhookCore(TestCase):
    def setUp(self):
        self.u_id = 'U012A3CDE'
        self.db = MemoryDB()
        self.bot = mock.Mock()
        self.handler = SlackEventsHandler(self.db, self.bot)
        self.event = {
            'token': 'XXYYZZ',
            'team_id': 'TXXXXXXXX',
            'api_app_id': 'AXXXXXXXXX',
            'event': {
                'type': 'team_join',
                'user': {
                    'id': self.u_id,
                    'team_id': 'T012AB3C4',
                    'name': 'spengler',
                    'deleted': False,
                    'color': '9f69e7',
                    'real_name': 'Egon Spengler',
                    'tz': 'America/Los_Angeles',
                    'tz_label': 'Pacific Daylight Time',
                    'tz_offset': -25200,
                    'profile': {
                        'avatar_hash': 'ge3b51ca72de',
                        'status_text': 'Print is dead',
                        'status_emoji': ':books:',
                        'status_expiration': 1502138999,
                        'real_name': 'Egon Spengler',
                        'display_name': 'spengler',
                        'real_name_normalized': 'Egon Spengler',
                        'display_name_normalized': 'spengler',
                        'email': '*****@*****.**',
                        'image_24': 'https://.../avatar/hello.jpg',
                        'image_32': 'https://.../avatar/hello.jpg',
                        'image_48': 'https://.../avatar/hello.jpg',
                        'image_72': 'https://.../avatar/hello.jpg',
                        'image_192': 'https://.../avatar/hello.jpg',
                        'image_512': 'https://.../avatar/hello.jpg',
                        'team': 'T012AB3C4'
                    },
                    'is_admin': True,
                    'is_owner': False,
                    'is_primary_owner': False,
                    'is_restricted': False,
                    'is_ultra_restricted': False,
                    'is_bot': False,
                    'is_stranger': False,
                    'updated': 1502138686,
                    'is_app_user': False,
                    'has_2fa': False,
                    'locale': 'en-US'
                }
            },
            'type': 'app_mention',
            'authed_users': ['UXXXXXXX1', 'UXXXXXXX2'],
            'event_id': 'Ev08MFMKH6',
            'event_time': 1234567890
        }

    def test_handle_team_join_success(self):
        self.handler.handle_team_join(self.event)
        self.bot.send_dm.assert_called_once_with(SlackEventsHandler.welcome,
                                                 self.u_id)
        u = self.db.retrieve(User, self.u_id)
        self.assertEqual(u.slack_id, self.u_id)

    def test_handle_team_join_slack_error(self):
        self.bot.send_dm.side_effect = SlackAPIError(None)
        self.handler.handle_team_join(self.event)
        self.bot.send_dm.assert_called_once_with(SlackEventsHandler.welcome,
                                                 self.u_id)
        u = self.db.retrieve(User, self.u_id)
        self.assertEqual(u.slack_id, self.u_id)
Exemple #22
0
 def test_get_team_by_name_lots_of_teams_same_name(self):
     db = MemoryDB(teams=[self.t0, self.t1])
     with self.assertRaises(RuntimeError):
         get_team_by_name(db, 'some-team')
Exemple #23
0
class TestTeamHandles(TestCase):
    def setUp(self):
        self.team = 'rocket'
        self.teamid = 4934950
        self.newteam = 'someteam'
        self.newteamid = 4028940
        self.created_payload = team_default_payload(self.newteam,
                                                    self.newteamid)
        self.deleted_payload = team_default_payload(self.team, self.teamid)
        self.edited_payload = team_default_payload(self.team, self.teamid)
        self.added_to_repo_payload = team_default_payload(
            self.team, self.teamid)
        self.rm_from_repo_payload = team_default_payload(
            self.team, self.teamid)
        self.empty_payload = team_default_payload(self.team, self.teamid)
        self.created_payload['action'] = 'created'
        self.deleted_payload['action'] = 'deleted'
        self.edited_payload['action'] = 'edited'
        self.added_to_repo_payload['action'] = 'added_to_repository'
        self.rm_from_repo_payload['action'] = 'removed_from_repository'
        self.empty_payload['action'] = ''

        self.t = Team(str(self.teamid), self.team, self.team.capitalize())
        self.db = MemoryDB(teams=[self.t])

        self.gh = mock.Mock()
        self.conf = mock.Mock()
        self.webhook_handler = TeamEventHandler(self.db, self.gh, self.conf)

    def test_handle_team_event_create_team(self):
        rsp, code = self.webhook_handler.handle(self.created_payload)
        self.assertEqual(rsp, f'created team with github id {self.newteamid}')
        self.assertEqual(code, 200)

        team = self.db.retrieve(Team, str(self.newteamid))
        self.assertEqual(team.github_team_name, self.newteam)

    def test_handle_team_event_create_update(self):
        self.t.github_team_id = str(self.newteamid)
        self.db.teams = {str(self.newteamid): self.t}
        self.assertNotEqual(self.t.github_team_name, self.newteam)
        rsp, code = self.webhook_handler.handle(self.created_payload)
        self.assertEqual(rsp, f'created team with github id {self.newteamid}')
        self.assertEqual(code, 200)

        self.assertEqual(self.t.github_team_name, self.newteam)

    def test_handle_team_event_delete_team(self):
        rsp, code = self.webhook_handler.handle(self.deleted_payload)
        self.assertEqual(rsp, f'deleted team with github id {self.teamid}')
        self.assertEqual(code, 200)
        self.assertNotIn(self.t, self.db.teams.values())

    def test_handle_team_event_deleted_not_in_db(self):
        self.db.teams = {}
        rsp, code = self.webhook_handler.handle(self.deleted_payload)
        self.assertEqual(rsp, f'team with github id {self.teamid} not found')
        self.assertEqual(code, 404)

    def test_handle_team_event_edit_team(self):
        rsp, code = self.webhook_handler.handle(self.edited_payload)
        self.assertEqual(rsp, f'updated team with id {self.teamid}')
        self.assertEqual(code, 200)

    def test_handle_team_event_edit_not_in_db(self):
        self.db.teams = {}
        rsp, code = self.webhook_handler.handle(self.edited_payload)
        self.assertEqual(rsp, f'team with github id {self.teamid} not found')
        self.assertEqual(code, 404)

    def test_handle_team_event_add_to_repo(self):
        rsp, code = self.webhook_handler.handle(self.added_to_repo_payload)
        self.assertEqual(
            rsp, f'team with id {self.teamid} added to repository Hello-World')
        self.assertEqual(code, 200)

    def test_handle_team_event_rm_from_repo(self):
        rsp, code = self.webhook_handler.handle(self.rm_from_repo_payload)
        self.assertEqual(
            rsp, f'team with id {self.teamid} removed repository Hello-World')
        self.assertEqual(code, 200)

    def test_handle_team_event_empty_payload(self):
        """Test empty/invalid payloads can be handled."""
        rsp, code = self.webhook_handler.handle(self.empty_payload)
        self.assertEqual(rsp, 'invalid payload')