def test_create_duplicate_refund_for_paid_invoice(session, monkeypatch): """Assert that the create duplicate refund fails for paid invoices.""" payment_account = factory_payment_account() payment_account.save() i = factory_invoice(payment_account=payment_account) i.save() inv_ref = factory_invoice_reference(i.id) inv_ref.status_code = InvoiceReferenceStatus.COMPLETED.value inv_ref.save() payment = factory_payment(invoice_number=inv_ref.invoice_number).save() factory_payment_transaction(payment_id=payment.id, status_code=TransactionStatus.COMPLETED.value).save() i.invoice_status_code = InvoiceStatus.PAID.value i.save() factory_receipt(invoice_id=i.id).save() monkeypatch.setattr('pay_api.services.payment_transaction.publish_response', lambda *args, **kwargs: None) RefundService.create_refund(invoice_id=i.id, request={'reason': 'Test'}) i = InvoiceModel.find_by_id(i.id) payment: PaymentModel = PaymentModel.find_by_id(payment.id) assert i.invoice_status_code == InvoiceStatus.REFUND_REQUESTED.value assert payment.payment_status_code == PaymentStatus.REFUNDED.value with pytest.raises(Exception) as excinfo: RefundService.create_refund(invoice_id=i.id, request={'reason': 'Test'}) assert excinfo.type == BusinessException
def test_create_refund_for_paid_invoice(session, monkeypatch, payment_method, invoice_status, pay_status, has_reference, expected_inv_status): """Assert that the create refund succeeds for paid invoices.""" expected = REFUND_SUCCESS_MESSAGES[f'{payment_method}.{invoice_status}'] payment_account = factory_payment_account() payment_account.save() i = factory_invoice(payment_account=payment_account, payment_method_code=payment_method) i.save() if has_reference: inv_ref = factory_invoice_reference(i.id) inv_ref.status_code = InvoiceReferenceStatus.COMPLETED.value inv_ref.save() payment = factory_payment(invoice_number=inv_ref.invoice_number, payment_status_code=pay_status).save() factory_payment_transaction(payment_id=payment.id, status_code=TransactionStatus.COMPLETED.value).save() i.invoice_status_code = invoice_status i.save() factory_receipt(invoice_id=i.id).save() monkeypatch.setattr('pay_api.services.payment_transaction.publish_response', lambda *args, **kwargs: None) message = RefundService.create_refund(invoice_id=i.id, request={'reason': 'Test'}) i = InvoiceModel.find_by_id(i.id) assert i.invoice_status_code == expected_inv_status assert message['message'] == expected
def test_find_older_records_invalid_status(session): """Assert a payment_transaction is stored. Start with a blank database. """ payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.save() invoice = factory_invoice(payment=payment, payment_account=payment_account) invoice.save() payment_transaction_now = factory_payment_transaction( payment_id=payment.id, status_code='COMPLETED') payment_transaction_now.save() # not eligible payment_transaction_now_draft = factory_payment_transaction( payment_id=payment.id, status_code='CREATED') payment_transaction_now_draft.save() # not eligible payment_transaction_now_draft_3_hours = factory_payment_transaction( payment_id=payment.id, status_code='CREATED', transaction_start_time=datetime.now() - timedelta(hours=3)) payment_transaction_now_draft_3_hours.save() # this is eligible payment_transaction_now_draft_completed_3_hours = factory_payment_transaction( payment_id=payment.id, status_code='COMPLETED', transaction_start_time=datetime.now() - timedelta(hours=3)) payment_transaction_now_draft_completed_3_hours.save() # not eligible all_records = payment_transaction_now.find_stale_records( hours=2, minutes=59) # find records which are 2.59 hourolder assert len(all_records) == 1
def test_create_receipt_without_invoice(session, public_user_mock): """Try creating a receipt without invoice number.""" payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.save() invoice = factory_invoice(payment.id, payment_account.id) invoice.save() factory_invoice_reference(invoice.id).save() fee_schedule = FeeSchedule.find_by_filing_type_and_corp_type('CP', 'OTANN') line = factory_payment_line_item( invoice.id, fee_schedule_id=fee_schedule.fee_schedule_id) line.save() transaction = factory_payment_transaction(payment.id) transaction.save() PaymentService.update_payment(payment.id, get_payment_request()) input_data = { 'corpName': 'Pennsular Coop ', 'filingDateTime': '1999', 'fileName': 'coopser' } response = ReceiptService.create_receipt(payment.id, '', input_data, skip_auth_check=True) assert response is not None
def test_payment_put_incomplete_input(session, client, jwt, app): """Assert that the endpoint returns 400.""" token = jwt.create_jwt(get_claims(), token_header) headers = { 'Authorization': f'Bearer {token}', 'content-type': 'application/json' } rv = client.post(f'/api/v1/payment-requests', data=json.dumps(get_payment_request()), headers=headers) pay_id = rv.json.get('id') transaction = factory_payment_transaction(pay_id) transaction.save() data = { 'businessInfo': { 'businessIdentifier': 'CP0001234', 'corpType': 'CP', 'businessName': 'ABC Corp', 'contactInfo': { 'city': 'Victoria', 'postalCode': 'V8P2P2', 'province': 'BC', 'addressLine1': '100 Douglas Street', 'country': 'CA' } } } rv = client.put(f'/api/v1/payment-requests/{pay_id}', data=json.dumps(data), headers=headers) assert rv.status_code == 400
def test_transaction_find_active_lookup(session): """Invalid lookup..""" payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.save() invoice = factory_invoice(payment, payment_account) invoice.save() factory_invoice_reference(invoice.id).save() fee_schedule = FeeSchedule.find_by_filing_type_and_corp_type('CP', 'OTANN') line = factory_payment_line_item( invoice.id, fee_schedule_id=fee_schedule.fee_schedule_id) line.save() transaction = factory_payment_transaction(payment.id, Status.CREATED.value) transaction.save() transaction = PaymentTransactionService.find_active_by_payment_id( payment.id) assert transaction is not None assert transaction.id is not None assert transaction.status_code is not None assert transaction.payment_id is not None assert transaction.client_system_url is not None assert transaction.pay_system_url is not None assert transaction.transaction_start_time is not None assert transaction.status_code == Status.CREATED.value
def test_delete_payment(session, auth_mock, public_user_mock): """Assert that the payment records are soft deleted.""" payment_account = factory_payment_account() # payment = factory_payment() payment_account.save() # payment.save() invoice = factory_invoice(payment_account, total=10) invoice.save() invoice_reference = factory_invoice_reference(invoice.id).save() # Create a payment for this reference payment = factory_payment(invoice_number=invoice_reference.invoice_number, invoice_amount=10).save() fee_schedule = FeeSchedule.find_by_filing_type_and_corp_type('CP', 'OTANN') line = factory_payment_line_item( invoice.id, fee_schedule_id=fee_schedule.fee_schedule_id) line.save() transaction = factory_payment_transaction(payment.id) transaction.save() PaymentService.delete_invoice(invoice.id) invoice = Invoice.find_by_id(invoice.id) payment = Payment.find_by_id(payment.id) assert invoice.invoice_status_code == InvoiceStatus.DELETED.value assert payment.payment_status_code == PaymentStatus.DELETED.value
def test_find_older_records(session): """Assert a payment_transaction is stored. Start with a blank database. """ payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.save() invoice = factory_invoice(payment_account=payment_account) invoice.save() payment_transaction_now = factory_payment_transaction(payment_id=payment.id) payment_transaction_now.save() payment_transaction_100_days_old = factory_payment_transaction( payment_id=payment.id, transaction_start_time=datetime.now() - timedelta(days=100)) payment_transaction_100_days_old.save() payment_transaction_3_hours_old = factory_payment_transaction( payment_id=payment.id, transaction_start_time=datetime.now() - timedelta( hours=3)) payment_transaction_3_hours_old.save() payment_transaction_1_hour_old = factory_payment_transaction( payment_id=payment.id, transaction_start_time=datetime.now() - timedelta( hours=1)) payment_transaction_1_hour_old.save() payment_transaction_2_hours_old = factory_payment_transaction( payment_id=payment.id, transaction_start_time=datetime.now() - timedelta( hours=2)) payment_transaction_2_hours_old.save() all_records = payment_transaction_now.find_stale_records(hours=2, minutes=10) # find records which are 2.10 hours older assert len(all_records) == 2 for record in all_records: assert record.transaction_start_time < datetime.now() - timedelta(hours=2)
def test_payment_transaction(session): """Assert a payment_transaction is stored. Start with a blank database. """ payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.save() invoice = factory_invoice(payment=payment, payment_account=payment_account) invoice.save() payment_transaction = factory_payment_transaction(payment_id=payment.id) payment_transaction.save() assert payment_transaction.id is not None
def test_update_payment_record(session, public_user_mock): """Assert that the payment records are updated.""" payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.save() invoice = factory_invoice(payment, payment_account) invoice.save() factory_invoice_reference(invoice.id).save() fee_schedule = FeeSchedule.find_by_filing_type_and_corp_type('CP', 'OTANN') line = factory_payment_line_item(invoice.id, fee_schedule_id=fee_schedule.fee_schedule_id) line.save() transaction = factory_payment_transaction(payment.id) transaction.save() payment_response = PaymentService.update_payment(payment.id, get_payment_request(), get_auth_basic_user()) assert payment_response.get('id') is not None
def test_delete_completed_payment(session, auth_mock): """Assert that the payment records are soft deleted.""" payment_account = factory_payment_account() payment = factory_payment(payment_status_code=PaymentStatus.COMPLETED.value) payment_account.save() payment.save() invoice = factory_invoice(payment, payment_account) invoice.save() factory_invoice_reference(invoice.id).save() fee_schedule = FeeSchedule.find_by_filing_type_and_corp_type('CP', 'OTANN') line = factory_payment_line_item(invoice.id, fee_schedule_id=fee_schedule.fee_schedule_id) line.save() transaction = factory_payment_transaction(payment.id) transaction.save() with pytest.raises(Exception) as excinfo: PaymentService.delete_payment(payment.id) assert excinfo.type == BusinessException
def test_payment_put(session, client, jwt, app): """Assert that the endpoint returns 200.""" token = jwt.create_jwt(get_claims(), token_header) headers = { 'Authorization': f'Bearer {token}', 'content-type': 'application/json' } rv = client.post(f'/api/v1/payment-requests', data=json.dumps(get_payment_request()), headers=headers) pay_id = rv.json.get('id') transaction = factory_payment_transaction(pay_id) transaction.save() rv = client.put(f'/api/v1/payment-requests/{pay_id}', data=json.dumps(get_payment_request()), headers=headers) assert rv.status_code == 200
def test_transaction_find_active_none_lookup(session): """Invalid lookup..""" payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.save() invoice = factory_invoice(payment, payment_account) invoice.save() factory_invoice_reference(invoice.id).save() fee_schedule = FeeSchedule.find_by_filing_type_and_corp_type('CP', 'OTANN') line = factory_payment_line_item( invoice.id, fee_schedule_id=fee_schedule.fee_schedule_id) line.save() transaction = factory_payment_transaction(payment.id, Status.COMPLETED.value) transaction.save() transaction = PaymentTransactionService.find_active_by_payment_id( payment.id) assert transaction is None
def test_transaction_find_by_payment_id(session): """Find all transactions by payment id..""" payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.save() invoice = factory_invoice(payment, payment_account) invoice.save() factory_invoice_reference(invoice.id).save() fee_schedule = FeeSchedule.find_by_filing_type_and_corp_type('CP', 'OTANN') line = factory_payment_line_item( invoice.id, fee_schedule_id=fee_schedule.fee_schedule_id) line.save() transaction = factory_payment_transaction(payment.id, Status.CREATED.value) transaction.save() transaction = PaymentTransactionService.find_by_payment_id(payment.id) assert transaction is not None assert transaction.get('items') is not None assert transaction.get('items')[0].get('_links') is not None
def test_update_payment_deleted_invalid(session, public_user_mock): """Assert that the payment records are not updated.""" payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.payment_status_code = PaymentStatus.DELETED.value payment.save() invoice = factory_invoice(payment, payment_account) invoice.save() factory_invoice_reference(invoice.id).save() fee_schedule = FeeSchedule.find_by_filing_type_and_corp_type('CP', 'OTANN') line = factory_payment_line_item(invoice.id, fee_schedule_id=fee_schedule.fee_schedule_id) line.save() transaction = factory_payment_transaction(payment.id) transaction.save() with pytest.raises(BusinessException) as excinfo: PaymentService.update_payment(payment.id, get_payment_request(), get_auth_basic_user()) assert excinfo.type == BusinessException
def test_payment_put_when_paybc_down(session, client, jwt, app): """Assert that the endpoint returns 400.""" token = jwt.create_jwt(get_claims(), token_header) headers = { 'Authorization': f'Bearer {token}', 'content-type': 'application/json' } rv = client.post(f'/api/v1/payment-requests', data=json.dumps(get_payment_request()), headers=headers) pay_id = rv.json.get('id') transaction = factory_payment_transaction(pay_id) transaction.save() with patch('pay_api.services.oauth_service.requests.post', side_effect=ConnectionError('mocked error')): rv = client.put(f'/api/v1/payment-requests/{pay_id}', data=json.dumps(get_payment_request()), headers=headers) assert rv.status_code == 400
def test_update_payment_record_rollback(session, public_user_mock): """Assert that the payment records are updated.""" payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.save() invoice = factory_invoice(payment.id, payment_account.id) invoice.save() factory_invoice_reference(invoice.id).save() fee_schedule = FeeSchedule.find_by_filing_type_and_corp_type('CP', 'OTANN') line = factory_payment_line_item( invoice.id, fee_schedule_id=fee_schedule.fee_schedule_id) line.save() transaction = factory_payment_transaction(payment.id) transaction.save() # Mock here that the invoice update fails here to test the rollback scenario with patch( 'pay_api.services.payment_transaction.PaymentTransaction.find_active_by_payment_id', side_effect=Exception('mocked error'), ): with pytest.raises(Exception) as excinfo: PaymentService.update_payment(payment.id, get_payment_request()) assert excinfo.type == Exception with patch( 'pay_api.services.payment_transaction.PaymentTransaction.update_transaction', side_effect=Exception('mocked error'), ): with pytest.raises(Exception) as excinfo: PaymentService.update_payment(payment.id, get_payment_request()) assert excinfo.type == Exception with patch('pay_api.services.payment.Payment.find_by_id', side_effect=Exception('mocked error')): with pytest.raises(Exception) as excinfo: PaymentService.update_payment(payment.id, get_payment_request()) assert excinfo.type == Exception with patch('pay_api.services.payment_line_item.PaymentLineItem.create', side_effect=Exception('mocked error')): with pytest.raises(Exception) as excinfo: PaymentService.update_payment(payment.id, get_payment_request()) assert excinfo.type == Exception # reset transaction transaction = factory_payment_transaction(payment.id) transaction.save() with patch('pay_api.services.paybc_service.PaybcService.update_invoice', side_effect=Exception('mocked error')): with pytest.raises(Exception) as excinfo: PaymentService.update_payment(payment.id, get_payment_request()) assert excinfo.type == Exception # reset transaction transaction = factory_payment_transaction(payment.id) transaction.save() with patch('pay_api.services.invoice.Invoice.find_by_id', side_effect=Exception('mocked error')): with pytest.raises(Exception) as excinfo: PaymentService.update_payment(payment.id, get_payment_request()) assert excinfo.type == Exception # reset transaction transaction = factory_payment_transaction(payment.id) transaction.save() with patch('pay_api.services.invoice.Invoice.save', side_effect=Exception('mocked error')): with pytest.raises(Exception) as excinfo: PaymentService.update_payment(payment.id, get_payment_request()) assert excinfo.type == Exception with patch('pay_api.services.payment.Payment.save', side_effect=Exception('mocked error')): with pytest.raises(Exception) as excinfo: PaymentService.update_payment(payment.id, get_payment_request()) assert excinfo.type == Exception