sproutbox-mousetrap 0.6.4

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.
@@ -0,0 +1,34 @@
1
+ module Mousetrap
2
+ class Plan < Resource
3
+ attr_accessor \
4
+ :code,
5
+ :name,
6
+ :items,
7
+ :recurring_charge_amount
8
+
9
+ def self.all
10
+ response = get_resources plural_resource_name
11
+ return [] unless response['plans']
12
+ build_resources_from response
13
+ end
14
+
15
+ protected
16
+
17
+ def self.plural_resource_name
18
+ 'plans'
19
+ end
20
+
21
+ def self.singular_resource_name
22
+ 'plan'
23
+ end
24
+
25
+ def self.attributes_from_api(attributes)
26
+ {
27
+ :code => attributes['code'],
28
+ :name => attributes['name'],
29
+ :items => attributes['items'],
30
+ :recurring_charge_amount => attributes['recurringChargeAmount']
31
+ }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,147 @@
1
+ module Mousetrap
2
+ class Resource
3
+ include HTTParty
4
+ headers 'User-Agent' => 'Mousetrap Ruby Client'
5
+ base_uri 'https://cheddargetter.com'
6
+
7
+ def initialize(hash={})
8
+ hash.each do |key, value|
9
+ self.send("#{key}=", value)
10
+ end
11
+ end
12
+
13
+ def self.[](code)
14
+ # Example error message:
15
+ #
16
+ # { "error" => "Resource not found: Customer not found for
17
+ # code=cantfindme within productCode=MOUSETRAP_TEST"}
18
+
19
+ response = get_resource plural_resource_name, code
20
+
21
+ if response['error']
22
+ if response['error'] =~ /not found/
23
+ return nil
24
+ else
25
+ raise response['error']
26
+ end
27
+ end
28
+
29
+ build_resource_from response
30
+ end
31
+
32
+ def self.destroy_all
33
+ all.each { |object| object.destroy }
34
+ end
35
+
36
+ def self.exists?(code)
37
+ !self[code].nil?
38
+ end
39
+
40
+ def self.new_from_api(attributes)
41
+ new(attributes_from_api(attributes))
42
+ end
43
+
44
+ def destroy
45
+ member_action 'delete' unless new_record?
46
+ end
47
+
48
+ def exists?
49
+ self.class.exists?(code)
50
+ end
51
+
52
+ def new?
53
+ id.nil?
54
+ end
55
+
56
+ alias new_record? new?
57
+
58
+
59
+ protected
60
+
61
+ def self.build_resource_from(response)
62
+ resource_attributes = extract_resources(response)
63
+ new_from_api(resource_attributes)
64
+ end
65
+
66
+ def self.build_resources_from(response)
67
+ resources = []
68
+
69
+ response_resources = extract_resources(response)
70
+
71
+ if response_resources.is_a?(Array)
72
+ extract_resources(response).each do |resource_attributes|
73
+ resources << new_from_api(resource_attributes)
74
+ end
75
+ else
76
+ resources << new_from_api(response_resources)
77
+ end
78
+
79
+ resources
80
+ end
81
+
82
+ def self.delete_resource(resource, code)
83
+ member_action(resource, 'delete', code)
84
+ end
85
+
86
+ def self.extract_resources(response)
87
+ response[plural_resource_name][singular_resource_name]
88
+ end
89
+
90
+ def self.get_resource(resource, code)
91
+ get resource_path(resource, 'get', code)
92
+ rescue Errno::ECONNREFUSED
93
+ raise_api_is_down
94
+ end
95
+
96
+ def self.get_resources(resource)
97
+ get resource_path(resource, 'get')
98
+ rescue Errno::ECONNREFUSED
99
+ raise_api_is_down
100
+ end
101
+
102
+ def self.member_action(resource, action, code, attributes = nil)
103
+ path = resource_path(resource, action, code)
104
+
105
+ if attributes
106
+ post path, :body => attributes
107
+ else
108
+ post path
109
+ end
110
+ rescue Errno::ECONNREFUSED
111
+ raise_api_is_down
112
+ end
113
+
114
+ def self.post_resource(resource, action, attributes)
115
+ path = resource_path(resource, action)
116
+ post path, :body => attributes
117
+ rescue Errno::ECONNREFUSED
118
+ raise_api_is_down
119
+ end
120
+
121
+ def self.put_resource(resource, action, code, attributes)
122
+ member_action(resource, action, code, attributes)
123
+ end
124
+
125
+ def self.raise_api_unsupported_error
126
+ raise NotImplementedError, API_UNSUPPORTED
127
+ end
128
+
129
+ def self.raise_api_is_down
130
+ raise ApiDown, "CheddarGetter is currently down"
131
+ end
132
+
133
+ def self.resource_path(resource, action, code = nil)
134
+ path = "/xml/#{resource}/#{action}/productCode/#{uri_encode(Mousetrap.product_code)}"
135
+ path += "/code/#{uri_encode(code)}" if code
136
+ path
137
+ end
138
+
139
+ def self.uri_encode(value)
140
+ URI.encode(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
141
+ end
142
+
143
+ def member_action(action)
144
+ self.class.member_action(self.class.plural_resource_name, action, code)
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,166 @@
1
+ module Mousetrap
2
+ class Subscription < Resource
3
+ # Attributes we send _to_ the API.
4
+ attr_accessor \
5
+ :plan_code,
6
+ :billing_first_name,
7
+ :billing_last_name,
8
+ :credit_card_number,
9
+ :credit_card_expiration_month,
10
+ :credit_card_expiration_year,
11
+ :credit_card_code,
12
+ :billing_country,
13
+ :billing_address,
14
+ :billing_city,
15
+ :billing_state,
16
+ :billing_zip_code,
17
+ :billing_date,
18
+ :plan,
19
+
20
+ :customer_code # belongs to customer
21
+
22
+ # Attributes that come _from_ the API.
23
+ attr_reader \
24
+ :id,
25
+ :canceled_at,
26
+ :created_at,
27
+ :credit_card_expiration_date,
28
+ :credit_card_last_four_digits,
29
+ :credit_card_type,
30
+ :invoices,
31
+ :items,
32
+ :billing_date
33
+
34
+ def self.[](code)
35
+ raise_api_unsupported_error
36
+ end
37
+
38
+ def self.all
39
+ raise_api_unsupported_error
40
+ end
41
+
42
+ def self.destroy_all
43
+ raise_api_unsupported_error
44
+ end
45
+
46
+ def self.exists?(code)
47
+ raise_api_unsupported_error
48
+ end
49
+
50
+ def current_invoice
51
+ invoice_attributes = if invoices['invoice'].kind_of?(Array)
52
+ invoices['invoice'][0]
53
+ else
54
+ invoices['invoice']
55
+ end
56
+
57
+ Invoice.new(invoice_attributes)
58
+ end
59
+
60
+ def attributes
61
+ {
62
+ :id => id,
63
+ :plan_code => plan_code,
64
+ :billing_first_name => billing_first_name,
65
+ :billing_last_name => billing_last_name,
66
+ :credit_card_number => credit_card_number,
67
+ :credit_card_expiration_month => credit_card_expiration_month,
68
+ :credit_card_expiration_year => credit_card_expiration_year,
69
+ :credit_card_code => credit_card_code,
70
+ :billing_country => billing_country,
71
+ :billing_address => billing_address,
72
+ :billing_city => billing_city,
73
+ :billing_state => billing_state,
74
+ :billing_zip_code => billing_zip_code,
75
+ :billing_date => billing_date
76
+ }
77
+ end
78
+
79
+ def attributes_for_api
80
+ self.class.attributes_for_api(attributes)
81
+ end
82
+
83
+ def destroy
84
+ self.class.raise_api_unsupported_error
85
+ end
86
+
87
+ def exists?
88
+ self.class.raise_api_unsupported_error
89
+ end
90
+
91
+ def self.new_from_api(attributes)
92
+ subscription = new(attributes_from_api(attributes))
93
+ subscription.plan = Plan.new_from_api(attributes['plans']['plan'])
94
+ subscription
95
+ end
96
+
97
+ def self.update(customer_code, attributes)
98
+ mutated_attributes = attributes_for_api(attributes)
99
+
100
+ mutated_attributes.delete_if { |k, v| v.blank? }
101
+
102
+ response = put_resource(
103
+ 'customers',
104
+ 'edit-subscription',
105
+ customer_code,
106
+ mutated_attributes
107
+ )
108
+
109
+ raise response['error'] if response['error']
110
+ end
111
+
112
+
113
+ protected
114
+
115
+ attr_writer \
116
+ :id,
117
+ :canceled_at,
118
+ :created_at,
119
+ :credit_card_expiration_date,
120
+ :credit_card_last_four_digits,
121
+ :credit_card_type,
122
+ :credit_card_verification_code,
123
+ :items,
124
+ :invoices,
125
+ :billing_date
126
+
127
+ def self.plural_resource_name
128
+ 'subscriptions'
129
+ end
130
+
131
+ def self.singular_resource_name
132
+ 'subscription'
133
+ end
134
+
135
+ def self.attributes_for_api(attributes)
136
+ {
137
+ :planCode => attributes[:plan_code],
138
+ :ccFirstName => attributes[:billing_first_name],
139
+ :ccLastName => attributes[:billing_last_name],
140
+ :ccNumber => attributes[:credit_card_number],
141
+ :ccExpMonth => ("%02d" % attributes[:credit_card_expiration_month].to_i if attributes[:credit_card_expiration_month]),
142
+ :ccExpYear => attributes[:credit_card_expiration_year],
143
+ :ccCardCode => attributes[:credit_card_code],
144
+ :ccCountry => attributes[:billing_country],
145
+ :ccAddress => attributes[:billing_address],
146
+ :ccCity => attributes[:billing_city],
147
+ :ccState => attributes[:billing_state],
148
+ :ccZip => attributes[:billing_zip_code],
149
+ :changeBillDate => attributes[:billing_date]
150
+ }
151
+ end
152
+
153
+ def self.attributes_from_api(attributes)
154
+ {
155
+ :id => attributes['id'],
156
+ :canceled_at => attributes['canceledDatetime'],
157
+ :created_at => attributes['createdDatetime'],
158
+ :credit_card_expiration_date => attributes['ccExpirationDate'],
159
+ :credit_card_last_four_digits => attributes['ccLastFour'],
160
+ :credit_card_type => attributes['ccType'],
161
+ :invoices => attributes['invoices'],
162
+ :items => attributes['items']
163
+ }
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,91 @@
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{mousetrap}
8
+ s.version = "0.6.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jon Larkowski", "Sandro Turriate", "Wolfram Arnold", "Corey Grusden"]
12
+ s.date = %q{2010-09-11}
13
+ s.description = %q{CheddarGetter API Client in Ruby}
14
+ s.email = %q{jonlarkowski@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README.textile"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ ".gitignore",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "MIT-LICENSE",
24
+ "README.textile",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/mousetrap.rb",
28
+ "lib/mousetrap/customer.rb",
29
+ "lib/mousetrap/invoice.rb",
30
+ "lib/mousetrap/plan.rb",
31
+ "lib/mousetrap/resource.rb",
32
+ "lib/mousetrap/subscription.rb",
33
+ "mousetrap.gemspec",
34
+ "script/authenticate.rb",
35
+ "script/cheddar_getter.example.yml",
36
+ "script/console",
37
+ "spec/factories.rb",
38
+ "spec/integration/settings.example.yml",
39
+ "spec/integration/smoke_test.rb",
40
+ "spec/integration/spike.rb",
41
+ "spec/mousetrap/customer_spec.rb",
42
+ "spec/mousetrap/plan_spec.rb",
43
+ "spec/mousetrap/resource_spec.rb",
44
+ "spec/mousetrap/subscription_spec.rb",
45
+ "spec/mousetrap_spec.rb",
46
+ "spec/spec_helper.rb",
47
+ "spec/support/fixtures.rb",
48
+ "spec/support/random_data.rb"
49
+ ]
50
+ s.homepage = %q{http://github.com/hashrocket/mousetrap}
51
+ s.rdoc_options = ["--charset=UTF-8"]
52
+ s.require_paths = ["lib"]
53
+ s.rubygems_version = %q{1.3.7}
54
+ s.summary = %q{CheddarGetter API Client in Ruby}
55
+ s.test_files = [
56
+ "spec/factories.rb",
57
+ "spec/integration/smoke_test.rb",
58
+ "spec/integration/spike.rb",
59
+ "spec/mousetrap/customer_spec.rb",
60
+ "spec/mousetrap/plan_spec.rb",
61
+ "spec/mousetrap/resource_spec.rb",
62
+ "spec/mousetrap/subscription_spec.rb",
63
+ "spec/mousetrap_spec.rb",
64
+ "spec/spec_helper.rb",
65
+ "spec/support/fixtures.rb",
66
+ "spec/support/random_data.rb"
67
+ ]
68
+
69
+ if s.respond_to? :specification_version then
70
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
71
+ s.specification_version = 3
72
+
73
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
74
+ s.add_runtime_dependency(%q<httparty>, [">= 0.6.1"])
75
+ s.add_development_dependency(%q<activesupport>, [">= 2.3.3"])
76
+ s.add_development_dependency(%q<rspec>, [">= 2.0.0.beta.20"])
77
+ s.add_development_dependency(%q<factory_girl>, ["= 1.2.3"])
78
+ else
79
+ s.add_dependency(%q<httparty>, [">= 0.6.1"])
80
+ s.add_dependency(%q<activesupport>, [">= 2.3.3"])
81
+ s.add_dependency(%q<rspec>, [">= 2.0.0.beta.20"])
82
+ s.add_dependency(%q<factory_girl>, ["= 1.2.3"])
83
+ end
84
+ else
85
+ s.add_dependency(%q<httparty>, [">= 0.6.1"])
86
+ s.add_dependency(%q<activesupport>, [">= 2.3.3"])
87
+ s.add_dependency(%q<rspec>, [">= 2.0.0.beta.20"])
88
+ s.add_dependency(%q<factory_girl>, ["= 1.2.3"])
89
+ end
90
+ end
91
+
@@ -0,0 +1,3 @@
1
+ settings = YAML.load_file(File.expand_path('../cheddar_getter.yml', __FILE__))
2
+ Mousetrap.authenticate settings['user'], settings['password']
3
+ Mousetrap.product_code = settings['product_code']
@@ -0,0 +1,3 @@
1
+ user: you@example.com
2
+ password: abc123
3
+ product_code: MOUSETRAP_TEST