rainmaker 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/.document +5 -0
  2. data/.gitignore +51 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE.md +20 -0
  6. data/README.md +32 -0
  7. data/Rakefile +25 -0
  8. data/VERSION +1 -0
  9. data/lib/faraday/request/gateway.rb +18 -0
  10. data/lib/faraday/response/raise_http_4xx.rb +45 -0
  11. data/lib/faraday/response/raise_http_5xx.rb +24 -0
  12. data/lib/rainmaker/api.rb +21 -0
  13. data/lib/rainmaker/client/person.rb +12 -0
  14. data/lib/rainmaker/client.rb +14 -0
  15. data/lib/rainmaker/configuration.rb +80 -0
  16. data/lib/rainmaker/connection.rb +38 -0
  17. data/lib/rainmaker/error.rb +39 -0
  18. data/lib/rainmaker/request.rb +24 -0
  19. data/lib/rainmaker/version.rb +3 -0
  20. data/lib/rainmaker.rb +27 -0
  21. data/rainmaker.gemspec +40 -0
  22. data/spec/faraday/response_spec.rb +56 -0
  23. data/spec/fixtures/person.json +48 -0
  24. data/spec/helper.rb +22 -0
  25. data/spec/rainmaker_spec.rb +110 -0
  26. data/spec/ruby_rainmaker/api_spec.rb +65 -0
  27. data/spec/ruby_rainmaker/client/person_spec.rb +12 -0
  28. data/spec/ruby_rainmaker/client_spec.rb +10 -0
  29. data/vendor/cache/addressable-2.2.6.gem +0 -0
  30. data/vendor/cache/crack-0.1.8.gem +0 -0
  31. data/vendor/cache/diff-lcs-1.1.2.gem +0 -0
  32. data/vendor/cache/faraday-0.6.1.gem +0 -0
  33. data/vendor/cache/faraday_middleware-0.6.3.gem +0 -0
  34. data/vendor/cache/hashie-1.0.0.gem +0 -0
  35. data/vendor/cache/maruku-0.6.0.gem +0 -0
  36. data/vendor/cache/multi_json-1.0.3.gem +0 -0
  37. data/vendor/cache/multi_xml-0.2.2.gem +0 -0
  38. data/vendor/cache/multipart-post-1.1.2.gem +0 -0
  39. data/vendor/cache/nokogiri-1.4.4.1-x86-mingw32.gem +0 -0
  40. data/vendor/cache/rack-1.3.0.gem +0 -0
  41. data/vendor/cache/rake-0.9.0.gem +0 -0
  42. data/vendor/cache/rash-0.3.0.gem +0 -0
  43. data/vendor/cache/rspec-2.6.0.gem +0 -0
  44. data/vendor/cache/rspec-core-2.6.3.gem +0 -0
  45. data/vendor/cache/rspec-expectations-2.6.0.gem +0 -0
  46. data/vendor/cache/rspec-mocks-2.6.0.gem +0 -0
  47. data/vendor/cache/simplecov-0.4.2.gem +0 -0
  48. data/vendor/cache/simplecov-html-0.4.5.gem +0 -0
  49. data/vendor/cache/syntax-1.0.0.gem +0 -0
  50. data/vendor/cache/webmock-1.6.4.gem +0 -0
  51. data/vendor/cache/yard-0.7.1.gem +0 -0
  52. metadata +250 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,51 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # bundler
12
+ .bundle
13
+
14
+ # jeweler generated
15
+ pkg
16
+
17
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
18
+ #
19
+ # * Create a file at ~/.gitignore
20
+ # * Include files you want ignored
21
+ # * Run: git config --global core.excludesfile ~/.gitignore
22
+ #
23
+ # After doing this, these files will be ignored in all your git projects,
24
+ # saving you from having to 'pollute' every project you touch with them
25
+ #
26
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
27
+ #
28
+ # For MacOS:
29
+ #
30
+ #.DS_Store
31
+
32
+ # For TextMate
33
+ #*.tmproj
34
+ #tmtags
35
+
36
+ # For emacs:
37
+ #*~
38
+ #\#*
39
+ #.\#*
40
+
41
+ # For vim:
42
+ #*.swp
43
+
44
+ # For redcar:
45
+ #.redcar
46
+
47
+ # For rubinius:
48
+ #*.rbc
49
+
50
+ .idea/
51
+ *.lock
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format=nested
3
+ --backtrace
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 John Nunemaker, Wynn Netherland, Erik Michaels-Ober, Steve Richert
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.md ADDED
@@ -0,0 +1,32 @@
1
+ Rainmaker Ruby Gem
2
+ ====================
3
+ A Ruby wrapper for the [Rainmaker API](http://api.rainmaker.cc)
4
+
5
+ Installation
6
+ ------------
7
+ gem install rainmaker
8
+
9
+ Documentation
10
+ -------------
11
+ [http://rdoc.info/gems/rainmaker](http://rdoc.info/gems/rainmaker)
12
+
13
+ Usage Examples
14
+ --------------
15
+ require "rubygems"
16
+ require "rainmaker"
17
+
18
+ # This could go in an initializer
19
+ Rainmaker.configure do |config|
20
+ config.api_key = "rainmaker_api_key_goes_here"
21
+ end
22
+
23
+ # Get information about an email address
24
+ person = Rainmaker.person("brawest@gmail.com")
25
+
26
+ # Get person's family_name
27
+ puts person.contact_info.family_name
28
+
29
+ Copyright
30
+ ---------
31
+ Copyright (c) 2010 Brandon West
32
+ See [LICENSE](https://github.com/brandonmwest/twitter/blob/master/LICENSE.md) for details.
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ task :test => :spec
10
+ task :default => :spec
11
+
12
+ namespace :doc do
13
+ require 'yard'
14
+ YARD::Rake::YardocTask.new do |task|
15
+ task.files = ['HISTORY.md', 'LICENSE.md', 'lib/**/*.rb']
16
+ task.options = [
17
+ '--protected',
18
+ '--output-dir', 'doc',
19
+ '--tag', 'format:Supported formats',
20
+ '--tag', 'authenticated:Requires Authentication',
21
+ '--tag', 'rate_limited:Rate Limited',
22
+ '--markup', 'markdown',
23
+ ]
24
+ end
25
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,18 @@
1
+ require 'faraday'
2
+
3
+ # @private
4
+ module Faraday
5
+ # @private
6
+ class Request::Gateway < Faraday::Middleware
7
+ def call(env)
8
+ url = env[:url].dup
9
+ url.host = @gateway
10
+ env[:url] = url
11
+ @app.call(env)
12
+ end
13
+
14
+ def initialize(app, gateway)
15
+ @app, @gateway = app, gateway
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,45 @@
1
+ require 'faraday'
2
+
3
+ # @private
4
+ module Faraday
5
+ # @private
6
+ class Response::RaiseHttp4xx < Response::Middleware
7
+ def on_complete(env)
8
+ case env[:status].to_i
9
+ when 400
10
+ raise Rainmaker::BadRequest.new(error_message(env), env[:response_headers])
11
+ when 401
12
+ raise Rainmaker::Unauthorized.new(error_message(env), env[:response_headers])
13
+ when 403
14
+ raise Rainmaker::Forbidden.new(error_message(env), env[:response_headers])
15
+ when 404
16
+ raise Rainmaker::NotFound.new(error_message(env), env[:response_headers])
17
+ when 422
18
+ raise Rainmaker::Invalid.new(error_message(env), env[:response_headers])
19
+ end
20
+
21
+
22
+ end
23
+
24
+ private
25
+
26
+ def error_message(env)
27
+ "#{env[:method].to_s.upcase} #{env[:url].to_s}: #{env[:status]}#{error_body(env[:body])}"
28
+ end
29
+
30
+ def error_body(body)
31
+ if body.nil?
32
+ nil
33
+ elsif body['error']
34
+ ": #{body['error']}"
35
+ elsif body['errors']
36
+ first = Array(body['errors']).first
37
+ if first.kind_of? Hash
38
+ ": #{first['message'].chomp}"
39
+ else
40
+ ": #{first.chomp}"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,24 @@
1
+ require 'faraday'
2
+
3
+ # @private
4
+ module Faraday
5
+ # @private
6
+ class Response::RaiseHttp5xx < Response::Middleware
7
+ def on_complete(env)
8
+ case env[:status].to_i
9
+ when 500
10
+ raise Rainmaker::InternalServerError.new(error_message(env, "Internal server error."), env[:response_headers])
11
+ when 502
12
+ raise Rainmaker::BadGateway.new(error_message(env, "Rainmaker is down or being upgraded."), env[:response_headers])
13
+ when 503
14
+ raise Rainmaker::ServiceUnavailable.new(error_message(env, "Service unavailable."), env[:response_headers])
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def error_message(env, body=nil)
21
+ "#{env[:method].to_s.upcase} #{env[:url].to_s}: #{[env[:status].to_s + ':', body].compact.join(' ')} Check http://api.rainmaker.cc/ for updates on the status of the Rainmaker service."
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ require 'rainmaker/connection'
2
+ require 'rainmaker/request'
3
+
4
+ module Rainmaker
5
+ # @private
6
+ class API
7
+ # @private
8
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
9
+
10
+ # Creates a new API
11
+ def initialize(options={})
12
+ options = Rainmaker.options.merge(options)
13
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
14
+ send("#{key}=", options[key])
15
+ end
16
+ end
17
+
18
+ include Connection
19
+ include Request
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ module Rainmaker
2
+ class Client
3
+ module Person
4
+ # Returns extended information for a given email
5
+ #
6
+ def person(email)
7
+ response = get('person', :email => email)
8
+ format.to_s.downcase == 'xml' ? response['person'] : response
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ module Rainmaker
2
+ # Wrapper for the Rainmaker REST API
3
+
4
+ class Client < API
5
+ # Require client method modules after initializing the Client class in
6
+ # order to avoid a superclass mismatch error, allowing those modules to be
7
+ # Client-namespaced.
8
+ require 'rainmaker/client/person'
9
+
10
+ alias :api_endpoint :endpoint
11
+
12
+ include Rainmaker::Client::Person
13
+ end
14
+ end
@@ -0,0 +1,80 @@
1
+ require 'faraday'
2
+
3
+ module Rainmaker
4
+ # Defines constants and methods related to configuration
5
+ module Configuration
6
+ # An array of valid keys in the options hash when configuring a {Rainmaker::API}
7
+ VALID_OPTIONS_KEYS = [
8
+ :adapter,
9
+ :api_key,
10
+ :endpoint,
11
+ :format,
12
+ :gateway,
13
+ :proxy,
14
+ :user_agent].freeze
15
+
16
+ # An array of valid request/response formats
17
+ #
18
+ # @note Not all methods support the XML format.
19
+ VALID_FORMATS = [
20
+ :json,
21
+ :xml].freeze
22
+
23
+ # The adapter that will be used to connect if none is set
24
+ #
25
+ # @note The default faraday adapter is Net::HTTP.
26
+ DEFAULT_ADAPTER = Faraday.default_adapter
27
+
28
+ # By default, don't set an application key
29
+ DEFAULT_API_KEY = nil
30
+
31
+ # The endpoint that will be used to connect if none is set
32
+ #
33
+ DEFAULT_ENDPOINT = 'http://api.rainmaker.cc/v1/'.freeze
34
+
35
+ # The response format appended to the path and sent in the 'Accept' header if none is set
36
+ #
37
+ # @note JSON is preferred over XML because it is more concise and faster to parse.
38
+ DEFAULT_FORMAT = :json
39
+
40
+ # By default, don't use a proxy server
41
+ DEFAULT_PROXY = nil
42
+
43
+ # The user agent that will be sent to the API endpoint if none is set
44
+ DEFAULT_USER_AGENT = "Rainmaker Ruby Gem".freeze
45
+
46
+ DEFAULT_GATEWAY = nil
47
+
48
+ # @private
49
+ attr_accessor *VALID_OPTIONS_KEYS
50
+
51
+ # When this module is extended, set all configuration options to their default values
52
+ def self.extended(base)
53
+ base.reset
54
+ end
55
+
56
+ # Convenience method to allow configuration options to be set in a block
57
+ def configure
58
+ yield self
59
+ end
60
+
61
+ # Create a hash of options and their values
62
+ def options
63
+ options = {}
64
+ VALID_OPTIONS_KEYS.each{|k| options[k] = send(k) }
65
+ options
66
+ end
67
+
68
+ # Reset all configuration options to defaults
69
+ def reset
70
+ self.adapter = DEFAULT_ADAPTER
71
+ self.api_key = DEFAULT_API_KEY
72
+ self.endpoint = DEFAULT_ENDPOINT
73
+ self.format = DEFAULT_FORMAT
74
+ self.proxy = DEFAULT_PROXY
75
+ self.user_agent = DEFAULT_USER_AGENT
76
+ self.gateway = DEFAULT_GATEWAY
77
+ self
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,38 @@
1
+ require 'faraday_middleware'
2
+ require 'faraday/request/gateway'
3
+ require 'faraday/response/raise_http_4xx'
4
+ require 'faraday/response/raise_http_5xx'
5
+
6
+ module Rainmaker
7
+ # @private
8
+ module Connection
9
+ private
10
+
11
+ def connection(raw=false)
12
+ options = {
13
+ :headers => {'Accept' => "application/#{format}", 'User-Agent' => user_agent},
14
+ :proxy => proxy,
15
+ :ssl => {:verify => false},
16
+ :url => api_endpoint,
17
+ }
18
+
19
+ Faraday.new(options) do |builder|
20
+ builder.use Faraday::Request::Multipart
21
+ builder.use Faraday::Request::UrlEncoded
22
+ builder.use Faraday::Request::Gateway, gateway if gateway
23
+ builder.use Faraday::Response::RaiseHttp4xx
24
+ builder.use Faraday::Response::Rashify unless raw
25
+ unless raw
26
+ case format.to_s.downcase
27
+ when 'json'
28
+ builder.use Faraday::Response::ParseJson
29
+ when 'xml'
30
+ builder.use Faraday::Response::ParseXml
31
+ end
32
+ end
33
+ builder.use Faraday::Response::RaiseHttp5xx
34
+ builder.adapter(adapter)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,39 @@
1
+ module Rainmaker
2
+ # Custom error class for rescuing from all Rainmaker errors
3
+ class Error < StandardError
4
+ attr_reader :http_headers
5
+
6
+ def initialize(message, http_headers)
7
+ @http_headers = Hash[http_headers]
8
+ super message
9
+ end
10
+
11
+ def retry_after
12
+ [(ratelimit_reset - Time.now).ceil, 0].max
13
+ end
14
+ end
15
+
16
+ # Raised when Rainmaker returns the HTTP status code 400
17
+ class BadRequest < Error; end
18
+
19
+ # Raised when Rainmaker returns the HTTP status code 401
20
+ class Unauthorized < Error; end
21
+
22
+ # Raised when Rainmaker returns the HTTP status code 403
23
+ class Forbidden < Error; end
24
+
25
+ # Raised when Rainmaker returns the HTTP status code 404
26
+ class NotFound < Error; end
27
+
28
+ # Raised when Rainmaker returns the HTTP status code 422
29
+ class Invalid < Error; end
30
+
31
+ # Raised when Rainmaker returns the HTTP status code 500
32
+ class InternalServerError < Error; end
33
+
34
+ # Raised when Rainmaker returns the HTTP status code 502
35
+ class BadGateway < Error; end
36
+
37
+ # Raised when Rainmaker returns the HTTP status code 503
38
+ class ServiceUnavailable < Error; end
39
+ end
@@ -0,0 +1,24 @@
1
+ module Rainmaker
2
+ # Defines HTTP request methods
3
+ module Request
4
+ # Perform an HTTP GET request
5
+ def get(path, options={}, raw=false)
6
+ request(:get, path, options, raw)
7
+ end
8
+
9
+ private
10
+
11
+ # Perform an HTTP request
12
+ def request(method, path, options, raw=false)
13
+ options[:apiKey] = Rainmaker.options[:api_key]
14
+ response = connection(raw).send(method) do |request|
15
+ request.url(formatted_path(path), options)
16
+ end
17
+ raw ? response : response.body
18
+ end
19
+
20
+ def formatted_path(path)
21
+ [path, format].compact.join('.')
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module Rainmaker
2
+ VERSION = "0.0.1"
3
+ end
data/lib/rainmaker.rb ADDED
@@ -0,0 +1,27 @@
1
+ require "faraday"
2
+ require "faraday_middleware"
3
+ require 'rainmaker/error'
4
+ require 'rainmaker/configuration'
5
+ require 'rainmaker/api'
6
+ require 'rainmaker/client'
7
+
8
+ module Rainmaker
9
+ extend Configuration
10
+
11
+ # Alias for Rainmaker::Client.new
12
+ #
13
+ # @return [Rainmaker::Client]
14
+ def self.client(options={})
15
+ Rainmaker::Client.new(options)
16
+ end
17
+
18
+ # Delegate to Rainmaker::Client
19
+ def self.method_missing(method, *args, &block)
20
+ return super unless client.respond_to?(method)
21
+ client.send(method, *args, &block)
22
+ end
23
+
24
+ def self.respond_to?(method, include_private = false)
25
+ client.respond_to?(method, include_private) || super(method, include_private)
26
+ end
27
+ end
data/rainmaker.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rainmaker/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.add_development_dependency 'maruku', '~> 0.6'
7
+ s.add_development_dependency 'nokogiri', '~> 1.4'
8
+ s.add_development_dependency 'rake', '~> 0.9'
9
+ s.add_development_dependency 'rspec', '~> 2.6'
10
+ s.add_development_dependency 'simplecov', '~> 0.4'
11
+ s.add_development_dependency 'webmock', '~> 1.6'
12
+ s.add_development_dependency 'yard', '~> 0.7'
13
+ s.add_runtime_dependency 'hashie', '~> 1.0.0'
14
+ s.add_runtime_dependency 'faraday', '~> 0.6.1'
15
+ s.add_runtime_dependency 'faraday_middleware', '~> 0.6.3'
16
+ s.add_runtime_dependency 'multi_json', '~> 1.0.0'
17
+ s.add_runtime_dependency 'multi_xml', '~> 0.2.0'
18
+ s.add_runtime_dependency 'rash', '~> 0.3.0'
19
+
20
+ s.author = "Brandon West"
21
+ s.description = %q{A Ruby wrapper for the Rainmaker API}
22
+ s.email = ['brawest@gmail.com']
23
+
24
+ s.post_install_message = '
25
+ -------------------------------------------------------------
26
+ Follow me on Twitter! http://twitter.com/brandonmwest
27
+ -------------------------------------------------------------
28
+
29
+ '
30
+
31
+ s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
32
+ s.files = `git ls-files`.split("\n")
33
+ s.homepage = 'https://github.com/brandonmwest/rainmaker'
34
+ s.name = 'rainmaker'
35
+ s.require_paths = ['lib']
36
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
37
+ s.summary = %q{Ruby wrapper for the Rainmaker API}
38
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
39
+ s.version = Rainmaker::VERSION
40
+ end
@@ -0,0 +1,56 @@
1
+ require 'helper'
2
+ require 'faraday'
3
+ require 'rainmaker'
4
+
5
+ describe Faraday::Response do
6
+ before do
7
+ Rainmaker.configure do |config|
8
+ config.api_key = "api_key"
9
+ end
10
+ @client = Rainmaker::Client.new
11
+ end
12
+
13
+ {
14
+ 400 => Rainmaker::BadRequest,
15
+ 401 => Rainmaker::Unauthorized,
16
+ 403 => Rainmaker::Forbidden,
17
+ 404 => Rainmaker::NotFound,
18
+ 422 => Rainmaker::Invalid,
19
+ 500 => Rainmaker::InternalServerError,
20
+ 502 => Rainmaker::BadGateway,
21
+ 503 => Rainmaker::ServiceUnavailable,
22
+ }.each do |status, exception|
23
+ if (status >= 500)
24
+ context "when HTTP status is #{status}" do
25
+ before do
26
+ stub_get('person.json').
27
+ with(:query => {:apiKey => "api_key", :email => 'brawest@gmail.com'}).
28
+ to_return(:status => status)
29
+ end
30
+
31
+ it "should raise #{exception.name} error" do
32
+ lambda do
33
+ @client.person( 'brawest@gmail.com')
34
+ end.should raise_error(exception)
35
+ end
36
+ end
37
+ else
38
+ [nil, "error", "errors"].each do |body|
39
+ context "when HTTP status is #{status} and body is #{body||='nil'}" do
40
+ before do
41
+ body_message = '{"'+body+'":"test"}' unless body.nil?
42
+ stub_get('person.json').
43
+ with(:query => {:apiKey => "api_key", :email => 'brawest@gmail.com'}).
44
+ to_return(:status => status, :body => body_message)
45
+ end
46
+
47
+ it "should raise #{exception.name} error" do
48
+ lambda do
49
+ @client.person( 'brawest@gmail.com')
50
+ end.should raise_error(exception)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,48 @@
1
+
2
+ {
3
+ "status": 200,
4
+ "photos":
5
+ [
6
+ {
7
+ "url": "http://a0.twimg.com/profile_images/1084241539/steps_normal.jpg",
8
+ "type": "twitter"
9
+ },
10
+ {
11
+ "isPrimary": false,
12
+ "type": "gravatar",
13
+ "url": "https://secure.gravatar.com/avatar/b2f65d319b253da9cf92635d8eac808b"
14
+ },
15
+ {
16
+ "message": "More Data Available - 3rd party credentials required - contact api@rainmaker.cc for more information."
17
+ }
18
+ ],
19
+ "contactInfo": {
20
+ "familyName": "West",
21
+ "givenName": "Brandon",
22
+ "fullName": "Brandon West"
23
+ },
24
+ "demographics": {
25
+ "age": {
26
+ "message": "More Data Available - 3rd party credentials required - contact api@rainmaker.cc for more information."
27
+ },
28
+ "locationGeneral": "Littleton, Colorado",
29
+ "gender": {
30
+ "message": "More Data Available - 3rd party credentials required - contact api@rainmaker.cc for more information."
31
+ }
32
+ },
33
+ "socialProfiles":
34
+ [
35
+ {
36
+ "url": "http://twitter.com/brandonmwest",
37
+ "id": "16517063",
38
+ "type": "twitter",
39
+ "username": "brandonmwest"
40
+ },
41
+ {
42
+ "message": "More Data Available - 3rd party credentials required - contact api@rainmaker.cc for more information."
43
+ },
44
+ {
45
+ "message": "More Data Available - 3rd party credentials required - contact api@rainmaker.cc for more information."
46
+ }
47
+ ]
48
+ }
data/spec/helper.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'rspec'
2
+ require 'webmock/rspec'
3
+ require 'simplecov'
4
+
5
+ SimpleCov.start
6
+
7
+
8
+ def a_get(path)
9
+ a_request(:get, Rainmaker.endpoint + path)
10
+ end
11
+
12
+ def stub_get(path)
13
+ stub_request(:get, Rainmaker.endpoint + path)
14
+ end
15
+
16
+ def fixture_path
17
+ File.expand_path("../fixtures", __FILE__)
18
+ end
19
+
20
+ def fixture(file)
21
+ File.new(fixture_path + '/' + file)
22
+ end
@@ -0,0 +1,110 @@
1
+ require 'helper'
2
+
3
+ describe Rainmaker do
4
+ after do
5
+ Rainmaker.reset
6
+ end
7
+
8
+ context "when delegating to a client" do
9
+
10
+ before do
11
+ Rainmaker.configure do |config|
12
+ config.api_key = "api_key"
13
+ end
14
+
15
+ stub_get("person.json").
16
+ with(:query => {:apiKey => "api_key", :email => "brawest@gmail.com"}).
17
+ to_return(:body => fixture("person.json"), :headers => {:content_type => "application/json; charset=utf-8"})
18
+
19
+ end
20
+
21
+ it "should get the correct resource" do
22
+ Rainmaker.person("brawest@gmail.com")
23
+ a_get("person.json")
24
+ .with(:query => {:apiKey => "api_key", :email => "brawest@gmail.com"})
25
+ .should have_been_made
26
+ end
27
+
28
+ it "should return the same results as a client" do
29
+ Rainmaker.person("brawest@gmail.com").should == Rainmaker::Client.new.person("brawest@gmail.com")
30
+ end
31
+
32
+ end
33
+
34
+ describe '.respond_to?' do
35
+ it 'takes an optional include private argument' do
36
+ Rainmaker.respond_to?(:client, true).should be_true
37
+ end
38
+ end
39
+
40
+ describe ".client" do
41
+ it "should be a Rainmaker::Client" do
42
+ Rainmaker.client.should be_a Rainmaker::Client
43
+ end
44
+ end
45
+
46
+ describe ".adapter" do
47
+ it "should return the default adapter" do
48
+ Rainmaker.adapter.should == Rainmaker::Configuration::DEFAULT_ADAPTER
49
+ end
50
+ end
51
+
52
+ describe ".adapter=" do
53
+ it "should set the adapter" do
54
+ Rainmaker.adapter = :typhoeus
55
+ Rainmaker.adapter.should == :typhoeus
56
+ end
57
+ end
58
+
59
+ describe ".endpoint" do
60
+ it "should return the default endpoint" do
61
+ Rainmaker.endpoint.should == Rainmaker::Configuration::DEFAULT_ENDPOINT
62
+ end
63
+ end
64
+
65
+ describe ".endpoint=" do
66
+ it "should set the endpoint" do
67
+ Rainmaker.endpoint = 'http://tumblr.com/'
68
+ Rainmaker.endpoint.should == 'http://tumblr.com/'
69
+ end
70
+ end
71
+
72
+ describe ".format" do
73
+ it "should return the default format" do
74
+ Rainmaker.format.should == Rainmaker::Configuration::DEFAULT_FORMAT
75
+ end
76
+ end
77
+
78
+ describe ".format=" do
79
+ it "should set the format" do
80
+ Rainmaker.format = 'xml'
81
+ Rainmaker.format.should == 'xml'
82
+ end
83
+ end
84
+
85
+ describe ".user_agent" do
86
+ it "should return the default user agent" do
87
+ Rainmaker.user_agent.should == Rainmaker::Configuration::DEFAULT_USER_AGENT
88
+ end
89
+ end
90
+
91
+ describe ".user_agent=" do
92
+ it "should set the user_agent" do
93
+ Rainmaker.user_agent = 'Custom User Agent'
94
+ Rainmaker.user_agent.should == 'Custom User Agent'
95
+ end
96
+ end
97
+
98
+ describe ".configure" do
99
+
100
+ Rainmaker::Configuration::VALID_OPTIONS_KEYS.each do |key|
101
+
102
+ it "should set the #{key}" do
103
+ Rainmaker.configure do |config|
104
+ config.send("#{key}=", key)
105
+ Rainmaker.send(key).should == key
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,65 @@
1
+ require 'helper'
2
+
3
+ describe Rainmaker::API do
4
+ before do
5
+ @keys = Rainmaker::Configuration::VALID_OPTIONS_KEYS
6
+ end
7
+
8
+ context "with module configuration" do
9
+ before do
10
+ Rainmaker.configure do |config|
11
+ @keys.each do |key|
12
+ config.send("#{key}=", key)
13
+ end
14
+ end
15
+ end
16
+
17
+ after do
18
+ Rainmaker.reset
19
+ end
20
+
21
+ it "should inherit module configuration" do
22
+ api = Rainmaker::API.new
23
+ @keys.each do |key|
24
+ api.send(key).should == key
25
+ end
26
+ end
27
+
28
+ context "with class configuration" do
29
+
30
+ before do
31
+ @configuration = {
32
+ :api_key => 'api_key',
33
+ :adapter => :typhoeus,
34
+ :endpoint => 'http://tumblr.com/',
35
+ :gateway => 'apigee-1111.apigee.com',
36
+ :format => :xml,
37
+ :proxy => 'http://erik:sekret@proxy.example.com:8080',
38
+ :user_agent => 'Custom User Agent',
39
+ }
40
+ end
41
+
42
+ context "during initialization"
43
+
44
+ it "should override module configuration" do
45
+ api = Rainmaker::API.new(@configuration)
46
+ @keys.each do |key|
47
+ api.send(key).should == @configuration[key]
48
+ end
49
+ end
50
+
51
+ context "after initilization" do
52
+
53
+ it "should override module configuration after initialization" do
54
+ api = Rainmaker::API.new
55
+ @configuration.each do |key, value|
56
+ api.send("#{key}=", value)
57
+ end
58
+ @keys.each do |key|
59
+ api.send(key).should == @configuration[key]
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,12 @@
1
+ require 'helper'
2
+
3
+ describe Rainmaker::Client do
4
+ Rainmaker::Configuration::VALID_FORMATS.each do |format|
5
+ context ".new(:format => '#{format}')" do
6
+ before do
7
+ @client = Rainmaker::Client.new(:format => format, :api_key => 'api_key')
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ require 'helper'
2
+
3
+ describe Rainmaker::Client do
4
+ it "should connect using the endpoint configuration" do
5
+ client = Rainmaker::Client.new
6
+ endpoint = URI.parse(client.api_endpoint)
7
+ connection = client.send(:connection).build_url(nil).to_s
8
+ connection.should == endpoint.to_s
9
+ end
10
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,250 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rainmaker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brandon West
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-05-31 00:00:00.000000000 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: maruku
17
+ requirement: &11140308 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '0.6'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *11140308
26
+ - !ruby/object:Gem::Dependency
27
+ name: nokogiri
28
+ requirement: &11140008 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.4'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *11140008
37
+ - !ruby/object:Gem::Dependency
38
+ name: rake
39
+ requirement: &11139732 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: '0.9'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *11139732
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: &11139456 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '2.6'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *11139456
59
+ - !ruby/object:Gem::Dependency
60
+ name: simplecov
61
+ requirement: &11139180 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: '0.4'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *11139180
70
+ - !ruby/object:Gem::Dependency
71
+ name: webmock
72
+ requirement: &11138904 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '1.6'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *11138904
81
+ - !ruby/object:Gem::Dependency
82
+ name: yard
83
+ requirement: &11138628 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ version: '0.7'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: *11138628
92
+ - !ruby/object:Gem::Dependency
93
+ name: hashie
94
+ requirement: &11138352 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ~>
98
+ - !ruby/object:Gem::Version
99
+ version: 1.0.0
100
+ type: :runtime
101
+ prerelease: false
102
+ version_requirements: *11138352
103
+ - !ruby/object:Gem::Dependency
104
+ name: faraday
105
+ requirement: &11138076 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 0.6.1
111
+ type: :runtime
112
+ prerelease: false
113
+ version_requirements: *11138076
114
+ - !ruby/object:Gem::Dependency
115
+ name: faraday_middleware
116
+ requirement: &11137800 !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ~>
120
+ - !ruby/object:Gem::Version
121
+ version: 0.6.3
122
+ type: :runtime
123
+ prerelease: false
124
+ version_requirements: *11137800
125
+ - !ruby/object:Gem::Dependency
126
+ name: multi_json
127
+ requirement: &11137524 !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ~>
131
+ - !ruby/object:Gem::Version
132
+ version: 1.0.0
133
+ type: :runtime
134
+ prerelease: false
135
+ version_requirements: *11137524
136
+ - !ruby/object:Gem::Dependency
137
+ name: multi_xml
138
+ requirement: &11137248 !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ~>
142
+ - !ruby/object:Gem::Version
143
+ version: 0.2.0
144
+ type: :runtime
145
+ prerelease: false
146
+ version_requirements: *11137248
147
+ - !ruby/object:Gem::Dependency
148
+ name: rash
149
+ requirement: &11136972 !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ~>
153
+ - !ruby/object:Gem::Version
154
+ version: 0.3.0
155
+ type: :runtime
156
+ prerelease: false
157
+ version_requirements: *11136972
158
+ description: A Ruby wrapper for the Rainmaker API
159
+ email:
160
+ - brawest@gmail.com
161
+ executables: []
162
+ extensions: []
163
+ extra_rdoc_files: []
164
+ files:
165
+ - .document
166
+ - .gitignore
167
+ - .rspec
168
+ - Gemfile
169
+ - LICENSE.md
170
+ - README.md
171
+ - Rakefile
172
+ - VERSION
173
+ - lib/faraday/request/gateway.rb
174
+ - lib/faraday/response/raise_http_4xx.rb
175
+ - lib/faraday/response/raise_http_5xx.rb
176
+ - lib/rainmaker.rb
177
+ - lib/rainmaker/api.rb
178
+ - lib/rainmaker/client.rb
179
+ - lib/rainmaker/client/person.rb
180
+ - lib/rainmaker/configuration.rb
181
+ - lib/rainmaker/connection.rb
182
+ - lib/rainmaker/error.rb
183
+ - lib/rainmaker/request.rb
184
+ - lib/rainmaker/version.rb
185
+ - rainmaker.gemspec
186
+ - spec/faraday/response_spec.rb
187
+ - spec/fixtures/person.json
188
+ - spec/helper.rb
189
+ - spec/rainmaker_spec.rb
190
+ - spec/ruby_rainmaker/api_spec.rb
191
+ - spec/ruby_rainmaker/client/person_spec.rb
192
+ - spec/ruby_rainmaker/client_spec.rb
193
+ - vendor/cache/addressable-2.2.6.gem
194
+ - vendor/cache/crack-0.1.8.gem
195
+ - vendor/cache/diff-lcs-1.1.2.gem
196
+ - vendor/cache/faraday-0.6.1.gem
197
+ - vendor/cache/faraday_middleware-0.6.3.gem
198
+ - vendor/cache/hashie-1.0.0.gem
199
+ - vendor/cache/maruku-0.6.0.gem
200
+ - vendor/cache/multi_json-1.0.3.gem
201
+ - vendor/cache/multi_xml-0.2.2.gem
202
+ - vendor/cache/multipart-post-1.1.2.gem
203
+ - vendor/cache/nokogiri-1.4.4.1-x86-mingw32.gem
204
+ - vendor/cache/rack-1.3.0.gem
205
+ - vendor/cache/rake-0.9.0.gem
206
+ - vendor/cache/rash-0.3.0.gem
207
+ - vendor/cache/rspec-2.6.0.gem
208
+ - vendor/cache/rspec-core-2.6.3.gem
209
+ - vendor/cache/rspec-expectations-2.6.0.gem
210
+ - vendor/cache/rspec-mocks-2.6.0.gem
211
+ - vendor/cache/simplecov-0.4.2.gem
212
+ - vendor/cache/simplecov-html-0.4.5.gem
213
+ - vendor/cache/syntax-1.0.0.gem
214
+ - vendor/cache/webmock-1.6.4.gem
215
+ - vendor/cache/yard-0.7.1.gem
216
+ has_rdoc: true
217
+ homepage: https://github.com/brandonmwest/rainmaker
218
+ licenses: []
219
+ post_install_message: ! '
220
+
221
+ -------------------------------------------------------------
222
+
223
+ Follow me on Twitter! http://twitter.com/brandonmwest
224
+
225
+ -------------------------------------------------------------
226
+
227
+
228
+ '
229
+ rdoc_options: []
230
+ require_paths:
231
+ - lib
232
+ required_ruby_version: !ruby/object:Gem::Requirement
233
+ none: false
234
+ requirements:
235
+ - - ! '>='
236
+ - !ruby/object:Gem::Version
237
+ version: '0'
238
+ required_rubygems_version: !ruby/object:Gem::Requirement
239
+ none: false
240
+ requirements:
241
+ - - ! '>='
242
+ - !ruby/object:Gem::Version
243
+ version: 1.3.6
244
+ requirements: []
245
+ rubyforge_project:
246
+ rubygems_version: 1.5.2
247
+ signing_key:
248
+ specification_version: 3
249
+ summary: Ruby wrapper for the Rainmaker API
250
+ test_files: []