diff --git a/spec/controllers/spree/admin/payment_payway_base_controller_spec.rb b/spec/controllers/spree/admin/payment_payway_base_controller_spec.rb deleted file mode 100644 index 5a7f287f..00000000 --- a/spec/controllers/spree/admin/payment_payway_base_controller_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Admin::PaymentPaywayBaseController, type: :controller do - - controller do - def update - render plain: :ok - end - end - - stub_authorization! - - let(:user) { create(:user) } - let(:gateway) { create(:payway_gateway, auto_capture: true) } - let(:payment_source) { create(:payway_payment_source, payment_method: gateway) } - - let(:order) { OrderWalkthrough.up_to( :payment) } - let(:payment) { create(:payway_payment, payment_method: gateway, source: payment_source, order: order) } - - describe "Put update" do - it "passes the validate order" do - put :update, params: {id: payment.number} - expect(response.status).to eq 200 - expect(response.body).to eq "ok" - end - end -end diff --git a/spec/controllers/spree/admin/payment_payway_checkers_controller_spec.rb b/spec/controllers/spree/admin/payment_payway_checkers_controller_spec.rb deleted file mode 100644 index ab973b99..00000000 --- a/spec/controllers/spree/admin/payment_payway_checkers_controller_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Admin::PaymentPaywayCheckersController, type: :controller do - stub_authorization! - - let(:user) { create(:user) } - - before do - allow(controller).to receive_messages spree_current_user: user - end - - - describe "PUT update" do - let(:gateway) { create(:payway_gateway, auto_capture: true) } - let(:payment_source) { create(:payway_payment_source, payment_method: gateway) } - - let(:order) { OrderWalkthrough.up_to( :payment) } - let(:payment) { create(:payway_payment, payment_method: gateway, source: payment_source, order: order) } - - before(:each) do - gateway.set_preference(:api_key, "api_key") - gateway.set_preference(:merchant_id, "vtenh") - gateway.set_preference(:endpoint, "https://payway-staging.ababank.com/api/pwvtenhv/") - gateway.set_preference(:return_url, "https://vtenh.com/webkook/payway_return_url") - gateway.set_preference(:continue_success_url, "https://vtenh.com/webkook/payway_continue_url") - gateway.set_preference(:payment_option, "cards") - gateway.set_preference(:transaction_fee_fix, 0) - gateway.save - - payment.process! - end - - it "redirects to order path if payment status updater is success" do - checker = double(:payway_status_checker, 'success?': true) - allow_any_instance_of(Vpago::Payway::PaymentRequestUpdater).to receive(:check_payway_status).and_return(checker) - - put :update, params: {id: payment.number} - - payment.reload - order.reload - - - expect(flash[:success]).to eq Spree.t(:successfully_updated, resource: Spree.t(:payments)) - expect(payment.completed?).to eq true - expect(order.completed?).to eq true - - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number) ) - end - - it "redirects to order path if payment status updater is false" do - checker = double(:payway_status_checker, 'success?': false, error_message: 'error-message') - allow_any_instance_of(Vpago::Payway::PaymentRequestUpdater).to receive(:check_payway_status).and_return(checker) - - put :update, params: {id: payment.number} - - payment.reload - order.reload - - expect(flash[:error]).to eq Spree.t(:unsuccessfully_updated, resource: Spree.t(:payments)) - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number) ) - end - - end - - - -end \ No newline at end of file diff --git a/spec/controllers/spree/admin/payment_payway_markers_controller_spec.rb b/spec/controllers/spree/admin/payment_payway_markers_controller_spec.rb deleted file mode 100644 index 68fee151..00000000 --- a/spec/controllers/spree/admin/payment_payway_markers_controller_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Admin::PaymentPaywayMarkersController, type: :controller do - stub_authorization! - - let(:user) { create(:user) } - - before do - allow(controller).to receive_messages spree_current_user: user - end - - - describe "PUT update" do - let(:gateway) { create(:payway_gateway, auto_capture: true) } - let(:payment_source) { create(:payway_payment_source, payment_method: gateway) } - - let(:order) { OrderWalkthrough.up_to( :payment) } - let(:payment) { create(:payway_payment, payment_method: gateway, source: payment_source, order: order) } - - before(:each) do - gateway.set_preference(:api_key, "api_key") - gateway.set_preference(:merchant_id, "vtenh") - gateway.set_preference(:endpoint, "https://payway-staging.ababank.com/api/pwvtenhv/") - gateway.set_preference(:return_url, "https://vtenh.com/webkook/payway_return_url") - gateway.set_preference(:continue_success_url, "https://vtenh.com/webkook/payway_continue_url") - gateway.set_preference(:payment_option, "cards") - gateway.set_preference(:transaction_fee_fix, 0) - gateway.save - - payment.process! - end - - it 'requires update_reason' do - put :update, params: {id: payment.number, update_reason: ' ' } - - payment.reload - order.reload - - expect(flash[:error]).to eq Spree.t('vpago.payments.failed_require_updated_reason') - expect(payment.completed?).to eq false - expect(order.completed?).to eq false - - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number) ) - end - - it "redirects to order path if payment status updater is success" do - reason = 'my-reason' - put :update, params: {id: payment.number, updated_reason: reason } - - payment.reload - order.reload - - expect(flash[:success]).to eq Spree.t(:successfully_updated, resource: Spree.t(:payments)) - expect(payment.completed?).to eq true - expect(order.completed?).to eq true - - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number) ) - end - end - - - -end \ No newline at end of file diff --git a/spec/controllers/spree/admin/payment_payway_queriers_controller_spec.rb b/spec/controllers/spree/admin/payment_payway_queriers_controller_spec.rb deleted file mode 100644 index 3e6bce0e..00000000 --- a/spec/controllers/spree/admin/payment_payway_queriers_controller_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Admin::PaymentPaywayQueriersController, type: :controller do - stub_authorization! - - let(:user) { create(:user) } - - before do - allow(controller).to receive_messages spree_current_user: user - end - - - describe "GET show" do - let(:gateway) { create(:payway_gateway, auto_capture: true) } - let(:payment_source) { create(:payway_payment_source, payment_method: gateway) } - - let(:order) { OrderWalkthrough.up_to( :payment) } - let(:payment) { create(:payway_payment, payment_method: gateway, source: payment_source, order: order) } - - before(:each) do - gateway.set_preference(:api_key, "api_key") - gateway.set_preference(:merchant_id, "vtenh") - gateway.set_preference(:endpoint, "https://payway-staging.ababank.com/api/pwvtenhv/") - gateway.set_preference(:return_url, "https://vtenh.com/webkook/payway_return_url") - gateway.set_preference(:continue_success_url, "https://vtenh.com/webkook/payway_continue_url") - gateway.set_preference(:payment_option, "cards") - gateway.set_preference(:transaction_fee_fix, 0) - gateway.save - - payment.process! - end - it "redirects to order path if payment status updater is success" do - tran_status_result = double(:tran_status_result, success?: true, json_response: {"status"=>0} ) - expect(Vpago::Payway::TransactionStatus).to receive(:new).with(payment).and_return(tran_status_result) - expect(tran_status_result).to receive(:call) - - get :show, params: { id: payment.number } - - expect(flash[:success]).to eq Spree.t('vpago.payments.payment_found_with_result', result: tran_status_result.json_response) - expect(response.status).to eq 302 - expect(response).to redirect_to(admin_order_payment_path(order_id: order.number, id: payment.number)) - end - - it "redirects to order path if payment status updater is false" do - tran_status_result = double(:tran_status_result, success?: false, error_message: {"status"=>1} ) - expect(Vpago::Payway::TransactionStatus).to receive(:new).with(payment).and_return(tran_status_result) - expect(tran_status_result).to receive(:call) - - get :show, params: {id: payment.number} - - expect(flash[:error]).to eq Spree.t('vpago.payments.payment_not_found_with_error', error: tran_status_result.error_message) - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number)) - end - end -end \ No newline at end of file diff --git a/spec/controllers/spree/admin/payment_wing_sdk_base_controller_spec.rb b/spec/controllers/spree/admin/payment_wing_sdk_base_controller_spec.rb deleted file mode 100644 index f26dd474..00000000 --- a/spec/controllers/spree/admin/payment_wing_sdk_base_controller_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Admin::PaymentWingSdkBaseController, type: :controller do - controller do - def update - render plain: :ok - end - end - - stub_authorization! - - let(:user) { create(:user) } - let(:gateway) { create(:wing_sdk_gateway, auto_capture: true) } - let(:payment_source) { create(:wing_sdk_payment_source, payment_method: gateway) } - - let(:order) { create(:order, state: 'payment') } - let(:payment) { create(:wing_sdk_payment, payment_method: gateway, source: payment_source, order: order) } - - describe "Put update" do - it "redirect to with error if order if complated" do - allow_any_instance_of(Spree::Order).to receive(:completed?).and_return(true) - put :update, params: {id: payment.number} - - expect(flash[:error]).to eq Spree.t('vpago.payments.not_allow_for_order_completed') - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number) ) - end - - it "passes the validate order" do - put :update, params: {id: payment.number} - expect(response.status).to eq 200 - expect(response.body).to eq "ok" - end - end -end diff --git a/spec/controllers/spree/admin/payment_wing_sdk_checkers_controller_spec.rb b/spec/controllers/spree/admin/payment_wing_sdk_checkers_controller_spec.rb deleted file mode 100644 index fcdd8aba..00000000 --- a/spec/controllers/spree/admin/payment_wing_sdk_checkers_controller_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Admin::PaymentWingSdkCheckersController, type: :controller do - stub_authorization! - - let(:user) { create(:user) } - - before do - allow(controller).to receive_messages spree_current_user: user - end - - - describe "PUT update" do - let(:gateway) { create(:wing_sdk_gateway, auto_capture: true) } - let(:payment_source) { create(:wing_sdk_payment_source, payment_method: gateway) } - - let(:order) { create(:order, state: 'payment') } - let(:payment) { create(:wing_sdk_payment, payment_method: gateway, source: payment_source, order: order) } - - before(:each) do - gateway.set_preference(:rest_api_key, "api_key") - gateway.set_preference(:username, "vtenh") - gateway.set_preference(:biller_code, "2001") - gateway.set_preference(:sandbox, true) - gateway.set_preference(:return_url, 'https://vtenh.com/webhook/wings/return') - gateway.set_preference(:host, 'https://stageonline.wingmoney.com') - gateway.set_preference(:transaction_fee_fix, 0) - gateway.save - - payment.process! - end - - it "redirects to order path if payment status updater is success" do - checker = double(:wing_sdk_status_checker, 'success?': true, result: {'transaction_id' => '345678'}) - allow_any_instance_of(Vpago::WingSdk::PaymentRequestUpdater).to receive(:check_wing_status).and_return(checker) - - put :update, params: {id: payment.number} - - payment.reload - order.reload - - - expect(flash[:success]).to eq Spree.t(:successfully_updated, resource: Spree.t(:payments)) - expect(payment.completed?).to eq true - expect(order.completed?).to eq true - - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number) ) - end - - it "redirects to order path if payment status updater is false" do - checker = double(:wing_sdk_status_checker, 'success?': false, error_message: 'error-message') - allow_any_instance_of(Vpago::WingSdk::PaymentRequestUpdater).to receive(:check_wing_status).and_return(checker) - - put :update, params: {id: payment.number} - - payment.reload - order.reload - - expect(flash[:error]).to eq Spree.t(:unsuccessfully_updated, resource: Spree.t(:payments)) - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number) ) - end - end -end diff --git a/spec/controllers/spree/admin/payment_wing_sdk_markers_controller_spec.rb b/spec/controllers/spree/admin/payment_wing_sdk_markers_controller_spec.rb deleted file mode 100644 index dc2fb6c4..00000000 --- a/spec/controllers/spree/admin/payment_wing_sdk_markers_controller_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Admin::PaymentWingSdkMarkersController, type: :controller do - stub_authorization! - - let(:user) { create(:user) } - - before do - allow(controller).to receive_messages spree_current_user: user - end - - - describe "PUT update" do - let(:gateway) { create(:wing_sdk_gateway, auto_capture: true) } - let(:payment_source) { create(:wing_sdk_payment_source, payment_method: gateway) } - - let(:order) { create(:order, state: 'payment') } - let(:payment) { create(:wing_sdk_payment, payment_method: gateway, source: payment_source, order: order) } - - before(:each) do - gateway.set_preference(:rest_api_key, "api_key") - gateway.set_preference(:username, "vtenh") - gateway.set_preference(:biller_code, "2001") - gateway.set_preference(:sandbox, true) - gateway.set_preference(:return_url, 'https://vtenh.com/webhook/wings/return') - gateway.set_preference(:host, 'https://stageonline.wingmoney.com') - gateway.set_preference(:transaction_fee_fix, 0) - gateway.save - - payment.process! - end - - it 'requires update_reason' do - put :update, params: {id: payment.number, update_reason: ' ' } - - payment.reload - order.reload - - expect(flash[:error]).to eq Spree.t('vpago.payments.failed_require_updated_reason') - expect(payment.completed?).to eq false - expect(order.completed?).to eq false - - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number) ) - end - - it "redirects to order path if payment status updater is success" do - reason = 'my-reason' - put :update, params: {id: payment.number, updated_reason: reason } - - payment.reload - order.reload - - expect(flash[:success]).to eq Spree.t(:successfully_updated, resource: Spree.t(:payments)) - expect(payment.completed?).to eq true - expect(order.completed?).to eq true - - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number) ) - end - end -end diff --git a/spec/controllers/spree/admin/payment_wing_sdk_queries_controller_spec.rb b/spec/controllers/spree/admin/payment_wing_sdk_queries_controller_spec.rb deleted file mode 100644 index a2b374c9..00000000 --- a/spec/controllers/spree/admin/payment_wing_sdk_queries_controller_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Admin::PaymentWingSdkQueriersController, type: :controller do - stub_authorization! - - let(:user) { create(:user) } - - before do - allow(controller).to receive_messages spree_current_user: user - end - - describe "GET show" do - let(:gateway) { create(:wing_sdk_gateway, auto_capture: true) } - let(:payment_source) { create(:wing_sdk_payment_source, payment_method: gateway) } - - let(:order) { create(:order, state: 'payment') } - let(:payment) { create(:wing_sdk_payment, payment_method: gateway, source: payment_source, order: order) } - - before(:each) do - gateway.set_preference(:rest_api_key, "api_key") - gateway.set_preference(:username, "vtenh") - gateway.set_preference(:biller_code, "2001") - gateway.set_preference(:sandbox, true) - gateway.set_preference(:return_url, 'https://vtenh.com/webhook/wings/return') - gateway.set_preference(:host, 'https://stageonline.wingmoney.com') - gateway.set_preference(:transaction_fee_fix, 0) - gateway.save - - payment.process! - end - - it "redirects to order path if payment status updater is success" do - - tran_status_result = double(:tran_status_result, success?: true, result: {"errorCode"=>200} ) - expect(Vpago::WingSdk::TransactionStatusChecker).to receive(:new).with(payment).and_return(tran_status_result) - expect(tran_status_result).to receive(:call) - - get :show, params: {id: payment.number} - - expect(flash[:success]).to eq Spree.t('vpago.payments.payment_found_with_result', result: tran_status_result.result) - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number)) - end - - it "redirects to order path if payment status updater is false" do - tran_status_result = double(:tran_status_result, success?: false, error_message: {"errorCode"=>100} ) - expect(Vpago::WingSdk::TransactionStatusChecker).to receive(:new).with(payment).and_return(tran_status_result) - expect(tran_status_result).to receive(:call) - - get :show, params: {id: payment.number} - - expect(flash[:error]).to eq Spree.t('vpago.payments.payment_not_found_with_error', error: tran_status_result.error_message) - expect(response.status).to eq 302 - expect(response).to redirect_to( admin_order_payment_path(order_id: order.number, id: payment.number)) - end - end -end diff --git a/spec/controllers/spree/webhook/acleda_mobile_controller_spec.rb b/spec/controllers/spree/webhook/acleda_mobile_controller_spec.rb deleted file mode 100644 index 61794eb4..00000000 --- a/spec/controllers/spree/webhook/acleda_mobile_controller_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Webhook::AcledaMobilesController, type: :controller do - - describe 'POST return' do - let(:payment) { create(:acleda_mobile_payment) } - - it 'response success with status 200 when successfully update the payment' do - payloads = { - TransactionId: "16de81d4-b5ef-ef59-16de-81d4b5efef59", - PaymentTokenId: payment.number, - TxnAmount: 30, - SenderName: "Test User", - SignedHash: "c5b9be690bde7dc8a0abebb1a45c0850359540a4977aecd4cdf13e15a2edfe79", - } - - allow_any_instance_of(Vpago::AcledaMobile::PaymentRetriever).to receive(:payment).and_return(payment) - allow_any_instance_of(Vpago::AcledaMobile::PaymentRetriever).to receive(:data_valid?).and_return(true) - allow_any_instance_of(Spree::Order).to receive(:paid?).and_return(true) - - post :return, params: payloads - - json_response = JSON.parse(response.body) - - expect(response.status).to eq 200 - expect(json_response['status']['message']).to eq 'Success' - expect(json_response['data']['PaymentTokenId']).to eq payment.number - end - - it 'response failed with status 403 when signed hash is invalid' do - payloads = { - TransactionId: "16de81d4-b5ef-ef59-16de-81d4b5efef59", - PaymentTokenId: payment.number, - TxnAmount: 30, - SenderName: "Test User", - SignedHash: "c5b9be690bde7dc8a0abebb1a45c0850359540a4977aecd4cdf13e15a2edfe79", - } - - allow_any_instance_of(Vpago::AcledaMobile::PaymentRetriever).to receive(:call).and_return(payment) - allow_any_instance_of(Vpago::AcledaMobile::PaymentRetriever).to receive(:payment).and_return(payment) - allow_any_instance_of(Vpago::AcledaMobile::PaymentRetriever).to receive(:data_valid?).and_return(false) - - post :return, params: payloads - - json_response = JSON.parse(response.body) - - expect(response.status).to eq 403 - expect(json_response['status']['message']).to eq 'Invalid SignedHash' - end - - it 'response failed with status 203 when cannot find the payment' do - payloads = { - TransactionId: "16de81d4-b5ef-ef59-16de-81d4b5efef59", - PaymentTokenId: 'Invalid', - TxnAmount: 30, - SenderName: "Test User", - SignedHash: "c5b9be690bde7dc8a0abebb1a45c0850359540a4977aecd4cdf13e15a2edfe79", - } - - allow_any_instance_of(Vpago::AcledaMobile::PaymentRetriever).to receive(:data_valid?).and_return(true) - - post :return, params: payloads - - json_response = JSON.parse(response.body) - expect(response.status).to eq 203 - expect(json_response['status']['message']).to eq "Payment not found" - end - end -end diff --git a/spec/controllers/spree/webhook/payways_controller_spec.rb b/spec/controllers/spree/webhook/payways_controller_spec.rb deleted file mode 100644 index a208a6c0..00000000 --- a/spec/controllers/spree/webhook/payways_controller_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Webhook::PaywaysController, type: :controller do - render_views - stub_authorization! - - describe "GET return" do - it "return ok" do - get :return - - expect(response.status).to eq 200 - expect(response.body).to eq "ok" - end - end - - describe "POST return" do - let(:gateway) { create(:payway_gateway, auto_capture: true) } - let(:payment_source) { create(:payway_payment_source, payment_method: gateway) } - - let(:order) { OrderWalkthrough.up_to( :payment) } - let(:payment) { create(:payway_payment, payment_method: gateway, source: payment_source, order: order) } - - before(:each) do - gateway.set_preference(:api_key, "api_key") - gateway.set_preference(:merchant_id, "vtenh") - gateway.set_preference(:endpoint, "https://payway-staging.ababank.com/api/pwvtenhv/") - gateway.set_preference(:return_url, "https://vtenh.com/webkook/payway_return_url") - gateway.set_preference(:continue_success_url, "https://vtenh.com/webkook/payway_continue_url") - gateway.set_preference(:payment_option, "cards") - gateway.set_preference(:transaction_fee_fix, 0) - gateway.save - - payment.process! - end - - it "redirects to order path if payment status updater is success" do - payload = { tran_id: payment.number, status: 0}.to_json - payment_success = double(:payment_status_updater, 'success?': true) - allow_any_instance_of(Vpago::Payway::PaymentRequestUpdater).to receive(:check_payway_status).and_return(payment_success) - - post :return, params: {response: payload} - # expect(subject).to redirect_to order_path(order.reload) - expect(response.body).to eq 'success' - end - - it "redirects to checkout with state :payment path if payment status updater is failed" do - payload = { tran_id: payment.number, status: 0}.to_json - payment_failed = double(:payment_status_updater, 'success?': false, error_message: "Invalid transaction from Payway") - allow_any_instance_of(Vpago::Payway::PaymentRequestUpdater).to receive(:check_payway_status).and_return(payment_failed) - - post :return, params: {response: payload} - expect(response.status).to eq 400 - end - end - - describe "GET continue" do - let(:order) { OrderWalkthrough.up_to( :payment) } - let(:payment) { create(:payway_payment, order: order) } - - it "redirects to order path if payment status updater is success" do - payment.complete! - payment.order.finalize! - payment.order.update(state: 'complete', completed_at: Time.zone.now) - - get :continue, params: {tran_id: payment.number, app_checkout: 'yes'} - expect(subject).to redirect_to success_payway_results_path - end - - it "redirects to checkout with state :payment path if payment status updater is failed" do - get :continue, params: {tran_id: payment.number, app_checkout: 'yes'} - expect(subject).to redirect_to failed_payway_results_path - end - end - - - -end \ No newline at end of file diff --git a/spec/jobs/vpago/payment_processor_job_spec.rb b/spec/jobs/vpago/payment_processor_job_spec.rb new file mode 100644 index 00000000..3283deca --- /dev/null +++ b/spec/jobs/vpago/payment_processor_job_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +RSpec.describe Vpago::PaymentProcessorJob, type: :job do + let!(:payment) { create(:payway_v2_payment) } + let!(:processor) { Vpago::PaymentProcessor.new(payment: payment) } + + describe '#perform' do + it 'find payment & call process payment' do + expect(Spree::Payment).to receive(:find_by).with(number: payment.number).and_return(payment) + expect(Vpago::PaymentProcessor).to receive(:new).with(payment: payment).and_return(processor) + expect(processor).to receive(:call) + + Vpago::PaymentProcessorJob.perform_now(payment_number: payment.number) + end + end +end diff --git a/spec/lib/vpago/payway/payment_status_marker_spec.rb b/spec/lib/vpago/payway/payment_status_marker_spec.rb deleted file mode 100644 index e68be9f8..00000000 --- a/spec/lib/vpago/payway/payment_status_marker_spec.rb +++ /dev/null @@ -1,110 +0,0 @@ -require 'spec_helper' - -RSpec.describe Vpago::Payway::PaymentStatusMarker, type: :model do - let(:gateway) { create(:payway_gateway, auto_capture: true) } - let(:payment_source) { create(:payway_payment_source, payment_method: gateway) } - - let(:order) { OrderWalkthrough.up_to( :payment) } - let(:payment) { create(:payway_payment, payment_method: gateway, source: payment_source, order: order) } - let(:user) { create(:user)} - - before(:each) { payment.process! } - - describe '#update_payment_source' do - context 'status true' do - it "update payment source payment_status to success" do - options = { - status: true, - updated_by_user_id: user.id, - updated_reason: 'manually-updated' - } - - old_updated_by_user_at = payment_source.updated_by_user_at - - status_updater = Vpago::Payway::PaymentStatusMarker.new(payment, options) - - status_updater.send(:update_payment_source) - payment_source.reload - - expect(payment_source.payment_status).to eq 'success' - expect(payment_source.updated_by_user_id).to eq user.id - expect(payment_source.updated_reason).to eq 'manually-updated' - expect(payment_source.updated_by_user_at).to_not eq old_updated_by_user_at - end - end - - context 'status false' do - it "update payment source status to failed and save error_message" do - description = 'error-message' - - options = { - status: false, - description: description, - updated_by_user_id: user.id, - updated_reason: 'manually-updated' - } - - status_updater = Vpago::Payway::PaymentStatusMarker.new(payment, options) - - status_updater.send(:update_payment_source) - payment_source.reload - - expect(payment_source.payment_status).to eq 'failed' - expect(payment_source.payment_description).to eq description - expect(payment_source.updated_by_user_id).to eq nil - expect(payment_source.updated_by_user_at).to eq nil - expect(payment_source.updated_reason).to eq nil - end - end - end - - describe '#complete_payment!' do - it 'marks payment state to completed' do - status_updater = Vpago::Payway::PaymentStatusMarker.new(payment, status: true) - status_updater.send(:complete_payment!) - payment.reload - - expect(payment.state).to eq 'completed' - end - end - describe '#complete_order!' do - it 'updates order state to be complete' do - - status_updater = Vpago::Payway::PaymentStatusMarker.new(payment, status: true) - status_updater.send(:complete_order!) - order.reload - - expect(order.state).to eq 'complete' - expect(order.completed_at).not_to be_nil - end - end - - describe '#transition_to_paid!' do - it 'mark payment and order state to be complete' do - status_updater = Vpago::Payway::PaymentStatusMarker.new(payment, status: true) - status_updater.send(:transition_to_paid!) - payment.reload - order.reload - - expect(payment.state).to eq 'completed' - - expect(order.payment_state).to eq 'paid' - expect(order.state).to eq 'complete' - expect(order.completed_at).not_to be_nil - end - end - - describe '#transition_to_failed!' do - it 'mark payment and order state to be complete' do - status_updater = Vpago::Payway::PaymentStatusMarker.new(payment, status: false) - - status_updater.send(:transition_to_failed!) - payment.reload - order.reload - - expect(payment.state).to eq 'failed' - expect(order.state).to eq 'payment' - end - end - -end diff --git a/spec/lib/vpago/payway_v2/base_spec.rb b/spec/lib/vpago/payway_v2/base_spec.rb index e90ded60..b03be602 100644 --- a/spec/lib/vpago/payway_v2/base_spec.rb +++ b/spec/lib/vpago/payway_v2/base_spec.rb @@ -46,17 +46,11 @@ end describe "#continue_success_url" do - it "return continue_success_url with tran_id, app_checkout, order_number, ot (order_token)" do - ENV['PAYWAY_CONTINUE_SUCCESS_CALLBACK_URL'] = "https://contigo.asia/webhook/payways/v2_continue" - + it "return payment processing url" do payment = create(:payway_payment) subject = described_class.new(payment) - allow(payment).to receive(:number).and_return "PF2IM21Q" - allow(payment.order).to receive(:number).and_return "R226226575" - allow(subject).to receive(:order_jwt_token).and_return("mocked-jwt-token") - - expect(subject.continue_success_url).to eq 'https://contigo.asia/webhook/payways/v2_continue?app_checkout=no&order_channel=spree&order_jwt_token=mocked-jwt-token&order_number=R226226575&tran_id=PF2IM21Q' + expect(subject.continue_success_url).to eq payment.processing_url end end @@ -74,64 +68,12 @@ end end - context 'when continue_callback_url is not present' do - let(:method) { create(:payway_v2_gateway, preferred_deeplink_scheme: 'bookmeplus') } - let(:payment) { create(:payway_v2_payment, payment_method: method) } - - it "return nil (because deeplink url base on continue_url)" do - ENV['PAYWAY_CONTINUE_SUCCESS_CALLBACK_URL'] = nil - - expect(subject.continue_success_url).to eq nil - expect(subject.return_deeplink_url).to eq nil - end - end - - context 'when preferred_deeplink_scheme is not present' do - let(:method) { create(:payway_v2_gateway, preferred_deeplink_scheme: nil) } - let(:payment) { create(:payway_v2_payment, payment_method: method) } - - it "return continue_callback_url" do - ENV['PAYWAY_CONTINUE_SUCCESS_CALLBACK_URL'] = "https://contigo.asia/webhook/payways/v2_continue" - - allow(payment).to receive(:number).and_return "PF2IM21Q" - allow(payment.order).to receive(:number).and_return "R226226575" - allow(subject).to receive(:order_jwt_token).and_return("mocked-jwt-token") - - expect(subject.return_deeplink_url).to eq 'https://contigo.asia/webhook/payways/v2_continue?app_checkout=no&order_channel=spree&order_jwt_token=mocked-jwt-token&order_number=R226226575&tran_id=PF2IM21Q' - end - end - - context 'when preferred_deeplink_scheme is present but is not app_checkout' do - let(:method) { create(:payway_v2_gateway, preferred_deeplink_scheme: nil) } - let(:payment) { create(:payway_v2_payment, payment_method: method) } - - subject { described_class.new(payment, { app_checkout: false }) } - - it "return continue_callback_url" do - ENV['PAYWAY_CONTINUE_SUCCESS_CALLBACK_URL'] = "https://contigo.asia/webhook/payways/v2_continue" - - allow(payment).to receive(:number).and_return "PF2IM21Q" - allow(payment.order).to receive(:number).and_return "R226226575" - allow(subject).to receive(:order_jwt_token).and_return("mocked-jwt-token") - - expect(subject.return_deeplink_url).to eq 'https://contigo.asia/webhook/payways/v2_continue?app_checkout=no&order_channel=spree&order_jwt_token=mocked-jwt-token&order_number=R226226575&tran_id=PF2IM21Q' - end - end - - context 'when continue_callback_url & preferred_deeplink_scheme is present & is app checkout' do - let(:method) { create(:payway_v2_gateway, preferred_deeplink_scheme: 'bookmeplus') } + context 'when override_return_deeplink_url is not present' do + let(:method) { create(:payway_v2_gateway) } let(:payment) { create(:payway_v2_payment, payment_method: method) } - subject { described_class.new(payment, { app_checkout: true }) } - - it "return return_deeplink url" do - ENV['PAYWAY_CONTINUE_SUCCESS_CALLBACK_URL'] = "https://contigo.asia/webhook/payways/v2_continue" - - allow(payment).to receive(:number).and_return "PF2IM21Q" - allow(payment.order).to receive(:number).and_return "R226226575" - allow(subject).to receive(:order_jwt_token).and_return("mocked-jwt-token") - - expect(subject.return_deeplink_url).to eq 'bookmeplus://contigo.asia/webhook/payways/v2_continue?app_checkout=yes&order_channel=spree&order_jwt_token=mocked-jwt-token&order_number=R226226575&tran_id=PF2IM21Q' + it "return payment" do + expect(subject.return_deeplink_url).to eq subject.continue_success_url end end end @@ -165,41 +107,11 @@ end describe "#view_type" do - it "return view_type: hosted_view for app checkout" do - payment = create(:payway_payment) - subject = described_class.new(payment, { app_checkout: true }) - - expect(subject.view_type).to eq 'hosted_view' - end - - it "return view_type: nil when not app checkout" do + it "return view_type: hosted_view" do payment = create(:payway_payment) subject = described_class.new(payment) - expect(subject.view_type).to eq nil - end - end - - describe '#payment_option' do - context 'when payment_option is abapay_khqr_deeplink' do - let(:payment_method) { create(:payway_v2_gateway, preferred_payment_option: 'abapay_khqr_deeplink') } - let(:payment) { create(:payway_payment, payment_method: payment_method) } - - context 'when is not app checkout' do - subject { described_class.new(payment, { app_checkout: false }) } - - it 'return payment_option = :abapay_khqr instead of :abapay_khqr_deeplink' do - expect(subject.payment_option).to eq 'abapay_khqr' - end - end - - context 'when is app checkout' do - subject { described_class.new(payment, { app_checkout: true }) } - - it 'return payment_option = :abapay_khqr_deeplink' do - expect(subject.payment_option).to eq 'abapay_khqr_deeplink' - end - end + expect(subject.view_type).to eq 'hosted_view' end end diff --git a/spec/models/spree/gateway/payway_spec.rb b/spec/models/spree/gateway/payway_spec.rb deleted file mode 100644 index 26e1e9e7..00000000 --- a/spec/models/spree/gateway/payway_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'spec_helper' - -RSpec.describe Spree::Gateway::Payway, type: :model do - let(:payment_state) { :payment } - let(:payway_gateway) { create(:payway_gateway, auto_capture: true) } - let(:payment_source) { create(:payway_payment_source, payment_method: payway_gateway) } - - let(:order) { OrderWalkthrough.up_to( payment_state) } - let(:payment) { create(:payway_payment, payment_method: payway_gateway, source: payment_source, order: order) } - - describe '#process' do - - it "transform payment state from checkout to processing" do - checkout = payment.state - - expect(checkout).to eq('checkout') - payment.process! - expect(payment.state).to eq('processing') - end - end -end diff --git a/spec/models/spree/gateway/payway_v2_spec.rb b/spec/models/spree/gateway/payway_v2_spec.rb new file mode 100644 index 00000000..7f43affb --- /dev/null +++ b/spec/models/spree/gateway/payway_v2_spec.rb @@ -0,0 +1,377 @@ +require 'spec_helper' + +RSpec.describe Spree::Gateway::PaywayV2, type: :model do + let!(:default_payout_profile) { create(:payway_payout_profile, active: true, bank_account_number: '333', default: true, verified_at: DateTime.current)} + let(:payment_method) { create(:payway_v2_gateway) } + let(:payment) { create(:payment, payment_method: payment_method) } + + describe '#default_payout_profile' do + it 'returns the default payout profile' do + expect(payment_method.default_payout_profile).to eq(Spree::PayoutProfiles::PaywayV2.default) + end + end + + describe '#support_payout?' do + it { expect(create(:payway_v2_gateway).support_payout?).to be true } + end + + describe '#support_pre_auth?' do + it { expect(create(:payway_v2_gateway).support_pre_auth?).to be true } + end + + describe '#enable_payout?' do + context 'when default payout is receivable' do + it 'returns true' do + default_payout_profile.verify!({}) + + expect(default_payout_profile.receivable?).to be true + expect(payment_method.enable_payout?).to be true + end + end + + context 'when default payout is not receivable' do + it 'returns false' do + default_payout_profile.reset_verification! + + expect(default_payout_profile.receivable?).to be false + expect(payment_method.enable_payout?).to be false + end + end + end + + describe '#enable_pre_auth?' do + it 'returns true when column :enable_pre_auth is true' do + payment_method.update(enable_pre_auth: true) + expect(payment_method.enable_pre_auth?).to be true + end + end + + describe '#auto_capture?' do + context 'when pre-auth is enabled' do + it 'returns false' do + payment_method.update(enable_pre_auth: true) + + expect(payment_method.enable_pre_auth?).to be true + expect(payment_method.auto_capture?).to be false + end + end + + context 'when pre-auth is disable' do + it 'returns true' do + payment_method.update(enable_pre_auth: false) + + expect(payment_method.enable_pre_auth?).to be false + expect(payment_method.auto_capture?).to be true + end + end + end + + # this is called when pre-auth is enabled + describe '#authorize' do + context 'when transaction checker response paid' do + let(:checker) { Vpago::PaywayV2::TransactionStatus.new(payment) } + + before do + allow(checker).to receive(:success?).and_return(true) + allow(checker).to receive(:json_response).and_return({ 'status'=>'any-result' }) + allow(payment_method).to receive(:check_transaction).and_return(checker) + end + + it 'check transaction with bank & save response to db & return success' do + response = payment_method.authorize(nil, nil, payment.gateway_options) + + expect(payment.reload.transaction_response).to eq({ 'status'=>'any-result' }) + expect(response.success?).to be true + end + end + + context 'when transaction checker response unpaid' do + let(:checker) { Vpago::PaywayV2::TransactionStatus.new(payment) } + + before do + allow(checker).to receive(:success?).and_return(false) + allow(checker).to receive(:json_response).and_return({ 'status'=>'any-result' }) + allow(payment_method).to receive(:check_transaction).and_return(checker) + end + + it 'check transaction with bank & save response to db & return fail' do + response = payment_method.authorize(nil, nil, payment.gateway_options) + + expect(payment.reload.transaction_response).to eq({ 'status'=>'any-result' }) + expect(response.success?).to be false + end + end + + context 'when transaction checker raise Faraday errors' do + let(:checker) { Vpago::PaywayV2::TransactionStatus.new(payment) } + + it 'rethrow the error' do + allow(Vpago::PaywayV2::TransactionStatus).to receive(:new).and_return(checker) + allow(checker).to receive(:check_remote_status).and_raise(Faraday::ConnectionFailed.new) + expect { payment_method.authorize(nil, nil, payment.gateway_options) }.to raise_error(Faraday::ConnectionFailed) + + allow(checker).to receive(:check_remote_status).and_raise(Faraday::TimeoutError.new) + expect { payment_method.authorize(nil, nil, payment.gateway_options) }.to raise_error(Faraday::TimeoutError) + + allow(checker).to receive(:check_remote_status).and_raise(StandardError.new) + expect { payment_method.authorize(nil, nil, payment.gateway_options) }.to raise_error(StandardError) + end + end + end + + # this is called when pre-auth is disabled, it captures amount from bank immediately. + describe '#purchase' do + let(:checker) { Vpago::PaywayV2::TransactionStatus.new(payment) } + + context 'when transaction checker response paid with payout' do + before do + allow(checker).to receive(:success?).and_return(true) + allow(checker).to receive(:json_response).and_return({ 'status'=>'any-result', "payout"=>[{"acc"=>"002092768", "amt"=>"54.00", "acc_name"=>"*********ount", "whitelist_id"=>"85"}] }) + allow(payment_method).to receive(:check_transaction).and_return(checker) + end + + it 'check transaction with bank & save response to db, confirm payout & return success' do + expect(payment_method).to receive(:confirm_payouts).and_return([true, {}]) + + response = payment_method.purchase(nil, nil, payment.gateway_options) + + expect(payment.reload.transaction_response).to eq({ 'status'=>'any-result', "payout"=>[{"acc"=>"002092768", "amt"=>"54.00", "acc_name"=>"*********ount", "whitelist_id"=>"85"}] }) + expect(response.success?).to be true + end + end + + context 'when transaction checker response paid without payout' do + before do + allow(checker).to receive(:success?).and_return(true) + allow(checker).to receive(:json_response).and_return({ 'status'=>'any-result' }) + allow(payment_method).to receive(:check_transaction).and_return(checker) + end + + it 'check transaction with bank & save response to db, skip confirming payout & return success' do + expect(payment_method).not_to receive(:confirm_payouts) + + response = payment_method.purchase(nil, nil, payment.gateway_options) + + expect(payment.reload.transaction_response).to eq({ 'status'=>'any-result' }) + expect(response.success?).to be true + end + end + + context 'when transaction checker response unpaid' do + let(:checker) { Vpago::PaywayV2::TransactionStatus.new(payment) } + + before do + allow(checker).to receive(:success?).and_return(false) + allow(checker).to receive(:json_response).and_return({ 'status'=>'any-result' }) + allow(payment_method).to receive(:check_transaction).and_return(checker) + end + + it 'check transaction with bank & save response to db & return fail' do + response = payment_method.authorize(nil, nil, payment.gateway_options) + + expect(payment.reload.transaction_response).to eq({ 'status'=>'any-result' }) + expect(response.success?).to be false + end + end + + context 'when transaction checker raise Faraday errors' do + let(:checker) { Vpago::PaywayV2::TransactionStatus.new(payment) } + + it 'rethrow the error' do + allow(Vpago::PaywayV2::TransactionStatus).to receive(:new).and_return(checker) + allow(checker).to receive(:check_remote_status).and_raise(Faraday::ConnectionFailed.new) + expect { payment_method.purchase(nil, nil, payment.gateway_options) }.to raise_error(Faraday::ConnectionFailed) + + allow(checker).to receive(:check_remote_status).and_raise(Faraday::TimeoutError.new) + expect { payment_method.purchase(nil, nil, payment.gateway_options) }.to raise_error(Faraday::TimeoutError) + + allow(checker).to receive(:check_remote_status).and_raise(StandardError.new) + expect { payment_method.purchase(nil, nil, payment.gateway_options) }.to raise_error(StandardError) + end + end + end + + describe '#capture' do + context 'when both pre-auth & payout is enabled' do + before do + expect(payment_method).to receive(:enable_pre_auth?).and_return(true) + end + + context 'when confirmed pre-auth success' do + it 'confirm pre-auth, payout & return success' do + expect(payment_method).to receive(:complete_pre_auth).and_return([true, {}]) + + expect(payment_method).to receive(:payout_total_from_response).and_return(10) + expect(payment_method).to receive(:confirm_payouts).and_return([true, {}]) + + response = payment_method.capture(nil, nil, payment.gateway_options) + expect(response.success?).to be true + end + end + + context 'when confirmed pre-auth failed' do + it 'did not confirm payout & return failded' do + expect(payment_method).to receive(:complete_pre_auth).and_return([false, {}]) + + expect(payment_method).not_to receive(:payout_total_from_response) + expect(payment_method).not_to receive(:confirm_payouts) + + response = payment_method.capture(nil, nil, payment.gateway_options) + expect(response.success?).to be false + end + end + end + + context 'when pre-auth is enabled but payout is disabled' do + before do + expect(payment_method).to receive(:enable_pre_auth?).and_return(true) + expect(payment_method).to receive(:payout_total_from_response).and_return(nil) + end + + it 'only confirm pre-auth & return success' do + expect(payment_method).to receive(:complete_pre_auth).and_return([true, {}]) + expect(payment_method).not_to receive(:confirm_payouts) + + response = payment_method.capture(nil, nil, payment.gateway_options) + expect(response.success?).to be true + end + end + + context 'when pre-auth is disabled but payout is enabled' do + it 'only confirm payout & return success' do + expect(payment_method).to receive(:enable_pre_auth?).and_return(false) + expect(payment_method).to receive(:payout_total_from_response).and_return(10) + + expect(payment_method).not_to receive(:complete_pre_auth) + expect(payment_method).to receive(:confirm_payouts).and_return([true, {}]) + + response = payment_method.capture(nil, nil, payment.gateway_options) + expect(response.success?).to be true + end + end + end + + describe '#void' do + context 'when pre-auth is enabled' do + context 'when pre-auth canceler response success' do + it 'send request to cancel the pre-auth with bank & return success' do + expect(payment_method).to receive(:enable_pre_auth?).and_return(true) + expect(payment_method).to receive(:cancel_pre_auth).and_return([true, { 'status'=>'any-result' }]) + + response = payment_method.void(nil, payment.gateway_options) + expect(response.success?).to be true + end + end + + context 'when pre-auth canceler response fail' do + it 'send request to cancel the pre-auth with bank & return fail' do + expect(payment_method).to receive(:enable_pre_auth?).and_return(true) + expect(payment_method).to receive(:cancel_pre_auth).and_return([false, { 'status'=>'any-result' }]) + + response = payment_method.void(nil, payment.gateway_options) + expect(response.success?).to be false + end + end + end + + context 'when pre-auth is disable' do + it 'return success true directly' do + expect(payment_method).to receive(:enable_pre_auth?).and_return(false) + expect(payment_method).not_to receive(:cancel_pre_auth) + + response = payment_method.void(nil, payment.gateway_options) + expect(response.success?).to be true + end + end + end + + describe '#check_transaction' do + let(:checker) { Vpago::PaywayV2::TransactionStatus.new(payment) } + + it 'execute .call and returns checker itself' do + expect(Vpago::PaywayV2::TransactionStatus).to receive(:new).with(payment).and_return(checker) + expect(checker).to receive(:call) + + expect(payment_method.send(:check_transaction, payment)).to eq(checker) + end + end + + describe '#cancel_pre_auth' do + let(:canceler) { Vpago::PaywayV2::PreAuthCanceler.new(payment) } + + it 'execute .call and returns success & request_data' do + expect(Vpago::PaywayV2::PreAuthCanceler).to receive(:new).with(payment).and_return(canceler) + expect(canceler).to receive(:call) + expect(canceler).to receive(:success?).and_return(true) + expect(canceler).to receive(:request_data).and_return({'merchant_id': 'any-merchant-id'}) + + expect(payment_method.send(:cancel_pre_auth, payment)).to eq([true, {'merchant_id': 'any-merchant-id'}]) + end + end + + + describe '#complete_pre_auth' do + let(:completer) { Vpago::PaywayV2::PreAuthCompleter.new(payment) } + + it 'execute .call and returns success & request_data' do + expect(Vpago::PaywayV2::PreAuthCompleter).to receive(:new).with(payment).and_return(completer) + expect(completer).to receive(:call) + expect(completer).to receive(:success?).and_return(true) + expect(completer).to receive(:request_data).and_return({'merchant_id': 'any-merchant-id'}) + + expect(payment_method.send(:cancel_pre_auth, payment)).to eq([true, {'merchant_id': 'any-merchant-id'}]) + end + end + + describe '#confirm_payouts' do + context 'when payout in db 100% matched with payout total from response' do + let!(:payout1) { create(:payout, payment: payment, amount: 5.0, state: :created) } + let!(:payout2) { create(:payout, payment: payment, amount: 4.0, state: :created) } + let!(:payout3) { create(:payout, payment: payment, amount: 3.0, state: :created) } + + before do + payment.transaction_response = { "payout": [ { "amt": "5.00" }, { "amt": "7.00" } ]} + payment.save! + end + + it 'set confirmed to db and return success' do + expect(payout1.confirmed?).to be false + expect(payout2.confirmed?).to be false + expect(payout3.confirmed?).to be false + + success, params = payment_method.send(:confirm_payouts, payment) + + expect(success).to be true + expect(params).to eq({:payout_total => 12.0, :expect_payout_total => 12.0}) + + expect(payout1.reload.confirmed?).to be true + expect(payout2.reload.confirmed?).to be true + expect(payout3.reload.confirmed?).to be true + + expect(payment_method.send(:payout_total_from_response, payment)).to be 12.0 + end + end + end + + describe '#payout_total_from_response' do + context 'when payment.transaction_response[:payout] is nil' do + it 'return nil' do + payment.transaction_response = nil + payment.save! + expect(payment_method.send(:payout_total_from_response, payment.reload)).to be nil + + payment.transaction_response = { "status": 0, 'description': 'any-response-here' } + payment.save! + expect(payment_method.send(:payout_total_from_response, payment.reload)).to be nil + end + end + + context 'when payment.transaction_response[:payout] is present' do + it 'return total payout base on transaction_response' do + payment.transaction_response = { "payout": [{"acc": "002092768", "amt": "54.00", "acc_name": "*********ount", "whitelist_id": "85"} ]} + payment.save! + expect(payment_method.send(:payout_total_from_response, payment.reload)).to be 54.00 + end + end + end +end diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index d06a8847..606e07a4 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -219,47 +219,4 @@ end end end - - describe '#available_vendor_payment_methods' do - let(:vendor1) { create(:vendor) } - let(:vendor2) { create(:vendor) } - let(:order) { create(:order) } - - before do - create(:line_item, order: order, product: create(:product_in_stock, vendor: vendor1)) - create(:line_item, order: order, product: create(:product_in_stock, vendor: vendor2)) - end - - context 'when user is a ticket seller' do - before do - allow(order).to receive(:ticket_seller_user?).and_return(true) - end - - it 'returns all vendor payment methods' do - payment_method1 = create(:payment_method, vendor: vendor1) - payment_method2 = create(:payment_method, vendor: vendor2, type: 'Spree::PaymentMethod::Check') - - order.stub(:vendor_payment_methods) { [payment_method1, payment_method2] } - - expect(order.available_vendor_payment_methods).to match_array([payment_method1, payment_method2]) - end - end - - context 'when user is not a ticket seller' do - before do - allow(order).to receive(:ticket_seller_user?).and_return(false) - end - - it 'returns vendor payment methods excluding the ones of type Check' do - payment_method1 = create(:payment_method, vendor: vendor1) - payment_method2 = create(:payment_method, vendor: vendor2) - payment_method_check = create(:payment_method, vendor: vendor1, type: 'Spree::PaymentMethod::Check') - - order.stub(:vendor_payment_methods) { [payment_method1, payment_method2, payment_method_check] } - - expect(order.available_vendor_payment_methods).to match_array([payment_method1, payment_method2]) - expect(order.available_vendor_payment_methods).not_to include(payment_method_check) - end - end - end end diff --git a/spec/models/spree/payment_method_spec.rb b/spec/models/spree/payment_method_spec.rb index 25a3af6d..152a262d 100644 --- a/spec/models/spree/payment_method_spec.rb +++ b/spec/models/spree/payment_method_spec.rb @@ -1,11 +1,11 @@ require 'spec_helper' RSpec.describe Spree::PaymentMethod, type: :model do - describe '#support_payout?' do + describe '#enable_payout?' do it 'return false when not type payway v2' do payment_method = create(:acleda_payment_method) - expect(payment_method.support_payout?).to be false + expect(payment_method.enable_payout?).to be false end it 'return false when default payout is not present' do @@ -14,7 +14,7 @@ expect(payment_method.type_payway_v2?).to be true expect(payment_method.default_payout_profile).to eq nil - expect(payment_method.support_payout?).to be false + expect(payment_method.enable_payout?).to be false end it 'return false when default payout is not receivable?' do @@ -25,7 +25,7 @@ expect(payment_method.default_payout_profile).to eq default_payout_profile expect(payment_method.default_payout_profile.receivable?).to be false - expect(payment_method.support_payout?).to be false + expect(payment_method.enable_payout?).to be false end it 'return true when is payway v2 & receiveable' do @@ -36,7 +36,7 @@ expect(payment_method.default_payout_profile).to eq default_payout_profile expect(payment_method.default_payout_profile.receivable?).to be true - expect(payment_method.support_payout?).to be true + expect(payment_method.enable_payout?).to be true end end end diff --git a/spec/models/spree/payment_spec.rb b/spec/models/spree/payment_spec.rb index 08bcb0de..809a0567 100644 --- a/spec/models/spree/payment_spec.rb +++ b/spec/models/spree/payment_spec.rb @@ -15,7 +15,7 @@ subject { build(:payway_v2_payment) } it 'calls Vpago::PayoutsGenerator' do - expect(subject.support_payout?).to be true + expect(subject.payment_method.enable_payout?).to be true expect(Vpago::PayoutsGenerator).to receive(:new).with(subject).and_return(generator) expect(generator).to receive(:call).and_call_original @@ -29,7 +29,7 @@ subject { build(:payway_payment) } it 'does not call Vpago::PayoutsGenerator' do - expect(subject.support_payout?).to be false + expect(subject.payment_method.enable_payout?).to be false expect(Vpago::PayoutsGenerator).to_not receive(:new).with(subject) subject.save! diff --git a/spec/services/vpago/payment_finder_spec.rb b/spec/services/vpago/payment_finder_spec.rb new file mode 100644 index 00000000..53d1b2a2 --- /dev/null +++ b/spec/services/vpago/payment_finder_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' + +RSpec.describe Vpago::PaymentFinder do + let(:order) { create(:order, number: 'R131576461') } + let(:payment) { create(:payway_v2_payment, number: 'PJ0MYD2Y', order: order) } + + describe '#find_and_verify!' do + context 'when all params is valid' do + let(:order_jwt_token) { Vpago::PaymentUrlConstructor.new(payment).send(:order_jwt_token) } + let(:params_hash) { { order_number: order.number, payment_number: payment.number, order_jwt_token: order_jwt_token } } + + subject { described_class.new(params_hash) } + + it 'return back correct payment' do + expect(subject.find_and_verify!).to eq payment + end + end + + context 'when order number or payment number is invalid' do + let(:order_jwt_token) { Vpago::PaymentUrlConstructor.new(payment).send(:order_jwt_token) } + let(:params_hash) { { order_number: 'INVALID', payment_number: payment.number, order_jwt_token: order_jwt_token } } + + subject { described_class.new(params_hash) } + + it 'raise record not found' do + expect { subject.find_and_verify! }.to raise_error(ActiveRecord::RecordNotFound) + end + end + + context 'when jwt is invalid' do + let(:order_jwt_token) { Vpago::PaymentUrlConstructor.new(payment).send(:order_jwt_token) } + let(:params_hash) { { order_number: order.number, payment_number: payment.number, order_jwt_token: 'invalid-jwt' } } + + subject { described_class.new(params_hash) } + + it 'raise standard error' do + expect { subject.find_and_verify! }.to raise_error(StandardError) + end + end + end + + describe '#find_and_verify' do + context 'when params is invalid' do + let(:order_jwt_token) { Vpago::PaymentUrlConstructor.new(payment).send(:order_jwt_token) } + let(:params_hash) { { order_number: order.number, payment_number: payment.number, order_jwt_token: 'invalid-jwt' } } + + subject { described_class.new(params_hash) } + + it 'rescue the errors and return payment nil' do + expect { subject.find_and_verify! }.to raise_error(StandardError) + expect(subject.find_and_verify).to eq nil + end + end + end +end diff --git a/spec/services/vpago/payment_processor_spec.rb b/spec/services/vpago/payment_processor_spec.rb new file mode 100644 index 00000000..9dd94b8a --- /dev/null +++ b/spec/services/vpago/payment_processor_spec.rb @@ -0,0 +1,156 @@ +require 'spec_helper' + +RSpec.describe Vpago::PaymentProcessor do + let(:user_informer) { ::Vpago::UserInformers::Firebase.new(payment.order) } + + let(:order) { create(:order) } + let(:payment) { create(:payway_v2_payment, number: 'PJ0MYD2Y', order: order) } + + subject { described_class.new(payment: payment) } + + before do + allow(subject).to receive(:user_informer).and_return(user_informer) + end + + describe '#call' do + context 'when payment is paid' do + it 'process_payment then process_order' do + allow(payment).to receive(:completed?).and_return(true) + + expect(subject).to receive(:process_payment!) + expect(subject).to receive(:process_order) + + subject.call + end + end + + context 'when payment is not paid' do + it 'process_payment then mark it as failed instead of continue process_order' do + allow(payment).to receive(:completed?).and_return(false) + allow(payment).to receive(:pending?).and_return(false) + + expect(subject).to receive(:process_payment!) + expect(subject).to receive(:mark_payment_process_failed) + + expect(subject).not_to receive(:process_order) + + subject.call + end + end + + context 'when process_payment! raise Spree::Core::GatewayError or StateMachines::InvalidTransition' do + it 'rescue the error & mark process_payment failed' do + allow(subject).to receive(:process_payment!).and_raise(Spree::Core::GatewayError.new('gateway_error')) + + expect(subject).to receive(:mark_payment_process_failed).with('gateway_error') + + subject.call + end + end + end + + describe '#process_payment!' do + it 'inform user that payment is processing & trigger payment.process!' do + expect(user_informer).to receive(:payment_is_processing).with(processing: true) + expect(payment).to receive(:process!) + + subject.send(:process_payment!) + end + end + + # more details how how completer work, we should check complete spec instead. + describe '#process_order' do + let(:completer) { Spree::Checkout::Complete.new } + + context 'when completer success' do + before do + allow(Spree::Checkout::Complete).to receive(:new).and_return(completer) + allow(completer).to receive(:success?).and_return(true) + end + + it 'inform user that order is processing, trigger completer & mark_order_process_completed' do + expect(user_informer).to receive(:order_is_processing).with(processing: true) + expect(completer).to receive(:call).with(order: payment.order).and_return(completer) + expect(subject).to receive(:mark_order_process_completed) + + subject.send(:process_order) + end + end + + context 'when completer failed' do + before do + allow(Spree::Checkout::Complete).to receive(:new).and_return(completer) + allow(completer).to receive(:success?).and_return(false) + allow(completer).to receive(:error).and_return('this-is-error') + end + + it 'inform user that order is processing, trigger completer & mark_order_process_failed' do + expect(user_informer).to receive(:order_is_processing).with(processing: true) + expect(completer).to receive(:call).with(order: payment.order).and_return(completer) + expect(subject).to receive(:mark_order_process_failed).with('this-is-error') + + subject.send(:process_order) + end + end + end + + describe '#mark_order_process_completed' do + context 'when pre-auth enabled or payment is authorized' do + before do + allow(payment).to receive(:pending?).and_return(true) + end + + it 'capture the payment & inform user the order is completed!' do + expect(payment).to receive(:capture!) + expect(user_informer).to receive(:order_is_completed).with(processing: false) + + subject.send(:mark_order_process_completed) + end + end + + context 'when pre-auth is disabled' do + before do + allow(payment).to receive(:pending?).and_return(false) + end + + it 'inform user the order is completed directly' do + expect(payment).not_to receive(:capture!) + expect(user_informer).to receive(:order_is_completed).with(processing: false) + + subject.send(:mark_order_process_completed) + end + end + end + + describe '#mark_order_process_failed' do + context 'when pre-auth enabled or payment is authorized' do + before do + allow(payment).to receive(:pending?).and_return(true) + end + + it 'inform user that process order failed & refund amount back to user' do + expect(user_informer).to receive(:order_process_failed).with(processing: true, log_message: 'this-is-log-message') + expect(payment).to receive(:void_transaction!) + expect(user_informer).to receive(:payment_is_refunded).with(processing: false) + + subject.send(:mark_order_process_failed, 'this-is-log-message') + end + end + + context 'when pre-auth is disabled' do + before do + allow(payment).to receive(:pending?).and_return(false) + end + + it 'only inform user that process order failed' do + expect(user_informer).to receive(:order_process_failed).with(processing: false, log_message: 'this-is-log-message') + + # when pre-auth disabled, we can't refund amount back to user. so these methods are not called. + expect(payment).not_to receive(:void_transaction!) + expect(user_informer).not_to receive(:payment_is_refunded) + + subject.send(:mark_order_process_failed, 'this-is-log-message') + end + end + end +end \ No newline at end of file diff --git a/spec/services/vpago/payment_redirect_handler_spec.rb b/spec/services/vpago/payment_redirect_handler_spec.rb deleted file mode 100644 index 0c4aa6b5..00000000 --- a/spec/services/vpago/payment_redirect_handler_spec.rb +++ /dev/null @@ -1,84 +0,0 @@ -require 'spec_helper' - -RSpec.describe Vpago::PaymentRedirectHandler do - let(:gateway) { create(:payway_gateway, auto_capture: true) } - let(:payment_source) { create(:payway_payment_source, payment_method: gateway) } - let(:payway_payment) { create(:payway_payment, payment_method: gateway, source: payment_source) } - let(:acleda_payment) { create(:acleda_payment) } - - let(:general_payment) { create(:payment) } - - before do - payway_payment.payment_method.preferences[:api_key] = 'API_KEY' - end - - describe '.validate_payment' do - context "when it's not payway gateway" do - it 'raise error' do - expect { - Vpago::PaymentRedirectHandler.new(payment: general_payment).validate_payment - }.to raise_error(ActiveRecord::RecordNotFound) - end - end - - context "when it's gateway payway" do - it 'return true' do - expect(Vpago::PaymentRedirectHandler.new(payment: payway_payment).validate_payment).to eq true - end - end - end - - describe '.check_and_process_payment' do - context "when payment option is cards" do - it 'process payway card' do - payway_payment.payment_method.preferences[:payment_option] = 'cards' - handler = Vpago::PaymentRedirectHandler.new(payment: payway_payment) - - expect(payway_payment).to receive(:process!) - expect(handler).to receive(:process_payway_card) - - handler.check_and_process_payment - end - end - - context "when payment options is abapay" do - it 'process abapay deeplink' do - payway_payment.payment_method.preferences[:payment_option] = 'abapay' - handler = Vpago::PaymentRedirectHandler.new(payment: payway_payment) - - expect(payway_payment).to receive(:process!) - expect(handler).to receive(:process_abapay_deeplink) - - handler.check_and_process_payment - end - end - - context "when payment options is abapay_khqr_deeplink" do - let(:payment_method) { create(:payway_v2_gateway, preferred_payment_option: 'abapay_khqr_deeplink')} - let(:payment) { create(:payway_v2_payment, payment_method: payment_method) } - - it 'process abapay deeplink' do - handler = Vpago::PaymentRedirectHandler.new(payment: payment) - - expect(payment).to receive(:process!) - expect(handler).to receive(:process_abapay_v2_deeplink) - - handler.check_and_process_payment - end - end - - context "when payment options is acleda" do - it 'processes payment & calls process_acleda_gateway' do - # avoid vcr error - allow(acleda_payment.payment_method).to receive(:vapgo_checkout_service).and_return(nil) - - handler = Vpago::PaymentRedirectHandler.new(payment: acleda_payment) - - expect(acleda_payment).to receive(:process!) - expect(handler).to receive(:process_acleda_gateway) - - handler.check_and_process_payment - end - end - end -end diff --git a/spec/services/vpago/payment_url_constructor_spec.rb b/spec/services/vpago/payment_url_constructor_spec.rb new file mode 100644 index 00000000..a42484b5 --- /dev/null +++ b/spec/services/vpago/payment_url_constructor_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +RSpec.describe Vpago::PaymentUrlConstructor do + let(:order) { create(:order, number: 'R322092410', token: 'ry9yYKOGP64e_VVDk8-zZA1705211585402') } + let!(:payment) { create(:payway_v2_payment, number: 'PJ0MYD2Y', order: order) } + + subject { described_class.new(payment) } + + describe '#checkout_url' do + it { expect(subject.checkout_url).to eq "http://localhost:4000/vpago_payments/checkout?order_jwt_token=#{subject.send(:order_jwt_token)}&order_number=R322092410&payment_number=PJ0MYD2Y" } + end + + describe '#processing_url' do + it { expect(subject.processing_url).to eq "http://localhost:4000/vpago_payments/processing?order_jwt_token=#{subject.send(:order_jwt_token)}&order_number=R322092410&payment_number=PJ0MYD2Y" } + end + + describe '#success_url' do + it { expect(subject.success_url).to eq "http://localhost:4000/vpago_payments/success?order_jwt_token=#{subject.send(:order_jwt_token)}&order_number=R322092410&payment_number=PJ0MYD2Y" } + end + + describe '#process_payment_url' do + it { expect(subject.process_payment_url).to eq "http://localhost:4000/vpago_payments/process_payment?order_jwt_token=#{subject.send(:order_jwt_token)}&order_number=R322092410&payment_number=PJ0MYD2Y" } + end + + describe '#query' do + it { expect(subject.query).to eq "order_jwt_token=#{subject.send(:order_jwt_token)}&order_number=R322092410&payment_number=PJ0MYD2Y" } + end + + describe '#order_jwt_token' do + it 'return encoded JWT of order number with token' do + payload = { order_number: order.number, order_id: order.id } + expect(subject.send(:order_jwt_token)).to eq JWT.encode(payload, order.token, 'HS256') + end + end +end \ No newline at end of file diff --git a/spec/services/vpago/payments/create_spec.rb b/spec/services/vpago/payments/create_spec.rb new file mode 100644 index 00000000..b1d5aeef --- /dev/null +++ b/spec/services/vpago/payments/create_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +RSpec.describe Vpago::Payments::Create do + describe '.call' do + context 'when all params is valid' do + let(:order) { create(:order) } + let(:method) { create(:payway_v2_gateway) } + let(:params) { { payment_method_id: method.id, source_attributes: { payment_option: 'abapay_khqr' } } } + + it 'create new payment with source' do + expect(order.payments.length).to eq 0 + + result = described_class.call(order: order, params: params) + + expect(result.success?) + expect(order.payments.length).to eq 1 + expect(order.payments[0].source.class).to eq method.payment_source_class + end + end + end +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index de2c8c15..06558feb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,6 @@ # Configure Rails Environment ENV['RAILS_ENV'] = 'test' +ENV['DEFAULT_URL_HOST'] = 'http://localhost:4000' require File.expand_path('../dummy/config/environment.rb', __FILE__)