pay_simple 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +12 -0
  5. data/Gemfile.lock +35 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +100 -0
  8. data/Rakefile +1 -0
  9. data/lib/ps.rb +32 -0
  10. data/lib/ps/api.rb +80 -0
  11. data/lib/ps/api/json.rb +78 -0
  12. data/lib/ps/base.rb +22 -0
  13. data/lib/ps/enumerations.rb +191 -0
  14. data/lib/ps/exceptions.rb +5 -0
  15. data/lib/ps/object.rb +48 -0
  16. data/lib/ps/objects/ach_account.rb +34 -0
  17. data/lib/ps/objects/credit_card_account.rb +38 -0
  18. data/lib/ps/objects/customer.rb +79 -0
  19. data/lib/ps/objects/customer_account.rb +25 -0
  20. data/lib/ps/objects/payment.rb +73 -0
  21. data/lib/ps/objects/payment_status_filter.rb +6 -0
  22. data/lib/ps/objects/recurring_payment.rb +60 -0
  23. data/lib/ps/objects/recurring_payment_filter.rb +26 -0
  24. data/lib/ps/objects/user.rb +10 -0
  25. data/lib/ps/response.rb +83 -0
  26. data/lib/ps/util.rb +28 -0
  27. data/lib/ps/util/hash.rb +17 -0
  28. data/lib/ps/util/state.rb +15 -0
  29. data/lib/ps/util/states.yml +263 -0
  30. data/lib/ps/util/string.rb +15 -0
  31. data/paysimple.gemspec +19 -0
  32. data/spec/config.yml.example +13 -0
  33. data/spec/factories/ach_account.rb +11 -0
  34. data/spec/factories/credit_card_accounts.rb +11 -0
  35. data/spec/factories/customer_accounts.rb +7 -0
  36. data/spec/factories/customers.rb +18 -0
  37. data/spec/factories/payment.rb +12 -0
  38. data/spec/factories/recurring_payment.rb +25 -0
  39. data/spec/ps/api/json_spec.rb +12 -0
  40. data/spec/ps/api_spec.rb +53 -0
  41. data/spec/ps/base_spec.rb +40 -0
  42. data/spec/ps/format_spec.rb +16 -0
  43. data/spec/ps/object_spec.rb +35 -0
  44. data/spec/ps/objects/ach_account_spec.rb +57 -0
  45. data/spec/ps/objects/credit_card_account_spec.rb +69 -0
  46. data/spec/ps/objects/customer_account_spec.rb +43 -0
  47. data/spec/ps/objects/customer_spec.rb +153 -0
  48. data/spec/ps/objects/payment_spec.rb +98 -0
  49. data/spec/ps/objects/recurring_payment_spec.rb +145 -0
  50. data/spec/ps/objects/user_spec.rb +14 -0
  51. data/spec/ps/response_spec.rb +39 -0
  52. data/spec/ps/util/hash_spec.rb +33 -0
  53. data/spec/ps/util/states_spec.rb +25 -0
  54. data/spec/ps/util/string_spec.rb +21 -0
  55. data/spec/ps/util_spec.rb +30 -0
  56. data/spec/spec_functions.rb +155 -0
  57. data/spec/spec_helper.rb +22 -0
  58. metadata +156 -0
@@ -0,0 +1,25 @@
1
+ FactoryGirl.define do
2
+ factory :recurring_payment, :class => PS::RecurringPayment do
3
+ customer_id 0
4
+ customer_account_id 0
5
+ schedule_type RecurringScheduleType::PAYMENT_PLAN
6
+ start_date Time.now
7
+ has_end_date false
8
+ billing_frequency_type BillingFrequencyType::WEEKLY
9
+ billing_frequency_param 1
10
+ payment_amount 100
11
+ first_payment_done true
12
+ first_payment_amount 100
13
+ first_payment_date Time.now-(86400*3)
14
+ total_due_amount 1000
15
+ total_number_of_payments 10
16
+ balance_remaining 900
17
+ number_of_payments_remaining 9
18
+ invoice_no 0
19
+ order_id 0
20
+ schedule_status PS::ScheduleStatus::ACTIVE
21
+ number_of_payment_made 1
22
+ total_amount_paid 100
23
+ date_of_last_payment_made Time.now-(86400*3)
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ describe "An instance of PS::Api::json" do
3
+ before { connect }
4
+ #TODO test date formatting
5
+ describe "#request" do
6
+ subject { $api }
7
+
8
+ it "should make a request" do
9
+ subject.request("addcustomer", FactoryGirl.attributes_for(:customer, { :last_modified => Time.now }))
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ class DummyClass
4
+ extend PS::Api
5
+ end
6
+ describe "An instance of", PS::Api do
7
+ before { connect() }
8
+ context "given a JSON format" do
9
+ subject { DummyClass }
10
+ before { subject.connect("json") }
11
+
12
+ it "should initialize the JSON api class" do
13
+ $api.class.should == PS::Api::Json
14
+ end
15
+
16
+ it "should returned the required attributes" do
17
+ subject.required_attributes().class.should == Array
18
+ end
19
+
20
+ it "should make an api request" do
21
+ #PS::Response.stub(:ps_object) { false }
22
+ PS::Api::Json.any_instance.should_receive(:request)
23
+ PS::Response.should_receive(:new)
24
+ subject.request("getstates")
25
+ end
26
+ end
27
+
28
+ context "Given an unsupported format" do
29
+ subject { DummyClass }
30
+
31
+ it "should raise a connection error" do
32
+ expect {
33
+ subject.connect("invalid_format")
34
+ }.to raise_error(PS::ConnectionError, "invalid_format is not a supported format")
35
+ end
36
+ end
37
+
38
+ describe "#host" do
39
+ let(:ps_api) { DummyClass }
40
+
41
+ subject { ps_api.host() }
42
+
43
+ it "should return the dev url" do
44
+ ps_api.should_receive(:env) { "development" }
45
+ subject.should == "https://sandbox-api.paysimple.com/3.00/paysimpleapi"
46
+ end
47
+
48
+ it "should return the production url" do
49
+ ps_api.should_receive(:env).exactly(2) { "production" }
50
+ subject.should == "https://api.paysimple.com/3.00/paysimpleapi"
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ describe "An instance of", PS::Base do
4
+ before { connect() }
5
+
6
+ context "given a valid connection Hash" do
7
+ context "with the format being JSON" do
8
+ let(:ps_base) { PS::Base }
9
+ subject { ps_base.establish_connection(formatted_connection_config("JSON")) }
10
+
11
+ it "should create a connection to the Paysimple API" do
12
+ subject
13
+ $api.class.should == PS::Api::Json
14
+ end
15
+
16
+ it "Should output the connection config" do
17
+ $stdout.should_receive(:puts)
18
+ subject
19
+ ps_base.current_connection()
20
+ end
21
+ end
22
+
23
+ context "with no format provided" do
24
+ subject { PS::Base.establish_connection(formatless_connection_config()) }
25
+
26
+ it "should default to JSON" do
27
+ subject
28
+ $api.class.should == PS::Api::Json
29
+ end
30
+ end
31
+ end
32
+
33
+ context "given an invalid connectiond Hash" do
34
+ subject { PS::Base.establish_connection({}) }
35
+
36
+ it "should raise an exception" do
37
+ expect { subject }.to raise_error(ArgumentError)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,16 @@
1
+ #high level tests for the format classes
2
+ require 'spec_helper'
3
+
4
+ describe "High level format class" do
5
+ Dir.glob("lib/ps/api/*.rb").each do |format_klass|
6
+ require File.dirname(__FILE__)+"/../../"+format_klass
7
+ klass = PS::Api.const_get(format_klass.scan(/[a-zA-Z]+\.rb/)[0].gsub(/\.rb/, '').capitalize)
8
+ describe klass do
9
+ context "required methods" do
10
+ it { klass.method_defined?(:request).should be_true }
11
+ it { klass.method_defined?(:date?).should be_true }
12
+ it { klass.method_defined?(:parse_date).should be_true }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ class PS::DummyClass < PS::Object
4
+ attr_accessor :first_name, :last_name
5
+
6
+ def initialize(params)
7
+ @first_name = params[:first_name]
8
+ @last_name = params[:last_name]
9
+ end
10
+ end
11
+
12
+ describe "An instance of", PS::Object do
13
+ describe "#attributes" do
14
+ let(:attributes_hash) { { :first_name => "test", :last_name => "test" } }
15
+
16
+ subject { PS::DummyClass.new(attributes_hash) }
17
+
18
+ it { subject.should respond_to(:request) }
19
+
20
+ it "should return the attributes of subject" do
21
+ subject.attributes.should == attributes_hash
22
+ end
23
+ end
24
+
25
+ describe "#new" do
26
+ let(:customer) { FactoryGirl.attributes_for(:customer) }
27
+ subject { PS::Customer.new(customer) }
28
+
29
+ it "should assign attributes for the appropriate class" do
30
+ subject.instance_variables.each do |v|
31
+ subject.send(v.to_s[1..-1]).should eq(customer[v.to_s[1..-1].to_sym])
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe "An instance of", PS::AchAccount do
4
+ before { connect() }
5
+ let(:customer_id) do
6
+ PS::Customer.create(FactoryGirl.attributes_for(:customer)).ps_reference_id
7
+ end
8
+
9
+ describe "#create" do
10
+ subject do
11
+ PS::AchAccount.create(
12
+ FactoryGirl.attributes_for(:ach_account, { :customer_id => customer_id })
13
+ )
14
+ end
15
+
16
+ it "should create an ach account" do
17
+ subject.ps_reference_id.should_not be_nil
18
+ end
19
+ end
20
+
21
+ describe "instantiated" do
22
+ let(:ach_account) do
23
+ PS::AchAccount.create(
24
+ FactoryGirl.attributes_for(:ach_account, { :customer_id => customer_id })
25
+ )
26
+ end
27
+
28
+ describe "#update" do
29
+ subject { ach_account.update }
30
+
31
+ it "should update attributes" do
32
+ ach_account.bank_name = "test"
33
+ subject
34
+ end
35
+ end
36
+
37
+ describe "delete" do
38
+ subject { ach_account.delete }
39
+
40
+ it "should delete the customer" do
41
+ subject
42
+ end
43
+ end
44
+
45
+ context "bad save" do
46
+ subject do
47
+ PS::AchAccount.new(
48
+ FactoryGirl.attributes_for(:ach_account)
49
+ ).save()
50
+ end
51
+
52
+ it "should catch the exception and return false" do
53
+ subject.should == false
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe PS::CreditCardAccount do
4
+ before { connect() }
5
+ let(:customer_id) do
6
+ PS::Customer.create(FactoryGirl.attributes_for(:customer)).ps_reference_id
7
+ end
8
+
9
+ describe "class methods" do
10
+ describe "#create" do
11
+ subject do
12
+ PS::CreditCardAccount.create(
13
+ FactoryGirl.attributes_for(:credit_card_account, :customer_id => customer_id)
14
+ )
15
+ end
16
+
17
+ it "should create a credit card account" do
18
+ subject.class.should == PS::CreditCardAccount
19
+ end
20
+
21
+ end
22
+
23
+ context "bad save" do
24
+ subject do
25
+ PS::CreditCardAccount.new(
26
+ FactoryGirl.attributes_for(:credit_card_account)
27
+ ).save
28
+ end
29
+
30
+ it "should catch the exception and return false" do
31
+ subject.should == false
32
+ end
33
+ end
34
+
35
+ describe "#default_for_customer_id" do
36
+ let(:credit_card) { FactoryGirl.create(:credit_card_account, :customer_id => customer_id) }
37
+ before { credit_card.make_default }
38
+ subject { PS::CreditCardAccount.default_for_customer_id(customer_id) }
39
+
40
+ it "should get the default credit card for a customer" do
41
+ subject.ps_reference_id.should == credit_card.ps_reference_id
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "instance methods" do
47
+ let(:credit_card) { FactoryGirl.create(:credit_card_account, :customer_id => customer_id) }
48
+
49
+ describe ".update" do
50
+ before do
51
+ credit_card.c_c_expiry = "11/2016"
52
+ end
53
+ subject { credit_card.update }
54
+
55
+ it "should update the credit card's attributes" do
56
+ subject
57
+ end
58
+ end
59
+
60
+
61
+ describe ".delete" do
62
+ subject { credit_card.delete() }
63
+
64
+ it "should delete the credit_card" do
65
+ subject
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe "An instance of", PS::CustomerAccount do
4
+ before { connect() }
5
+ let(:customer_id) { FactoryGirl.create(:customer).ps_reference_id }
6
+
7
+ describe ".make_default" do
8
+ let(:customer_id) { FactoryGirl.create(:customer).ps_reference_id }
9
+ subject do
10
+ FactoryGirl.create(:credit_card_account, { :customer_id => customer_id })
11
+ end
12
+
13
+ it "should make it default" do
14
+ subject.make_default
15
+ PS::CustomerAccount.default(customer_id).ps_reference_id.should == subject.ps_reference_id
16
+ end
17
+ end
18
+
19
+ describe "#find" do
20
+ let(:account_id) do
21
+ FactoryGirl.create(:credit_card_account, { :customer_id => customer_id }).ps_reference_id
22
+ end
23
+ subject { PS::CustomerAccount.find(account_id, customer_id) }
24
+
25
+ it "should retreive the customer account" do
26
+ subject.ps_reference_id.should == account_id
27
+ end
28
+ end
29
+
30
+ describe "#default" do
31
+ let(:default_account) do
32
+ FactoryGirl.create(:credit_card_account, { :customer_id => customer_id })
33
+ end
34
+ before do
35
+ default_account.make_default
36
+ end
37
+ subject { PS::CustomerAccount.default(customer_id) }
38
+
39
+ it "should get the default customer account" do
40
+ subject.ps_reference_id.should == default_account.ps_reference_id
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,153 @@
1
+ require 'spec_helper'
2
+
3
+ describe "An instance of", PS::Customer do
4
+ before { connect() }
5
+
6
+ describe "#create" do
7
+ subject { PS::Customer }
8
+
9
+ it "should create a new customer" do
10
+ new_customer = subject.create(FactoryGirl.attributes_for(:customer))
11
+ new_customer.class.should == subject
12
+ end
13
+ end
14
+
15
+ describe "#create_and_make_cc_payment" do
16
+ subject do
17
+ PS::Customer.create_and_make_cc_payment(
18
+ FactoryGirl.attributes_for(:customer),
19
+ FactoryGirl.attributes_for(:credit_card_account),
20
+ amount=1.00,
21
+ "999"
22
+ )
23
+ end
24
+
25
+ it "should create a customer, creditCardAccount, and Payment" do
26
+ response = subject
27
+ response[0].class.should == PS::Customer
28
+ response[1].class.should == PS::CreditCardAccount
29
+ response[2].class.should == PS::Payment
30
+ end
31
+ end
32
+
33
+ describe "#create_and_make_ach_payment" do
34
+ subject do
35
+ PS::Customer.create_and_make_ach_payment(
36
+ FactoryGirl.attributes_for(:customer),
37
+ FactoryGirl.attributes_for(:ach_account),
38
+ amount=1.00,
39
+ "999"
40
+ )
41
+ end
42
+
43
+ it "should create a customer, customerAccount, and Payment" do
44
+ response = subject
45
+ response[0].class.should == PS::Customer
46
+ response[1].class.should == PS::AchAccount
47
+ response[2].class.should == PS::Payment
48
+ end
49
+ end
50
+
51
+ describe "get_customer_and_default_accounts" do
52
+ let(:customer_id) { FactoryGirl.create(:customer).ps_reference_id }
53
+
54
+ before do
55
+ FactoryGirl.create(:credit_card_account, { :customer_id => customer_id }).make_default
56
+ #FactoryGirl.create(:ach_account, { :customer_id => customer_id }).make_default
57
+ end
58
+
59
+ subject { PS::Customer.get_customer_and_default_accounts(customer_id) }
60
+
61
+ it "should get the customer and return customerAccount subclasses" do
62
+ response = subject
63
+ response[0].class.should == PS::Customer
64
+ response[1].class.should == PS::CreditCardAccount
65
+ #response[2].class.should == PS::AchAccount
66
+ end
67
+ end
68
+
69
+ describe "list methods" do
70
+ subject { PS::Customer }
71
+
72
+ describe "#find" do
73
+ let(:customer_id) { PS::Customer.create(FactoryGirl.attributes_for(:customer)).ps_reference_id }
74
+ context "given an id" do
75
+ it "should find a customer" do
76
+ customer = subject.find(customer_id)
77
+ customer.class.should == subject
78
+ end
79
+ end
80
+
81
+ context "given a hash of customer attributes" do
82
+ let(:customer_attributes) { FactoryGirl.attributes_for(:customer) }
83
+ it "should find a customer"
84
+ end
85
+
86
+ it "should search for a customer based off of search criteria provided."
87
+ it "should list all customers"
88
+ end
89
+ end
90
+
91
+ describe "#destroy" do
92
+ context "given existing customer object" do
93
+ subject { PS::Customer.create(FactoryGirl.attributes_for(:customer)) }
94
+
95
+ it "should delete a customer object that exists" do
96
+ subject.destroy.should == true
97
+ end
98
+ end
99
+
100
+ context "given a customer object that doesn't exist" do
101
+ subject { FactoryGirl.build(:customer).destroy }
102
+
103
+ it "should return false" do
104
+ subject.should eq(false)
105
+ end
106
+ end
107
+ end
108
+
109
+ describe "#save" do
110
+ context "with valid input" do
111
+ subject { PS::Customer.new(FactoryGirl.attributes_for(:customer)) }
112
+
113
+ it "should save a customer" do
114
+ subject.save().should == true
115
+ subject.ps_reference_id.should_not be_nil
116
+ end
117
+ end
118
+
119
+ context "with invalid input" do
120
+ subject { PS::Customer.new({ :farw => 'tetet' }) }
121
+
122
+ it "should return false" do
123
+ subject.save().should == false
124
+ end
125
+ end
126
+ end
127
+
128
+ describe "relations" do
129
+ let(:customer_id) { PS::Customer.create(FactoryGirl.attributes_for(:customer)).ps_reference_id }
130
+ subject { PS::Customer.find(customer_id) }
131
+
132
+ it "should find the credit card account associated with the customer" do
133
+ PS::CreditCardAccount.should_receive(:default_for_customer_id).with(customer_id)
134
+ subject.default_credit_card_account
135
+ end
136
+
137
+ it "should set the default customer account" do
138
+ PS::CustomerAccount.should_receive(:find) { FactoryGirl.build(:customer_account) }
139
+ PS::CustomerAccount.any_instance.should_receive(:make_default)
140
+ subject.set_default_customer_account(5)
141
+ end
142
+
143
+ it "should get the default customer account" do
144
+ PS::CustomerAccount.should_receive(:default).with(customer_id)
145
+ subject.default_customer_account
146
+ end
147
+
148
+ it "should get payments for the customer" do
149
+ PS::Payment.should_receive(:find).with(customer_id)
150
+ subject.payments
151
+ end
152
+ end
153
+ end