def test_private_node_logged_out_user_cannot_see_deleted_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401)
def test_private_node_logged_out_user_cannot_see_deleted_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401)
def test_private_node_only_logged_in_commenter_can_view_deleted_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['content'], comment.content)
def test_private_node_contributor_cannot_see_other_users_deleted_file_comment(self): self._set_up_private_project_with_file_comment() comment = CommentFactory(node=self.private_project, target=self.file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content'])
def test_private_node_logged_out_user_cannot_see_deleted_file_comment(self): self._set_up_private_project_with_file_comment() comment = CommentFactory(node=self.private_project, target=self.file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.')
def test_public_node_logged_out_user_cannot_view_deleted_comments(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content'])
def test_private_node_contributor_cannot_see_other_users_deleted_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content'])
def test_public_node_logged_out_user_cannot_view_deleted_file_comments(self): self._set_up_public_project_with_file_comment() comment = CommentFactory(node=self.public_project, target=self.public_file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content'])
def test_public_node_non_contributor_cannot_view_other_users_deleted_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content'])
def test_private_node_only_logged_in_contributor_commenter_can_undelete_own_reply(self): self._set_up_private_project_with_comment() reply_target = Guid.load(self.comment._id) reply = CommentFactory(node=self.private_project, target=reply_target, user=self.user) reply_url = '/{}comments/{}/'.format(API_BASE, reply) reply.is_deleted = True reply.save() payload = self._set_up_payload(reply._id, has_content=False) res = self.app.patch_json_api(reply_url, payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_false(res.json['data']['attributes']['deleted']) assert_equal(res.json['data']['attributes']['content'], reply.content)
def test_public_node_private_comment_level_non_contributor_cannot_see_reports(self): project = ProjectFactory(is_public=True, creator=self.user, comment_level='private') comment = CommentFactory(node=project, target=project, user=self.user) comment.reports = dict() comment.reports[self.user._id] = { 'category': 'spam', 'text': 'This is spam', 'date': datetime.utcnow(), 'retracted': False, } comment.save() url = '/{}comments/{}/reports/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.')
def test_public_node_private_comment_level_non_contributor_cannot_see_reports(self): project = ProjectFactory(is_public=True, creator=self.user, comment_level='private') comment = CommentFactory(node=project, user=self.user) comment.reports = dict() comment.reports[self.user._id] = { 'category': 'spam', 'text': 'This is spam', 'date': datetime.utcnow(), 'retracted': False, } comment.save() url = '/{}comments/{}/reports/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.')
def test_public_node_private_comment_level_non_contributor_cannot_see_reports(self): project = ProjectFactory(is_public=True, creator=self.user, comment_level="private") comment = CommentFactory(node=project, target=project, user=self.user) comment.reports = dict() comment.reports[self.user._id] = { "category": "spam", "text": "This is spam", "date": datetime.utcnow(), "retracted": False, } comment.save() url = "/{}comments/{}/reports/".format(API_BASE, comment._id) res = self.app.get(url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json["errors"][0]["detail"], "You do not have permission to perform this action.")
def test_private_node_only_logged_in_contributor_commenter_can_undelete_own_reply( self): self._set_up_private_project_with_comment() reply_target = Guid.load(self.comment._id) reply = CommentFactory(node=self.private_project, target=reply_target, user=self.user) reply_url = '/{}comments/{}/'.format(API_BASE, reply) reply.is_deleted = True reply.save() payload = self._set_up_payload(reply._id, has_content=False) res = self.app.patch_json_api(reply_url, payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_false(res.json['data']['attributes']['deleted']) assert_equal(res.json['data']['attributes']['content'], reply.content)
class TestSpamMixin(OsfTestCase): def setUp(self): super(TestSpamMixin, self).setUp() self.comment = CommentFactory() self.auth = Auth(user=self.comment.user) def test_report_abuse(self): user = UserFactory() time = datetime.utcnow() self.comment.report_abuse( user, date=time, category='spam', text='ads', save=True) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) equivalent = dict( date=time, category='spam', text='ads', retracted=False ) assert_in(user._id, self.comment.reports) assert_equal(self.comment.reports[user._id], equivalent) def test_report_abuse_own_comment(self): with assert_raises(ValueError): self.comment.report_abuse( self.comment.user, category='spam', text='ads', save=True ) assert_equal(self.comment.spam_status, SpamStatus.UNKNOWN) def test_retract_report(self): user = UserFactory() time = datetime.utcnow() self.comment.report_abuse( user, date=time, category='spam', text='ads', save=True ) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) self.comment.retract_report(user, save=True) assert_equal(self.comment.spam_status, SpamStatus.UNKNOWN) equivalent = { 'date': time, 'category': 'spam', 'text': 'ads', 'retracted': True } assert_in(user._id, self.comment.reports) assert_equal(self.comment.reports[user._id], equivalent) def test_retract_report_not_reporter(self): reporter = UserFactory() non_reporter = UserFactory() self.comment.report_abuse( reporter, category='spam', text='ads', save=True ) with assert_raises(ValueError): self.comment.retract_report(non_reporter, save=True) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) def test_retract_one_report_of_many(self): user_1 = UserFactory() user_2 = UserFactory() time = datetime.utcnow() self.comment.report_abuse( user_1, date=time, category='spam', text='ads', save=True ) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) self.comment.report_abuse( user_2, date=time, category='spam', text='all', save=True ) self.comment.retract_report(user_1, save=True) equivalent = { 'date': time, 'category': 'spam', 'text': 'ads', 'retracted': True } assert_in(user_1._id, self.comment.reports) assert_equal(self.comment.reports[user_1._id], equivalent) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) def test_flag_spam(self): self.comment.flag_spam() self.comment.save() assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) def test_cannot_remove_flag_not_retracted(self): user = UserFactory() self.comment.report_abuse( user, category='spam', text='ads', save=True ) self.comment.remove_flag(save=True) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) def test_remove_flag(self): self.comment.flag_spam() self.comment.save() assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) self.comment.remove_flag(save=True) assert_equal(self.comment.spam_status, SpamStatus.UNKNOWN) def test_confirm_ham(self): self.comment.confirm_ham(save=True) assert_equal(self.comment.spam_status, SpamStatus.HAM) def test_confirm_spam(self): self.comment.confirm_spam(save=True) assert_equal(self.comment.spam_status, SpamStatus.SPAM) def test_validate_reports_bad_key(self): self.comment.reports[None] = {'category': 'spam', 'text': 'ads'} with assert_raises(ValidationValueError): self.comment.save() def test_validate_reports_bad_type(self): self.comment.reports[self.comment.user._id] = 'not a dict' with assert_raises(ValidationTypeError): self.comment.save() def test_validate_reports_bad_value(self): self.comment.reports[self.comment.user._id] = {'foo': 'bar'} with assert_raises(ValidationValueError): self.comment.save()
class TestCommentModel(OsfTestCase): def setUp(self): super(TestCommentModel, self).setUp() self.comment = CommentFactory() self.auth = Auth(user=self.comment.user) def test_create(self): comment = Comment.create( auth=self.auth, user=self.comment.user, node=self.comment.node, target=self.comment.target, page='node', is_public=True, content='This is a comment.' ) assert_equal(comment.user, self.comment.user) assert_equal(comment.node, self.comment.node) assert_equal(comment.target, self.comment.target) assert_equal(len(comment.node.logs), 2) assert_equal(comment.node.logs[-1].action, NodeLog.COMMENT_ADDED) def test_create_comment_content_cannot_exceed_max_length(self): with assert_raises(ValidationValueError): comment = Comment.create( auth=self.auth, user=self.comment.user, node=self.comment.node, target=self.comment.target, is_public=True, content=''.join(['c' for c in range(settings.COMMENT_MAXLENGTH + 1)]) ) def test_create_comment_content_cannot_be_none(self): with assert_raises(ValidationError) as error: comment = Comment.create( auth=self.auth, user=self.comment.user, node=self.comment.node, target=self.comment.target, is_public=True, content=None ) assert_equal(error.exception.message, 'Value <content> is required.') def test_create_comment_content_cannot_be_empty(self): with assert_raises(ValidationValueError) as error: comment = Comment.create( auth=self.auth, user=self.comment.user, node=self.comment.node, target=self.comment.target, is_public=True, content='' ) assert_equal(error.exception.message, 'Value must not be empty.') def test_create_comment_content_cannot_be_whitespace(self): with assert_raises(ValidationValueError) as error: comment = Comment.create( auth=self.auth, user=self.comment.user, node=self.comment.node, target=self.comment.target, is_public=True, content=' ' ) assert_equal(error.exception.message, 'Value must not be empty.') def test_create_sends_comment_added_signal(self): with capture_signals() as mock_signals: comment = Comment.create( auth=self.auth, user=self.comment.user, node=self.comment.node, target=self.comment.target, is_public=True, content='This is a comment.' ) assert_equal(mock_signals.signals_sent(), set([comment_added])) def test_edit(self): self.comment.edit( auth=self.auth, content='edited', save=True ) assert_equal(self.comment.content, 'edited') assert_true(self.comment.modified) assert_equal(len(self.comment.node.logs), 2) assert_equal(self.comment.node.logs[-1].action, NodeLog.COMMENT_UPDATED) def test_delete(self): self.comment.delete(auth=self.auth, save=True) assert_equal(self.comment.is_deleted, True) assert_equal(len(self.comment.node.logs), 2) assert_equal(self.comment.node.logs[-1].action, NodeLog.COMMENT_REMOVED) def test_undelete(self): self.comment.delete(auth=self.auth, save=True) self.comment.undelete(auth=self.auth, save=True) assert_equal(self.comment.is_deleted, False) assert_equal(len(self.comment.node.logs), 3) assert_equal(self.comment.node.logs[-1].action, NodeLog.COMMENT_RESTORED) def test_report_abuse(self): user = UserFactory() self.comment.report_abuse(user, category='spam', text='ads', save=True) assert_in(user._id, self.comment.reports) assert_equal( self.comment.reports[user._id], {'category': 'spam', 'text': 'ads'} ) def test_report_abuse_own_comment(self): with assert_raises(ValueError): self.comment.report_abuse( self.comment.user, category='spam', text='ads', save=True ) def test_unreport_abuse(self): user = UserFactory() self.comment.report_abuse(user, category='spam', text='ads', save=True) self.comment.unreport_abuse(user, save=True) assert_not_in(user._id, self.comment.reports) def test_unreport_abuse_not_reporter(self): reporter = UserFactory() non_reporter = UserFactory() self.comment.report_abuse(reporter, category='spam', text='ads', save=True) with assert_raises(ValueError): self.comment.unreport_abuse(non_reporter, save=True) assert_in(reporter._id, self.comment.reports) def test_validate_reports_bad_key(self): self.comment.reports[None] = {'category': 'spam', 'text': 'ads'} with assert_raises(ValidationValueError): self.comment.save() def test_validate_reports_bad_type(self): self.comment.reports[self.comment.user._id] = 'not a dict' with assert_raises(ValidationTypeError): self.comment.save() def test_validate_reports_bad_value(self): self.comment.reports[self.comment.user._id] = {'foo': 'bar'} with assert_raises(ValidationValueError): self.comment.save() def test_read_permission_contributor_can_comment(self): project = ProjectFactory() user = UserFactory() project.set_privacy('private') project.add_contributor(user, 'read') project.save() assert_true(project.can_comment(Auth(user=user))) def test_get_content_for_not_deleted_comment(self): project = ProjectFactory(is_public=True) comment = CommentFactory(node=project) content = comment.get_content(auth=Auth(comment.user)) assert_equal(content, comment.content) def test_get_content_returns_deleted_content_to_commenter(self): comment = CommentFactory(is_deleted=True) content = comment.get_content(auth=Auth(comment.user)) assert_equal(content, comment.content) def test_get_content_does_not_return_deleted_content_to_non_commenter(self): user = AuthUserFactory() comment = CommentFactory(is_deleted=True) content = comment.get_content(auth=Auth(user)) assert_is_none(content) def test_get_content_public_project_does_not_return_deleted_content_to_logged_out_user(self): project = ProjectFactory(is_public=True) comment = CommentFactory(node=project, is_deleted=True) content = comment.get_content(auth=None) assert_is_none(content) def test_get_content_private_project_throws_permissions_error_for_logged_out_users(self): project = ProjectFactory(is_public=False) comment = CommentFactory(node=project, is_deleted=True) with assert_raises(PermissionsError): comment.get_content(auth=None) def test_find_unread_is_zero_when_no_comments(self): n_unread = Comment.find_n_unread(user=UserFactory(), node=ProjectFactory()) assert_equal(n_unread, 0) def test_find_unread_new_comments(self): project = ProjectFactory() user = UserFactory() project.add_contributor(user) project.save() comment = CommentFactory(node=project, user=project.creator) n_unread = Comment.find_n_unread(user=user, node=project) assert_equal(n_unread, 1) def test_find_unread_includes_comment_replies(self): project = ProjectFactory() user = UserFactory() project.add_contributor(user) project.save() comment = CommentFactory(node=project, user=user) reply = CommentFactory(node=project, target=comment, user=project.creator) n_unread = Comment.find_n_unread(user=user, node=project) assert_equal(n_unread, 1) # Regression test for https://openscience.atlassian.net/browse/OSF-5193 def test_find_unread_includes_edited_comments(self): project = ProjectFactory() user = AuthUserFactory() project.add_contributor(user) project.save() comment = CommentFactory(node=project, user=project.creator) url = project.api_url_for('update_comments_timestamp') payload = {'page': 'node', 'rootId': project._id} res = self.app.put_json(url, payload, auth=user.auth) user.reload() n_unread = Comment.find_n_unread(user=user, node=project) assert_equal(n_unread, 0) # Edit previously read comment comment.edit( auth=Auth(project.creator), content='edited', save=True ) n_unread = Comment.find_n_unread(user=user, node=project) assert_equal(n_unread, 1) def test_find_unread_does_not_include_deleted_comments(self): project = ProjectFactory() user = AuthUserFactory() project.add_contributor(user) project.save() comment = CommentFactory(node=project, user=project.creator, is_deleted=True) n_unread = Comment.find_n_unread(user=user, node=project) assert_equal(n_unread, 0)
class TestSpamMixin(OsfTestCase): def setUp(self): super(TestSpamMixin, self).setUp() self.comment = CommentFactory() self.auth = Auth(user=self.comment.user) def test_report_abuse(self): user = UserFactory() time = datetime.utcnow() self.comment.report_abuse(user, date=time, category='spam', text='ads', save=True) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) equivalent = dict(date=time, category='spam', text='ads', retracted=False) assert_in(user._id, self.comment.reports) assert_equal(self.comment.reports[user._id], equivalent) def test_report_abuse_own_comment(self): with assert_raises(ValueError): self.comment.report_abuse(self.comment.user, category='spam', text='ads', save=True) assert_equal(self.comment.spam_status, SpamStatus.UNKNOWN) def test_retract_report(self): user = UserFactory() time = datetime.utcnow() self.comment.report_abuse(user, date=time, category='spam', text='ads', save=True) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) self.comment.retract_report(user, save=True) assert_equal(self.comment.spam_status, SpamStatus.UNKNOWN) equivalent = { 'date': time, 'category': 'spam', 'text': 'ads', 'retracted': True } assert_in(user._id, self.comment.reports) assert_equal(self.comment.reports[user._id], equivalent) def test_retract_report_not_reporter(self): reporter = UserFactory() non_reporter = UserFactory() self.comment.report_abuse(reporter, category='spam', text='ads', save=True) with assert_raises(ValueError): self.comment.retract_report(non_reporter, save=True) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) def test_retract_one_report_of_many(self): user_1 = UserFactory() user_2 = UserFactory() time = datetime.utcnow() self.comment.report_abuse(user_1, date=time, category='spam', text='ads', save=True) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) self.comment.report_abuse(user_2, date=time, category='spam', text='all', save=True) self.comment.retract_report(user_1, save=True) equivalent = { 'date': time, 'category': 'spam', 'text': 'ads', 'retracted': True } assert_in(user_1._id, self.comment.reports) assert_equal(self.comment.reports[user_1._id], equivalent) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) def test_flag_spam(self): self.comment.flag_spam() self.comment.save() assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) def test_cannot_remove_flag_not_retracted(self): user = UserFactory() self.comment.report_abuse(user, category='spam', text='ads', save=True) self.comment.remove_flag(save=True) assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) def test_remove_flag(self): self.comment.flag_spam() self.comment.save() assert_equal(self.comment.spam_status, SpamStatus.FLAGGED) self.comment.remove_flag(save=True) assert_equal(self.comment.spam_status, SpamStatus.UNKNOWN) def test_confirm_ham(self): self.comment.confirm_ham(save=True) assert_equal(self.comment.spam_status, SpamStatus.HAM) def test_confirm_spam(self): self.comment.confirm_spam(save=True) assert_equal(self.comment.spam_status, SpamStatus.SPAM) def test_validate_reports_bad_key(self): self.comment.reports[None] = {'category': 'spam', 'text': 'ads'} with assert_raises(ValidationValueError): self.comment.save() def test_validate_reports_bad_type(self): self.comment.reports[self.comment.user._id] = 'not a dict' with assert_raises(ValidationTypeError): self.comment.save() def test_validate_reports_bad_value(self): self.comment.reports[self.comment.user._id] = {'foo': 'bar'} with assert_raises(ValidationValueError): self.comment.save()
class TestCommentDetailView(ApiTestCase): def setUp(self): super(TestCommentDetailView, self).setUp() self.user = AuthUserFactory() self.contributor = AuthUserFactory() self.non_contributor = AuthUserFactory() def _set_up_private_project_with_comment(self): self.private_project = ProjectFactory.build(is_public=False, creator=self.user) self.private_project.add_contributor(self.contributor, save=True) self.comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) self.private_url = '/{}comments/{}/'.format(API_BASE, self.comment._id) self.payload = { 'data': { 'id': self.comment._id, 'type': 'comments', 'attributes': { 'content': 'Updating this comment', 'deleted': False } } } def _set_up_public_project_with_comment(self): self.public_project = ProjectFactory.build(is_public=True, creator=self.user) self.public_project.add_contributor(self.contributor, save=True) self.public_comment = CommentFactory(node=self.public_project, target=self.public_project, user=self.user) self.public_url = '/{}comments/{}/'.format(API_BASE, self.public_comment._id) self.public_comment_payload = { 'data': { 'id': self.public_comment._id, 'type': 'comments', 'attributes': { 'content': 'Updating this comment', 'deleted': False } } } def _set_up_registration_with_comment(self): self.registration = RegistrationFactory(creator=self.user) self.registration_comment = CommentFactory(node=self.registration, user=self.user) self.registration_url = '/{}comments/{}/'.format(API_BASE, self.registration_comment._id) def test_private_node_logged_in_contributor_can_view_comment(self): self._set_up_private_project_with_comment() res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.comment._id, res.json['data']['id']) assert_equal(self.comment.content, res.json['data']['attributes']['content']) def test_private_node_logged_in_non_contributor_cannot_view_comment(self): self._set_up_private_project_with_comment() res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_logged_out_user_cannot_view_comment(self): self._set_up_private_project_with_comment() res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) def test_private_node_user_with_private_link_can_see_comment(self): self._set_up_private_project_with_comment() private_link = PrivateLinkFactory(anonymous=False) private_link.nodes.append(self.private_project) private_link.save() res = self.app.get('/{}comments/{}/'.format(API_BASE, self.comment._id), {'view_only': private_link.key}, expect_errors=True) assert_equal(res.status_code, 200) assert_equal(self.comment._id, res.json['data']['id']) assert_equal(self.comment.content, res.json['data']['attributes']['content']) def test_private_node_user_with_anonymous_link_cannot_see_commenter_info(self): self._set_up_private_project_with_comment() private_link = PrivateLinkFactory(anonymous=True) private_link.nodes.append(self.private_project) private_link.save() res = self.app.get('/{}comments/{}/'.format(API_BASE, self.comment._id), {'view_only': private_link.key}, expect_errors=True) assert_equal(res.status_code, 200) assert_equal(self.comment._id, res.json['data']['id']) assert_equal(self.comment.content, res.json['data']['attributes']['content']) assert_not_in('user', res.json['data']['relationships']) def test_public_node_logged_in_contributor_can_view_comment(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_public_node_logged_in_non_contributor_can_view_comment(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_public_node_logged_out_user_can_view_comment(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) assert_equal(res.status_code, 200) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_public_node_user_with_private_link_can_view_comment(self): self._set_up_public_project_with_comment() private_link = PrivateLinkFactory(anonymous=False) private_link.nodes.append(self.public_project) private_link.save() res = self.app.get('/{}comments/{}/'.format(API_BASE, self.public_comment._id), {'view_only': private_link.key}, expect_errors=True) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_registration_logged_in_contributor_can_view_comment(self): self._set_up_registration_with_comment() res = self.app.get(self.registration_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.registration_comment._id, res.json['data']['id']) assert_equal(self.registration_comment.content, res.json['data']['attributes']['content']) def test_comment_has_user_link(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['user']['links']['related']['href'] expected_url = '/{}users/{}/'.format(API_BASE, self.user._id) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_comment_has_node_link(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['node']['links']['related']['href'] expected_url = '/{}nodes/{}/'.format(API_BASE, self.public_project._id) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_comment_has_target_link_with_correct_type(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['target']['links']['related']['href'] expected_url = '/{}nodes/{}/'.format(API_BASE, self.public_project._id) target_type = res.json['data']['relationships']['target']['links']['related']['meta']['type'] expected_type = 'nodes' assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) assert_equal(target_type, expected_type) def test_comment_has_replies_link(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['replies']['links']['self']['href'] expected_url = '/{}comments/{}/replies/'.format(API_BASE, self.public_comment) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_comment_has_reports_link(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['reports']['links']['related']['href'] expected_url = '/{}comments/{}/reports/'.format(API_BASE, self.public_comment) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_private_node_only_logged_in_contributor_commenter_can_update_comment(self): self._set_up_private_project_with_comment() res = self.app.put_json_api(self.private_url, self.payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.payload['data']['attributes']['content'], res.json['data']['attributes']['content']) def test_private_node_logged_in_non_contributor_cannot_update_comment(self): self._set_up_private_project_with_comment() res = self.app.put_json_api(self.private_url, self.payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_logged_out_user_cannot_update_comment(self): self._set_up_private_project_with_comment() res = self.app.put_json_api(self.private_url, self.payload, expect_errors=True) assert_equal(res.status_code, 401) def test_public_node_only_contributor_commenter_can_update_comment(self): self._set_up_public_project_with_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.public_comment_payload['data']['attributes']['content'], res.json['data']['attributes']['content']) def test_public_node_contributor_cannot_update_other_users_comment(self): self._set_up_public_project_with_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_public_node_non_contributor_cannot_update_other_users_comment(self): self._set_up_public_project_with_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_public_node_logged_out_user_cannot_update_comment(self): self._set_up_public_project_with_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, expect_errors=True) assert_equal(res.status_code, 401) def test_public_node_non_contributor_commenter_can_update_comment(self): project = ProjectFactory(is_public=True, comment_level='public') comment = CommentFactory(node=project, target=project, user=self.non_contributor) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'content': 'Updating this comment', 'deleted': False } } } res = self.app.put_json_api(url, payload, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_equal(payload['data']['attributes']['content'], res.json['data']['attributes']['content']) def test_update_comment_cannot_exceed_max_length(self): self._set_up_private_project_with_comment() payload = { 'data': { 'id': self.comment._id, 'type': 'comments', 'attributes': { 'content': ''.join(['c' for c in range(osf_settings.COMMENT_MAXLENGTH + 1)]), 'deleted': False } } } res = self.app.put_json_api(self.private_url, payload, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'Ensure this field has no more than {} characters.'.format(str(osf_settings.COMMENT_MAXLENGTH))) def test_update_comment_cannot_be_empty(self): self._set_up_private_project_with_comment() payload = { 'data': { 'id': self.comment._id, 'type': 'comments', 'attributes': { 'content': '', 'deleted': False } } } res = self.app.put_json_api(self.private_url, payload, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'This field may not be blank.') def test_private_node_only_logged_in_contributor_commenter_can_delete_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': True } } } res = self.app.patch_json_api(url, payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_true(res.json['data']['attributes']['deleted']) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_private_node_contributor_cannot_delete_other_users_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': True } } } res = self.app.patch_json_api(url, payload, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_non_contributor_cannot_delete_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': True } } } res = self.app.patch_json_api(url, payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_logged_out_user_cannot_delete_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': True } } } res = self.app.patch_json_api(url, payload, expect_errors=True) assert_equal(res.status_code, 401) def test_private_node_only_logged_in_contributor_commenter_can_undelete_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory.build(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_false(res.json['data']['attributes']['deleted']) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_private_node_contributor_cannot_undelete_other_users_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory.build(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_non_contributor_cannot_undelete_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory.build(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_logged_out_user_cannot_undelete_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory.build(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, expect_errors=True) assert_equal(res.status_code, 401) def test_public_node_only_logged_in_contributor_commenter_can_delete_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': True } } } res = self.app.patch_json_api(url, payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_true(res.json['data']['attributes']['deleted']) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_public_node_contributor_cannot_delete_other_users_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': True } } } res = self.app.patch_json_api(url, payload, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_public_node_non_contributor_cannot_delete_other_users_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': True } } } res = self.app.patch_json_api(url, payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_public_node_logged_out_user_cannot_delete_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': True } } } res = self.app.patch_json_api(url, payload, expect_errors=True) assert_equal(res.status_code, 401) def test_public_node_non_contributor_commenter_can_delete_comment(self): project = ProjectFactory(is_public=True, comment_level='public') comment = CommentFactory(node=project, target=project, user=self.non_contributor) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': True } } } res = self.app.patch_json_api(url, payload, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_true(res.json['data']['attributes']['deleted']) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_private_node_only_logged_in_commenter_can_view_deleted_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_private_node_contributor_cannot_see_other_users_deleted_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_private_node_logged_out_user_cannot_see_deleted_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_private_node_view_only_link_user_cannot_see_deleted_comment(self): self._set_up_private_project_with_comment() self.comment.is_deleted = True self.comment.save() private_link = PrivateLinkFactory(anonymous=False) private_link.nodes.append(self.private_project) private_link.save() res= self.app.get('/{}comments/{}/'.format(API_BASE, self.comment._id), {'view_only': private_link.key}, expect_errors=True) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_private_node_anonymous_view_only_link_user_cannot_see_deleted_comment(self): self._set_up_private_project_with_comment() self.comment.is_deleted = True self.comment.save() anonymous_link = PrivateLinkFactory(anonymous=True) anonymous_link.nodes.append(self.private_project) anonymous_link.save() res= self.app.get('/{}comments/{}/'.format(API_BASE, self.comment._id), {'view_only': anonymous_link.key}, expect_errors=True) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_public_node_only_logged_in_commenter_can_view_deleted_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_public_node_contributor_cannot_view_other_users_deleted_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_public_node_non_contributor_cannot_view_other_users_deleted_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_public_node_logged_out_user_cannot_view_deleted_comments(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_public_node_view_only_link_user_cannot_see_deleted_comment(self): self._set_up_public_project_with_comment() self.public_comment.is_deleted = True self.public_comment.save() private_link = PrivateLinkFactory(anonymous=False) private_link.nodes.append(self.public_project) private_link.save() res = self.app.get('/{}comments/{}/'.format(API_BASE, self.public_comment._id), {'view_only': private_link.key}, expect_errors=True) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content'])
class TestCommentDetailView(ApiTestCase): def setUp(self): super(TestCommentDetailView, self).setUp() self.user = AuthUserFactory() self.contributor = AuthUserFactory() self.non_contributor = AuthUserFactory() def _set_up_private_project_with_comment(self): self.private_project = ProjectFactory.build(is_public=False, creator=self.user) self.private_project.add_contributor(self.contributor, save=True) self.comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) self.private_url = '/{}comments/{}/'.format(API_BASE, self.comment._id) self.payload = { 'data': { 'id': self.comment._id, 'type': 'comments', 'attributes': { 'content': 'Updating this comment', 'deleted': False } } } def _set_up_public_project_with_comment(self): self.public_project = ProjectFactory.build(is_public=True, creator=self.user) self.public_project.add_contributor(self.contributor, save=True) self.public_comment = CommentFactory(node=self.public_project, target=self.public_project, user=self.user) self.public_url = '/{}comments/{}/'.format(API_BASE, self.public_comment._id) self.public_comment_payload = { 'data': { 'id': self.public_comment._id, 'type': 'comments', 'attributes': { 'content': 'Updating this comment', 'deleted': False } } } def _set_up_registration_with_comment(self): self.registration = RegistrationFactory(creator=self.user) self.registration_comment = CommentFactory(node=self.registration, user=self.user) self.registration_url = '/{}comments/{}/'.format(API_BASE, self.registration_comment._id) def test_private_node_logged_in_contributor_can_view_comment(self): self._set_up_private_project_with_comment() res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.comment._id, res.json['data']['id']) assert_equal(self.comment.content, res.json['data']['attributes']['content']) def test_private_node_logged_in_non_contributor_cannot_view_comment(self): self._set_up_private_project_with_comment() res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_logged_out_user_cannot_view_comment(self): self._set_up_private_project_with_comment() res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) def test_private_node_user_with_private_link_can_see_comment(self): self._set_up_private_project_with_comment() private_link = PrivateLinkFactory(anonymous=False) private_link.nodes.append(self.private_project) private_link.save() res = self.app.get('/{}comments/{}/'.format(API_BASE, self.comment._id), {'view_only': private_link.key}, expect_errors=True) assert_equal(res.status_code, 200) assert_equal(self.comment._id, res.json['data']['id']) assert_equal(self.comment.content, res.json['data']['attributes']['content']) def test_private_node_user_with_anonymous_link_cannot_see_commenter_info(self): self._set_up_private_project_with_comment() private_link = PrivateLinkFactory(anonymous=True) private_link.nodes.append(self.private_project) private_link.save() res = self.app.get('/{}comments/{}/'.format(API_BASE, self.comment._id), {'view_only': private_link.key}, expect_errors=True) assert_equal(res.status_code, 200) assert_equal(self.comment._id, res.json['data']['id']) assert_equal(self.comment.content, res.json['data']['attributes']['content']) assert_not_in('user', res.json['data']['relationships']) def test_public_node_logged_in_contributor_can_view_comment(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_public_node_logged_in_non_contributor_can_view_comment(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_public_node_logged_out_user_can_view_comment(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) assert_equal(res.status_code, 200) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_public_node_user_with_private_link_can_view_comment(self): self._set_up_public_project_with_comment() private_link = PrivateLinkFactory(anonymous=False) private_link.nodes.append(self.public_project) private_link.save() res = self.app.get('/{}comments/{}/'.format(API_BASE, self.public_comment._id), {'view_only': private_link.key}, expect_errors=True) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_registration_logged_in_contributor_can_view_comment(self): self._set_up_registration_with_comment() res = self.app.get(self.registration_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.registration_comment._id, res.json['data']['id']) assert_equal(self.registration_comment.content, res.json['data']['attributes']['content']) def test_comment_has_user_link(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['user']['links']['related']['href'] expected_url = '/{}users/{}/'.format(API_BASE, self.user._id) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_comment_has_node_link(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['node']['links']['related']['href'] expected_url = '/{}nodes/{}/'.format(API_BASE, self.public_project._id) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_comment_has_target_link_with_correct_type(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['target']['links']['related']['href'] expected_url = '/{}nodes/{}/'.format(API_BASE, self.public_project._id) target_type = res.json['data']['relationships']['target']['links']['related']['meta']['type'] expected_type = 'nodes' assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) assert_equal(target_type, expected_type) def test_comment_has_replies_link(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['replies']['links']['self']['href'] expected_url = '/{}nodes/{}/comments/?filter[target]={}'.format(API_BASE, self.public_project._id, self.public_comment._id) assert_equal(res.status_code, 200) assert_in(expected_url, url) def test_comment_has_reports_link(self): self._set_up_public_project_with_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['reports']['links']['related']['href'] expected_url = '/{}comments/{}/reports/'.format(API_BASE, self.public_comment) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_private_node_only_logged_in_contributor_commenter_can_update_comment(self): self._set_up_private_project_with_comment() res = self.app.put_json_api(self.private_url, self.payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.payload['data']['attributes']['content'], res.json['data']['attributes']['content']) def test_private_node_logged_in_non_contributor_cannot_update_comment(self): self._set_up_private_project_with_comment() res = self.app.put_json_api(self.private_url, self.payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_logged_out_user_cannot_update_comment(self): self._set_up_private_project_with_comment() res = self.app.put_json_api(self.private_url, self.payload, expect_errors=True) assert_equal(res.status_code, 401) def test_public_node_only_contributor_commenter_can_update_comment(self): self._set_up_public_project_with_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.public_comment_payload['data']['attributes']['content'], res.json['data']['attributes']['content']) def test_public_node_contributor_cannot_update_other_users_comment(self): self._set_up_public_project_with_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_public_node_non_contributor_cannot_update_other_users_comment(self): self._set_up_public_project_with_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_public_node_logged_out_user_cannot_update_comment(self): self._set_up_public_project_with_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, expect_errors=True) assert_equal(res.status_code, 401) def test_public_node_non_contributor_commenter_can_update_comment(self): project = ProjectFactory(is_public=True, comment_level='public') comment = CommentFactory(node=project, target=project, user=self.non_contributor) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'content': 'Updating this comment', 'deleted': False } } } res = self.app.put_json_api(url, payload, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_equal(payload['data']['attributes']['content'], res.json['data']['attributes']['content']) def test_update_comment_cannot_exceed_max_length(self): self._set_up_private_project_with_comment() payload = { 'data': { 'id': self.comment._id, 'type': 'comments', 'attributes': { 'content': ''.join(['c' for c in range(osf_settings.COMMENT_MAXLENGTH + 1)]), 'deleted': False } } } res = self.app.put_json_api(self.private_url, payload, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'Ensure this field has no more than {} characters.'.format(str(osf_settings.COMMENT_MAXLENGTH))) def test_update_comment_cannot_be_empty(self): self._set_up_private_project_with_comment() payload = { 'data': { 'id': self.comment._id, 'type': 'comments', 'attributes': { 'content': '', 'deleted': False } } } res = self.app.put_json_api(self.private_url, payload, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'This field may not be blank.') def test_private_node_only_logged_in_contributor_commenter_can_delete_comment(self): self._set_up_private_project_with_comment() res = self.app.delete_json_api(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 204) def test_private_node_contributor_cannot_delete_other_users_comment(self): self._set_up_private_project_with_comment() res = self.app.delete_json_api(self.private_url, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_non_contributor_cannot_delete_comment(self): self._set_up_private_project_with_comment() res = self.app.delete_json_api(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_logged_out_user_cannot_delete_comment(self): self._set_up_private_project_with_comment() res = self.app.delete_json_api(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) def test_private_node_user_cannot_delete_already_deleted_comment(self): self._set_up_private_project_with_comment() self.comment.is_deleted = True self.comment.save() res = self.app.delete_json_api(self.private_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'Comment already deleted.') def test_private_node_only_logged_in_contributor_commenter_can_undelete_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory.build(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_false(res.json['data']['attributes']['deleted']) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_private_node_contributor_cannot_undelete_other_users_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory.build(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_non_contributor_cannot_undelete_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory.build(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_private_node_logged_out_user_cannot_undelete_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory.build(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, expect_errors=True) assert_equal(res.status_code, 401) def test_public_node_only_logged_in_contributor_commenter_can_delete_comment(self): self._set_up_public_project_with_comment() res = self.app.delete_json_api(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 204) def test_public_node_contributor_cannot_delete_other_users_comment(self): self._set_up_public_project_with_comment() res = self.app.delete_json_api(self.public_url, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_public_node_non_contributor_cannot_delete_other_users_comment(self): self._set_up_public_project_with_comment() res = self.app.delete_json_api(self.public_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_public_node_logged_out_user_cannot_delete_comment(self): self._set_up_public_project_with_comment() res = self.app.delete_json_api(self.public_url, expect_errors=True) assert_equal(res.status_code, 401) def test_public_node_non_contributor_commenter_can_delete_comment(self): project = ProjectFactory(is_public=True, comment_level='public') comment = CommentFactory(node=project, target=project, user=self.non_contributor) url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.delete_json_api(url, auth=self.non_contributor.auth) assert_equal(res.status_code, 204) def test_public_node_user_cannot_delete_already_deleted_comment(self): self._set_up_public_project_with_comment() self.public_comment.is_deleted = True self.public_comment.save() res = self.app.delete_json_api(self.public_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'Comment already deleted.') def test_private_node_only_logged_in_commenter_can_view_deleted_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_private_node_contributor_cannot_see_other_users_deleted_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_private_node_logged_out_user_cannot_see_deleted_comment(self): self._set_up_private_project_with_comment() comment = CommentFactory(node=self.private_project, target=self.private_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_private_node_view_only_link_user_cannot_see_deleted_comment(self): self._set_up_private_project_with_comment() self.comment.is_deleted = True self.comment.save() private_link = PrivateLinkFactory(anonymous=False) private_link.nodes.append(self.private_project) private_link.save() res = self.app.get('/{}comments/{}/'.format(API_BASE, self.comment._id), {'view_only': private_link.key}, expect_errors=True) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_private_node_anonymous_view_only_link_user_cannot_see_deleted_comment(self): self._set_up_private_project_with_comment() self.comment.is_deleted = True self.comment.save() anonymous_link = PrivateLinkFactory(anonymous=True) anonymous_link.nodes.append(self.private_project) anonymous_link.save() res = self.app.get('/{}comments/{}/'.format(API_BASE, self.comment._id), {'view_only': anonymous_link.key}, expect_errors=True) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_public_node_only_logged_in_commenter_can_view_deleted_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_public_node_contributor_cannot_view_other_users_deleted_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_public_node_non_contributor_cannot_view_other_users_deleted_comment(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_public_node_logged_out_user_cannot_view_deleted_comments(self): public_project = ProjectFactory(is_public=True, creator=self.user) comment = CommentFactory(node=public_project, target=public_project, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_public_node_view_only_link_user_cannot_see_deleted_comment(self): self._set_up_public_project_with_comment() self.public_comment.is_deleted = True self.public_comment.save() private_link = PrivateLinkFactory(anonymous=False) private_link.nodes.append(self.public_project) private_link.save() res = self.app.get('/{}comments/{}/'.format(API_BASE, self.public_comment._id), {'view_only': private_link.key}, expect_errors=True) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content'])
def _set_up_comment_with_target(self, root_target, target): comment = CommentFactory(node=self.project) comment.root_target = root_target comment.target = target comment.save() return comment
class TestMigrateSpam(OsfTestCase): def setUp(self): super(TestMigrateSpam, self).setUp() self.generic_report = { 'category': 'spam', 'text': 'spammer spam', 'date': datetime.utcnow(), 'retracted': False } Comment.remove() self.user = AuthUserFactory() self.comment_1 = CommentFactory() self.comment_1.spam_status = 0 self.comment_1.reports[self.user._id] = self.generic_report self.comment_1.save() self.comment_2 = CommentFactory() self.comment_2.spam_status = 0 self.comment_2.reports[self.user._id] = self.generic_report self.comment_2.save() self.comment_3 = CommentFactory() self.comment_3.spam_status = 0 self.comment_3.save() self.comment_4 = CommentFactory() self.comment_4.date_last_reported = None self.comment_4.spam_status = Comment.FLAGGED self.comment_4.reports[self.user._id] = self.generic_report self.comment_4.save() self.comment_5 = CommentFactory() self.comment_5.date_last_reported = None self.comment_5.spam_status = Comment.UNKNOWN self.comment_5.save() self.comment_6 = CommentFactory() self.comment_6.date_last_reported = None self.comment_6.spam_status = Comment.SPAM self.comment_6.reports[self.user._id] = self.generic_report self.comment_6.save() def test_get_status_targets(self): targets = migrate_spam.get_no_status_targets() nt.assert_equal(len(targets), 3) def test_get_latest_targets(self): migrate_spam.migrate_status(migrate_spam.get_no_status_targets()) targets = migrate_spam.get_no_latest_targets() nt.assert_equal(len(targets), 4) def test_migrate_status(self): migrate_spam.migrate_status(migrate_spam.get_no_status_targets()) self.comment_2.reload() self.comment_1.reload() self.comment_3.reload() nt.assert_equal(self.comment_1.spam_status, Comment.FLAGGED) nt.assert_equal(self.comment_2.spam_status, Comment.FLAGGED) nt.assert_equal(self.comment_3.spam_status, Comment.UNKNOWN) def test_migrate_latest(self): migrate_spam.migrate_status(migrate_spam.get_no_status_targets()) migrate_spam.migrate_latest(migrate_spam.get_no_latest_targets()) date = self.generic_report['date'] self.comment_4.reload() self.comment_6.reload() nt.assert_almost_equal( self.comment_4.date_last_reported, date, delta=timedelta(microseconds=1000) ) nt.assert_almost_equal( self.comment_6.date_last_reported, date, delta=timedelta(microseconds=1000) )
class TestFileCommentDetailView(ApiTestCase): def setUp(self): super(TestFileCommentDetailView, self).setUp() self.user = AuthUserFactory() self.contributor = AuthUserFactory() self.non_contributor = AuthUserFactory() def _set_up_payload(self, target_id): return { 'data': { 'id': target_id, 'type': 'comments', 'attributes': { 'content': 'Updating this comment', 'deleted': False } } } def _set_up_private_project_with_file_comment(self): self.private_project = ProjectFactory.build(is_public=False, creator=self.user, comment_level='private') self.private_project.add_contributor(self.contributor, save=True) self.file = test_utils.create_test_file(self.private_project, self.user) self.comment = CommentFactory(node=self.private_project, target=self.file, user=self.user) self.private_url = '/{}comments/{}/'.format(API_BASE, self.comment._id) self.payload = self._set_up_payload(self.comment._id) def _set_up_public_project_with_file_comment(self): self.public_project = ProjectFactory.build(is_public=True, creator=self.user, comment_level='private') self.public_project.add_contributor(self.contributor, save=True) self.public_file = test_utils.create_test_file(self.public_project, self.user) self.public_comment = CommentFactory(node=self.public_project, target=self.public_file, user=self.user) self.public_url = '/{}comments/{}/'.format(API_BASE, self.public_comment._id) self.public_comment_payload = self._set_up_payload(self.public_comment._id) def _set_up_registration_with_file_comment(self): self.registration = RegistrationFactory(creator=self.user, comment_level='private') self.registration_file = test_utils.create_test_file(self.registration, self.user) self.registration_comment = CommentFactory(node=self.registration, target=self.registration_file, user=self.user) self.registration_url = '/{}comments/{}/'.format(API_BASE, self.registration_comment._id) def test_private_node_logged_in_contributor_can_view_file_comment(self): self._set_up_private_project_with_file_comment() res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.comment._id, res.json['data']['id']) assert_equal(self.comment.content, res.json['data']['attributes']['content']) def test_private_node_logged_in_non_contributor_cannot_view_file_comment(self): self._set_up_private_project_with_file_comment() res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_private_node_logged_out_user_cannot_view_file_comment(self): self._set_up_private_project_with_file_comment() res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_public_node_logged_in_contributor_can_view_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_public_node_logged_in_non_contributor_can_view_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.get(self.public_url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_public_node_logged_out_user_can_view_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.get(self.public_url) assert_equal(res.status_code, 200) assert_equal(self.public_comment._id, res.json['data']['id']) assert_equal(self.public_comment.content, res.json['data']['attributes']['content']) def test_registration_logged_in_contributor_can_view_file_comment(self): self._set_up_registration_with_file_comment() res = self.app.get(self.registration_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.registration_comment._id, res.json['data']['id']) assert_equal(self.registration_comment.content, res.json['data']['attributes']['content']) def test_file_comment_has_user_link(self): self._set_up_public_project_with_file_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['user']['links']['related']['href'] expected_url = '/{}users/{}/'.format(API_BASE, self.user._id) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_file_comment_has_node_link(self): self._set_up_public_project_with_file_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['node']['links']['related']['href'] expected_url = '/{}nodes/{}/'.format(API_BASE, self.public_project._id) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_file_comment_has_target_link_with_correct_type(self): self._set_up_public_project_with_file_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['target']['links']['related']['href'] expected_url = '/{}files/{}/'.format(API_BASE, self.public_file._id) target_type = res.json['data']['relationships']['target']['links']['related']['meta']['type'] expected_type = 'files' assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) assert_equal(target_type, expected_type) def test_file_comment_has_replies_link(self): self._set_up_public_project_with_file_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['replies']['links']['self']['href'] expected_url = '/{}nodes/{}/comments/'.format(API_BASE, self.public_project._id) + '?filter[target]=' + str(self.public_comment._id) assert_equal(res.status_code, 200) assert_in(expected_url, url) def test_file_comment_has_reports_link(self): self._set_up_public_project_with_file_comment() res = self.app.get(self.public_url) url = res.json['data']['relationships']['reports']['links']['related']['href'] expected_url = '/{}comments/{}/reports/'.format(API_BASE, self.public_comment) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_private_node_only_logged_in_contributor_commenter_can_update_file_comment(self): self._set_up_private_project_with_file_comment() res = self.app.put_json_api(self.private_url, self.payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.payload['data']['attributes']['content'], res.json['data']['attributes']['content']) def test_private_node_logged_in_non_contributor_cannot_update_file_comment(self): self._set_up_private_project_with_file_comment() res = self.app.put_json_api(self.private_url, self.payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_private_node_logged_out_user_cannot_update_file_comment(self): self._set_up_private_project_with_file_comment() res = self.app.put_json_api(self.private_url, self.payload, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_public_node_only_contributor_commenter_can_update_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(self.public_comment_payload['data']['attributes']['content'], res.json['data']['attributes']['content']) def test_public_node_contributor_cannot_update_other_users_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_public_node_non_contributor_cannot_update_other_users_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_public_node_logged_out_user_cannot_update_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.put_json_api(self.public_url, self.public_comment_payload, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_public_node_non_contributor_commenter_can_update_file_comment(self): project = ProjectFactory(is_public=True, comment_level='public') test_file = test_utils.create_test_file(project, project.creator) comment = CommentFactory(node=project, target=test_file, user=self.non_contributor) url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = self._set_up_payload(comment._id) res = self.app.put_json_api(url, payload, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_equal(payload['data']['attributes']['content'], res.json['data']['attributes']['content']) def test_private_node_only_logged_in_contributor_commenter_can_delete_file_comment(self): self._set_up_private_project_with_file_comment() res = self.app.delete_json_api(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 204) def test_private_node_contributor_cannot_delete_other_users_file_comment(self): self._set_up_private_project_with_file_comment() res = self.app.delete_json_api(self.private_url, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_private_node_non_contributor_cannot_delete_file_comment(self): self._set_up_private_project_with_file_comment() res = self.app.delete_json_api(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_private_node_logged_out_user_cannot_delete_file_comment(self): self._set_up_private_project_with_file_comment() res = self.app.delete_json_api(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_private_node_user_cannot_delete_already_deleted_file_comment(self): self._set_up_private_project_with_file_comment() self.comment.is_deleted = True self.comment.save() res = self.app.delete_json_api(self.private_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'Comment already deleted.') def test_private_node_only_logged_in_contributor_commenter_can_undelete_file_comment(self): self._set_up_private_project_with_file_comment() comment = CommentFactory.build(node=self.private_project, target=self.file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, auth=self.user.auth) assert_equal(res.status_code, 200) assert_false(res.json['data']['attributes']['deleted']) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_private_node_contributor_cannot_undelete_other_users_file_comment(self): self._set_up_private_project_with_file_comment() comment = CommentFactory.build(node=self.private_project, target=self.file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_private_node_non_contributor_cannot_undelete_file_comment(self): self._set_up_private_project_with_file_comment() comment = CommentFactory.build(node=self.private_project, target=self.file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_private_node_logged_out_user_cannot_undelete_file_comment(self): self._set_up_private_project_with_file_comment() comment = CommentFactory.build(node=self.private_project, target=self.file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) payload = { 'data': { 'id': comment._id, 'type': 'comments', 'attributes': { 'deleted': False } } } res = self.app.patch_json_api(url, payload, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_public_node_only_logged_in_contributor_commenter_can_delete_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.delete_json_api(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 204) def test_public_node_contributor_cannot_delete_other_users_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.delete_json_api(self.public_url, auth=self.contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_public_node_non_contributor_cannot_delete_other_users_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.delete_json_api(self.public_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_public_node_logged_out_user_cannot_delete_file_comment(self): self._set_up_public_project_with_file_comment() res = self.app.delete_json_api(self.public_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_public_node_non_contributor_commenter_can_delete_file_comment(self): project = ProjectFactory(is_public=True, comment_level='public') test_file = test_utils.create_test_file(project, project.creator) comment = CommentFactory(node=project, target=test_file, user=self.non_contributor) url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.delete_json_api(url, auth=self.non_contributor.auth) assert_equal(res.status_code, 204) def test_public_node_user_cannot_delete_already_deleted_file_comment(self): self._set_up_public_project_with_file_comment() self.public_comment.is_deleted = True self.public_comment.save() res = self.app.delete_json_api(self.public_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'Comment already deleted.') def test_private_node_only_logged_in_commenter_can_view_deleted_file_comment(self): self._set_up_private_project_with_file_comment() comment = CommentFactory(node=self.private_project, target=self.file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_private_node_contributor_cannot_see_other_users_deleted_file_comment(self): self._set_up_private_project_with_file_comment() comment = CommentFactory(node=self.private_project, target=self.file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_private_node_logged_out_user_cannot_see_deleted_file_comment(self): self._set_up_private_project_with_file_comment() comment = CommentFactory(node=self.private_project, target=self.file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_public_node_only_logged_in_commenter_can_view_deleted_file_comment(self): self._set_up_public_project_with_file_comment() comment = CommentFactory(node=self.public_project, target=self.public_file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['attributes']['content'], comment.content) def test_public_node_contributor_cannot_view_other_users_deleted_file_comment(self): self._set_up_public_project_with_file_comment() comment = CommentFactory(node=self.public_project, target=self.public_file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_public_node_non_contributor_cannot_view_other_users_deleted_file_comment(self): self._set_up_public_project_with_file_comment() comment = CommentFactory(node=self.public_project, target=self.public_file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_public_node_logged_out_user_cannot_view_deleted_file_comments(self): self._set_up_public_project_with_file_comment() comment = CommentFactory(node=self.public_project, target=self.public_file, user=self.user) comment.is_deleted = True comment.save() url = '/{}comments/{}/'.format(API_BASE, comment._id) res = self.app.get(url) assert_equal(res.status_code, 200) assert_is_none(res.json['data']['attributes']['content']) def test_comment_detail_for_deleted_file_is_not_returned(self): self._set_up_private_project_with_file_comment() # Delete commented file osfstorage = self.private_project.get_addon('osfstorage') root_node = osfstorage.get_root() root_node.delete(self.file) res = self.app.get(self.private_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404)
def _set_up_comment_with_target(self, root_target, target): comment = CommentFactory(node=self.project) comment.root_target = root_target comment.target = target comment.save() return comment