var_spec.rb 13.7 KB
# frozen_string_literal: true
require 'spec_helper'

describe Var do
  context 'as a class' do
    it { is_expected.to respond_to(:var_classes) }
    it { is_expected.to respond_to(:add_var_class) }
    it { is_expected.to respond_to(:create_charge) }
    it { is_expected.to respond_to(:conekta_webhook) }
    it { is_expected.to respond_to(:find_charge) }
  end

  it 'supports conekta' do
    expect(Var.send(:supported_service?, :conekta)).to be true
  end

  it 'holds var classes' do
    expect(Var.var_classes).to eq([Product])
    class Dummy < ActiveRecord::Base
      acts_as_chargeable
    end
    expect(Var.var_classes).to eq([Product, Dummy])
  end

  context 'when creating a charge' do
    it 'is delegates the call' do
      product = instance_double('Product')
      allow(product).to receive(:charge_with).and_return(:success)
      charge = Var.create_charge(:conekta, product, {})
      expect(charge).to eq :success
    end

    it 'raises an error if service is not supported' do
      product = instance_double('Product')
      expect do
        Var.create_charge(:random_payment_service, product, {})
      end.to raise_error 'Service is not supported'
    end

    it 'raises an error if object cannot be chargable' do
      product = instance_double('Product')
      expect do
        Var.create_charge(:conekta, product, {})
      end.to raise_error "#{product.class} doesn't support charges"
    end
  end

  context 'when receiving a webhook from conekta' do
    let!(:chargable_product) do
      Product.new # Weird hack to enable connection
      instance_double('Product')
    end

    it 'expects a Hash as an input' do
      [[], '', nil].each do |input|
        expect do
          Var.conekta_webhook(input)
        end.to raise_error "Hash expected, received #{input.class}"
      end
    end

    it 'expects a {data: {object: ... }} as an input' do
      expect do
        Var.conekta_webhook({})
      end.to raise_error 'Malformed hash received'
    end

    it 'handles card charge creation' do
      params = { "data": { "object": { "id": '5511d4ce2412294cf6000081', "livemode": false, "created_at": 1_427_231_950, "status": 'pending_payment', "currency": 'MXN', "description": 'Stogies', "reference_id": '9839-wolf_pack', "failure_code": nil, "failure_message": nil, "monthly_installments": nil, "object": 'charge', "amount": 20_000, "paid_at": nil, "fee": 963, "customer_id": '', "refunds": [], "payment_method": { "name": 'Jorge Lopez', "exp_month": '12', "exp_year": '19', "auth_code": nil, "object": 'card_payment', "last4": '4242', "brand": 'visa' }, "details": { "name": nil, "phone": nil, "email": nil, "line_items": [] } }, "previous_attributes": {} }, "livemode": false, "webhook_status": 'pending', "id": '5511d4ce2412294cf6000084', "object": 'event', "type": 'charge.created', "created_at": 1_427_231_950, "webhook_logs": [{ "id": 'webhl_nPzGMBeQmMUu7aQ', "url": 'http://requestb.in/1em0jsx1', "failed_attempts": 0, "last_http_response_status": -1, "object": 'webhook_log', "last_attempted_at": 0 }] }
      cardHandler = class_double('Var::ConektaCardHandler')
                    .as_stubbed_const(transfer_nested_constants: true)
      expect(cardHandler).to receive(:analyze).with(params)
      Var.conekta_webhook(params)
    end

    it 'handles oxxo charge creation' do
      null = nil
      params = { "data": { "object": { "id": '5514803f241229981e0022e6', "livemode": false, "created_at": 1_427_406_911, "status": 'pending_payment', "currency": 'MXN', "description": 'Stogies', "reference_id": '9839-wolf_pack', "failure_code": null, "failure_message": null, "monthly_installments": null, "object": 'charge', "amount": 20_000, "paid_at": null, "fee": 812, "customer_id": '', "refunds": [], "payment_method": { "barcode": '38100000000042290121213001160013', "barcode_url": 'http://s3.amazonaws.com/cash_payment_barcodes/38100000000042290121213001160013.png', "object": 'cash_payment', "type": 'oxxo', "expires_at": 1_430_006_400, "store_name": 'OXXO' }, "details": { "name": 'Wolverine', "phone": '403-342-0642', "email": 'logan@x-men.org', "line_items": [] } }, "previous_attributes": {} }, "livemode": false, "webhook_status": 'pending', "id": '5514803f241229981e0022e9', "object": 'event', "type": 'charge.created', "created_at": 1_427_406_911, "webhook_logs": [{ "id": 'webhl_PBmYvkfdNDYKezJ', "url": 'http://requestb.in/u3n4ywu3', "failed_attempts": 0, "last_http_response_status": -1, "object": 'webhook_log', "last_attempted_at": 0 }] }
      oxxoHandler = class_double('Var::ConektaOxxoHandler')
                    .as_stubbed_const(transfer_nested_constants: true)
      expect(oxxoHandler).to receive(:analyze).with(params)
      Var.conekta_webhook(params)
    end

    it 'handles SPEI charge creation' do
      null = nil
      params = { "data": { "object": { "id": '551499322412292eec002159', "livemode": false, "created_at": 1_427_413_298, "status": 'pending_payment', "currency": 'MXN', "description": 'Stogies', "reference_id": '9839-wolf_pack', "failure_code": null, "failure_message": null, "monthly_installments": null, "object": 'charge', "amount": 20_000, "paid_at": null, "fee": 928, "customer_id": '', "refunds": [], "payment_method": { "clabe": '646180111800012432', "bank": 'STP', "issuing_account_holder": null, "issuing_account_tax_id": null, "issuing_account_bank": null, "issuing_account_number": null, "receiving_account_holder": null, "receiving_account_tax_id": null, "receiving_account_number": '646180111800012432', "receiving_account_bank": 'STP', "reference_number": null, "description": null, "tracking_code": null, "executed_at": null, "object": 'bank_transfer_payment', "type": 'spei', "expires_at": 1_435_189_298 }, "details": { "name": 'Wolverine', "phone": '403-342-0642', "email": 'logan@x-men.org', "line_items": [] } }, "previous_attributes": {} }, "livemode": false, "webhook_status": 'pending', "id": '551499322412292eec00215c', "object": 'event', "type": 'charge.created', "created_at": 1_427_413_298, "webhook_logs": [{ "id": 'webhl_ENPXoFkKWyDqTAt', "url": 'http://requestb.in/151xj4r1', "failed_attempts": 0, "last_http_response_status": -1, "object": 'webhook_log', "last_attempted_at": 1_427_413_285 }] }
      speiHandler = class_double('Var::ConektaSpeiHandler')
                    .as_stubbed_const(transfer_nested_constants: true)
      expect(speiHandler).to receive(:analyze).with(params)
      Var.conekta_webhook(params)
    end

    it 'handles card payment' do
      null = nil
      params = { "data": { "object": { "id": '5511d4ce2412294cf6000081', "livemode": false, "created_at": 1_427_231_950, "status": 'paid', "currency": 'MXN', "description": 'Stogies', "reference_id": '9839-wolf_pack', "failure_code": null, "failure_message": null, "monthly_installments": null, "object": 'charge', "amount": 20_000, "paid_at": 1_427_231_952, "fee": 963, "customer_id": '', "refunds": [], "payment_method": { "name": 'Jorge Lopez', "exp_month": '12', "exp_year": '19', "auth_code": '000000', "object": 'card_payment', "last4": '4242', "brand": 'visa' }, "details": { "name": null, "phone": null, "email": null, "line_items": [] } }, "previous_attributes": { "payment_method": {} } }, "livemode": false, "webhook_status": 'pending', "id": '5511d4d02412294cf6000088', "object": 'event', "type": 'charge.paid', "created_at": 1_427_231_952, "webhook_logs": [{ "id": 'webhl_m5kgkhmgETe6Y4s', "url": 'http://requestb.in/1em0jsx1', "failed_attempts": 0, "last_http_response_status": -1, "object": 'webhook_log', "last_attempted_at": 0 }] }
      cardHandler = class_double('Var::ConektaCardHandler')
                    .as_stubbed_const(transfer_nested_constants: true)
      expect(cardHandler).to receive(:analyze).with(params)
      Var.conekta_webhook(params)
    end

    it 'handles oxxo payment' do
      null = nil
      params = { "data": { "object": { "id": '5514803f241229981e0022e6', "livemode": false, "created_at": 1_427_406_911, "status": 'paid', "currency": 'MXN', "description": 'Stogies', "reference_id": '9839-wolf_pack', "failure_code": null, "failure_message": null, "monthly_installments": null, "object": 'charge', "amount": 20_000, "paid_at": 1_427_406_913, "fee": 812, "customer_id": '', "refunds": [], "payment_method": { "barcode": '38100000000042290121213001160013', "barcode_url": 'http://s3.amazonaws.com/cash_payment_barcodes/38100000000042290121213001160013.png', "object": 'cash_payment', "type": 'oxxo', "expires_at": 1_430_006_400, "store_name": 'OXXO' }, "details": { "name": 'Wolverine', "phone": '403-342-0642', "email": 'logan@x-men.org', "line_items": [] } }, "previous_attributes": { "status": 'pending_payment' } }, "livemode": false, "webhook_status": 'pending', "id": '55148042241229d4fb00b58a', "object": 'event', "type": 'charge.paid', "created_at": 1_427_406_914, "webhook_logs": [{ "id": 'webhl_yYes9gx41vAj6ag', "url": 'http://requestb.in/151xj4r1', "failed_attempts": 0, "last_http_response_status": -1, "object": 'webhook_log', "last_attempted_at": 1_427_406_984 }] }
      oxxoHandler = class_double('Var::ConektaOxxoHandler')
                    .as_stubbed_const(transfer_nested_constants: true)
      expect(oxxoHandler).to receive(:analyze).with(params)
      Var.conekta_webhook(params)
    end

    it 'handles SPEI payment' do
      null = nil
      params = { "data": { "object": { "id": '551499322412292eec002159', "livemode": false, "created_at": 1_427_413_298, "status": 'pending_payment', "currency": 'MXN', "description": 'Stogies', "reference_id": '9839-wolf_pack', "failure_code": null, "failure_message": null, "monthly_installments": null, "object": 'charge', "amount": 20_000, "paid_at": null, "fee": 928, "customer_id": '', "refunds": [], "payment_method": { "clabe": '646180111800012432', "bank": 'STP', "issuing_account_holder": null, "issuing_account_tax_id": null, "issuing_account_bank": null, "issuing_account_number": null, "receiving_account_holder": null, "receiving_account_tax_id": null, "receiving_account_number": '646180111800012432', "receiving_account_bank": 'STP', "reference_number": null, "description": null, "tracking_code": null, "executed_at": null, "object": 'bank_transfer_payment', "type": 'spei', "expires_at": 1_435_189_298 }, "details": { "name": 'Wolverine', "phone": '403-342-0642', "email": 'logan@x-men.org', "line_items": [] } }, "previous_attributes": {} }, "livemode": false, "webhook_status": 'pending', "id": '551499322412292eec00215c', "object": 'event', "type": 'charge.created', "created_at": 1_427_413_298, "webhook_logs": [{ "id": 'webhl_ENPXoFkKWyDqTAt', "url": 'http://requestb.in/151xj4r1', "failed_attempts": 0, "last_http_response_status": -1, "object": 'webhook_log', "last_attempted_at": 1_427_413_285 }] }
      speiHandler = class_double('Var::ConektaSpeiHandler')
                    .as_stubbed_const(transfer_nested_constants: true)
      expect(speiHandler).to receive(:analyze).with(params)
      Var.conekta_webhook(params)
    end

    it 'handles payout scheduled' do
      null = nil
      params = { "object": { "livemode": true, "currency": 'MXN', "method": { "id": 'pytmtd_MymQ7favB2hQJC', "created_at": 1_467_832_748, "payee_id": null, "_type": 'BankTransferPayoutMethod', "object": 'bank_transfer_payout_method', "account_number": '072580002374915018', "account_holder": 'UKKO SOLUTIONS SA DE CV', "bank": 'Banco Mercantil del Norte, S.A.' }, "object": 'transfer', "amount": 303_534, "id": '577d59ac243c7fee8100146d', "created_at": 1_467_832_748, "status": 'scheduled', "statement_reference": '4632539', "statement_description": 'Conekta 4632539' }, "previous_attributes": { "status": 'pending', "broker_transaction_reference": null } }
      payoutHandler = class_double('Var::ConektaPayoutHandler')
                      .as_stubbed_const(transfer_nested_constants: true)
      expect(payoutHandler).to receive(:analyze).with(params)
      Var.conekta_webhook(params)
    end

    it 'handles payout paid' do
      null = nil
      params = { "object": { "livemode": true, "currency": 'MXN', "method": { "id": 'pytmtd_MymQ7favB2hQJC', "created_at": 1_467_832_748, "payee_id": null, "_type": 'BankTransferPayoutMethod', "object": 'bank_transfer_payout_method', "account_number": '072580002374915018', "account_holder": 'UKKO SOLUTIONS SA DE CV', "bank": 'Banco Mercantil del Norte, S.A.' }, "object": 'transfer', "amount": 303_534, "id": '577d59ac243c7fee8100146d', "created_at": 1_467_832_748, "status": 'scheduled', "statement_reference": '4632539', "statement_description": 'Conekta 4632539' }, "previous_attributes": {} }
      payoutHandler = class_double('Var::ConektaPayoutHandler')
                      .as_stubbed_const(transfer_nested_constants: true)
      expect(payoutHandler).to receive(:analyze).with(params)
      Var.conekta_webhook(params)
    end

    it 'processes card charge' do
      # allow(Var).to receive(:find_charge).and_return chargable_product
      #
      # allow(chargable_product).to receive(:update_columns).and_return true
      # allow(chargable_product).to receive(:var_payed?).and_return false
      # allow(chargable_product).to receive(:var_id).
      #   and_return '5511d4ce2412294cf6000081'

      # expect(result.var_id).to eq('5511d4ce2412294cf6000081')
      # TODO: Define what is actually being teted
    end

    xit 'handles Plan creado' do
      pending
    end

    xit 'handles Crear un customer sin tarjeta y sin plan' do
      pending
    end

    xit 'handles Customer creado con una tarjeta y sin plan' do
      pending
    end

    xit 'handles Customer creado con tarjeta y con plan (suscripción)' do
      pending
    end

    xit 'handles Suscripción creada' do
      pending
    end

    xit 'handles Suscripción pagada' do
      pending
    end

    xit 'handles Suscripción activa' do
      pending
    end

    xit 'handles Contracargo creado' do
      pending
    end

    xit 'handles Contracargo ganado' do
      pending
    end

    xit 'handles Contracargo perdido' do
      pending
    end
  end
end