diff --git a/app/complaint/complaint_rest.py b/app/complaint/complaint_rest.py index 88123d796..91743e27e 100644 --- a/app/complaint/complaint_rest.py +++ b/app/complaint/complaint_rest.py @@ -1,13 +1,12 @@ from datetime import datetime from flask import Blueprint, jsonify, request -from sqlalchemy import desc from app.complaint.complaint_schema import complaint_count_request -from app.dao.complaint_dao import fetch_count_of_complaints +from app.dao.complaint_dao import fetch_count_of_complaints, fetch_paginated_complaints from app.errors import register_errors -from app.models import Complaint from app.schema_validation import validate +from app.utils import pagination_links complaint_blueprint = Blueprint('complaint', __name__, url_prefix='/complaint') @@ -16,9 +15,17 @@ register_errors(complaint_blueprint) @complaint_blueprint.route('', methods=['GET']) def get_all_complaints(): - complaints = Complaint.query.order_by(desc(Complaint.created_at)).all() + page = int(request.args.get('page', 1)) + pagination = fetch_paginated_complaints(page=page) - return jsonify([x.serialize() for x in complaints]), 200 + return jsonify( + complaints=[x.serialize() for x in pagination.items], + links=pagination_links( + pagination, + '.get_all_complaints', + **request.args.to_dict() + ) + ), 200 @complaint_blueprint.route('/count-by-date-range', methods=['GET']) diff --git a/app/dao/complaint_dao.py b/app/dao/complaint_dao.py index e23a28955..e7840fe70 100644 --- a/app/dao/complaint_dao.py +++ b/app/dao/complaint_dao.py @@ -1,5 +1,6 @@ from datetime import timedelta +from flask import current_app from sqlalchemy import desc from app import db @@ -13,6 +14,15 @@ def save_complaint(complaint): db.session.add(complaint) +def fetch_paginated_complaints(page=1): + return Complaint.query.order_by( + desc(Complaint.created_at) + ).paginate( + page=page, + per_page=current_app.config['PAGE_SIZE'] + ) + + def fetch_complaints_by_service(service_id): return Complaint.query.filter_by(service_id=service_id).order_by(desc(Complaint.created_at)).all() diff --git a/tests/app/complaint/test_complaint_rest.py b/tests/app/complaint/test_complaint_rest.py index 17de1406d..0fa97f2d7 100644 --- a/tests/app/complaint/test_complaint_rest.py +++ b/tests/app/complaint/test_complaint_rest.py @@ -8,7 +8,7 @@ from tests import create_authorization_header from tests.app.db import create_complaint, create_service, create_template, create_notification -def test_get_all_complaints_returns_list_for_multiple_services_and_complaints(client, notify_db_session): +def test_get_all_complaints_returns_complaints_for_multiple_services(client, notify_db_session): service = create_service(service_name='service1') template = create_template(service=service) notification = create_notification(template=template) @@ -18,14 +18,33 @@ def test_get_all_complaints_returns_list_for_multiple_services_and_complaints(cl response = client.get('/complaint', headers=[create_authorization_header()]) assert response.status_code == 200 - assert json.loads(response.get_data(as_text=True)) == [complaint_2.serialize(), complaint_1.serialize()] + assert json.loads(response.get_data(as_text=True))['complaints'] == [ + complaint_2.serialize(), complaint_1.serialize()] -def test_get_all_complaints_returns_empty_list(client): +def test_get_all_complaints_returns_empty_complaints_list(client): response = client.get('/complaint', headers=[create_authorization_header()]) assert response.status_code == 200 - assert json.loads(response.get_data(as_text=True)) == [] + assert json.loads(response.get_data(as_text=True))['complaints'] == [] + + +def test_get_all_complaints_returns_pagination_links(mocker, client, notify_db_session): + mocker.patch.dict('app.dao.complaint_dao.current_app.config', {'PAGE_SIZE': 1}) + service_1 = create_service(service_name='service1') + service_2 = create_service(service_name='service2') + + create_complaint() + create_complaint(service=service_1) + create_complaint(service=service_2) + + response = client.get(url_for('complaint.get_all_complaints', page=2), headers=[create_authorization_header()]) + + assert response.status_code == 200 + assert json.loads(response.get_data(as_text=True))['links'] == { + 'last': '/complaint?page=3', + 'next': '/complaint?page=3', + 'prev': '/complaint?page=1'} def test_get_complaint_with_start_and_end_date_passes_these_to_dao_function(mocker, client): diff --git a/tests/app/dao/test_complaint_dao.py b/tests/app/dao/test_complaint_dao.py index 5533f43f7..14b7cac53 100644 --- a/tests/app/dao/test_complaint_dao.py +++ b/tests/app/dao/test_complaint_dao.py @@ -2,11 +2,40 @@ import uuid from datetime import datetime, timedelta -from app.dao.complaint_dao import save_complaint, fetch_complaints_by_service, fetch_count_of_complaints +from app.dao.complaint_dao import ( + fetch_complaints_by_service, + fetch_count_of_complaints, + fetch_paginated_complaints, + save_complaint, +) from app.models import Complaint from tests.app.db import create_service, create_template, create_notification, create_complaint +def test_fetch_paginated_complaints(mocker, sample_email_notification): + mocker.patch.dict('app.dao.complaint_dao.current_app.config', {'PAGE_SIZE': 2}) + create_complaint(service=sample_email_notification.service, + notification=sample_email_notification, + created_at=datetime(2018, 1, 1)) + create_complaint(service=sample_email_notification.service, + notification=sample_email_notification, + created_at=datetime(2018, 1, 2)) + create_complaint(service=sample_email_notification.service, + notification=sample_email_notification, + created_at=datetime(2018, 1, 3)) + + res = fetch_paginated_complaints(page=1) + + assert len(res.items) == 2 + assert res.items[0].created_at == datetime(2018, 1, 3) + assert res.items[1].created_at == datetime(2018, 1, 2) + + res = fetch_paginated_complaints(page=2) + + assert len(res.items) == 1 + assert res.items[0].created_at == datetime(2018, 1, 1) + + def test_fetch_complaint_by_service_returns_one(sample_service, sample_email_notification): complaint = Complaint(notification_id=sample_email_notification.id, service_id=sample_service.id,