def test_get_block_schemas(app, test_communities):
    """"Test getting list of given community's schemas."""
    with app.app_context():
        community = Community.create_community('name1', 'desc1')
        community_id = community.id
        community_2 = Community.create_community('name2', 'desc2')
        community_id2 = community_2.id
        block_schema_1 = BlockSchema.create_block_schema(community_id, 'abc')
        block_schema_2 = BlockSchema.create_block_schema(community_id2, 'abc2')
        block_schema_3 = BlockSchema.create_block_schema(community_id2, 'abc3')
        with app.test_client() as client:
            headers = [('Content-Type', 'application/json'),
                       ('Accept', 'application/json')]
            res = client.get(
                url_for(
                    'b2share_schemas.block_schema_list',
                    community_id=community_id2
                ),
                headers=headers)
            assert res.status_code == 200
            response_data = json.loads(res.get_data(as_text=True))
            assert isinstance(response_data['schemas'], list)
            assert len(response_data['schemas']) == 2
            assert response_data['schemas'][0]['name'] == block_schema_2.name
            assert response_data['schemas'][1]['name'] == block_schema_3.name
示例#2
0
def update_sets():
    """Check that each community has a corresponding oai set"""
    for community in Community.get_all():
        dirty = False
        oaiset = OAISet.query.filter(
            OAISet.spec == str(community.id)).one_or_none()
        if not oaiset:
            click.secho('Adding new oai set {}'.format(community.name),
                        fg='yellow',
                        bold=True)
            oaiset = OAISet(spec=str(community.id),
                            name=community.name,
                            description=community.description)
            dirty = True
        else:
            if oaiset.name != community.name:
                oaiset.name = community.name
                dirty = True
                click.secho('Update name for set {}'.format(oaiset.spec),
                            fg='yellow',
                            bold=True)
            if oaiset.description != community.description:
                oaiset.description = community.description
                dirty = True
                click.secho('Update description for set {}'.format(
                    oaiset.spec),
                            fg='yellow',
                            bold=True)
        if dirty:
            db.session.add(oaiset)
    db.session.commit()
示例#3
0
def community_schema_list(verbose, community):
    """Lists all community schema versions for this b2share instance (filtered for a
    community)."""
    comm = None
    if community:
        comm = get_community_by_name_or_id(community)
    community_id = None
    if comm:
        community_id = comm.id
    if verbose:
        click.secho("filtering for community %s" % comm)
    try:
        community_schemas = \
        CommunitySchema.get_all_community_schemas(community_id=community_id)
    except CommunitySchemaDoesNotExistError:
        raise click.ClickException("""No community schemas found, community
            parameter was: %s""" % community)
    click.secho(
        """COMMUNITY ID\t\t\t\tNAME\t\tVERSION\tROOT SCHEMA\tRELEASED\t\t\t\tBLOCK SCHEMA ID"""
    )
    for cs in community_schemas:
        cs_comm = Community.get(id=cs.community)
        click.secho("%s\t%s\t%d\t%d\t\t%s\t\t%s" %
                    (cs.community, cs_comm.name[0:15].ljust(15), cs.version,
                     cs.root_schema, cs.released, cs.block_schema_id))
示例#4
0
文件: cli.py 项目: haatveit/b2share
def block_schema_list(verbose, community):
    """Lists all block schemas for this b2share instance (filtered for a
    community)."""
    comm = None
    if community:
        comm = get_community_by_name_or_id(community)
    community_id = None
    if comm:
        community_id = comm.id
    if verbose:
        click.secho("filtering for community %s" % comm)
    try:
        block_schemas = \
        BlockSchema.get_all_block_schemas(community_id=community_id)
    except BlockSchemaDoesNotExistError:
        raise click.ClickException("""No block schemas found, community
            parameter was: %s""" % community)
    click.secho(
        """BLOCK SCHEMA ID\t\t\t\tNAME\t\tMAINTAINER\tDEPRECATED\t#VERSIONS""")
    for bs in block_schemas:
        bs_comm = Community.get(id=bs.community)
        click.secho(
            "%s\t%s\t%s\t%s\t\t%d" %
            (bs.id, bs.name[0:15].ljust(15), bs_comm.name[0:15].ljust(15),
             bs.deprecated, len(bs.versions)))
示例#5
0
def test_unassign_community_roles(app, test_users, test_community,
                                  login_user):
    with app.app_context():
        community = Community.get(id=test_community.id)
        com_admin = create_user('test_community_admin',
                                roles=[community.admin_role])
        db.session.commit()

    headers = [('Content-Type', 'application/json'),
               ('Accept', 'application/json')]

    with app.app_context():
        with app.test_client() as client:
            # send the request as global admin
            login_user(test_users['admin'], client)
            res = client.delete(
                url_for(
                    'invenio_accounts_rest.assign_role',
                    user_id=com_admin.id,
                    role_id=test_community.admin_role_id,
                ),
                headers=headers
            )
            assert res.status_code == 204

    with app.app_context():
        user_roles = User.query.get(com_admin.id).roles
        assert test_community.admin_role_id \
            not in [role.id for role in user_roles]
示例#6
0
def test_unassign_community_roles(app, test_users, test_community, login_user):
    with app.app_context():
        community = Community.get(id=test_community.id)
        com_admin = create_user('test_community_admin',
                                roles=[community.admin_role])
        db.session.commit()

    headers = [('Content-Type', 'application/json'),
               ('Accept', 'application/json')]

    with app.app_context():
        with app.test_client() as client:
            # send the request as global admin
            login_user(test_users['admin'], client)
            res = client.delete(url_for(
                'invenio_accounts_rest.assign_role',
                user_id=com_admin.id,
                role_id=test_community.admin_role_id,
            ),
                                headers=headers)
            assert res.status_code == 204

    with app.app_context():
        user_roles = User.query.get(com_admin.id).roles
        assert test_community.admin_role_id \
            not in [role.id for role in user_roles]
示例#7
0
    def __init__(self, record=None, previous_record=None):
        """Constructor.

        Args:
            record: data submitted for the new deposit
        """
        super(CreateDepositPermission, self).__init__()
        self.record = record
        if record is not None:
            needs = set()
            community = Community.get(record['community'])
            publication_state = record.get('publication_state', 'draft')
            if publication_state != 'draft' or community.restricted_submission:
                needs.add(create_deposit_need_factory())
                needs.add(create_deposit_need_factory(
                    community=record['community'],
                    publication_state=publication_state,
                ))
            elif not community.restricted_submission:
                needs.add(AuthenticatedNeed)

            self.permissions.add(StrictDynamicPermission(*needs))
            if previous_record:
                # we allow only the owner of a record to
                # create a new version of it.
                needs = set()
                for owner_id in previous_record['_deposit']['owners']:
                    needs.add(UserNeed(owner_id))
                self.permissions.add(StrictDynamicPermission(*needs))
示例#8
0
def update_sets():
    """Check that each community has a corresponding oai set"""
    for community in Community.get_all():
        dirty = False
        oaiset = OAISet.query.filter(OAISet.spec == str(community.id)).one_or_none()
        if not oaiset:
            click.secho('Adding new oai set {}'.format(community.name),
                        fg='yellow', bold=True)
            oaiset = OAISet(spec=str(community.id),
                            name=community.name,
                            description=community.description)
            dirty = True
        else:
            if oaiset.name != community.name:
                oaiset.name = community.name
                dirty = True
                click.secho('Update name for set {}'.format(oaiset.spec),
                            fg='yellow', bold=True)
            if oaiset.description != community.description:
                oaiset.description = community.description
                dirty = True
                click.secho('Update description for set {}'.format(oaiset.spec),
                            fg='yellow', bold=True)
        if dirty:
            db.session.add(oaiset)
    db.session.commit()
示例#9
0
    def __init__(self, record=None, previous_record=None):
        """Constructor.

        Args:
            record: data submitted for the new deposit
        """
        super(CreateDepositPermission, self).__init__()
        self.record = record
        if record is not None:
            needs = set()
            community = Community.get(record['community'])
            publication_state = record.get('publication_state', 'draft')
            if publication_state != 'draft' or community.restricted_submission:
                needs.add(create_deposit_need_factory())
                needs.add(create_deposit_need_factory(
                    community=record['community'],
                    publication_state=publication_state,
                ))
            elif not community.restricted_submission:
                needs.add(AuthenticatedNeed)

            self.permissions.add(StrictDynamicPermission(*needs))
            if previous_record:
                # we allow only the owner of a record to
                # create a new version of it.
                needs = set()
                for owner_id in previous_record['_deposit']['owners']:
                    needs.add(UserNeed(owner_id))
                self.permissions.add(StrictDynamicPermission(*needs))
示例#10
0
def test_deposit_create_permission(app, test_users, login_user,
                                   test_communities):
    """Test record draft creation."""
    headers = [('Content-Type', 'application/json'),
               ('Accept', 'application/json')]

    with app.app_context():
        community_name = 'MyTestCommunity1'
        record_data = generate_record_data(community=community_name)
        community_id = test_communities[community_name]
        community = Community.get(community_id)

        creator = create_user('creator')
        need = create_deposit_need_factory(str(community_id))
        allowed = create_user('allowed', permissions=[need])
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])
        deposit, pid, record = create_record(record_data, creator)

        def restrict_creation(restricted):
            community.update({'restricted_submission':restricted})
            db.session.commit()

        def test_creation(expected_code, user=None, version_of=None):
            with app.test_client() as client:
                if user is not None:
                    login_user(user, client)
                draft_create_res = client.post(
                    url_for('b2share_records_rest.b2rec_list',
                            version_of=version_of),
                    data=json.dumps(record_data),
                    headers=headers
                )
                assert draft_create_res.status_code == expected_code

        # test creating a deposit with anonymous user
        restrict_creation(False)
        test_creation(401)
        restrict_creation(True)
        test_creation(401)

        # test creating a deposit with a logged in user
        restrict_creation(False)
        test_creation(201, creator)
        restrict_creation(True)
        test_creation(403, creator)
        # test with a use who is allowed
        test_creation(201, allowed)
        # test with a community member and admin
        test_creation(201, com_member)
        test_creation(201, com_admin)

        # test creating a new version
        test_creation(401, None, version_of=pid.pid_value)
        test_creation(403, com_member, version_of=pid.pid_value)
        restrict_creation(True)
        test_creation(403, creator, version_of=pid.pid_value)
        restrict_creation(False)
        test_creation(201, creator, version_of=pid.pid_value)
def test_deposit_create_permission(app, test_users, login_user,
                                   test_communities):
    """Test record draft creation."""
    headers = [('Content-Type', 'application/json'),
               ('Accept', 'application/json')]

    with app.app_context():
        community_name = 'MyTestCommunity1'
        record_data = generate_record_data(community=community_name)
        community_id = test_communities[community_name]
        community = Community.get(community_id)

        creator = create_user('creator')
        need = create_deposit_need_factory(str(community_id))
        allowed = create_user('allowed', permissions=[need])
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])
        deposit, pid, record = create_record(record_data, creator)

        def restrict_creation(restricted):
            community.update({'restricted_submission': restricted})
            db.session.commit()

        def test_creation(expected_code, user=None, version_of=None):
            with app.test_client() as client:
                if user is not None:
                    login_user(user, client)
                draft_create_res = client.post(url_for(
                    'b2share_records_rest.b2rec_list', version_of=version_of),
                                               data=json.dumps(record_data),
                                               headers=headers)
                assert draft_create_res.status_code == expected_code

        # test creating a deposit with anonymous user
        restrict_creation(False)
        test_creation(401)
        restrict_creation(True)
        test_creation(401)

        # test creating a deposit with a logged in user
        restrict_creation(False)
        test_creation(201, creator)
        restrict_creation(True)
        test_creation(403, creator)
        # test with a use who is allowed
        test_creation(201, allowed)
        # test with a community member and admin
        test_creation(201, com_member)
        test_creation(201, com_admin)

        # test creating a new version
        test_creation(401, None, version_of=pid.pid_value)
        test_creation(403, com_member, version_of=pid.pid_value)
        restrict_creation(True)
        test_creation(403, creator, version_of=pid.pid_value)
        restrict_creation(False)
        test_creation(201, creator, version_of=pid.pid_value)
def test_modify_metadata_published_record_permissions(app, test_communities,
                                                      login_user, test_users):
    """Test record's metadata modification with REST API."""

    admin = test_users['admin']
    with app.app_context():
        creator = create_user('creator')
        non_creator = create_user('non-creator')
        record_data = generate_record_data(open_access=True)
        community = Community.get(id=record_data['community'])
        com_admin = create_user('com_admin', roles=[community.admin_role])
        com_member = create_user('com_member', roles=[community.member_role])

        def test_modify(status, user=None):
            patch = [{
                "op": "replace",
                "path": "/titles",
                "value": [{
                    'title': 'newtitle'
                }]
            }]
            with app.test_client() as client:
                _, record_pid, record = create_record(record_data, creator)
                if user is not None:
                    login_user(user, client)
                # test patching the document
                headers = [('Content-Type', 'application/json-patch+json'),
                           ('Accept', 'application/json')]
                request_res = client.patch(url_for(
                    'b2share_records_rest.b2rec_item',
                    pid_value=record_pid.pid_value),
                                           data=json.dumps(patch),
                                           headers=headers)
                assert request_res.status_code == status

                # _, record_pid, record = create_record(record_data, creator)
                # test putting the document
                # data = dict(record)
                # apply_patch(data, patch)
                # headers = [('Content-Type', 'application/json'),
                #            ('Accept', 'application/json')]
                # request_res = client.put(
                #     url_for('b2share_records_rest.b2rec_item',
                #             pid_value=record_pid.pid_value),
                #     data=json.dumps(data),
                #     headers=headers)
                # assert request_res.status_code == status

        # test with anonymous user
        test_modify(401)
        test_modify(403, non_creator)
        test_modify(200, creator)
        test_modify(403, com_member)
        test_modify(200, com_admin)
        test_modify(200, admin)
示例#13
0
    def commit(self):
        """Store changes on current instance in database.

        This method extends the default implementation by publishing the
        deposition when 'publication_state' is set to 'published'.
        """
        if self.model is None or self.model.json is None:
            raise MissingModelError()

        # automatically make embargoed records private
        if self.get('embargo_date') and self.get('open_access'):
            if is_under_embargo(self):
                self['open_access'] = False

        if 'community' in self:
            try:
                community = Community.get(self['community'])
            except CommunityDoesNotExistError as e:
                raise InvalidDepositError('Community {} does not exist.'.format(
                    self['community'])) from e
            workflow = publication_workflows[community.publication_workflow]
            workflow(self.model, self)

        # publish the deposition if needed
        if (self['publication_state'] == PublicationStates.published.name
                # check invenio-deposit status so that we do not loop
                and self['_deposit']['status'] != PublicationStates.published.name):

            # Retrieve previous version in order to reindex it later.
            previous_version_pid = None
            # Save the previous "last" version for later use
            if self.versioning.parent.status == PIDStatus.REDIRECTED and \
                    self.versioning.has_children:
                previous_version_pid = self.versioning.last_child
                previous_version_uuid = str(RecordUUIDProvider.get(
                    previous_version_pid.pid_value
                ).pid.object_uuid)

            super(Deposit, self).publish()  # publish() already calls commit()
            # Register parent PID if necessary and update redirect
            self.versioning.update_redirect()
            # Reindex previous version. This is needed in order to update
            # the is_last_version flag
            if previous_version_pid is not None:
                self.indexer.index_by_id(previous_version_uuid)

            # save the action for later indexing
            if g:
                g.deposit_action = 'publish'
        else:
            super(Deposit, self).commit()
            if g:
                g.deposit_action = 'update-metadata'
        return self
def test_deposit_publish_permissions(app, login_user, test_communities,
                                     test_users):
    """Test deposit publication with HTTP PATCH."""
    with app.app_context():
        community_name = 'MyTestCommunity1'
        record_data = generate_record_data(community=community_name)

        admin = test_users['admin']
        creator = create_user('creator')
        non_creator = create_user('non-creator')

        community = Community.get(name=community_name)
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])

        def test_publish(status, user=None):
            deposit = create_deposit(record_data, creator)
            deposit.submit()
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            with app.test_client() as client:
                if user is not None:
                    login_user(user, client)
                request_res = client.patch(url_for(
                    'b2share_deposit_rest.b2dep_item',
                    pid_value=deposit.pid.pid_value),
                                           data=json.dumps([{
                                               "op":
                                               "replace",
                                               "path":
                                               "/publication_state",
                                               "value":
                                               PublicationStates.published.name
                                           }, {
                                               "op":
                                               "replace",
                                               "path":
                                               "/titles",
                                               "value": [{
                                                   'title': 'newtitle'
                                               }]
                                           }]),
                                           headers=headers)
                assert request_res.status_code == status

        # test with anonymous user
        test_publish(401)
        test_publish(403, non_creator)
        test_publish(403, creator)
        test_publish(200, admin)
        test_publish(403, com_member)
        test_publish(200, com_admin)
示例#15
0
def test_modify_metadata_published_record_permissions(app, test_communities,
                                                      login_user, test_users):
    """Test record's metadata modification with REST API."""

    admin = test_users['admin']
    with app.app_context():
        creator = create_user('creator')
        non_creator = create_user('non-creator')
        record_data = generate_record_data(open_access=True)
        community = Community.get(id=record_data['community'])
        com_admin = create_user('com_admin', roles=[community.admin_role])
        com_member = create_user('com_member', roles=[community.member_role])

        def test_modify(status, user=None):
            patch = [{
                "op": "replace", "path": "/titles",
                "value": [{'title':'newtitle'}]
            }]
            with app.test_client() as client:
                _, record_pid, record = create_record(record_data, creator)
                if user is not None:
                    login_user(user, client)
                # test patching the document
                headers = [('Content-Type', 'application/json-patch+json'),
                           ('Accept', 'application/json')]
                request_res = client.patch(
                    url_for('b2share_records_rest.b2rec_item',
                            pid_value=record_pid.pid_value),
                    data=json.dumps(patch),
                    headers=headers)
                assert request_res.status_code == status

                # _, record_pid, record = create_record(record_data, creator)
                # test putting the document
                # data = dict(record)
                # apply_patch(data, patch)
                # headers = [('Content-Type', 'application/json'),
                #            ('Accept', 'application/json')]
                # request_res = client.put(
                #     url_for('b2share_records_rest.b2rec_item',
                #             pid_value=record_pid.pid_value),
                #     data=json.dumps(data),
                #     headers=headers)
                # assert request_res.status_code == status

        # test with anonymous user
        test_modify(401)
        test_modify(403, non_creator)
        test_modify(200, creator)
        test_modify(403, com_member)
        test_modify(200, com_admin)
        test_modify(200, admin)
示例#16
0
def test_get_block_schemas(app, test_communities):
    """"Test getting list of given community's schemas."""
    with app.app_context():
        community = Community.create_community('name1', 'desc1')
        community_id = community.id
        community_2 = Community.create_community('name2', 'desc2')
        community_id2 = community_2.id
        block_schema_1 = BlockSchema.create_block_schema(community_id, 'abc')
        block_schema_2 = BlockSchema.create_block_schema(community_id2, 'abc2')
        block_schema_3 = BlockSchema.create_block_schema(community_id2, 'abc3')
        with app.test_client() as client:
            headers = [('Content-Type', 'application/json'),
                       ('Accept', 'application/json')]
            res = client.get(url_for('b2share_schemas.block_schema_list',
                                     community_id=community_id2),
                             headers=headers)
            assert res.status_code == 200
            response_data = json.loads(res.get_data(as_text=True))
            assert isinstance(response_data['schemas'], list)
            assert len(response_data['schemas']) == 2
            assert response_data['schemas'][0]['name'] == block_schema_2.name
            assert response_data['schemas'][1]['name'] == block_schema_3.name
def test_deposit_modify_published_permissions(app, login_user,
                                              test_communities, test_users):
    """Test deposit edition after its publication.

    FIXME: This test should evolve when we allow deposit edition.
    """
    with app.app_context():
        community_name = 'MyTestCommunity1'
        record_data = generate_record_data(community=community_name)

        admin = test_users['admin']
        creator = create_user('creator')
        non_creator = create_user('non-creator')

        community = Community.get(name=community_name)
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])

        deposit = create_deposit(record_data, creator)
        deposit.submit()
        deposit.publish()

        def test_edit(status, user=None):
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            with app.test_client() as client:
                if user is not None:
                    login_user(user, client)
                request_res = client.patch(url_for(
                    'b2share_deposit_rest.b2dep_item',
                    pid_value=deposit.pid.pid_value),
                                           data=json.dumps([{
                                               "op":
                                               "replace",
                                               "path":
                                               "/publication_state",
                                               "value":
                                               PublicationStates.draft.name
                                           }]),
                                           headers=headers)
                assert request_res.status_code == status

        # test with anonymous user
        test_edit(401)
        test_edit(403, non_creator)
        test_edit(403, creator)
        test_edit(403, admin)
        test_edit(403, com_member)
        test_edit(403, com_admin)
示例#18
0
def test_updating_block_schema(app, test_communities):
    """Test updating a block schema."""
    with app.app_context():
        community = Community.create_community('name1', 'desc1')
        community_id = community.id
        block_schema = BlockSchema.create_block_schema(community_id,
                                                       'original')
        with app.test_client() as client:
            headers = [('Content-Type', 'application/json'),
                       ('Accept', 'application/json')]
            res = client.patch(url_for('b2share_schemas.block_schema_item',
                                       schema_id=block_schema.id),
                               data=json.dumps({'name': 'abc'}),
                               headers=headers)
            assert res.status_code == 200
示例#19
0
def test_community(app, test_communities):
    """Initialize member and admin of a community."""
    CommunityRef = namedtuple(
        'CommunityRef',
        ['name', 'id', 'admin_role_id', 'member_role_id', 'admin', 'member'])
    with app.app_context():
        community_name = 'MyTestCommunity1'
        community = CommunityAPI.get(name=community_name)
        admin_role_id = community.admin_role.id
        member_role_id = community.member_role.id
        com_admin = create_user('com_admin', roles=[community.admin_role])
        com_member = create_user('com_member', roles=[community.member_role])
        db.session.commit()
        return CommunityRef(community_name, community.id, admin_role_id,
                            member_role_id, com_admin, com_member)
示例#20
0
def test_community(app, test_communities):
    """Initialize member and admin of a community."""
    CommunityRef = namedtuple('CommunityRef',[
        'name', 'id', 'admin_role_id', 'member_role_id', 'admin', 'member'
    ])
    with app.app_context():
        community_name = 'MyTestCommunity1'
        community = CommunityAPI.get(name=community_name)
        admin_role_id = community.admin_role.id
        member_role_id = community.member_role.id
        com_admin = create_user('com_admin', roles=[community.admin_role])
        com_member = create_user('com_member', roles=[community.member_role])
        db.session.commit()
        return CommunityRef(community_name, community.id,
                            admin_role_id, member_role_id,
                            com_admin, com_member)
示例#21
0
def test_deposit(app, test_communities, login_user, authentication):
    """Test record submission with classic login and access token."""
    with app.app_context():
        allowed_user = create_user('allowed')

        scopes = current_oauth2server.scope_choices()
        allowed_token = Token.create_personal(
            'allowed_token', allowed_user.id,
            scopes=[s[0] for s in scopes]
        )
        # application authentication token header
        allowed_headers = [('Authorization',
                            'Bearer {}'.format(allowed_token.access_token))]

        other_user = create_user('other')
        other_token = Token.create_personal(
            'other_token', other_user.id,
            scopes=[s[0] for s in scopes]
        )
        # application authentication token header
        other_headers = [('Authorization',
                          'Bearer {}'.format(other_token.access_token))]

        community_name = 'MyTestCommunity1'
        community = Community.get(name=community_name)
        com_admin = create_user('com_admin', roles=[community.admin_role])
        com_admin_token = Token.create_personal(
            'com_admin_token', com_admin.id,
            scopes=[s[0] for s in scopes]
        )
        # application authentication token header
        com_admin_headers = [('Authorization',
                              'Bearer {}'.format(com_admin_token.access_token))]

        test_records_data = [generate_record_data(community=community_name)
                             for idx in range(1,3)]

        db.session.commit()

    if authentication == 'user/password':
        subtest_deposit(app, test_communities, allowed_user, other_user,
                        com_admin, [], [], [], login_user, test_records_data)
    else:
        subtest_deposit(app, test_communities, allowed_user, other_user,
                        com_admin, allowed_headers, other_headers,
                        com_admin_headers, lambda u, c: 42, test_records_data)
示例#22
0
def test_deposit(app, test_communities, login_user, authentication):
    """Test record submission with classic login and access token."""
    with app.app_context():
        allowed_user = create_user('allowed')

        scopes = current_oauth2server.scope_choices()
        allowed_token = Token.create_personal('allowed_token',
                                              allowed_user.id,
                                              scopes=[s[0] for s in scopes])
        # application authentication token header
        allowed_headers = [('Authorization',
                            'Bearer {}'.format(allowed_token.access_token))]

        other_user = create_user('other')
        other_token = Token.create_personal('other_token',
                                            other_user.id,
                                            scopes=[s[0] for s in scopes])
        # application authentication token header
        other_headers = [('Authorization',
                          'Bearer {}'.format(other_token.access_token))]

        community_name = 'MyTestCommunity1'
        community = Community.get(name=community_name)
        com_admin = create_user('com_admin', roles=[community.admin_role])
        com_admin_token = Token.create_personal('com_admin_token',
                                                com_admin.id,
                                                scopes=[s[0] for s in scopes])
        # application authentication token header
        com_admin_headers = [
            ('Authorization', 'Bearer {}'.format(com_admin_token.access_token))
        ]

        test_records_data = [
            generate_record_data(community=community_name)
            for idx in range(1, 3)
        ]

        db.session.commit()

    if authentication == 'user/password':
        subtest_deposit(app, test_communities, allowed_user, other_user,
                        com_admin, [], [], [], login_user, test_records_data)
    else:
        subtest_deposit(app, test_communities, allowed_user, other_user,
                        com_admin, allowed_headers, other_headers,
                        com_admin_headers, lambda u, c: 42, test_records_data)
示例#23
0
def test_deposit_modify_published_permissions(app, login_user, test_communities,
                                              test_users):
    """Test deposit edition after its publication.

    FIXME: This test should evolve when we allow deposit edition.
    """
    with app.app_context():
        community_name = 'MyTestCommunity1'
        record_data = generate_record_data(community=community_name)

        admin = test_users['admin']
        creator = create_user('creator')
        non_creator = create_user('non-creator')

        community = Community.get(name=community_name)
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])

        deposit = create_deposit(record_data, creator)
        deposit.submit()
        deposit.publish()

        def test_edit(status, user=None):
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            with app.test_client() as client:
                if user is not None:
                    login_user(user, client)
                request_res = client.patch(
                    url_for('b2share_deposit_rest.b2dep_item',
                            pid_value=deposit.pid.pid_value),
                    data=json.dumps([{
                        "op": "replace", "path": "/publication_state",
                        "value": PublicationStates.draft.name
                    }]),
                    headers=headers)
                assert request_res.status_code == status

        # test with anonymous user
        test_edit(401)
        test_edit(403, non_creator)
        test_edit(403, creator)
        test_edit(403, admin)
        test_edit(403, com_member)
        test_edit(403, com_admin)
示例#24
0
def test_deposit_publish_permissions(app, login_user, test_communities,
                                     test_users):
    """Test deposit publication with HTTP PATCH."""
    with app.app_context():
        community_name = 'MyTestCommunity1'
        record_data = generate_record_data(community=community_name)

        admin = test_users['admin']
        creator = create_user('creator')
        non_creator = create_user('non-creator')

        community = Community.get(name=community_name)
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])

        def test_publish(status, user=None):
            deposit = create_deposit(record_data, creator)
            deposit.submit()
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            with app.test_client() as client:
                if user is not None:
                    login_user(user, client)
                request_res = client.patch(
                    url_for('b2share_deposit_rest.b2dep_item',
                            pid_value=deposit.pid.pid_value),
                    data=json.dumps([{
                        "op": "replace", "path": "/publication_state",
                        "value": PublicationStates.published.name
                    }, {
                        "op": "replace", "path": "/titles",
                        "value": [{'title':'newtitle'}]
                    }]),
                    headers=headers)
                assert request_res.status_code == status

        # test with anonymous user
        test_publish(401)
        test_publish(403, non_creator)
        test_publish(403, creator)
        test_publish(200, admin)
        test_publish(403, com_member)
        test_publish(200, com_admin)
示例#25
0
文件: cli.py 项目: haatveit/b2share
def block_schema_list_versions(verbose, block_schema_id):
    """show the version number and release date of the versions of a block
        schema."""
    try:
        UUID(block_schema_id, version=4)
    except ValueError:
        raise click.BadParameter("""BLOCK_SCHEMA_ID is not a valid UUID
         (hexadecimal numbers and dashes e.g.
         fa52bec3-a847-4602-8af5-b8d41a5215bc )""")
    try:
        block_schema = BlockSchema.get_block_schema(schema_id=block_schema_id)
    except BlockSchemaDoesNotExistError:
        raise click.BadParameter("No block_schema with id %s" %
                                 block_schema_id)
    click.secho(
        "BLOCK SCHEMA VERSIONS FOR community %s, block schema %s" %
        (Community.get(id=block_schema.community).name, block_schema.name))
    click.secho("Version no.\tRelease date")
    for bl_schema_version in block_schema.versions:
        click.secho("%s\t%s" %
                    (bl_schema_version.version, bl_schema_version.released))
示例#26
0
    def commit(self):
        """Store changes on current instance in database.

        This method extends the default implementation by publishing the
        deposition when 'publication_state' is set to 'published'.
        """
        if self.model is None or self.model.json is None:
            raise MissingModelError()

        # automatically make embargoed records private
        if self.get('embargo_date') and self.get('open_access'):
            if is_under_embargo(self):
                self['open_access'] = False

        if 'community' in self:
            try:
                community = Community.get(self['community'])
            except CommunityDoesNotExistError as e:
                raise InvalidDepositError(
                    'Community {} does not exist.'.format(
                        self['community'])) from e
            workflow = publication_workflows[community.publication_workflow]
            workflow(self.model, self)

        # publish the deposition if needed
        if (self['publication_state'] == PublicationStates.published.name
                # check invenio-deposit status so that we do not loop
                and self['_deposit']['status'] !=
                PublicationStates.published.name):
            super(Deposit, self).publish()  # publish() already calls commit()
            # save the action for later indexing
            if g:
                g.deposit_action = 'publish'
        else:
            super(Deposit, self).commit()
            if g:
                g.deposit_action = 'update-metadata'
        return self
示例#27
0
    def __init__(self, record=None):
        """Constructor.

        Args:
            record: data submitted for the new deposit
        """
        super(CreateDepositPermission, self).__init__()
        self.record = record

        if record is not None:
            needs = set()
            community = Community.get(record['community'])
            publication_state = record.get('publication_state', 'draft')
            if publication_state != 'draft' or community.restricted_submission:
                needs.add(create_deposit_need_factory())
                needs.add(
                    create_deposit_need_factory(
                        community=record['community'],
                        publication_state=publication_state,
                    ))
            elif not community.restricted_submission:
                needs.add(AuthenticatedNeed)

            self.permissions.add(StrictDynamicPermission(*needs))
示例#28
0
def test_new_community_set_schema_cmd(app, login_user, tmp_location):
    """Test adding a community and setting its schema using CLI commands."""
    with app.app_context():
        tmp_location.default = True
        db.session.merge(tmp_location)
        db.session.commit()

        runner = CliRunner()
        script_info = ScriptInfo(create_app=lambda info: app)
        comm_name = 'MyCom'

        # Create a new community on the command line
        args = ['create', comm_name, 'MyCom description', 'eudat.png']
        result = runner.invoke(communities_cmd, args, obj=script_info)
        assert result.exit_code == 0
        community = Community.get(name=comm_name)
        assert community
        assert community.name == comm_name

        # Create a schema for this new community
        with runner.isolated_filesystem():
            with open("schema.json", "w") as f:
                f.write(json.dumps(test_schema))

            # check RootSchemaDoesNotExistError
            with pytest.raises(RootSchemaDoesNotExistError):
                update_or_set_community_schema(comm_name, 'schema.json')

            # check RootSchemaDoesNotExistError via cli
            args = ['set_schema', comm_name, 'schema.json']
            result = runner.invoke(communities_cmd, args, obj=script_info)
            assert result.exit_code != 0

            # initialize the root schema in the test environment
            result = runner.invoke(schemas_cmd,
                                   ['init', '--ignore-mismatches'],
                                   obj=script_info)
            assert result.exit_code == 0

            # Make custom schema via cli
            args = ['set_schema', comm_name, 'schema.json']
            result = runner.invoke(communities_cmd, args, obj=script_info)
            assert result.exit_code == 0

        community_name = 'MyCom'
        community = Community.get(name=community_name)

        # Get the block schema id
        community_schema = CommunitySchema.get_community_schema(
            community.id).community_schema
        props = json.loads(community_schema).get('properties')
        assert len(props) == 1
        block_schema_id = props.popitem()[0]

        # Test the community schema by publishing a record
        with app.test_client() as client:
            user = create_user('allowed')
            login_user(user, client)

            record_data = {
                'titles': [{
                    'title': 'My Test Record'
                }],
                'community': str(community.id),
                'open_access': True,
                'community_specific': {
                    block_schema_id: {
                        'test_field1': "string value",
                        'test_field2': 10,
                    }
                },
            }

            headers = [('Content-Type', 'application/json'),
                       ('Accept', 'application/json')]
            draft_res = client.post(url_for('b2share_records_rest.b2rec_list'),
                                    data=json.dumps(record_data),
                                    headers=headers)
            draft_data = json.loads(draft_res.get_data(as_text=True))
            assert draft_res.status_code == 201

            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            draft_submit_res = client.patch(url_for(
                'b2share_deposit_rest.b2dep_item', pid_value=draft_data['id']),
                                            data=json.dumps([{
                                                "op":
                                                "replace",
                                                "path":
                                                "/publication_state",
                                                "value":
                                                "submitted",
                                            }]),
                                            headers=headers)
            assert draft_submit_res.status_code == 200
示例#29
0
def test_deposit_files_permissions(app, test_communities, login_user,
                                   test_users):
    """Test deposit read with HTTP GET."""
    with app.app_context():
        community_name = 'MyTestCommunity1'

        admin = test_users['admin']
        creator = create_user('creator')
        non_creator = create_user('non-creator')

        community = Community.get(name=community_name)
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])

        uploaded_files = {
            'myfile1.dat': b'contents1',
            'myfile2.dat': b'contents2'
        }
        test_record_data = generate_record_data(community=community_name)

        def test_files_access(draft_access, submitted_access,
                              published_access, user=None):
            def get_file(deposit, file_access):
                with app.test_client() as client:
                    if user is not None:
                        login_user(user, client)
                    subtest_file_bucket_permissions(
                        client, deposit.files.bucket,
                        access_level=file_access,
                        is_authenticated=user is not None
                    )
            deposit = create_deposit(test_record_data, creator, uploaded_files)
            get_file(deposit, file_access=draft_access)

            deposit = create_deposit(test_record_data, creator, uploaded_files)
            deposit.submit()
            get_file(deposit, file_access=submitted_access)

            deposit = create_deposit(test_record_data, creator, uploaded_files)
            deposit.submit()
            deposit.publish()
            get_file(deposit, file_access=published_access)

        # Anonymous user
        test_files_access(draft_access=None, submitted_access=None,
                          published_access=None)
        # Non creator user
        test_files_access(user=non_creator, draft_access=None,
                          submitted_access=None,
                          published_access=None)
        # Creator
        test_files_access(user=creator, draft_access='write',
                          submitted_access='write',
                          published_access=None)
        # Admin
        test_files_access(user=admin, draft_access='write',
                          submitted_access='write',
                          published_access=None)
        # Community member
        test_files_access(user=com_member, draft_access=None,
                          submitted_access=None,
                          published_access=None)
        # Community admin
        test_files_access(user=com_admin, draft_access=None,
                          submitted_access='write',
                          published_access=None)
示例#30
0
def test_make_record_with_no_file_and_search(app, test_communities,
                                             login_user):
    '''Test for issue https://github.com/EUDAT-B2SHARE/b2share/issues/1073'''
    def url_for(*args, **kwargs):
        with app.app_context():
            return flask_url_for(*args, **kwargs)

    with app.app_context():
        community_name = 'MyTestCommunity1'
        record_data = generate_record_data(community=community_name)

        allowed_user = create_user('allowed')
        community = Community.get(name=community_name)
        com_admin = create_user('com_admin', roles=[community.admin_role])
        db.session.commit()

    with app.test_client() as client:
        login_user(allowed_user, client)
        headers = [('Content-Type', 'application/json'),
                   ('Accept', 'application/json')]
        patch_headers = [('Content-Type', 'application/json-patch+json'),
                         ('Accept', 'application/json')]

        # create record without files
        draft_create_res = client.post(
            url_for('b2share_records_rest.b2rec_list'),
            data=json.dumps(record_data),
            headers=headers)
        assert draft_create_res.status_code == 201
        draft_create_data = json.loads(draft_create_res.get_data(as_text=True))

        # submit the record
        draft_submit_res = client.patch(url_for(
            'b2share_deposit_rest.b2dep_item',
            pid_value=draft_create_data['id']),
                                        data=json.dumps([{
                                            "op":
                                            "replace",
                                            "path":
                                            "/publication_state",
                                            "value":
                                            PublicationStates.submitted.name
                                        }]),
                                        headers=patch_headers)
        assert draft_submit_res.status_code == 200

    with app.test_client() as client:
        login_user(com_admin, client)
        # publish record
        draft_publish_res = client.patch(url_for(
            'b2share_deposit_rest.b2dep_item',
            pid_value=draft_create_data['id']),
                                         data=json.dumps([{
                                             "op":
                                             "replace",
                                             "path":
                                             "/publication_state",
                                             "value":
                                             PublicationStates.published.name
                                         }]),
                                         headers=patch_headers)
        assert draft_publish_res.status_code == 200
        draft_publish_data = json.loads(
            draft_publish_res.get_data(as_text=True))

        # get record
        record_get_res = client.get(url_for(
            'b2share_records_rest.b2rec_item',
            pid_value=draft_publish_data['id']),
                                    headers=headers)
        assert record_get_res.status_code == 200
        record_get_data = json.loads(record_get_res.get_data(as_text=True))

    with app.test_client() as client:
        # refresh index to make records searchable
        with app.app_context():
            current_search._client.indices.refresh()

    with app.test_client() as client:
        # test search, for crashes
        record_search_res = client.get(
            url_for('b2share_records_rest.b2rec_list'),
            data='',
            headers=headers)
        assert record_search_res.status_code == 200
        record_search_data = json.loads(
            record_search_res.get_data(as_text=True))
        assert len(record_search_data['hits']['hits']) == 1
        record_hit = record_search_data['hits']['hits'][0]

        # TODO: the following assert should work:
        # assert record_hit == record_get_data
        # -- but currently it doesn't because records with no files
        #    do not have a 'files' link

        assert record_hit['metadata'] == record_get_data['metadata']
def test_deposit_files_permissions(app, test_communities, login_user,
                                   test_users):
    """Test deposit read with HTTP GET."""
    with app.app_context():
        community_name = 'MyTestCommunity1'

        admin = test_users['admin']
        creator = create_user('creator')
        non_creator = create_user('non-creator')

        community = Community.get(name=community_name)
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])

        uploaded_files = {
            'myfile1.dat': b'contents1',
            'myfile2.dat': b'contents2'
        }
        test_record_data = generate_record_data(community=community_name)

        def test_files_access(draft_access,
                              submitted_access,
                              published_access,
                              user=None):
            def get_file(deposit, file_access):
                with app.test_client() as client:
                    if user is not None:
                        login_user(user, client)
                    subtest_file_bucket_permissions(client,
                                                    deposit.files.bucket,
                                                    access_level=file_access,
                                                    is_authenticated=user
                                                    is not None)

            deposit = create_deposit(test_record_data, creator, uploaded_files)
            get_file(deposit, file_access=draft_access)

            deposit = create_deposit(test_record_data, creator, uploaded_files)
            deposit.submit()
            get_file(deposit, file_access=submitted_access)

            deposit = create_deposit(test_record_data, creator, uploaded_files)
            deposit.submit()
            deposit.publish()
            get_file(deposit, file_access=published_access)

        # Anonymous user
        test_files_access(draft_access=None,
                          submitted_access=None,
                          published_access=None)
        # Non creator user
        test_files_access(user=non_creator,
                          draft_access=None,
                          submitted_access=None,
                          published_access=None)
        # Creator
        test_files_access(user=creator,
                          draft_access='write',
                          submitted_access='write',
                          published_access=None)
        # Admin
        test_files_access(user=admin,
                          draft_access='write',
                          submitted_access='write',
                          published_access=None)
        # Community member
        test_files_access(user=com_member,
                          draft_access=None,
                          submitted_access=None,
                          published_access=None)
        # Community admin
        test_files_access(user=com_admin,
                          draft_access=None,
                          submitted_access='write',
                          published_access=None)
def test_deposit_read_permissions(app, login_user, test_users,
                                  test_communities):
    """Test deposit read with HTTP GET."""
    with app.app_context():
        community_name = 'MyTestCommunity1'
        record_data = generate_record_data(community=community_name)
        community = Community.get(name=community_name)

        admin = test_users['admin']
        creator = create_user('creator')
        non_creator = create_user('non-creator')
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])

        def test_get(deposit, status, user=None):
            with app.test_client() as client:
                if user is not None:
                    login_user(user, client)
                headers = [('Accept', 'application/json')]
                request_res = client.get(url_for(
                    'b2share_deposit_rest.b2dep_item',
                    pid_value=deposit.pid.pid_value),
                                         headers=headers)
                assert request_res.status_code == status

        # test with anonymous user
        deposit = create_deposit(record_data, creator)
        test_get(deposit, 401)
        deposit.submit()
        test_get(deposit, 401)
        deposit.publish()
        test_get(deposit, 401)

        deposit = create_deposit(record_data, creator)
        test_get(deposit, 403, non_creator)
        deposit.submit()
        test_get(deposit, 403, non_creator)
        deposit.publish()
        test_get(deposit, 403, non_creator)

        deposit = create_deposit(record_data, creator)
        test_get(deposit, 200, creator)
        deposit.submit()
        test_get(deposit, 200, creator)
        deposit.publish()
        test_get(deposit, 200, creator)

        deposit = create_deposit(record_data, creator)
        test_get(deposit, 200, admin)
        deposit.submit()
        test_get(deposit, 200, admin)
        deposit.publish()
        test_get(deposit, 200, admin)

        deposit = create_deposit(record_data, creator)
        test_get(deposit, 403, com_member)
        deposit.submit()
        test_get(deposit, 403, com_member)
        deposit.publish()
        test_get(deposit, 403, com_member)

        deposit = create_deposit(record_data, creator)
        test_get(deposit, 403, com_admin)
        deposit.submit()
        test_get(deposit, 200, com_admin)
        deposit.publish()
        test_get(deposit, 200, com_admin)
def test_deposit_publish(app, test_users, test_communities, login_user):
    """Test record draft publication with HTTP PATCH."""
    with app.app_context():
        community_name = 'MyTestCommunity1'
        creator = test_users['deposits_creator']
        record_data = generate_record_data(community=community_name)
        community = Community.get(name=community_name)
        com_admin = create_user('com_admin', roles=[community.admin_role])

        deposit = create_deposit(record_data, creator)
        deposit_id = deposit.id
        deposit.submit()
        db.session.commit()

        with app.test_client() as client:
            login_user(com_admin, client)

            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            draft_patch_res = client.patch(url_for(
                'b2share_deposit_rest.b2dep_item',
                pid_value=deposit.pid.pid_value),
                                           data=json.dumps([{
                                               "op":
                                               "replace",
                                               "path":
                                               "/publication_state",
                                               "value":
                                               PublicationStates.published.name
                                           }]),
                                           headers=headers)
            assert draft_patch_res.status_code == 200
            draft_patch_data = json.loads(
                draft_patch_res.get_data(as_text=True))
            expected_metadata = build_expected_metadata(
                record_data,
                PublicationStates.published.name,
                owners=[creator.id],
                draft=True,
                PID=draft_patch_data['metadata'].get('ePIC_PID'),
                DOI=draft_patch_data['metadata'].get('DOI'),
            )

    with app.app_context():
        deposit = Deposit.get_record(deposit_id)
        with app.test_client() as client:
            login_user(creator, client)
            assert expected_metadata == draft_patch_data['metadata']
            assert (deposit['publication_state'] ==
                    PublicationStates.published.name)
            subtest_self_link(draft_patch_data, draft_patch_res.headers,
                              client)

            pid, published = deposit.fetch_published()
            # check that the published record and the deposit are equal except
            # for the schema
            cleaned_deposit = {
                f: v
                for f, v in deposit.items() if f != '$schema'
            }
            cleaned_published = {
                f: v
                for f, v in deposit.items() if f != '$schema'
            }
            assert cleaned_published == cleaned_deposit
            # check "published" link
            assert draft_patch_data['links']['publication'] == \
                url_for('b2share_records_rest.{0}_item'.format(
                    RecordUUIDProvider.pid_type
                ), pid_value=pid.pid_value, _external=True)
            # check that the published record content match the deposit
            headers = [('Accept', 'application/json')]
            self_response = client.get(
                draft_patch_data['links']['publication'], headers=headers)
            assert self_response.status_code == 200
            published_data = json.loads(self_response.get_data(as_text=True))
            # we don't want to compare the links and dates
            cleaned_published_data = deepcopy(published_data)
            # the published record has an extra empty 'files' array
            assert cleaned_published_data['files'] == []
            del cleaned_published_data['files']
            cleaned_draft_data = deepcopy(draft_patch_data)
            for item in [cleaned_published_data, cleaned_draft_data]:
                del item['links']
                del item['created']
                del item['updated']
                del item['metadata']['$schema']
            assert cleaned_draft_data == cleaned_published_data
示例#34
0
文件: eudatcore.py 项目: hevp/b2share
 def community(self, metadata, root):
     try:
         c = Community.get(id=metadata['community'])
         root.append(E.community(c.name))
     except CommunityDoesNotExistError:
         root.append(E.community('unknown'))
示例#35
0
def test_new_community_set_schema_cmd(app, login_user, tmp_location):
    """Test adding a community and setting its schema using CLI commands."""
    with app.app_context():
        tmp_location.default = True
        db.session.merge(tmp_location)
        db.session.commit()

        runner = CliRunner()
        script_info = ScriptInfo(create_app=lambda info: app)
        comm_name = 'MyCom'

        # Create a new community on the command line
        args = ['create', comm_name, 'MyCom description', 'eudat.png']
        result = runner.invoke(communities_cmd, args, obj=script_info)
        assert result.exit_code == 0
        community = Community.get(name=comm_name)
        assert community
        assert community.name == comm_name

        # Create a schema for this new community
        with runner.isolated_filesystem():
            with open("schema.json", "w") as f:
                f.write(json.dumps(test_schema))

            # check RootSchemaDoesNotExistError
            with pytest.raises(RootSchemaDoesNotExistError):
                update_or_set_community_schema(comm_name, 'schema.json')

            # check RootSchemaDoesNotExistError via cli
            args = ['set_schema', comm_name, 'schema.json']
            result = runner.invoke(communities_cmd, args, obj=script_info)
            assert result.exit_code != 0

            # initialize the root schema in the test environment
            result = runner.invoke(schemas_cmd, ['init'], obj=script_info)
            assert result.exit_code == 0

            # Make custom schema via cli
            args = ['set_schema', comm_name, 'schema.json']
            result = runner.invoke(communities_cmd, args, obj=script_info)
            assert result.exit_code == 0

        community_name = 'MyCom'
        community = Community.get(name=community_name)

        # Get the block schema id
        community_schema = CommunitySchema.get_community_schema(
            community.id).community_schema
        props = json.loads(community_schema).get('properties')
        assert len(props) == 1
        block_schema_id = props.popitem()[0]

        # Test the community schema by publishing a record
        with app.test_client() as client:
            user = create_user('allowed')
            login_user(user, client)

            record_data = {
                'titles': [{'title':'My Test Record'}],
                'community': str(community.id),
                'open_access': True,
                'community_specific': {
                    block_schema_id: {
                        'test_field1': "string value",
                        'test_field2': 10,
                    }
                },
            }

            headers = [('Content-Type', 'application/json'),
                       ('Accept', 'application/json')]
            draft_res = client.post(url_for('b2share_records_rest.b2rec_list'),
                                    data=json.dumps(record_data),
                                    headers=headers)
            draft_data = json.loads(draft_res.get_data(as_text=True))
            assert draft_res.status_code == 201

            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            draft_submit_res = client.patch(
                url_for('b2share_deposit_rest.b2dep_item',
                        pid_value=draft_data['id']),
                data=json.dumps([{
                    "op": "replace",
                    "path": "/publication_state",
                    "value": "submitted",
                }]),
                headers=headers)
            assert draft_submit_res.status_code == 200
示例#36
0
    def commit(self):
        """Store changes on current instance in database.

        This method extends the default implementation by publishing the
        deposition when 'publication_state' is set to 'published'.
        """
        if 'external_pids' in self:
            deposit_id = self['_deposit']['id']
            recid = PersistentIdentifier.query.filter_by(
                pid_value=deposit_id).first()
            assert recid.status == 'R'
            record_bucket = RecordsBuckets.query.filter_by(
                record_id=recid.pid_value).first()
            bucket = Bucket.query.filter_by(id=record_bucket.bucket_id).first()
            object_versions = ObjectVersion.query.filter_by(
                bucket_id=bucket.id).all()
            key_to_pid = {
                ext_pid.get('key'): ext_pid.get('ePIC_PID')
                for ext_pid in self['external_pids']
            }
            # for the existing files
            for object_version in object_versions:
                if object_version.file is None or \
                        object_version.file.storage_class != 'B':
                    continue
                # check that they are still in the file pids list or remove
                if object_version.key not in key_to_pid:
                    ObjectVersion.delete(bucket,
                                         object_version.key)
                # check that the uri is still the same or update it
                elif object_version.file.uri != \
                        key_to_pid[object_version.key]:
                    db.session.query(FileInstance).\
                        filter(FileInstance.id == object_version.file_id).\
                        update({"uri": key_to_pid[object_version.key]})
            create_b2safe_file(self['external_pids'], bucket)
            del self['external_pids']

        if self.model is None or self.model.json is None:
            raise MissingModelError()

        # automatically make embargoed records private
        if self.get('embargo_date') and self.get('open_access'):
            if is_under_embargo(self):
                self['open_access'] = False

        if 'community' in self:
            try:
                community = Community.get(self['community'])
            except CommunityDoesNotExistError as e:
                raise InvalidDepositError('Community {} does not exist.'.format(
                    self['community'])) from e
            workflow = publication_workflows[community.publication_workflow]
            workflow(self.model, self)

        # publish the deposition if needed
        if (self['publication_state'] == PublicationStates.published.name
                # check invenio-deposit status so that we do not loop
                and self['_deposit']['status'] != PublicationStates.published.name):

            # Retrieve previous version in order to reindex it later.
            previous_version_pid = None
            # Save the previous "last" version for later use
            if self.versioning.parent.status == PIDStatus.REDIRECTED and \
                    self.versioning.has_children:
                previous_version_pid = self.versioning.last_child
                previous_version_uuid = str(RecordUUIDProvider.get(
                    previous_version_pid.pid_value
                ).pid.object_uuid)
            external_pids = generate_external_pids(self)
            if external_pids:
                self['_deposit']['external_pids'] = external_pids

            super(Deposit, self).publish()  # publish() already calls commit()
            # Register parent PID if necessary and update redirect
            self.versioning.update_redirect()
            # Reindex previous version. This is needed in order to update
            # the is_last_version flag
            if previous_version_pid is not None:
                self.indexer.index_by_id(previous_version_uuid)

            # save the action for later indexing
            if g:
                g.deposit_action = 'publish'
        else:
            super(Deposit, self).commit()
            if g:
                g.deposit_action = 'update-metadata'
        return self
示例#37
0
 def community(self, metadata, root):
     c = Community.get(id=metadata['community'])
     root.append(E.community(c.name))
示例#38
0
def test_deposit_publish(app, test_users, test_communities,
                         login_user):
    """Test record draft publication with HTTP PATCH."""
    with app.app_context():
        community_name = 'MyTestCommunity1'
        creator = test_users['deposits_creator']
        record_data = generate_record_data(community=community_name)
        community = Community.get(name=community_name)
        com_admin = create_user('com_admin', roles=[community.admin_role])

        deposit = create_deposit(record_data, creator)
        deposit_id = deposit.id
        deposit.submit()
        db.session.commit()

        with app.test_client() as client:
            login_user(com_admin, client)

            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            draft_patch_res = client.patch(
                url_for('b2share_deposit_rest.b2dep_item',
                        pid_value=deposit.pid.pid_value),
                data=json.dumps([{
                    "op": "replace", "path": "/publication_state",
                    "value": PublicationStates.published.name
                }]),
                headers=headers)
            assert draft_patch_res.status_code == 200
            draft_patch_data = json.loads(
                draft_patch_res.get_data(as_text=True))
            expected_metadata = build_expected_metadata(
                record_data,
                PublicationStates.published.name,
                owners=[creator.id],
                draft=True,
                PID=draft_patch_data['metadata'].get('ePIC_PID'),
                DOI=draft_patch_data['metadata'].get('DOI'),
            )

    with app.app_context():
        deposit = Deposit.get_record(deposit_id)
        with app.test_client() as client:
            login_user(creator, client)
            assert expected_metadata == draft_patch_data['metadata']
            assert (deposit['publication_state']
                    == PublicationStates.published.name)
            subtest_self_link(draft_patch_data,
                              draft_patch_res.headers,
                              client)

            pid, published = deposit.fetch_published()
            # check that the published record and the deposit are equal except
            # for the schema
            cleaned_deposit = {f: v for f, v in deposit.items()
                               if f != '$schema'}
            cleaned_published = {f: v for f, v in deposit.items()
                                 if f != '$schema'}
            assert cleaned_published == cleaned_deposit
            # check "published" link
            assert draft_patch_data['links']['publication'] == \
                url_for('b2share_records_rest.{0}_item'.format(
                    RecordUUIDProvider.pid_type
                ), pid_value=pid.pid_value, _external=True)
            # check that the published record content match the deposit
            headers = [('Accept', 'application/json')]
            self_response = client.get(
                draft_patch_data['links']['publication'],
                headers=headers
            )
            assert self_response.status_code == 200
            published_data = json.loads(self_response.get_data(
                as_text=True))
            # we don't want to compare the links and dates
            cleaned_published_data = deepcopy(published_data)
            # the published record has an extra empty 'files' array
            assert cleaned_published_data['files'] == []
            del cleaned_published_data['files']
            cleaned_draft_data = deepcopy(draft_patch_data)
            for item in [cleaned_published_data, cleaned_draft_data]:
                del item['links']
                del item['created']
                del item['updated']
                del item['metadata']['$schema']
            assert cleaned_draft_data == cleaned_published_data
def test_deposit_search_permissions(app, draft_deposits, submitted_deposits,
                                    test_users, login_user, test_communities):
    """Test deposit search permissions."""
    with app.app_context():
        # flush the indices so that indexed deposits are searchable
        current_search_client.indices.flush('*')

        admin = test_users['admin']
        creator = test_users['deposits_creator']
        non_creator = create_user('non-creator')

        permission_to_read_all_submitted_deposits = read_deposit_need_factory(
            community=str(test_communities['MyTestCommunity2']),
            publication_state='submitted',
        )
        allowed_role = create_role(
            'allowed_role',
            permissions=[permission_to_read_all_submitted_deposits])
        user_allowed_by_role = create_user('user-allowed-by-role',
                                           roles=[allowed_role])
        user_allowed_by_permission = create_user(
            'user-allowed-by-permission',
            permissions=[permission_to_read_all_submitted_deposits])

        community = Community.get(test_communities['MyTestCommunity2'])
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])

        search_deposits_url = url_for('b2share_records_rest.b2rec_list',
                                      drafts=1,
                                      size=100)
        headers = [('Content-Type', 'application/json'),
                   ('Accept', 'application/json')]

        def test_search(status, expected_deposits, user=None):
            with app.test_client() as client:
                if user is not None:
                    login_user(user, client)
                deposit_search_res = client.get(search_deposits_url,
                                                headers=headers)
                assert deposit_search_res.status_code == status
                # test the response data only when the user is allowed to
                # search for deposits
                if status != 200:
                    return
                deposit_search_data = json.loads(
                    deposit_search_res.get_data(as_text=True))

                assert deposit_search_data['hits']['total'] == \
                    len(expected_deposits)

                deposit_pids = [
                    hit['id'] for hit in deposit_search_data['hits']['hits']
                ]
                expected_deposit_pids = [
                    dep.deposit_id.hex for dep in expected_deposits
                ]
                deposit_pids.sort()
                expected_deposit_pids.sort()
                assert deposit_pids == expected_deposit_pids

        test_search(200, draft_deposits + submitted_deposits, creator)
        test_search(200, draft_deposits + submitted_deposits, admin)
        test_search(401, [], None)
        test_search(200, [], non_creator)

        # search for submitted records
        community2_deposits = [
            dep for dep in submitted_deposits if dep.data['community'] == str(
                test_communities['MyTestCommunity2'])
        ]
        test_search(200, community2_deposits, user_allowed_by_role)
        test_search(200, community2_deposits, user_allowed_by_permission)

        # community admin should have access to all submitted records
        # in their community
        test_search(200, [], com_member)
        test_search(200, community2_deposits, com_admin)
示例#40
0
    def commit(self):
        """Store changes on current instance in database.

        This method extends the default implementation by publishing the
        deposition when 'publication_state' is set to 'published'.
        """
        if 'external_pids' in self:
            deposit_id = self['_deposit']['id']
            recid = PersistentIdentifier.query.filter_by(
                pid_value=deposit_id).first()
            assert recid.status == 'R'
            record_bucket = RecordsBuckets.query.filter_by(
                record_id=recid.pid_value).first()
            bucket = Bucket.query.filter_by(id=record_bucket.bucket_id).first()
            object_versions = ObjectVersion.query.filter_by(
                bucket_id=bucket.id).all()
            key_to_pid = {
                ext_pid.get('key'): ext_pid.get('ePIC_PID')
                for ext_pid in self['external_pids']
            }
            # for the existing files
            for object_version in object_versions:
                if object_version.file is None or \
                        object_version.file.storage_class != 'B':
                    continue
                # check that they are still in the file pids list or remove
                if object_version.key not in key_to_pid:
                    ObjectVersion.delete(bucket,
                                         object_version.key)
                # check that the uri is still the same or update it
                elif object_version.file.uri != \
                        key_to_pid[object_version.key]:
                    db.session.query(FileInstance).\
                        filter(FileInstance.id == object_version.file_id).\
                        update({"uri": key_to_pid[object_version.key]})
            create_b2safe_file(self['external_pids'], bucket)
            del self['external_pids']

        if self.model is None or self.model.json is None:
            raise MissingModelError()

        # automatically make embargoed records private
        if self.get('embargo_date') and self.get('open_access'):
            if is_under_embargo(self):
                self['open_access'] = False

        if 'community' in self:
            try:
                community = Community.get(self['community'])
            except CommunityDoesNotExistError as e:
                raise InvalidDepositError('Community {} does not exist.'.format(
                    self['community'])) from e
            workflow = publication_workflows[community.publication_workflow]
            workflow(self.model, self)

        # publish the deposition if needed
        if (self['publication_state'] == PublicationStates.published.name
                # check invenio-deposit status so that we do not loop
                and self['_deposit']['status'] != PublicationStates.published.name):

            # Retrieve previous version in order to reindex it later.
            previous_version_pid = None
            # Save the previous "last" version for later use
            if self.versioning.parent.status == PIDStatus.REDIRECTED and \
                    self.versioning.has_children:
                previous_version_pid = self.versioning.last_child
                previous_version_uuid = str(RecordUUIDProvider.get(
                    previous_version_pid.pid_value
                ).pid.object_uuid)
            external_pids = generate_external_pids(self)
            if external_pids:
                self['_deposit']['external_pids'] = external_pids

            super(Deposit, self).publish()  # publish() already calls commit()
            # Register parent PID if necessary and update redirect
            self.versioning.update_redirect()
            # Reindex previous version. This is needed in order to update
            # the is_last_version flag
            if previous_version_pid is not None:
                self.indexer.index_by_id(previous_version_uuid)

            # save the action for later indexing
            if g:
                g.deposit_action = 'publish'
        else:
            super(Deposit, self).commit()
            if g:
                g.deposit_action = 'update-metadata'
        return self
示例#41
0
def test_deposit_read_permissions(app, login_user, test_users,
                                  test_communities):
    """Test deposit read with HTTP GET."""
    with app.app_context():
        community_name = 'MyTestCommunity1'
        record_data = generate_record_data(community=community_name)
        community = Community.get(name=community_name)

        admin = test_users['admin']
        creator = create_user('creator')
        non_creator = create_user('non-creator')
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])

        def test_get(deposit, status, user=None):
            with app.test_client() as client:
                if user is not None:
                    login_user(user, client)
                headers = [('Accept', 'application/json')]
                request_res = client.get(
                    url_for('b2share_deposit_rest.b2dep_item',
                            pid_value=deposit.pid.pid_value),
                    headers=headers)
                assert request_res.status_code == status

        # test with anonymous user
        deposit = create_deposit(record_data, creator)
        test_get(deposit, 401)
        deposit.submit()
        test_get(deposit, 401)
        deposit.publish()
        test_get(deposit, 401)

        deposit = create_deposit(record_data, creator)
        test_get(deposit, 403, non_creator)
        deposit.submit()
        test_get(deposit, 403, non_creator)
        deposit.publish()
        test_get(deposit, 403, non_creator)

        deposit = create_deposit(record_data, creator)
        test_get(deposit, 200, creator)
        deposit.submit()
        test_get(deposit, 200, creator)
        deposit.publish()
        test_get(deposit, 200, creator)

        deposit = create_deposit(record_data, creator)
        test_get(deposit, 200, admin)
        deposit.submit()
        test_get(deposit, 200, admin)
        deposit.publish()
        test_get(deposit, 200, admin)

        deposit = create_deposit(record_data, creator)
        test_get(deposit, 403, com_member)
        deposit.submit()
        test_get(deposit, 403, com_member)
        deposit.publish()
        test_get(deposit, 403, com_member)

        deposit = create_deposit(record_data, creator)
        test_get(deposit, 403, com_admin)
        deposit.submit()
        test_get(deposit, 200, com_admin)
        deposit.publish()
        test_get(deposit, 200, com_admin)
示例#42
0
def test_deposit_search_permissions(app, draft_deposits, submitted_deposits,
                                    test_users, login_user, test_communities):
    """Test deposit search permissions."""
    with app.app_context():
        # flush the indices so that indexed deposits are searchable
        current_search_client.indices.flush('*')

        admin = test_users['admin']
        creator = test_users['deposits_creator']
        non_creator = create_user('non-creator')

        permission_to_read_all_submitted_deposits = read_deposit_need_factory(
            community=str(test_communities['MyTestCommunity2']),
            publication_state='submitted',
        )
        allowed_role = create_role(
            'allowed_role',
            permissions=[
                permission_to_read_all_submitted_deposits
            ]
        )
        user_allowed_by_role = create_user('user-allowed-by-role',
                                           roles=[allowed_role])
        user_allowed_by_permission = create_user(
            'user-allowed-by-permission',
            permissions=[
                permission_to_read_all_submitted_deposits
            ]
        )

        community = Community.get(test_communities['MyTestCommunity2'])
        com_member = create_user('com_member', roles=[community.member_role])
        com_admin = create_user('com_admin', roles=[community.admin_role])

        search_deposits_url = url_for(
            'b2share_records_rest.b2rec_list', drafts=1, size=100)
        headers = [('Content-Type', 'application/json'),
                ('Accept', 'application/json')]

        def test_search(status, expected_deposits, user=None):
            with app.test_client() as client:
                if user is not None:
                    login_user(user, client)
                deposit_search_res = client.get(
                    search_deposits_url,
                    headers=headers)
                assert deposit_search_res.status_code == status
                # test the response data only when the user is allowed to
                # search for deposits
                if status != 200:
                    return
                deposit_search_data = json.loads(
                    deposit_search_res.get_data(as_text=True))

                assert deposit_search_data['hits']['total'] == \
                    len(expected_deposits)

                deposit_pids = [hit['id'] for hit
                            in deposit_search_data['hits']['hits']]
                expected_deposit_pids = [dep.deposit_id.hex for dep
                                         in expected_deposits]
                deposit_pids.sort()
                expected_deposit_pids.sort()
                assert deposit_pids == expected_deposit_pids
        test_search(200, draft_deposits + submitted_deposits, creator)
        test_search(200, draft_deposits + submitted_deposits, admin)
        test_search(401, [], None)
        test_search(200, [], non_creator)


        # search for submitted records
        community2_deposits = [dep for dep in submitted_deposits
                                if dep.data['community'] ==
                                str(test_communities['MyTestCommunity2'])]
        test_search(200, community2_deposits, user_allowed_by_role)
        test_search(200,
                    community2_deposits,
                    user_allowed_by_permission)

        # community admin should have access to all submitted records
        # in their community
        test_search(200, [], com_member)
        test_search(200, community2_deposits, com_admin)
示例#43
0
def test_make_record_with_no_file_and_search(app, test_communities,
                                             login_user):
    '''Test for issue https://github.com/EUDAT-B2SHARE/b2share/issues/1073'''
    def url_for(*args, **kwargs):
        with app.app_context():
            return flask_url_for(*args, **kwargs)

    with app.app_context():
        community_name = 'MyTestCommunity1'
        record_data = generate_record_data(community=community_name)

        allowed_user = create_user('allowed')
        community = Community.get(name=community_name)
        com_admin = create_user('com_admin', roles=[community.admin_role])
        db.session.commit()

    with app.test_client() as client:
        login_user(allowed_user, client)
        headers = [('Content-Type', 'application/json'),
                   ('Accept', 'application/json')]
        patch_headers = [('Content-Type', 'application/json-patch+json'),
                         ('Accept', 'application/json')]

        # create record without files
        draft_create_res = client.post(
            url_for('b2share_records_rest.b2rec_list'),
            data=json.dumps(record_data), headers=headers)
        assert draft_create_res.status_code == 201
        draft_create_data = json.loads(
            draft_create_res.get_data(as_text=True))

        # submit the record
        draft_submit_res = client.patch(
            url_for('b2share_deposit_rest.b2dep_item',
                    pid_value=draft_create_data['id']),
            data=json.dumps([{
                "op": "replace", "path": "/publication_state",
                "value": PublicationStates.submitted.name
            }]),
            headers=patch_headers)
        assert draft_submit_res.status_code == 200

    with app.test_client() as client:
        login_user(com_admin, client)
        # publish record
        draft_publish_res = client.patch(
            url_for('b2share_deposit_rest.b2dep_item',
                    pid_value=draft_create_data['id']),
            data=json.dumps([{
                "op": "replace", "path": "/publication_state",
                "value": PublicationStates.published.name
            }]),
            headers=patch_headers)
        assert draft_publish_res.status_code == 200
        draft_publish_data = json.loads(
            draft_publish_res.get_data(as_text=True))

        # get record
        record_get_res = client.get(
            url_for('b2share_records_rest.b2rec_item',
                    pid_value=draft_publish_data['id']),
            headers=headers)
        assert record_get_res.status_code == 200
        record_get_data = json.loads(
            record_get_res.get_data(as_text=True))

    with app.test_client() as client:
        # refresh index to make records searchable
        with app.app_context():
            current_search._client.indices.refresh()

    with app.test_client() as client:
        # test search, for crashes
        record_search_res = client.get(
            url_for('b2share_records_rest.b2rec_list'),
            data='',
            headers=headers)
        assert record_search_res.status_code == 200
        record_search_data = json.loads(
            record_search_res.get_data(as_text=True))
        assert len(record_search_data['hits']['hits']) == 1
        record_hit = record_search_data['hits']['hits'][0]

        # TODO: the following assert should work:
        # assert record_hit == record_get_data
        # -- but currently it doesn't because records with no files
        #    do not have a 'files' link

        assert record_hit['metadata'] == record_get_data['metadata']
示例#44
0
def test_file_download_statistics(app, test_community, test_users,
                                  test_records, login_user):
    """Test checking a record's DOI using CLI commands."""
    with app.app_context():

        def url_for(*args, **kwargs):
            """Generate url using flask.url_for and the current app ctx."""
            with app.app_context():
                return flask_url_for(*args, **kwargs)

        # create user that will create the record and the files
        scopes = current_oauth2server.scope_choices()

        allowed_user = create_user('allowed')

        scopes = current_oauth2server.scope_choices()
        allowed_token = Token.create_personal('allowed_token',
                                              allowed_user.id,
                                              scopes=[s[0] for s in scopes])
        # application authentication token header
        allowed_headers = [('Authorization',
                            'Bearer {}'.format(allowed_token.access_token))]

        community_name = 'MyTestCommunity1'
        community = Community.get(name=community_name)
        com_admin = create_user('com_admin2', roles=[community.admin_role])
        com_admin_token = Token.create_personal('com_admin_token',
                                                com_admin.id,
                                                scopes=[s[0] for s in scopes])
        # application authentication token header
        com_admin_headers = [
            ('Authorization',
             'Bearer {}'.format(com_admin_token.access_token)),
            ('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) '
             'AppleWebKit/537.36 (KHTML, like Gecko)'
             'Chrome/45.0.2454.101 Safari/537.36')
        ]
        publish_headers = [('Content-Type', 'application/json-patch+json'),
                           ('Accept', 'application/json')] + com_admin_headers
        submit_headers = [('Content-Type', 'application/json-patch+json'),
                          ('Accept', 'application/json')] + allowed_headers
        stats_headers = [('Content-Type', 'application/json')]

        test_records_data = [
            generate_record_data(community=test_community.name)
            for idx in range(1, 3)
        ]

        for record_data in test_records_data:
            with app.test_client() as client:
                login_user(allowed_user, client)

                record_list_url = (lambda **kwargs: url_for(
                    'b2share_records_rest.b2rec_list', **kwargs))

                headers = [('Content-Type', 'application/json'),
                           ('Accept', 'application/json')] + allowed_headers
                draft_create_res = client.post(record_list_url(),
                                               data=json.dumps(record_data),
                                               headers=headers)
                assert draft_create_res.status_code == 201
                draft_create_data = json.loads(
                    draft_create_res.get_data(as_text=True))

                uploaded_files = {
                    'myfile1.html': b'contents1',
                    'myfile2.html': b'contents2'
                }

                for file_key, file_content in uploaded_files.items():
                    # Test file upload
                    headers = [('Accept', '*/*'),
                               ('Content-Type', 'text/html; charset=utf-8')
                               ] + allowed_headers
                    object_url = '{0}/{1}'.format(
                        draft_create_data['links']['files'], file_key)
                    file_put_res = client.put(
                        object_url,
                        input_stream=BytesIO(file_content),
                        headers=headers)
                    assert file_put_res.status_code == 200
                    file_put_data = json.loads(
                        file_put_res.get_data(as_text=True))
                    assert 'created' in file_put_data

                    bucket_id = draft_create_data['links']['files'].split(
                        '/')[-1]
                    # make sure that downloads from deposits are skipped
                    client.get(
                        url_for('invenio_files_rest.object_api',
                                bucket_id=bucket_id,
                                key=file_key))
                    assert process_events(['file-download']) == \
                        [('file-download', (0, 0))]

                # test draft submit
                draft_submit_res = client.patch(
                    url_for('b2share_deposit_rest.b2dep_item',
                            pid_value=draft_create_data['id']),
                    data=json.dumps([{
                        "op": "replace",
                        "path": "/publication_state",
                        "value": PublicationStates.submitted.name
                    }]),
                    headers=submit_headers)
                assert draft_submit_res.status_code == 200

            with app.test_client() as client:
                login_user(com_admin, client)
                # test draft publish
                draft_publish_res = client.patch(
                    url_for('b2share_deposit_rest.b2dep_item',
                            pid_value=draft_create_data['id']),
                    data=json.dumps([{
                        "op": "replace",
                        "path": "/publication_state",
                        "value": PublicationStates.published.name
                    }]),
                    headers=publish_headers)

                assert draft_publish_res.status_code == 200
                draft_publish_data = json.loads(
                    draft_publish_res.get_data(as_text=True))

                # Test record GET
                record_get_res = client.get(url_for(
                    'b2share_records_rest.b2rec_item',
                    pid_value=draft_publish_data['id']),
                                            headers=headers)
                assert record_get_res.status_code == 200
                record_get_data = json.loads(
                    record_get_res.get_data(as_text=True))

                # make sure that templates are in the ES
                list(current_search.put_templates())

                # test that a record is accessible through the rest api
                file1 = record_get_data['files'][0]

                # download once
                client.get(url_for('invenio_files_rest.object_api',
                                   bucket_id=file1['bucket'],
                                   key=file1['key']),
                           headers=com_admin_headers)
                # make sure that the queue contains the event
                assert list(
                    current_queues.queues['stats-file-download'].consume())

                # download again
                client.get(url_for('invenio_files_rest.object_api',
                                   bucket_id=file1['bucket'],
                                   key=file1['key']),
                           headers=com_admin_headers)

                process_events(['file-download'])
                current_search_client.indices.refresh('*')
                # make sure that new index for events is created in ES
                current_search_client.indices.exists(
                    index='events-stats-file-download')

                aggregate_events(['file-download-agg'])
                current_search_client.indices.refresh('*')

                # make sure that new aggregation index is created in ES
                current_search_client.indices.exists(
                    index='stats-file-download')

                stats_ret = client.post(url_for('invenio_stats.stat_query'),
                                        data=json.dumps({
                                            'mystat': {
                                                'stat':
                                                'bucket-file-download-total',
                                                'params': {
                                                    'start_date': '2017-01-01',
                                                    'bucket_id':
                                                    file1['bucket'],
                                                }
                                            }
                                        }),
                                        headers=stats_headers)
                stats_ret_data = json.loads(stats_ret.get_data(as_text=True))
                assert stats_ret_data['mystat']['buckets'][0]['value'] == 1.0