invenio-app-ils 4.6.0__py2.py3-none-any.whl → 5.0.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- invenio_app_ils/__init__.py +1 -1
- invenio_app_ils/assets/semantic-ui/less/theme.config +103 -0
- invenio_app_ils/circulation/api.py +9 -5
- invenio_app_ils/circulation/config.py +1 -0
- invenio_app_ils/circulation/loaders/schemas/json/loan_checkout.py +1 -1
- invenio_app_ils/circulation/loaders/schemas/json/loan_request.py +2 -2
- invenio_app_ils/circulation/notifications/api.py +9 -1
- invenio_app_ils/circulation/notifications/messages.py +2 -1
- invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/update_dates.html +19 -0
- invenio_app_ils/cli.py +92 -64
- invenio_app_ils/config.py +10 -2
- invenio_app_ils/documents/loaders/jsonschemas/document.py +1 -1
- invenio_app_ils/eitems/loaders/jsonschemas/eitems.py +2 -2
- invenio_app_ils/patrons/anonymization.py +0 -4
- invenio_app_ils/series/loaders/jsonschemas/series.py +1 -1
- invenio_app_ils/webpack.py +27 -0
- {invenio_app_ils-4.6.0.dist-info → invenio_app_ils-5.0.0.dist-info}/METADATA +52 -42
- {invenio_app_ils-4.6.0.dist-info → invenio_app_ils-5.0.0.dist-info}/RECORD +24 -112
- {invenio_app_ils-4.6.0.dist-info → invenio_app_ils-5.0.0.dist-info}/entry_points.txt +3 -0
- {invenio_app_ils-4.6.0.dist-info → invenio_app_ils-5.0.0.dist-info}/top_level.txt +0 -1
- invenio_app_ils/notifications/admin.py +0 -57
- tests/__init__.py +0 -8
- tests/api/__init__.py +0 -8
- tests/api/acquisition/__init__.py +0 -8
- tests/api/acquisition/test_acq_orders_crud.py +0 -99
- tests/api/acquisition/test_acq_orders_permissions.py +0 -104
- tests/api/acquisition/test_acq_providers_permissions.py +0 -83
- tests/api/circulation/__init__.py +0 -8
- tests/api/circulation/test_expired_loans.py +0 -88
- tests/api/circulation/test_loan_bulk_extend.py +0 -169
- tests/api/circulation/test_loan_checkout.py +0 -422
- tests/api/circulation/test_loan_default_durations.py +0 -43
- tests/api/circulation/test_loan_document_resolver.py +0 -18
- tests/api/circulation/test_loan_extend.py +0 -122
- tests/api/circulation/test_loan_item_permissions.py +0 -135
- tests/api/circulation/test_loan_item_resolver.py +0 -26
- tests/api/circulation/test_loan_list_permissions.py +0 -98
- tests/api/circulation/test_loan_patron_resolver.py +0 -38
- tests/api/circulation/test_loan_request.py +0 -338
- tests/api/circulation/test_loan_update.py +0 -150
- tests/api/circulation/test_notifications.py +0 -221
- tests/api/conftest.py +0 -227
- tests/api/document_requests/__init__.py +0 -8
- tests/api/document_requests/test_document_requests.py +0 -131
- tests/api/document_requests/test_document_requests_permissions.py +0 -159
- tests/api/document_requests/test_notifications_filter.py +0 -35
- tests/api/ill/__init__.py +0 -8
- tests/api/ill/test_ill_brw_crud.py +0 -74
- tests/api/ill/test_ill_brw_reqs_patron_loan_create_action.py +0 -198
- tests/api/ill/test_ill_brw_reqs_patron_loan_extension_actions.py +0 -280
- tests/api/ill/test_ill_brw_reqs_permissions.py +0 -163
- tests/api/ill/test_ill_providers_permissions.py +0 -82
- tests/api/ils/__init__.py +0 -8
- tests/api/ils/documents/__init__.py +0 -8
- tests/api/ils/documents/test_document_crud.py +0 -57
- tests/api/ils/documents/test_document_permissions.py +0 -100
- tests/api/ils/documents/test_document_resolvers.py +0 -35
- tests/api/ils/eitems/__init__.py +0 -8
- tests/api/ils/eitems/test_eitems_crud.py +0 -42
- tests/api/ils/eitems/test_eitems_permissions.py +0 -85
- tests/api/ils/eitems/test_files.py +0 -162
- tests/api/ils/items/__init__.py +0 -8
- tests/api/ils/items/test_apis.py +0 -43
- tests/api/ils/items/test_items_crud.py +0 -99
- tests/api/ils/items/test_items_permissions.py +0 -107
- tests/api/ils/records_relations/__init__.py +0 -8
- tests/api/ils/records_relations/helpers.py +0 -115
- tests/api/ils/records_relations/test_records_relations_parentchild.py +0 -560
- tests/api/ils/records_relations/test_records_relations_sequence.py +0 -294
- tests/api/ils/records_relations/test_records_relations_siblings.py +0 -751
- tests/api/ils/series/__init__.py +0 -8
- tests/api/ils/series/test_series_permissions.py +0 -95
- tests/api/ils/test_anonymization.py +0 -181
- tests/api/ils/test_apis.py +0 -76
- tests/api/ils/test_closures.py +0 -353
- tests/api/ils/test_errors.py +0 -125
- tests/api/ils/test_facets.py +0 -88
- tests/api/ils/test_internal_locations.py +0 -96
- tests/api/ils/test_loaders.py +0 -51
- tests/api/ils/test_metadata_extensions.py +0 -206
- tests/api/ils/test_notifications.py +0 -173
- tests/api/ils/test_notifications_mails.py +0 -37
- tests/api/ils/test_notifications_permissions.py +0 -55
- tests/api/ils/test_patrons.py +0 -102
- tests/api/ils/test_record_delete.py +0 -42
- tests/api/ils/test_record_permissions.py +0 -132
- tests/api/ils/test_resolvers.py +0 -205
- tests/api/ils/test_stats.py +0 -142
- tests/api/ils/test_tasks.py +0 -209
- tests/api/ils/test_vocabularies.py +0 -35
- tests/conftest.py +0 -221
- tests/data/acq_orders.json +0 -110
- tests/data/acq_providers.json +0 -12
- tests/data/document_requests.json +0 -77
- tests/data/documents.json +0 -238
- tests/data/eitems.json +0 -71
- tests/data/ill_borrowing_requests.json +0 -77
- tests/data/ill_providers.json +0 -12
- tests/data/internal_locations.json +0 -22
- tests/data/items.json +0 -304
- tests/data/loans.json +0 -133
- tests/data/loans_most_loaned.json +0 -128
- tests/data/locations.json +0 -26
- tests/data/series.json +0 -33
- tests/helpers.py +0 -107
- tests/templates/notifications/title_body.html +0 -8
- tests/templates/notifications/title_body_html.html +0 -13
- tests/templates/notifications/title_body_html_ctx.html +0 -13
- tests/templates/notifications/title_only.html +0 -3
- tests/test_post_logout_redirect.py +0 -23
- tests/test_version.py +0 -17
- /tests/templates/notifications/blank.html → /invenio_app_ils/assets/semantic-ui/templates/.gitkeep +0 -0
- {invenio_app_ils-4.6.0.dist-info → invenio_app_ils-5.0.0.dist-info}/WHEEL +0 -0
- {invenio_app_ils-4.6.0.dist-info → invenio_app_ils-5.0.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {invenio_app_ils-4.6.0.dist-info → invenio_app_ils-5.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2020 CERN.
|
|
4
|
-
#
|
|
5
|
-
# Invenio-Circulation is free software; you can redistribute it and/or modify
|
|
6
|
-
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Tests documents REST APIs permissions."""
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
|
|
12
|
-
from flask import url_for
|
|
13
|
-
from invenio_db import db
|
|
14
|
-
from invenio_indexer.api import RecordIndexer
|
|
15
|
-
from invenio_search import current_search
|
|
16
|
-
|
|
17
|
-
from invenio_app_ils.documents.api import Document
|
|
18
|
-
from tests.helpers import user_login
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def test_open_access_permissions(client, json_headers, testdata, users):
|
|
22
|
-
"""Test GET open/close access documents."""
|
|
23
|
-
# set the documents to have read access only by patron2. `_access` should
|
|
24
|
-
# be totally ignored.
|
|
25
|
-
indexer = RecordIndexer()
|
|
26
|
-
doc1 = Document.get_record_by_pid("docid-open-access")
|
|
27
|
-
doc2 = Document.get_record_by_pid("docid-closed-access")
|
|
28
|
-
for doc in [doc1, doc2]:
|
|
29
|
-
doc.update(dict(_access=dict(read=["patron2"])))
|
|
30
|
-
doc.commit()
|
|
31
|
-
db.session.commit()
|
|
32
|
-
indexer.index(doc)
|
|
33
|
-
current_search.flush_and_refresh(index="documents")
|
|
34
|
-
|
|
35
|
-
test_data = [
|
|
36
|
-
("anonymous", "docid-open-access", 200, 1),
|
|
37
|
-
("patron1", "docid-open-access", 200, 1),
|
|
38
|
-
("patron2", "docid-open-access", 200, 1),
|
|
39
|
-
("librarian", "docid-open-access", 200, 1),
|
|
40
|
-
("admin", "docid-open-access", 200, 1),
|
|
41
|
-
("anonymous", "docid-closed-access", 401, 0),
|
|
42
|
-
("patron1", "docid-closed-access", 403, 0),
|
|
43
|
-
("patron2", "docid-closed-access", 403, 0),
|
|
44
|
-
("librarian", "docid-closed-access", 200, 1),
|
|
45
|
-
("admin", "docid-closed-access", 200, 1),
|
|
46
|
-
]
|
|
47
|
-
for user, pid, status_code, n_hits in test_data:
|
|
48
|
-
# item endpoint
|
|
49
|
-
user_login(client, user, users)
|
|
50
|
-
url = url_for("invenio_records_rest.docid_item", pid_value=pid)
|
|
51
|
-
res = client.get(url, headers=json_headers)
|
|
52
|
-
assert res.status_code == status_code
|
|
53
|
-
|
|
54
|
-
# list endpoint
|
|
55
|
-
user_login(client, user, users)
|
|
56
|
-
url = url_for("invenio_records_rest.docid_list", q="pid:{}".format(pid))
|
|
57
|
-
res = client.get(url, headers=json_headers)
|
|
58
|
-
hits = json.loads(res.data.decode("utf-8"))
|
|
59
|
-
assert hits["hits"]["total"] == n_hits
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def test_access_permissions(client, json_headers, testdata, users, with_access):
|
|
63
|
-
"""Test GET documents with `_access` ignoring `restricted`."""
|
|
64
|
-
# set the documents to have read access only by patron2. `_access` should
|
|
65
|
-
# be taken into account and take precedence over `restricted`.
|
|
66
|
-
indexer = RecordIndexer()
|
|
67
|
-
doc1 = Document.get_record_by_pid("docid-open-access")
|
|
68
|
-
doc2 = Document.get_record_by_pid("docid-closed-access")
|
|
69
|
-
for doc in [doc1, doc2]:
|
|
70
|
-
doc.update(dict(_access=dict(read=[users["patron2"].id])))
|
|
71
|
-
doc.commit()
|
|
72
|
-
db.session.commit()
|
|
73
|
-
indexer.index(doc)
|
|
74
|
-
current_search.flush_and_refresh(index="documents")
|
|
75
|
-
|
|
76
|
-
test_data = [
|
|
77
|
-
("anonymous", "docid-open-access", 401, 0),
|
|
78
|
-
("patron1", "docid-open-access", 403, 0),
|
|
79
|
-
("patron2", "docid-open-access", 200, 1), # should have access
|
|
80
|
-
("librarian", "docid-open-access", 200, 1),
|
|
81
|
-
("admin", "docid-open-access", 200, 1),
|
|
82
|
-
("anonymous", "docid-closed-access", 401, 0),
|
|
83
|
-
("patron1", "docid-closed-access", 403, 0),
|
|
84
|
-
("patron2", "docid-closed-access", 200, 1), # should have access
|
|
85
|
-
("librarian", "docid-closed-access", 200, 1),
|
|
86
|
-
("admin", "docid-closed-access", 200, 1),
|
|
87
|
-
]
|
|
88
|
-
for user, pid, status_code, n_hits in test_data:
|
|
89
|
-
# item endpoint
|
|
90
|
-
user_login(client, user, users)
|
|
91
|
-
url = url_for("invenio_records_rest.docid_item", pid_value=pid)
|
|
92
|
-
res = client.get(url, headers=json_headers)
|
|
93
|
-
assert res.status_code == status_code
|
|
94
|
-
|
|
95
|
-
# list endpoint
|
|
96
|
-
user_login(client, user, users)
|
|
97
|
-
url = url_for("invenio_records_rest.docid_list", q="pid:{}".format(pid))
|
|
98
|
-
res = client.get(url, headers=json_headers)
|
|
99
|
-
hits = json.loads(res.data.decode("utf-8"))
|
|
100
|
-
assert hits["hits"]["total"] == n_hits
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2019 CERN.
|
|
4
|
-
#
|
|
5
|
-
# Invenio-Circulation is free software; you can redistribute it and/or modify
|
|
6
|
-
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Tests for document resolvers."""
|
|
9
|
-
|
|
10
|
-
from invenio_app_ils.documents.api import Document
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def test_document_resolvers(app, testdata):
|
|
14
|
-
"""Test item resolving from loan."""
|
|
15
|
-
doc_pid = testdata["documents"][0]["pid"]
|
|
16
|
-
document = Document.get_record_by_pid(doc_pid)
|
|
17
|
-
document = document.replace_refs()
|
|
18
|
-
|
|
19
|
-
# relations
|
|
20
|
-
assert "relations" in document
|
|
21
|
-
|
|
22
|
-
# circulation
|
|
23
|
-
assert "active_loans_count" in document["circulation"]
|
|
24
|
-
assert "pending_loans_count" in document["circulation"]
|
|
25
|
-
assert "overdue_loans_count" in document["circulation"]
|
|
26
|
-
assert "past_loans_count" in document["circulation"]
|
|
27
|
-
|
|
28
|
-
# item and eitems
|
|
29
|
-
assert document["items"]["total"] == 9 and document["items"]["hits"]
|
|
30
|
-
assert document["eitems"]["total"] == 3 and document["eitems"]["hits"]
|
|
31
|
-
|
|
32
|
-
# stock
|
|
33
|
-
mediums = set([item["medium"] for item in document["items"]["hits"]])
|
|
34
|
-
mediums.add("E-BOOK")
|
|
35
|
-
assert set(document["stock"]["mediums"]) == mediums
|
tests/api/ils/eitems/__init__.py
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2021 CERN.
|
|
4
|
-
#
|
|
5
|
-
# Invenio-Circulation is free software; you can redistribute it and/or modify
|
|
6
|
-
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Tests eitems CRUD."""
|
|
9
|
-
|
|
10
|
-
import pytest
|
|
11
|
-
|
|
12
|
-
from invenio_app_ils.eitems.api import EItem
|
|
13
|
-
from invenio_app_ils.errors import DocumentNotFoundError
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def test_eitem_refs(app, testdata):
|
|
17
|
-
"""Test creation of an eitem."""
|
|
18
|
-
eitem = EItem.create(
|
|
19
|
-
dict(
|
|
20
|
-
pid="eitemid-99",
|
|
21
|
-
eitem_type="E-BOOK",
|
|
22
|
-
document_pid="docid-1",
|
|
23
|
-
created_by=dict(type="script", value="demo"),
|
|
24
|
-
)
|
|
25
|
-
)
|
|
26
|
-
assert "$schema" in eitem
|
|
27
|
-
assert "document" in eitem and "$ref" in eitem["document"]
|
|
28
|
-
|
|
29
|
-
eitem = EItem.get_record_by_pid("eitemid-4")
|
|
30
|
-
eitem = eitem.replace_refs()
|
|
31
|
-
assert "document" in eitem and eitem["document"]["title"]
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def test_eitem_validation(db, testdata):
|
|
35
|
-
"""Test validation when updating an eitem."""
|
|
36
|
-
eitem_pid = testdata["eitems"][0]["pid"]
|
|
37
|
-
eitem = EItem.get_record_by_pid(eitem_pid)
|
|
38
|
-
|
|
39
|
-
# change document pid
|
|
40
|
-
eitem["document_pid"] = "not_found_doc"
|
|
41
|
-
with pytest.raises(DocumentNotFoundError):
|
|
42
|
-
eitem.commit()
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2020 CERN.
|
|
4
|
-
#
|
|
5
|
-
# invenio-app-ils is free software; you can redistribute it and/or modify it
|
|
6
|
-
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Test Eitems permissions."""
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
|
|
12
|
-
from flask import url_for
|
|
13
|
-
|
|
14
|
-
from tests.helpers import user_login
|
|
15
|
-
|
|
16
|
-
_HTTP_OK = [200, 201, 204]
|
|
17
|
-
EITEM_PID = "eitemid-1"
|
|
18
|
-
ITEM_ENDPOINT = "invenio_records_rest.eitmid_item"
|
|
19
|
-
LIST_ENDPOINT = "invenio_records_rest.eitmid_list"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def test_eitems_permissions(client, testdata, json_headers, users):
|
|
23
|
-
"""Test eitems endpoints permissions."""
|
|
24
|
-
dummy_eitem = dict(
|
|
25
|
-
document_pid="docid-1",
|
|
26
|
-
eitem_type="E-BOOK",
|
|
27
|
-
internal_notes="An internal note",
|
|
28
|
-
description="Description of the electronic item",
|
|
29
|
-
open_access=True,
|
|
30
|
-
)
|
|
31
|
-
tests = [
|
|
32
|
-
("admin", _HTTP_OK, dummy_eitem),
|
|
33
|
-
("librarian", _HTTP_OK, dummy_eitem),
|
|
34
|
-
("patron1", [403], dummy_eitem),
|
|
35
|
-
("anonymous", [401], dummy_eitem),
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
def _test_list(expected_status):
|
|
39
|
-
"""Test get list."""
|
|
40
|
-
url = url_for(LIST_ENDPOINT)
|
|
41
|
-
res = client.get(url, headers=json_headers)
|
|
42
|
-
assert res.status_code in expected_status
|
|
43
|
-
|
|
44
|
-
def _test_create(expected_status, data):
|
|
45
|
-
"""Test record creation."""
|
|
46
|
-
url = url_for(LIST_ENDPOINT)
|
|
47
|
-
res = client.post(url, headers=json_headers, data=json.dumps(data))
|
|
48
|
-
assert res.status_code in expected_status
|
|
49
|
-
|
|
50
|
-
if res.status_code < 400:
|
|
51
|
-
record = res.get_json()["metadata"]
|
|
52
|
-
assert record
|
|
53
|
-
return record["pid"]
|
|
54
|
-
|
|
55
|
-
def _test_update(expected_status, data, pid):
|
|
56
|
-
"""Test record update."""
|
|
57
|
-
pid_value = pid or EITEM_PID
|
|
58
|
-
url = url_for(ITEM_ENDPOINT, pid_value=pid_value)
|
|
59
|
-
res = client.put(url, headers=json_headers, data=json.dumps(data))
|
|
60
|
-
assert res.status_code in expected_status
|
|
61
|
-
if res.status_code < 400:
|
|
62
|
-
record = res.get_json()["metadata"]
|
|
63
|
-
assert record
|
|
64
|
-
|
|
65
|
-
def _test_read(expected_status, pid):
|
|
66
|
-
"""Test record read."""
|
|
67
|
-
pid_value = pid or EITEM_PID
|
|
68
|
-
url = url_for(ITEM_ENDPOINT, pid_value=pid_value)
|
|
69
|
-
res = client.get(url, headers=json_headers)
|
|
70
|
-
assert res.status_code in expected_status
|
|
71
|
-
|
|
72
|
-
def _test_delete(expected_status, pid):
|
|
73
|
-
"""Test record delete."""
|
|
74
|
-
pid_value = pid or EITEM_PID
|
|
75
|
-
url = url_for(ITEM_ENDPOINT, pid_value=pid_value)
|
|
76
|
-
res = client.delete(url, headers=json_headers)
|
|
77
|
-
assert res.status_code in expected_status
|
|
78
|
-
|
|
79
|
-
for username, expected_status, data in tests:
|
|
80
|
-
user_login(client, username, users)
|
|
81
|
-
_test_list(expected_status)
|
|
82
|
-
pid = _test_create(expected_status, data)
|
|
83
|
-
_test_update(expected_status, data, pid)
|
|
84
|
-
_test_read(expected_status, pid)
|
|
85
|
-
_test_delete(expected_status, pid)
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2019 CERN.
|
|
4
|
-
#
|
|
5
|
-
# invenio-app-ils is free software; you can redistribute it and/or modify it
|
|
6
|
-
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Test files."""
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
|
|
12
|
-
from flask import url_for
|
|
13
|
-
from invenio_search import current_search
|
|
14
|
-
from six import BytesIO
|
|
15
|
-
|
|
16
|
-
from tests.helpers import user_login
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def _test_response(
|
|
20
|
-
client,
|
|
21
|
-
req_method,
|
|
22
|
-
url,
|
|
23
|
-
headers,
|
|
24
|
-
data,
|
|
25
|
-
expected_resp_code,
|
|
26
|
-
input_stream=None,
|
|
27
|
-
):
|
|
28
|
-
"""Util function testing response code."""
|
|
29
|
-
kwargs = {}
|
|
30
|
-
if input_stream:
|
|
31
|
-
kwargs["input_stream"] = input_stream
|
|
32
|
-
if data:
|
|
33
|
-
res = getattr(client, req_method)(
|
|
34
|
-
url, headers=headers, data=json.dumps(data), **kwargs
|
|
35
|
-
)
|
|
36
|
-
else:
|
|
37
|
-
res = getattr(client, req_method)(url, headers=headers, **kwargs)
|
|
38
|
-
assert expected_resp_code == res.status_code
|
|
39
|
-
return res
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def _test_data_exists(key, res):
|
|
43
|
-
"""Util function for testing output data."""
|
|
44
|
-
data = json.loads(res.data.decode("utf-8"))["metadata"]
|
|
45
|
-
assert key in data
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def test_create_bucket_endpoint(client, json_headers, location, testdata, users):
|
|
49
|
-
"""Test GET permissions."""
|
|
50
|
-
user_login(client, "admin", users)
|
|
51
|
-
|
|
52
|
-
url_with_bucket_id = url_for(
|
|
53
|
-
"invenio_app_ils_files.eitmid_bucket", pid_value="eitemid-3"
|
|
54
|
-
)
|
|
55
|
-
url_without_bucket_id = url_for(
|
|
56
|
-
"invenio_app_ils_files.eitmid_bucket", pid_value="eitemid-4"
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
res1 = _test_response(client, "post", url_with_bucket_id, json_headers, None, 200)
|
|
60
|
-
_test_data_exists("bucket_id", res1)
|
|
61
|
-
res2 = _test_response(
|
|
62
|
-
client, "post", url_without_bucket_id, json_headers, None, 201
|
|
63
|
-
)
|
|
64
|
-
_test_data_exists("bucket_id", res2)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def test_create_bucket_permissions(client, json_headers, location, testdata, users):
|
|
68
|
-
"""Test create bucket permissions."""
|
|
69
|
-
url = url_for("invenio_app_ils_files.eitmid_bucket", pid_value="eitemid-1")
|
|
70
|
-
_test_response(client, "post", url, json_headers, None, 401)
|
|
71
|
-
|
|
72
|
-
test_data = [
|
|
73
|
-
("admin", "eitemid-1", 201),
|
|
74
|
-
("librarian", "eitemid-2", 201),
|
|
75
|
-
("patron1", "eitemid-2", 403),
|
|
76
|
-
]
|
|
77
|
-
for user, pid, status_code in test_data:
|
|
78
|
-
user_login(client, user, users)
|
|
79
|
-
url = url_for("invenio_app_ils_files.eitmid_bucket", pid_value=pid)
|
|
80
|
-
_test_response(client, "post", url, json_headers, None, status_code)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def test_upload_files_permissions(client, json_headers, bucket, testdata, users):
|
|
84
|
-
"""Test upload files permissions."""
|
|
85
|
-
filename = "myfile.txt"
|
|
86
|
-
data = b"hello world"
|
|
87
|
-
url = url_for(
|
|
88
|
-
"invenio_files_rest.object_api", bucket_id=str(bucket.id), key=filename
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
test_data = [
|
|
92
|
-
("anonymous", 404),
|
|
93
|
-
("admin", 200),
|
|
94
|
-
("librarian", 200),
|
|
95
|
-
("patron1", 404),
|
|
96
|
-
]
|
|
97
|
-
for user, status_code in test_data:
|
|
98
|
-
user_login(client, user, users)
|
|
99
|
-
_test_response(
|
|
100
|
-
client,
|
|
101
|
-
"put",
|
|
102
|
-
url,
|
|
103
|
-
json_headers,
|
|
104
|
-
None,
|
|
105
|
-
status_code,
|
|
106
|
-
input_stream=BytesIO(data),
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def test_download_files_permissions(client, json_headers, location, testdata, users):
|
|
111
|
-
"""Test download files permissions."""
|
|
112
|
-
|
|
113
|
-
tests = [
|
|
114
|
-
(
|
|
115
|
-
"eitemid-4",
|
|
116
|
-
[
|
|
117
|
-
("anonymous", 200),
|
|
118
|
-
("admin", 200),
|
|
119
|
-
("librarian", 200),
|
|
120
|
-
("patron1", 200),
|
|
121
|
-
],
|
|
122
|
-
),
|
|
123
|
-
(
|
|
124
|
-
"eitemid-5",
|
|
125
|
-
[
|
|
126
|
-
("anonymous", 404),
|
|
127
|
-
("admin", 200),
|
|
128
|
-
("librarian", 200),
|
|
129
|
-
("patron1", 200),
|
|
130
|
-
],
|
|
131
|
-
),
|
|
132
|
-
]
|
|
133
|
-
|
|
134
|
-
for pid, expected in tests:
|
|
135
|
-
# Create e-item bucket
|
|
136
|
-
user_login(client, "admin", users)
|
|
137
|
-
url = url_for("invenio_app_ils_files.eitmid_bucket", pid_value=pid)
|
|
138
|
-
res = _test_response(client, "post", url, json_headers, None, 201)
|
|
139
|
-
bucket_id = json.loads(res.data)["metadata"]["bucket_id"]
|
|
140
|
-
|
|
141
|
-
# Upload file to e-item bucket
|
|
142
|
-
filename = "myfile.txt"
|
|
143
|
-
data = b"hello world"
|
|
144
|
-
url = url_for(
|
|
145
|
-
"invenio_files_rest.object_api", bucket_id=bucket_id, key=filename
|
|
146
|
-
)
|
|
147
|
-
_test_response(
|
|
148
|
-
client,
|
|
149
|
-
"put",
|
|
150
|
-
url,
|
|
151
|
-
json_headers,
|
|
152
|
-
None,
|
|
153
|
-
200,
|
|
154
|
-
input_stream=BytesIO(data),
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
current_search.flush_and_refresh(index="eitems")
|
|
158
|
-
|
|
159
|
-
# Download file
|
|
160
|
-
for user, status_code in expected:
|
|
161
|
-
user_login(client, user, users)
|
|
162
|
-
_test_response(client, "get", url, None, None, status_code)
|
tests/api/ils/items/__init__.py
DELETED
tests/api/ils/items/test_apis.py
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2020 CERN.
|
|
4
|
-
#
|
|
5
|
-
# invenio-app-ils is free software; you can redistribute it and/or modify it
|
|
6
|
-
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Test Items APIs."""
|
|
9
|
-
|
|
10
|
-
from invenio_app_ils.items.api import (
|
|
11
|
-
ITEM_PID_TYPE,
|
|
12
|
-
get_document_pid_by_item_pid,
|
|
13
|
-
get_item_pids_by_document_pid,
|
|
14
|
-
item_exists,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def test_get_item_pids_by_document_pid(testdata):
|
|
19
|
-
"""Test retrieve Items PIDs for the given Document PID."""
|
|
20
|
-
first_doc_pid = testdata["documents"][0]["pid"]
|
|
21
|
-
items_pids = get_item_pids_by_document_pid(first_doc_pid)
|
|
22
|
-
assert len(list(items_pids)) == 9
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def test_get_document_pid_by_item_pid(testdata):
|
|
26
|
-
"""Test retrieve Document PID for the given Item."""
|
|
27
|
-
first_item_pid = testdata["items"][0]["pid"]
|
|
28
|
-
item_pid = dict(type=ITEM_PID_TYPE, value=first_item_pid)
|
|
29
|
-
doc_pid = get_document_pid_by_item_pid(item_pid)
|
|
30
|
-
assert doc_pid == "docid-1"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def test_item_exists(testdata):
|
|
34
|
-
"""Test return True if item exists."""
|
|
35
|
-
first_item_pid = testdata["items"][0]["pid"]
|
|
36
|
-
item_pid = dict(type=ITEM_PID_TYPE, value=first_item_pid)
|
|
37
|
-
assert item_exists(item_pid)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def test_item_not_exist(testdata):
|
|
41
|
-
"""Test return False if item does not exist."""
|
|
42
|
-
item_pid = dict(type=ITEM_PID_TYPE, value="not-existing-item-pid")
|
|
43
|
-
assert not item_exists(item_pid)
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2021 CERN.
|
|
4
|
-
#
|
|
5
|
-
# Invenio-Circulation is free software; you can redistribute it and/or modify
|
|
6
|
-
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Tests items CRUD."""
|
|
9
|
-
|
|
10
|
-
from copy import deepcopy
|
|
11
|
-
|
|
12
|
-
import pytest
|
|
13
|
-
|
|
14
|
-
from invenio_app_ils.circulation.search import get_active_loan_by_item_pid
|
|
15
|
-
from invenio_app_ils.errors import (
|
|
16
|
-
DocumentNotFoundError,
|
|
17
|
-
InternalLocationNotFoundError,
|
|
18
|
-
ItemHasPastLoansError,
|
|
19
|
-
)
|
|
20
|
-
from invenio_app_ils.items.api import ITEM_PID_TYPE, Item
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def test_item_create(app, testdata):
|
|
24
|
-
"""Test creation of an item."""
|
|
25
|
-
item = Item.create(
|
|
26
|
-
dict(
|
|
27
|
-
pid="itemid-99",
|
|
28
|
-
document_pid="docid-1",
|
|
29
|
-
internal_location_pid="ilocid-4",
|
|
30
|
-
created_by=dict(type="script", value="demo"),
|
|
31
|
-
barcode="cm-348048",
|
|
32
|
-
status="CAN_CIRCULATE",
|
|
33
|
-
circulation_restriction="NO_RESTRICTION",
|
|
34
|
-
medium="PAPER",
|
|
35
|
-
)
|
|
36
|
-
)
|
|
37
|
-
assert "$schema" in item
|
|
38
|
-
assert "document" in item and "$ref" in item["document"]
|
|
39
|
-
assert item["barcode"] == "CM-348048"
|
|
40
|
-
assert "internal_location" in item and "$ref" in item["internal_location"]
|
|
41
|
-
|
|
42
|
-
item = Item.get_record_by_pid("itemid-1")
|
|
43
|
-
item = item.replace_refs()
|
|
44
|
-
assert "document" in item and item["document"]["title"]
|
|
45
|
-
assert "internal_location" in item and item["internal_location"]["name"]
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def test_item_update(app, db, testdata):
|
|
49
|
-
"""Test update of an item."""
|
|
50
|
-
item = Item.get_record_by_pid("itemid-1")
|
|
51
|
-
item.update(dict(barcode="cm-348048"))
|
|
52
|
-
item.commit()
|
|
53
|
-
db.session.commit()
|
|
54
|
-
|
|
55
|
-
assert Item.get_record_by_pid("itemid-1")["barcode"] == "CM-348048"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def test_item_validation(db, testdata):
|
|
59
|
-
"""Test validation when updating an item."""
|
|
60
|
-
item_pid = testdata["items"][0]["pid"]
|
|
61
|
-
orginal_item = Item.get_record_by_pid(item_pid)
|
|
62
|
-
|
|
63
|
-
# change document pid
|
|
64
|
-
item = deepcopy(orginal_item)
|
|
65
|
-
item["document_pid"] = "not_found_doc"
|
|
66
|
-
with pytest.raises(DocumentNotFoundError):
|
|
67
|
-
item.commit()
|
|
68
|
-
|
|
69
|
-
# change internal location pid
|
|
70
|
-
item = deepcopy(orginal_item)
|
|
71
|
-
item["internal_location_pid"] = "not_found_pid"
|
|
72
|
-
with pytest.raises(InternalLocationNotFoundError):
|
|
73
|
-
item.commit()
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def test_item_references(db, testdata):
|
|
77
|
-
"""Test references when updating an item."""
|
|
78
|
-
|
|
79
|
-
def get_active_loan_pid_and_item_pid():
|
|
80
|
-
for t in testdata["items"]:
|
|
81
|
-
if t["status"] == "CAN_CIRCULATE":
|
|
82
|
-
item_pid = dict(type=ITEM_PID_TYPE, value=t["pid"])
|
|
83
|
-
active_loan = get_active_loan_by_item_pid(item_pid).execute().hits
|
|
84
|
-
total = active_loan.total.value
|
|
85
|
-
if total > 0:
|
|
86
|
-
return t["pid"], active_loan[0]["pid"]
|
|
87
|
-
|
|
88
|
-
# change document pid while is on loan
|
|
89
|
-
item_pid, loan_pid = get_active_loan_pid_and_item_pid()
|
|
90
|
-
item = Item.get_record_by_pid(item_pid)
|
|
91
|
-
item["document_pid"] = "docid-1"
|
|
92
|
-
with pytest.raises(ItemHasPastLoansError):
|
|
93
|
-
item.commit()
|
|
94
|
-
|
|
95
|
-
# change document to one that does not exist
|
|
96
|
-
item = Item.get_record_by_pid("itemid-1")
|
|
97
|
-
item["document_pid"] = "not_found_doc"
|
|
98
|
-
with pytest.raises(DocumentNotFoundError):
|
|
99
|
-
item.commit()
|