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))
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
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
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
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
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
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