"""Tests for Report Payment Handlers.""" from unittest.mock import call, patch from flask import abort from payment.blueprints.report_payment import ( ReportPaymentDetailSchema, ReportPaymentDownloadSchema, ReportPaymentPutSchema, ) from payment.constants.constants import REPORT_TYPE from payment.logic.exceptions import LogicError from tests.utils.factories import ReportPaymentFactory @patch('payment.connectors.s3.get_object_metadata_by_s3_url') @patch('payment.blueprints.report_payment.logic.create_or_update_report_payment') def test_create_or_update_report_payment_success( mock_logic, mock_s3, fixture_client, faker, mocker ) -> None: mock_filename = faker.file_name(extension='pdf') mock_s3.return_value = {'Metadata': {'original_filename': mock_filename}} payload = { 'report_type': REPORT_TYPE.APPROVAL, 'report_export_url': faker.uri(), } expected = { 'target_type': f'{faker.word()}_{faker.word()}', 'target_id': faker.pyint(), **payload, } url = ( f'/reports/{expected["target_type"].replace("_", "-")}/{expected["target_id"]}/' ) mock_logic.return_value = ReportPaymentFactory.build(**expected) spy_validation = mocker.spy(ReportPaymentPutSchema, 'load') spy_serialization = mocker.spy(ReportPaymentDetailSchema, 'dump') resp = fixture_client.put(url, json=payload) assert resp.status_code == 200 assert resp.json.items() >= expected.items() assert spy_validation.called assert spy_serialization.called assert mock_logic.call_args_list == [call(**expected)] @patch('payment.blueprints.report_payment.logic.create_or_update_report_payment') def test_create_or_update_report_payment_failure_params( mock_logic, fixture_client, mocker ) -> None: spy_validation = mocker.spy(ReportPaymentPutSchema, 'load') response = fixture_client.put('/reports/some-type/123/', json={}) assert response.status_code == 400 assert spy_validation.called assert not mock_logic.called @patch('payment.blueprints.report_payment.logic.create_or_update_report_payment') def test_create_or_update_report_payment_failure_logic( mock_logic, fixture_client, faker, mocker ) -> None: payload = { 'report_type': REPORT_TYPE.APPROVAL, 'report_export_url': faker.uri(), } expected = {'target_type': faker.word(), 'target_id': faker.pyint(), **payload} url = f'/reports/{expected["target_type"]}/{expected["target_id"]}/' mock_logic.side_effect = LogicError('Some logic error') spy_validation = mocker.spy(ReportPaymentPutSchema, 'load') resp = fixture_client.put(url, json=payload) assert resp.status_code == 400 assert spy_validation.called assert mock_logic.call_args_list == [call(**expected)] @patch('payment.connectors.s3.get_object_metadata_by_s3_url') @patch('payment.blueprints.report_payment.logic.get_reports_by_target') def test_get_reports_by_target_success( mock_logic, mock_s3, fixture_client, faker, mocker ) -> None: mock_filename = faker.file_name(extension='pdf') mock_s3.return_value = {'Metadata': {'original_filename': mock_filename}} target_type = f'{faker.word()}_{faker.word()}' target_id = faker.pyint() url = f'/reports/{target_type.replace("_", "-")}/{target_id}/' expected = { 'target_type': target_type, 'target_id': target_id, 'report_type': REPORT_TYPE.APPROVAL, 'report_export_url': faker.uri(), } mock_logic.return_value = [ReportPaymentFactory.build(**expected)] spy_serialization = mocker.spy(ReportPaymentDetailSchema, 'dump') resp = fixture_client.get(url) assert resp.status_code == 200 assert resp.json[0].items() >= expected.items() assert mock_logic.call_args_list == [ call(target_type=target_type, target_id=target_id) ] assert spy_serialization.called @patch('payment.blueprints.report_payment.logic.get_reports_by_target') def test_get_reports_by_target_empty_list( mock_logic, fixture_client, faker, mocker ) -> None: target_type = faker.word() target_id = faker.pyint() url = f'/reports/{target_type}/{target_id}/' mock_logic.return_value = [] spy_serialization = mocker.spy(ReportPaymentDetailSchema, 'dump') resp = fixture_client.get(url) assert resp.status_code == 200 assert resp.json == [] assert mock_logic.call_args_list == [ call(target_type=target_type, target_id=target_id) ] assert spy_serialization.called @patch('payment.blueprints.report_payment.logic.get_reports_by_target') def test_get_reports_by_target_failure_logic(mock_logic, fixture_client, faker) -> None: target_type = faker.word() target_id = faker.pyint() url = f'/reports/{target_type}/{target_id}/' mock_logic.side_effect = LogicError('Some logic error') resp = fixture_client.get(url) assert resp.status_code == 400 assert mock_logic.call_args_list == [ call(target_type=target_type, target_id=target_id) ] @patch('payment.blueprints.report_payment.logic.get_download') def test_get_download_success(mock_logic, fixture_client, faker, mocker) -> None: report_payment_id = faker.pyint() url = f'/report-payment/{report_payment_id}/download/' expected = { 'download_url': faker.uri(), } mock_logic.return_value = expected spy_serialization = mocker.spy(ReportPaymentDownloadSchema, 'dump') resp = fixture_client.get(url) assert resp.status_code == 200 assert resp.json == expected assert mock_logic.call_args_list == [call(report_payment_id=report_payment_id)] assert spy_serialization.called @patch('payment.blueprints.report_payment.logic.get_download') def test_get_download_not_found(mock_logic, fixture_client, faker) -> None: report_payment_id = faker.pyint() url = f'/report-payment/{report_payment_id}/download/' mock_logic.side_effect = lambda *args, **kwargs: abort(404) resp = fixture_client.get(url) assert resp.status_code == 404 assert mock_logic.call_args_list == [call(report_payment_id=report_payment_id)] @patch('payment.blueprints.report_payment.logic.get_report_payment') def test_get_report_payment_success(mock_logic, fixture_client, faker, mocker) -> None: report_payment_id = faker.pyint() url = f'/report-payment/{report_payment_id}/' expected = { 'target_type': faker.word(), 'target_id': report_payment_id, 'report_type': REPORT_TYPE.APPROVAL, 'report_export_url': faker.uri(), } mock_logic.return_value = expected spy_serialization = mocker.spy(ReportPaymentDetailSchema, 'dump') resp = fixture_client.get(url) assert resp.status_code == 200 assert resp.json == expected assert mock_logic.call_args_list == [call(report_payment_id=report_payment_id)] assert spy_serialization.called @patch('payment.blueprints.report_payment.logic.get_report_payment') def test_get_report_payment_not_found(mock_logic, fixture_client, faker) -> None: report_payment_id = faker.pyint() url = f'/report-payment/{report_payment_id}/' mock_logic.side_effect = lambda *args, **kwargs: abort(404) resp = fixture_client.get(url) assert resp.status_code == 404 assert mock_logic.call_args_list == [call(report_payment_id=report_payment_id)]