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.
- data/.document +5 -0
- data/.gitignore +10 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +36 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +26 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/lib/mousetrap.rb +25 -0
- data/lib/mousetrap/customer.rb +214 -0
- data/lib/mousetrap/invoice.rb +41 -0
- data/lib/mousetrap/plan.rb +34 -0
- data/lib/mousetrap/resource.rb +147 -0
- data/lib/mousetrap/subscription.rb +166 -0
- data/mousetrap.gemspec +91 -0
- data/script/authenticate.rb +3 -0
- data/script/cheddar_getter.example.yml +3 -0
- data/script/console +15 -0
- data/spec/factories.rb +42 -0
- data/spec/integration/settings.example.yml +6 -0
- data/spec/integration/smoke_test.rb +358 -0
- data/spec/integration/spike.rb +108 -0
- data/spec/mousetrap/customer_spec.rb +491 -0
- data/spec/mousetrap/plan_spec.rb +41 -0
- data/spec/mousetrap/resource_spec.rb +188 -0
- data/spec/mousetrap/subscription_spec.rb +164 -0
- data/spec/mousetrap_spec.rb +17 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/support/fixtures.rb +189 -0
- data/spec/support/random_data.rb +21 -0
- metadata +174 -0
@@ -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
|
data/mousetrap.gemspec
ADDED
@@ -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
|
+
|