Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

global: test coverage and docs for patrons #290

Merged
merged 1 commit into from
May 14, 2019
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
10 changes: 5 additions & 5 deletions rero_ils/modules/patrons/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class Patron(IlsRecord):
@classmethod
def create(cls, data, id_=None, delete_pid=True,
dbcommit=False, reindex=False, **kwargs):
"""."""
"""Patron record creation."""
record = super(Patron, cls).create(
data, id_, delete_pid, dbcommit, reindex, **kwargs)
record._update_roles()
Expand All @@ -101,7 +101,7 @@ def update(self, data, dbcommit=False, reindex=False):

@cached_property
def user(self):
"""."""
"""Invenio user of a patron."""
email = self.get('email')
user = _datastore.find_user(email=email)
if not user:
Expand All @@ -116,7 +116,7 @@ def user(self):
return user

def _update_roles(self):
"""."""
"""Update user roles."""
db_roles = self.user.roles
for role in self.available_roles:
in_db = role in db_roles
Expand All @@ -127,7 +127,7 @@ def _update_roles(self):
self.remove_role(role)

def _remove_roles(self):
"""."""
"""Remove roles."""
db_roles = self.user.roles
for role in self.available_roles:
if role in db_roles:
Expand Down Expand Up @@ -162,7 +162,7 @@ def get_pid_by_email(cls, email):

@classmethod
def get_librarian_pickup_location_pid(cls):
"""."""
"""Returns pickup locations for a librarian."""
if 'librarian' in current_patron['roles']:
library = Library.get_record_by_pid(
current_patron.replace_refs()['library']['pid']
Expand Down
2 changes: 1 addition & 1 deletion rero_ils/modules/patrons/jsonschemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 for rero-ils."""
"""JSON schemas for patrons."""
41 changes: 20 additions & 21 deletions rero_ils/modules/patrons/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,23 @@ def func_item_at_desk(sender, *args, **kwargs):
"""Function for signal item_at_desk."""
item = kwargs['item']

# Get patron for holding.
holdings = item.get('_circulation', {}).get('holdings', [])
if holdings:
patron_barcode = holdings[0].get('patron_barcode')
patron = Patron.get_patron_by_barcode(patron_barcode)

if patron:
# Send at desk mail
subject = _('Document at desk')
email = patron.get('email')
recipients = [email]
template = 'patron_request_at_desk'
send_mail(
subject=subject,
recipients=recipients,
template=template,
language='eng',
document=Document.get_document_by_itemid(item.id),
# holding=item.dumps().get('_circulation').get('holdings')[0],
holding='get loans with state ITEM_AT_DESK, To be implemented',
)
requests = item.number_of_requests()
BadrAly marked this conversation as resolved.
Show resolved Hide resolved
if requests:
for request in item.get_requests():
if request.get('state') == 'ITEM_AT_DESK':
patron = Patron.get_record_by_pid(request.get('patron_pid'))
if patron:
# Send at desk mail
subject = _('Document at desk')
document_pid = request.get('document_pid')
email = patron.get('email')
recipients = [email]
template = 'patron_request_at_desk'
send_mail(
subject=subject,
recipients=recipients,
template=template,
language='eng',
document=Document.get_record_by_pid(document_pid),
holding=request
)
2 changes: 1 addition & 1 deletion rero_ils/modules/patrons/mappings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
"""Elasticsearch mappings for patrons."""
2 changes: 1 addition & 1 deletion rero_ils/modules/patrons/mappings/v6/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
"""Elasticsearch mappings for patrons."""
2 changes: 1 addition & 1 deletion rero_ils/modules/patrons/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.

"""Utilities functions for rero-ils."""
"""Utilities functions for patrons."""


from flask_login import current_user
Expand Down
16 changes: 1 addition & 15 deletions rero_ils/modules/patrons/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@

from __future__ import absolute_import, print_function

from functools import wraps

from flask import Blueprint, current_app, jsonify, render_template, request
from flask_babelex import gettext as _
from flask_login import current_user, login_required
Expand All @@ -42,7 +40,6 @@
from ..libraries.api import Library
from ..loans.api import get_loans_by_patron_pid
from ..locations.api import Location
from ...permissions import login_and_librarian

api_blueprint = Blueprint(
'api_patrons',
Expand All @@ -53,16 +50,6 @@
)

BadrAly marked this conversation as resolved.
Show resolved Hide resolved

def check_permission(fn):
"""."""
@wraps(fn)
def decorated_view(*args, **kwargs):
"""."""
login_and_librarian()
return fn(*args, **kwargs)
return decorated_view


blueprint = Blueprint(
'patrons',
__name__,
Expand Down Expand Up @@ -121,7 +108,6 @@ def profile():
if patron is None:
raise NotFound()
loans = get_loans_by_patron_pid(patron.pid)

checkouts = []
requests = []
if loans:
Expand Down Expand Up @@ -159,7 +145,7 @@ def get_patron_from_barcode(value):

@blueprint.app_template_filter('get_patron_from_checkout_item_pid')
def get_patron_from_checkout_item_pid(item_pid):
"""Get patron from a checkout item pid."""
"""Get patron from a checked out item pid."""
from invenio_circulation.api import get_loan_for_item
patron_pid = get_loan_for_item(item_pid)['patron_pid']
return Patron.get_record_by_pid(patron_pid)
Expand Down
4 changes: 4 additions & 0 deletions tests/api/test_items_rest_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ def test_checkout_no_loan_given(client, librarian_martigny_no_email,
data = get_json(res)
loan_pid = data.get('action_applied')[LoanAction.CHECKOUT].get('loan_pid')

from rero_ils.modules.patrons.views import \
get_patron_from_checkout_item_pid
assert get_patron_from_checkout_item_pid(item.pid) == patron

res = client.post(
url_for('api_item.checkin'),
data=json.dumps(
Expand Down
4 changes: 2 additions & 2 deletions tests/api/test_loans_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from invenio_accounts.testutils import login_user_via_session


def test_loans_permissions(client, loan_pedning, json_header):
def test_loans_permissions(client, loan_pending, json_header):
"""Test record retrieval."""
item_url = url_for('invenio_records_rest.loanid_item', pid_value='1')
post_url = url_for('invenio_records_rest.loanid_list')
Expand All @@ -56,7 +56,7 @@ def test_loans_permissions(client, loan_pedning, json_header):
assert res.status_code == 401


def test_loans_logged_permissions(client, loan_pedning,
def test_loans_logged_permissions(client, loan_pending,
librarian_martigny_no_email,
json_header):
"""Test record retrieval."""
Expand Down
5 changes: 5 additions & 0 deletions tests/api/test_patrons_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@

import mock
from flask import url_for
from invenio_accounts.testutils import login_user_via_session
from utils import VerifyRecordPermissionPatch, get_json, to_relative_url

from rero_ils.modules.items.api import ItemStatus
from rero_ils.modules.loans.api import Loan, LoanAction
from rero_ils.modules.patrons.utils import user_has_patron


def test_patrons_permissions(client, librarian_martigny_no_email,
json_header):
Expand Down
152 changes: 152 additions & 0 deletions tests/api/test_patrons_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#
# 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 Views for patrons."""

import json

import mock
import pytest
from flask import url_for
from invenio_accounts.testutils import login_user_via_session
from utils import VerifyRecordPermissionPatch, get_json, to_relative_url

from rero_ils.modules.items.api import ItemStatus
from rero_ils.modules.loans.api import Loan, LoanAction
from rero_ils.modules.patrons.cli import import_users
from rero_ils.modules.patrons.listener import func_item_at_desk, \
listener_item_at_desk
from rero_ils.modules.patrons.utils import user_has_patron


def test_patron_can_delete(client, librarian_martigny_no_email,
patron_martigny_no_email, loc_public_martigny,
item_lib_martigny, json_header,
circulation_policies):
"""Test patron can delete."""
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
data = get_json(res)
loan_pid = data.get('action_applied')[LoanAction.REQUEST].get('loan_pid')

links = patron_martigny_no_email.get_links_to_me()
assert 'loans' in links

assert not patron_martigny_no_email.can_delete

reasons = patron_martigny_no_email.reasons_not_to_delete()
assert 'links' in reasons

item.cancel_loan(loan_pid=loan_pid)
assert item.status == ItemStatus.ON_SHELF


def test_patron_utils(client, librarian_martigny_no_email,
patron_martigny_no_email, loc_public_martigny,
item_lib_martigny, json_header,
circulation_policies, librarian_martigny):
"""Test patron utils."""
login_user_via_session(client, librarian_martigny_no_email.user)
item = item_lib_martigny
patron = patron_martigny_no_email
location = loc_public_martigny

from rero_ils.modules.patrons.views import get_location_name_from_pid
assert get_location_name_from_pid(loc_public_martigny.pid) == \
location.get('name')

from rero_ils.modules.patrons.views import get_patron_from_pid
assert get_patron_from_pid(patron.pid) == patron

from rero_ils.modules.patrons.views import get_checkout_loan_for_item
assert not get_checkout_loan_for_item(item.pid)

from rero_ils.modules.patrons.views import get_patron_from_barcode
assert get_patron_from_barcode(patron.get('barcode')) == patron


def test_librarian_pickup_locations(client, librarian_martigny_no_email,
lib_martigny, loc_public_martigny,
patron_martigny_no_email,
patron_martigny):
"""Test get librarian pickup locations."""
login_user_via_session(client, librarian_martigny_no_email.user)

with mock.patch(
'rero_ils.modules.patrons.api.current_patron',
librarian_martigny_no_email
):
assert user_has_patron
pick = librarian_martigny_no_email.get_librarian_pickup_location_pid()
assert pick == loc_public_martigny.pid

with mock.patch(
'rero_ils.modules.patrons.api.current_patron',
patron_martigny
):
assert user_has_patron
pick = librarian_martigny_no_email.get_librarian_pickup_location_pid()
assert not pick
record = patron_martigny
del record['roles']
assert user_has_patron


def test_patron_listener(client, librarian_martigny_no_email,
item_lib_fully,
lib_fully, loc_public_martigny,
patron_martigny_no_email,
patron_martigny,
loan_pending):
"""Test patron listener."""
login_user_via_session(client, librarian_martigny_no_email.user)
requests = item_lib_fully.number_of_requests()
assert requests == 1
for request in item_lib_fully.get_requests():
item_lib_fully.validate_request(**request)
item_lib_fully.receive(**loan_pending)

with mock.patch(
'rero_ils.modules.ext.current_admin',
{}
):
sender = {}
data = {'item': item_lib_fully}
with mock.patch('rero_ils.utils.send_mail'):
with pytest.raises(AttributeError):
assert listener_item_at_desk(sender, **data)
1 change: 1 addition & 0 deletions tests/data/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,7 @@
"patron_pid": "ptrn1",
"start_date": "2019-01-09T08:18:22.576291+00:00",
"end_date": "2019-02-08T08:18:22.576291+00:00",
"pickup_location_pid": "loc1",
"transaction_date": "2019-01-09T08:18:22.576291+00:00",
"transaction_location_pid": "loc1",
"transaction_user_pid": "ptrn1"
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/circulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def loan_data_tmp(data):


@pytest.fixture(scope="module")
def loan_pedning(
def loan_pending(
app,
item_lib_fully,
loc_public_martigny,
Expand Down
Loading