"""Unit tests for report_payment_group_payment handlers.""" from unittest.mock import call, patch from flask import abort from payment.blueprints.report_payment_group_payment import ( ReportPaymentGroupPaymentDetailSchema, ReportPaymentGroupPaymentDownloadSchema, ReportPaymentGroupPaymentPutSchema, ) from payment.constants.constants import REPORT_TYPE from tests.utils.factories import ReportPaymentGroupPaymentFactory @patch('payment.blueprints.report_payment_group_payment.logic.create_or_update_report') def test_create_or_update_report_created(mock_logic, fixture_client, faker, mocker): """Test PUT /payment-group-payment//report returns 201 when report is created.""" payment_group_payment_id = faker.pyint() payload = { 'report_export_url': faker.uri(), 'report_type': REPORT_TYPE.SUMMARY, } expected = {'payment_group_payment_id': payment_group_payment_id, **payload} mock_logic.return_value = ( ReportPaymentGroupPaymentFactory.build( report_payment_group_payment_id=faker.pyint(), **expected ), True, ) spy_validation = mocker.spy(ReportPaymentGroupPaymentPutSchema, 'load') spy_serialization = mocker.spy(ReportPaymentGroupPaymentDetailSchema, 'dump') resp = fixture_client.put( f'/payment-group-payment/{payment_group_payment_id}/report', json=payload ) assert resp.status_code == 201 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_group_payment.logic.create_or_update_report') def test_create_or_update_report_updated(mock_logic, fixture_client, faker, mocker): """Test PUT /payment-group-payment//report returns 200 when report is updated.""" payment_group_payment_id = faker.pyint() payload = { 'report_export_url': faker.uri(), 'report_type': REPORT_TYPE.SUMMARY, } expected = {'payment_group_payment_id': payment_group_payment_id, **payload} mock_logic.return_value = ( ReportPaymentGroupPaymentFactory.build( report_payment_group_payment_id=faker.pyint(), **expected ), False, ) spy_validation = mocker.spy(ReportPaymentGroupPaymentPutSchema, 'load') spy_serialization = mocker.spy(ReportPaymentGroupPaymentDetailSchema, 'dump') resp = fixture_client.put( f'/payment-group-payment/{payment_group_payment_id}/report', 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_group_payment.logic.create_or_update_report') def test_create_or_update_report_invalid_params( mock_logic, fixture_client, faker, mocker ): """Test PUT /payment-group-payment//report with missing required fields returns 400.""" payment_group_payment_id = faker.pyint() spy_validation = mocker.spy(ReportPaymentGroupPaymentPutSchema, 'load') resp = fixture_client.put( f'/payment-group-payment/{payment_group_payment_id}/report', json={} ) assert resp.status_code == 400 assert spy_validation.called assert not mock_logic.called @patch('payment.blueprints.report_payment_group_payment.logic.get_report') def test_get_report_success(mock_logic, fixture_client, faker, mocker): """Test GET /report-payment-group-payment/ success.""" report_id = faker.pyint() expected = { 'payment_group_payment_id': faker.pyint(), 'report_export_url': faker.uri(), 'report_type': REPORT_TYPE.SUMMARY, } mock_logic.return_value = ReportPaymentGroupPaymentFactory.build( report_payment_group_payment_id=report_id, **expected ) spy_serialization = mocker.spy(ReportPaymentGroupPaymentDetailSchema, 'dump') resp = fixture_client.get(f'/report-payment-group-payment/{report_id}') assert resp.status_code == 200 assert resp.json.items() >= expected.items() assert spy_serialization.called assert mock_logic.call_args_list == [ call(report_payment_group_payment_id=report_id) ] @patch('payment.blueprints.report_payment_group_payment.logic.get_report') def test_get_report_not_found(mock_logic, fixture_client, faker): """Test GET /report-payment-group-payment/ returns 404 when not found.""" report_id = faker.pyint() mock_logic.side_effect = lambda *args, **kwargs: abort(404) resp = fixture_client.get(f'/report-payment-group-payment/{report_id}') assert resp.status_code == 404 assert mock_logic.call_args_list == [ call(report_payment_group_payment_id=report_id) ] @patch('payment.blueprints.report_payment_group_payment.logic.delete_report') def test_delete_report_success(mock_logic, fixture_client, faker): """Test DELETE /report-payment-group-payment/ success returns 204.""" report_id = faker.pyint() resp = fixture_client.delete(f'/report-payment-group-payment/{report_id}') assert resp.status_code == 204 assert resp.data == b'' assert mock_logic.call_args_list == [ call(report_payment_group_payment_id=report_id) ] @patch('payment.blueprints.report_payment_group_payment.logic.delete_report') def test_delete_report_not_found(mock_logic, fixture_client, faker): """Test DELETE /report-payment-group-payment/ returns 404 when not found.""" report_id = faker.pyint() mock_logic.side_effect = lambda *args, **kwargs: abort(404) resp = fixture_client.delete(f'/report-payment-group-payment/{report_id}') assert resp.status_code == 404 assert mock_logic.call_args_list == [ call(report_payment_group_payment_id=report_id) ] @patch('payment.blueprints.report_payment_group_payment.logic.get_download') def test_download_report_success(mock_logic, fixture_client, faker, mocker): """Test GET /report-payment-group-payment//download success.""" report_id = faker.pyint() expected = {'download_url': faker.uri()} mock_logic.return_value = expected spy_serialization = mocker.spy(ReportPaymentGroupPaymentDownloadSchema, 'dump') resp = fixture_client.get(f'/report-payment-group-payment/{report_id}/download') assert resp.status_code == 200 assert resp.json == expected assert spy_serialization.called assert mock_logic.call_args_list == [ call(report_payment_group_payment_id=report_id) ] @patch('payment.blueprints.report_payment_group_payment.logic.get_download') def test_download_report_not_found(mock_logic, fixture_client, faker): """Test GET /report-payment-group-payment//download returns 404 when not found.""" report_id = faker.pyint() mock_logic.side_effect = lambda *args, **kwargs: abort(404) resp = fixture_client.get(f'/report-payment-group-payment/{report_id}/download') assert resp.status_code == 404 assert mock_logic.call_args_list == [ call(report_payment_group_payment_id=report_id) ] @patch( 'payment.blueprints.report_payment_group_payment.logic.get_by_payment_group_payment' ) def test_get_reports_by_payment_group_payment_success( mock_logic, fixture_client, faker, mocker ): """Test GET /payment-group-payment//reports success.""" payment_group_payment_id = faker.pyint() mock_report = ReportPaymentGroupPaymentFactory.build( payment_group_payment_id=payment_group_payment_id, report_export_url=faker.uri(), report_type=REPORT_TYPE.SUMMARY, ) mock_logic.return_value = [mock_report] spy_serialization = mocker.spy(ReportPaymentGroupPaymentDetailSchema, 'dump') resp = fixture_client.get( f'/payment-group-payment/{payment_group_payment_id}/reports' ) assert resp.status_code == 200 assert isinstance(resp.json, list) assert spy_serialization.called assert mock_logic.call_args_list == [ call(payment_group_payment_id=payment_group_payment_id) ] @patch( 'payment.blueprints.report_payment_group_payment.logic.get_by_payment_group_payment' ) def test_get_reports_by_payment_group_payment_not_found( mock_logic, fixture_client, faker ): """Test GET /payment-group-payment//reports returns 404 when parent not found.""" payment_group_payment_id = faker.pyint() mock_logic.side_effect = lambda *args, **kwargs: abort(404) resp = fixture_client.get( f'/payment-group-payment/{payment_group_payment_id}/reports' ) assert resp.status_code == 404 assert mock_logic.call_args_list == [ call(payment_group_payment_id=payment_group_payment_id) ]