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,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,10 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ spec/integration/settings.yml
7
+ script/cheddar_getter.yml
8
+ mousetrap_config.yml
9
+ .rvmrc
10
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source :rubygems
2
+
3
+ gem 'httparty', '>= 0.6.1'
4
+
5
+ # handles installing all the dependencies needed for running the mousetrap specs
6
+ gem "rspec", ">= 2.0.0.beta.20"
7
+ gem "activesupport", '>= 2.3.3'
8
+ gem 'factory_girl', '= 1.2.3'
9
+ gem "jeweler"
@@ -0,0 +1,36 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.0.0)
5
+ crack (0.1.8)
6
+ diff-lcs (1.1.2)
7
+ factory_girl (1.2.3)
8
+ gemcutter (0.6.1)
9
+ git (1.2.5)
10
+ httparty (0.6.1)
11
+ crack (= 0.1.8)
12
+ jeweler (1.4.0)
13
+ gemcutter (>= 0.1.0)
14
+ git (>= 1.2.5)
15
+ rubyforge (>= 2.0.0)
16
+ json_pure (1.4.6)
17
+ rspec (2.0.0.beta.20)
18
+ rspec-core (= 2.0.0.beta.20)
19
+ rspec-expectations (= 2.0.0.beta.20)
20
+ rspec-mocks (= 2.0.0.beta.20)
21
+ rspec-core (2.0.0.beta.20)
22
+ rspec-expectations (2.0.0.beta.20)
23
+ diff-lcs (>= 1.1.2)
24
+ rspec-mocks (2.0.0.beta.20)
25
+ rubyforge (2.0.4)
26
+ json_pure (>= 1.1.7)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ activesupport (>= 2.3.3)
33
+ factory_girl (= 1.2.3)
34
+ httparty (>= 0.6.1)
35
+ jeweler
36
+ rspec (>= 2.0.0.beta.20)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jon Larkowski
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.
@@ -0,0 +1,26 @@
1
+ h1. Mousetrap
2
+
3
+ _CheddarGetter API Client in Ruby_
4
+
5
+ Docs coming Real Soon Now (TM).
6
+
7
+
8
+ h2. Tests
9
+
10
+ h3. Unit Tests
11
+
12
+ Run RSpec tests with the @rake spec@ task.
13
+
14
+ h3. Integration Smoke Test
15
+
16
+ This test runs against the actual CheddarGetter service, using a test Product
17
+ that you create.
18
+
19
+ # Set up a CheddarGetter account.
20
+ # Add a Product with a code named: @MOUSETRAP_TEST@
21
+ # Add a Plan with a code named: @TEST@
22
+ # Add another Plan with a code named: @TEST_2@
23
+ # Put your credentials into a _spec/integration/settings.yml_ file.
24
+ # Run the tests with: @rspec spec/integration/smoke_test.rb@
25
+
26
+ Copyright (c) 2009 Hashrocket. See MIT-LICENSE for details.
@@ -0,0 +1,51 @@
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+ require "bundler"
4
+ Bundler.setup
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gem|
9
+ gem.name = "sproutbox-mousetrap"
10
+ gem.summary = %Q{CheddarGetter API Client in Ruby}
11
+ gem.description = %Q{CheddarGetter API Client in Ruby}
12
+ gem.email = "jonlarkowski@gmail.com"
13
+ gem.homepage = "http://github.com/hashrocket/mousetrap"
14
+ gem.authors = ["Jon Larkowski", "Sandro Turriate", "Wolfram Arnold", "Corey Grusden"]
15
+ gem.add_dependency 'httparty', '>= 0.6.1'
16
+ gem.add_development_dependency "activesupport", '>= 2.3.3'
17
+ gem.add_development_dependency "rspec", '>= 2.0.0.beta.20'
18
+ gem.add_development_dependency 'factory_girl', '= 1.2.3'
19
+ end
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'rspec'
25
+ require "rspec/core/rake_task"
26
+ Rspec::Core::RakeTask.new(:spec) do |spec|
27
+ spec.pattern = 'spec/**/*_spec.rb'
28
+ end
29
+
30
+ Rspec::Core::RakeTask.new(:rcov) do |spec|
31
+ # spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.rcov = true
34
+ end
35
+
36
+ task :spec => :check_dependencies
37
+
38
+ task :default => :spec
39
+
40
+ Rake::RDocTask.new do |rdoc|
41
+ if File.exist?('VERSION')
42
+ version = File.read('VERSION')
43
+ else
44
+ version = ""
45
+ end
46
+
47
+ rdoc.rdoc_dir = 'rdoc'
48
+ rdoc.title = "mousetrap #{version}"
49
+ rdoc.rdoc_files.include('README*')
50
+ rdoc.rdoc_files.include('lib/**/*.rb')
51
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.6.4
@@ -0,0 +1,25 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ begin; require 'rubygems'; rescue LoadError; end
4
+ require 'httparty'
5
+
6
+ module Mousetrap
7
+ API_UNSUPPORTED = "CheddarGetter API doesn't support this."
8
+
9
+ class ApiDown < Exception
10
+ end
11
+
12
+ autoload :Customer, 'mousetrap/customer'
13
+ autoload :Plan, 'mousetrap/plan'
14
+ autoload :Resource, 'mousetrap/resource'
15
+ autoload :Invoice, 'mousetrap/invoice'
16
+ autoload :Subscription, 'mousetrap/subscription'
17
+
18
+ class << self
19
+ attr_accessor :product_code
20
+
21
+ def authenticate(user, password)
22
+ Resource.basic_auth user, password
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,214 @@
1
+ module Mousetrap
2
+ class Customer < Resource
3
+ attr_accessor \
4
+ :id,
5
+ :code,
6
+ :email,
7
+ :first_name,
8
+ :last_name,
9
+ :company,
10
+ :notes,
11
+ :subscription,
12
+ :charges,
13
+ :items
14
+
15
+ def update_tracked_item_quantity(item_code, quantity = 1)
16
+ tracked_item_resource = if quantity == quantity.abs
17
+ 'add-item-quantity'
18
+ else
19
+ 'remove-item-quantity'
20
+ end
21
+
22
+ attributes = {
23
+ :itemCode => item_code,
24
+ :quantity => quantity.abs
25
+ }
26
+
27
+ response = self.class.put_resource 'customers', tracked_item_resource, code, attributes
28
+
29
+ raise response['error'] if response['error']
30
+ response
31
+ end
32
+
33
+ def add_item_quantity(item_code, quantity = 1)
34
+ update_tracked_item_quantity(item_code, quantity)
35
+ end
36
+
37
+ def remove_item_quantity(item_code, quantity = 1)
38
+ update_tracked_item_quantity(item_code, -quantity)
39
+ end
40
+
41
+ def add_custom_charge(item_code, amount = 1.0, quantity = 1, description = nil)
42
+ attributes = {
43
+ :chargeCode => item_code,
44
+ :eachAmount => amount,
45
+ :quantity => quantity,
46
+ :description => description
47
+ }
48
+
49
+ response = self.class.put_resource 'customers', 'add-charge', code, attributes
50
+ raise response['error'] if response['error']
51
+ response
52
+ end
53
+
54
+ def instant_bill_custom_charge(item_code, amount = 1.0, quantity = 1, description = nil)
55
+ add_custom_charge(item_code, amount, quantity, description)
56
+ bill_now
57
+ end
58
+
59
+ def subscription_attributes=(attributes)
60
+ self.subscription = Subscription.new attributes
61
+ end
62
+
63
+ def attributes
64
+ {
65
+ :id => id,
66
+ :code => code,
67
+ :email => email,
68
+ :first_name => first_name,
69
+ :last_name => last_name,
70
+ :company => company,
71
+ :notes => notes,
72
+ :charges => charges,
73
+ :items => items
74
+ }
75
+ end
76
+
77
+ def attributes_for_api
78
+ # TODO: superclass?
79
+ self.class.attributes_for_api(attributes, new_record?)
80
+ end
81
+
82
+ def attributes_for_api_with_subscription
83
+ raise "Must have subscription" unless subscription
84
+ a = attributes_for_api
85
+ a[:subscription] = subscription.attributes_for_api
86
+ a
87
+ end
88
+
89
+ def cancel
90
+ member_action 'cancel' unless new_record?
91
+ end
92
+
93
+ def new?
94
+ if api_customer = self.class[code]
95
+ self.id = api_customer.id
96
+
97
+ return false
98
+ else
99
+ return true
100
+ end
101
+ end
102
+
103
+ def save
104
+ new? ? create : update
105
+ end
106
+
107
+ def switch_to_plan(plan_code)
108
+ raise "Can only call this on an existing CheddarGetter customer." unless exists?
109
+
110
+ attributes = { :planCode => plan_code }
111
+ self.class.put_resource('customers', 'edit-subscription', code, attributes)
112
+
113
+ # TODO: Refresh self with reload here?
114
+ end
115
+
116
+ def bill_now
117
+ raise "Can only call this on an existing CheddarGetter customer." unless exists?
118
+
119
+ attributes = { :changeBillDate => 'now' }
120
+ self.class.put_resource('customers', 'edit-subscription', code, attributes)
121
+ end
122
+
123
+ def self.all
124
+ response = get_resources 'customers'
125
+
126
+ if response['error']
127
+ if response['error'] =~ /No customers found/
128
+ return []
129
+ else
130
+ raise response['error']
131
+ end
132
+ end
133
+
134
+ build_resources_from response
135
+ end
136
+
137
+ def self.create(attributes)
138
+ object = new(attributes)
139
+ object.send(:create)
140
+ object
141
+ end
142
+
143
+ def self.new_from_api(attributes)
144
+ customer = new(attributes_from_api(attributes))
145
+ subscription_attrs = attributes['subscriptions']['subscription']
146
+ customer.subscription = Subscription.new_from_api(subscription_attrs.kind_of?(Array) ? subscription_attrs.first : subscription_attrs)
147
+ customer
148
+ end
149
+
150
+ def self.update(customer_code, attributes)
151
+ customer = new(attributes)
152
+ customer.code = customer_code
153
+ customer.send :update
154
+ end
155
+
156
+
157
+ protected
158
+
159
+ def self.plural_resource_name
160
+ 'customers'
161
+ end
162
+
163
+ def self.singular_resource_name
164
+ 'customer'
165
+ end
166
+
167
+ def self.attributes_for_api(attributes, new_record = true)
168
+ mutated_hash = {
169
+ :email => attributes[:email],
170
+ :firstName => attributes[:first_name],
171
+ :lastName => attributes[:last_name],
172
+ :company => attributes[:company],
173
+ :notes => attributes[:notes]
174
+ }
175
+
176
+ mutated_hash.merge!(:charges => attributes[:charges]) if attributes[:charges]
177
+ mutated_hash.merge!(:items => attributes[:items]) if attributes[:items]
178
+ mutated_hash.merge!(:code => attributes[:code]) if new_record
179
+ mutated_hash
180
+ end
181
+
182
+ def self.attributes_from_api(attributes)
183
+ {
184
+ :id => attributes['id'],
185
+ :code => attributes['code'],
186
+ :first_name => attributes['firstName'],
187
+ :last_name => attributes['lastName'],
188
+ :company => attributes['company'],
189
+ :email => attributes['email'],
190
+ :notes => attributes['notes']
191
+ }
192
+ end
193
+
194
+ def create
195
+ response = self.class.post_resource 'customers', 'new', attributes_for_api_with_subscription
196
+
197
+ raise response['error'] if response['error']
198
+
199
+ returned_customer = self.class.build_resource_from response
200
+ self.id = returned_customer.id
201
+ response
202
+ end
203
+
204
+ def update
205
+ if subscription
206
+ response = self.class.put_resource 'customers', 'edit', code, attributes_for_api_with_subscription
207
+ else
208
+ response = self.class.put_resource 'customers', 'edit-customer', code, attributes_for_api
209
+ end
210
+
211
+ raise response['error'] if response['error']
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,41 @@
1
+ module Mousetrap
2
+ class Invoice < Resource
3
+ attr_accessor \
4
+ :id,
5
+ :number,
6
+ :billing_date,
7
+ :created_at
8
+
9
+ def initialize(hash = {})
10
+ super(self.class.attributes_from_api(hash))
11
+ end
12
+
13
+ protected
14
+
15
+ def self.plural_resource_name
16
+ 'invoices'
17
+ end
18
+
19
+ def self.singular_resource_name
20
+ 'invoice'
21
+ end
22
+
23
+ def attributes
24
+ {
25
+ :id => id,
26
+ :number => number,
27
+ :billing_date => billing_date,
28
+ :created_at => created_at
29
+ }
30
+ end
31
+
32
+ def self.attributes_from_api(attributes)
33
+ {
34
+ :id => attributes['id'],
35
+ :number => attributes['number'],
36
+ :billing_date => attributes['billingDatetime'],
37
+ :created_at => attributes['createdDatetime']
38
+ }
39
+ end
40
+ end
41
+ end