fake_chargify 0.1.0

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.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'webmock'
4
+ gem 'nokogiri'
5
+
6
+ group :test, :development do
7
+ gem 'rspec'
8
+ gem 'activeresource'
9
+ gem 'chargify_api_ares'
10
+ end
@@ -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,150 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'date'
4
+
5
+ #############################################################################
6
+ #
7
+ # Helper functions
8
+ #
9
+ #############################################################################
10
+
11
+ def name
12
+ @name ||= Dir['*.gemspec'].first.split('.').first
13
+ end
14
+
15
+ def version
16
+ line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
17
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
18
+ end
19
+
20
+ def date
21
+ Date.today.to_s
22
+ end
23
+
24
+ def rubyforge_project
25
+ name
26
+ end
27
+
28
+ def gemspec_file
29
+ "#{name}.gemspec"
30
+ end
31
+
32
+ def gem_file
33
+ "#{name}-#{version}.gem"
34
+ end
35
+
36
+ def replace_header(head, header_name)
37
+ head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
38
+ end
39
+
40
+ #############################################################################
41
+ #
42
+ # Standard tasks
43
+ #
44
+ #############################################################################
45
+
46
+ task :default => :test
47
+
48
+ require 'rake/testtask'
49
+ Rake::TestTask.new(:test) do |test|
50
+ test.libs << 'lib' << 'test'
51
+ test.pattern = 'test/**/test_*.rb'
52
+ test.verbose = true
53
+ end
54
+
55
+ desc "Generate RCov test coverage and open in your browser"
56
+ task :coverage do
57
+ require 'rcov'
58
+ sh "rm -fr coverage"
59
+ sh "rcov test/test_*.rb"
60
+ sh "open coverage/index.html"
61
+ end
62
+
63
+ require 'rake/rdoctask'
64
+ Rake::RDocTask.new do |rdoc|
65
+ rdoc.rdoc_dir = 'rdoc'
66
+ rdoc.title = "#{name} #{version}"
67
+ rdoc.rdoc_files.include('README*')
68
+ rdoc.rdoc_files.include('lib/**/*.rb')
69
+ end
70
+
71
+ desc "Open an irb session preloaded with this library"
72
+ task :console do
73
+ sh "irb -rubygems -r ./lib/#{name}.rb"
74
+ end
75
+
76
+ #############################################################################
77
+ #
78
+ # Custom tasks (add your own tasks here)
79
+ #
80
+ #############################################################################
81
+
82
+
83
+
84
+ #############################################################################
85
+ #
86
+ # Packaging tasks
87
+ #
88
+ #############################################################################
89
+
90
+ desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
91
+ task :release => :build do
92
+ unless `git branch` =~ /^\* master$/
93
+ puts "You must be on the master branch to release!"
94
+ exit!
95
+ end
96
+ sh "git commit --allow-empty -a -m 'Release #{version}'"
97
+ sh "git tag v#{version}"
98
+ sh "git push origin master"
99
+ sh "git push origin v#{version}"
100
+ sh "gem push pkg/#{name}-#{version}.gem"
101
+ end
102
+
103
+ desc "Build #{gem_file} into the pkg directory"
104
+ task :build => :gemspec do
105
+ sh "mkdir -p pkg"
106
+ sh "gem build #{gemspec_file}"
107
+ sh "mv #{gem_file} pkg"
108
+ end
109
+
110
+ desc "Generate #{gemspec_file}"
111
+ task :gemspec => :validate do
112
+ # read spec file and split out manifest section
113
+ spec = File.read(gemspec_file)
114
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
115
+
116
+ # replace name version and date
117
+ replace_header(head, :name)
118
+ replace_header(head, :version)
119
+ replace_header(head, :date)
120
+ #comment this out if your rubyforge_project has a different name
121
+ replace_header(head, :rubyforge_project)
122
+
123
+ # determine file list from git ls-files
124
+ files = `git ls-files`.
125
+ split("\n").
126
+ sort.
127
+ reject { |file| file =~ /^\./ }.
128
+ reject { |file| file =~ /^(rdoc|pkg)/ }.
129
+ map { |file| " #{file}" }.
130
+ join("\n")
131
+
132
+ # piece file back together and write
133
+ manifest = " s.files = %w[\n#{files}\n ]\n"
134
+ spec = [head, manifest, tail].join(" # = MANIFEST =\n")
135
+ File.open(gemspec_file, 'w') { |io| io.write(spec) }
136
+ puts "Updated #{gemspec_file}"
137
+ end
138
+
139
+ desc "Validate #{gemspec_file}"
140
+ task :validate do
141
+ libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
142
+ unless libfiles.empty?
143
+ puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
144
+ exit!
145
+ end
146
+ unless Dir['VERSION*'].empty?
147
+ puts "A `VERSION` file at root level violates Gem best practices."
148
+ exit!
149
+ end
150
+ end
@@ -0,0 +1,68 @@
1
+
2
+ Gem::Specification.new do |s|
3
+ s.specification_version = 2 if s.respond_to? :specification_version=
4
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
5
+ s.rubygems_version = '1.3.5'
6
+
7
+ s.name = 'fake_chargify'
8
+ s.version = '0.1.0'
9
+ s.date = '2011-11-29'
10
+ s.rubyforge_project = 'fake_chargify'
11
+
12
+ s.summary = "A helper for faking web requests and responses to and from the Chargify API."
13
+ s.description = "A helper for faking web requests and responses to and from the Chargify API."
14
+
15
+ ## List the primary authors. If there are a bunch of authors, it's probably
16
+ ## better to set the email to an email list or something. If you don't have
17
+ ## a custom homepage, consider using your GitHub URL or the like.
18
+ s.authors = ["Jamie Wright"]
19
+ s.email = 'jamie@brilliantfantastic.com'
20
+ s.homepage = 'http://github.com/brilliantfantastic/fake_chargify'
21
+
22
+ s.require_paths = %w[lib]
23
+
24
+ s.rdoc_options = ["--charset=UTF-8"]
25
+ s.extra_rdoc_files = %w[README.md]
26
+
27
+ ## List your runtime dependencies here. Runtime dependencies are those
28
+ ## that are needed for an end user to actually USE your code.
29
+ s.add_dependency('webmock', "~> 1.7.8")
30
+ s.add_dependency('nokogiri', "~> 1.5.0")
31
+
32
+ #s.add_development_dependency('DEVDEPNAME', [">= 1.1.0", "< 2.0.0"])
33
+
34
+ ## Leave this section as-is. It will be automatically generated from the
35
+ ## contents of your Git repository via the gemspec task. DO NOT REMOVE
36
+ ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
37
+ # = MANIFEST =
38
+ s.files = %w[
39
+ Gemfile
40
+ Rakefile
41
+ fake_chargify.gemspec
42
+ lib/fake_chargify.rb
43
+ lib/fake_chargify/configuration.rb
44
+ lib/fake_chargify/credit_card.rb
45
+ lib/fake_chargify/customer.rb
46
+ lib/fake_chargify/customer_registry.rb
47
+ lib/fake_chargify/product.rb
48
+ lib/fake_chargify/product_family.rb
49
+ lib/fake_chargify/statement.rb
50
+ lib/fake_chargify/statement_registry.rb
51
+ lib/fake_chargify/string_patches.rb
52
+ lib/fake_chargify/subscription.rb
53
+ lib/fake_chargify/subscription_registry.rb
54
+ lib/fake_chargify/url_parser.rb
55
+ readme.md
56
+ spec/fake_chargify/configuration_spec.rb
57
+ spec/fake_chargify/credit_card_spec.rb
58
+ spec/fake_chargify/customer_spec.rb
59
+ spec/fake_chargify/product_family_spec.rb
60
+ spec/fake_chargify/product_spec.rb
61
+ spec/fake_chargify/statement_spec.rb
62
+ spec/fake_chargify/subscription_spec.rb
63
+ spec/fake_chargify_spec.rb
64
+ spec/spec_helper.rb
65
+ spec/string_patches_spec.rb
66
+ ]
67
+ # = MANIFEST =
68
+ end
@@ -0,0 +1,45 @@
1
+ require 'webmock'
2
+ require 'fake_chargify/string_patches'
3
+ require 'fake_chargify/customer_registry'
4
+ require 'fake_chargify/subscription_registry'
5
+ require 'fake_chargify/statement_registry'
6
+ require 'fake_chargify/configuration'
7
+
8
+ module FakeChargify
9
+ VERSION = '0.1.0'
10
+
11
+ class << self
12
+ attr_accessor :customers, :subscriptions, :statements
13
+ end
14
+
15
+ def self.clear!
16
+ self.customers = CustomerRegistry.new
17
+ self.subscriptions = SubscriptionRegistry.new
18
+ self.statements = StatementRegistry.new
19
+ end
20
+
21
+ def self.activate!
22
+ self.activate = true
23
+ end
24
+
25
+ def self.activate=(activate)
26
+ if activate
27
+ WebMock.disable_net_connect!(:allow_localhost => true)
28
+ self.clear!
29
+
30
+ self.customers.stub_requests!
31
+ self.subscriptions.stub_requests!
32
+ self.statements.stub_requests!
33
+ else
34
+ WebMock.allow_net_connect!
35
+ end
36
+ end
37
+
38
+ def self.configuration
39
+ @configuration ||= FakeChargify::Configuration.new
40
+ end
41
+
42
+ def self.configure
43
+ yield configuration if block_given?
44
+ end
45
+ end
@@ -0,0 +1,5 @@
1
+ module FakeChargify
2
+ class Configuration
3
+ attr_accessor :subdomain, :api_key
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ require 'nokogiri'
2
+
3
+ module FakeChargify
4
+ class CreditCard
5
+ attr_accessor :expiration_month, :expiration_year
6
+
7
+ def full_number=(value)
8
+ @full_number = value
9
+ end
10
+
11
+ def masked_card_number
12
+ "XXXX-XXXX-XXXX-#{@full_number.to_s.last(4)}"
13
+ end
14
+
15
+ def to_xml
16
+ builder = Nokogiri::XML::Builder.new do |xml|
17
+ xml.credit_card {
18
+ xml.masked_card_number masked_card_number
19
+ xml.expiration_month expiration_month
20
+ xml.expiration_year expiration_year
21
+ }
22
+ end
23
+ builder.to_xml
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,40 @@
1
+ require 'nokogiri'
2
+
3
+ module FakeChargify
4
+ class Customer
5
+ attr_accessor :id, :first_name, :last_name, :email, :organization, :reference, :created_at, :updated_at
6
+
7
+ def to_xml
8
+ builder = Nokogiri::XML::Builder.new do |xml|
9
+ xml.customer {
10
+ xml.id_ id
11
+ xml.first_name first_name
12
+ xml.last_name last_name
13
+ xml.email email
14
+ xml.organization organization
15
+ xml.reference reference
16
+ xml.created_at created_at
17
+ xml.updated_at updated_at
18
+ }
19
+ end
20
+ builder.to_xml
21
+ end
22
+
23
+ def self.from_xml(xml)
24
+ customer = Customer.new
25
+ doc = Nokogiri::XML.parse(xml)
26
+ doc.xpath('//customer').map do |e|
27
+ customer.id = e.xpath('id').text.to_i
28
+ customer.first_name = e.xpath('first_name').text
29
+ customer.last_name = e.xpath('last_name').text
30
+ customer.email = e.xpath('email').text
31
+ customer.organization = e.xpath('organization').text
32
+ customer.reference = e.xpath('reference').text
33
+ customer.created_at = Time.parse(e.xpath('created_at').text)
34
+ customer.updated_at = Time.parse(e.xpath('updated_at').text)
35
+ end
36
+ customer
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,65 @@
1
+ require 'fake_chargify/customer'
2
+ require 'fake_chargify/url_parser'
3
+
4
+ module FakeChargify
5
+ class CustomerRegistry
6
+ include UrlParser
7
+
8
+ def repository
9
+ @customers ||= []
10
+ end
11
+
12
+ def stub_requests!
13
+ stub_create!
14
+ stub_update!
15
+ stub_show!
16
+ stub_lookup!
17
+ end
18
+
19
+ private
20
+
21
+ def stub_create!
22
+ WebMock::API.stub_request(:post, "https://#{FakeChargify.configuration.api_key}:X@#{FakeChargify.configuration.subdomain}.chargify.com/customers.xml").
23
+ to_return(:status => 201, :body => lambda { |request|
24
+ customer = Customer.from_xml(request.body)
25
+ repository << customer
26
+ customer.to_xml
27
+ })
28
+ end
29
+
30
+ def stub_update!
31
+ WebMock::API.stub_request(:put, /https:\/\/#{FakeChargify.configuration.api_key}:X@#{FakeChargify.configuration.subdomain}.chargify.com\/customers\/#{/\d/}.xml/).
32
+ to_return(:status => 200, :body => lambda { |request|
33
+ id = get_id_from_uri request.uri
34
+ customer = Customer.from_xml(request.body)
35
+ repository.map! do |c|
36
+ if c.id == id
37
+ customer
38
+ else
39
+ c
40
+ end
41
+ end
42
+ customer.to_xml
43
+ })
44
+ end
45
+
46
+ def stub_show!
47
+ WebMock::API.stub_request(:get, /https:\/\/#{FakeChargify.configuration.api_key}:X@#{FakeChargify.configuration.subdomain}.chargify.com\/customers\/#{/\d/}.xml/).
48
+ to_return(:status => 200, :body => lambda { |request|
49
+ id = get_id_from_uri request.uri
50
+ customers = repository.select { |customer| customer.id == id }
51
+ customers.first.to_xml
52
+ })
53
+ end
54
+
55
+ def stub_lookup!
56
+ WebMock::API.stub_request(:get, /https:\/\/#{FakeChargify.configuration.api_key}:X@#{FakeChargify.configuration.subdomain}.chargify.com\/customers\/lookup.xml\?reference=#{/\w/}/).
57
+ to_return(:status => 200, :body => lambda { |request|
58
+ reference = request.uri.query_values['reference']
59
+ customers = repository.select { |customer| customer.reference == reference }
60
+ customers.first.to_xml
61
+ })
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,21 @@
1
+ require 'fake_chargify/product_family'
2
+
3
+ module FakeChargify
4
+ class Product
5
+ attr_accessor :accounting_code, :handle, :interval, :name, :price_in_cents, :family
6
+
7
+ def to_xml
8
+ builder = Nokogiri::XML::Builder.new do |xml|
9
+ xml.product {
10
+ xml.accounting_code accounting_code
11
+ xml.handle handle
12
+ xml.interval interval
13
+ xml.name name
14
+ xml.price_in_cents price_in_cents
15
+ xml << Nokogiri.XML(family.to_xml).root.to_xml unless family.nil?
16
+ }
17
+ end
18
+ builder.to_xml
19
+ end
20
+ end
21
+ end