wishsimple 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|