wishsimple 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,6 @@
1
+ History
2
+ =======
3
+
4
+ 0.0.1 - June 14, 2012
5
+ ---------------------
6
+ Initial release
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Shaun Chapman and WishSimple, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,99 @@
1
+ WishSimple
2
+ ==========
3
+ Ruby wrapper for the WishSimple API
4
+
5
+ WishSimple provides gift recommendations as a service. It's currently in
6
+ private beta and you can request an API key [here](http://wishsimple.com/).
7
+
8
+ Installation
9
+ ------------
10
+ gem install wishsimple
11
+
12
+ Authentication
13
+ --------------
14
+ If you're using Rails, you may want to add the following to
15
+ `config/initializers/wishsimple.rb`:
16
+
17
+ ``` ruby
18
+ WishSimple.configure do |config|
19
+ config.api_key = '<your API key>'
20
+ end
21
+ ```
22
+
23
+ You can also set the key directly:
24
+
25
+ ``` ruby
26
+ WishSimple.api_key = '<your API key>'
27
+ ```
28
+
29
+ Usage
30
+ -----
31
+ WishSimple uses a Facebook user's interactions with products to generate gift
32
+ recommendations. Currently, only purchases are supported, though more types of
33
+ interactions will be supported in the near future (e.g. ratings, adding to a
34
+ wish list, etc.).
35
+
36
+ To begin, you'll need the following data:
37
+
38
+ * `facebook_uid` - The Facebook user's numerical UID
39
+ * `access_token` - The Facebook user's OAuth access token (see "Permissions" below)
40
+ * `product_uid` - Whatever you use to identify the product; usually the database ID
41
+
42
+ Recording a purchase is as easy as:
43
+
44
+ ``` ruby
45
+ user = WishSimple::User.create(facebook_uid, access_token)
46
+ product = WishSimple::Product.create(product_uid)
47
+ user.purchase!(product)
48
+ ```
49
+
50
+ You can interact with objects as you would expect:
51
+
52
+ ``` ruby
53
+ user = WishSimple::User.new(facebook_uid)
54
+ user.access_token = access_token
55
+ user.save
56
+
57
+ purchase = WishSimple::Purchase.new
58
+ purchase.user = user
59
+ purchase.product = product
60
+ purchase.save
61
+ ```
62
+
63
+ You can delete data like so:
64
+
65
+ ``` ruby
66
+ # Purchases
67
+ purchase = WishSimple::Purchase.new(user: user, product: product)
68
+ purchase.destroy
69
+
70
+ # Users (this will also delete the user's purchases)
71
+ user = WishSimple::User.new(facebook_uid)
72
+ user.destroy
73
+
74
+ # Products (this will also delete the product's purchases)
75
+ product = WishSimple::Product.new(product_uid)
76
+ product.destroy
77
+ ```
78
+
79
+ Permissions
80
+ -----------
81
+ You'll want to request the following Facebook permissions when generating the
82
+ access token:
83
+
84
+ `user_birthday`, `user_interests`, `user_likes`
85
+
86
+ Gift Recommendations
87
+ --------------------
88
+ Here's a funny riddle:
89
+
90
+ **Q:** *What kind of gift recommendation service doesn't actually have the
91
+ ability to request the gift recommendations?*
92
+ **A:** *One that's in private beta.*
93
+
94
+ Okay, that was terrible, but jokes aside, we're working hard to make the gift
95
+ recommendations awesome. You can expect them soon.
96
+
97
+ Copyright
98
+ ---------
99
+ Copyright (c) 2012 Shaun Chapman and WishSimple, Inc. See LICENSE for details.
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rake
2
+
3
+ # Bundler
4
+ require 'bundler/gem_tasks'
5
+
6
+ # RSpec
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new(:spec)
9
+ task :default => :spec
10
+ task :test => :spec
@@ -0,0 +1,88 @@
1
+ require 'faraday'
2
+
3
+ require 'wishsimple/action'
4
+ require 'wishsimple/configuration'
5
+ require 'wishsimple/product'
6
+ require 'wishsimple/response/raise_error'
7
+ require 'wishsimple/user'
8
+
9
+ module WishSimple
10
+ extend Configuration
11
+
12
+ class << self
13
+ # Accepts (api_key, [options]) or (options) as parameters
14
+ def new(*args)
15
+ options = {}
16
+
17
+ # TODO: Raise an error when params don't match (string, [hash]) or (hash)
18
+ if args[0].is_a? String
19
+ options[:api_key] = args[0]
20
+ options.merge!(args[1]) if args[1].is_a? Hash
21
+ elsif args[0].is_a? Hash
22
+ options = args[0]
23
+ end
24
+
25
+ Configuration::OPTIONS_KEYS.each do |key|
26
+ send("#{key}=", options[key])
27
+ end
28
+ end
29
+
30
+ # Perform an HTTP GET request
31
+ def get(path, params={})
32
+ request(:get, path, params)
33
+ end
34
+
35
+ # Perform an HTTP PUT request
36
+ def put(path, params={})
37
+ request(:put, path, params)
38
+ end
39
+
40
+ # Perform an HTTP DELETE request
41
+ def delete(path, params={})
42
+ request(:delete, path, params)
43
+ end
44
+
45
+ # Converts a path into a full API URL
46
+ def request_url(path)
47
+ endpoint + request_path(path)
48
+ end
49
+
50
+ # Converts a resource path into a full API path with API version
51
+ def request_path(path)
52
+ "/#{api_version}#{path}"
53
+ end
54
+
55
+ private
56
+ def connection
57
+ default_options = {
58
+ headers: {
59
+ accept: 'application/json',
60
+ authorization: "Token #{api_key}",
61
+ user_agent: user_agent,
62
+ },
63
+ ssl: {verify: false},
64
+ url: endpoint,
65
+ }
66
+
67
+ Faraday.new(default_options) do |builder|
68
+ builder.use WishSimple::Response::RaiseError
69
+ builder.request(:url_encoded)
70
+ builder.adapter(adapter)
71
+ end
72
+ end
73
+
74
+ # Perform an HTTP request
75
+ def request(method, path, params={})
76
+ path = request_path(path)
77
+ connection.run_request(method, nil, nil, nil) do |request|
78
+ case method.to_sym
79
+ when :delete, :get
80
+ request.url(path, params)
81
+ when :put
82
+ request.path = path
83
+ request.body = params unless params.empty?
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,33 @@
1
+ require 'wishsimple/resource'
2
+
3
+ module WishSimple
4
+ class Action < Resource
5
+ attr_accessor :user, :product
6
+
7
+ def self.verb
8
+ name.split('::')[-1].downcase.to_sym
9
+ end
10
+
11
+ def initialize(attrs={})
12
+ self.user = attrs[:user]
13
+ self.product = attrs[:product]
14
+ end
15
+
16
+ def ==(other)
17
+ super || (
18
+ other.class == self.class \
19
+ && other.user == self.user \
20
+ && other.product == self.product
21
+ )
22
+ end
23
+
24
+ protected
25
+ def path
26
+ "/users/#{user.facebook_uid}/products/#{product.uid}/#{self.class.verb}"
27
+ end
28
+
29
+ def params; {}; end
30
+ end
31
+ end
32
+
33
+ require 'wishsimple/action/purchase'
@@ -0,0 +1,5 @@
1
+ require 'wishsimple/action'
2
+
3
+ module WishSimple
4
+ class Purchase < Action; end
5
+ end
@@ -0,0 +1,43 @@
1
+ require 'wishsimple/version'
2
+
3
+ module WishSimple
4
+ module Configuration
5
+ DEFAULT_ADAPTER = Faraday.default_adapter
6
+ DEFAULT_API_KEY = nil
7
+ DEFAULT_API_VERSION = 'v1'
8
+ DEFAULT_ENDPOINT = 'https://api.wishsimple.com'
9
+ DEFAULT_USER_AGENT = "WishSimple Ruby Gem #{WishSimple::VERSION}"
10
+
11
+ OPTIONS_KEYS = [
12
+ :adapter,
13
+ :api_key,
14
+ :api_version,
15
+ :endpoint,
16
+ :user_agent,
17
+ ]
18
+
19
+ attr_accessor *OPTIONS_KEYS
20
+
21
+ def self.extended(base)
22
+ base.reset
23
+ end
24
+
25
+ def configure
26
+ yield self
27
+ true
28
+ end
29
+
30
+ def options
31
+ options = {}
32
+ OPTIONS_KEYS.each{|k| options[k] = send(k)}
33
+ options
34
+ end
35
+
36
+ def reset
37
+ OPTIONS_KEYS.each do |key|
38
+ send("#{key}=", eval("DEFAULT_#{key.upcase}"))
39
+ end
40
+ self
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,19 @@
1
+ module WishSimple
2
+ class Error < StandardError; end
3
+ class Error::ClientError < Error; end
4
+ class Error::ServerError < Error; end
5
+
6
+ # Client Errors
7
+ class Error::BadRequest < Error::ClientError; end # 400
8
+ class Error::Unauthorized < Error::ClientError; end # 401
9
+ class Error::Forbidden < Error::ClientError; end # 403
10
+ class Error::NotFound < Error::ClientError; end # 404
11
+ class Error::NotAcceptable < Error::ClientError; end # 406
12
+ class Error::UnprocessableEntity < Error::ClientError; end # 422
13
+
14
+ # Server Errors
15
+ class Error::InternalServerError < Error::ServerError; end # 500
16
+ class Error::NotImplemented < Error::ServerError; end # 501
17
+ class Error::BadGateway < Error::ServerError; end # 502
18
+ class Error::ServiceUnavailable < Error::ServerError; end # 503
19
+ end
@@ -0,0 +1,23 @@
1
+ require 'wishsimple/resource'
2
+
3
+ module WishSimple
4
+ class Product < Resource
5
+ ATTRS = [:uid]
6
+ attr_accessor *ATTRS
7
+
8
+ def initialize(uid)
9
+ self.uid = uid.to_s
10
+ end
11
+
12
+ def ==(other)
13
+ super || (other.class == self.class && other.uid == self.uid)
14
+ end
15
+
16
+ protected
17
+ def path
18
+ "/products/#{uid}"
19
+ end
20
+
21
+ def params; {}; end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ require 'multi_json'
2
+
3
+ module WishSimple
4
+ class Resource
5
+ ATTRS = []
6
+ attr_reader :created_at
7
+
8
+ def self.create(*args)
9
+ new(*args).save
10
+ end
11
+
12
+ def save
13
+ response = WishSimple.put(path, params)
14
+ response.success? ? build_from_response(response) : self
15
+ end
16
+
17
+ def destroy
18
+ WishSimple.delete(path)
19
+ self
20
+ end
21
+
22
+ protected
23
+ def build_from_response(response)
24
+ if response.body && response.body.is_a?(String)
25
+ body = MultiJson.load(response.body, symbolize_keys: true)
26
+ @created_at = Time.at(body.delete(:created_at))
27
+ ATTRS.each {|k| send("#{k}=", body[k])}
28
+ end
29
+
30
+ self
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ require 'faraday'
2
+ require 'multi_json'
3
+ require 'wishsimple/error'
4
+
5
+ module WishSimple
6
+ module Response
7
+ class RaiseError < Faraday::Response::Middleware
8
+ def on_complete(response)
9
+ case response[:status].to_i
10
+ when 400
11
+ raise WishSimple::Error::BadRequest, error_message(response)
12
+ when 401
13
+ raise WishSimple::Error::Unauthorized, error_message(response)
14
+ when 403
15
+ raise WishSimple::Error::Forbidden, error_message(response)
16
+ when 404
17
+ raise WishSimple::Error::NotFound, error_message(response)
18
+ when 406
19
+ raise WishSimple::Error::NotAcceptable, error_message(response)
20
+ when 422
21
+ raise WishSimple::Error::UnprocessableEntity, error_message(response)
22
+ when 500
23
+ raise WishSimple::Error::InternalServerError, error_message(response)
24
+ when 501
25
+ raise WishSimple::Error::NotImplemented, error_message(response)
26
+ when 502
27
+ raise WishSimple::Error::BadGateway, error_message(response)
28
+ when 503
29
+ raise WishSimple::Error::ServiceUnavailable, error_message(response)
30
+ end
31
+ end
32
+
33
+ def error_message(response)
34
+ if response[:body] && response[:body].is_a?(String)
35
+ body = MultiJson.load(response[:body], symbolize_keys: true)
36
+ body[:error] || ''
37
+ else
38
+ ''
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,31 @@
1
+ require 'wishsimple/resource'
2
+
3
+ module WishSimple
4
+ class User < Resource
5
+ ATTRS = [:facebook_uid, :access_token]
6
+ attr_accessor *ATTRS
7
+
8
+ def initialize(facebook_uid, access_token=nil)
9
+ self.facebook_uid = facebook_uid
10
+ self.access_token = access_token
11
+ end
12
+
13
+ def ==(other)
14
+ super || (other.class == self.class && other.facebook_uid == self.facebook_uid)
15
+ end
16
+
17
+ # Actions
18
+ def purchase!(product)
19
+ WishSimple::Purchase.create(user: self, product: product)
20
+ end
21
+
22
+ protected
23
+ def path
24
+ "/users/#{facebook_uid}"
25
+ end
26
+
27
+ def params
28
+ {access_token: access_token}
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module WishSimple
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Faraday::Response do
4
+ {
5
+ 400 => WishSimple::Error::BadRequest,
6
+ 401 => WishSimple::Error::Unauthorized,
7
+ 403 => WishSimple::Error::Forbidden,
8
+ 404 => WishSimple::Error::NotFound,
9
+ 406 => WishSimple::Error::NotAcceptable,
10
+ 422 => WishSimple::Error::UnprocessableEntity,
11
+ 500 => WishSimple::Error::InternalServerError,
12
+ 501 => WishSimple::Error::NotImplemented,
13
+ 502 => WishSimple::Error::BadGateway,
14
+ 503 => WishSimple::Error::ServiceUnavailable,
15
+ }.each do |status, exception|
16
+ context "when HTTP status is #{status}" do
17
+ before do
18
+ # TODO: Create more specific error fixtures
19
+ stub_put('/products/94043').to_return({
20
+ status: status,
21
+ body: fixture('error/generic.json'),
22
+ })
23
+ end
24
+
25
+ it "should raise #{exception.name}" do
26
+ lambda do
27
+ WishSimple::Product.create('94043')
28
+ end.should raise_error(exception)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1 @@
1
+ {"created_at":519868800}
@@ -0,0 +1 @@
1
+ {"error":"An error occurred."}
@@ -0,0 +1 @@
1
+ {"uid":"94043","created_at":519868800}
@@ -0,0 +1 @@
1
+ {"facebook_uid":"shaunchapman","access_token":"fake-access-token","created_at":519868800}
@@ -0,0 +1,39 @@
1
+ require 'wishsimple'
2
+ require 'rspec'
3
+ require 'webmock/rspec'
4
+
5
+ RSpec.configure do |config|
6
+ config.color_enabled = true
7
+ end
8
+
9
+ def a_get(path)
10
+ a_request(:get, WishSimple.request_url(path))
11
+ end
12
+
13
+ def a_put(path)
14
+ a_request(:put, WishSimple.request_url(path))
15
+ end
16
+
17
+ def a_delete(path)
18
+ a_request(:delete, WishSimple.request_url(path))
19
+ end
20
+
21
+ def stub_get(path)
22
+ stub_request(:get, WishSimple.request_url(path))
23
+ end
24
+
25
+ def stub_put(path)
26
+ stub_request(:put, WishSimple.request_url(path))
27
+ end
28
+
29
+ def stub_delete(path)
30
+ stub_request(:delete, WishSimple.request_url(path))
31
+ end
32
+
33
+ def fixture_path
34
+ File.expand_path('../fixtures', __FILE__)
35
+ end
36
+
37
+ def fixture(file)
38
+ File.new(File.join(fixture_path, file))
39
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe WishSimple::Purchase do
4
+ before do
5
+ @user = WishSimple::User.new('shaunchapman')
6
+ @product = WishSimple::Product.new('94043')
7
+ end
8
+
9
+ describe '.new' do
10
+ it 'sets the user and product' do
11
+ purchase = WishSimple::Purchase.new(user: @user, product: @product)
12
+ purchase.user.should == @user
13
+ purchase.product.should == @product
14
+ end
15
+ end
16
+
17
+ describe '.verb' do
18
+ it 'sets the verb from the class name' do
19
+ WishSimple::Purchase.verb.should == :purchase
20
+ end
21
+ end
22
+
23
+ describe '.create' do
24
+ before do
25
+ stub_put('/users/shaunchapman/products/94043/purchase').
26
+ to_return(body: fixture('action/purchase.json'))
27
+ end
28
+
29
+ it 'makes a put request to create the purchase' do
30
+ WishSimple::Purchase.create(user: @user, product: @product)
31
+ a_put('/users/shaunchapman/products/94043/purchase').should have_been_made
32
+ end
33
+ end
34
+
35
+ describe '#save' do
36
+ before do
37
+ stub_put('/users/shaunchapman/products/94043/purchase').
38
+ to_return(body: fixture('action/purchase.json'))
39
+ end
40
+
41
+ it 'makes a put request to save the purchase' do
42
+ purchase = WishSimple::Purchase.new(user: @user, product: @product)
43
+ purchase.save
44
+ a_put('/users/shaunchapman/products/94043/purchase').should have_been_made
45
+ end
46
+ end
47
+
48
+ describe '#destroy' do
49
+ before do
50
+ stub_delete('/users/shaunchapman/products/94043/purchase').
51
+ to_return(status: 204)
52
+ end
53
+
54
+ it 'makes a delete request to destroy the purchase' do
55
+ purchase = WishSimple::Purchase.new(user: @user, product: @product)
56
+ purchase.destroy
57
+ a_delete('/users/shaunchapman/products/94043/purchase').
58
+ should have_been_made
59
+ end
60
+ end
61
+
62
+ describe '#build_from_response' do
63
+ before do
64
+ stub_put('/users/shaunchapman/products/94043/purchase').
65
+ to_return(body: fixture('action/purchase.json'))
66
+ end
67
+
68
+ it 'sets created_at from the response' do
69
+ purchase = WishSimple::Purchase.create(user: @user, product: @product)
70
+ purchase.created_at.should == Time.at(519868800)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe WishSimple::Product do
4
+ it 'defines attribute accessors' do
5
+ product = WishSimple::Product.new('94043')
6
+
7
+ [:uid].each do |attribute|
8
+ product.should respond_to("#{attribute}=")
9
+ product.should respond_to(attribute)
10
+ end
11
+ end
12
+
13
+ describe '.new' do
14
+ it 'sets the uid' do
15
+ product = WishSimple::Product.new('94043')
16
+ product.uid.should == '94043'
17
+ end
18
+
19
+ it 'typecasts the uid to string' do
20
+ product = WishSimple::Product.new(94043)
21
+ product.uid.should be_a(String)
22
+ end
23
+ end
24
+
25
+ describe '.create' do
26
+ before do
27
+ stub_put('/products/94043').to_return(body: fixture('product.json'))
28
+ end
29
+
30
+ it 'makes a put request to save the product' do
31
+ WishSimple::Product.create('94043')
32
+ a_put('/products/94043').should have_been_made
33
+ end
34
+ end
35
+
36
+ describe '#save' do
37
+ before do
38
+ stub_put('/products/94043').to_return(body: fixture('product.json'))
39
+ end
40
+
41
+ it 'makes a put request to save the product' do
42
+ product = WishSimple::Product.new('94043')
43
+ product.save
44
+ a_put('/products/94043').should have_been_made
45
+ end
46
+ end
47
+
48
+ describe '#destroy' do
49
+ before do
50
+ stub_delete('/products/94043').to_return(status: 204)
51
+ end
52
+
53
+ it 'makes a delete request to destroy the product' do
54
+ product = WishSimple::Product.new('94043')
55
+ product.destroy
56
+ a_delete('/products/94043').should have_been_made
57
+ end
58
+ end
59
+
60
+ describe '#build_from_response' do
61
+ before do
62
+ stub_put('/products/94043').to_return(body: fixture('product.json'))
63
+ end
64
+
65
+ it 'sets created_at from the response' do
66
+ product = WishSimple::Product.create('94043')
67
+ product.created_at.should == Time.at(519868800)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ describe WishSimple::User do
4
+ it 'defines attribute accessors' do
5
+ user = WishSimple::User.new('shaunchapman')
6
+
7
+ [:facebook_uid, :access_token].each do |attribute|
8
+ user.should respond_to("#{attribute}=")
9
+ user.should respond_to(attribute)
10
+ end
11
+ end
12
+
13
+ describe '.new' do
14
+ it 'sets the facebook_uid and access_token' do
15
+ user = WishSimple::User.new('shaunchapman', 'fake-access-token')
16
+ user.facebook_uid.should == 'shaunchapman'
17
+ user.access_token.should == 'fake-access-token'
18
+ end
19
+ end
20
+
21
+ describe '.create' do
22
+ before do
23
+ stub_put('/users/shaunchapman').to_return(body: fixture('user.json'))
24
+ end
25
+
26
+ it 'makes a put request to create the user' do
27
+ WishSimple::User.create('shaunchapman', 'fake-access-token')
28
+ a_put('/users/shaunchapman').
29
+ with(body: {access_token: 'fake-access-token'}).
30
+ should have_been_made
31
+ end
32
+ end
33
+
34
+ describe '#save' do
35
+ before do
36
+ stub_put('/users/shaunchapman').to_return(body: fixture('user.json'))
37
+ end
38
+
39
+ it 'makes a put request to save the user' do
40
+ user = WishSimple::User.new('shaunchapman', 'fake-access-token')
41
+ user.save
42
+ a_put('/users/shaunchapman').
43
+ with(body: {access_token: 'fake-access-token'}).
44
+ should have_been_made
45
+ end
46
+ end
47
+
48
+ describe '#destroy' do
49
+ before do
50
+ stub_delete('/users/shaunchapman').to_return(status: 204)
51
+ end
52
+
53
+ it 'makes a delete request to destroy the user' do
54
+ user = WishSimple::User.new('shaunchapman')
55
+ user.destroy
56
+ a_delete('/users/shaunchapman').should have_been_made
57
+ end
58
+ end
59
+
60
+ describe '#purchase!' do
61
+ before do
62
+ stub_put('/users/shaunchapman/products/94043/purchase').
63
+ to_return(body: fixture('action/purchase.json'))
64
+ end
65
+
66
+ it 'makes a put request to create the purchase' do
67
+ user = WishSimple::User.new('shaunchapman', 'fake-access-token')
68
+ product = WishSimple::Product.new('94043')
69
+ user.purchase!(product)
70
+ a_put('/users/shaunchapman/products/94043/purchase').should have_been_made
71
+ end
72
+ end
73
+
74
+ describe '#build_from_response' do
75
+ before do
76
+ stub_put('/users/shaunchapman').to_return(body: fixture('user.json'))
77
+ end
78
+
79
+ it 'sets created_at from the response' do
80
+ user = WishSimple::User.create('shaunchapman')
81
+ user.created_at.should == Time.at(519868800)
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe WishSimple do
4
+ before do
5
+ @options_keys = WishSimple::Configuration::OPTIONS_KEYS
6
+ @test_options = {
7
+ :adapter => :fake_adapter,
8
+ :api_key => 'fake-api-key',
9
+ :api_version => 'v3',
10
+ :endpoint => 'http://example.com',
11
+ :user_agent => 'Fake User Agent'
12
+ }
13
+ end
14
+
15
+ after do
16
+ WishSimple.reset
17
+ end
18
+
19
+ # TODO: Write tests to handle authentication errors
20
+ describe '.configure' do
21
+ it 'should set the options' do
22
+ WishSimple.configure do |c|
23
+ @options_keys.each do |key|
24
+ c.send("#{key}=", @test_options[key])
25
+ end
26
+ end
27
+
28
+ # Assert that all options were set
29
+ @options_keys.each do |key|
30
+ WishSimple.send(key).should == @test_options[key]
31
+ end
32
+ end
33
+ end
34
+
35
+ describe '.reset' do
36
+ before do
37
+ # Set all options using the instance variables in the "before" block
38
+ WishSimple.configure do |c|
39
+ @options_keys.each do |key|
40
+ c.send("#{key}=", @test_options[key])
41
+ end
42
+ end
43
+ end
44
+
45
+ it 'should reset the options' do
46
+ WishSimple.reset
47
+ @options_keys.each do |key|
48
+ WishSimple.send(key).should == WishSimple::Configuration.const_get("DEFAULT_#{key.upcase}")
49
+ end
50
+ end
51
+ end
52
+
53
+ describe '.adapter' do
54
+ it 'should return the default adapter' do
55
+ WishSimple.adapter.should == WishSimple::Configuration::DEFAULT_ADAPTER
56
+ end
57
+ end
58
+
59
+ describe '.adapter=' do
60
+ it 'should set the adapter' do
61
+ WishSimple.adapter = @test_options[:adapter]
62
+ WishSimple.adapter.should == @test_options[:adapter]
63
+ end
64
+ end
65
+
66
+ describe '.api_key' do
67
+ it 'should return the default api_key' do
68
+ WishSimple.api_key.should == WishSimple::Configuration::DEFAULT_API_KEY
69
+ end
70
+ end
71
+
72
+ describe '.api_key=' do
73
+ it 'should set the api_key' do
74
+ WishSimple.api_key = @test_options[:api_key]
75
+ WishSimple.api_key.should == @test_options[:api_key]
76
+ end
77
+ end
78
+
79
+ describe '.api_version' do
80
+ it 'should return the default api_version' do
81
+ WishSimple.api_version.should == WishSimple::Configuration::DEFAULT_API_VERSION
82
+ end
83
+ end
84
+
85
+ describe '.api_version=' do
86
+ it 'should set the api_version' do
87
+ WishSimple.api_version = @test_options[:api_version]
88
+ WishSimple.api_version.should == @test_options[:api_version]
89
+ end
90
+ end
91
+
92
+ describe '.endpoint' do
93
+ it 'should return the default endpoint' do
94
+ WishSimple.endpoint.should == WishSimple::Configuration::DEFAULT_ENDPOINT
95
+ end
96
+ end
97
+
98
+ describe '.endpoint=' do
99
+ it 'should set the endpoint' do
100
+ WishSimple.endpoint = @test_options[:endpoint]
101
+ WishSimple.endpoint.should == @test_options[:endpoint]
102
+ end
103
+ end
104
+
105
+ describe '.user_agent' do
106
+ it 'should return the default user_agent' do
107
+ WishSimple.user_agent.should == WishSimple::Configuration::DEFAULT_USER_AGENT
108
+ end
109
+ end
110
+
111
+ describe '.user_agent=' do
112
+ it 'should set the user_agent' do
113
+ WishSimple.user_agent = @test_options[:user_agent]
114
+ WishSimple.user_agent.should == @test_options[:user_agent]
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path('../lib/wishsimple/version', __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'wishsimple'
5
+ gem.version = WishSimple::VERSION
6
+
7
+ gem.authors = ['Shaun Chapman']
8
+ gem.email = ['shaun@wishsimple.com']
9
+ gem.description = %q{Ruby wrapper for the WishSimple API}
10
+ gem.summary = %q{WishSimple API Ruby wrapper}
11
+ gem.homepage = 'https://github.com/wishsimple/wishsimple-ruby'
12
+
13
+ # Dependencies
14
+ gem.add_dependency 'faraday', '~> 0.8'
15
+ gem.add_dependency 'multi_json', '~> 1.3'
16
+ gem.add_development_dependency 'json'
17
+ gem.add_development_dependency 'rake'
18
+ gem.add_development_dependency 'rspec'
19
+ gem.add_development_dependency 'webmock'
20
+
21
+ gem.files = `git ls-files`.split($\)
22
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
23
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
24
+ gem.require_paths = ['lib']
25
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wishsimple
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Shaun Chapman
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-15 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: &70297423868280 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '0.8'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70297423868280
25
+ - !ruby/object:Gem::Dependency
26
+ name: multi_json
27
+ requirement: &70297423867760 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '1.3'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70297423867760
36
+ - !ruby/object:Gem::Dependency
37
+ name: json
38
+ requirement: &70297423867380 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70297423867380
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &70297423866920 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70297423866920
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70297423866500 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70297423866500
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: &70297423866040 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70297423866040
80
+ description: Ruby wrapper for the WishSimple API
81
+ email:
82
+ - shaun@wishsimple.com
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files: []
86
+ files:
87
+ - .gitignore
88
+ - Gemfile
89
+ - HISTORY.md
90
+ - LICENSE
91
+ - README.md
92
+ - Rakefile
93
+ - lib/wishsimple.rb
94
+ - lib/wishsimple/action.rb
95
+ - lib/wishsimple/action/purchase.rb
96
+ - lib/wishsimple/configuration.rb
97
+ - lib/wishsimple/error.rb
98
+ - lib/wishsimple/product.rb
99
+ - lib/wishsimple/resource.rb
100
+ - lib/wishsimple/response/raise_error.rb
101
+ - lib/wishsimple/user.rb
102
+ - lib/wishsimple/version.rb
103
+ - spec/faraday/response_spec.rb
104
+ - spec/fixtures/action/purchase.json
105
+ - spec/fixtures/error/generic.json
106
+ - spec/fixtures/product.json
107
+ - spec/fixtures/user.json
108
+ - spec/spec_helper.rb
109
+ - spec/wishsimple/action/purchase_spec.rb
110
+ - spec/wishsimple/product_spec.rb
111
+ - spec/wishsimple/user_spec.rb
112
+ - spec/wishsimple_spec.rb
113
+ - wishsimple.gemspec
114
+ homepage: https://github.com/wishsimple/wishsimple-ruby
115
+ licenses: []
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 1.8.10
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: WishSimple API Ruby wrapper
138
+ test_files:
139
+ - spec/faraday/response_spec.rb
140
+ - spec/fixtures/action/purchase.json
141
+ - spec/fixtures/error/generic.json
142
+ - spec/fixtures/product.json
143
+ - spec/fixtures/user.json
144
+ - spec/spec_helper.rb
145
+ - spec/wishsimple/action/purchase_spec.rb
146
+ - spec/wishsimple/product_spec.rb
147
+ - spec/wishsimple/user_spec.rb
148
+ - spec/wishsimple_spec.rb
149
+ has_rdoc: