# frozen_string_literal: true require 'spec_helper' RSpec.describe PaymentGateways::PaypalController do context '#cancel' do it 'redirects back to checkout' do expect(get(:cancel)).to redirect_to checkout_path end end context '#confirm' do let(:previous_order) { controller.current_order(true) } let(:payment_method) { create(:payment_method) } before do allow(previous_order).to receive(:complete?).and_return(true) allow(previous_order).to receive(:checkout_allowed?).and_return(true) end it 'resets the order' do post :confirm, params: { payment_method_id: payment_method.id } expect(controller.current_order).not_to eq(previous_order) end it 'sets the access token of the session' do post :confirm, params: { payment_method_id: payment_method.id } expect(session[:access_token]).to eq(controller.current_order.token) end context "if the stock ran out whilst the payment was being placed" do it "redirects to the details page with out of stock error" do mock_order_check_stock_service(controller.current_order) post(:confirm, params: { payment_method_id: payment_method.id }) expect(response).to redirect_to checkout_step_path(step: :details) order = controller.current_order.reload # Order is in "cart" state and did not complete processing of the payment expect(order.state).to eq "cart" expect(order.payments.count).to eq 0 end end context "when order completion fails" do before do allow(previous_order).to receive(:complete?).and_return(false) end it "redirects to checkout state path" do expect(post(:confirm, params: { payment_method_id: payment_method.id })). to redirect_to checkout_step_path(step: :payment) expect(flash[:error]).to eq( 'Payment could not be processed, please check the details you entered' ) end end end describe "#express" do let(:order) { create(:order_with_totals_and_distribution) } let(:response) { true } let(:provider_success_url) { "https://test.com/success" } let(:response_mock) { double(:response, success?: response, errors: [] ) } let(:provider_mock) { double(:provider, build_set_express_checkout: true, set_express_checkout: response_mock, express_checkout_url: provider_success_url) } before do allow(controller).to receive(:current_order) { order } allow(controller).to receive(:provider) { provider_mock } allow(controller).to receive(:express_checkout_request_details) { {} } end context "when processing is successful" do it "redirects to a success URL generated by the payment provider" do expect(post(:express)).to redirect_to provider_success_url end end context "when processing fails" do let(:response) { false } it "redirects to checkout_step_path with a flash error" do expect(post(:express)).to redirect_to checkout_step_path(:payment) expect(flash[:error]).to eq "PayPal failed. " end end context "when a SocketError is encountered during processing" do before do allow(response_mock).to receive(:success?).and_raise(SocketError) end it "redirects to checkout_step_path with a flash error" do expect(post(:express)).to redirect_to checkout_step_path(:payment) expect(flash[:error]).to eq "Could not connect to PayPal." end end context "when the stock ran out whilst the payment was being placed" do it "redirects to the details page with out of stock error" do mock_order_check_stock_service(controller.current_order) post(:express) expect(response).to redirect_to checkout_step_path(step: :details) end end end describe '#expire_current_order' do it 'empties the order_id of the session' do expect(session).to receive(:[]=).with(:order_id, nil) controller.__send__(:expire_current_order) end it 'resets the @current_order ivar' do controller.__send__(:expire_current_order) expect(controller.instance_variable_get(:@current_order)).to be_nil end end def mock_order_check_stock_service(order) check_stock_service_mock = instance_double(Orders::CheckStockService) expect(Orders::CheckStockService).to receive(:new).and_return(check_stock_service_mock) expect(check_stock_service_mock).to receive(:sufficient_stock?).and_return(false) expect(check_stock_service_mock).to receive(:update_line_items).and_return(order.variants) end end