Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

search: aggregations order endpoint #624

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
'translations = sonar.translations.rest:blueprint',
'suggestions = sonar.suggestions.rest:blueprint',
'validation = sonar.modules.validation.views:blueprint',
'documents = sonar.modules.documents.rest:blueprint',
'swisscovery = sonar.modules.swisscovery.rest:blueprint'
],
'invenio_assets.webpack': [
Expand Down
96 changes: 96 additions & 0 deletions sonar/modules/documents/rest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# -*- 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 <http://www.gnu.org/licenses/>.

"""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',
'subdivision',
'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'])
}

# Don't display subdivision in global context
if view and view == current_app.config.get(
'SONAR_APP_DEFAULT_ORGANISATION'):
aggregations_list.remove('subdivision')

return jsonify(aggregations_list)
42 changes: 1 addition & 41 deletions sonar/modules/documents/serializers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@
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.subdivisions.api import Record as SubdivisionRecord
from sonar.modules.users.api import current_user_record
Expand All @@ -52,14 +51,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'] = {
Expand All @@ -77,32 +68,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',
Expand All @@ -111,11 +76,6 @@ def post_process_serialize_search(self, results, pid_fetcher):
if collection:
org_term['name'] = get_language_value(collection['name'])

# Don't display subdivision in global context
if view and view == current_app.config.get(
'SONAR_APP_DEFAULT_ORGANISATION'):
results['aggregations'].pop('subdivision', {})

return super(JSONSerializer,
self).post_process_serialize_search(results, pid_fetcher)

Expand Down
8 changes: 0 additions & 8 deletions tests/api/documents/test_documents_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 0 additions & 1 deletion tests/api/documents/test_documents_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, organisation, document, es_clear):
Expand Down
54 changes: 54 additions & 0 deletions tests/api/documents/test_documents_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -39,3 +40,56 @@ 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', 'subdivision'
]

# Collection view
res = client.get(url_for('documents.aggregations', collection='coll'))
assert res.json == [
'document_type', 'controlled_affiliation', 'year', 'language',
'author', 'subject', 'organisation', 'subdivision'
]

# Dedicated view
res = client.get(url_for('documents.aggregations', view='rero'))
assert res.json == [
'document_type', 'controlled_affiliation', 'year', 'collection',
'language', 'author', 'subject', 'subdivision'
]

# Global view
res = client.get(url_for('documents.aggregations', view='global'))
assert res.json == [
'document_type', 'controlled_affiliation', 'year', 'collection',
'language', 'author', 'subject', 'organisation'
]

# 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', 'subdivision', {
'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', 'subdivision', {
'key': 'customField1',
'name': 'Test'
}
]
6 changes: 0 additions & 6 deletions tests/api/subdivisions/test_subdivisions_documents_facets.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,3 @@ def test_list(app, db, client, document, subdivision, superuser):
'name':
'Subdivision name'
}]

# Don't display aggregation in global context
res = client.get(url_for('invenio_records_rest.doc_list', view='global'))
assert res.status_code == 200
assert res.json['hits']['total']['value'] == 1
assert 'subdivision' not in res.json['aggregations']