Ricardo Garcia

Add more specs

1 source 'https://rubygems.org' 1 source 'https://rubygems.org'
2 2
3 group :development do 3 group :development do
4 - gem "sqlite3" 4 + gem 'sqlite3'
5 end 5 end
6 6
7 gemspec 7 gemspec
......
1 +# A sample Guardfile
2 +# More info at https://github.com/guard/guard#readme
3 +
4 +## Uncomment and set this to only include directories you want to watch
5 +# directories %w(app lib config test spec features) \
6 +# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7 +
8 +## Note: if you are using the `directories` clause above and you are not
9 +## watching the project directory ('.'), then you will want to move
10 +## the Guardfile to a watched dir and symlink it back, e.g.
11 +#
12 +# $ mkdir config
13 +# $ mv Guardfile config/
14 +# $ ln -s config/Guardfile .
15 +#
16 +# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17 +
18 +# Note: The cmd option is now required due to the increasing number of ways
19 +# rspec may be run, below are examples of the most common uses.
20 +# * bundler: 'bundle exec rspec'
21 +# * bundler binstubs: 'bin/rspec'
22 +# * spring: 'bin/rspec' (This will use spring if running and you have
23 +# installed the spring binstubs per the docs)
24 +# * zeus: 'zeus rspec' (requires the server to be started separately)
25 +# * 'just' rspec: 'rspec'
26 +
27 +guard :rspec, cmd: 'bundle exec rspec --color --format d' do
28 + require 'guard/rspec/dsl'
29 + dsl = Guard::RSpec::Dsl.new(self)
30 +
31 + # Feel free to open issues for suggestions and improvements
32 +
33 + # RSpec files
34 + rspec = dsl.rspec
35 + watch(rspec.spec_helper) { rspec.spec_dir }
36 + watch(rspec.spec_support) { rspec.spec_dir }
37 + watch(rspec.spec_files)
38 +
39 + # Ruby files
40 + ruby = dsl.ruby
41 + dsl.watch_spec_files_for(ruby.lib_files)
42 +
43 + # Rails files
44 + rails = dsl.rails(view_extensions: %w(erb haml slim))
45 + dsl.watch_spec_files_for(rails.app_files)
46 + dsl.watch_spec_files_for(rails.views)
47 +
48 + watch(rails.controllers) do |m|
49 + [
50 + rspec.spec.call("routing/#{m[1]}_routing"),
51 + rspec.spec.call("controllers/#{m[1]}_controller"),
52 + rspec.spec.call("acceptance/#{m[1]}")
53 + ]
54 + end
55 +
56 + # Rails config changes
57 + watch(rails.spec_helper) { rspec.spec_dir }
58 + watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59 + watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60 +
61 + # Capybara features specs
62 + watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
63 + watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
64 +
65 + # Turnip features and steps
66 + watch(%r{^spec/acceptance/(.+)\.feature$})
67 + watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68 + Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance'
69 + end
70 +end
...@@ -3,13 +3,14 @@ ...@@ -3,13 +3,14 @@
3 require 'bundler/setup' 3 require 'bundler/setup'
4 require 'active_record' 4 require 'active_record'
5 require 'active_support' 5 require 'active_support'
6 +require 'var'
7 +
6 require_relative '../spec/mocks/var_database_mock.rb' 8 require_relative '../spec/mocks/var_database_mock.rb'
7 require_relative '../spec/mocks/var_models_mock.rb' 9 require_relative '../spec/mocks/var_models_mock.rb'
8 -require 'var'
9 10
10 -ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") 11 +ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
11 ActiveRecord::Schema.verbose = false 12 ActiveRecord::Schema.verbose = false
12 VarDatabaseMock.setup_db 13 VarDatabaseMock.setup_db
13 14
14 -require "pry" 15 +require 'pry'
15 Pry.start 16 Pry.start
......
...@@ -52,7 +52,8 @@ module ActsAsChargeable ...@@ -52,7 +52,8 @@ module ActsAsChargeable
52 line_items: [{ 52 line_items: [{
53 description: sync(:conekta, 'description'), quantity: 1, 53 description: sync(:conekta, 'description'), quantity: 1,
54 unit_price: sync(:conekta, 'amount'), name: sync(:conekta, 'name') 54 unit_price: sync(:conekta, 'amount'), name: sync(:conekta, 'name')
55 - }] } 55 + }]
56 + }
56 }.merge(conekta_type_of_charge(options))) 57 }.merge(conekta_type_of_charge(options)))
57 end 58 end
58 59
...@@ -61,8 +62,7 @@ module ActsAsChargeable ...@@ -61,8 +62,7 @@ module ActsAsChargeable
61 { card: options[:card_token] } 62 { card: options[:card_token] }
62 elsif options[:conekta_type] == 'oxxo' 63 elsif options[:conekta_type] == 'oxxo'
63 { cash: { type: 'oxxo', 64 { cash: { type: 'oxxo',
64 - expires_at: (Time.zone.today + 3.days).strftime('%Y-%m-%d') } 65 + expires_at: (Time.zone.today + 3.days).strftime('%Y-%m-%d') } }
65 - }
66 end 66 end
67 end 67 end
68 68
...@@ -176,13 +176,11 @@ module ActsAsChargeable ...@@ -176,13 +176,11 @@ module ActsAsChargeable
176 private 176 private
177 177
178 def clean_var_variables 178 def clean_var_variables
179 - if update_columns(var_status: nil, var_barcode: nil, var_barcode_url: nil, 179 + return { object: code } if update(var_status: nil, var_barcode: nil,
180 - var_id: nil, var_service: nil, var_payment_at: nil, 180 + var_barcode_url: nil, var_id: nil,
181 + var_service: nil, var_payment_at: nil,
181 var_payment_expires_at: nil) 182 var_payment_expires_at: nil)
182 - { object: code }
183 - else
184 { error_message: 'Something went wrong' } 183 { error_message: 'Something went wrong' }
185 end 184 end
186 end 185 end
187 - end
188 end 186 end
......
...@@ -5,16 +5,10 @@ require 'acts_as_chargeable' ...@@ -5,16 +5,10 @@ require 'acts_as_chargeable'
5 5
6 # Main Module 6 # Main Module
7 module Var 7 module Var
8 - 8 + VALID_SERVICES = [:conekta].freeze
9 - VALID_SERVICES = [:conekta]
10 @@var_classes = [] 9 @@var_classes = []
11 10
12 class << self 11 class << self
13 -
14 - def valid_services
15 - VALID_SERVICES
16 - end
17 -
18 def var_classes 12 def var_classes
19 @@var_classes 13 @@var_classes
20 end 14 end
...@@ -24,26 +18,31 @@ module Var ...@@ -24,26 +18,31 @@ module Var
24 end 18 end
25 19
26 def create_charge(service, object, options = {}) 20 def create_charge(service, object, options = {})
27 - return { error_message: 'Service is not supported' } unless VALID_SERVICES.include? service 21 + raise 'Service is not supported' unless supported_service? service
28 - return { error_message: "#{object.class} doesn't support charges" } unless object.respond_to?(:charge_with) 22 + raise "#{object.class} doesn't support charges" unless object.respond_to? :charge_with
29 - charge = object.charge_with(service, options) 23 + object.charge_with(service, options)
30 - charge
31 end 24 end
32 25
33 def conekta_webhook(params) 26 def conekta_webhook(params)
34 payment = params[:data][:object] 27 payment = params[:data][:object]
35 object = Var.find_charge payment[:id] 28 object = Var.find_charge payment[:id]
29 + update_object_var_data(object, payment)
30 + object
31 + # rescue Exception => exception
32 + # puts exception
33 + # false
34 + end
35 +
36 + def update_object_var_data(object, data)
37 + payment = data
36 object.update_columns(var_status: payment[:status]) 38 object.update_columns(var_status: payment[:status])
37 - if object.var_payed? 39 + return object unless object.var_payed?
38 time = Time.strptime payment[:paid_at].to_s, '%s' 40 time = Time.strptime payment[:paid_at].to_s, '%s'
39 amount = payment[:amount].to_f / 100.0 41 amount = payment[:amount].to_f / 100.0
40 fee = payment[:fee].to_f / 100.0 42 fee = payment[:fee].to_f / 100.0
41 - object.update(var_fee: fee, var_paid_amount: amount, var_payment_method: payment[:payment_method][:object], var_payment_at: time) 43 + object.update(var_fee: fee, var_paid_amount: amount,
42 - end 44 + var_payment_method: payment[:payment_method][:object],
43 - object 45 + var_payment_at: time)
44 - rescue Exception => exception
45 - puts exception
46 - false
47 end 46 end
48 47
49 def find_charge(id) 48 def find_charge(id)
...@@ -52,6 +51,13 @@ module Var ...@@ -52,6 +51,13 @@ module Var
52 class_name.where(var_id: id) 51 class_name.where(var_id: id)
53 end.flatten.first 52 end.flatten.first
54 end 53 end
54 +
55 + private
56 +
57 + def supported_service?(service)
58 + VALID_SERVICES.include? service
59 + end
60 +
55 end 61 end
56 end 62 end
57 63
......
1 # Var Version 1 # Var Version
2 module Var 2 module Var
3 - VERSION = '0.3.0' 3 + VERSION = '0.3.0'.freeze
4 end 4 end
......
1 +require 'spec_helper'
2 +
3 +describe ActsAsChargeable do
4 + context 'as a module' do
5 + it 'can be implemented in ActiveRecord' do
6 + expect(Product).to respond_to(:acts_as_chargeable)
7 + end
8 + end
9 +end
10 +
11 +# Tests for mock on Chargeable class
12 +describe Product do
13 + it { is_expected.to respond_to(:charge_with) }
14 + it { is_expected.to respond_to(:charge_with_conekta) }
15 + it { is_expected.to respond_to(:conekta_charge) }
16 + it { is_expected.to respond_to(:conekta_type_of_charge) }
17 + it { is_expected.to respond_to(:update_conekta_barcode) }
18 + it { is_expected.to respond_to(:manual_charge) }
19 + it { is_expected.to respond_to(:manual_discharge) }
20 + it { is_expected.to respond_to(:find_charge) }
21 + it { is_expected.to respond_to(:charged?) }
22 + it { is_expected.to respond_to(:find_conekta_charge) }
23 + it { is_expected.to respond_to(:instance_support?) }
24 + it { is_expected.to respond_to(:sync) }
25 + it { is_expected.to respond_to(:conekta_attributes) }
26 + it { is_expected.to respond_to(:paypal_attributes) }
27 + it { is_expected.to respond_to(:var_payed?) }
28 + it { is_expected.to respond_to(:cancel_oxxo_payment) }
29 + it { is_expected.to respond_to(:var_expired_by) }
30 +end
1 class Product < ActiveRecord::Base 1 class Product < ActiveRecord::Base
2 + acts_as_chargeable
2 end 3 end
......
1 require 'pry' 1 require 'pry'
2 require 'active_record' 2 require 'active_record'
3 require 'active_support' 3 require 'active_support'
4 +require 'Var'
5 +
4 require 'mocks/var_database_mock' 6 require 'mocks/var_database_mock'
5 require 'mocks/var_models_mock' 7 require 'mocks/var_models_mock'
6 -require 'Var'
7 8
8 -ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") 9 +ActiveRecord::Base.establish_connection(adapter: 'sqlite3',
10 + database: ':memory:')
9 ActiveRecord::Schema.verbose = false 11 ActiveRecord::Schema.verbose = false
10 VarDatabaseMock.setup_db 12 VarDatabaseMock.setup_db
......
...@@ -2,15 +2,129 @@ require 'spec_helper' ...@@ -2,15 +2,129 @@ require 'spec_helper'
2 2
3 describe Var do 3 describe Var do
4 context 'as a class' do 4 context 'as a class' do
5 - it { is_expected.to respond_to(:valid_services) }
6 it { is_expected.to respond_to(:var_classes) } 5 it { is_expected.to respond_to(:var_classes) }
7 it { is_expected.to respond_to(:add_var_class) } 6 it { is_expected.to respond_to(:add_var_class) }
8 it { is_expected.to respond_to(:create_charge) } 7 it { is_expected.to respond_to(:create_charge) }
9 it { is_expected.to respond_to(:conekta_webhook) } 8 it { is_expected.to respond_to(:conekta_webhook) }
10 it { is_expected.to respond_to(:find_charge) } 9 it { is_expected.to respond_to(:find_charge) }
10 + end
11 +
12 + it 'supports conekta' do
13 + expect(Var.send(:supported_service?, :conekta)).to be true
14 + end
15 +
16 + it 'holds var classes' do
17 + expect(Var.var_classes).to eq([Product])
18 + class Dummy < ActiveRecord::Base
19 + acts_as_chargeable
20 + end
21 + expect(Var.var_classes).to eq([Product, Dummy])
22 + end
23 +
24 + context 'when creating a charge' do
25 + it 'is delegates the call' do
26 + product = instance_double('Product')
27 + allow(product).to receive(:charge_with).and_return(:success)
28 + charge = Var.create_charge(:conekta, product, {})
29 + expect(charge).to eq :success
30 + end
31 +
32 + it 'raises an error if service is not supported' do
33 + product = instance_double('Product')
34 + expect do
35 + Var.create_charge(:random_payment_service, product, {})
36 + end.to raise_error 'Service is not supported'
37 + end
38 +
39 + it 'raises an error if object cannot be chargable' do
40 + product = instance_double('Product')
41 + expect do
42 + Var.create_charge(:conekta, product, {})
43 + end.to raise_error "#{product.class} doesn't support charges"
44 + end
45 + end
46 +
47 + context 'when receiving a webhook from conekta' do
48 +
49 + let!(:chargable_product) do
50 + Product.new # Weird hack to enable connection
51 + instance_double('Product')
52 + end
53 +
54 + it 'handles Cargo creado con tarjeta' do
55 + params = {"data":{"object":{"id":"5511d4ce2412294cf6000081","livemode":false,"created_at":1427231950,"status":"pending_payment","currency":"MXN","description":"Stogies","reference_id":"9839-wolf_pack","failure_code":nil,"failure_message":nil,"monthly_installments":nil,"object":"charge","amount":20000,"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":1427231950,"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}]}
56 +
57 + allow(Var).to receive(:find_charge).and_return chargable_product
58 + allow(chargable_product).to receive(:update_columns).and_return true
59 + allow(chargable_product).to receive(:var_payed?).and_return false
60 + allow(chargable_product).to receive(:var_id).and_return '5511d4ce2412294cf6000081'
61 +
62 + result = Var.conekta_webhook params
63 + expect(result.var_id).to eq('5511d4ce2412294cf6000081')
64 +
65 + # TODO: Define what is actually being teted
66 +
67 + pending
68 + end
69 +
70 + it 'handles Cargo pagado con tarjeta' do
71 + pending
72 + end
73 +
74 + it 'handles Cargo de OXXO creado' do
75 + pending
76 + end
77 +
78 + it 'handles Cargo de OXXO pagado' do
79 + pending
80 + end
81 +
82 + xit 'handles Cargo de SPEI creado' do
83 + pending
84 + end
85 +
86 + xit 'handles Cargo de SPEI pagado' do
87 + pending
88 + end
89 +
90 + xit 'handles Plan creado' do
91 + pending
92 + end
93 +
94 + xit 'handles Crear un customer sin tarjeta y sin plan' do
95 + pending
96 + end
97 +
98 + xit 'handles Customer creado con una tarjeta y sin plan' do
99 + pending
100 + end
101 +
102 + xit 'handles Customer creado con tarjeta y con plan (suscripción)' do
103 + pending
104 + end
105 +
106 + xit 'handles Suscripción creada' do
107 + pending
108 + end
109 +
110 + xit 'handles Suscripción pagada' do
111 + pending
112 + end
113 +
114 + xit 'handles Suscripción activa' do
115 + pending
116 + end
117 +
118 + xit 'handles Contracargo creado' do
119 + pending
120 + end
121 +
122 + xit 'handles Contracargo ganado' do
123 + pending
124 + end
11 125
12 - it 'returns conekta as a valid service' do 126 + xit 'handles Contracargo perdido' do
13 - expect(Var.valid_services).to eq([:conekta]) 127 + pending
14 end 128 end
15 end 129 end
16 end 130 end
......
...@@ -5,7 +5,7 @@ require 'var/version' ...@@ -5,7 +5,7 @@ require 'var/version'
5 Gem::Specification.new do |spec| 5 Gem::Specification.new do |spec|
6 spec.name = 'var' 6 spec.name = 'var'
7 spec.version = Var::VERSION 7 spec.version = Var::VERSION
8 - spec.authors = ['abrahamrq', 'chelord', 'rgp'] 8 + spec.authors = %w(abrahamrq chelord rgp)
9 spec.email = ['abraham.rq03@gmail.com'] 9 spec.email = ['abraham.rq03@gmail.com']
10 10
11 spec.summary = 'Payment gateway for Conekta, Paypal' 11 spec.summary = 'Payment gateway for Conekta, Paypal'
...@@ -17,7 +17,7 @@ Gem::Specification.new do |spec| ...@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17 if spec.respond_to?(:metadata) 17 if spec.respond_to?(:metadata)
18 spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'" 18 spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
19 else 19 else
20 - fail 'RubyGems 2.0+ is required to protect against public gem pushes.' 20 + raise 'RubyGems 2.0+ is required to protect against public gem pushes.'
21 end 21 end
22 22
23 spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 23 spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
...@@ -28,15 +28,15 @@ Gem::Specification.new do |spec| ...@@ -28,15 +28,15 @@ Gem::Specification.new do |spec|
28 spec.add_dependency 'conekta', '~> 0.5' 28 spec.add_dependency 'conekta', '~> 0.5'
29 spec.add_dependency 'paypal-sdk-rest' 29 spec.add_dependency 'paypal-sdk-rest'
30 spec.add_dependency 'activerecord', '>= 4.0', '< 5.1' 30 spec.add_dependency 'activerecord', '>= 4.0', '< 5.1'
31 - spec.add_dependency "activesupport" 31 + spec.add_dependency 'activesupport'
32 spec.add_development_dependency 'bundler', '~> 1.10.a' 32 spec.add_development_dependency 'bundler', '~> 1.10.a'
33 spec.add_development_dependency 'rake', '~> 10.0' 33 spec.add_development_dependency 'rake', '~> 10.0'
34 34
35 - spec.add_development_dependency "rspec" 35 + spec.add_development_dependency 'rspec'
36 - spec.add_development_dependency "rspec-nc" 36 + spec.add_development_dependency 'rspec-nc'
37 - spec.add_development_dependency "guard" 37 + spec.add_development_dependency 'guard'
38 - spec.add_development_dependency "guard-rspec" 38 + spec.add_development_dependency 'guard-rspec'
39 - spec.add_development_dependency "pry" 39 + spec.add_development_dependency 'pry'
40 - spec.add_development_dependency "pry-remote" 40 + spec.add_development_dependency 'pry-remote'
41 - spec.add_development_dependency "pry-nav" 41 + spec.add_development_dependency 'pry-nav'
42 end 42 end
......