diff --git a/setup.py b/setup.py index 1abf85a01..ed8bd3be3 100644 --- a/setup.py +++ b/setup.py @@ -90,7 +90,8 @@ 'monitoring = sonar.monitoring.views:blueprint', 'translations = sonar.translations.rest:blueprint', 'suggestions = sonar.suggestions.rest:blueprint', - 'validation = sonar.modules.validation.views:blueprint' + 'validation = sonar.modules.validation.views:blueprint', + 'documents = sonar.modules.documents.rest:blueprint' ], 'invenio_assets.webpack': [ 'sonar_theme = sonar.theme.webpack:theme' diff --git a/sonar/modules/documents/rest.py b/sonar/modules/documents/rest.py new file mode 100644 index 000000000..096c3b944 --- /dev/null +++ b/sonar/modules/documents/rest.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# +# Swiss Open Access Repository +# Copyright (C) 2021 RERO +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +"""Documents rest views.""" + +from flask import Blueprint, current_app, jsonify, request + +from sonar.modules.organisations.api import OrganisationRecord, \ + current_organisation +from sonar.modules.users.api import current_user_record +from sonar.modules.utils import get_language_value + +blueprint = Blueprint('documents', __name__, url_prefix='/documents') + + +@blueprint.route('/aggregations', methods=['GET']) +def aggregations(): + """Get aggregations list.""" + view = request.args.get('view') + collection = request.args.get('collection') + + aggregations_list = [ + 'document_type', + 'controlled_affiliation', + 'year', + 'collection', + 'language', + 'author', + 'subject', + 'organisation', + 'sections', + 'customField1', + 'customField2', + 'customField3', + ] + + if view: + # Remove organisation in dedicated view + if view != current_app.config.get('SONAR_APP_DEFAULT_ORGANISATION'): + aggregations_list.remove('organisation') + else: + # Remove organisation for non superusers. + if current_user_record and not current_user_record.is_superuser: + aggregations_list.remove('organisation') + + # Remove collection in collection context + if collection: + aggregations_list.remove('collection') + + # Custom fields + if view and view != current_app.config.get( + 'SONAR_APP_DEFAULT_ORGANISATION'): + organisation = OrganisationRecord.get_record_by_pid(view) + else: + organisation = current_organisation + + for i in range(1, 4): + # Remove custom fields if we are in global view, or the fields is not + # configured in organisation. + if view == current_app.config.get( + 'SONAR_APP_DEFAULT_ORGANISATION' + ) or not organisation or not organisation.get( + f'documentsCustomField{i}', {}).get('includeInFacets'): + aggregations_list.remove(f'customField{i}') + else: + # Add the right label + if organisation[f'documentsCustomField{i}'].get('label'): + aggregations_list[aggregations_list.index( + f'customField{i}')] = { + 'key': + f'customField{1}', + 'name': + get_language_value( + organisation[f'documentsCustomField{i}']['label']) + } + + return jsonify(aggregations_list) diff --git a/sonar/modules/documents/serializers/__init__.py b/sonar/modules/documents/serializers/__init__.py index 347a74ce5..727f6efd5 100644 --- a/sonar/modules/documents/serializers/__init__.py +++ b/sonar/modules/documents/serializers/__init__.py @@ -35,11 +35,9 @@ from sonar.modules.documents.serializers.schemas.google_scholar import \ GoogleScholarV1 from sonar.modules.documents.serializers.schemas.schemaorg import SchemaOrgV1 -from sonar.modules.organisations.api import OrganisationRecord, \ - current_organisation +from sonar.modules.organisations.api import OrganisationRecord from sonar.modules.serializers import JSONSerializer as _JSONSerializer from sonar.modules.users.api import current_user_record -from sonar.modules.utils import get_language_value from ..marshmallow import DocumentSchemaV1 @@ -51,14 +49,6 @@ def post_process_serialize_search(self, results, pid_fetcher): """Post process the search results.""" view = request.args.get('view') - if view: - if view != current_app.config.get( - 'SONAR_APP_DEFAULT_ORGANISATION'): - results['aggregations'].pop('organisation', {}) - else: - if current_user_record and not current_user_record.is_superuser: - results['aggregations'].pop('organisation', {}) - if results['aggregations'].get('year'): results['aggregations']['year']['type'] = 'range' results['aggregations']['year']['config'] = { @@ -76,32 +66,6 @@ def post_process_serialize_search(self, results, pid_fetcher): if organisation: org_term['name'] = organisation['name'] - # Process facets for custom fields - if view and view != current_app.config.get( - 'SONAR_APP_DEFAULT_ORGANISATION'): - organisation = OrganisationRecord.get_record_by_pid(view) - else: - organisation = current_organisation - - for i in range(1, 4): - if results.get('aggregations').get(f'customField{i}'): - # The facet is displayed only in dedicated view. - if view == current_app.config.get( - 'SONAR_APP_DEFAULT_ORGANISATION' - ) or not organisation or not organisation.get( - f'documentsCustomField{i}', {}).get('includeInFacets'): - results['aggregations'].pop(f'customField{i}', None) - else: - if organisation[f'documentsCustomField{i}'].get('label'): - results['aggregations'][f'customField{i}'][ - 'name'] = get_language_value( - organisation[f'documentsCustomField{i}'] - ['label']) - - # Dont display collection aggregation in the collection context - if request.args.get('collection_view'): - results['aggregations'].pop('collection', None) - # Add collection name for org_term in results.get('aggregations', {}).get('collection', diff --git a/tests/api/documents/test_documents_permissions.py b/tests/api/documents/test_documents_permissions.py index 5eb681765..2c1b091ca 100644 --- a/tests/api/documents/test_documents_permissions.py +++ b/tests/api/documents/test_documents_permissions.py @@ -56,36 +56,28 @@ def test_list(app, client, make_document, superuser, admin, moderator, res = client.get(url_for('invenio_records_rest.doc_list')) assert res.status_code == 200 assert res.json['hits']['total']['value'] == 1 - assert not res.json['aggregations'].get('organisation') # Logged as admin login_user_via_session(client, email=admin['email']) res = client.get(url_for('invenio_records_rest.doc_list')) assert res.status_code == 200 assert res.json['hits']['total']['value'] == 1 - assert res.json['aggregations']['customField1']['name'] == 'Test' - assert not res.json['aggregations'].get('organisation') # Logged as superuser login_user_via_session(client, email=superuser['email']) res = client.get(url_for('invenio_records_rest.doc_list')) assert res.status_code == 200 assert res.json['hits']['total']['value'] == 2 - assert res.json['aggregations'].get('organisation') # Public search res = client.get(url_for('invenio_records_rest.doc_list', view='global')) assert res.status_code == 200 assert res.json['hits']['total']['value'] == 2 - assert not res.json['aggregations'].get('customField1') - assert res.json['aggregations'].get('organisation') # Public search for organisation res = client.get(url_for('invenio_records_rest.doc_list', view='org')) assert res.status_code == 200 assert res.json['hits']['total']['value'] == 1 - assert res.json['aggregations']['customField1']['name'] == 'Test' - assert not res.json['aggregations'].get('organisation') def test_create(client, document_json, superuser, admin, moderator, submitter, diff --git a/tests/api/documents/test_documents_query.py b/tests/api/documents/test_documents_query.py index 0203e04b4..695be4f78 100644 --- a/tests/api/documents/test_documents_query.py +++ b/tests/api/documents/test_documents_query.py @@ -35,7 +35,6 @@ def test_collection_query(db, client, document, collection, es_clear): collection_view=collection['pid'])) assert res.status_code == 200 assert res.json['hits']['total']['value'] == 1 - assert not res.json['aggregations'].get('collection') def test_masked_document(db, client, document, es_clear): diff --git a/tests/api/documents/test_documents_rest.py b/tests/api/documents/test_documents_rest.py index cb57e78f8..edb392c9e 100644 --- a/tests/api/documents/test_documents_rest.py +++ b/tests/api/documents/test_documents_rest.py @@ -20,6 +20,7 @@ import json from flask import url_for +from invenio_accounts.testutils import login_user_via_session def test_put(app, client, document_with_file): @@ -39,3 +40,49 @@ def test_put(app, client, document_with_file): headers=headers, data=json.dumps(response.json['metadata'])) assert response.status_code == 200 + + +def test_aggregations(app, client, document, superuser, admin): + """Test aggregations.""" + # No context + res = client.get(url_for('documents.aggregations')) + assert res.json == [ + 'document_type', 'controlled_affiliation', 'year', 'collection', + 'language', 'author', 'subject', 'organisation', 'sections' + ] + + # Collection view + res = client.get(url_for('documents.aggregations', collection='coll')) + assert res.json == [ + 'document_type', 'controlled_affiliation', 'year', 'language', + 'author', 'subject', 'organisation', 'sections' + ] + + # Dedicated view + res = client.get(url_for('documents.aggregations', view='rero')) + assert res.json == [ + 'document_type', 'controlled_affiliation', 'year', 'collection', + 'language', 'author', 'subject', 'sections' + ] + + # Logged as superuser + login_user_via_session(client, email=superuser['email']) + res = client.get(url_for('documents.aggregations')) + assert res.json == [ + 'document_type', 'controlled_affiliation', 'year', 'collection', + 'language', 'author', 'subject', 'organisation', 'sections', { + 'key': 'customField1', + 'name': 'Test' + } + ] + + # Logged as admin + login_user_via_session(client, email=admin['email']) + res = client.get(url_for('documents.aggregations')) + assert res.json == [ + 'document_type', 'controlled_affiliation', 'year', 'collection', + 'language', 'author', 'subject', 'sections', { + 'key': 'customField1', + 'name': 'Test' + } + ]