acts_as_chargeable_spec.rb 9.37 KB
# frozen_string_literal: true
require 'spec_helper'

describe ActsAsChargeable do
  before(:each) do
    Product.delete_all
  end

  let!(:Time) {
    zone = Time.zone
    now = zone.now
    time = class_double(Time)
    allow(zone).to receive(:now) { now }
    allow(time).to receive(:zone) { zone }
  }

  context 'as a module' do
    it 'can be implemented in ActiveRecord' do
      expect(Product).to respond_to(:acts_as_chargeable)
    end
  end

  context 'Charges with conekta' do
    it 'An oxxo charge' do
      product = Product.create
      conekta_object_mock = JSON.parse(
        ConektaChargeCreateObject::OXXO_CREATE_CHARGE_OBJECT,
        object_class: OpenStruct)
      allow(product).to receive(:conekta_charge).and_return(conekta_object_mock)
      
      Var.create_charge(:conekta, product, {"conekta_type": "oxxo"})
      expect(product.var_id).to eq conekta_object_mock.id
      expect(product.var_service).to eq 'conekta'
      expect(product.var_status).to eq 'pending_payment'
      expect(product.var_paid_amount).to eq conekta_object_mock.amount
      expect(product.var_fee).to eq conekta_object_mock.fee
      expect(product.var_payment_method).to eq 'OXXO'
    end

    it 'A card charge' do
      product = Product.create
      conekta_object_mock = JSON.parse(
        ConektaChargeCreateObject::CARD_CREATE_CHARGE_OBJECT,
        object_class: OpenStruct)
      allow(product).to receive(:conekta_charge).and_return(conekta_object_mock)

      Var.create_charge(:conekta, product, { conekta_type: 'card', card_token: 'token' })
      product.reload
      expect(product.var_id).to eq conekta_object_mock.id
      expect(product.var_service).to eq 'conekta'
      expect(product.var_status).to eq 'paid'
      expect(product.var_paid_amount).to eq conekta_object_mock.amount
      expect(product.var_fee).to eq conekta_object_mock.fee
      expect(product.var_payment_method).to eq 'Card'
      expect(product.var_payment_at).to eq(Time.strptime conekta_object_mock.paid_at.to_s, '%s')
    end

    xit ': spei' do
    end
  end

  context 'instance methods' do
    it 'returns error message if does not support specified service' do
      product = instance_double('Product')
      expect do
        product.charge_with("paypal", { conekta_type: 'card' })
      end.to raise_error "#{self.class} doesn't support" \
                        " charges with #{service}"
    end

    it 'Chooses proper method to attend specified service payment' do
      product = instance_double('Product')
      options = { conekta_type: 'card' }
      expect do
        product.charge_with("conekta", options)
      end.to send("charge_with_#{service}", options)
    end

    it 'Raises Conekta authentication error' do
      product = instance_double('Product')
      expect do
        charge = product.conekta_charge({})
      end.to raise_error Conekta::AuthenticationError
    end

    it 'Raises Conekta parameter validation error' do
      product = instance_double('Product')
      allow(product).to receive(:conekta_charge).and_raise(Conekta::ParameterValidationError)
      expect do
        charge = product.conekta_charge({})
      end.to raise_error Conekta::ParameterValidationError
    end

    it 'Raises Conekta parameter processing error' do
      product = instance_double('Product')
      allow(product).to receive(:conekta_charge).and_raise(Conekta::ProcessingError)
      expect do
        charge = product.conekta_charge({})
      end.to raise_error Conekta::ProcessingError
    end

    it 'Raises Conekta error' do
      product = instance_double('Product')
      allow(product).to receive(:conekta_charge).and_raise(Conekta::Error)
      expect do
        charge = product.conekta_charge({})
      end.to raise_error Conekta::Error
    end

    it 'Returns card token' do
      product = instance_double('Product')
      hash = product.conekta_type_of_charge(
              {conekta_type: 'card', card_token: 'token'})
      returned_hash = {card: 'token'}
      expect(hash).to eq returned_hash
    end

    it 'Returns card token' do
      product = Product.new
      hash = product.conekta_type_of_charge({conekta_type: 'oxxo'})
      returned_hash = { cash: { type: 'oxxo', expires_at: (Time.zone.now + 3.days).strftime('%Y-%m-%d') } }
      expect(hash).to eq returned_hash
    end

    it 'Updates conekta barcode' do
      product = instance_double('Product')
      conekta_object_mock = JSON.parse(
        ConektaChargeCreateObject::OXXO_CREATE_CHARGE_OBJECT,
        object_class: OpenStruct)
      previous_payment_expiration = product.var_payment_expires_at

      product.update_conekta_barcode conekta_object_mock
      expect(product.var_barcode).to eq conekta_object_mock.payment_method.barcode
      expect(product.var_barcode_url).to eq conekta_object_mock.payment_method.barcode_url
      expect(product.var_payment_expires_at).to_not eq previous_payment_expiration
    end

    it 'Makes manual charge' do
      product = instance_double('Product')
      product.manual_charge
      previous_time = product.var_payment_at

      expect(product.var_service).to eq 'manual'
      expect(product.status).to eq 'paid'
      expect(product.var_payment_at).to_not eq previous_time
    end

    it 'Makes manual discharge' do
      product = instance_double('Product')
      product.manual_charge

      expect(product.var_service).to eq 'manual'
      expect(product.status).to eq 'pending'
      expect(product.var_payment_at).to be_nil
    end
    
    it 'Return not charged yet error' do
      product = Product.create
      msg = product.find_charge
      error = { error_message: 'Not charged yet' }
      expect(msg).to eq error
    end

    it 'Returns Conekta Object' do
      product = Product.create
      conekta_object_mock = JSON.parse(
        ConektaChargeCreateObject::OXXO_CREATE_CHARGE_OBJECT,
        object_class: OpenStruct)
      allow(product).to receive(:find_conekta_charge).and_return conekta_object_mock
      expect(product.find_conekta_charge).to eq conekta_object_mock
    end

    it 'Returns true when object is charged' do
      product = Product.create
      conekta_object_mock = JSON.parse(
        ConektaChargeCreateObject::CARD_CREATE_CHARGE_OBJECT,
        object_class: OpenStruct)
      allow(product).to receive(:find_charge).and_return(conekta_object_mock)

      expect(product.charged?).to be true
    end

    it 'Returns false when object has not been charged' do
      product = Product.create
      expect(product.charged?).to be false
    end

    xit 'Test instance support' do
    end

    xit 'Test sync' do
    end

    xit 'Test conekta_attributes' do
    end

    it 'Returns true if object is payed' do
      product = Product.new
      product.status = 'paid'
      expect(product.payed?).to be true
    end

    it 'Returns true if object is payed' do
      product = Product.new
      expect(product.payed?).to be false
    end

    it 'Returns already paid error when cancelling oxxo payment' do
      product = Product.new
      product.status = 'paid'
      error_msg = { error_message: 'Already paid' }

      expect(product.cancel_oxxo_payment).to eq error_msg
    end

    it 'Returns object not charged error when cancelling oxxo payment' do
      product = Product.new
      error_msg = { error_message: 'Not charged yet' }

      expect(product.cancel_oxxo_payment).to eq error_msg
    end

    it 'Returns not charged with oxxo error when cancelling oxxo payment' do
      product = Product.new
      product.var_service = 'conekta'
      error_msg = { error_message: 'Not charged with oxxo' }
      expect(product.cancel_oxxo_payment).to eq error_msg
    end

    it 'Nils every object attribute' do
      product = Product.create
      conekta_object_mock = JSON.parse(
        ConektaChargeCreateObject::OXXO_CREATE_CHARGE_OBJECT,
        object_class: OpenStruct)
      allow(product).to receive(:conekta_charge).and_return(conekta_object_mock)

      Var.create_charge(:conekta, product, {"conekta_type": "oxxo"})
      product.clean_var_variables

      # TODO: Check unused attribute in migration "var_payment::Datetime"
      expect(product.var_id).to be_nil
      expect(product.var_service).to be_nil
      expect(product.var_status).to be_nil
      expect(product.var_paid_amount).to be_nil
      expect(product.var_fee).to be_nil
      expect(product.var_payment_method).to be_nil
      expect(product.var_barcode).to be_nil
      expect(product.var_barcode_url).to be_nil
      expect(product.var_payment_at).to be_nil
      expect(product.var_payment_expires_at).to be_nil
    end
  end
end

# Tests for mock on Chargeable class
describe Product do
  it { is_expected.to respond_to(:charge_with) }
  it { is_expected.to respond_to(:charge_with_conekta) }
  it { is_expected.to respond_to(:conekta_charge) }
  it { is_expected.to respond_to(:conekta_type_of_charge) }
  it { is_expected.to respond_to(:update_conekta_barcode) }
  it { is_expected.to respond_to(:manual_charge) }
  it { is_expected.to respond_to(:manual_discharge) }
  it { is_expected.to respond_to(:find_charge) }
  it { is_expected.to respond_to(:charged?) }
  it { is_expected.to respond_to(:find_conekta_charge) }
  it { is_expected.to respond_to(:instance_support?) }
  it { is_expected.to respond_to(:sync) }
  it { is_expected.to respond_to(:conekta_attributes) }
  it { is_expected.to respond_to(:paypal_attributes) }
  it { is_expected.to respond_to(:var_payed?) }
  it { is_expected.to respond_to(:cancel_oxxo_payment) }
  it { is_expected.to respond_to(:var_expired_by) }
end