Example #1
0
 def setUp(self):
     self.config = MagicMock(Config)
     self.config.aws_users_tablename = 'users_test'
     self.config.aws_teams_tablename = 'teams_test'
     self.config.aws_projects_tablename = 'projects_test'
     self.config.aws_local = True
     self.ddb = DynamoDB(self.config)
Example #2
0
def make_command_parser(config: Config,
                        gh: Optional[GithubInterface] = None) \
        -> CommandParser:
    """
    Initialize and returns a :class:`CommandParser` object.

    :return: a new ``CommandParser`` object, freshly initialized
    """
    slack_api_token, slack_notification_channel = "", ""
    signing_key = ""
    if not config.testing:
        slack_api_token = config.slack_api_token
        github_auth_key = config.github_key
        github_app_id = config.github_app_id
        github_organization = config.github_org_name
        slack_notification_channel = config.slack_notification_channel
        gh = GithubInterface(DefaultGithubFactory(github_app_id,
                                                  github_auth_key),
                             github_organization)
        signing_key = config.github_key
    facade = DBFacade(DynamoDB(config))
    bot = Bot(WebClient(slack_api_token), slack_notification_channel)
    # TODO: make token config expiry configurable
    token_config = TokenCommandConfig(timedelta(days=7), signing_key)
    return CommandParser(facade, bot, cast(GithubInterface, gh), token_config)
Example #3
0
 def setUp(self):
     """Set up configurations for the constants."""
     self.config = MagicMock(Config)
     self.config.aws_users_tablename = 'users'
     self.config.aws_teams_tablename = 'teams'
     self.config.aws_projects_tablename = 'projects'
     self.const = DynamoDB.Const(self.config)
Example #4
0
def make_github_webhook_handler(config: Config) -> GitHubWebhookHandler:
    """
    Initialize a :class:`GitHubWebhookHandler` object.

    :return: a new ``GitHubWebhookHandler`` object, freshly initialized
    """
    facade = DBFacade(DynamoDB(config))
    return GitHubWebhookHandler(facade, config)
Example #5
0
def make_slack_events_handler(config: Config) -> SlackEventsHandler:
    """
    Initialize a :class:`SlackEventsHandler` object.

    :return: a new ``SlackEventsHandler`` object, freshly initialized
    """
    facade = DBFacade(DynamoDB(config))
    bot = Bot(WebClient(config.slack_api_token),
              config.slack_notification_channel)
    return SlackEventsHandler(facade, bot)
Example #6
0
def ddb():
    """Create a new DynamoDb instance."""
    from db.dynamodb import DynamoDB
    test_config = MagicMock(Config)
    test_config.aws_users_tablename = 'users_test'
    test_config.aws_teams_tablename = 'teams_test'
    test_config.aws_projects_tablename = 'projects_test'
    test_config.testing = True
    actual = DynamoDB(test_config)
    yield actual
    ts = [User, Team, Project]
    for t in ts:
        items = actual.query(t)
        for item in items:
            if t == User:
                actual.delete(t, item.slack_id)
            elif t == Team:
                actual.delete(t, item.github_team_id)
            elif t == Project:
                actual.delete(t, item.project_id)
Example #7
0
def make_dbfacade(config: Config) -> DBFacade:
    return DynamoDB(config)
Example #8
0
class TestDynamoDB(TestCase):
    def setUp(self):
        self.config = MagicMock(Config)
        self.config.aws_users_tablename = 'users_test'
        self.config.aws_teams_tablename = 'teams_test'
        self.config.aws_local = True
        self.ddb = DynamoDB(self.config)

    def tearDown(self):
        """Delete all database tables after usage."""
        # Delete the table itself instead of just the items in it
        botodb = boto3.resource(service_name="dynamodb",
                                region_name="",
                                aws_access_key_id="",
                                aws_secret_access_key="",
                                endpoint_url="http://localhost:8000")
        for table in botodb.tables.all():
            table.delete()

    @pytest.mark.db
    def test_store_invalid_type(self):
        """Test that we cannot store an object that isn't one of the types."""
        with self.assertRaises(RuntimeError):
            self.ddb.store(30)

    @pytest.mark.db
    def test_store_invalid_user(self):
        user = User('')
        self.assertFalse(self.ddb.store(user))

    @pytest.mark.db
    def test_store_invalid_team(self):
        team = Team('1', '', 'Brussel Sprouts')
        self.assertFalse(self.ddb.store(team))

    @pytest.mark.db
    def test_store_same_users(self):
        """Test how database handles overwriting same user (same slack_id)."""
        user = create_test_admin('abc_123')
        user2 = create_test_admin('abc_123')
        user2.name = 'Sprouts'
        self.assertTrue(self.ddb.store(user))
        self.assertTrue(self.ddb.store(user2))

        self.assertEqual(self.ddb.retrieve(User, 'abc_123'), user2)

    @pytest.mark.db
    def test_store_retrieve_user(self):
        """Test to see if we can store and retrieve the same user."""
        user = create_test_admin('abc_123')

        success = self.ddb.store(user)
        another_user = self.ddb.retrieve(User, 'abc_123')

        self.assertTrue(success)
        self.assertEqual(user, another_user)

    @pytest.mark.db
    def test_retrieve_invalid_user(self):
        """Test to see if we can retrieve a non-existant user."""
        with self.assertRaises(LookupError):
            self.ddb.retrieve(User, 'abc_123')

    @pytest.mark.db
    def test_query_user(self):
        """Test to see if we can store and query the same user."""
        user = create_test_admin('abc_123')
        self.assertTrue(self.ddb.store(user))
        users = self.ddb.query(User, [('permission_level', 'admin')])
        strict_users = self.ddb.query(User, [('permission_level', 'admin'),
                                             ('slack_id', 'abc_123')])
        all_users = self.ddb.query(User)
        self.assertEqual(user, users[0])
        self.assertEqual(user, all_users[0])
        self.assertEqual(user, strict_users[0])

    @pytest.mark.db
    def test_retrieve_invalid_team(self):
        """Test to see if we can retrieve a non-existent team."""
        with self.assertRaises(LookupError):
            self.ddb.retrieve(Team, '1')

    @pytest.mark.db
    def test_update_user(self):
        """Test to see if we can update a user."""
        u = User('abc_123')
        self.assertTrue(self.ddb.store(u))

        u = self.ddb.retrieve(User, 'abc_123')
        u.name = 'Steven Universe'
        self.assertTrue(self.ddb.store(u))

        self.assertEqual(
            self.ddb.retrieve(User, 'abc_123').name, 'Steven Universe')

    @pytest.mark.db
    def test_update_team(self):
        """Test to see if we can update a team."""
        t = Team('1', 'brussel-sprouts', 'Brussel Sprouts')
        self.assertTrue(self.ddb.store(t))

        t = self.ddb.retrieve(Team, '1')
        t.add_member('abc_123')
        t.add_member('123_abc')
        self.assertTrue(self.ddb.store(t))

        self.assertEqual(len(self.ddb.retrieve(Team, '1').members), 2)

    @pytest.mark.db
    def test_store_retrieve_team(self):
        """Test to see if we can store and retrieve the same team."""
        team = create_test_team('1', 'rocket2.0', 'Rocket 2.0')
        self.assertTrue(self.ddb.store(team))
        another_team = self.ddb.retrieve(Team, '1')

        self.assertEqual(team, another_team)

    @pytest.mark.db
    def test_bulk_retrieve_no_users(self):
        uids = list(map(str, range(10)))
        self.assertEqual(self.ddb.bulk_retrieve(User, uids), [])

    @pytest.mark.db
    def test_bulk_retrieve_users(self):
        uids = list(map(str, range(10)))
        users = [create_test_admin(i) for i in uids]
        for user in users:
            self.assertTrue(self.ddb.store(user))

        retrieved_users = self.ddb.bulk_retrieve(User, uids)
        for user in retrieved_users:
            self.assertIn(user, users)

    @pytest.mark.db
    def test_query_or_teams(self):
        """Test edge cases like set inclusion in query_or."""
        teams = [
            create_test_team(str(i), "glob", "displayname") for i in range(10)
        ]
        member_to_check = list(teams[0].members)[0]
        param = [('members', member_to_check)]
        for team in teams:
            self.assertTrue(self.ddb.store(team))
        queried_teams = self.ddb.query_or(Team, param)
        for team in teams:
            self.assertIn(team, queried_teams)

    @pytest.mark.db
    def test_query_or_users(self):
        uids = list(map(str, range(10)))
        users = [create_test_admin(i) for i in uids]

        for user in users[:5]:
            user.permissions_level = Permissions.member

        for user in users:
            self.assertTrue(self.ddb.store(user))

        params = [('slack_id', str(uid)) for uid in uids]
        queried_users = self.ddb.query_or(User, params)
        for user in queried_users:
            self.assertIn(user, users)

        params = [('permissions_level', lvl) for lvl in ['admin', 'member']]
        queried_users = self.ddb.query_or(User, params)
        for user in queried_users:
            self.assertIn(user, users)

    @pytest.mark.db
    def test_query_or_lotsa_users(self):
        uids = list(map(str, range(250)))
        users = [create_test_admin(i) for i in uids]

        # Bulk store to save on time
        table_name = self.ddb.CONST.get_table_name(User)
        table = self.ddb.ddb.Table(table_name)
        with table.batch_writer() as batch:
            for user in users:
                batch.put_item(Item=User.to_dict(user))

        params = [('slack_id', uid) for uid in uids]
        queried_users = self.ddb.query_or(User, params)
        self.assertCountEqual(queried_users, users)

    @pytest.mark.db
    def test_query_team(self):
        """Test to see if we can store and query the same team."""
        team = create_test_team('1', 'rocket2.0', 'Rocket 2.0')
        team2 = create_test_team('2', 'lame-o', 'Lame-O Team')
        team2.add_member('apple')
        self.assertTrue(self.ddb.store(team))
        self.assertTrue(self.ddb.store(team2))

        another_team = self.ddb.query(Team, [('displayname', 'Rocket 2.0')])
        same_team = self.ddb.query(Team, [('platform', 'slack')])
        multi_queries = self.ddb.query(Team, [('displayname', 'Rocket 2.0'),
                                              ('platform', 'slack')])
        member_team = self.ddb.query(Team, [('members', 'abc_123'),
                                            ('members', 'apple')])
        all_team = self.ddb.query(Team)

        self.assertEqual(team, another_team[0])
        self.assertEqual(team, all_team[0])
        self.assertEqual(team, same_team[0])
        self.assertEqual(team, multi_queries[0])
        self.assertEqual(team2, member_team[0])

    @pytest.mark.db
    def test_delete_user(self):
        user = create_test_admin('abc_123')
        self.assertTrue(self.ddb.store(user))

        self.assertEqual(len(self.ddb.query(User)), 1)
        self.ddb.delete(User, 'abc_123')
        self.assertEqual(len(self.ddb.query(User)), 0)

    @pytest.mark.db
    def test_delete_team(self):
        team = create_test_team('1', 'rocket-2.0', 'Rocket 2.0')
        self.assertTrue(self.ddb.store(team))

        self.assertEqual(len(self.ddb.query(Team)), 1)
        self.ddb.delete(Team, '1')
        self.assertEqual(len(self.ddb.query(Team)), 0)