fizx-chargify 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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