mercredi 29 mars 2017

"normalize_opts expects a string or a hash" error testing Stripe in Rails

Im trying to create a test for a method that make a charge in a credit card using Stripe, I have set all the Stripe configurations and already got working other tests like "create stripe customer" and "assign bank account" but when I try to create a charge the test show me the next failure:

1) STRIPE API POST /v1/clinics/:id/pay when the event exist pay event
 Failure/Error: @charge = Stripe::Charge.create( charge_attrs, user.secret_key )

 TypeError:
   normalize_opts expects a string or a hash
 # /.rvm/gems/ruby-2.4.0/gems/stripe-1.58.0/lib/stripe/util.rb:203:in `normalize_opts'


Gemfile

gem 'rails', '~> 5.0.1'
gem 'stripe', '~> 1.31'
gem 'stripe-ruby-mock', '~> 2.4.0', :require => 'stripe_mock'


stripe_spec.rb

  RSpec.describe 'STRIPE API', type: :request do
    describe 'POST /v1/events/:id/pay' do
        let!(:events) { create_list(:event, 2) }
        let(:event_id) { events.first.id }

        let!(:users) { create_list(:user, 2) }
        let(:user_id) { users.first.id }

        let(:auth_headers) { users.first.create_new_auth_token }

        let(:stripe_helper) { StripeMock.create_test_helper }

        context 'when the event exist' do
          before {
            StripeMock.start
            card_token = StripeMock.generate_card_token(last4: "9191", exp_year: 2020)

            post "/v1/events/#{event_id}/pay", params: { token: card_token, user_id: user_id } , headers: auth_headers
          }
          after { StripeMock.stop }

          it "pay event" do
            p json
            expect(response).to be_success
          end
        end
    end
end


events_controller

module Api::V1
  class EventsController < ApiController
    #POST events/{id}/pay/{user_id, token}
    def pay
      @event = Event.all.active.find(params[:id])
    # Find the user to pay.
      user = User.find( params[:id] )
      # Charge fee.
      amount = 10
      user.currency = 'USD'
      # Calculate the fee amount that goes to the application.
      fee = (amount * Rails.application.secrets.fee_percentage).to_i
      begin
        charge_attrs = {
          amount: amount,
          currency: user.currency,
          source: params[:token],
          description: "Pickleball Clinic",
          application_fee: fee
        }
        # Use the user-to-be-paid's access token
        # to make the charge directly on their account
        @charge = Stripe::Charge.create( charge_attrs, user.secret_key )

        json_response(@charge)

      rescue Stripe::CardError => e
        @error = e.json_body[:error][:message]
        json_response(@error)
      end        
    end
end


event.rb

class Event < ApplicationRecord
  validates_presence_of :name
  validates_presence_of :description
  validates_presence_of :created_by
  belongs_to  :admin, :class_name => 'User', :foreign_key => 'created_by'
  scope :active, -> { where( is_active: true ) }

  has_many    :event_participants
  has_many    :participants, :through => :event_participants, foreign_key: "participant_id" do
    def active
      where("event_participants.is_active = ?", true)
    end
  end
end


FactoryGirl

FactoryGirl.define do
  factory :event do
    association :admin, factory: :user
    name        { Faker::Lorem.sentence }
    description { Faker::Lorem.paragraphs(2) }
    status      { Faker::Number.between(0,3) }
    fee         { Faker::Number.between(5,10) }

    created_at  { Faker::Date.between(2.days.ago, Date.today) }
    updated_at  { Faker::Date.between(1.days.ago, Date.today) }
    is_active   { 1 }

    association       :location, factory: :location

    after(:create) do |event|
      create_list(:event_participants, 3, event: event)
    end

  end
end

Aucun commentaire:

Enregistrer un commentaire