From 6418924fafda1a7e1b46f1f2f4c5670b13e15d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Tue, 4 Feb 2020 09:42:26 +0200 Subject: [PATCH] Cover EveryPay / BankLink payments with tests --- .../registrar/payments_controller.rb | 7 +- app/models/payment_order.rb | 15 ++-- test/fixtures/payment_orders.yml | 13 +++- .../invoices/payment_callback_test.rb | 44 ++++++------ .../invoices/payment_return_test.rb | 68 ++++++++++++++++--- test/models/payment_orders/bank_link_test.rb | 38 ++++++----- test/models/payment_orders_test.rb | 21 ++++++ 7 files changed, 145 insertions(+), 61 deletions(-) diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index a988dc57e..e356f7049 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -57,14 +57,9 @@ class Registrar private def check_supported_payment_method - return if supported_payment_method? + return if PaymentOrder.supported_method?(params[:bank], shortname: true) raise(StandardError, 'Not supported payment method') end - - def supported_payment_method? - method_name = PaymentOrder.type_from_shortname(params[:bank]) - PaymentOrder.supported_method?(method_name) - end end end diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index bc10528fc..b6fea65be 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -30,7 +30,7 @@ class PaymentOrder < ApplicationRecord end def self.create_with_type(type:, invoice:) - channel = PaymentOrder.type_from_shortname(type) + channel = ('PaymentOrders::' + type.camelize).constantize PaymentOrder.new(type: channel, invoice: invoice) end @@ -39,7 +39,7 @@ class PaymentOrder < ApplicationRecord def self.config_namespace_name; end def supported_payment_method - return if PaymentOrder.supported_method? type.constantize + return if PaymentOrder.supported_method?(type) errors.add(:type, 'is not supported') end @@ -50,11 +50,12 @@ class PaymentOrder < ApplicationRecord errors.add(:invoice, 'is already paid') end - def self.type_from_shortname(shortname) - ('PaymentOrders::' + shortname.camelize).constantize - end - - def self.supported_method?(some_class) + def self.supported_method?(name, shortname: false) + some_class = if shortname + ('PaymentOrders::' + name.camelize).constantize + else + name.constantize + end supported_methods.include? some_class rescue NameError false diff --git a/test/fixtures/payment_orders.yml b/test/fixtures/payment_orders.yml index b39d309dc..39289b7d1 100644 --- a/test/fixtures/payment_orders.yml +++ b/test/fixtures/payment_orders.yml @@ -1,20 +1,27 @@ -issued: +everypay_issued: type: PaymentOrders::EveryPay status: issued invoice: one response: notes: +banklink_issued: + type: PaymentOrders::Seb + status: issued + invoice: one + response: + notes: + paid: type: PaymentOrders::EveryPay status: paid - invoice: one + invoice: unpaid response: "{}" notes: cancelled: type: PaymentOrders::Seb status: cancelled - invoice: one + invoice: unpaid response: "{}" notes: User failed to make payment. Bank responded with code 1911 diff --git a/test/integration/registrar_area/invoices/payment_callback_test.rb b/test/integration/registrar_area/invoices/payment_callback_test.rb index c26ffa8c0..94ca6e373 100644 --- a/test/integration/registrar_area/invoices/payment_callback_test.rb +++ b/test/integration/registrar_area/invoices/payment_callback_test.rb @@ -6,34 +6,40 @@ class PaymentCallbackTest < ApplicationIntegrationTest @user = users(:api_bestnames) sign_in @user + + @payment_order = payment_orders(:everypay_issued) + @invoice = invoices(:one) + @invoice.update!(account_activity: nil, total: 12) end def test_every_pay_callback_returns_status_200 - invoice = payable_invoice - assert_matching_bank_transaction_exists(invoice) - - request_params = every_pay_request_params.merge(payment_order: invoice.id) - post "/registrar/pay/callback/every_pay", params: request_params + request_params = every_pay_request_params + post "/registrar/pay/callback/#{@payment_order.id}", params: request_params assert_response :ok end + def test_invoice_is_marked_as_paid + request_params = every_pay_request_params + post "/registrar/pay/callback/#{@payment_order.id}", params: request_params + + assert @payment_order.invoice.paid? + end + + def failure_log_is_created_if_unsuccessful_payment + request_params = every_pay_request_params.dup + request_params['payment_state'] = 'cancelled' + request_params['transaction_result'] = 'failed' + + post "/registrar/pay/callback/#{@payment_order.id}", params: request_params + + @payment_order.reload + assert @payment_order.cancelled? + assert_includes @payment_order.notes, 'Payment state: cancelled' + end + private - def payable_invoice - invoice = invoices(:one) - invoice.update!(account_activity: nil) - invoice - end - - def assert_matching_bank_transaction_exists(invoice) - assert BankTransaction.find_by( - description: invoice.description, - currency: invoice.currency, - iban: invoice.seller_iban - ), 'Matching bank transaction should exist' - end - def every_pay_request_params { nonce: "392f2d7748bc8cb0d14f263ebb7b8932", diff --git a/test/integration/registrar_area/invoices/payment_return_test.rb b/test/integration/registrar_area/invoices/payment_return_test.rb index de65cccb0..a4adb8160 100644 --- a/test/integration/registrar_area/invoices/payment_return_test.rb +++ b/test/integration/registrar_area/invoices/payment_return_test.rb @@ -8,6 +8,9 @@ class PaymentReturnTest < ApplicationIntegrationTest sign_in @user @invoice = invoices(:one) + @invoice.update!(account_activity: nil, total: 12) + @everypay_order = payment_orders(:everypay_issued) + @banklink_order = payment_orders(:banklink_issued) end def every_pay_request_params @@ -57,33 +60,78 @@ class PaymentReturnTest < ApplicationIntegrationTest } end - def test_every_pay_return_creates_activity_redirects_to_invoice_path - request_params = every_pay_request_params.merge(invoice_id: @invoice.id) + def test_successful_bank_payment_marks_invoice_as_paid + @invoice.update!(account_activity: nil) + request_params = bank_link_request_params - post "/registrar/pay/return/every_pay", params: request_params + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + + @banklink_order.reload + assert @banklink_order.invoice.paid? + end + + def test_every_pay_return_creates_activity_redirects_to_invoice_path + request_params = every_pay_request_params + + post "/registrar/pay/return/#{@everypay_order.id}", params: request_params assert_equal(302, response.status) assert_redirected_to(registrar_invoice_path(@invoice)) end - def test_Every_Pay_return_raises_RecordNotFound - request_params = every_pay_request_params.merge(invoice_id: "178907") + def test_every_pay_return_raises_record_not_found + request_params = every_pay_request_params assert_raises(ActiveRecord::RecordNotFound) do - post "/registrar/pay/return/every_pay", params: request_params + post '/registrar/pay/return/123456', params: request_params end end def test_bank_link_return_redirects_to_invoice_paths - request_params = bank_link_request_params.merge(invoice_id: @invoice.id) + request_params = bank_link_request_params - post "/registrar/pay/return/seb", params: request_params + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params assert_equal(302, response.status) assert_redirected_to(registrar_invoice_path(@invoice)) end def test_bank_link_return - request_params = bank_link_request_params.merge(invoice_id: "178907") + request_params = bank_link_request_params assert_raises(ActiveRecord::RecordNotFound) do - post "/registrar/pay/return/seb", params: request_params + post '/registrar/pay/return/123456', params: request_params end end + + def test_marks_as_paid_and_adds_notes_if_failed_to_bind + request_params = bank_link_request_params + + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + @banklink_order.reload + + assert @banklink_order.notes.present? + assert @banklink_order.paid? + assert_includes @banklink_order.notes, 'Failed to bind' + end + + def test_failed_bank_link_payment_creates_brief_error_explanation + request_params = bank_link_request_params.dup + request_params['VK_SERVICE'] = '1911' + + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + + @banklink_order.reload + + assert_includes @banklink_order.notes, 'Bank responded with code 1911' + end + + def test_failed_every_pay_payment_creates_brief_error_explanation + request_params = every_pay_request_params.dup + request_params['payment_state'] = 'cancelled' + request_params['transaction_result'] = 'failed' + + post "/registrar/pay/return/#{@everypay_order.id}", params: request_params + + @everypay_order.reload + + assert_includes @everypay_order.notes, 'Payment state: cancelled' + end end diff --git a/test/models/payment_orders/bank_link_test.rb b/test/models/payment_orders/bank_link_test.rb index 775e82cf9..7f7897f5f 100644 --- a/test/models/payment_orders/bank_link_test.rb +++ b/test/models/payment_orders/bank_link_test.rb @@ -8,7 +8,7 @@ class BankLinkTest < ActiveSupport::TestCase super @invoice = invoices(:one) - @invoice.update!(total: 12) + @invoice.update!(account_activity: nil, total: 12) travel_to '2018-04-01 00:30 +0300' create_new_bank_link @@ -63,7 +63,6 @@ class BankLinkTest < ActiveSupport::TestCase end def create_new_bank_link - params = { return_url: 'return.url', response_url: 'response.url' } @new_bank_link = PaymentOrder.new(type: 'PaymentOrders::Seb', invoice: @invoice) @new_bank_link.return_url = 'return.url' @new_bank_link.response_url = 'response.url' @@ -94,6 +93,20 @@ class BankLinkTest < ActiveSupport::TestCase assert_equal(expected_response, @new_bank_link.form_fields) end + def test_correct_channel_is_assigned + swed_link = PaymentOrder.create_with_type(type: 'swed', invoice: @invoice) + assert_equal swed_link.channel, 'Swed' + assert_equal swed_link.class.config_namespace_name, 'swed' + + seb_link = PaymentOrder.create_with_type(type: 'seb', invoice: @invoice) + assert_equal seb_link.channel, 'Seb' + assert_equal seb_link.class.config_namespace_name, 'seb' + + lhv_link = PaymentOrder.create_with_type(type: 'lhv', invoice: @invoice) + assert_equal lhv_link.channel, 'Lhv' + assert_equal lhv_link.class.config_namespace_name, 'lhv' + end + def test_valid_success_response_from_intermediary? assert(@completed_bank_link.valid_response_from_intermediary?) end @@ -107,21 +120,14 @@ class BankLinkTest < ActiveSupport::TestCase refute(@cancelled_bank_link.settled_payment?) end - def test_complete_transaction_calls_methods_on_transaction - mock_transaction = MiniTest::Mock.new - mock_transaction.expect(:sum= , '12.00', ['12.00']) - mock_transaction.expect(:bank_reference= , '1', ['1']) - mock_transaction.expect(:buyer_bank_code= , 'testvpos', ['testvpos']) - mock_transaction.expect(:buyer_iban= , '1234', ['1234']) - mock_transaction.expect(:paid_at= , Date.parse('2018-04-01 00:30:00 +0300'), [Time.parse('2018-04-01T00:30:00+0300')]) - mock_transaction.expect(:buyer_name=, 'John Doe', ['John Doe']) - mock_transaction.expect(:save!, true) - mock_transaction.expect(:autobind_invoice, AccountActivity.new) + def test_successful_payment_creates_bank_transaction + @completed_bank_link.complete_transaction - BankTransaction.stub(:find_by, mock_transaction) do - @completed_bank_link.complete_transaction - end + transaction = BankTransaction.find_by( + sum: @completed_bank_link.response['VK_AMOUNT'], + buyer_name: @completed_bank_link.response['VK_SND_NAME'] + ) - mock_transaction.verify + assert transaction.present? end end diff --git a/test/models/payment_orders_test.rb b/test/models/payment_orders_test.rb index 3027bb60e..3f72dcf8f 100644 --- a/test/models/payment_orders_test.rb +++ b/test/models/payment_orders_test.rb @@ -43,12 +43,33 @@ class PaymentOrdersTest < ActiveSupport::TestCase end end + def test_can_not_create_order_for_paid_invoice + invoice = invoices(:one) + payment_order = PaymentOrder.create_with_type(type: 'every_pay', invoice: invoice) + assert payment_order.invalid? + assert_includes payment_order.errors[:invoice], 'is already paid' + end + + def test_order_without_channel_is_invalid + payment_order = PaymentOrder.new + assert payment_order.invalid? + assert_includes payment_order.errors[:type], 'is not supported' + end + def test_can_not_create_order_with_invalid_type assert_raise NameError do PaymentOrder.create_with_type(type: 'not_implemented', invoice: Invoice.new) end end + def test_supported_method_bool_does_not_fail + assert_not PaymentOrder.supported_method?('not_implemented', shortname: true) + assert PaymentOrder.supported_method?('every_pay', shortname: true) + + assert_not PaymentOrder.supported_method?('PaymentOrders::NonExistant') + assert PaymentOrder.supported_method?('PaymentOrders::EveryPay') + end + def test_can_create_with_correct_subclass payment = PaymentOrder.create_with_type(type: 'seb', invoice: Invoice.new) assert_equal PaymentOrders::Seb, payment.class