invenio-app-ils 4.5.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.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/METADATA +56 -43
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/RECORD +24 -112
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/entry_points.txt +3 -0
- {invenio_app_ils-4.5.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.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/WHEEL +0 -0
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,131 +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 document requests."""
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
|
|
12
|
-
from flask import url_for
|
|
13
|
-
|
|
14
|
-
from tests.helpers import user_login
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def _compare_list_data(all_expected, data, user_id, is_admin):
|
|
18
|
-
"""Compare list data with expected values."""
|
|
19
|
-
if is_admin:
|
|
20
|
-
expected = []
|
|
21
|
-
for pids in all_expected.values():
|
|
22
|
-
for pid in pids:
|
|
23
|
-
expected.append(pid)
|
|
24
|
-
else:
|
|
25
|
-
expected = all_expected[str(user_id)]
|
|
26
|
-
|
|
27
|
-
for hit in data["hits"]["hits"]:
|
|
28
|
-
assert hit["metadata"]["pid"] in expected
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def test_request_list_permissions(client, testdata, json_headers, users):
|
|
32
|
-
"""Test doc req list permissions."""
|
|
33
|
-
url = url_for("invenio_records_rest.dreqid_list")
|
|
34
|
-
res = client.get(url, headers=json_headers)
|
|
35
|
-
assert res.status_code == 401
|
|
36
|
-
|
|
37
|
-
requests_by_patron = {}
|
|
38
|
-
for req in testdata["document_requests"]:
|
|
39
|
-
if req["patron_pid"] not in requests_by_patron:
|
|
40
|
-
requests_by_patron[req["patron_pid"]] = []
|
|
41
|
-
requests_by_patron[req["patron_pid"]].append(req["pid"])
|
|
42
|
-
|
|
43
|
-
for username in users.keys():
|
|
44
|
-
user = user_login(client, username, users)
|
|
45
|
-
url = url_for("invenio_records_rest.dreqid_list")
|
|
46
|
-
res = client.get(url, headers=json_headers)
|
|
47
|
-
assert res.status_code == 200
|
|
48
|
-
data = json.loads(res.data.decode("utf-8"))
|
|
49
|
-
is_admin = "librarian" in user.email or "admin" in user.email
|
|
50
|
-
_compare_list_data(requests_by_patron, data, user.id, is_admin)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def test_create_document_request(client, testdata, json_headers, users):
|
|
54
|
-
"""Test creating document requests."""
|
|
55
|
-
tests = [
|
|
56
|
-
(
|
|
57
|
-
"admin",
|
|
58
|
-
201,
|
|
59
|
-
dict(
|
|
60
|
-
title="Test title",
|
|
61
|
-
request_type="LOAN",
|
|
62
|
-
medium="Paper",
|
|
63
|
-
patron_pid="1",
|
|
64
|
-
),
|
|
65
|
-
),
|
|
66
|
-
(
|
|
67
|
-
"librarian",
|
|
68
|
-
400,
|
|
69
|
-
dict(
|
|
70
|
-
patron_pid="1",
|
|
71
|
-
),
|
|
72
|
-
),
|
|
73
|
-
(
|
|
74
|
-
"admin",
|
|
75
|
-
201,
|
|
76
|
-
dict(
|
|
77
|
-
patron_pid="1",
|
|
78
|
-
title="Test",
|
|
79
|
-
invalid_param="Test",
|
|
80
|
-
request_type="LOAN",
|
|
81
|
-
medium="Paper",
|
|
82
|
-
),
|
|
83
|
-
),
|
|
84
|
-
(
|
|
85
|
-
"librarian",
|
|
86
|
-
201,
|
|
87
|
-
dict(
|
|
88
|
-
title="Test title",
|
|
89
|
-
patron_pid="1",
|
|
90
|
-
request_type="BUY",
|
|
91
|
-
medium="Paper",
|
|
92
|
-
),
|
|
93
|
-
),
|
|
94
|
-
(
|
|
95
|
-
"patron1",
|
|
96
|
-
201,
|
|
97
|
-
dict(
|
|
98
|
-
title="Test title",
|
|
99
|
-
patron_pid="1",
|
|
100
|
-
request_type="BUY",
|
|
101
|
-
medium="Paper",
|
|
102
|
-
),
|
|
103
|
-
),
|
|
104
|
-
(
|
|
105
|
-
"patron2",
|
|
106
|
-
400,
|
|
107
|
-
dict(
|
|
108
|
-
title="Test title",
|
|
109
|
-
patron_pid="1",
|
|
110
|
-
request_type="LOAN",
|
|
111
|
-
medium="Paper",
|
|
112
|
-
),
|
|
113
|
-
),
|
|
114
|
-
(
|
|
115
|
-
"patron2",
|
|
116
|
-
201,
|
|
117
|
-
dict(
|
|
118
|
-
title="Test title",
|
|
119
|
-
patron_pid="2",
|
|
120
|
-
request_type="LOAN",
|
|
121
|
-
medium="Paper",
|
|
122
|
-
),
|
|
123
|
-
),
|
|
124
|
-
]
|
|
125
|
-
for username, expected_status, data in tests:
|
|
126
|
-
user_login(client, username, users)
|
|
127
|
-
url = url_for("invenio_records_rest.dreqid_list")
|
|
128
|
-
res = client.post(url, headers=json_headers, data=json.dumps(data))
|
|
129
|
-
assert res.status_code == expected_status
|
|
130
|
-
if res.status_code == 201:
|
|
131
|
-
assert "invalid_param" not in json.loads(res.data)["metadata"]
|
|
@@ -1,159 +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 accessibility of document request resource endpoints."""
|
|
9
|
-
|
|
10
|
-
from flask import url_for
|
|
11
|
-
|
|
12
|
-
from tests.helpers import user_login, validate_response
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def test_get_document_request_endpoint(client, json_headers, testdata, users):
|
|
16
|
-
"""Test GET permissions."""
|
|
17
|
-
|
|
18
|
-
tests = [
|
|
19
|
-
("patron1", "dreq-1", 200),
|
|
20
|
-
("librarian", "dreq-1", 200),
|
|
21
|
-
("admin", "dreq-1", 200),
|
|
22
|
-
("patron2", "dreq-1", 403),
|
|
23
|
-
("anonymous", "dreq-1", 401),
|
|
24
|
-
("patron2", "dreq-2", 200),
|
|
25
|
-
("librarian", "dreq-2", 200),
|
|
26
|
-
("admin", "dreq-2", 200),
|
|
27
|
-
("patron1", "dreq-2", 403),
|
|
28
|
-
("anonymous", "dreq-2", 401),
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
for user, res_id, expected_resp_code in tests:
|
|
32
|
-
user_login(client, user, users)
|
|
33
|
-
url = url_for("invenio_records_rest.dreqid_item", pid_value=res_id)
|
|
34
|
-
validate_response(client, "get", url, json_headers, None, expected_resp_code)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def test_document_request_add_document(client, json_headers, testdata, users):
|
|
38
|
-
"""Test add document to Document Request permissions."""
|
|
39
|
-
|
|
40
|
-
tests = [
|
|
41
|
-
("patron1", "dreq-1", 403),
|
|
42
|
-
("librarian", "dreq-1", 202),
|
|
43
|
-
("admin", "dreq-1", 202),
|
|
44
|
-
("anonymous", "dreq-1", 401),
|
|
45
|
-
]
|
|
46
|
-
|
|
47
|
-
for user, res_id, expected_resp_code in tests:
|
|
48
|
-
user_login(client, user, users)
|
|
49
|
-
url = url_for(
|
|
50
|
-
"invenio_app_ils_document_requests.dreqid_document",
|
|
51
|
-
pid_value=res_id,
|
|
52
|
-
)
|
|
53
|
-
data = {"document_pid": "docid-1"}
|
|
54
|
-
validate_response(client, "post", url, json_headers, data, expected_resp_code)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def test_document_request_remove_document(client, json_headers, testdata, users):
|
|
58
|
-
"""Test remove document from Document Request permissions."""
|
|
59
|
-
|
|
60
|
-
tests = [
|
|
61
|
-
("patron1", "dreq-1", 403),
|
|
62
|
-
("librarian", "dreq-1", 202),
|
|
63
|
-
("admin", "dreq-1", 202),
|
|
64
|
-
("anonymous", "dreq-1", 401),
|
|
65
|
-
]
|
|
66
|
-
|
|
67
|
-
for user, res_id, expected_resp_code in tests:
|
|
68
|
-
user_login(client, user, users)
|
|
69
|
-
url = url_for(
|
|
70
|
-
"invenio_app_ils_document_requests.dreqid_document",
|
|
71
|
-
pid_value=res_id,
|
|
72
|
-
)
|
|
73
|
-
data = {"document_pid": "docid-1"}
|
|
74
|
-
validate_response(client, "delete", url, json_headers, data, expected_resp_code)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def test_document_request_add_provider(client, json_headers, testdata, users):
|
|
78
|
-
"""Test add provider to Document Request permissions."""
|
|
79
|
-
|
|
80
|
-
tests = [
|
|
81
|
-
("patron1", "dreq-1", 403),
|
|
82
|
-
("librarian", "dreq-1", 202),
|
|
83
|
-
("admin", "dreq-1", 202),
|
|
84
|
-
("anonymous", "dreq-1", 401),
|
|
85
|
-
]
|
|
86
|
-
|
|
87
|
-
for user, res_id, expected_resp_code in tests:
|
|
88
|
-
user_login(client, user, users)
|
|
89
|
-
url = url_for(
|
|
90
|
-
"invenio_app_ils_document_requests.dreqid_provider",
|
|
91
|
-
pid_value=res_id,
|
|
92
|
-
)
|
|
93
|
-
data = {
|
|
94
|
-
"physical_item_provider": {
|
|
95
|
-
"pid": "acqoid-1",
|
|
96
|
-
"pid_type": "acqoid",
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
validate_response(client, "post", url, json_headers, data, expected_resp_code)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
def test_document_request_remove_provider(client, json_headers, testdata, users):
|
|
103
|
-
"""Test remove provider from Document Request permissions."""
|
|
104
|
-
|
|
105
|
-
tests = [
|
|
106
|
-
("patron1", "dreq-1", 403),
|
|
107
|
-
("librarian", "dreq-1", 202),
|
|
108
|
-
("admin", "dreq-1", 202),
|
|
109
|
-
("anonymous", "dreq-1", 401),
|
|
110
|
-
]
|
|
111
|
-
|
|
112
|
-
for user, res_id, expected_resp_code in tests:
|
|
113
|
-
user_login(client, user, users)
|
|
114
|
-
url = url_for(
|
|
115
|
-
"invenio_app_ils_document_requests.dreqid_provider",
|
|
116
|
-
pid_value=res_id,
|
|
117
|
-
)
|
|
118
|
-
validate_response(client, "delete", url, json_headers, None, expected_resp_code)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def test_document_request_accept(client, json_headers, testdata, users):
|
|
122
|
-
"""Test Document Request permissions to accept request."""
|
|
123
|
-
|
|
124
|
-
tests = [
|
|
125
|
-
("patron1", "dreq-1", 403),
|
|
126
|
-
("librarian", "dreq-5", 202),
|
|
127
|
-
("admin", "dreq-6", 202),
|
|
128
|
-
("anonymous", "dreq-1", 401),
|
|
129
|
-
("admin", "dreq-2", 400),
|
|
130
|
-
]
|
|
131
|
-
|
|
132
|
-
for user, res_id, expected_resp_code in tests:
|
|
133
|
-
user_login(client, user, users)
|
|
134
|
-
url = url_for(
|
|
135
|
-
"invenio_app_ils_document_requests.dreqid_accept", pid_value=res_id
|
|
136
|
-
)
|
|
137
|
-
data = {"state": "ACCEPTED"}
|
|
138
|
-
validate_response(client, "post", url, json_headers, data, expected_resp_code)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
def test_document_request_decline(client, json_headers, testdata, users):
|
|
142
|
-
"""Test Document Request permissions to decline request."""
|
|
143
|
-
|
|
144
|
-
tests = [
|
|
145
|
-
("patron1", "dreq-1", 202),
|
|
146
|
-
("librarian", "dreq-5", 202),
|
|
147
|
-
("admin", "dreq-6", 202),
|
|
148
|
-
("anonymous", "dreq-1", 401),
|
|
149
|
-
("admin", "dreq-2", 400),
|
|
150
|
-
]
|
|
151
|
-
|
|
152
|
-
for user, res_id, expected_resp_code in tests:
|
|
153
|
-
user_login(client, user, users)
|
|
154
|
-
url = url_for(
|
|
155
|
-
"invenio_app_ils_document_requests.dreqid_decline",
|
|
156
|
-
pid_value=res_id,
|
|
157
|
-
)
|
|
158
|
-
data = {"decline_reason": "USER_CANCEL"}
|
|
159
|
-
validate_response(client, "post", url, json_headers, data, expected_resp_code)
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from invenio_app_ils.document_requests.notifications.api import (
|
|
2
|
-
send_document_request_notification,
|
|
3
|
-
)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def test_notification_document_request_filter(app_with_notifs, mocker, users, testdata):
|
|
7
|
-
"""Test notification filtering."""
|
|
8
|
-
|
|
9
|
-
def filter_document_request_messages(record, action, **kwargs):
|
|
10
|
-
"""Define notification filter."""
|
|
11
|
-
if action == "decline":
|
|
12
|
-
return False
|
|
13
|
-
return True
|
|
14
|
-
|
|
15
|
-
send_mocked = mocker.patch("invenio_app_ils.notifications.backends.mail.send")
|
|
16
|
-
send_mocked.__name__ = "send"
|
|
17
|
-
send_mocked.__annotations__ = "send"
|
|
18
|
-
backends = mocker.patch(
|
|
19
|
-
"invenio_app_ils.notifications.api._get_notification_backends",
|
|
20
|
-
return_value=[send_mocked],
|
|
21
|
-
)
|
|
22
|
-
document_request = testdata["document_requests"][0]
|
|
23
|
-
with app_with_notifs.app_context():
|
|
24
|
-
# remove footer
|
|
25
|
-
app_with_notifs.config["ILS_NOTIFICATIONS_TEMPLATES"] = {}
|
|
26
|
-
# set filtering on the document requests
|
|
27
|
-
app_with_notifs.config["ILS_NOTIFICATIONS_FILTER_DOCUMENT_REQUEST"] = (
|
|
28
|
-
filter_document_request_messages
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
send_document_request_notification(
|
|
32
|
-
document_request, action="decline", msg_extra_ctx={}
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
assert not send_mocked.apply_async.called
|
tests/api/ill/__init__.py
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2021 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 record CRUD."""
|
|
9
|
-
|
|
10
|
-
import pytest
|
|
11
|
-
|
|
12
|
-
from invenio_app_ils.errors import DocumentNotFoundError, PatronNotFoundError
|
|
13
|
-
from invenio_app_ils.ill.api import BorrowingRequest
|
|
14
|
-
from invenio_app_ils.ill.errors import ILLError
|
|
15
|
-
from invenio_app_ils.providers.errors import ProviderNotFoundError
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def test_brw_req_refs(app, testdata):
|
|
19
|
-
"""Test creation of a borrowing request."""
|
|
20
|
-
brw_req = BorrowingRequest.create(
|
|
21
|
-
dict(
|
|
22
|
-
pid="illlid-99",
|
|
23
|
-
document_pid="docid-1",
|
|
24
|
-
patron_pid="1",
|
|
25
|
-
provider_pid="ill-provid-1",
|
|
26
|
-
status="PENDING",
|
|
27
|
-
type="PHYSICAL_COPY",
|
|
28
|
-
)
|
|
29
|
-
)
|
|
30
|
-
assert "$schema" in brw_req
|
|
31
|
-
assert "provider" in brw_req and "$ref" in brw_req["provider"]
|
|
32
|
-
assert "document" in brw_req and "$ref" in brw_req["document"]
|
|
33
|
-
assert "patron" in brw_req and "$ref" in brw_req["patron"]
|
|
34
|
-
|
|
35
|
-
brw_req = BorrowingRequest.get_record_by_pid("illbid-1")
|
|
36
|
-
brw_req = brw_req.replace_refs()
|
|
37
|
-
assert "provider" in brw_req and brw_req["provider"]["name"]
|
|
38
|
-
assert "document" in brw_req and brw_req["document"]["title"]
|
|
39
|
-
assert "patron" in brw_req and brw_req["patron"]["name"]
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def test_ill_brw_validation(db, testdata):
|
|
43
|
-
"""Test validation when updating a borrowing request."""
|
|
44
|
-
borrowing_request_pid = testdata["ill_brw_reqs"][0]["pid"]
|
|
45
|
-
|
|
46
|
-
# change document pid
|
|
47
|
-
borrowing_request = BorrowingRequest.get_record_by_pid(borrowing_request_pid)
|
|
48
|
-
borrowing_request["document_pid"] = "not_found_doc"
|
|
49
|
-
with pytest.raises(DocumentNotFoundError):
|
|
50
|
-
borrowing_request.commit()
|
|
51
|
-
|
|
52
|
-
# change provider pid
|
|
53
|
-
borrowing_request = BorrowingRequest.get_record_by_pid(borrowing_request_pid)
|
|
54
|
-
borrowing_request["provider_pid"] = "not_found_lib"
|
|
55
|
-
with pytest.raises(ProviderNotFoundError):
|
|
56
|
-
borrowing_request.commit()
|
|
57
|
-
|
|
58
|
-
# change patron pid
|
|
59
|
-
borrowing_request = BorrowingRequest.get_record_by_pid(borrowing_request_pid)
|
|
60
|
-
borrowing_request["patron_pid"] = "9999"
|
|
61
|
-
with pytest.raises(PatronNotFoundError):
|
|
62
|
-
borrowing_request.commit()
|
|
63
|
-
|
|
64
|
-
# add cancel reason without status CANCELLED
|
|
65
|
-
borrowing_request = BorrowingRequest.get_record_by_pid(borrowing_request_pid)
|
|
66
|
-
borrowing_request["cancel_reason"] = "USER_CANCEL"
|
|
67
|
-
with pytest.raises(ILLError):
|
|
68
|
-
borrowing_request.commit()
|
|
69
|
-
|
|
70
|
-
# update status to CANCELLED without cancel_reason
|
|
71
|
-
borrowing_request = BorrowingRequest.get_record_by_pid(borrowing_request_pid)
|
|
72
|
-
borrowing_request["status"] = "CANCELLED"
|
|
73
|
-
with pytest.raises(ILLError):
|
|
74
|
-
borrowing_request.commit()
|
|
@@ -1,198 +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 ILL borrowing requests actions."""
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
from datetime import timedelta
|
|
12
|
-
|
|
13
|
-
import arrow
|
|
14
|
-
from flask import url_for
|
|
15
|
-
|
|
16
|
-
from invenio_app_ils.ill.api import BORROWING_REQUEST_PID_TYPE, BorrowingRequest
|
|
17
|
-
from tests.helpers import user_login
|
|
18
|
-
|
|
19
|
-
_HTTP_OK = [200, 201, 204]
|
|
20
|
-
ITEM_ENDPOINT = "invenio_records_rest.illbid_item"
|
|
21
|
-
LIST_ENDPOINT = "invenio_records_rest.illbid_list"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def _create_loan_action(pid, data, client, json_headers):
|
|
25
|
-
"""Send request to create a new loan from the ILL."""
|
|
26
|
-
url = url_for("invenio_app_ils_ill.illbid_create_loan", pid_value=pid)
|
|
27
|
-
data["transaction_location_pid"] = "locid-1"
|
|
28
|
-
return client.post(url, headers=json_headers, data=json.dumps(data))
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def _assert_create_loan_action_fails(pid, data, client, json_headers):
|
|
32
|
-
"""Asserts that the create loan action validation fails."""
|
|
33
|
-
res = _create_loan_action(pid, data, client, json_headers)
|
|
34
|
-
assert res.status_code == 400
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def test_brwreq_create_loan_only_backoffice(client, testdata, json_headers, users):
|
|
38
|
-
"""Test that patron have no permission of creating loans from ILLs."""
|
|
39
|
-
user_login(client, "patron1", users)
|
|
40
|
-
res = _create_loan_action("illbid-2", dict(), client, json_headers)
|
|
41
|
-
assert res.status_code == 403
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def test_brwreq_create_loan_fails_on_wrong_status(
|
|
45
|
-
db, client, testdata, json_headers, users
|
|
46
|
-
):
|
|
47
|
-
"""Test borrowing requests create loan action fails on wrong status."""
|
|
48
|
-
user_login(client, "librarian", users)
|
|
49
|
-
|
|
50
|
-
def _create_new_brwreq(data=None):
|
|
51
|
-
brwreq = data or dict(
|
|
52
|
-
document_pid="docid-3",
|
|
53
|
-
provider_pid="ill-provid-2",
|
|
54
|
-
patron_pid="1",
|
|
55
|
-
status="PENDING",
|
|
56
|
-
type="PHYSICAL_COPY",
|
|
57
|
-
)
|
|
58
|
-
url = url_for(LIST_ENDPOINT)
|
|
59
|
-
res = client.post(url, headers=json_headers, data=json.dumps(brwreq))
|
|
60
|
-
assert res.status_code in _HTTP_OK
|
|
61
|
-
brw_req = res.get_json()["metadata"]
|
|
62
|
-
return brw_req["pid"]
|
|
63
|
-
|
|
64
|
-
def _update_brwreq_with_new_status(pid, status):
|
|
65
|
-
rec = BorrowingRequest.get_record_by_pid(pid)
|
|
66
|
-
rec["status"] = status
|
|
67
|
-
if status == "CANCELLED":
|
|
68
|
-
rec["cancel_reason"] = "OTHER"
|
|
69
|
-
rec.commit()
|
|
70
|
-
db.session.commit()
|
|
71
|
-
|
|
72
|
-
def _assert_fail_when_status(pid, status):
|
|
73
|
-
_update_brwreq_with_new_status(pid, status)
|
|
74
|
-
|
|
75
|
-
now = arrow.utcnow()
|
|
76
|
-
future = now + timedelta(days=15)
|
|
77
|
-
data = dict(loan_start_date=now.isoformat(), loan_end_date=future.isoformat())
|
|
78
|
-
_assert_create_loan_action_fails(pid, data, client, json_headers)
|
|
79
|
-
|
|
80
|
-
pid = _create_new_brwreq()
|
|
81
|
-
|
|
82
|
-
_assert_fail_when_status(pid, "PENDING")
|
|
83
|
-
_assert_fail_when_status(pid, "ON_LOAN")
|
|
84
|
-
_assert_fail_when_status(pid, "RETURNED")
|
|
85
|
-
_assert_fail_when_status(pid, "CANCELLED")
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def test_brwreq_create_loan_fails_on_wrong_loan_end_date(
|
|
89
|
-
db, client, testdata, json_headers, users
|
|
90
|
-
):
|
|
91
|
-
"""Test borrowing requests create loan action fails on wrong end date."""
|
|
92
|
-
user_login(client, "librarian", users)
|
|
93
|
-
|
|
94
|
-
# demo data "illbid-2" has the valid state `REQUESTED`
|
|
95
|
-
pid = "illbid-2"
|
|
96
|
-
# missing date param
|
|
97
|
-
_assert_create_loan_action_fails(pid, dict(), client, json_headers)
|
|
98
|
-
|
|
99
|
-
now = arrow.utcnow()
|
|
100
|
-
|
|
101
|
-
# wrong format date
|
|
102
|
-
future = now + timedelta(days=5)
|
|
103
|
-
data = dict(
|
|
104
|
-
loan_start_date=now.isoformat(),
|
|
105
|
-
loan_end_date=future.date().isoformat(),
|
|
106
|
-
)
|
|
107
|
-
_assert_create_loan_action_fails(pid, data, client, json_headers)
|
|
108
|
-
data = dict(
|
|
109
|
-
loan_start_date=now.date().isoformat(),
|
|
110
|
-
loan_end_date=future.isoformat(),
|
|
111
|
-
)
|
|
112
|
-
_assert_create_loan_action_fails(pid, data, client, json_headers)
|
|
113
|
-
|
|
114
|
-
# past date
|
|
115
|
-
past = now - timedelta(days=15)
|
|
116
|
-
data = dict(
|
|
117
|
-
loan_start_date=now.date().isoformat(),
|
|
118
|
-
loan_end_date=past.date().isoformat(),
|
|
119
|
-
)
|
|
120
|
-
_assert_create_loan_action_fails(pid, data, client, json_headers)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def test_brwreq_create_loan_fails_on_loan_pid_already_attached(
|
|
124
|
-
db, client, testdata, json_headers, users
|
|
125
|
-
):
|
|
126
|
-
"""Test borrowing requests create loan action fails on loan_pid already."""
|
|
127
|
-
user_login(client, "librarian", users)
|
|
128
|
-
|
|
129
|
-
# demo data "illbid-2" has the valid state `REQUESTED`
|
|
130
|
-
pid = "illbid-2"
|
|
131
|
-
|
|
132
|
-
rec = BorrowingRequest.get_record_by_pid(pid)
|
|
133
|
-
rec.setdefault("patron_loan", {})
|
|
134
|
-
rec["patron_loan"]["pid"] = "loanid-3"
|
|
135
|
-
rec.commit()
|
|
136
|
-
db.session.commit()
|
|
137
|
-
|
|
138
|
-
# already with a loan pid for some reasons
|
|
139
|
-
now = arrow.utcnow()
|
|
140
|
-
future = now + timedelta(days=5)
|
|
141
|
-
data = dict(
|
|
142
|
-
loan_start_date=now.date().isoformat(),
|
|
143
|
-
loan_end_date=future.date().isoformat(),
|
|
144
|
-
)
|
|
145
|
-
_assert_create_loan_action_fails(pid, data, client, json_headers)
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def test_brwreq_create_loan_succeeds(db, client, testdata, json_headers, users):
|
|
149
|
-
"""Test borrowing requests create loan action succeeds."""
|
|
150
|
-
user = user_login(client, "librarian", users)
|
|
151
|
-
|
|
152
|
-
# demo data "illbid-2" has the valid state `REQUESTED`
|
|
153
|
-
pid = "illbid-2"
|
|
154
|
-
|
|
155
|
-
now = arrow.utcnow()
|
|
156
|
-
start = (now + timedelta(days=3)).date().isoformat()
|
|
157
|
-
future = (now + timedelta(days=5)).date().isoformat()
|
|
158
|
-
data = dict(loan_start_date=start, loan_end_date=future)
|
|
159
|
-
res = _create_loan_action(pid, data, client, json_headers)
|
|
160
|
-
assert res.status_code in _HTTP_OK
|
|
161
|
-
brw_req = res.get_json()["metadata"]
|
|
162
|
-
|
|
163
|
-
assert brw_req["status"] == "ON_LOAN"
|
|
164
|
-
assert "patron_loan" in brw_req
|
|
165
|
-
patron_loan = brw_req["patron_loan"]
|
|
166
|
-
assert "pid" in patron_loan
|
|
167
|
-
assert "loan" in patron_loan
|
|
168
|
-
loan = patron_loan["loan"]
|
|
169
|
-
assert patron_loan["pid"] == loan["pid"]
|
|
170
|
-
assert loan["end_date"] == future
|
|
171
|
-
loan_pid = loan["pid"]
|
|
172
|
-
|
|
173
|
-
# fetch the loan
|
|
174
|
-
url = url_for("invenio_records_rest.loanid_item", pid_value=loan_pid)
|
|
175
|
-
res = client.get(url, headers=json_headers)
|
|
176
|
-
assert res.status_code in _HTTP_OK
|
|
177
|
-
loan = res.get_json()["metadata"]
|
|
178
|
-
|
|
179
|
-
# make sure the loan is created with the data from the ILL
|
|
180
|
-
assert loan["item_pid"] == dict(type=BORROWING_REQUEST_PID_TYPE, value=pid)
|
|
181
|
-
assert loan["start_date"] == start
|
|
182
|
-
assert loan["end_date"] == future
|
|
183
|
-
assert loan["document_pid"] == brw_req["document_pid"]
|
|
184
|
-
assert loan["patron_pid"] == brw_req["patron_pid"]
|
|
185
|
-
assert loan["transaction_user_pid"] == str(user.id)
|
|
186
|
-
|
|
187
|
-
# update notes (a random field)
|
|
188
|
-
brw_req["notes"] = "This is a note"
|
|
189
|
-
url = url_for(ITEM_ENDPOINT, pid_value=pid)
|
|
190
|
-
res = client.put(url, headers=json_headers, data=json.dumps(brw_req))
|
|
191
|
-
assert res.status_code in _HTTP_OK
|
|
192
|
-
updated_brw_req = res.get_json()["metadata"]
|
|
193
|
-
|
|
194
|
-
# make sure `patron_loan` system field is preserved
|
|
195
|
-
assert updated_brw_req["notes"] == "This is a note"
|
|
196
|
-
assert "patron_loan" in updated_brw_req
|
|
197
|
-
assert "pid" in patron_loan
|
|
198
|
-
assert "loan" in patron_loan
|