wishsimple 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/Gemfile +2 -0
- data/HISTORY.md +6 -0
- data/LICENSE +22 -0
- data/README.md +99 -0
- data/Rakefile +10 -0
- data/lib/wishsimple.rb +88 -0
- data/lib/wishsimple/action.rb +33 -0
- data/lib/wishsimple/action/purchase.rb +5 -0
- data/lib/wishsimple/configuration.rb +43 -0
- data/lib/wishsimple/error.rb +19 -0
- data/lib/wishsimple/product.rb +23 -0
- data/lib/wishsimple/resource.rb +33 -0
- data/lib/wishsimple/response/raise_error.rb +43 -0
- data/lib/wishsimple/user.rb +31 -0
- data/lib/wishsimple/version.rb +3 -0
- data/spec/faraday/response_spec.rb +32 -0
- data/spec/fixtures/action/purchase.json +1 -0
- data/spec/fixtures/error/generic.json +1 -0
- data/spec/fixtures/product.json +1 -0
- data/spec/fixtures/user.json +1 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/wishsimple/action/purchase_spec.rb +73 -0
- data/spec/wishsimple/product_spec.rb +70 -0
- data/spec/wishsimple/user_spec.rb +84 -0
- data/spec/wishsimple_spec.rb +117 -0
- data/wishsimple.gemspec +25 -0
- metadata +149 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/HISTORY.md
ADDED
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.
|
data/README.md
ADDED
@@ -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.
|
data/Rakefile
ADDED
data/lib/wishsimple.rb
ADDED
@@ -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,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,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}
|
data/spec/spec_helper.rb
ADDED
@@ -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
|
data/wishsimple.gemspec
ADDED
@@ -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:
|