cheddargetter 0.1.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.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Atlantic Dominion Solutions
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
+ = CheddarGetter
2
+
3
+ Wrapper for the Cheddar Getter API. Currently limited to the subset of API calls we actually use...
4
+
5
+ == Installation
6
+
7
+ gem install cheddargetter -s http://gemcutter.org/
8
+
9
+ == Usage
10
+
11
+ Create a CheddarGetter object with your username (email), password, and product code:
12
+
13
+ @cheddar_getter = CheddarGetter.new('me@mysite.com', 'password', 'MY_PRODUCT')
14
+
15
+ Now you can call methods that correspond to the CheddarGetter API. For example, to get a list of all plans:
16
+
17
+ @cheddar_getter.plans
18
+
19
+ For the available methods and more detailed information on each, see the RDocs and Cheddar Getter API:
20
+
21
+ * RDocs: http://rdoc.info/projects/ads/cheddargetter
22
+ * Cheddar Getter API: https://cheddargetter.com/api
23
+
24
+ == Copyright
25
+
26
+ Copyright (c) 2009 Atlantic Dominion Solutions. See LICENSE for details.
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "cheddargetter"
8
+ gem.summary = "Ruby wrapper for the CheddarGetter API"
9
+ gem.description = "Ruby wrapper for the CheddarGetter API"
10
+ gem.email = "justin@adsdevshop.com"
11
+ gem.homepage = "http://github.com/ads/cheddargetter"
12
+ gem.authors = ["Atlantic Dominion Solutions"]
13
+ gem.add_dependency "httparty"
14
+ gem.add_development_dependency "rspec"
15
+ gem.add_development_dependency "fakeweb"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
20
+ end
21
+
22
+ require 'spec/rake/spectask'
23
+ Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ spec.spec_opts = ['-c']
27
+ end
28
+ Spec::Rake::SpecTask.new(:specdoc) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.spec_files = FileList['spec/**/*_spec.rb']
31
+ spec.spec_opts = ['-cf', 's']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ task :default => :spec
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ if File.exist?('VERSION')
47
+ version = File.read('VERSION')
48
+ else
49
+ version = ""
50
+ end
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "cheddargetter #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,61 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{cheddargetter}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Atlantic Dominion Solutions"]
12
+ s.date = %q{2009-09-28}
13
+ s.description = %q{Ruby wrapper for the CheddarGetter API}
14
+ s.email = %q{justin@adsdevshop.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "cheddargetter.gemspec",
27
+ "lib/cheddargetter.rb",
28
+ "spec/cheddargetter_spec.rb",
29
+ "spec/spec_helper.rb",
30
+ "spec/spec_watcher.rb"
31
+ ]
32
+ s.homepage = %q{http://github.com/ads/cheddargetter}
33
+ s.rdoc_options = ["--charset=UTF-8"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = %q{1.3.3}
36
+ s.summary = %q{Ruby wrapper for the CheddarGetter API}
37
+ s.test_files = [
38
+ "spec/cheddargetter_spec.rb",
39
+ "spec/spec_helper.rb",
40
+ "spec/spec_watcher.rb"
41
+ ]
42
+
43
+ if s.respond_to? :specification_version then
44
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
45
+ s.specification_version = 3
46
+
47
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
48
+ s.add_runtime_dependency(%q<httparty>, [">= 0"])
49
+ s.add_development_dependency(%q<rspec>, [">= 0"])
50
+ s.add_development_dependency(%q<fakeweb>, [">= 0"])
51
+ else
52
+ s.add_dependency(%q<httparty>, [">= 0"])
53
+ s.add_dependency(%q<rspec>, [">= 0"])
54
+ s.add_dependency(%q<fakeweb>, [">= 0"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<httparty>, [">= 0"])
58
+ s.add_dependency(%q<rspec>, [">= 0"])
59
+ s.add_dependency(%q<fakeweb>, [">= 0"])
60
+ end
61
+ end
@@ -0,0 +1,107 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+
4
+ class CheddarGetter
5
+ include HTTParty
6
+
7
+ class Error < StandardError; end
8
+
9
+ def initialize(username, password, product_code)
10
+ @product_code = product_code
11
+ self.class.basic_auth(username, password)
12
+ end
13
+
14
+ # Returns an array of all plans:
15
+ #
16
+ # [{"name" => "Little", "code" => "LITTLE", "recurringChargeAmount" => "1.00", etc...},
17
+ # {"name" => "Big", "code" => "BIG", "recurringChargeAmount" => "100.00", etc..}]
18
+ def plans
19
+ response = get("/plans/get/productCode/#{@product_code}")
20
+ normalize_collection(response, 'plans', 'plan')
21
+ end
22
+
23
+ # Returns the requested plan as a hash:
24
+ #
25
+ # {"name" => "Little", "code" => "LITTLE", "recurringChargeAmount" => "1.00", etc...}
26
+ def plan(plan_code)
27
+ response = get("/plans/get/productCode/#{@product_code}/code/#{plan_code}")
28
+ normalize(response, 'plans', 'plan')
29
+ end
30
+
31
+ def customers
32
+ response = get("/customers/get/productCode/#{@product_code}")
33
+ normalize_collection(response, 'customers', 'customer')
34
+ rescue Error => e # HACK! the api is inconsitent about returning empty nodes vs. sending errors
35
+ if e.message =~ /no customers found/i
36
+ return []
37
+ else
38
+ raise
39
+ end
40
+ end
41
+
42
+ def customer(customer_code)
43
+ response = get("/customers/get/productCode/#{@product_code}/code/#{customer_code}")
44
+ normalize(response, 'customers', 'customer')
45
+ end
46
+
47
+ # Pass an attributes hash for the new customer:
48
+ #
49
+ # :code => 'CUSTOMER-1', # required
50
+ # :firstName => 'Justin', # required
51
+ # :lastName => 'Blake', # required
52
+ # :email => 'justin@adsdevshop.com', # required
53
+ # :company => 'ADS', # optional
54
+ # :subscription => {
55
+ # :planCode => "INDY", # required
56
+ # :ccFirstName => "Justin", # required unless plan is free
57
+ # :ccLastName => "Blake", # required unless plan is free
58
+ # :ccNumber => "numbers only", # required unless plan is free
59
+ # :ccExpiration => "MM-YYYY", # required unless plan is free
60
+ # :ccZip => "5 digits only" # required unless plan is free
61
+ # }
62
+ #
63
+ # Returns the customer:
64
+ #
65
+ # {"firstName" => "Justin", "lastName" => "Blake", etc...}
66
+ def create_customer(attributes)
67
+ response = post("/customers/new/productCode/#{@product_code}", :body => attributes)
68
+ normalize(response, 'customers', 'customer')
69
+ end
70
+
71
+ # Attributes are the same as #create_customer
72
+ # Only included attributes will be udpated.
73
+ # Credit Card information is only required if the plan is not free and
74
+ # no credit card information is already saved.
75
+ def update_customer(customer_code, attributes)
76
+ response = post("/customers/edit/productCode/#{@product_code}/code/#{customer_code}", :body => attributes)
77
+ normalize(response, 'customers', 'customer')
78
+ end
79
+
80
+ private
81
+
82
+ def get(path)
83
+ request(:get, path)
84
+ end
85
+
86
+ def post(path, options = {})
87
+ request(:post, path, options)
88
+ end
89
+
90
+ def request(method, path, options = {})
91
+ path = "https://cheddargetter.com/xml" + path
92
+ response = self.class.send(method, path, options)
93
+ raise Error.new(response['error']) if response['error']
94
+ response
95
+ end
96
+
97
+ def normalize(response, parent_node, child_node)
98
+ return [] unless response[parent_node]
99
+ response[parent_node][child_node]
100
+ end
101
+
102
+ def normalize_collection(response, parent_node, child_node)
103
+ children = normalize(response, parent_node, child_node)
104
+ children = [children] unless children.is_a?(Array)
105
+ children
106
+ end
107
+ end
@@ -0,0 +1,130 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "an instance of CheddarGetter" do
4
+ before(:all) do
5
+ CheddarGetter.stub!(:basic_auth)
6
+ @cheddar_getter = CheddarGetter.new('my_username', 'my_password', 'MY_PRODUCT')
7
+ end
8
+
9
+ it "should use the supplied username and password for basic auth" do
10
+ CheddarGetter.should_receive(:basic_auth).with('my_username', 'my_password')
11
+ CheddarGetter.new('my_username', 'my_password', 'MY_PRODUCT')
12
+ end
13
+
14
+ describe 'calling #plans' do
15
+ it "should return an empty array if there are no plans" do
16
+ mock_request(:get, "/plans/get/productCode/MY_PRODUCT", "<plans></plans>")
17
+ @cheddar_getter.plans.should == []
18
+ end
19
+
20
+ it "should return the plan in an array if there is one plan" do
21
+ mock_request(:get, "/plans/get/productCode/MY_PRODUCT", "<plans><plan>plan1</plan></plans>")
22
+ plans = @cheddar_getter.plans
23
+ plans.length.should == 1
24
+ plans.should include('plan1')
25
+ end
26
+
27
+ it "should return the plans in an array if there are multiple plans" do
28
+ mock_request(:get, "/plans/get/productCode/MY_PRODUCT", "<plans><plan>plan1</plan><plan>plan2</plan></plans>")
29
+ plans = @cheddar_getter.plans
30
+ plans.length.should == 2
31
+ plans.should include('plan1')
32
+ plans.should include('plan2')
33
+ end
34
+
35
+ it "should raise if an error is returned" do
36
+ mock_request(:get, "/plans/get/productCode/MY_PRODUCT", "<error>the message</error>")
37
+ lambda { @cheddar_getter.plans }.should raise_error(CheddarGetter::Error, 'the message')
38
+ end
39
+ end
40
+
41
+ describe 'calling #plan(plan_code)' do
42
+ it "should return the requested plan if the plan code is valid" do
43
+ (1..3).each do |i|
44
+ mock_request(:get, "/plans/get/productCode/MY_PRODUCT/code/MY_PLAN#{i}", "<plans><plan>plan#{i}</plan></plans>")
45
+ @cheddar_getter.plan("MY_PLAN#{i}").should == "plan#{i}"
46
+ end
47
+ end
48
+
49
+ it "should raise if the plan code is not valid" do
50
+ mock_request(:get, "/plans/get/productCode/MY_PRODUCT/code/BAD_CODE", "<error>bad code</error>")
51
+ lambda { @cheddar_getter.plan('BAD_CODE') }.should raise_error(CheddarGetter::Error, 'bad code')
52
+ end
53
+ end
54
+
55
+ describe 'calling #customers' do
56
+ it "should return an empty array if there are no customers" do
57
+ mock_request(:get, "/customers/get/productCode/MY_PRODUCT", "<customers></customers>")
58
+ @cheddar_getter.customers.should == []
59
+ end
60
+
61
+ it "should return an empty array if there is a stupid, inconsistent error about there being no customers" do
62
+ mock_request(:get, "/customers/get/productCode/MY_PRODUCT", "<error>Bad request: No customers found</error>")
63
+ @cheddar_getter.customers.should == []
64
+ end
65
+
66
+ it "should return the customer in an array if there is one customer" do
67
+ mock_request(:get, "/customers/get/productCode/MY_PRODUCT", "<customers><customer>customer1</customer></customers>")
68
+ customers = @cheddar_getter.customers
69
+ customers.length.should == 1
70
+ customers.should include('customer1')
71
+ end
72
+
73
+ it "should return the customers in an array if there are multiple customers" do
74
+ mock_request(:get, "/customers/get/productCode/MY_PRODUCT", "<customers><customer>customer1</customer><customer>customer2</customer></customers>")
75
+ customers = @cheddar_getter.customers
76
+ customers.length.should == 2
77
+ customers.should include('customer1')
78
+ customers.should include('customer2')
79
+ end
80
+
81
+ it "should raise if an error is returned" do
82
+ mock_request(:get, "/customers/get/productCode/MY_PRODUCT", "<error>the message</error>")
83
+ lambda { @cheddar_getter.customers }.should raise_error(CheddarGetter::Error, 'the message')
84
+ end
85
+ end
86
+
87
+ describe 'calling #customer(customer_code)' do
88
+ it "should return the requested customer if the customer code is valid" do
89
+ (1..3).each do |i|
90
+ mock_request(:get, "/customers/get/productCode/MY_PRODUCT/code/MY_CUSTOMER#{i}", "<customers><customer>customer#{i}</customer></customers>")
91
+ @cheddar_getter.customer("MY_CUSTOMER#{i}").should == "customer#{i}"
92
+ end
93
+ end
94
+
95
+ it "should raise if the customer code is not valid" do
96
+ mock_request(:get, "/customers/get/productCode/MY_PRODUCT/code/BAD_CODE", "<error>bad code</error>")
97
+ lambda { @cheddar_getter.customer('BAD_CODE') }.should raise_error(CheddarGetter::Error, 'bad code')
98
+ end
99
+ end
100
+
101
+ describe 'calling #create_customer(attributes)' do
102
+ it "should return the created customer" do
103
+ mock_request(:post, "/customers/new/productCode/MY_PRODUCT", "<customers><customer>new customer</customer></customers>")
104
+ @cheddar_getter.create_customer(:name => 'justin', :age => 12).should == "new customer"
105
+ end
106
+
107
+ it "should raise if an error is returned" do
108
+ mock_request(:post, "/customers/new/productCode/MY_PRODUCT", "<error>failed create</error>")
109
+ lambda { @cheddar_getter.create_customer(:name => 'justin') }.should raise_error(CheddarGetter::Error, 'failed create')
110
+ end
111
+ end
112
+
113
+ describe 'calling #update_customer(customer_code, attributes)' do
114
+ it "should return the updated customer" do
115
+ mock_request(:post, "/customers/edit/productCode/MY_PRODUCT/code/MY_CUSTOMER", "<customers><customer>updated customer</customer></customers>")
116
+ @cheddar_getter.update_customer('MY_CUSTOMER', :name => "new name").should == "updated customer"
117
+ end
118
+
119
+ it "should raise if an error is returned" do
120
+ mock_request(:post, "/customers/edit/productCode/MY_PRODUCT/code/MY_CUSTOMER", "<error>failed update</error>")
121
+ lambda { @cheddar_getter.update_customer('MY_CUSTOMER', :name => "new name") }.should raise_error(CheddarGetter::Error, 'failed update')
122
+ end
123
+ end
124
+
125
+ def mock_request(method, request_path, response_xml)
126
+ request_path.gsub!(/^\//, '')
127
+ options = { :body => response_xml, :content_type => "text/xml" }
128
+ FakeWeb.register_uri(method, "https://cheddargetter.com/xml/#{request_path}", options)
129
+ end
130
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'cheddargetter'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+ require 'fakeweb'
7
+
8
+ # Let's keep these specs self-contained.
9
+ # All web service requests should be mocked.
10
+ FakeWeb.allow_net_connect = false
11
+
12
+ Spec::Runner.configure do |config|
13
+
14
+ end
@@ -0,0 +1,26 @@
1
+ #
2
+ # Config for watchr: http://github.com/mynyml/watchr
3
+ #
4
+
5
+ def specdoc
6
+ puts
7
+ puts "=" * 50
8
+ puts
9
+ system("rake specdoc")
10
+ end
11
+
12
+ # run specdoc on startup
13
+ specdoc
14
+
15
+ # watch the spec and lib dirs
16
+ watch('spec/.+_spec\.rb') { |m| system("spec -c #{m[0]}") }
17
+ watch('lib/(.*)\.rb') { |m| system("spec -c spec/#{m[1]}_spec.rb") }
18
+
19
+ # run all tests if spec helper changes
20
+ watch('spec/spec_helper.rb') { |m| system("rake spec") }
21
+
22
+ # Ctrl-\ runs specdoc
23
+ Signal.trap('QUIT') { specdoc }
24
+
25
+ # Ctrl-C quits
26
+ Signal.trap('INT') { abort("\n") }
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cheddargetter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Atlantic Dominion Solutions
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-28 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: httparty
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: fakeweb
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ description: Ruby wrapper for the CheddarGetter API
46
+ email: justin@adsdevshop.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - LICENSE
53
+ - README.rdoc
54
+ files:
55
+ - .document
56
+ - .gitignore
57
+ - LICENSE
58
+ - README.rdoc
59
+ - Rakefile
60
+ - VERSION
61
+ - cheddargetter.gemspec
62
+ - lib/cheddargetter.rb
63
+ - spec/cheddargetter_spec.rb
64
+ - spec/spec_helper.rb
65
+ - spec/spec_watcher.rb
66
+ has_rdoc: true
67
+ homepage: http://github.com/ads/cheddargetter
68
+ licenses: []
69
+
70
+ post_install_message:
71
+ rdoc_options:
72
+ - --charset=UTF-8
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "0"
86
+ version:
87
+ requirements: []
88
+
89
+ rubyforge_project:
90
+ rubygems_version: 1.3.3
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Ruby wrapper for the CheddarGetter API
94
+ test_files:
95
+ - spec/cheddargetter_spec.rb
96
+ - spec/spec_helper.rb
97
+ - spec/spec_watcher.rb