fizx-chargify 0.2.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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Wynn Netherland
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,25 @@
1
+ # chargify
2
+
3
+ Ruby wrapper for the chargify.com SAAS and billing API
4
+
5
+ ## Installation
6
+
7
+ sudo gem install gemcutter
8
+ gem tumble
9
+ sudo gem install chargify
10
+
11
+
12
+ ## Note on Patches/Pull Requests
13
+
14
+ * Fork the project.
15
+ * Make your feature addition or bug fix.
16
+ * Add tests for it. This is important so I don't break it in a
17
+ future version unintentionally.
18
+ * Commit, do not mess with rakefile, version, or history.
19
+ (if you want to have your own version, that is fine but
20
+ bump version in a commit by itself I can ignore when I pull)
21
+ * Send me a pull request. Bonus points for topic branches.
22
+
23
+ ### Copyright
24
+
25
+ Copyright (c) 2009 [Wynn Netherland](http://wynnnetherland.com). See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rake'
2
+ require 'shoulda/tasks'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "fizx-chargify"
8
+ gem.summary = %Q{Ruby wrapper for the chargify.com SAAS and billing API}
9
+ gem.description = %Q{Ruby wrapper for the chargify.com SAAS and billing API}
10
+ gem.email = "wynn.netherland@gmail.com"
11
+ gem.homepage = "http://github.com/pengwynn/chargify"
12
+ gem.authors = ["Wynn Netherland","Nash Kabbara"]
13
+
14
+ gem.add_development_dependency('thoughtbot-shoulda', '>= 2.10.1')
15
+ gem.add_development_dependency('jnunemaker-matchy', '0.4.0')
16
+ gem.add_development_dependency('mocha', '0.9.4')
17
+ gem.add_development_dependency('fakeweb', '>= 1.2.5')
18
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
23
+ end
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/test_*.rb'
29
+ test.verbose = true
30
+ end
31
+
32
+ begin
33
+ require 'rcov/rcovtask'
34
+ Rcov::RcovTask.new do |test|
35
+ test.libs << 'test'
36
+ test.pattern = 'test/**/test_*.rb'
37
+ test.verbose = true
38
+ end
39
+ rescue LoadError
40
+ task :rcov do
41
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
42
+ end
43
+ end
44
+
45
+ task :test => :check_dependencies
46
+
47
+ task :default => :test
48
+
49
+ require 'rake/rdoctask'
50
+ Rake::RDocTask.new do |rdoc|
51
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "chargify #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
data/changelog.md ADDED
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 January 26, 2010
4
+
5
+ * Substantial fixes and convenience enhancements from [@nkabbara](http://github.com/nkabbara)
6
+
7
+ ## 0.1.0 November 18, 2009
8
+
9
+ * Initial version
data/chargify.gemspec ADDED
@@ -0,0 +1,81 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{chargify}
8
+ s.version = "0.2.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Wynn Netherland", "Nash Kabbara"]
12
+ s.date = %q{2010-03-19}
13
+ s.description = %q{Ruby wrapper for the chargify.com SAAS and billing API}
14
+ s.email = %q{wynn.netherland@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.markdown",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "changelog.md",
27
+ "chargify.gemspec",
28
+ "lib/chargify.rb",
29
+ "lib/chargify/client.rb",
30
+ "test/fixtures/customer.json",
31
+ "test/fixtures/customers.json",
32
+ "test/fixtures/deleted_subscription.json",
33
+ "test/fixtures/invalid_subscription.json",
34
+ "test/fixtures/new_customer.json",
35
+ "test/fixtures/product.json",
36
+ "test/fixtures/products.json",
37
+ "test/fixtures/subscription.json",
38
+ "test/fixtures/subscription_not_found.json",
39
+ "test/fixtures/subscriptions.json",
40
+ "test/helper.rb",
41
+ "test/test_chargify.rb"
42
+ ]
43
+ s.homepage = %q{http://github.com/pengwynn/chargify}
44
+ s.rdoc_options = ["--charset=UTF-8"]
45
+ s.require_paths = ["lib"]
46
+ s.rubygems_version = %q{1.3.6}
47
+ s.summary = %q{Ruby wrapper for the chargify.com SAAS and billing API}
48
+ s.test_files = [
49
+ "test/helper.rb",
50
+ "test/test_chargify.rb"
51
+ ]
52
+
53
+ if s.respond_to? :specification_version then
54
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
58
+ s.add_runtime_dependency(%q<hashie>, ["~> 0.1.3"])
59
+ s.add_runtime_dependency(%q<httparty>, ["~> 0.4.5"])
60
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 2.10.1"])
61
+ s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
62
+ s.add_development_dependency(%q<mocha>, ["= 0.9.4"])
63
+ s.add_development_dependency(%q<fakeweb>, [">= 1.2.5"])
64
+ else
65
+ s.add_dependency(%q<hashie>, ["~> 0.1.3"])
66
+ s.add_dependency(%q<httparty>, ["~> 0.4.5"])
67
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 2.10.1"])
68
+ s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
69
+ s.add_dependency(%q<mocha>, ["= 0.9.4"])
70
+ s.add_dependency(%q<fakeweb>, [">= 1.2.5"])
71
+ end
72
+ else
73
+ s.add_dependency(%q<hashie>, ["~> 0.1.3"])
74
+ s.add_dependency(%q<httparty>, ["~> 0.4.5"])
75
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 2.10.1"])
76
+ s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
77
+ s.add_dependency(%q<mocha>, ["= 0.9.4"])
78
+ s.add_dependency(%q<fakeweb>, [">= 1.2.5"])
79
+ end
80
+ end
81
+
data/lib/chargify.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'hashie'
2
+ require 'httparty'
3
+ require "json"
4
+
5
+ directory = File.expand_path(File.dirname(__FILE__))
6
+
7
+ Hash.send :include, Hashie::HashExtensions
8
+
9
+ require File.join(directory, 'chargify', 'client')
@@ -0,0 +1,123 @@
1
+ module Chargify
2
+ class UnexpectedResponseError < RuntimeError;end
3
+
4
+ def self.custom_parser
5
+ proc do |data|
6
+ begin
7
+ Crack::JSON.parse(data)
8
+ rescue => e
9
+ error_msg = "Crack could not parse JSON. It said: #{e.message}. Chargify's raw response: #{data}"
10
+ raise UnexpectedResponseError, error_msg
11
+ end
12
+ end
13
+ end
14
+
15
+ class Client
16
+ include HTTParty
17
+ format :json
18
+ parser Chargify::custom_parser
19
+ headers 'Content-Type' => 'application/json'
20
+
21
+ attr_reader :api_key, :subdomain
22
+
23
+ # Your API key can be generated on the settings screen.
24
+ def initialize(api_key, subdomain)
25
+ @api_key = api_key
26
+ @subdomain = subdomain
27
+
28
+ self.class.base_uri "https://#{@subdomain}.chargify.com"
29
+ self.class.basic_auth @api_key, 'x'
30
+
31
+ end
32
+
33
+ # options: page
34
+ def list_customers(options={})
35
+ customers = self.class.get("/customers.json", :query => options)
36
+ customers.map{|c| Hashie::Mash.new c['customer']}
37
+ end
38
+
39
+ def customer(chargify_id)
40
+ Hashie::Mash.new(self.class.get("/customers/lookup.json?reference=#{chargify_id}")).customer
41
+ end
42
+
43
+ #
44
+ # * first_name (Required)
45
+ # * last_name (Required)
46
+ # * email (Required)
47
+ # * organization (Optional) Company/Organization name
48
+ # * reference (Optional, but encouraged) The unique identifier used within your own application for this customer
49
+ #
50
+ def create_customer(info={})
51
+ response = Hashie::Mash.new(self.class.post("/customers.json", :body => {:customer => info}.to_json))
52
+ return response.customer if response.customer
53
+ response
54
+ end
55
+
56
+ #
57
+ # * first_name (Required)
58
+ # * last_name (Required)
59
+ # * email (Required)
60
+ # * organization (Optional) Company/Organization name
61
+ # * reference (Optional, but encouraged) The unique identifier used within your own application for this customer
62
+ #
63
+ def update_customer(info={})
64
+ info.stringify_keys!
65
+ chargify_id = info.delete('id')
66
+ response = Hashie::Mash.new(self.class.put("/customers/#{chargify_id}.json", :body => {:customer => info}))
67
+ return response.customer unless response.customer.to_a.empty?
68
+ response
69
+ end
70
+
71
+ def customer_subscriptions(chargify_id)
72
+ subscriptions = self.class.get("/customers/#{chargify_id}/subscriptions.json")
73
+ subscriptions.map{|s| Hashie::Mash.new s['subscription']}
74
+ end
75
+
76
+ def subscription(subscription_id)
77
+ raw_response = self.class.get("/subscriptions/#{subscription_id}.json")
78
+ return nil if raw_response.code != 200
79
+ Hashie::Mash.new(raw_response).subscription
80
+ end
81
+
82
+ # Returns all elements outputted by Chargify plus:
83
+ # response.success? -> true if response code is 201, false otherwise
84
+ def create_subscription(subscription_attributes={})
85
+ raw_response = self.class.post("/subscriptions.json", :body => {:subscription => subscription_attributes}.to_json)
86
+ created = true if raw_response.code == 201
87
+ response = Hashie::Mash.new(raw_response)
88
+ (response.subscription || response).update(:success? => created)
89
+ end
90
+
91
+ # Returns all elements outputted by Chargify plus:
92
+ # response.success? -> true if response code is 200, false otherwise
93
+ def update_subscription(sub_id, subscription_attributes = {})
94
+ raw_response = self.class.put("/subscriptions/#{sub_id}.json", :body => {:subscription => subscription_attributes}.to_json)
95
+ updated = true if raw_response.code == 200
96
+ response = Hashie::Mash.new(raw_response)
97
+ (response.subscription || response).update(:success? => updated)
98
+ end
99
+
100
+ # Returns all elements outputted by Chargify plus:
101
+ # response.success? -> true if response code is 200, false otherwise
102
+ def cancel_subscription(sub_id, message="")
103
+ raw_response = self.class.delete("/subscriptions/#{sub_id}.json", :body => {:subscription => {:cancellation_message => message} }.to_json)
104
+ deleted = true if raw_response.code == 200
105
+ response = Hashie::Mash.new(raw_response)
106
+ (response.subscription || response).update(:success? => deleted)
107
+ end
108
+
109
+ def list_products
110
+ products = self.class.get("/products.json")
111
+ products.map{|p| Hashie::Mash.new p['product']}
112
+ end
113
+
114
+ def product(product_id)
115
+ Hashie::Mash.new( self.class.get("/products/#{product_id}.json")).product
116
+ end
117
+
118
+ def product_by_handle(handle)
119
+ Hashie::Mash.new(self.class.get("/products/handle/#{handle}.json")).product
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,12 @@
1
+ {
2
+ "customer": {
3
+ "reference": "bradleyjoyce",
4
+ "updated_at": "2009-10-07T11:10:27-04:00",
5
+ "id": 16,
6
+ "organization": "Squeejee",
7
+ "first_name": "Bradley",
8
+ "last_name": "Joyce",
9
+ "email": "bradley@squeejee.com",
10
+ "created_at": "2009-10-07T11:10:27-04:00"
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ [{
2
+ "customer": {
3
+ "reference": "bradleyjoyce",
4
+ "updated_at": "2009-10-07T11:10:27-04:00",
5
+ "id": 16,
6
+ "organization": "Squeejee",
7
+ "first_name": "Bradley",
8
+ "last_name": "Joyce",
9
+ "email": "bradley@squeejee.com",
10
+ "created_at": "2009-10-07T11:10:27-04:00"
11
+ }
12
+ }]
@@ -0,0 +1 @@
1
+ {"created_at":"Tue Jan 26 18:40:32 -0600 2010","activated_at":"Tue Jan 26 18:40:33 -0600 2010","expires_at":null,"cancellation_message":"Optional message","trial_ended_at":null,"updated_at":"Tue Jan 26 18:40:35 -0600 2010","credit_card":{"card_type":"bogus","expiration_year":2013,"masked_card_number":"XXXX-XXXX-XXXX-1","expiration_month":3,"last_name":"Indicisive","first_name":"John"},"id":3642,"current_period_ends_at":"Fri Feb 26 18:40:32 -0600 2010","product":{"product_family":{"name":"ZipZoomAuto","handle":"zipzoomauto","accounting_code":null,"id":268,"description":""},"name":"Basic Plan","handle":"basic","price_in_cents":5000,"accounting_code":"","id":689,"interval":1,"description":"","interval_unit":"month"},"success?":true,"customer":{"reference":"11654","created_at":"Tue Jan 26 18:40:32 -0600 2010","updated_at":"Tue Jan 26 18:40:32 -0600 2010","id":3546,"last_name":"Indicisive","organization":null,"email":"john@doe.com","first_name":"John"},"trial_started_at":null,"balance_in_cents":0,"current_period_started_at":"Tue Jan 26 18:40:32 -0600 2010","state":"canceled"}
@@ -0,0 +1,48 @@
1
+ "subscription": {
2
+ "customer": {
3
+ "reference": "bradleyjoyce",
4
+ "updated_at": "2009-10-07T11:10:27-04:00",
5
+ "id": 16,
6
+ "organization": "Squeejee",
7
+ "first_name": "Bradley",
8
+ "last_name": "Joyce",
9
+ "email": "bradley@squeejee.com",
10
+ "created_at": "2009-10-07T11:10:27-04:00"
11
+ },
12
+ "cancellation_message": null,
13
+ "updated_at": "2009-10-07T11:10:56-04:00",
14
+ "expires_at": null,
15
+ "activated_at": "2009-10-23T16:16:59-04:00",
16
+ "current_period_started_at": "2009-11-14T11:10:56-05:00",
17
+ "credit_card": {
18
+ "card_type": "bogus",
19
+ "expiration_year": 2015,
20
+ "masked_card_number": "XXXX-XXXX-XXXX-1",
21
+ "first_name": "Bradley",
22
+ "last_name": "Joyce",
23
+ "expiration_month": 7
24
+ },
25
+ "trial_ended_at": "2009-10-14T11:10:56-04:00",
26
+ "id": 14,
27
+ "product": {
28
+ "price_in_cents": 500,
29
+ "name": "Monthly",
30
+ "handle": "monthly",
31
+ "id": 8,
32
+ "accounting_code": "TSMO",
33
+ "product_family": {
34
+ "name": "TweetSaver",
35
+ "handle": "tweetsaver",
36
+ "id": 7,
37
+ "accounting_code": null
38
+ },
39
+ "interval_unit": "month",
40
+ "interval": 1
41
+ },
42
+ "current_period_ends_at": "2009-12-14T11:10:56-05:00",
43
+ "trial_started_at": "2009-10-07T11:10:56-04:00",
44
+ "balance_in_cents": 0,
45
+ "state": "active",
46
+ "created_at": "2009-10-07T11:10:56-04:00"
47
+ }
48
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "customer": {
3
+ "created_at": "2009-11-18T10:56:22-05:00",
4
+ "email": "wynn.netherland@gmail.com",
5
+ "first_name": "Wynn",
6
+ "id": 333,
7
+ "last_name": "Netherland",
8
+ "organization": null,
9
+ "reference": null,
10
+ "updated_at": "2009-11-18T10:56:22-05:00"
11
+ }
12
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "product": {
3
+ "price_in_cents": 500,
4
+ "name": "Monthly",
5
+ "handle": "monthly",
6
+ "id": 8,
7
+ "accounting_code": "TSMO",
8
+ "product_family": {
9
+ "name": "TweetSaver",
10
+ "handle": "tweetsaver",
11
+ "id": 7,
12
+ "accounting_code": null
13
+ },
14
+ "interval_unit": "month",
15
+ "interval": 1
16
+ }
17
+ }
@@ -0,0 +1,17 @@
1
+ [{
2
+ "product": {
3
+ "price_in_cents": 500,
4
+ "name": "Monthly",
5
+ "handle": "monthly",
6
+ "id": 8,
7
+ "accounting_code": "TSMO",
8
+ "product_family": {
9
+ "name": "TweetSaver",
10
+ "handle": "tweetsaver",
11
+ "id": 7,
12
+ "accounting_code": null
13
+ },
14
+ "interval_unit": "month",
15
+ "interval": 1
16
+ }
17
+ }]
@@ -0,0 +1,49 @@
1
+ {
2
+ "subscription": {
3
+ "customer": {
4
+ "reference": "bradleyjoyce",
5
+ "updated_at": "2009-10-07T11:10:27-04:00",
6
+ "id": 16,
7
+ "organization": "Squeejee",
8
+ "first_name": "Bradley",
9
+ "last_name": "Joyce",
10
+ "email": "bradley@squeejee.com",
11
+ "created_at": "2009-10-07T11:10:27-04:00"
12
+ },
13
+ "cancellation_message": null,
14
+ "updated_at": "2009-10-07T11:10:56-04:00",
15
+ "expires_at": null,
16
+ "activated_at": "2009-10-23T16:16:59-04:00",
17
+ "current_period_started_at": "2009-11-14T11:10:56-05:00",
18
+ "credit_card": {
19
+ "card_type": "bogus",
20
+ "expiration_year": 2015,
21
+ "masked_card_number": "XXXX-XXXX-XXXX-1",
22
+ "first_name": "Bradley",
23
+ "last_name": "Joyce",
24
+ "expiration_month": 7
25
+ },
26
+ "trial_ended_at": "2009-10-14T11:10:56-04:00",
27
+ "id": 14,
28
+ "product": {
29
+ "price_in_cents": 500,
30
+ "name": "Monthly",
31
+ "handle": "monthly",
32
+ "id": 8,
33
+ "accounting_code": "TSMO",
34
+ "product_family": {
35
+ "name": "TweetSaver",
36
+ "handle": "tweetsaver",
37
+ "id": 7,
38
+ "accounting_code": null
39
+ },
40
+ "interval_unit": "month",
41
+ "interval": 1
42
+ },
43
+ "current_period_ends_at": "2009-12-14T11:10:56-05:00",
44
+ "trial_started_at": "2009-10-07T11:10:56-04:00",
45
+ "balance_in_cents": 0,
46
+ "state": "active",
47
+ "created_at": "2009-10-07T11:10:56-04:00"
48
+ }
49
+ }
@@ -0,0 +1 @@
1
+ \r\n
@@ -0,0 +1,49 @@
1
+ [{
2
+ "subscription": {
3
+ "customer": {
4
+ "reference": "bradleyjoyce",
5
+ "updated_at": "2009-10-07T11:10:27-04:00",
6
+ "id": 16,
7
+ "organization": "Squeejee",
8
+ "first_name": "Bradley",
9
+ "last_name": "Joyce",
10
+ "email": "bradley@squeejee.com",
11
+ "created_at": "2009-10-07T11:10:27-04:00"
12
+ },
13
+ "cancellation_message": null,
14
+ "updated_at": "2009-10-07T11:10:56-04:00",
15
+ "expires_at": null,
16
+ "activated_at": "2009-10-23T16:16:59-04:00",
17
+ "current_period_started_at": "2009-11-14T11:10:56-05:00",
18
+ "credit_card": {
19
+ "card_type": "bogus",
20
+ "expiration_year": 2015,
21
+ "masked_card_number": "XXXX-XXXX-XXXX-1",
22
+ "first_name": "Bradley",
23
+ "last_name": "Joyce",
24
+ "expiration_month": 7
25
+ },
26
+ "trial_ended_at": "2009-10-14T11:10:56-04:00",
27
+ "id": 14,
28
+ "product": {
29
+ "price_in_cents": 500,
30
+ "name": "Monthly",
31
+ "handle": "monthly",
32
+ "id": 8,
33
+ "accounting_code": "TSMO",
34
+ "product_family": {
35
+ "name": "TweetSaver",
36
+ "handle": "tweetsaver",
37
+ "id": 7,
38
+ "accounting_code": null
39
+ },
40
+ "interval_unit": "month",
41
+ "interval": 1
42
+ },
43
+ "current_period_ends_at": "2009-12-14T11:10:56-05:00",
44
+ "trial_started_at": "2009-10-07T11:10:56-04:00",
45
+ "balance_in_cents": 0,
46
+ "state": "active",
47
+ "created_at": "2009-10-07T11:10:56-04:00"
48
+ }
49
+ }]
data/test/helper.rb ADDED
@@ -0,0 +1,61 @@
1
+ require 'test/unit'
2
+ require 'pathname'
3
+ require 'rubygems'
4
+
5
+ gem 'thoughtbot-shoulda', '>= 2.10.1'
6
+ gem 'jnunemaker-matchy', '0.4.0'
7
+ gem 'mocha', '0.9.4'
8
+ gem 'fakeweb', '>= 1.2.5'
9
+
10
+ require 'shoulda'
11
+ require 'matchy'
12
+ require 'mocha'
13
+ require 'fakeweb'
14
+
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
17
+ require 'chargify'
18
+
19
+ class Test::Unit::TestCase
20
+ end
21
+
22
+ FakeWeb.allow_net_connect = false
23
+
24
+
25
+ class Test::Unit::TestCase
26
+ end
27
+
28
+ def fixture_file(filename)
29
+ return '' if filename == ''
30
+ file_path = File.expand_path(File.dirname(__FILE__) + '/fixtures/' + filename)
31
+ File.read(file_path)
32
+ end
33
+
34
+
35
+ def stub_get(url, filename, status=nil)
36
+ options = {:body => fixture_file(filename)}
37
+ options.merge!({:status => status}) unless status.nil?
38
+
39
+ FakeWeb.register_uri(:get, url, options)
40
+ end
41
+
42
+ def stub_post(url, filename, status=nil)
43
+ options = {:body => fixture_file(filename)}
44
+ options.merge!({:status => status}) unless status.nil?
45
+
46
+ FakeWeb.register_uri(:post, url, options)
47
+ end
48
+
49
+ def stub_put(url, filename, status=nil)
50
+ options = {:body => fixture_file(filename)}
51
+ options.merge!({:status => status}) unless status.nil?
52
+
53
+ FakeWeb.register_uri(:put, url, options)
54
+ end
55
+
56
+ def stub_delete(url, filename, status=nil)
57
+ options = {:body => fixture_file(filename)}
58
+ options.merge!({:status => status}) unless status.nil?
59
+
60
+ FakeWeb.register_uri(:delete, url, options)
61
+ end
@@ -0,0 +1,243 @@
1
+ require 'helper'
2
+
3
+ class TestChargify < Test::Unit::TestCase
4
+ context "When hitting the Chargify API" do
5
+ setup do
6
+ @client = Chargify::Client.new('OU812', 'pengwynn')
7
+ end
8
+
9
+ should "raise UnexpectedResponseError when reponse is invalid JSON" do
10
+ stub_post "https://OU812:x@pengwynn.chargify.com/subscriptions.json", "invalid_subscription.json"
11
+ options = {
12
+ :product_handle => 'monthly',
13
+ :customer_reference => 'bradleyjoyce',
14
+ :customer_attributes => {
15
+ :first_name => "Wynn",
16
+ :last_name => "Netherland",
17
+ :email => "wynn@example.com"
18
+ }
19
+ }
20
+ assert_raise Chargify::UnexpectedResponseError do
21
+ @client.create_subscription(options)
22
+ end
23
+ end
24
+
25
+ should "return a list of customers" do
26
+ stub_get "https://OU812:x@pengwynn.chargify.com/customers.json", "customers.json"
27
+ customers = @client.list_customers
28
+ customers.size.should == 1
29
+ customers.first.reference.should == 'bradleyjoyce'
30
+ customers.first.organization.should == 'Squeejee'
31
+ end
32
+
33
+
34
+ should "return info for a customer" do
35
+ stub_get "https://OU812:x@pengwynn.chargify.com/customers/lookup.json?reference=16", "customer.json"
36
+ customer = @client.customer(16)
37
+ customer.reference.should == 'bradleyjoyce'
38
+ customer.organization.should == 'Squeejee'
39
+ end
40
+
41
+ should "create a new customer" do
42
+ stub_post "https://OU812:x@pengwynn.chargify.com/customers.json", "new_customer.json"
43
+ info = {
44
+ :first_name => "Wynn",
45
+ :last_name => "Netherland",
46
+ :email => "wynn@example.com"
47
+ }
48
+ customer = @client.create_customer(info)
49
+ customer.first_name.should == "Wynn"
50
+ end
51
+
52
+ should "update a customer" do
53
+ stub_put "https://OU812:x@pengwynn.chargify.com/customers/16.json", "new_customer.json"
54
+ info = {
55
+ :id => 16,
56
+ :first_name => "Wynn",
57
+ :last_name => "Netherland",
58
+ :email => "wynn@example.com"
59
+ }
60
+ customer = @client.update_customer(info)
61
+ customer.first_name.should == "Wynn"
62
+ end
63
+
64
+ should_eventually "raise an exception if a customer is not found" do
65
+
66
+ end
67
+
68
+ should_eventually "delete a customer" do
69
+
70
+ end
71
+
72
+ should "return a list of customer subscriptions" do
73
+ stub_get "https://OU812:x@pengwynn.chargify.com/customers/16/subscriptions.json", "subscriptions.json"
74
+ subscriptions = @client.customer_subscriptions(16)
75
+ subscriptions.size.should == 1
76
+ subscriptions.first.customer.reference.should == "bradleyjoyce"
77
+ end
78
+
79
+
80
+ should "return info for a subscription" do
81
+ stub_get "https://OU812:x@pengwynn.chargify.com/subscriptions/13.json", "subscription.json"
82
+ subscription = @client.subscription(13)
83
+ subscription.customer.reference.should == 'bradleyjoyce'
84
+ end
85
+
86
+ should "return nil if a subscription is not found" do
87
+ stub_get "https://OU812:x@pengwynn.chargify.com/subscriptions/18.json", "subscription_not_found.json", 404
88
+ subscription = @client.subscription(18)
89
+ subscription.should == nil
90
+ end
91
+
92
+ should "update a customer subscription" do
93
+ stub_put "https://OU812:x@pengwynn.chargify.com/subscriptions/123.json", "subscription.json"
94
+ options = {
95
+ :product_handle => 'monthly',
96
+ :customer_reference => 'bradleyjoyce',
97
+ :customer_attributes => {
98
+ :first_name => "Wynn",
99
+ :last_name => "Netherland",
100
+ :email => "wynn@example.com"
101
+ }
102
+ }
103
+ subscription = @client.update_subscription(123, options)
104
+ subscription.customer.organization.should == 'Squeejee'
105
+ end
106
+
107
+ should "set success? to true when subscription is updated successfully" do
108
+ stub_put "https://OU812:x@pengwynn.chargify.com/subscriptions/123.json", "subscription.json", 200
109
+ options = {
110
+ :product_handle => 'monthly',
111
+ :customer_reference => 'bradleyjoyce',
112
+ :customer_attributes => {
113
+ :first_name => "Wynn",
114
+ :last_name => "Netherland",
115
+ :email => "wynn@example.com"
116
+ }
117
+ }
118
+ subscription = @client.update_subscription(123, options)
119
+ subscription.success?.should == true
120
+ end
121
+
122
+ should "set success? to false when subscription is not updated successfully" do
123
+ stub_put "https://OU812:x@pengwynn.chargify.com/subscriptions/123.json", "subscription.json", 500
124
+ options = {
125
+ :product_handle => 'monthly',
126
+ :customer_reference => 'bradleyjoyce',
127
+ :customer_attributes => {
128
+ :first_name => "Wynn",
129
+ :last_name => "Netherland",
130
+ :email => "wynn@example.com"
131
+ }
132
+ }
133
+ subscription = @client.update_subscription(123, options)
134
+ subscription.success?.should == nil
135
+ end
136
+
137
+ should "create a customer subscription" do
138
+ stub_post "https://OU812:x@pengwynn.chargify.com/subscriptions.json", "subscription.json"
139
+ options = {
140
+ :product_handle => 'monthly',
141
+ :customer_reference => 'bradleyjoyce',
142
+ :customer_attributes => {
143
+ :first_name => "Wynn",
144
+ :last_name => "Netherland",
145
+ :email => "wynn@example.com"
146
+ }
147
+ }
148
+ subscription = @client.create_subscription(options)
149
+ subscription.customer.organization.should == 'Squeejee'
150
+ end
151
+
152
+ should "set success? to true when subscription is created successfully" do
153
+ stub_post "https://OU812:x@pengwynn.chargify.com/subscriptions.json", "subscription.json", 201
154
+ options = {
155
+ :product_handle => 'monthly',
156
+ :customer_reference => 'bradleyjoyce',
157
+ :customer_attributes => {
158
+ :first_name => "Wynn",
159
+ :last_name => "Netherland",
160
+ :email => "wynn@example.com"
161
+ }
162
+ }
163
+ subscription = @client.create_subscription(options)
164
+ subscription.success?.should == true
165
+ end
166
+
167
+ should "set success? to nil when subscription is not created successfully" do
168
+ stub_post "https://OU812:x@pengwynn.chargify.com/subscriptions.json", "subscription.json", 400
169
+ options = {
170
+ :product_handle => 'monthly',
171
+ :customer_reference => 'bradleyjoyce',
172
+ :customer_attributes => {
173
+ :first_name => "Wynn",
174
+ :last_name => "Netherland",
175
+ :email => "wynn@example.com"
176
+ }
177
+ }
178
+ subscription = @client.create_subscription(options)
179
+ subscription.success?.should == nil
180
+ end
181
+
182
+ should "cancel subscription" do
183
+ stub_delete "https://OU812:x@pengwynn.chargify.com/subscriptions/123.json", "deleted_subscription.json", 200
184
+ subscription = @client.cancel_subscription(123)
185
+
186
+ subscription.state.should == "canceled"
187
+ end
188
+
189
+ should "set success? to nil when subscription is not cancelled successfully" do
190
+ stub_delete "https://OU812:x@pengwynn.chargify.com/subscriptions/123.json", "deleted_subscription.json", 500
191
+ subscription = @client.cancel_subscription(123)
192
+
193
+ subscription.success?.should == nil
194
+ end
195
+
196
+ should "set success? to true when subscription is cancelled successfully" do
197
+ stub_delete "https://OU812:x@pengwynn.chargify.com/subscriptions/123.json", "deleted_subscription.json", 200
198
+ subscription = @client.cancel_subscription(123)
199
+
200
+ subscription.success?.should == true
201
+ end
202
+
203
+ should_eventually "create a one-off charge for a subscription" do
204
+
205
+ end
206
+
207
+ should_eventually "list metered usage for a subscription" do
208
+
209
+ end
210
+
211
+ should_eventually "record metered usage for a subscription" do
212
+
213
+ end
214
+
215
+ should_eventually "migrate a subscription to a new product" do
216
+
217
+ end
218
+
219
+ should_eventually "create one-time coupons" do
220
+
221
+ end
222
+
223
+ should "return a list of products" do
224
+ stub_get "https://OU812:x@pengwynn.chargify.com/products.json", "products.json"
225
+ products = @client.list_products
226
+ products.first.accounting_code.should == 'TSMO'
227
+ end
228
+
229
+ should "return info for a product" do
230
+ stub_get "https://OU812:x@pengwynn.chargify.com/products/8.json", "product.json"
231
+ product = @client.product(8)
232
+ product.accounting_code.should == 'TSMO'
233
+ end
234
+
235
+ should "return info for a product by its handle" do
236
+ stub_get "https://OU812:x@pengwynn.chargify.com/products/handle/tweetsaver.json", "product.json"
237
+ product = @client.product_by_handle('tweetsaver')
238
+ product.accounting_code.should == 'TSMO'
239
+ end
240
+
241
+
242
+ end
243
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fizx-chargify
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 1
9
+ version: 0.2.1
10
+ platform: ruby
11
+ authors:
12
+ - Wynn Netherland
13
+ - Nash Kabbara
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-05-01 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: thoughtbot-shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 10
31
+ - 1
32
+ version: 2.10.1
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: jnunemaker-matchy
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ - 4
45
+ - 0
46
+ version: 0.4.0
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: mocha
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 0
58
+ - 9
59
+ - 4
60
+ version: 0.9.4
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: fakeweb
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ segments:
71
+ - 1
72
+ - 2
73
+ - 5
74
+ version: 1.2.5
75
+ type: :development
76
+ version_requirements: *id004
77
+ description: Ruby wrapper for the chargify.com SAAS and billing API
78
+ email: wynn.netherland@gmail.com
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files:
84
+ - LICENSE
85
+ - README.markdown
86
+ files:
87
+ - .document
88
+ - .gitignore
89
+ - LICENSE
90
+ - README.markdown
91
+ - Rakefile
92
+ - VERSION
93
+ - changelog.md
94
+ - chargify.gemspec
95
+ - lib/chargify.rb
96
+ - lib/chargify/client.rb
97
+ - test/fixtures/customer.json
98
+ - test/fixtures/customers.json
99
+ - test/fixtures/deleted_subscription.json
100
+ - test/fixtures/invalid_subscription.json
101
+ - test/fixtures/new_customer.json
102
+ - test/fixtures/product.json
103
+ - test/fixtures/products.json
104
+ - test/fixtures/subscription.json
105
+ - test/fixtures/subscription_not_found.json
106
+ - test/fixtures/subscriptions.json
107
+ - test/helper.rb
108
+ - test/test_chargify.rb
109
+ has_rdoc: true
110
+ homepage: http://github.com/pengwynn/chargify
111
+ licenses: []
112
+
113
+ post_install_message:
114
+ rdoc_options:
115
+ - --charset=UTF-8
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ segments:
123
+ - 0
124
+ version: "0"
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ segments:
130
+ - 0
131
+ version: "0"
132
+ requirements: []
133
+
134
+ rubyforge_project:
135
+ rubygems_version: 1.3.6
136
+ signing_key:
137
+ specification_version: 3
138
+ summary: Ruby wrapper for the chargify.com SAAS and billing API
139
+ test_files:
140
+ - test/helper.rb
141
+ - test/test_chargify.rb