fake_chargify 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +10 -0
- data/README.md +20 -0
- data/Rakefile +150 -0
- data/fake_chargify.gemspec +68 -0
- data/lib/fake_chargify.rb +45 -0
- data/lib/fake_chargify/configuration.rb +5 -0
- data/lib/fake_chargify/credit_card.rb +26 -0
- data/lib/fake_chargify/customer.rb +40 -0
- data/lib/fake_chargify/customer_registry.rb +65 -0
- data/lib/fake_chargify/product.rb +21 -0
- data/lib/fake_chargify/product_family.rb +18 -0
- data/lib/fake_chargify/statement.rb +51 -0
- data/lib/fake_chargify/statement_registry.rb +32 -0
- data/lib/fake_chargify/string_patches.rb +5 -0
- data/lib/fake_chargify/subscription.rb +64 -0
- data/lib/fake_chargify/subscription_registry.rb +77 -0
- data/lib/fake_chargify/url_parser.rb +11 -0
- data/readme.md +20 -0
- data/spec/fake_chargify/configuration_spec.rb +14 -0
- data/spec/fake_chargify/credit_card_spec.rb +21 -0
- data/spec/fake_chargify/customer_spec.rb +99 -0
- data/spec/fake_chargify/product_family_spec.rb +21 -0
- data/spec/fake_chargify/product_spec.rb +34 -0
- data/spec/fake_chargify/statement_spec.rb +79 -0
- data/spec/fake_chargify/subscription_spec.rb +195 -0
- data/spec/fake_chargify_spec.rb +27 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/string_patches_spec.rb +21 -0
- metadata +116 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module FakeChargify
|
4
|
+
class ProductFamily
|
5
|
+
attr_accessor :accounting_code, :handle, :name
|
6
|
+
|
7
|
+
def to_xml
|
8
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
9
|
+
xml.product_family {
|
10
|
+
xml.accounting_code accounting_code
|
11
|
+
xml.handle handle
|
12
|
+
xml.name name
|
13
|
+
}
|
14
|
+
end
|
15
|
+
builder.to_xml
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module FakeChargify
|
4
|
+
class Statement
|
5
|
+
attr_accessor :id, :subscription_id, :opened_at, :closed_at, :settled_at, :text_view, :basic_html_view, :html_view,
|
6
|
+
:future_payments, :starting_balance_in_cents, :ending_balance_in_cents, :customer_first_name, :customer_last_name,
|
7
|
+
:customer_organization, :customer_shipping_address, :customer_shipping_address_2, :customer_shipping_city,
|
8
|
+
:customer_shipping_state, :customer_shipping_country, :customer_shipping_zip, :customer_billing_address,
|
9
|
+
:customer_billing_address_2, :customer_billing_city, :customer_billing_state, :customer_billing_country,
|
10
|
+
:customer_billing_zip, :transactions, :events, :created_at, :updated_at
|
11
|
+
|
12
|
+
def initialize(attributes = {})
|
13
|
+
attributes.each { |key, val| send("#{key}=", val) if respond_to?("#{key}=") }
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_xml
|
17
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
18
|
+
xml.statement {
|
19
|
+
xml.id_ id
|
20
|
+
xml.subscription_id subscription_id
|
21
|
+
xml.opened_at opened_at
|
22
|
+
xml.closed_at closed_at
|
23
|
+
xml.settled_at settled_at
|
24
|
+
xml.text_view text_view
|
25
|
+
xml.basic_html_view basic_html_view
|
26
|
+
xml.html_view html_view
|
27
|
+
xml.starting_balance_in_cents starting_balance_in_cents
|
28
|
+
xml.ending_balance_in_cents ending_balance_in_cents
|
29
|
+
xml.customer_first_name customer_first_name
|
30
|
+
xml.customer_last_name customer_last_name
|
31
|
+
xml.customer_organization customer_organization
|
32
|
+
xml.customer_shipping_address customer_shipping_address
|
33
|
+
xml.customer_shipping_address_2 customer_shipping_address_2
|
34
|
+
xml.customer_shipping_city customer_shipping_city
|
35
|
+
xml.customer_shipping_state customer_shipping_state
|
36
|
+
xml.customer_shipping_country customer_shipping_country
|
37
|
+
xml.customer_shipping_zip customer_shipping_zip
|
38
|
+
xml.customer_billing_address customer_billing_address
|
39
|
+
xml.customer_billing_address_2 customer_billing_address_2
|
40
|
+
xml.customer_billing_city customer_billing_city
|
41
|
+
xml.customer_billing_state customer_billing_state
|
42
|
+
xml.customer_billing_country customer_billing_country
|
43
|
+
xml.customer_billing_zip customer_billing_zip
|
44
|
+
xml.created_at created_at
|
45
|
+
xml.updated_at updated_at
|
46
|
+
}
|
47
|
+
end
|
48
|
+
builder.to_xml
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'fake_chargify/statement'
|
3
|
+
|
4
|
+
module FakeChargify
|
5
|
+
class StatementRegistry
|
6
|
+
include UrlParser
|
7
|
+
|
8
|
+
def repository
|
9
|
+
@statements ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
def stub_requests!
|
13
|
+
stub_list!
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def stub_list!
|
19
|
+
WebMock::API.stub_request(:get, /https:\/\/#{FakeChargify.configuration.api_key}:X@#{FakeChargify.configuration.subdomain}.chargify.com\/subscriptions\/#{/\d/}\/statements.xml/).
|
20
|
+
to_return(:status => 200, :body => lambda { |request|
|
21
|
+
subscription_id = request.uri.path.match(/(\/\d.statements.(xml|json)\z)/)[0].match(/\d/)[0].to_i
|
22
|
+
statements = FakeChargify.statements.repository.select { |s| s.subscription_id == subscription_id }
|
23
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
24
|
+
xml.statements(:type => 'array') {
|
25
|
+
statements.each { |statement| xml << Nokogiri.XML(statement.to_xml).root.to_xml }
|
26
|
+
}
|
27
|
+
end
|
28
|
+
builder.to_xml
|
29
|
+
})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'fake_chargify/product'
|
3
|
+
require 'fake_chargify/credit_card'
|
4
|
+
|
5
|
+
module FakeChargify
|
6
|
+
class Subscription
|
7
|
+
attr_accessor :id, :state, :balance_in_cents, :current_period_started_at, :current_period_ends_at,
|
8
|
+
:trial_started_at, :trial_ended_at, :activated_at, :expires_at,
|
9
|
+
:product, :credit_card, :customer, :created_at, :updated_at
|
10
|
+
|
11
|
+
def to_xml
|
12
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
13
|
+
xml.subscription {
|
14
|
+
xml.id_ id
|
15
|
+
xml.state state
|
16
|
+
xml.balance_in_cents balance_in_cents
|
17
|
+
xml.current_period_started_at current_period_started_at
|
18
|
+
xml.current_period_ends_at current_period_ends_at
|
19
|
+
xml.trial_started_at trial_started_at
|
20
|
+
xml.trial_ended_at trial_ended_at
|
21
|
+
xml.activated_at activated_at
|
22
|
+
xml.expires_at expires_at
|
23
|
+
xml.created_at created_at
|
24
|
+
xml.updated_at updated_at
|
25
|
+
xml << Nokogiri.XML(customer.to_xml).root.to_xml unless customer.nil?
|
26
|
+
xml << Nokogiri.XML(product.to_xml).root.to_xml unless product.nil?
|
27
|
+
xml << Nokogiri.XML(credit_card.to_xml).root.to_xml unless credit_card.nil?
|
28
|
+
}
|
29
|
+
end
|
30
|
+
builder.to_xml
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.from_xml(xml)
|
34
|
+
subscription = Subscription.new
|
35
|
+
doc = Nokogiri::XML.parse(xml)
|
36
|
+
doc.xpath('//subscription').map do |e|
|
37
|
+
subscription.id = e.xpath('id').text.to_i
|
38
|
+
subscription.balance_in_cents = e.xpath('balance_in_cents').text.to_i
|
39
|
+
unless e.xpath('product_handle').empty?
|
40
|
+
subscription.product = Product.new
|
41
|
+
subscription.product.handle = e.xpath('product_handle').text
|
42
|
+
end
|
43
|
+
if e.xpath('customer_reference').empty?
|
44
|
+
e.xpath('customer_attributes').map do |c|
|
45
|
+
subscription.customer = Customer.new
|
46
|
+
subscription.customer.first_name = c.xpath('first_name').text
|
47
|
+
subscription.customer.last_name = c.xpath('last_name').text
|
48
|
+
subscription.customer.email = c.xpath('email').text
|
49
|
+
end
|
50
|
+
else
|
51
|
+
customers = FakeChargify.customers.repository.select { |c| c.reference == e.xpath('customer_reference').text }
|
52
|
+
subscription.customer = customers.first
|
53
|
+
end
|
54
|
+
e.xpath('credit_card_attributes').map do |cc|
|
55
|
+
subscription.credit_card = CreditCard.new
|
56
|
+
subscription.credit_card.full_number = cc.xpath('full_number').text
|
57
|
+
subscription.credit_card.expiration_month = cc.xpath('expiration_month').text.to_i
|
58
|
+
subscription.credit_card.expiration_year = cc.xpath('expiration_year').text.to_i
|
59
|
+
end
|
60
|
+
end
|
61
|
+
subscription
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'fake_chargify/subscription'
|
3
|
+
require 'fake_chargify/url_parser'
|
4
|
+
|
5
|
+
module FakeChargify
|
6
|
+
class SubscriptionRegistry
|
7
|
+
include UrlParser
|
8
|
+
|
9
|
+
def repository
|
10
|
+
@subscriptions ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def stub_requests!
|
14
|
+
stub_create!
|
15
|
+
stub_list!
|
16
|
+
stub_show!
|
17
|
+
stub_update!
|
18
|
+
stub_delete!
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def stub_create!
|
24
|
+
WebMock::API.stub_request(:post, "https://#{FakeChargify.configuration.api_key}:X@#{FakeChargify.configuration.subdomain}.chargify.com/subscriptions.xml").
|
25
|
+
to_return(:status => 201, :body => lambda { |request|
|
26
|
+
subscription = Subscription.from_xml(request.body)
|
27
|
+
repository << subscription
|
28
|
+
subscription.to_xml
|
29
|
+
})
|
30
|
+
end
|
31
|
+
|
32
|
+
def stub_list!
|
33
|
+
WebMock::API.stub_request(:get, "https://#{FakeChargify.configuration.api_key}:X@#{FakeChargify.configuration.subdomain}.chargify.com/subscriptions.xml").
|
34
|
+
to_return(:status => 200, :body => lambda { |request|
|
35
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
36
|
+
xml.subscriptions(:type => 'array') {
|
37
|
+
repository.each { |subscription| xml << Nokogiri.XML(subscription.to_xml).root.to_xml }
|
38
|
+
}
|
39
|
+
end
|
40
|
+
builder.to_xml
|
41
|
+
})
|
42
|
+
end
|
43
|
+
|
44
|
+
def stub_show!
|
45
|
+
WebMock::API.stub_request(:get, /https:\/\/#{FakeChargify.configuration.api_key}:X@#{FakeChargify.configuration.subdomain}.chargify.com\/subscriptions\/#{/\d/}.xml/).
|
46
|
+
to_return(:status => 200, :body => lambda { |request|
|
47
|
+
id = get_id_from_uri request.uri
|
48
|
+
subscriptions = repository.select { |subscription| subscription.id == id }
|
49
|
+
subscriptions.first.to_xml
|
50
|
+
})
|
51
|
+
end
|
52
|
+
|
53
|
+
def stub_update!
|
54
|
+
WebMock::API.stub_request(:put, /https:\/\/#{FakeChargify.configuration.api_key}:X@#{FakeChargify.configuration.subdomain}.chargify.com\/subscriptions\/#{/\d/}.xml/).
|
55
|
+
to_return(:status => 200, :body => lambda { |request|
|
56
|
+
id = get_id_from_uri request.uri
|
57
|
+
subscription = Subscription.from_xml(request.body)
|
58
|
+
repository.map! do |s|
|
59
|
+
if s.id == id
|
60
|
+
subscription
|
61
|
+
else
|
62
|
+
s
|
63
|
+
end
|
64
|
+
end
|
65
|
+
subscription.to_xml
|
66
|
+
})
|
67
|
+
end
|
68
|
+
|
69
|
+
def stub_delete!
|
70
|
+
WebMock::API.stub_request(:delete, /https:\/\/#{FakeChargify.configuration.api_key}:X@#{FakeChargify.configuration.subdomain}.chargify.com\/subscriptions\/#{/\d/}.xml/).
|
71
|
+
to_return(:status => 200, :body => lambda { |request|
|
72
|
+
id = get_id_from_uri request.uri
|
73
|
+
repository.delete_if { |subscription| subscription.id == id }
|
74
|
+
})
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module FakeChargify
|
2
|
+
module UrlParser
|
3
|
+
def get_id_from_uri(uri)
|
4
|
+
match = uri.path.match(/(\/\d.(xml|json)\z)/)
|
5
|
+
if !match.nil? && match.size > 0
|
6
|
+
match = match[0].match(/\d/)
|
7
|
+
return id = match[0].to_i if !match.nil? && match.size > 0
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/readme.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
fake_chargify
|
2
|
+
==============
|
3
|
+
fake_chargify is a helper for faking web requests and responses to and from the Chargify API. You can test Chargify within your application on a plane now. I am sure that happens all the time.
|
4
|
+
|
5
|
+
# Installation
|
6
|
+
|
7
|
+
gem 'fake_chargify'
|
8
|
+
require 'fake_chargify'
|
9
|
+
|
10
|
+
# The basics
|
11
|
+
|
12
|
+
Example, in spec_helper.rb
|
13
|
+
|
14
|
+
FakeChargify.activate!
|
15
|
+
RSpec.configure do |c|
|
16
|
+
c.before do
|
17
|
+
FakeChargify.clear!
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe FakeChargify do
|
4
|
+
describe ".configure" do
|
5
|
+
it "should set the configuration by using a block" do
|
6
|
+
FakeChargify.configure do |c|
|
7
|
+
c.subdomain = 'test'
|
8
|
+
c.api_key = 'api'
|
9
|
+
end
|
10
|
+
FakeChargify.configuration.subdomain.should == 'test'
|
11
|
+
FakeChargify.configuration.api_key.should == 'api'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "FakeChargify::CreditCard" do
|
4
|
+
describe ".to_xml" do
|
5
|
+
it "returns xml from object properties" do
|
6
|
+
card = FakeChargify::CreditCard.new
|
7
|
+
card.full_number = "1"
|
8
|
+
card.expiration_month = 12
|
9
|
+
card.expiration_year = 2011
|
10
|
+
card.to_xml.gsub(/\s/,'').should ==
|
11
|
+
"""
|
12
|
+
<?xml version=\"1.0\"?>
|
13
|
+
<credit_card>
|
14
|
+
<masked_card_number>XXXX-XXXX-XXXX-1</masked_card_number>
|
15
|
+
<expiration_month>12</expiration_month>
|
16
|
+
<expiration_year>2011</expiration_year>
|
17
|
+
</credit_card>
|
18
|
+
""".gsub(/\s/,'')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "chargify_api_ares gem" do
|
4
|
+
before(:each) do
|
5
|
+
FakeChargify.activate!
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "Chargify::Customer.create" do
|
9
|
+
it "returns the correct values" do
|
10
|
+
customer = Chargify::Customer.create(:id => 5, :reference => 'dogs')
|
11
|
+
customer.id.should == '5'
|
12
|
+
customer.reference.should == 'dogs'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "Chargify::Customer.update" do
|
17
|
+
it "returns the correct values" do
|
18
|
+
customer = Chargify::Customer.create(:id => 5, :reference => 'dogs')
|
19
|
+
customer.reference = 'cats'
|
20
|
+
customer.save
|
21
|
+
Chargify::Customer.find_by_reference('cats').should_not be_nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "Chargify::Customer.find" do
|
26
|
+
it "returns the correct customer by id" do
|
27
|
+
Chargify::Customer.create(:id => 5, :reference => 'dogs')
|
28
|
+
customer = Chargify::Customer.find 5
|
29
|
+
customer.id.should == '5'
|
30
|
+
customer.reference.should == 'dogs'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "Chargify::Customer.find_by_reference" do
|
35
|
+
it "returns the correct customer by reference" do
|
36
|
+
Chargify::Customer.create(:id => 5, :reference => 'dogs', :first_name => 'Joe', :last_name => 'Blow', :email => 'joe@example.com')
|
37
|
+
customer = Chargify::Customer.find_by_reference 'dogs'
|
38
|
+
customer.id.should == '5'
|
39
|
+
customer.reference.should == 'dogs'
|
40
|
+
customer.first_name == 'Joe'
|
41
|
+
customer.last_name == 'Blow'
|
42
|
+
customer.email == 'joe@example.com'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "FakeChargify::Customer" do
|
48
|
+
describe ".to_xml" do
|
49
|
+
it "returns xml from object properties" do
|
50
|
+
customer = FakeChargify::Customer.new
|
51
|
+
customer.id = 5
|
52
|
+
customer.first_name = "Joe"
|
53
|
+
customer.last_name = "Blow"
|
54
|
+
customer.email = "joe@example.com"
|
55
|
+
customer.organization = "Chargify"
|
56
|
+
customer.reference = "jblow"
|
57
|
+
customer.to_xml.gsub(/\s/,'').should ==
|
58
|
+
"""
|
59
|
+
<?xml version=\"1.0\"?>
|
60
|
+
<customer>
|
61
|
+
<id>5</id>
|
62
|
+
<first_name>Joe</first_name>
|
63
|
+
<last_name>Blow</last_name>
|
64
|
+
<email>joe@example.com</email>
|
65
|
+
<organization>Chargify</organization>
|
66
|
+
<reference>jblow</reference>
|
67
|
+
<created_at></created_at>
|
68
|
+
<updated_at></updated_at>
|
69
|
+
</customer>
|
70
|
+
""".gsub(/\s/,'')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe ".from_xml" do
|
75
|
+
it "parses valid xml and sets properties" do
|
76
|
+
customer = FakeChargify::Customer.from_xml """
|
77
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
78
|
+
<customer>
|
79
|
+
<id type='integer'>5</id>
|
80
|
+
<first_name>Joe</first_name>
|
81
|
+
<last_name>Blow</last_name>
|
82
|
+
<email>joe@example.com</email>
|
83
|
+
<organization>Chargify</organization>
|
84
|
+
<reference>jblow</reference>
|
85
|
+
<created_at type='datetime'>2011-11-20T18:34:07-05:00</created_at>
|
86
|
+
<updated_at type='datetime'>2011-11-20T18:34:07-05:00</updated_at>
|
87
|
+
</customer>
|
88
|
+
"""
|
89
|
+
customer.id.should == 5
|
90
|
+
customer.first_name.should == "Joe"
|
91
|
+
customer.last_name.should == "Blow"
|
92
|
+
customer.email.should == "joe@example.com"
|
93
|
+
customer.organization.should == "Chargify"
|
94
|
+
customer.reference.should == "jblow"
|
95
|
+
customer.created_at.should == Time.parse('2011-11-20T18:34:07-05:00')
|
96
|
+
customer.updated_at.should == Time.parse('2011-11-20T18:34:07-05:00')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "FakeChargify::ProductFamily" do
|
4
|
+
describe ".to_xml" do
|
5
|
+
it "returns xml from object properties" do
|
6
|
+
family = FakeChargify::ProductFamily.new
|
7
|
+
family.accounting_code = '1234'
|
8
|
+
family.handle = 'Starter'
|
9
|
+
family.name = 'Subscription'
|
10
|
+
family.to_xml.gsub(/\s/,'').should ==
|
11
|
+
"""
|
12
|
+
<?xml version=\"1.0\"?>
|
13
|
+
<product_family>
|
14
|
+
<accounting_code>1234</accounting_code>
|
15
|
+
<handle>Starter</handle>
|
16
|
+
<name>Subscription</name>
|
17
|
+
</product_family>
|
18
|
+
""".gsub(/\s/,'')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|