Example #1
0
class TestCollectionNodeLinkDetail(ApiTestCase):

    def setUp(self):
        super(TestCollectionNodeLinkDetail, self).setUp()
        self.user_one = AuthUserFactory()
        self.user_two = AuthUserFactory()
        self.collection = FolderFactory(creator=self.user_one)
        self.project = ProjectFactory(creator=self.user_one, is_public=False)
        self.project_public = ProjectFactory(creator=self.user_one, is_public=False)
        self.node_link = self.collection.add_pointer(self.project, auth=Auth(self.user_one), save=True)
        self.node_link_public = self.collection.add_pointer(self.project_public, auth=Auth(self.user_one), save=True)
        self.url = '/{}collections/{}/node_links/{}/'.format(API_BASE, self.collection._id, self.node_link._id)
        self.url_public = '/{}collections/{}/node_links/{}/'.format(API_BASE, self.collection._id, self.node_link_public._id)

    def test_returns_error_public_node_link_detail_unauthenticated(self):
        res = self.app.get(self.url_public, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_in('detail', res.json['errors'][0])

    def test_returns_public_node_pointer_detail_authorized(self):
        res = self.app.get(self.url_public, auth=self.user_one.auth)
        res_json = res.json['data']
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'application/vnd.api+json')
        expected_path = node_url_for(self.project_public._id)
        actual_path = urlparse(res_json['relationships']['target_node']['links']['related']['href']).path
        assert_equal(expected_path, actual_path)

    def test_returns_error_private_node_link_detail_unauthenticated(self):
        res = self.app.get(self.url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_in('detail', res.json['errors'][0])

    def test_returns_private_node_link_detail_authorized(self):
        res = self.app.get(self.url, auth=self.user_one.auth)
        res_json = res.json['data']
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'application/vnd.api+json')
        expected_path = node_url_for(self.project._id)
        actual_path = urlparse(res_json['relationships']['target_node']['links']['related']['href']).path
        assert_equal(expected_path, actual_path)

    def test_returns_error_private_node_link_detail_unauthorized(self):
        res = self.app.get(self.url, auth=self.user_two.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_in('detail', res.json['errors'][0])

    def test_self_link_points_to_node_link_detail_url(self):
        res = self.app.get(self.url, auth=self.user_one.auth)
        assert_equal(res.status_code, 200)
        url = res.json['data']['links']['self']
        assert_in(self.url, url)

    def test_delete_node_link_no_permissions_for_target_node(self):
        pointer_project = FolderFactory(creator=self.user_two)
        pointer = self.collection.add_pointer(pointer_project, auth=Auth(self.user_one), save=True)
        assert_in(pointer, self.collection.nodes)
        url = '/{}collections/{}/node_links/{}/'.format(API_BASE, self.collection._id, pointer._id)
        res = self.app.delete_json_api(url, auth=self.user_one.auth)
        assert_equal(res.status_code, 204)

    def test_can_not_delete_collection_public_node_link_unauthenticated(self):
        res = self.app.delete(self.url_public, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_in('detail', res.json['errors'][0].keys())

    def test_can_not_delete_collection_public_node_pointer_unauthorized(self):
        node_count_before = len(self.collection.nodes_pointer)
        res = self.app.delete(self.url_public, auth=self.user_two.auth, expect_errors=True)
        # This is could arguably be a 405, but we don't need to go crazy with status codes
        assert_equal(res.status_code, 403)
        assert_in('detail', res.json['errors'][0])
        self.collection.reload()
        assert_equal(node_count_before, len(self.collection.nodes_pointer))

    @assert_logs(NodeLog.POINTER_REMOVED, 'collection')
    def test_delete_public_node_pointer_authorized(self):
        node_count_before = len(self.collection.nodes_pointer)
        res = self.app.delete(self.url_public, auth=self.user_one.auth)
        self.collection.reload()
        assert_equal(res.status_code, 204)
        assert_equal(node_count_before - 1, len(self.collection.nodes_pointer))

    @assert_logs(NodeLog.POINTER_REMOVED, 'collection')
    def test_delete_private_node_link_authorized(self):
        node_count_before = len(self.collection.nodes_pointer)
        res = self.app.delete(self.url, auth=self.user_one.auth)
        self.collection.reload()
        assert_equal(res.status_code, 204)
        assert_equal(node_count_before - 1, len(self.collection.nodes_pointer))

    def test_can_not_delete_collection_private_node_link_unauthorized(self):
        res = self.app.delete(self.url, auth=self.user_two.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_in('detail', res.json['errors'][0])

    @assert_logs(NodeLog.POINTER_REMOVED, 'collection')
    def test_can_not_return_deleted_collection_public_node_pointer(self):
        res = self.app.delete(self.url_public, auth=self.user_one.auth)
        self.collection.reload()
        assert_equal(res.status_code, 204)

        res = self.app.get(self.url_public, auth=self.user_one.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    @assert_logs(NodeLog.POINTER_REMOVED, 'collection')
    def test_return_deleted_private_node_pointer(self):
        res = self.app.delete(self.url, auth=self.user_one.auth)
        self.project.reload()
        assert_equal(res.status_code, 204)

        res = self.app.get(self.url, auth=self.user_one.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    # Regression test for https://openscience.atlassian.net/browse/OSF-4322
    def test_delete_link_that_is_not_linked_to_correct_node(self):
        collection = FolderFactory(creator=self.user_one)
        # The node link belongs to a different project
        res = self.app.delete(
            '/{}nodes/{}/node_links/{}/'.format(API_BASE, collection._id, self.node_link._id),
            auth=self.user_one.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 404)
        errors = res.json['errors']
        assert_equal(len(errors), 1)
        assert_equal(errors[0]['detail'], 'Not found.')