Example #1
0
class TestComment(TestSuite):
    comment1 = CommentData(
        Comment({
            'comment_id': 1,
            'username': '******',
            'first': 'Andy',
            'last': 'Jarombek',
            'log_id': 1,
            'time': datetime.fromisoformat('2019-11-09'),
            'content': 'Test Comment',
            'deleted': False
        }))

    comment2 = CommentData(
        Comment({
            'comment_id': 2,
            'username': '******',
            'first': 'Andy',
            'last': 'Jarombek',
            'log_id': 1,
            'time': datetime.now(),
            'content': 'Another Test Comment',
            'deleted': False
        }))

    def test_comment_data_str(self) -> None:
        """
        Prove that the human readable string representation of an CommentData object is as expected.
        """
        self.assertEquals(
            str(self.comment1),
            'CommentData: [comment_id: 1, username: andy, first: Andy, last: Jarombek, log_id: 1, '
            'time: 2019-11-09 00:00:00, content: Test Comment, deleted: False]'
        )
        self.assertEquals(
            self.comment1.__str__(),
            'CommentData: [comment_id: 1, username: andy, first: Andy, last: Jarombek, log_id: 1, '
            'time: 2019-11-09 00:00:00, content: Test Comment, deleted: False]'
        )

    def test_comment_data_repr(self) -> None:
        """
        Prove that the machine readable string representation of an CommentData object is as expected.
        """
        self.assertEquals(repr(self.comment1), "<CommentData 1>")
        self.assertEquals(self.comment1.__repr__(), "<CommentData 1>")

    def test_comment_data_eq(self) -> None:
        """
        Prove that two CommentData objects with the same property values test positive for value equality.
        """
        self.assertTrue(self.comment1 == self.comment1)
        self.assertTrue(self.comment1.__eq__(self.comment1))

    def test_comment_data_ne(self) -> None:
        """
        Prove that two CommentData objects with different property values test negative for value equality.
        """
        self.assertTrue(self.comment1 != self.comment2)
        self.assertTrue(self.comment1.__ne__(self.comment2))
Example #2
0
def comment_with_id_get(comment_id):
    """
    Get a single comment with a unique ID.
    :param comment_id: The unique identifier for a comment.
    :return: A response object for the GET API request.
    """
    comment = CommentDao.get_comment_by_id(comment_id=comment_id)

    if comment is None:
        response = jsonify({
            'self': f'/v2/comments/{comment_id}',
            'comment': None,
            'log': None,
            'error': 'there is no comment with this identifier'
        })
        response.status_code = 400
        return response
    else:
        comment_dict: dict = CommentData(comment).__dict__
        comment_dict['time'] = str(comment_dict['time'])

        response = jsonify({
            'self': f'/v2/comments/{comment_id}',
            'comment': comment_dict,
            'log': f'/v2/logs/{comment_dict.get("log_id")}'
        })
        response.status_code = 200
        return response
Example #3
0
def comments_get():
    """
    Get all the comments in the database.
    :return: A response object for the GET API request.
    """
    comments: list = CommentDao.get_comments()

    if comments is None:
        response = jsonify({
            'self':
            '/v2/comments',
            'comments':
            None,
            'error':
            'an unexpected error occurred retrieving comments'
        })
        response.status_code = 500
        return response
    else:
        comment_dicts = [CommentData(comment).__dict__ for comment in comments]

        for comment_dict in comment_dicts:
            comment_dict['log'] = f'/v2/logs/{comment_dict.get("log_id")}'

        response = jsonify({'self': '/v2/comments', 'comments': comment_dicts})
        response.status_code = 200
        return response
Example #4
0
def logs_get() -> Response:
    """
    Retrieve all the exercise logs in the database.
    :return: A response object for the GET API request.
    """
    logs: list = LogDao.get_logs()

    if logs is None:
        response = jsonify({
            'self': '/v2/logs',
            'logs': None,
            'error': 'an unexpected error occurred retrieving logs'
        })
        response.status_code = 500
        return response
    else:
        log_dicts = []

        for log in logs:
            log_dict: dict = LogData(log).__dict__
            log_comments = CommentDao.get_comments_by_log_id(log.log_id)

            comment_dicts = []
            for comment in log_comments:
                comment_dict: dict = CommentData(comment).__dict__
                comment_dict['comment'] = f'/v2/comments/{comment.comment_id}'
                comment_dict['time'] = str(comment_dict['time'])

                comment_dicts.append(comment_dict)

            log_dict['comments'] = comment_dicts

            if log_dict.get('date') is not None:
                log_dict['date'] = str(log_dict['date'])
            if log_dict.get('time') is not None:
                log_dict['time'] = str(log_dict['time'])
            if log_dict.get('pace') is not None:
                log_dict['pace'] = str(log_dict['pace'])

            log_dicts.append(log_dict)

        response = jsonify({
            'self': '/v2/logs',
            'logs': log_dicts
        })
        response.status_code = 200
        return response
Example #5
0
def log_by_id_get(log_id) -> Response:
    """
    Get a single exercise log based on a unique ID.
    :param log_id: The unique identifier for an exercise log.
    :return: A response object for the GET API request.
    """
    log: Log = LogDao.get_log_by_id(log_id)

    if log is not None:
        comments = CommentDao.get_comments_by_log_id(log_id)

        comment_dicts = []
        for comment in comments:
            comment_dict: dict = CommentData(comment).__dict__
            comment_dict['comment'] = f'/v2/comments/{comment.comment_id}'
            comment_dict['time'] = str(comment_dict['time'])

            comment_dicts.append(comment_dict)

        log_dict = LogData(log).__dict__

        if log_dict.get('date') is not None:
            log_dict['date'] = str(log_dict['date'])
        if log_dict.get('time') is not None:
            log_dict['time'] = str(log_dict['time'])
        if log_dict.get('pace') is not None:
            log_dict['pace'] = str(log_dict['pace'])

        response = jsonify({
            'self': f'/v2/logs/{log_id}',
            'log': log_dict,
            'comments': comment_dicts
        })
        response.status_code = 200
        return response
    else:
        response = jsonify({
            'self': f'/v2/logs/{log_id}',
            'log': None,
            'comments': None,
            'error': 'there is no log with this identifier'
        })
        response.status_code = 400
        return response
Example #6
0
def comment_with_id_put(comment_id):
    """
    Update an existing comment.
    :param comment_id: The unique identifier for a comment.
    :return: A response object for the PUT API request.
    """
    old_comment: Comment = CommentDao.get_comment_by_id(comment_id=comment_id)

    if old_comment is None:
        response = jsonify({
            'self': f'/v2/comments/{comment_id}',
            'updated': False,
            'comment': None,
            'error': 'there is no existing comment with this id'
        })
        response.status_code = 400
        return response

    jwt_claims: dict = get_claims(request)
    jwt_username = jwt_claims.get('sub')

    if old_comment.username == jwt_username:
        current_app.logger.info(
            f'User {jwt_username} is updating a comment with id {old_comment.comment_id}.'
        )
    else:
        current_app.logger.info(
            f'User {jwt_username} is not authorized to update a comment with id {old_comment.comment_id}.'
        )
        response = jsonify({
            'self':
            f'/v2/comments/{comment_id}',
            'updated':
            False,
            'comment':
            None,
            'error':
            f'User {jwt_username} is not authorized to update a comment with id {old_comment.comment_id}.'
        })
        response.status_code = 400
        return response

    comment_data: dict = request.get_json()
    new_comment = Comment(comment_data)

    if old_comment != new_comment:

        new_comment.modified_date = datetime.now()
        new_comment.modified_app = 'saints-xctf-api'

        is_updated = CommentDao.update_comment(comment=new_comment)

        if is_updated:
            updated_comment: Comment = CommentDao.get_comment_by_id(
                comment_id=new_comment.comment_id)
            updated_comment_dict: dict = CommentData(updated_comment).__dict__

            response = jsonify({
                'self': f'/v2/comments/{comment_id}',
                'updated': True,
                'comment': updated_comment_dict
            })
            response.status_code = 200
            return response
        else:
            response = jsonify({
                'self': f'/v2/comments/{comment_id}',
                'updated': False,
                'comment': None,
                'error': 'the comment failed to update'
            })
            response.status_code = 500
            return response
    else:
        response = jsonify({
            'self':
            f'/v2/comments/{comment_id}',
            'updated':
            False,
            'comment':
            None,
            'error':
            'the comment submitted is equal to the existing comment with the same id'
        })
        response.status_code = 400
        return response
Example #7
0
def comment_post():
    """
    Create a new comment.
    :return: A response object for the POST API request.
    """
    comment_data: dict = request.get_json()

    if comment_data is None:
        response = jsonify({
            'self': f'/v2/comments',
            'added': False,
            'comment': None,
            'error': "the request body isn't populated"
        })
        response.status_code = 400
        return response

    comment_to_add = Comment(comment_data)

    jwt_claims: dict = get_claims(request)
    jwt_username = jwt_claims.get('sub')

    if comment_to_add.username == jwt_username:
        # You are so loved.
        current_app.logger.info(
            f'User {jwt_username} is creating a comment on log {comment_to_add.log_id}.'
        )
    else:
        current_app.logger.info(
            f'User {jwt_username} is not authorized to create a comment for user {comment_to_add.username}.'
        )
        response = jsonify({
            'self':
            f'/v2/comments',
            'added':
            False,
            'comment':
            None,
            'error':
            f'User {jwt_username} is not authorized to create a comment for user {comment_to_add.username}.'
        })
        response.status_code = 400
        return response

    if None in [
            comment_to_add.username, comment_to_add.first, comment_to_add.last,
            comment_to_add.log_id
    ]:
        response = jsonify({
            'self':
            f'/v2/comments',
            'added':
            False,
            'comment':
            None,
            'error':
            "'username', 'first', 'last', and 'log_id' are required fields"
        })
        response.status_code = 400
        return response

    comment_to_add.time = datetime.now()
    comment_to_add.created_date = datetime.now()
    comment_to_add.created_app = 'saints-xctf-api'
    comment_to_add.created_user = None
    comment_to_add.modified_date = None
    comment_to_add.modified_app = None
    comment_to_add.modified_user = None
    comment_to_add.deleted_date = None
    comment_to_add.deleted_app = None
    comment_to_add.deleted_user = None
    comment_to_add.deleted = False

    comment_added_successfully: bool = CommentDao.add_comment(
        new_comment=comment_to_add)

    if comment_added_successfully:
        comment_added = CommentDao.get_comment_by_id(comment_to_add.comment_id)
        comment_added_dict: dict = CommentData(comment_added).__dict__

        response = jsonify({
            'self': '/v2/comments',
            'added': True,
            'comment': comment_added_dict
        })
        response.status_code = 200
        return response
    else:
        response = jsonify({
            'self': '/v2/comments',
            'added': False,
            'comment': None,
            'error': 'failed to create a new comment'
        })
        response.status_code = 500
        return response
def log_feed_get(filter_by, bucket, limit, offset) -> Response:
    """
    Get a list of exercise logs based on certain filters.
    :param filter_by: The filtering mechanism for the exercise logs.
    You can filter by user (username) or group (group_name).
    :param bucket: The bucket to filter by (either a username or a group name)
    :param limit: The maximum number of logs to return
    :param offset: The number of logs to skip from the results of this filter before returning
    :return: A response object for the GET API request.
    """
    logs: ResultProxy = None
    count: int = 0
    limit = int(limit)
    offset = int(offset)

    jwt_claims: dict = get_claims(request)
    jwt_username = jwt_claims.get('sub')

    if filter_by == 'group' or filter_by == 'groups':
        logs = LogDao.get_group_log_feed(group_id=int(bucket), limit=limit, offset=offset)
        count = LogDao.get_group_log_feed_count(group_id=int(bucket)).first()['count']
    elif filter_by == 'user' or filter_by == 'users' or filter_by == 'username':
        logs = LogDao.get_user_log_feed(username=bucket, limit=limit, offset=offset)
        count = LogDao.get_user_log_feed_count(username=bucket).first()['count']
    elif filter_by == 'all':
        logs = LogDao.get_log_feed(limit=limit, offset=offset, username=jwt_username)
        count = LogDao.get_log_feed_count().first()['count']

    pages = int((count - 1) / limit) + 1

    # Generate LogFeed API URLs
    self_url = f'/v2/log_feed/{filter_by}/{bucket}/{limit}/{offset}'

    prev_offset = offset - limit
    if prev_offset >= 0:
        prev_url = f'/v2/log_feed/{filter_by}/{bucket}/{limit}/{prev_offset}'
    else:
        prev_url = None

    if logs is None or logs.rowcount == 0:
        response = jsonify({
            'self': self_url,
            'next': None,
            'prev': prev_url,
            'logs': None,
            'pages': 0,
            'error': 'no logs found in this feed'
        })
        response.status_code = 500
        return response
    else:
        log_list = []
        for log in logs:
            comments: list = CommentDao.get_comments_by_log_id(log.log_id)
            comments = [CommentData(comment).__dict__ for comment in comments]

            log_list.append({
                'log_id': log.log_id,
                'username': log.username,
                'first': log.first,
                'last': log.last,
                'name': log.name,
                'location': log.location,
                'date': str(log.date) if log.date is not None else None,
                'type': log.type,
                'distance': log.distance,
                'metric': log.metric,
                'miles': log.miles,
                'time': str(log.time) if log.time is not None else None,
                'pace': str(log.pace) if log.pace is not None else None,
                'feel': log.feel,
                'description': log.description,
                'comments': comments
            })

        next_url = f'/v2/log_feed/{filter_by}/{bucket}/{limit}/{offset + limit}'

        response = jsonify({
            'self': self_url,
            'next': next_url,
            'prev': prev_url,
            'logs': log_list,
            'pages': pages,
        })
        response.status_code = 200
        return response