thounds 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 +11 -0
- data/.rspec +3 -0
- data/.yardopts +9 -0
- data/Gemfile +3 -0
- data/HISTORY.mkd +3 -0
- data/LICENSE.mkd +20 -0
- data/README.mkd +81 -0
- data/Rakefile +22 -0
- data/lib/faraday/multipart.rb +30 -0
- data/lib/faraday/oauth.rb +22 -0
- data/lib/faraday/raise_http_4xx.rb +50 -0
- data/lib/faraday/raise_http_5xx.rb +31 -0
- data/lib/thounds.rb +26 -0
- data/lib/thounds/api.rb +23 -0
- data/lib/thounds/authentication.rb +25 -0
- data/lib/thounds/client.rb +46 -0
- data/lib/thounds/client/proxy.rb +46 -0
- data/lib/thounds/configuration.rb +93 -0
- data/lib/thounds/connection.rb +33 -0
- data/lib/thounds/error.rb +28 -0
- data/lib/thounds/request.rb +24 -0
- data/lib/thounds/version.rb +4 -0
- data/spec/faraday/response_spec.rb +31 -0
- data/spec/fixtures/user_31.js +1 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/thounds/api_spec.rb +68 -0
- data/spec/thounds/client_spec.rb +10 -0
- data/spec/thounds_spec.rb +358 -0
- data/test.rb +78 -0
- data/thounds.gemspec +44 -0
- metadata +356 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require File.expand_path('../version', __FILE__)
|
3
|
+
|
4
|
+
module Thounds
|
5
|
+
# Defines constants and methods related to configuration
|
6
|
+
module Configuration
|
7
|
+
# An array of valid keys in the options hash when configuring a {Thounds::API}
|
8
|
+
VALID_OPTIONS_KEYS = [
|
9
|
+
:adapter,
|
10
|
+
:consumer_key,
|
11
|
+
:consumer_secret,
|
12
|
+
:endpoint,
|
13
|
+
:format,
|
14
|
+
:oauth_token,
|
15
|
+
:oauth_token_secret,
|
16
|
+
:proxy,
|
17
|
+
:user_agent].freeze
|
18
|
+
|
19
|
+
# An array of valid request/response formats
|
20
|
+
#
|
21
|
+
# @note Not all methods support the XML format.
|
22
|
+
VALID_FORMATS = [
|
23
|
+
:json,
|
24
|
+
:xml].freeze
|
25
|
+
|
26
|
+
# The adapter that will be used to connect if none is set
|
27
|
+
#
|
28
|
+
# @note The default faraday adapter is Net::HTTP.
|
29
|
+
DEFAULT_ADAPTER = Faraday.default_adapter
|
30
|
+
|
31
|
+
# By default, don't set an application key
|
32
|
+
DEFAULT_CONSUMER_KEY = nil
|
33
|
+
|
34
|
+
# By default, don't set an application secret
|
35
|
+
DEFAULT_CONSUMER_SECRET = nil
|
36
|
+
|
37
|
+
# The endpoint that will be used to connect if none is set
|
38
|
+
#
|
39
|
+
# @note This is configurable in case you want to use HTTP instead of HTTPS, specify a different API version, or use a Thounds-compatible endpoint.
|
40
|
+
DEFAULT_ENDPOINT = 'http://thounds.local:3000/'.freeze
|
41
|
+
|
42
|
+
# The response format appended to the path and sent in the 'Accept' header if none is set
|
43
|
+
#
|
44
|
+
# @note JSON is preferred over XML because it is more concise and faster to parse.
|
45
|
+
DEFAULT_FORMAT = :json
|
46
|
+
|
47
|
+
# By default, don't set a user oauth token
|
48
|
+
DEFAULT_OAUTH_TOKEN = nil
|
49
|
+
|
50
|
+
# By default, don't set a user oauth secret
|
51
|
+
DEFAULT_OAUTH_TOKEN_SECRET = nil
|
52
|
+
|
53
|
+
# By default, don't use a proxy server
|
54
|
+
DEFAULT_PROXY = nil
|
55
|
+
|
56
|
+
# The user agent that will be sent to the API endpoint if none is set
|
57
|
+
DEFAULT_USER_AGENT = "Thounds Ruby Gem #{Thounds::VERSION}".freeze
|
58
|
+
|
59
|
+
# @private
|
60
|
+
attr_accessor *VALID_OPTIONS_KEYS
|
61
|
+
|
62
|
+
# When this module is extended, set all configuration options to their default values
|
63
|
+
def self.extended(base)
|
64
|
+
base.reset
|
65
|
+
end
|
66
|
+
|
67
|
+
# Convenience method to allow configuration options to be set in a block
|
68
|
+
def configure
|
69
|
+
yield self
|
70
|
+
end
|
71
|
+
|
72
|
+
# Create a hash of options and their values
|
73
|
+
def options
|
74
|
+
VALID_OPTIONS_KEYS.inject({}) do |option, key|
|
75
|
+
option.merge!(key => send(key))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Reset all configuration options to defaults
|
80
|
+
def reset
|
81
|
+
self.adapter = DEFAULT_ADAPTER
|
82
|
+
self.consumer_key = DEFAULT_CONSUMER_KEY
|
83
|
+
self.consumer_secret = DEFAULT_CONSUMER_SECRET
|
84
|
+
self.endpoint = DEFAULT_ENDPOINT
|
85
|
+
self.format = DEFAULT_FORMAT
|
86
|
+
self.oauth_token = DEFAULT_OAUTH_TOKEN
|
87
|
+
self.oauth_token_secret = DEFAULT_OAUTH_TOKEN_SECRET
|
88
|
+
self.proxy = DEFAULT_PROXY
|
89
|
+
self.user_agent = DEFAULT_USER_AGENT
|
90
|
+
self
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'faraday_middleware'
|
2
|
+
Dir[File.expand_path('../../faraday/*.rb', __FILE__)].each{|f| require f}
|
3
|
+
|
4
|
+
module Thounds
|
5
|
+
# @private
|
6
|
+
module Connection
|
7
|
+
private
|
8
|
+
|
9
|
+
def connection(raw=false)
|
10
|
+
options = {
|
11
|
+
:headers => {'Accept' => "application/#{format}", 'User-Agent' => user_agent},
|
12
|
+
:proxy => proxy,
|
13
|
+
:ssl => {:verify => false},
|
14
|
+
:url => api_endpoint,
|
15
|
+
}
|
16
|
+
|
17
|
+
Faraday::Connection.new(options) do |connection|
|
18
|
+
connection.use Faraday::Request::Multipart
|
19
|
+
connection.use Faraday::Request::OAuth, authentication if authenticated?
|
20
|
+
connection.adapter(adapter)
|
21
|
+
connection.use Faraday::Response::RaiseHttp5xx
|
22
|
+
unless raw
|
23
|
+
case format.to_s.downcase
|
24
|
+
when 'json' then connection.use Faraday::Response::ParseJson
|
25
|
+
when 'xml' then connection.use Faraday::Response::ParseXml
|
26
|
+
end
|
27
|
+
end
|
28
|
+
connection.use Faraday::Response::RaiseHttp4xx
|
29
|
+
connection.use Faraday::Response::Mashify unless raw
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Thounds
|
2
|
+
# Custom error class for rescuing from all Thounds errors
|
3
|
+
class Error < StandardError; end
|
4
|
+
|
5
|
+
# Raised when Thounds returns the HTTP status code 400
|
6
|
+
class BadRequest < Error; end
|
7
|
+
|
8
|
+
# Raised when Thounds returns the HTTP status code 401
|
9
|
+
class Unauthorized < Error; end
|
10
|
+
|
11
|
+
# Raised when Thounds returns the HTTP status code 403
|
12
|
+
class Forbidden < Error; end
|
13
|
+
|
14
|
+
# Raised when Thounds returns the HTTP status code 404
|
15
|
+
class NotFound < Error; end
|
16
|
+
|
17
|
+
# Raised when Thounds returns the HTTP status code 406
|
18
|
+
class NotAcceptable < Error; end
|
19
|
+
|
20
|
+
# Raised when Thounds returns the HTTP status code 500
|
21
|
+
class InternalServerError < Error; end
|
22
|
+
|
23
|
+
# Raised when Thounds returns the HTTP status code 502
|
24
|
+
class BadGateway < Error; end
|
25
|
+
|
26
|
+
# Raised when Thounds returns the HTTP status code 503
|
27
|
+
class ServiceUnavailable < Error; end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Thounds
|
2
|
+
# Defines HTTP request methods
|
3
|
+
module Request
|
4
|
+
# Perform an HTTP request
|
5
|
+
def request(method, path, options={}, raw=false)
|
6
|
+
response = connection(raw).send(method) do |request|
|
7
|
+
case method
|
8
|
+
when :get, :delete
|
9
|
+
request.url(formatted_path(path), options)
|
10
|
+
when :post, :put
|
11
|
+
request.path = formatted_path(path)
|
12
|
+
request.body = options unless options.empty?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
raw ? response : response.body
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def formatted_path(path)
|
21
|
+
path
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Faraday::Response do
|
4
|
+
before do
|
5
|
+
@client = Thounds::Client.new
|
6
|
+
end
|
7
|
+
|
8
|
+
{
|
9
|
+
400 => Thounds::BadRequest,
|
10
|
+
401 => Thounds::Unauthorized,
|
11
|
+
403 => Thounds::Forbidden,
|
12
|
+
404 => Thounds::NotFound,
|
13
|
+
406 => Thounds::NotAcceptable,
|
14
|
+
500 => Thounds::InternalServerError,
|
15
|
+
502 => Thounds::BadGateway,
|
16
|
+
503 => Thounds::ServiceUnavailable,
|
17
|
+
}.each do |status, exception|
|
18
|
+
context "when HTTP status is #{status}" do
|
19
|
+
|
20
|
+
before do
|
21
|
+
stub_get('users/171').to_return(:status => status)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should raise #{exception.name} error" do
|
25
|
+
lambda do
|
26
|
+
@client.users(171) {|user| user}
|
27
|
+
end.should raise_error(exception)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"friend_of_mine":true,"blog_url":null,"created_at":"2009-06-30T09:52:15Z","city":"30027","friendship_id":2914,"profile_url":"smashing","about":null,"avatar":"http://gravatar.com/avatar/8e6e5c47e1d1b87a322fd2bac7f09d2e.png?d=http%3A%2F%2Fthounds.com%2Fimages%2Favatar-big.jpg&r=PG&s=77","country":"Italy","default_thound":{"privacy":"contacts","public_url":"http://thounds.local:3000/t/6245c9","created_at":"2009-07-24T13:08:08Z","bpm":60,"video":false,"lead_track_id":961,"comments_count":0,"mix_url":"http://thounds.local:3000/thounds/611/stream","user_id":31,"plays_count":6,"mix_duration":0,"tracks":[{"title":"Smash Vs. Fraioli from http://www.randomthink.net/labs/html5drums/","duration":0,"created_at":"2009-07-24T13:08:08Z","privacy":"contacts","offset":0,"path":"thounds/611/tracks/961.mp3","uri":"http://thounds.local:3000/tracks/961/stream","youtube_id":null,"thound_id":611,"lat":null,"user_id":31,"host":"s3","lng":null,"delay":0,"cover":null,"id":961,"user":{"city":"30027","avatar":"http://gravatar.com/avatar/8e6e5c47e1d1b87a322fd2bac7f09d2e.png?d=http%3A%2F%2Fwww.thounds.com%2Fimages%2Favatar-big.jpg&r=PG&s=77","country":"Italy","name":"Smash","id":31},"tags":"drum"},{"title":"yo!","duration":0,"created_at":"2010-04-01T08:17:49Z","privacy":"contacts","offset":133,"path":"/mp3/thound_user_171_mix_thound_611_1270109855794.mp3","uri":"http://stage.thounds.astrails.com//mp3/thound_user_171_mix_thound_611_1270109855794.mp3","youtube_id":null,"thound_id":611,"lat":null,"user_id":171,"host":"stage.thounds.astrails.com","lng":null,"delay":0,"cover":null,"id":2223,"user":{"city":"Treviso","avatar":"http://gravatar.com/avatar/5420033d57945e871b468e1a225cb079.png?d=http%3A%2F%2Fwww.thounds.com%2Fimages%2Favatar-big.jpg&r=PG&s=77","country":"Guinea","name":"Giovanni \u3072\u3089\u304c\u306a","id":171},"tags":"ciao"}],"id":611,"tags":"drum ciao","public_id":"6245c9"},"is_new_user":false,"name":"Smash","id":31,"site_url":null,"tags":[]}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_group 'Thounds', 'lib/thounds'
|
4
|
+
add_group 'Faraday Middleware', 'lib/faraday'
|
5
|
+
add_group 'Specs', 'spec'
|
6
|
+
end
|
7
|
+
|
8
|
+
require File.expand_path('../../lib/thounds', __FILE__)
|
9
|
+
|
10
|
+
require 'rspec'
|
11
|
+
require 'webmock/rspec'
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.include WebMock::API
|
14
|
+
end
|
15
|
+
|
16
|
+
def a_delete(path)
|
17
|
+
a_request(:delete, Thounds.endpoint + path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def a_get(path)
|
21
|
+
a_request(:get, Thounds.endpoint + path)
|
22
|
+
end
|
23
|
+
|
24
|
+
def a_post(path)
|
25
|
+
a_request(:post, Thounds.endpoint + path)
|
26
|
+
end
|
27
|
+
|
28
|
+
def a_put(path)
|
29
|
+
a_request(:put, Thounds.endpoint + path)
|
30
|
+
end
|
31
|
+
|
32
|
+
def stub_delete(path)
|
33
|
+
stub_request(:delete, Thounds.endpoint + path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def stub_get(path)
|
37
|
+
stub_request(:get, Thounds.endpoint + path)
|
38
|
+
end
|
39
|
+
|
40
|
+
def stub_post(path)
|
41
|
+
stub_request(:post, Thounds.endpoint + path)
|
42
|
+
end
|
43
|
+
|
44
|
+
def stub_put(path)
|
45
|
+
stub_request(:put, Thounds.endpoint + path)
|
46
|
+
end
|
47
|
+
|
48
|
+
def fixture_path
|
49
|
+
File.expand_path("../fixtures", __FILE__)
|
50
|
+
end
|
51
|
+
|
52
|
+
def fixture(file)
|
53
|
+
File.new(fixture_path + '/' + file)
|
54
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Thounds::API do
|
4
|
+
before do
|
5
|
+
@keys = Thounds::Configuration::VALID_OPTIONS_KEYS
|
6
|
+
end
|
7
|
+
|
8
|
+
context "with module configuration" do
|
9
|
+
|
10
|
+
before do
|
11
|
+
Thounds.configure do |config|
|
12
|
+
@keys.each do |key|
|
13
|
+
config.send("#{key}=", key)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
after do
|
19
|
+
Thounds.reset
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should inherit module configuration" do
|
23
|
+
api = Thounds::API.new
|
24
|
+
@keys.each do |key|
|
25
|
+
api.send(key).should == key
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with class configuration" do
|
30
|
+
|
31
|
+
before do
|
32
|
+
@configuration = {
|
33
|
+
:consumer_key => 'CK',
|
34
|
+
:consumer_secret => 'CS',
|
35
|
+
:oauth_token => 'OT',
|
36
|
+
:oauth_token_secret => 'OS',
|
37
|
+
:adapter => :typhoeus,
|
38
|
+
:endpoint => 'http://tumblr.com/',
|
39
|
+
:format => :xml,
|
40
|
+
:proxy => 'http://giovanni:secret@proxy.example.com:8080',
|
41
|
+
:user_agent => 'Custom User Agent',
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
context "during initialization"
|
46
|
+
|
47
|
+
it "should override module configuration" do
|
48
|
+
api = Thounds::API.new(@configuration)
|
49
|
+
@keys.each do |key|
|
50
|
+
api.send(key).should == @configuration[key]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "after initilization" do
|
55
|
+
|
56
|
+
it "should override module configuration after initialization" do
|
57
|
+
api = Thounds::API.new
|
58
|
+
@configuration.each do |key, value|
|
59
|
+
api.send("#{key}=", value)
|
60
|
+
end
|
61
|
+
@keys.each do |key|
|
62
|
+
api.send(key).should == @configuration[key]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Thounds::Client do
|
4
|
+
it "should connect using the endpoint configuration" do
|
5
|
+
client = Thounds::Client.new
|
6
|
+
endpoint = URI.parse(client.api_endpoint)
|
7
|
+
connection = client.send(:connection).build_url(nil).to_s
|
8
|
+
connection.should == endpoint.to_s
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,358 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Thounds do
|
4
|
+
after do
|
5
|
+
Thounds.reset
|
6
|
+
end
|
7
|
+
|
8
|
+
context "when delegating to a client" do
|
9
|
+
|
10
|
+
before do
|
11
|
+
stub_get("users/31").
|
12
|
+
to_return(:body => fixture("user_31.js"), :headers => {:content_type => "application/json; charset=utf-8"})
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should get the correct resource" do
|
16
|
+
Thounds.users(31) {|user| user}
|
17
|
+
a_get("users/31").
|
18
|
+
should have_been_made
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return the same results as a client" do
|
22
|
+
class_obj = nil
|
23
|
+
client_obj = nil
|
24
|
+
|
25
|
+
Thounds.users(31) {|user| class_obj = user}
|
26
|
+
Thounds::Client.new.users(31) {|user| client_obj = user}
|
27
|
+
|
28
|
+
class_obj.should == client_obj
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when making a request to" do
|
34
|
+
|
35
|
+
# http://developers.thounds.com/API/HomeStream
|
36
|
+
describe "GET home" do
|
37
|
+
before do
|
38
|
+
stub_get("home")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should use 'home' request path" do
|
42
|
+
Thounds.home {|r| r}.proxy.path.should == "home"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# http://developers.thounds.com/API/UserMetadata
|
47
|
+
describe "GET profile" do
|
48
|
+
before do
|
49
|
+
stub_get("profile")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should use 'profile' request path" do
|
53
|
+
Thounds.profile {|r| r}.proxy.path.should == "profile"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# http://developers.thounds.com/API/UserMetadata
|
58
|
+
describe "GET users/123" do
|
59
|
+
before do
|
60
|
+
stub_get("users/123")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should use 'users/123' request path" do
|
64
|
+
Thounds.users(123) {|r| r}.proxy.path.should == "users/123"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# http://developers.thounds.com/API/UserBand
|
69
|
+
# http://developers.thounds.com/API/UserLibrary
|
70
|
+
# http://developers.thounds.com/API/UserNotifications
|
71
|
+
["band", "library", "notifications"].each do |member|
|
72
|
+
describe "GET profile/#{member}" do
|
73
|
+
before do
|
74
|
+
stub_get("profile/#{member}")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should use 'profile/#{member}' request path" do
|
78
|
+
Thounds.profile.send(member) {|r| r}.proxy.path.should == "profile/#{member}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# http://developers.thounds.com/API/UserBand
|
84
|
+
# http://developers.thounds.com/API/UserLibrary
|
85
|
+
["band", "library"].each do |member|
|
86
|
+
describe "GET users/123/#{member}" do
|
87
|
+
before do
|
88
|
+
stub_get("users/123/#{member}")
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should use 'users/123/#{member}' request path" do
|
92
|
+
Thounds.users(123).send(member) {|r| r}.proxy.path.should == "users/123/#{member}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# http://developers.thounds.com/API/UserRegistration
|
98
|
+
describe "POST users" do
|
99
|
+
before do
|
100
|
+
stub_post("users")
|
101
|
+
|
102
|
+
@options = {
|
103
|
+
:user => {
|
104
|
+
:name => "John Doe",
|
105
|
+
:email => "john@doe.com",
|
106
|
+
:country => "Italy",
|
107
|
+
:city => "Roma",
|
108
|
+
:tags => "jazz vocal"
|
109
|
+
}
|
110
|
+
}
|
111
|
+
@request = Thounds.users.post(@options) {|r| r}
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should use 'users' request path" do
|
115
|
+
@request.proxy.path.should == "users"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should use POST request verb" do
|
119
|
+
@request.proxy.verb.should == :post
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should include new user parameters into request" do
|
123
|
+
@request.proxy.options.should == @options
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# http://developers.thounds.com/API/FriendshipRequest
|
128
|
+
describe "POST users/123/friendships" do
|
129
|
+
before do
|
130
|
+
stub_post("users/123/friendships")
|
131
|
+
|
132
|
+
@request = Thounds.users(123).friendships.post {|r| r}
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should use 'users/123/friendships' request path" do
|
136
|
+
@request.proxy.path.should == "users/123/friendships"
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should use POST request verb" do
|
140
|
+
@request.proxy.verb.should == :post
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# http://developers.thounds.com/API/FriendshipAcceptRefuse
|
145
|
+
# http://developers.thounds.com/API/FriendshipDelete
|
146
|
+
[:put, :delete].each do |verb|
|
147
|
+
describe "#{verb.to_s.upcase} profile/friendships/123" do
|
148
|
+
before do
|
149
|
+
send("stub_#{verb}", "profile/friendships/123")
|
150
|
+
|
151
|
+
@request = Thounds.profile.friendships(123).send(verb) {|r| r}
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should use 'profile/friendships/123' request path" do
|
155
|
+
@request.proxy.path.should == "profile/friendships/123"
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should use #{verb.to_s.upcase} request verb" do
|
159
|
+
@request.proxy.verb.should == verb
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# http://developers.thounds.com/API/ThoundMetadata
|
165
|
+
# http://developers.thounds.com/API/ThoundDelete
|
166
|
+
[:get, :delete].each do |verb|
|
167
|
+
describe "#{verb.to_s.upcase} thounds/123" do
|
168
|
+
before do
|
169
|
+
send("stub_#{verb}", "thounds/123")
|
170
|
+
|
171
|
+
@request = Thounds.thounds(123).send(verb) {|r| r}
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should use 'thounds/123' request path" do
|
175
|
+
@request.proxy.path.should == "thounds/123"
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should use #{verb.to_s.upcase} request verb" do
|
179
|
+
@request.proxy.verb.should == verb
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# http://developers.thounds.com/API/ThoundPublicStream
|
185
|
+
describe "GET thounds/public_stream" do
|
186
|
+
before do
|
187
|
+
stub_get("thounds/public_stream")
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should use 'thounds/public_stream' request path" do
|
191
|
+
Thounds.thounds.public_stream {|r| r}.proxy.path.should == "thounds/public_stream"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# http://developers.thounds.com/API/ThoundSearch
|
196
|
+
describe "GET thounds/search" do
|
197
|
+
before do
|
198
|
+
stub_get("thounds/search?q=query")
|
199
|
+
|
200
|
+
@options = {:q => "query"}
|
201
|
+
@request = Thounds.thounds.search(@options) {|r| r}
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should use 'thounds/search' request path" do
|
205
|
+
@request.proxy.path.should == "thounds/search"
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should include new user parameters into request" do
|
209
|
+
@request.proxy.options.should == @options
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# http://developers.thounds.com/API/TrackCreate
|
214
|
+
# http://developers.thounds.com/API/ThoundCreate
|
215
|
+
describe "POST tracks" do
|
216
|
+
before do
|
217
|
+
stub_post("tracks")
|
218
|
+
|
219
|
+
@options = {
|
220
|
+
:track => {
|
221
|
+
:delay => 0,
|
222
|
+
:offset => 0,
|
223
|
+
:duration => 0,
|
224
|
+
:lat => 45.4375,
|
225
|
+
:lng => 12.3358,
|
226
|
+
:title => "My new default thound!",
|
227
|
+
:privacy => "contacts",
|
228
|
+
:thound_attributes => {
|
229
|
+
:bpm => 90
|
230
|
+
},
|
231
|
+
:tag_list => "vocal jazz",
|
232
|
+
:thoundfile => "SUQzB...",
|
233
|
+
:coverfile => "iVBOR..."
|
234
|
+
}
|
235
|
+
}
|
236
|
+
@request = Thounds.tracks.post(@options) {|r| r}
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should use 'tracks' request path" do
|
240
|
+
@request.proxy.path.should == "tracks"
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should use POST request verb" do
|
244
|
+
@request.proxy.verb.should == :post
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should include new track parameters into request" do
|
248
|
+
@request.proxy.options.should == @options
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
# http://developers.thounds.com/API/TrackDelete
|
253
|
+
describe "DELETE tracks/123" do
|
254
|
+
before do
|
255
|
+
stub_delete("tracks/123")
|
256
|
+
|
257
|
+
@request = Thounds.tracks(123).delete {|r| r}
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should use 'tracks/123' request path" do
|
261
|
+
@request.proxy.path.should == "tracks/123"
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should use DELETE request verb" do
|
265
|
+
@request.proxy.verb.should == :delete
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# http://developers.thounds.com/API/TrackNotificationsDelete
|
270
|
+
describe "DELETE track_notifications/123" do
|
271
|
+
before do
|
272
|
+
stub_delete("track_notifications/123")
|
273
|
+
|
274
|
+
@request = Thounds.track_notifications(123).delete {|r| r}
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should use 'track_notifications/123' request path" do
|
278
|
+
@request.proxy.path.should == "track_notifications/123"
|
279
|
+
end
|
280
|
+
|
281
|
+
it "should use DELETE request verb" do
|
282
|
+
@request.proxy.verb.should == :delete
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
describe ".client" do
|
289
|
+
it "should be a Thounds::Client" do
|
290
|
+
Thounds.client.should be_a Thounds::Client
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
describe ".adapter" do
|
295
|
+
it "should return the default adapter" do
|
296
|
+
Thounds.adapter.should == Thounds::Configuration::DEFAULT_ADAPTER
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
describe ".adapter=" do
|
301
|
+
it "should set the adapter" do
|
302
|
+
Thounds.adapter = :typhoeus
|
303
|
+
Thounds.adapter.should == :typhoeus
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
describe ".endpoint" do
|
308
|
+
it "should return the default endpoint" do
|
309
|
+
Thounds.endpoint.should == Thounds::Configuration::DEFAULT_ENDPOINT
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
describe ".endpoint=" do
|
314
|
+
it "should set the endpoint" do
|
315
|
+
Thounds.endpoint = 'http://tumblr.com/'
|
316
|
+
Thounds.endpoint.should == 'http://tumblr.com/'
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
describe ".format" do
|
321
|
+
it "should return the default format" do
|
322
|
+
Thounds.format.should == Thounds::Configuration::DEFAULT_FORMAT
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
describe ".format=" do
|
327
|
+
it "should set the format" do
|
328
|
+
Thounds.format = 'xml'
|
329
|
+
Thounds.format.should == 'xml'
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe ".user_agent" do
|
334
|
+
it "should return the default user agent" do
|
335
|
+
Thounds.user_agent.should == Thounds::Configuration::DEFAULT_USER_AGENT
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
describe ".user_agent=" do
|
340
|
+
it "should set the user_agent" do
|
341
|
+
Thounds.user_agent = 'Custom User Agent'
|
342
|
+
Thounds.user_agent.should == 'Custom User Agent'
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
describe ".configure" do
|
347
|
+
|
348
|
+
Thounds::Configuration::VALID_OPTIONS_KEYS.each do |key|
|
349
|
+
|
350
|
+
it "should set the #{key}" do
|
351
|
+
Thounds.configure do |config|
|
352
|
+
config.send("#{key}=", key)
|
353
|
+
Thounds.send(key).should == key
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|