class TestNodeContributorPartialUpdate(ApiTestCase):
    def setUp(self):
        super(TestNodeContributorPartialUpdate, self).setUp()
        self.user = AuthUserFactory()
        self.user_two = AuthUserFactory()

        self.project = ProjectFactory(creator=self.user)
        self.project.add_contributor(self.user_two, permissions=[permissions.READ, permissions.WRITE], visible=True, save=True)

        self.url_creator = '/{}nodes/{}/contributors/{}/'.format(API_BASE, self.project._id, self.user._id)
        self.url_contributor = '/{}nodes/{}/contributors/{}/'.format(API_BASE, self.project._id, self.user_two._id)

    def test_patch_bibliographic_only(self):
        creator_id = '{}-{}'.format(self.project._id, self.user._id)
        data = {
            'data': {
                'id': creator_id,
                'type': 'contributors',
                'attributes': {
                    'bibliographic': False,
                }
            }
        }
        res = self.app.patch_json_api(self.url_creator, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        self.project.reload()
        assert_equal(self.project.get_permissions(self.user), [permissions.READ, permissions.WRITE, permissions.ADMIN])
        assert_false(self.project.get_visible(self.user))

    def test_patch_permission_only(self):
        user_three = AuthUserFactory()
        self.project.add_contributor(user_three, permissions=[permissions.READ, permissions.WRITE], visible=False, save=True)
        url_contributor = '/{}nodes/{}/contributors/{}/'.format(API_BASE, self.project._id, user_three._id)
        contributor_id = '{}-{}'.format(self.project._id, user_three._id)
        data = {
            'data': {
                'id': contributor_id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.READ,
                }
            }
        }
        res = self.app.patch_json_api(url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        self.project.reload()
        assert_equal(self.project.get_permissions(user_three), [permissions.READ])
        assert_false(self.project.get_visible(user_three))
class TestNodeContributorUpdate(ApiTestCase):
    def setUp(self):
        super(TestNodeContributorUpdate, self).setUp()
        self.user = AuthUserFactory()
        self.user_two = AuthUserFactory()

        self.project = ProjectFactory(creator=self.user)
        self.project.add_contributor(self.user_two, permissions=[permissions.READ, permissions.WRITE], visible=True, save=True)

        self.url_creator = '/{}nodes/{}/contributors/{}/'.format(API_BASE, self.project._id, self.user._id)
        self.url_contributor = '/{}nodes/{}/contributors/{}/'.format(API_BASE, self.project._id, self.user_two._id)

    def test_node_update_invalid_data(self):
        res = self.app.put_json_api(self.url_creator, "Incorrect data", auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)
        assert_equal(res.json['errors'][0]['detail'], "Malformed request.")

        res = self.app.put_json_api(self.url_creator, ["Incorrect data"], auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)
        assert_equal(res.json['errors'][0]['detail'], "Malformed request.")

    def test_change_contributor_no_id(self):
        data = {
            'data': {
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.ADMIN,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_change_contributor_incorrect_id(self):
        data = {
            'data': {
                'id': '12345',
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.ADMIN,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_change_contributor_no_type(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'attributes': {
                    'permission': permissions.ADMIN,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_change_contributor_incorrect_type(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'Wrong type.',
                'attributes': {
                    'permission': permissions.ADMIN,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 409)


    @assert_logs(NodeLog.PERMISSIONS_UPDATED, 'project', -3)
    @assert_logs(NodeLog.PERMISSIONS_UPDATED, 'project', -2)
    @assert_logs(NodeLog.PERMISSIONS_UPDATED, 'project')
    def test_change_contributor_permissions(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.ADMIN,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.ADMIN)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE, permissions.ADMIN])

        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.WRITE,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.WRITE)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE])

        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.READ,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.READ)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ])

    @assert_logs(NodeLog.MADE_CONTRIBUTOR_INVISIBLE, 'project', -2)
    @assert_logs(NodeLog.MADE_CONTRIBUTOR_VISIBLE, 'project')
    def test_change_contributor_bibliographic(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'bibliographic': False
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['bibliographic'], False)

        self.project.reload()
        assert_false(self.project.get_visible(self.user_two))

        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['bibliographic'], True)

        self.project.reload()
        assert_true(self.project.get_visible(self.user_two))

    @assert_logs(NodeLog.PERMISSIONS_UPDATED, 'project', -2)
    @assert_logs(NodeLog.MADE_CONTRIBUTOR_INVISIBLE, 'project')
    def test_change_contributor_permission_and_bibliographic(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.READ,
                    'bibliographic': False
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.READ)
        assert_equal(attributes['bibliographic'], False)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ])
        assert_false(self.project.get_visible(self.user_two))

    @assert_not_logs(NodeLog.PERMISSIONS_UPDATED, 'project')
    def test_not_change_contributor(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': None,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.WRITE)
        assert_equal(attributes['bibliographic'], True)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE])
        assert_true(self.project.get_visible(self.user_two))

    def test_invalid_change_inputs_contributor(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': 'invalid',
                    'bibliographic': 'invalid'
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE])
        assert_true(self.project.get_visible(self.user_two))

    @assert_logs(NodeLog.PERMISSIONS_UPDATED, 'project')
    def test_change_admin_self_with_other_admin(self):
        self.project.add_permission(self.user_two, permissions.ADMIN, save=True)
        data = {
            'data': {
                'id': self.user._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.WRITE,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_creator, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.WRITE)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user), [permissions.READ, permissions.WRITE])

    def test_change_admin_self_without_other_admin(self):
        data = {
            'data': {
                'id': self.user._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.WRITE,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_creator, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user), [permissions.READ, permissions.WRITE, permissions.ADMIN])

    def test_remove_all_bibliographic_statuses_contributors(self):
        self.project.set_visible(self.user_two, False, save=True)
        data = {
            'data': {
                'id': self.user._id,
                'type': 'contributors',
                'attributes': {
                    'bibliographic': False
                }
            }
        }
        res = self.app.put_json_api(self.url_creator, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)

        self.project.reload()
        assert_true(self.project.get_visible(self.user))

    def test_change_contributor_non_admin_auth(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.READ,
                    'bibliographic': False
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user_two.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE])
        assert_true(self.project.get_visible(self.user_two))

    def test_change_contributor_not_logged_in(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.READ,
                    'bibliographic': False
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, expect_errors=True)
        assert_equal(res.status_code, 401)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE])
        assert_true(self.project.get_visible(self.user_two))
class TestNodeContributorUpdate(ApiTestCase):
    def setUp(self):
        super(TestNodeContributorUpdate, self).setUp()
        self.user = AuthUserFactory()
        self.user_two = AuthUserFactory()

        self.project = ProjectFactory(creator=self.user)
        self.project.add_contributor(self.user_two, permissions=[permissions.READ, permissions.WRITE], visible=True, save=True)

        self.url_creator = '/{}nodes/{}/contributors/{}/'.format(API_BASE, self.project._id, self.user._id)
        self.url_contributor = '/{}nodes/{}/contributors/{}/'.format(API_BASE, self.project._id, self.user_two._id)

    def test_node_update_invalid_data(self):
        res = self.app.put_json_api(self.url_creator, "Incorrect data", auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)
        assert_equal(res.json['errors'][0]['detail'], "Malformed request.")

        res = self.app.put_json_api(self.url_creator, ["Incorrect data"], auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)
        assert_equal(res.json['errors'][0]['detail'], "Malformed request.")

    def test_change_contributor_no_id(self):
        data = {
            'data': {
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.ADMIN,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_change_contributor_incorrect_id(self):
        data = {
            'data': {
                'id': '12345',
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.ADMIN,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_change_contributor_no_type(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'attributes': {
                    'permission': permissions.ADMIN,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_change_contributor_incorrect_type(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'Wrong type.',
                'attributes': {
                    'permission': permissions.ADMIN,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 409)


    @assert_logs(NodeLog.PERMISSIONS_UPDATED, 'project', -3)
    @assert_logs(NodeLog.PERMISSIONS_UPDATED, 'project', -2)
    @assert_logs(NodeLog.PERMISSIONS_UPDATED, 'project')
    def test_change_contributor_permissions(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.ADMIN,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.ADMIN)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE, permissions.ADMIN])

        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.WRITE,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.WRITE)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE])

        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.READ,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.READ)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ])

    @assert_logs(NodeLog.MADE_CONTRIBUTOR_INVISIBLE, 'project', -2)
    @assert_logs(NodeLog.MADE_CONTRIBUTOR_VISIBLE, 'project')
    def test_change_contributor_bibliographic(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'bibliographic': False
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['bibliographic'], False)

        self.project.reload()
        assert_false(self.project.get_visible(self.user_two))

        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['bibliographic'], True)

        self.project.reload()
        assert_true(self.project.get_visible(self.user_two))

    @assert_logs(NodeLog.PERMISSIONS_UPDATED, 'project', -2)
    @assert_logs(NodeLog.MADE_CONTRIBUTOR_INVISIBLE, 'project')
    def test_change_contributor_permission_and_bibliographic(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.READ,
                    'bibliographic': False
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.READ)
        assert_equal(attributes['bibliographic'], False)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ])
        assert_false(self.project.get_visible(self.user_two))

    @assert_not_logs(NodeLog.PERMISSIONS_UPDATED, 'project')
    def test_not_change_contributor(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': None,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.WRITE)
        assert_equal(attributes['bibliographic'], True)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE])
        assert_true(self.project.get_visible(self.user_two))

    def test_invalid_change_inputs_contributor(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': 'invalid',
                    'bibliographic': 'invalid'
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE])
        assert_true(self.project.get_visible(self.user_two))

    @assert_logs(NodeLog.PERMISSIONS_UPDATED, 'project')
    def test_change_admin_self_with_other_admin(self):
        self.project.add_permission(self.user_two, permissions.ADMIN, save=True)
        data = {
            'data': {
                'id': self.user._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.WRITE,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_creator, data, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        assert_equal(attributes['permission'], permissions.WRITE)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user), [permissions.READ, permissions.WRITE])

    def test_change_admin_self_without_other_admin(self):
        data = {
            'data': {
                'id': self.user._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.WRITE,
                    'bibliographic': True
                }
            }
        }
        res = self.app.put_json_api(self.url_creator, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user), [permissions.READ, permissions.WRITE, permissions.ADMIN])

    def test_remove_all_bibliographic_statuses_contributors(self):
        self.project.set_visible(self.user_two, False, save=True)
        data = {
            'data': {
                'id': self.user._id,
                'type': 'contributors',
                'attributes': {
                    'bibliographic': False
                }
            }
        }
        res = self.app.put_json_api(self.url_creator, data, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)

        self.project.reload()
        assert_true(self.project.get_visible(self.user))

    def test_change_contributor_non_admin_auth(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.READ,
                    'bibliographic': False
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, auth=self.user_two.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE])
        assert_true(self.project.get_visible(self.user_two))

    def test_change_contributor_not_logged_in(self):
        data = {
            'data': {
                'id': self.user_two._id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.READ,
                    'bibliographic': False
                }
            }
        }
        res = self.app.put_json_api(self.url_contributor, data, expect_errors=True)
        assert_equal(res.status_code, 401)

        self.project.reload()
        assert_equal(self.project.get_permissions(self.user_two), [permissions.READ, permissions.WRITE])
        assert_true(self.project.get_visible(self.user_two))
class TestNodeContributorPartialUpdate(ApiTestCase):
    def setUp(self):
        super(TestNodeContributorPartialUpdate, self).setUp()
        self.user = AuthUserFactory()
        self.user_two = AuthUserFactory()

        self.project = ProjectFactory(creator=self.user)
        self.project.add_contributor(
            self.user_two,
            permissions=[permissions.READ, permissions.WRITE],
            visible=True,
            save=True)

        self.url_creator = '/{}nodes/{}/contributors/{}/'.format(
            API_BASE, self.project._id, self.user._id)
        self.url_contributor = '/{}nodes/{}/contributors/{}/'.format(
            API_BASE, self.project._id, self.user_two._id)

    def test_patch_bibliographic_only(self):
        creator_id = '{}-{}'.format(self.project._id, self.user._id)
        data = {
            'data': {
                'id': creator_id,
                'type': 'contributors',
                'attributes': {
                    'bibliographic': False,
                }
            }
        }
        res = self.app.patch_json_api(self.url_creator,
                                      data,
                                      auth=self.user.auth)
        assert_equal(res.status_code, 200)
        self.project.reload()
        assert_equal(self.project.get_permissions(self.user),
                     [permissions.READ, permissions.WRITE, permissions.ADMIN])
        assert_false(self.project.get_visible(self.user))

    def test_patch_permission_only(self):
        user_three = AuthUserFactory()
        self.project.add_contributor(
            user_three,
            permissions=[permissions.READ, permissions.WRITE],
            visible=False,
            save=True)
        url_contributor = '/{}nodes/{}/contributors/{}/'.format(
            API_BASE, self.project._id, user_three._id)
        contributor_id = '{}-{}'.format(self.project._id, user_three._id)
        data = {
            'data': {
                'id': contributor_id,
                'type': 'contributors',
                'attributes': {
                    'permission': permissions.READ,
                }
            }
        }
        res = self.app.patch_json_api(url_contributor,
                                      data,
                                      auth=self.user.auth)
        assert_equal(res.status_code, 200)
        self.project.reload()
        assert_equal(self.project.get_permissions(user_three),
                     [permissions.READ])
        assert_false(self.project.get_visible(user_three))