Skip to content
Merged
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
20 changes: 20 additions & 0 deletions data/collections.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@
"collection_id": "Expo 1",
"title": "Expo \u2013 The Number 1",
"collection_type": "exhibition",
"libraries": [
{
"$ref": "https://bib.rero.ch/api/libraries/2"
}
],
"description": "List of items for the exhibition",
"start_date": "2020-10-01",
"end_date": "2021-06-30",
Expand Down Expand Up @@ -124,6 +129,11 @@
"collection_id": "Expo 2",
"title": "Expo \u2013 The Number 2",
"collection_type": "exhibition",
"libraries": [
{
"$ref": "https://bib.rero.ch/api/libraries/5"
}
],
"description": "List of items for the exhibition",
"start_date": "2020-10-01",
"end_date": "2021-06-30",
Expand Down Expand Up @@ -180,6 +190,11 @@
"collection_id": "Expo 3",
"title": "Expo \u2013 The Number 3",
"collection_type": "exhibition",
"libraries": [
{
"$ref": "https://bib.rero.ch/api/libraries/5"
}
],
"description": "List of items for the exhibition",
"start_date": "2020-10-01",
"end_date": "2021-06-30",
Expand Down Expand Up @@ -236,6 +251,11 @@
"collection_id": "Expo 4",
"title": "Expo \u2013 The Number 4",
"collection_type": "exhibition",
"libraries": [
{
"$ref": "https://bib.rero.ch/api/libraries/5"
}
],
"description": "List of items for the exhibition",
"start_date": "2020-10-01",
"end_date": "2021-12-31",
Expand Down
25 changes: 24 additions & 1 deletion rero_ils/modules/collections/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
from datetime import datetime, timezone
from functools import partial

from rero_ils.modules.items.api import Item
from flask_babel import gettext as _

from rero_ils.modules.items.api import Item, ItemsSearch

from ..api import IlsRecord, IlsRecordsIndexer, IlsRecordsSearch
from ..fetchers import id_fetcher
Expand Down Expand Up @@ -79,6 +81,27 @@ class Collection(IlsRecord):
}
}

def extended_validation(self, **kwargs):
"""Add additional record validation.

:return: Validation message if
- an item does not belong to selected libraries.
"""
library_pids = []
for library in self.get("libraries", []):
library_pids.append(extracted_data_from_ref(library))

for item in self.get("items", []):
query = (
ItemsSearch()
.filter("term", pid=extracted_data_from_ref(item))
.filter("terms", library__pid=library_pids)
.count()
)
if query < 1:
return _("All items should belong to one of the selected libraries.")
return True

def get_items(self):
"""Get items.

Expand Down
14 changes: 7 additions & 7 deletions rero_ils/modules/collections/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@
@with_appcontext
def create_collections(input_file, max_item=10):
"""Create collections."""
organisation_items = {}
with open(input_file, encoding="utf-8") as request_file:
collections = json.load(request_file)
for collection_data in collections:
organisation_pid = extracted_data_from_ref(collection_data.get("organisation").get("$ref"))
if organisation_pid not in organisation_items:
organisation_items[organisation_pid] = get_items_by_organisation_pid(organisation_pid)
items = random.choices(organisation_items[organisation_pid], k=random.randint(1, max_item))
libraries_pids = [
extracted_data_from_ref(library.get("$ref")) for library in collection_data.get("libraries")
]
eligible_items = get_items_by_libraries_pid(libraries_pids)
items = random.choices(eligible_items, k=random.randint(1, max_item))
collection_data["items"] = []
for item_pid in items:
ref = get_ref_for_pid("items", item_pid)
Expand All @@ -49,7 +49,7 @@ def create_collections(input_file, max_item=10):
click.echo(f"\tCollection: #{request.pid}")


def get_items_by_organisation_pid(organisation_pid):
def get_items_by_libraries_pid(libraries_pids):
"""Get items by organisation pid."""
query = ItemsSearch().filter("term", organisation__pid=organisation_pid).source("pid")
query = ItemsSearch().filter("terms", library__pid=libraries_pids).source("pid")
return [item.pid for item in query.scan()]
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"start_date",
"end_date",
"organisation",
"libraries",
"published"
],
"propertiesOrder": [
Expand Down
20 changes: 20 additions & 0 deletions tests/api/collections/test_collections_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

"""Test item collections."""

import pytest
from jsonschema.exceptions import ValidationError


def test_get_items(item_lib_martigny, item2_lib_martigny, coll_martigny_1):
"""Test get items for a collection"""
Expand All @@ -31,3 +34,20 @@ def test_get_items(item_lib_martigny, item2_lib_martigny, coll_martigny_1):
def test_get_libraries(coll_martigny_1, lib_martigny):
"""Test get library pids for a collection."""
assert coll_martigny_1.library_pids[0] == lib_martigny["pid"]


def test_collections_extended_validation(lib_fully, item_lib_fully, coll_martigny_1):
"""Test that all items in the collection belong to a selected library."""
# check that there is no validation error with items from martigny library
assert coll_martigny_1.update(coll_martigny_1)

coll_martigny_1["items"].append({"$ref": "https://bib.rero.ch/api/items/item3"})
with pytest.raises(ValidationError) as err:
coll_martigny_1.update(coll_martigny_1, dbcommit=True, reindex=True)
assert "items should belong to one of the selected libraries" in str(err)

# add fully library to the collection
coll_martigny_1["libraries"].append({"$ref": "https://bib.rero.ch/api/libraries/lib3"})

# check that now the collection can be saved
assert coll_martigny_1.update(coll_martigny_1)
2 changes: 1 addition & 1 deletion tests/api/collections/test_collections_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def test_collections_permissions(
)
check_permission(
CollectionPermissionPolicy,
{"search": True, "read": True, "create": True, "update": True, "delete": True},
{"search": True, "read": True, "create": False, "update": False, "delete": False},
coll_saxon_1,
)
check_permission(
Expand Down
9 changes: 7 additions & 2 deletions tests/data/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -5180,6 +5180,11 @@
"name": "Pr. Smith, Will"
}
],
"libraries": [
{
"$ref": "https://bib.rero.ch/api/libraries/lib2"
}
],
"description": "List of items for course 1",
"subjects": [
{
Expand All @@ -5193,10 +5198,10 @@
},
"items": [
{
"$ref": "https://bib.rero.ch/api/items/item1"
"$ref": "https://bib.rero.ch/api/items/item2"
},
{
"$ref": "https://bib.rero.ch/api/items/item5"
"$ref": "https://bib.rero.ch/api/items/item9"
}
],
"published": true
Expand Down
4 changes: 2 additions & 2 deletions tests/fixtures/organisations.py
Original file line number Diff line number Diff line change
Expand Up @@ -908,8 +908,8 @@ def coll_saxon_1(
org_martigny,
lib_saxon,
coll_saxon_1_data,
item2_lib_martigny,
item_lib_martigny,
item2_lib_saxon,
item_lib_saxon,
):
"""Create collection Saxon 1."""
coll = Collection.create(data=coll_saxon_1_data, delete_pid=False, dbcommit=True, reindex=True)
Expand Down
7 changes: 0 additions & 7 deletions tests/ui/collections/test_collections_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@
from flask import url_for


def test_collection_detailed_view_without_library(client, coll_saxon_1):
"""Test collection detailed view."""
# check redirection
res = client.get(url_for("invenio_records_ui.coll", viewcode="org1", pid_value=coll_saxon_1.pid))
assert res.status_code == 200


def test_collection_detailed_view(client, coll_martigny_1):
"""Test collection detailed view."""
# check redirection
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/collections/test_collections_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def test_get_teachers(db, coll_martigny_1_data):
assert get_teachers(coll_martigny_1_data) == result


def test_start_end_date(db, coll_martigny_1_data):
def test_start_end_date(db, coll_martigny_1_data, item_lib_martigny, item2_lib_martigny):
"""Test date format."""
result = "01/09/2020 - 31/12/2020"
coll = Collection.create(coll_martigny_1_data, delete_pid=True)
Expand Down