From e0bb39de1d3386dd6745d5cdef28f56bf8ec9f9e Mon Sep 17 00:00:00 2001 From: Aly Badr Date: Fri, 10 May 2019 15:02:18 +0200 Subject: [PATCH] global: test coverage and docs for items * BETTER increase test coverage and add docs for items. Signed-off-by: Aly Badr --- rero_ils/modules/errors.py | 4 + rero_ils/modules/items/api.py | 40 +- rero_ils/modules/items/api_views.py | 4 +- rero_ils/modules/items/cli.py | 2 +- .../modules/items/jsonschemas/__init__.py | 2 +- rero_ils/modules/items/mappings/__init__.py | 2 +- .../modules/items/mappings/v6/__init__.py | 2 +- rero_ils/modules/items/views.py | 2 +- tests/api/test_items_rest.py | 31 +- tests/api/test_items_rest_views.py | 392 ++++++++++++++++++ tests/data/data.json | 2 +- tests/fixtures/circulation.py | 18 + tests/ui/items/test_items_api.py | 4 +- 13 files changed, 458 insertions(+), 47 deletions(-) create mode 100644 tests/api/test_items_rest_views.py diff --git a/rero_ils/modules/errors.py b/rero_ils/modules/errors.py index 11d9428870..c38063681f 100644 --- a/rero_ils/modules/errors.py +++ b/rero_ils/modules/errors.py @@ -35,3 +35,7 @@ class OrganisationDoesNotExist(RecordsError): class PolicyNameAlreadyExists(RecordsError): """Error raised when the name of the new policy record exists.""" + + +class InvalidRecordID(RecordsError): + """Error raised when the ID of record in invalid.""" diff --git a/rero_ils/modules/items/api.py b/rero_ils/modules/items/api.py index 207163e130..c5aa898df7 100644 --- a/rero_ils/modules/items/api.py +++ b/rero_ils/modules/items/api.py @@ -34,11 +34,13 @@ NoValidTransitionAvailable from invenio_circulation.proxies import current_circulation from invenio_circulation.search.api import search_by_pid +from invenio_i18n.ext import current_i18n from invenio_search import current_search from .models import ItemIdentifier, ItemStatus from ..api import IlsRecord, IlsRecordIndexer, IlsRecordsSearch from ..documents.api import Document, DocumentsSearch +from ..errors import InvalidRecordID from ..fetchers import id_fetcher from ..libraries.api import Library from ..loans.api import Loan, LoanAction, \ @@ -63,10 +65,10 @@ class ItemsIndexer(IlsRecordIndexer): - """.""" + """Indexing items in Elasticsearch.""" def index(self, record): - """.""" + """Index an item.""" return_value = super(ItemsIndexer, self).index(record) document_pid = record.replace_refs()['document']['pid'] document = Document.get_record_by_pid(document_pid) @@ -97,7 +99,7 @@ class Meta: @classmethod def flush(cls): - """.""" + """Flush indexes.""" current_search.flush_and_refresh(DocumentsSearch.Meta.index) current_search.flush_and_refresh(cls.Meta.index) @@ -106,7 +108,7 @@ def add_loans_parameters_and_flush_indexes(function): """Add missing action parameters.""" @wraps(function) def wrapper(item, *args, **kwargs): - """.""" + """Executed before loan action.""" loan = None web_request = False patron_pid = kwargs.get('patron_pid') @@ -191,7 +193,7 @@ class Item(IlsRecord): } def dumps_for_circulation(self): - """.""" + """Enhance item information for api_views.""" item = self.replace_refs() data = item.dumps() @@ -213,13 +215,13 @@ def dumps_for_circulation(self): @classmethod def get_document_pid_by_item_pid(cls, item_pid): - """.""" + """Returns document pid from item pid.""" item = cls.get_record_by_pid(item_pid).replace_refs() return item.get('document', {}).get('pid') @classmethod def get_items_pid_by_document_pid(cls, document_pid): - """.""" + """Returns item pisd from document pid.""" results = ItemsSearch()\ .filter('term', document__pid=document_pid)\ .source(['pid']).scan() @@ -236,7 +238,7 @@ def get_loans_by_item_pid(cls, item_pid): @classmethod def get_loan_pid_with_item_on_loan(cls, item_pid): - """.""" + """Returns loan pid for checked out item.""" search = search_by_pid( item_pid=item_pid, filter_states=['ITEM_ON_LOAN']) results = search.source(['loan_pid']).scan() @@ -247,7 +249,7 @@ def get_loan_pid_with_item_on_loan(cls, item_pid): @classmethod def get_loan_pid_with_item_in_transit(cls, item_pid): - """.""" + """Returns loan pi for in_transit item.""" search = search_by_pid( item_pid=item_pid, filter_states=[ "ITEM_IN_TRANSIT_FOR_PICKUP", @@ -270,7 +272,7 @@ def get_item_by_barcode(cls, barcode=None): @classmethod def get_pendings_loans(cls, library_pid): - """.""" + """Returns list of pending loand for a given library.""" # check library exists lib = Library.get_record_by_pid(library_pid) if not lib: @@ -288,12 +290,11 @@ def get_pendings_loans(cls, library_pid): @classmethod def get_checked_out_loans(cls, patron_pid): - """.""" + """Returns checked out loans for a given patron.""" # check library exists patron = Patron.get_record_by_pid(patron_pid) if not patron: - raise Exception('Invalid Patron PID') - + raise InvalidRecordID('Invalid Patron PID') results = current_circulation.loan_search\ .source(['loan_pid'])\ .params(preserve_order=True)\ @@ -306,7 +307,7 @@ def get_checked_out_loans(cls, patron_pid): @classmethod def get_checked_out_items(cls, patron_pid): - """.""" + """Return checked out items for a given patron.""" loans = cls.get_checked_out_loans(patron_pid) returned_item_pids = [] for loan in loans: @@ -332,7 +333,7 @@ def get_requests(self): @classmethod def get_requests_to_validate(cls, library_pid): - """.""" + """Returns list of requests to validate for a given library.""" loans = cls.get_pendings_loans(library_pid) returned_item_pids = [] for loan in loans: @@ -344,11 +345,11 @@ def get_requests_to_validate(cls, library_pid): yield item, loan def get_library(self): - """Shortcut library.""" + """Shortcut to the library of the item location.""" return self.get_location().get_library() def get_location(self): - """Shortcut for item status.""" + """Shortcut to the location of the item.""" location_pid = self.replace_refs()['location']['pid'] return Location.get_record_by_pid(location_pid) @@ -508,13 +509,12 @@ def available(self): self.number_of_requests() == 0 def get_item_end_date(self): - """Get item due date a given item.""" + """Get item due date for a given item.""" loan = get_loan_for_item(self.pid) if loan: end_date = loan['end_date'] # due_date = datetime.strptime(end_date, '%Y-%m-%d') from ...filter import format_date_filter - from invenio_i18n.ext import current_i18n due_date = format_date_filter( end_date, @@ -663,7 +663,7 @@ def cancel_loan(self, current_loan, **kwargs): } def get_owning_pickup_location_pid(self): - """.""" + """Returns the pickup location for the item owning location.""" library = self.get_library() return library.get_pickup_location_pid() diff --git a/rero_ils/modules/items/api_views.py b/rero_ils/modules/items/api_views.py index 47b9e07c6a..185105c135 100644 --- a/rero_ils/modules/items/api_views.py +++ b/rero_ils/modules/items/api_views.py @@ -63,7 +63,7 @@ def decorated_view(*args, **kwargs): def jsonify_error(func): - """.""" + """Jsonify errors.""" @wraps(func) def decorated_view(*args, **kwargs): try: @@ -77,7 +77,7 @@ def decorated_view(*args, **kwargs): def jsonify_action(func): - """.""" + """Jsonify loan actions.""" @wraps(func) def decorated_view(*args, **kwargs): try: diff --git a/rero_ils/modules/items/cli.py b/rero_ils/modules/items/cli.py index 48f52e0630..2b94be3691 100644 --- a/rero_ils/modules/items/cli.py +++ b/rero_ils/modules/items/cli.py @@ -64,7 +64,7 @@ def __len__(self): @click.command('reindex_items') @with_appcontext def reindex_items(): - """.""" + """Reindexing of item.""" ids = Item.get_all_ids() with click.progressbar(ids, length=len(ids)) as bar: for uuid in bar: diff --git a/rero_ils/modules/items/jsonschemas/__init__.py b/rero_ils/modules/items/jsonschemas/__init__.py index 17442d80bc..0c05cc7697 100644 --- a/rero_ils/modules/items/jsonschemas/__init__.py +++ b/rero_ils/modules/items/jsonschemas/__init__.py @@ -22,4 +22,4 @@ # waive the privileges and immunities granted to it by virtue of its status # as an Intergovernmental Organization or submit itself to any jurisdiction. -"""JSON schemas.""" +"""Item JSON schemas.""" diff --git a/rero_ils/modules/items/mappings/__init__.py b/rero_ils/modules/items/mappings/__init__.py index 37d287d54f..399b9c8371 100644 --- a/rero_ils/modules/items/mappings/__init__.py +++ b/rero_ils/modules/items/mappings/__init__.py @@ -22,4 +22,4 @@ # waive the privileges and immunities granted to it by virtue of its status # as an Intergovernmental Organization or submit itself to any jurisdiction. -"""Elasticsearch mappings.""" +"""Item Elasticsearch mappings.""" diff --git a/rero_ils/modules/items/mappings/v6/__init__.py b/rero_ils/modules/items/mappings/v6/__init__.py index 37d287d54f..399b9c8371 100644 --- a/rero_ils/modules/items/mappings/v6/__init__.py +++ b/rero_ils/modules/items/mappings/v6/__init__.py @@ -22,4 +22,4 @@ # waive the privileges and immunities granted to it by virtue of its status # as an Intergovernmental Organization or submit itself to any jurisdiction. -"""Elasticsearch mappings.""" +"""Item Elasticsearch mappings.""" diff --git a/rero_ils/modules/items/views.py b/rero_ils/modules/items/views.py index 07f2ab52ab..8ac05323ff 100644 --- a/rero_ils/modules/items/views.py +++ b/rero_ils/modules/items/views.py @@ -90,7 +90,7 @@ def decorated_view(*args, **kwargs): def jsonify_error(func): - """.""" + """Jsonify the errors.""" @wraps(func) def decorated_view(*args, **kwargs): try: diff --git a/tests/api/test_items_rest.py b/tests/api/test_items_rest.py index 578cde10ea..3a692dc38c 100644 --- a/tests/api/test_items_rest.py +++ b/tests/api/test_items_rest.py @@ -23,9 +23,6 @@ """Tests REST API items.""" -# import json -# from utils import get_json, to_relative_url - import json from datetime import datetime, timedelta @@ -172,7 +169,7 @@ def test_items_failed_actions(client, patron_martigny_no_email, loc_public_martigny, item_type_standard_martigny, item_lib_martigny, json_header): - """.""" + """Test item failed actions.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid @@ -221,7 +218,7 @@ def test_items_simple_checkout(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circulation_policies): - """.""" + """Test item checkout.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid @@ -446,7 +443,7 @@ def test_items_requests(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circulation_policies): - """.""" + """Test requesting an item and validation.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid @@ -609,7 +606,7 @@ def test_items_cancel_request(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circulation_policies): - """.""" + """Test cancel item request.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid @@ -659,7 +656,7 @@ def test_items_extend(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circulation_policies): - """.""" + """Test item renewal.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid @@ -733,7 +730,7 @@ def test_items_lose(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circulation_policies): - """.""" + """Test item action lose.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid @@ -821,7 +818,7 @@ def test_items_receive(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circulation_policies): - """.""" + """Test item receive.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid @@ -892,7 +889,7 @@ def test_items_automatic_checkin(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circulation_policies): - """.""" + """Test automatic checkin for items.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid @@ -1012,7 +1009,7 @@ def test_items_no_extend(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circ_policy_short_martigny): - """.""" + """Test items when no renewals is possible.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid @@ -1085,7 +1082,7 @@ def test_items_deny_requests(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circ_policy_short_martigny): - """.""" + """Test items when requests are denied.""" location = loc_public_martigny circ_policy_short_martigny['allow_requests'] = False circ_policy_short_martigny.update( @@ -1126,7 +1123,7 @@ def test_extend_possible_actions(client, item_lib_martigny, librarian_martigny_no_email, patron_martigny_no_email, circ_policy_short_martigny): - """Extend action changes according to params of cipo""" + """Extend action changes according to params of cipo.""" login_user_via_session(client, librarian_martigny_no_email.user) circ_policy = circ_policy_short_martigny item = item_lib_martigny @@ -1200,7 +1197,7 @@ def test_item_possible_actions(client, item_lib_martigny, librarian_martigny_no_email, patron_martigny_no_email, circulation_policies): - """Possible action changes according to params of cipo""" + """Possible action changes according to params of cipo.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny patron_pid = patron_martigny_no_email.pid @@ -1258,7 +1255,7 @@ def test_items_extend_rejected(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circ_policy_short_martigny): - """.""" + """Test items when extend will be rejected.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid @@ -1341,7 +1338,7 @@ def test_items_extend_end_date(client, librarian_martigny_no_email, item_type_standard_martigny, item_lib_martigny, json_header, circ_policy_short_martigny): - """.""" + """Test correct renewal due date for items.""" login_user_via_session(client, librarian_martigny_no_email.user) item = item_lib_martigny item_pid = item.pid diff --git a/tests/api/test_items_rest_views.py b/tests/api/test_items_rest_views.py new file mode 100644 index 0000000000..5cdeb84102 --- /dev/null +++ b/tests/api/test_items_rest_views.py @@ -0,0 +1,392 @@ +# +# This file is part of RERO ILS. +# Copyright (C) 2017 RERO. +# +# RERO ILS is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# RERO ILS 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 +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with RERO ILS; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307, USA. +# +# In applying this license, RERO does not +# waive the privileges and immunities granted to it by virtue of its status +# as an Intergovernmental Organization or submit itself to any jurisdiction. + +"""Tests REST API items.""" + +import json +from copy import deepcopy +from datetime import datetime, timedelta + +import ciso8601 +import mock +import pytest +from flask import url_for +from invenio_accounts.testutils import login_user_via_session +from utils import VerifyRecordPermissionPatch, flush_index, get_json + +from rero_ils.modules.circ_policies.api import CircPoliciesSearch, CircPolicy +from rero_ils.modules.errors import InvalidRecordID +from rero_ils.modules.items.api import Item, ItemStatus +from rero_ils.modules.loans.api import Loan, LoanAction +from rero_ils.modules.loans.utils import get_extension_params + + +def test_checkout_no_loan_given(client, librarian_martigny_no_email, + patron_martigny_no_email, loc_public_martigny, + item_lib_martigny, json_header, + circulation_policies): + """Test checkout item when request loan is not given.""" + login_user_via_session(client, librarian_martigny_no_email.user) + item = item_lib_martigny + patron = patron_martigny_no_email + location = loc_public_martigny + # request + res = client.post( + url_for('api_item.librarian_request'), + data=json.dumps( + dict( + item_pid=item.pid, + pickup_location_pid=location.pid, + patron_pid=patron.pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + + # checkout + res = client.post( + url_for('api_item.checkout'), + data=json.dumps( + dict( + item_pid=item.pid, + patron_pid=patron.pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + data = get_json(res) + loan_pid = data.get('action_applied')[LoanAction.CHECKOUT].get('loan_pid') + + res = client.post( + url_for('api_item.checkin'), + data=json.dumps( + dict( + item_pid=item.pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 403 + + res = client.post( + url_for('api_item.checkin'), + data=json.dumps( + dict( + item_pid=item.pid, + loan_pid=loan_pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + + +def test_item_misc(client, librarian_martigny_no_email, lib_martigny, + patron_martigny_no_email, loc_public_martigny, + item_lib_martigny, json_header, item_type_standard_martigny, + circ_policy_short_martigny, patron_type_children_martigny): + """Test item different functions.""" + login_user_via_session(client, librarian_martigny_no_email.user) + item = item_lib_martigny + patron = patron_martigny_no_email + location = loc_public_martigny + circ_policy_origin = deepcopy(circ_policy_short_martigny) + circ_policy = circ_policy_short_martigny + + assert not item.get_extension_count() + assert not item.get_loan_pid_with_item_in_transit(item.pid) + assert not item.get_loan_pid_with_item_on_loan(item.pid) + assert not item.get_item_by_barcode(barcode='does not exist') + + loans = item.get_checked_out_loans('does not exist') + + with pytest.raises(InvalidRecordID): + assert sum(1 for loan in loans) + + assert 'checkout' in item.actions + + res = client.post( + url_for('api_item.librarian_request'), + data=json.dumps( + dict( + item_pid=item.pid, + pickup_location_pid=location.pid, + patron_pid=patron.pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + data = get_json(res) + loan_pid = data.get('action_applied')[LoanAction.REQUEST].get('loan_pid') + + res = client.post( + url_for('api_item.validate_request'), + data=json.dumps( + dict( + item_pid=item.pid, + loan_pid=loan_pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + + circ_policy['allow_checkout'] = False + circ_policy['renewal_duration'] = 30 + + circ_policy.update(circ_policy, dbcommit=True, reindex=True) + assert not circ_policy.get('allow_checkout') + assert 'checkout' not in item.actions + + circ_policy['allow_checkout'] = True + circ_policy.update( + circ_policy, + dbcommit=True, + reindex=True + ) + + # checkout + res = client.post( + url_for('api_item.checkout'), + data=json.dumps( + dict( + item_pid=item.pid, + patron_pid=patron.pid, + loan_pid=loan_pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + assert 'extend_loan' in item.actions + + class current_i18n: + class locale: + language = 'fr' + with mock.patch( + 'rero_ils.modules.items.api.current_i18n', + current_i18n + ): + assert item.get_item_end_date() + + circ_policy.update(circ_policy_origin, dbcommit=True, reindex=True) + res = client.post( + url_for('api_item.checkin'), + data=json.dumps( + dict( + item_pid=item.pid, + loan_pid=loan_pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + + class current_i18n: + class locale: + language = 'fr' + with mock.patch( + 'rero_ils.modules.items.api.current_i18n', + current_i18n + ): + assert not item.get_item_end_date() + + +def test_automatic_checkin(client, librarian_martigny_no_email, lib_martigny, + patron_martigny_no_email, loc_public_martigny, + item_lib_martigny, json_header, + item_type_standard_martigny, + circ_policy_short_martigny, + patron_type_children_martigny, lib_saxon, + loc_public_saxon, librarian_saxon_no_email): + """Test item automatic checkin.""" + login_user_via_session(client, librarian_saxon_no_email.user) + circ_policy_origin = deepcopy(circ_policy_short_martigny) + circ_policy = circ_policy_short_martigny + + record, actions = item_lib_martigny.automatic_checkin() + assert actions == {'no': None} + + res = client.post( + url_for('api_item.librarian_request'), + data=json.dumps( + dict( + item_pid=item_lib_martigny.pid, + pickup_location_pid=loc_public_saxon.pid, + patron_pid=patron_martigny_no_email.pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + data = get_json(res) + loan_pid = data.get('action_applied')[LoanAction.REQUEST].get('loan_pid') + + res = client.post( + url_for('api_item.validate_request'), + data=json.dumps( + dict( + item_pid=item_lib_martigny.pid, + loan_pid=loan_pid, + transaction_location_pid=loc_public_martigny.pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + + item = Item.get_record_by_pid(item_lib_martigny.pid) + assert item.status == ItemStatus.IN_TRANSIT + + record, actions = item.automatic_checkin() + assert 'receive' in actions + + item.cancel_loan(loan_pid=loan_pid) + assert item.status == ItemStatus.ON_SHELF + + +def test_auto_checkin_else(client, librarian_martigny_no_email, lib_martigny, + patron_martigny_no_email, loc_public_martigny, + item_lib_martigny, json_header, + item_type_standard_martigny, + circ_policy_short_martigny, + patron_type_children_martigny, lib_saxon, + loc_public_saxon, librarian_saxon_no_email): + """Test item automatic checkin other scenarios.""" + login_user_via_session(client, librarian_martigny_no_email.user) + circ_policy_origin = deepcopy(circ_policy_short_martigny) + circ_policy = circ_policy_short_martigny + + record, actions = item_lib_martigny.automatic_checkin() + assert actions == {'no': None} + + res = client.post( + url_for('api_item.librarian_request'), + data=json.dumps( + dict( + item_pid=item_lib_martigny.pid, + pickup_location_pid=loc_public_saxon.pid, + patron_pid=patron_martigny_no_email.pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + data = get_json(res) + loan_pid = data.get('action_applied')[LoanAction.REQUEST].get('loan_pid') + + res = client.post( + url_for('api_item.validate_request'), + data=json.dumps( + dict( + item_pid=item_lib_martigny.pid, + loan_pid=loan_pid, + transaction_location_pid=loc_public_martigny.pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + + item = Item.get_record_by_pid(item_lib_martigny.pid) + assert item.status == ItemStatus.AT_DESK + + record, actions = item.automatic_checkin() + assert actions == {'no': None} + + item.cancel_loan(loan_pid=loan_pid) + assert item.status == ItemStatus.ON_SHELF + + +def test_item_different_actions(client, librarian_martigny_no_email, + lib_martigny, + patron_martigny_no_email, loc_public_martigny, + item_lib_martigny, json_header, + item_type_standard_martigny, + circ_policy_short_martigny, + patron_type_children_martigny, lib_saxon, + loc_public_saxon, librarian_saxon_no_email): + """Test item possible actions other scenarios.""" + login_user_via_session(client, librarian_martigny_no_email.user) + circ_policy_origin = deepcopy(circ_policy_short_martigny) + circ_policy = circ_policy_short_martigny + + patron_pid = patron_martigny_no_email.pid + res = client.get( + url_for( + 'api_item.item', + item_barcode='does not exist', + patron_pid=patron_pid + ) + ) + assert res.status_code == 404 + + res = client.post( + url_for('api_item.checkout'), + data=json.dumps( + dict( + item_pid=item_lib_martigny.pid, + patron_pid=patron_pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + data = get_json(res) + loan_pid = data.get('action_applied')[LoanAction.CHECKOUT].get('loan_pid') + + res = client.post( + url_for('api_item.checkin'), + data=json.dumps( + dict( + item_pid='does not exist', + loan_pid=loan_pid, + transaction_location_pid=loc_public_saxon.pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 404 + + res = client.post( + url_for('api_item.checkin'), + data=json.dumps( + dict( + item_pid=item_lib_martigny.pid, + loan_pid=loan_pid, + transaction_location_pid=loc_public_saxon.pid + ) + ), + content_type='application/json', + ) + assert res.status_code == 200 + data = get_json(res) + loan_pid = data.get('action_applied')[LoanAction.CHECKIN].get('loan_pid') + + from rero_ils.modules.items.api_views import prior_checkout_actions + data = {'loan_pid': loan_pid} + return_data = prior_checkout_actions(item_lib_martigny, data) + assert return_data == {} diff --git a/tests/data/data.json b/tests/data/data.json index 30edfabcdf..6cd6d84f25 100644 --- a/tests/data/data.json +++ b/tests/data/data.json @@ -993,7 +993,7 @@ "email": "elena_rodriguez@gmail.com", "phone": "+41324993515", "patron_type": { - "$ref": "https://ils.rero.ch/api/patron_types/ptty2" + "$ref": "https://ils.rero.ch/api/patron_types/ptty1" }, "roles": [ "librarian", diff --git a/tests/fixtures/circulation.py b/tests/fixtures/circulation.py index 7cc1a2f0c0..08a084d37d 100644 --- a/tests/fixtures/circulation.py +++ b/tests/fixtures/circulation.py @@ -153,6 +153,24 @@ def librarian_saxon_data(data): return deepcopy(data.get('ptrn2')) +@pytest.fixture(scope="module") +@mock.patch('rero_ils.modules.patrons.api.send_reset_password_instructions') +def librarian_saxon_no_email( + app, + roles, + lib_saxon, + patron_type_children_martigny, + librarian_saxon_data): + """Create Martigny patron record no email.""" + ptrn = Patron.create( + data=librarian_saxon_data, + delete_pid=False, + dbcommit=True, + reindex=True) + flush_index(PatronsSearch.Meta.index) + return ptrn + + @pytest.fixture(scope="module") def librarian_saxon( app, diff --git a/tests/ui/items/test_items_api.py b/tests/ui/items/test_items_api.py index 523d70202a..2e6fe41662 100644 --- a/tests/ui/items/test_items_api.py +++ b/tests/ui/items/test_items_api.py @@ -39,7 +39,7 @@ def test_item_item_location_retriever(item_lib_martigny, loc_public_martigny, def test_item_get_items_pid_by_document_pid(document, item_lib_martigny): - """.""" + """Test get items by document pid.""" assert len(list(Item.get_items_pid_by_document_pid(document.pid))) == 1 @@ -74,6 +74,6 @@ def test_item_es_mapping(es_clear, db, document, loc_public_martigny, def test_item_can_delete(item_lib_martigny): - """Test can delete""" + """Test can delete.""" assert item_lib_martigny.get_links_to_me() == {} assert item_lib_martigny.can_delete