soundcloud-client 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +23 -0
- data/.rspec +3 -0
- data/Gemfile +5 -0
- data/README.md +200 -0
- data/Rakefile +1 -0
- data/VERSION +1 -0
- data/lib/soundcloud-client.rb +8 -0
- data/lib/soundcloud/api.rb +202 -0
- data/lib/soundcloud/error.rb +52 -0
- data/lib/soundcloud/middleware.rb +24 -0
- data/soundcloud-client.gemspec +27 -0
- data/spec/api_conformity_spec.rb +92 -0
- data/spec/soundcloud_spec.rb +113 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/stubs.rb +620 -0
- metadata +143 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
# 400 Bad Request Check if your request is a valid HTTP request.
|
2
|
+
# 401 Unauthorized Check if you've send a valid client_id or access_token.
|
3
|
+
# 403 Forbidden Access to the requested resource is forbidden.
|
4
|
+
# 404 Not Found The requested resource was not found or is not accessible to the user.
|
5
|
+
# 406 Not Acceptable The resource is not available in the format you requested.
|
6
|
+
# 422 Unprocessable Entity The request is syntaxtically correct, but of an incorrect structure for this resource. Typically you are missing required properties or use incorrect data structures (e.g. strings instead of arrays).
|
7
|
+
# 500 Internal Server Error Occurs when an unexpected error on our side happend. Please contact us to resolve that issue.
|
8
|
+
# 503 Service Unavailable Occurs when no services are available to process your request. If possible provide your app users a way to manually trigger a retry.
|
9
|
+
# 504 Gateway Timeout Occurs when the request processing took to long. Be aware that your request could still be executed and manipulate data.
|
10
|
+
|
11
|
+
|
12
|
+
module Soundcloud
|
13
|
+
module Error
|
14
|
+
|
15
|
+
class Error < Faraday::Error::ClientError; end
|
16
|
+
class ClientError < Error; end
|
17
|
+
class ServerError < Error; end
|
18
|
+
class UnexpectedError < Error; end
|
19
|
+
|
20
|
+
class BadRequest < ClientError; end
|
21
|
+
class Unauthorized < ClientError; end
|
22
|
+
class PaymentRequired < ClientError; end
|
23
|
+
class Forbidden < ClientError; end
|
24
|
+
class NotFound < ClientError; end
|
25
|
+
class NotAcceptable < ClientError; end
|
26
|
+
class UnprocessableEntity < ClientError; end
|
27
|
+
class InternalServerError < ServerError; end
|
28
|
+
class ServiceUnavailable < ServerError; end
|
29
|
+
class GatewayTimeout < ServerError; end
|
30
|
+
|
31
|
+
STATUS_ERROR_MAP = Hash.new do |h, k|
|
32
|
+
case k
|
33
|
+
when 400...500 then :ClientError
|
34
|
+
when 500...600 then :ServerError
|
35
|
+
end
|
36
|
+
end.merge(400 => :BadRequest,
|
37
|
+
401 => :Unauthorized,
|
38
|
+
402 => :PaymentRequired,
|
39
|
+
403 => :Forbidden,
|
40
|
+
404 => :NotFound,
|
41
|
+
406 => :NotAcceptable,
|
42
|
+
422 => :UnprocessableEntity,
|
43
|
+
500 => :InternalServerError,
|
44
|
+
503 => :ServiceUnavailable,
|
45
|
+
504 => :GatewayTimeout)
|
46
|
+
|
47
|
+
def self.[](status)
|
48
|
+
self.const_get(STATUS_ERROR_MAP[status])
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'soundcloud/error'
|
3
|
+
|
4
|
+
module Soundcloud
|
5
|
+
module Middleware
|
6
|
+
|
7
|
+
class RaiseError < Faraday::Response::Middleware
|
8
|
+
|
9
|
+
def on_complete(env)
|
10
|
+
case env[:status]
|
11
|
+
when 400...600
|
12
|
+
raise Soundcloud::Error[env[:status]], response_values(env)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def response_values(env)
|
17
|
+
{:status => env[:status], :headers => env[:response_headers], :body => env[:body]}
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
3
|
+
require "soundcloud-client"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "soundcloud-client"
|
7
|
+
s.version = Soundcloud::VERSION
|
8
|
+
s.authors = ["rewritten"]
|
9
|
+
s.email = ["saverio@socialfolders.me", "fabien@socialfolders.me"]
|
10
|
+
s.homepage = "https://github.com/SocialFolders/soundcloud-client"
|
11
|
+
s.summary = "Soundcloud API client"
|
12
|
+
s.description = %q{Soundcloud API client, with configurable HTTP backend}
|
13
|
+
|
14
|
+
# s.rubyforge_project = "soundcloud-client"
|
15
|
+
|
16
|
+
s.add_dependency("faraday", "~> 0.8.0")
|
17
|
+
s.add_dependency("faraday_middleware")
|
18
|
+
|
19
|
+
s.add_development_dependency("rspec")
|
20
|
+
s.add_development_dependency("rake")
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
25
|
+
s.executables = []
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
describe "API conformity" do
|
2
|
+
before do
|
3
|
+
@item = {id: 123}
|
4
|
+
@other = {id: 456}
|
5
|
+
end
|
6
|
+
|
7
|
+
subject { Soundcloud::API.new("fake", verbose: false, stubs: STUBS) }
|
8
|
+
|
9
|
+
[
|
10
|
+
[:users, "/users"],
|
11
|
+
[:user, "/users/123"],
|
12
|
+
[:user_tracks, "/users/123/tracks"],
|
13
|
+
[:user_playlists, "/users/123/playlists"],
|
14
|
+
[:user_groups, "/users/123/groups"],
|
15
|
+
[:user_web_profiles, "/users/123/web-profiles"],
|
16
|
+
[:user_followings, "/users/123/followings"],
|
17
|
+
[:follow!, "/users/me/followings/123", :put],
|
18
|
+
[:follow?, "/users/456/followings/123"],
|
19
|
+
[:unfollow!, "/users/me/followings/123", :delete],
|
20
|
+
[:user_followers, "/users/123/followers"],
|
21
|
+
[:user_comments, "/users/123/comments"],
|
22
|
+
[:user_favorites, "/users/123/favorites"],
|
23
|
+
[:favorite!, "/users/me/favorites/123", :put],
|
24
|
+
[:favorite?, "/users/456/favorites/123"],
|
25
|
+
[:unfavorite!, "/users/me/favorites/123", :delete],
|
26
|
+
[:user_connections, "/users/123/connections"],
|
27
|
+
[:user_activities, "/users/123/activities"],
|
28
|
+
[:tracks, "/tracks"],
|
29
|
+
[:track, "/tracks/123"],
|
30
|
+
[:create_track, "/tracks", :post],
|
31
|
+
[:update_track, "/tracks/123", :put],
|
32
|
+
[:delete_track, "/tracks/123", :delete],
|
33
|
+
[:track_comments, "/tracks/123/comments"],
|
34
|
+
[:track_favoriters, "/tracks/123/favoriters"],
|
35
|
+
[:track_shared_to_users, "/tracks/123/shared-to/users"],
|
36
|
+
[:track_shared_to_emails, "/tracks/123/shared-to/emails"],
|
37
|
+
[:track_secret_token, "/tracks/123/secret-token"],
|
38
|
+
[:playlists, "/playlists"],
|
39
|
+
[:playlist, "/playlists/123"],
|
40
|
+
[:create_playlist, "/playlists", :post],
|
41
|
+
[:update_playlist, "/playlists/123", :put],
|
42
|
+
[:delete_playlist, "/playlists/123", :delete],
|
43
|
+
[:playlist_shared_to_users, "/playlists/123/shared-to/users"],
|
44
|
+
[:playlist_shared_to_emails, "/playlists/123/shared-to/emails"],
|
45
|
+
[:playlist_secret_token, "/playlists/123/secret-token"],
|
46
|
+
[:groups, "/groups"],
|
47
|
+
[:group, "/groups/123"],
|
48
|
+
[:create_group, "/groups", :post],
|
49
|
+
[:update_group, "/groups/123", :put],
|
50
|
+
[:delete_group, "/groups/123", :delete],
|
51
|
+
[:group_moderators, "/groups/123/moderators"],
|
52
|
+
[:group_members, "/groups/123/members"],
|
53
|
+
[:group_contributors, "/groups/123/contributors"],
|
54
|
+
[:group_users, "/groups/123/users"],
|
55
|
+
[:group_tracks, "/groups/123/tracks"],
|
56
|
+
[:group_pending_tracks, "/groups/123/pending-tracks"],
|
57
|
+
[:group_contributions, "/groups/123/contributions"],
|
58
|
+
[:comments, "/comments"],
|
59
|
+
[:comment, "/comments/123"],
|
60
|
+
[:apps, "/apps"],
|
61
|
+
[:app, "/apps/123"],
|
62
|
+
[:app_tracks, "/apps/123/tracks"]
|
63
|
+
].each do |meth, path, verb=nil|
|
64
|
+
verb ||= :get
|
65
|
+
describe meth do
|
66
|
+
last_param = Soundcloud::API.instance_method(meth).parameters.last
|
67
|
+
if last_param == [:opt, :opts]
|
68
|
+
it "should #{verb.upcase} #{path} (when not given options)" do
|
69
|
+
subject.should_receive(verb).with(path, {}).and_return(mock(:response, body: nil))
|
70
|
+
subject.send meth, *[@item, @other].take(subject.method(meth).arity.abs)
|
71
|
+
end
|
72
|
+
it "should #{verb.upcase} #{path}?some=option (when given options)" do
|
73
|
+
subject.should_receive(verb).with(path, {:some=>"option"}).and_return(mock(:response, body: nil))
|
74
|
+
subject.send meth, *[@item, @other].take(subject.method(meth).arity.abs), {some: "option"}
|
75
|
+
end
|
76
|
+
else
|
77
|
+
it "should #{verb.upcase} #{path}" do
|
78
|
+
subject.stub!(verb).with(path).and_return(mock(:response, body: nil))
|
79
|
+
subject.stub!(verb).with(path, instance_of(Hash)).and_return(mock(:response, body: nil))
|
80
|
+
subject.send meth, *[@item, @other].take(subject.method(meth).arity.abs)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
if last_param == [:opt, :who]
|
84
|
+
default_path = path.gsub("456", "me")
|
85
|
+
it "should #{verb.upcase} #{default_path} (when the :who param is not given)" do
|
86
|
+
subject.should_receive(verb).with(default_path).and_return(mock(:response, body: nil))
|
87
|
+
subject.send meth, *[@item, @other].take(subject.method(meth).arity.abs - 1)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
describe :VERSION do
|
2
|
+
subject { Soundcloud::VERSION }
|
3
|
+
it { should be_a String }
|
4
|
+
it { should match /^\d+\.\d+\.\d+/ }
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
describe Soundcloud::API do
|
9
|
+
|
10
|
+
it "should raise ArgumentError when initialized with no options" do
|
11
|
+
lambda do
|
12
|
+
Soundcloud::API.new
|
13
|
+
end.should raise_error ArgumentError
|
14
|
+
end
|
15
|
+
|
16
|
+
before do
|
17
|
+
@api = Soundcloud::API.new("fake", verbose: false, stubs: STUBS)
|
18
|
+
end
|
19
|
+
|
20
|
+
subject { @api }
|
21
|
+
|
22
|
+
describe "when receiving errors" do
|
23
|
+
it "should raise correct error from a haproxy error page (503)" do
|
24
|
+
lambda {
|
25
|
+
subject.user_playlists id: "haproxy_error"
|
26
|
+
}.should raise_exception Soundcloud::Error::ServiceUnavailable
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should raise correct error from a server error page (503)" do
|
30
|
+
lambda {
|
31
|
+
subject.user_playlists id: "bleh"
|
32
|
+
}.should raise_exception Soundcloud::Error::ServiceUnavailable
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "when receiving data" do
|
37
|
+
it "should wrap the response object of a single resource in a hash" do
|
38
|
+
subject.track(123).should be_a Hash
|
39
|
+
end
|
40
|
+
it "should wrap the response object of a colletion in a list of hashes" do
|
41
|
+
result = subject.tracks
|
42
|
+
result.should be_a Array
|
43
|
+
result.should_not be_empty
|
44
|
+
result.each do |m|
|
45
|
+
m.should be_a Hash
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
describe :id_of do
|
52
|
+
|
53
|
+
it "should pass through basic types" do
|
54
|
+
subject.id_of("me").should == "me"
|
55
|
+
subject.id_of(123).should == 123
|
56
|
+
end
|
57
|
+
it "extract id from hash" do
|
58
|
+
subject.id_of({id: "my_id"}).should == "my_id"
|
59
|
+
subject.id_of({"id" => "my_id"}).should == "my_id"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "have connection wrappers" do
|
64
|
+
before do
|
65
|
+
@connection = mock(Faraday::Connection)
|
66
|
+
subject.stub(:connection).and_return(@connection)
|
67
|
+
end
|
68
|
+
|
69
|
+
[:get, :post, :put, :delete].each do |verb|
|
70
|
+
it "should hand out #{verb.inspect} to the connection" do
|
71
|
+
@connection.should_receive(verb).and_return(mock(:response, body: "body"))
|
72
|
+
subject.send verb
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe :connection do
|
78
|
+
let(:args) { Array.new }
|
79
|
+
subject { Soundcloud::API.new("fake", verbose: false).connection(*args) }
|
80
|
+
it { should_not be_nil }
|
81
|
+
|
82
|
+
describe "with no args" do
|
83
|
+
let(:args) { Array.new }
|
84
|
+
it "should be the default one" do should eql @api.class.connection end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "verbose" do
|
88
|
+
let(:args) { [{verbose: true}] }
|
89
|
+
it "should not be the default one" do should_not eql @api.class.connection end
|
90
|
+
it "should contain a logger middleware" do
|
91
|
+
subject.builder.handlers.any? { |h| h == Faraday::Response::Logger }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "with stubs" do
|
96
|
+
let(:args) { [{stubs: mock(:stubs)}] }
|
97
|
+
it "should not be the default one" do should_not eql @api.class.connection end
|
98
|
+
it "should end with a Stubs adapter" do
|
99
|
+
subject.builder.handlers.last.should == Faraday::Adapter::Test
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should be verbose when the class is set as such" do
|
104
|
+
Soundcloud::API.new("fake", verbose: true).connection.builder.handlers.any? { |h| h == Faraday::Response::Logger }
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should be stubbed when the class is set as such" do
|
108
|
+
Soundcloud::API.new("fake", stubs: mock(Faraday::Adapter::Test::Stubs)).connection.builder.handlers.last.should == Faraday::Adapter::Test
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/stubs.rb
ADDED
@@ -0,0 +1,620 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
SAMPLES = {
|
4
|
+
|
5
|
+
user: <<-JS.gsub(/\s+/, " "),
|
6
|
+
{
|
7
|
+
"id": 3207,
|
8
|
+
"permalink": "jwagener",
|
9
|
+
"username": "Johannes Wagener",
|
10
|
+
"uri": "http://api.soundcloud.com/users/3207",
|
11
|
+
"permalink_url": "http://soundcloud.com/jwagener",
|
12
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000001552142-pbw8yd-large.jpg?142a848",
|
13
|
+
"country": "Germany",
|
14
|
+
"full_name": "Johannes Wagener",
|
15
|
+
"city": "Berlin",
|
16
|
+
"description": "<b>Hacker at SoundCloud</b>\r\n\r\nSome of my recent Hacks:\r\n\r\nsoundiverse.com \r\nbrowse recordings with the FiRe app by artwork\r\n\r\ntopbillin.com \r\nfind people to follow on SoundCloud\r\n\r\nchatter.fm \r\nget your account hooked up with a voicebox\r\n\r\nrecbutton.com \r\nrecord straight to your soundcloud account",
|
17
|
+
"discogs_name": null,
|
18
|
+
"myspace_name": null,
|
19
|
+
"website": "http://johannes.wagener.cc",
|
20
|
+
"website_title": "johannes.wagener.cc",
|
21
|
+
"online": true,
|
22
|
+
"track_count": 12,
|
23
|
+
"playlist_count": 1,
|
24
|
+
"followers_count": 417,
|
25
|
+
"followings_count": 174,
|
26
|
+
"public_favorites_count": 26
|
27
|
+
}
|
28
|
+
JS
|
29
|
+
|
30
|
+
users: <<-JS.gsub(/\s+/, " "),
|
31
|
+
[
|
32
|
+
{
|
33
|
+
"id": 1007028,
|
34
|
+
"permalink": "lansinghiphop",
|
35
|
+
"username": "LansingHipHop",
|
36
|
+
"uri": "http://api.soundcloud.com/users/1007028",
|
37
|
+
"permalink_url": "http://soundcloud.com/lansinghiphop",
|
38
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000001229324-2l55vi-large.jpg?142a848",
|
39
|
+
"country": "United States",
|
40
|
+
"full_name": "Lansing HipHop",
|
41
|
+
"city": "Lansing",
|
42
|
+
"description": null,
|
43
|
+
"discogs_name": null,
|
44
|
+
"myspace_name": null,
|
45
|
+
"website": null,
|
46
|
+
"website_title": null,
|
47
|
+
"online": false,
|
48
|
+
"track_count": 1,
|
49
|
+
"playlist_count": 0,
|
50
|
+
"followers_count": 97,
|
51
|
+
"followings_count": 0,
|
52
|
+
"public_favorites_count": 0
|
53
|
+
},
|
54
|
+
{
|
55
|
+
"id": 1858228,
|
56
|
+
"permalink": "chicoseah",
|
57
|
+
"username": "ChicoSeah",
|
58
|
+
"uri": "http://api.soundcloud.com/users/1858228",
|
59
|
+
"permalink_url": "http://soundcloud.com/chicoseah",
|
60
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000001837875-prjwx9-large.jpg?142a848",
|
61
|
+
"country": null,
|
62
|
+
"full_name": "HipHop",
|
63
|
+
"city": "ZNC",
|
64
|
+
"description": null,
|
65
|
+
"discogs_name": null,
|
66
|
+
"myspace_name": null,
|
67
|
+
"website": null,
|
68
|
+
"website_title": null,
|
69
|
+
"online": false,
|
70
|
+
"track_count": 1,
|
71
|
+
"playlist_count": 0,
|
72
|
+
"followers_count": 41,
|
73
|
+
"followings_count": 3,
|
74
|
+
"public_favorites_count": 0
|
75
|
+
},
|
76
|
+
{
|
77
|
+
"id": 2168214,
|
78
|
+
"permalink": "hip-hop-2",
|
79
|
+
"username": "hip hop",
|
80
|
+
"uri": "http://api.soundcloud.com/users/2168214",
|
81
|
+
"permalink_url": "http://soundcloud.com/hip-hop-2",
|
82
|
+
"avatar_url": "http://a1.sndcdn.com/images/default_avatar_large.png?142a848",
|
83
|
+
"country": "United States",
|
84
|
+
"full_name": "hiphop",
|
85
|
+
"city": "new york",
|
86
|
+
"description": null,
|
87
|
+
"discogs_name": null,
|
88
|
+
"myspace_name": null,
|
89
|
+
"website": null,
|
90
|
+
"website_title": null,
|
91
|
+
"online": false,
|
92
|
+
"track_count": 3,
|
93
|
+
"playlist_count": 0,
|
94
|
+
"followers_count": 99,
|
95
|
+
"followings_count": 1,
|
96
|
+
"public_favorites_count": 0
|
97
|
+
},
|
98
|
+
{
|
99
|
+
"id": 1562800,
|
100
|
+
"permalink": "chedee-1",
|
101
|
+
"username": "Chedee",
|
102
|
+
"uri": "http://api.soundcloud.com/users/1562800",
|
103
|
+
"permalink_url": "http://soundcloud.com/chedee-1",
|
104
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000003117449-uj69ym-large.jpg?142a848",
|
105
|
+
"country": "Switzerland",
|
106
|
+
"full_name": "HipHop",
|
107
|
+
"city": "Zurich",
|
108
|
+
"description": "Street Guerilla",
|
109
|
+
"discogs_name": "Chedee",
|
110
|
+
"myspace_name": null,
|
111
|
+
"website": null,
|
112
|
+
"website_title": null,
|
113
|
+
"online": false,
|
114
|
+
"track_count": 7,
|
115
|
+
"playlist_count": 2,
|
116
|
+
"followers_count": 105,
|
117
|
+
"followings_count": 51,
|
118
|
+
"public_favorites_count": 1
|
119
|
+
},
|
120
|
+
{
|
121
|
+
"id": 3498284,
|
122
|
+
"permalink": "hiphop-honky",
|
123
|
+
"username": "hiphop-honky",
|
124
|
+
"uri": "http://api.soundcloud.com/users/3498284",
|
125
|
+
"permalink_url": "http://soundcloud.com/hiphop-honky",
|
126
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000002860787-fdb9ga-large.jpg?142a848",
|
127
|
+
"country": "United States",
|
128
|
+
"full_name": "HipHop Honky",
|
129
|
+
"city": "Portland",
|
130
|
+
"description": "I BELIEVE.....\r\n\r\n",
|
131
|
+
"discogs_name": null,
|
132
|
+
"myspace_name": null,
|
133
|
+
"website": null,
|
134
|
+
"website_title": null,
|
135
|
+
"online": false,
|
136
|
+
"track_count": 4,
|
137
|
+
"playlist_count": 0,
|
138
|
+
"followers_count": 9,
|
139
|
+
"followings_count": 0,
|
140
|
+
"public_favorites_count": 0
|
141
|
+
}
|
142
|
+
]
|
143
|
+
JS
|
144
|
+
|
145
|
+
track: <<-JS.gsub(/\s+/, " "),
|
146
|
+
{
|
147
|
+
"id": 13158665,
|
148
|
+
"created_at": "2011/04/06 15:37:43 +0000",
|
149
|
+
"user_id": 3699101,
|
150
|
+
"duration": 18109,
|
151
|
+
"commentable": true,
|
152
|
+
"state": "finished",
|
153
|
+
"sharing": "public",
|
154
|
+
"tag_list": "soundcloud:source=iphone-record",
|
155
|
+
"permalink": "munching-at-tiannas-house",
|
156
|
+
"description": null,
|
157
|
+
"streamable": true,
|
158
|
+
"downloadable": true,
|
159
|
+
"genre": null,
|
160
|
+
"release": null,
|
161
|
+
"purchase_url": null,
|
162
|
+
"label_id": null,
|
163
|
+
"label_name": null,
|
164
|
+
"isrc": null,
|
165
|
+
"video_url": null,
|
166
|
+
"track_type": "recording",
|
167
|
+
"key_signature": null,
|
168
|
+
"bpm": null,
|
169
|
+
"title": "Munching at Tiannas house",
|
170
|
+
"release_year": null,
|
171
|
+
"release_month": null,
|
172
|
+
"release_day": null,
|
173
|
+
"original_format": "m4a",
|
174
|
+
"original_content_size": 10211857,
|
175
|
+
"license": "all-rights-reserved",
|
176
|
+
"uri": "http://api.soundcloud.com/tracks/13158665",
|
177
|
+
"permalink_url": "http://soundcloud.com/user2835985/munching-at-tiannas-house",
|
178
|
+
"artwork_url": null,
|
179
|
+
"waveform_url": "http://w1.sndcdn.com/fxguEjG4ax6B_m.png",
|
180
|
+
"user": {
|
181
|
+
"id": 3699101,
|
182
|
+
"permalink": "user2835985",
|
183
|
+
"username": "user2835985",
|
184
|
+
"uri": "http://api.soundcloud.com/users/3699101",
|
185
|
+
"permalink_url": "http://soundcloud.com/user2835985",
|
186
|
+
"avatar_url": "http://a1.sndcdn.com/images/default_avatar_large.png?142a848"
|
187
|
+
},
|
188
|
+
"stream_url": "http://api.soundcloud.com/tracks/13158665/stream",
|
189
|
+
"download_url": "http://api.soundcloud.com/tracks/13158665/download",
|
190
|
+
"playback_count": 0,
|
191
|
+
"download_count": 0,
|
192
|
+
"favoritings_count": 0,
|
193
|
+
"comment_count": 0,
|
194
|
+
"created_with": {
|
195
|
+
"id": 124,
|
196
|
+
"name": "SoundCloud iPhone",
|
197
|
+
"uri": "http://api.soundcloud.com/apps/124",
|
198
|
+
"permalink_url": "http://soundcloud.com/apps/iphone"
|
199
|
+
},
|
200
|
+
"attachments_uri": "http://api.soundcloud.com/tracks/13158665/attachments"
|
201
|
+
}
|
202
|
+
JS
|
203
|
+
|
204
|
+
playlist: <<-JS.gsub(/\s+/, " "),
|
205
|
+
{
|
206
|
+
"id": 405726,
|
207
|
+
"created_at": "2010/11/02 09:24:50 +0000",
|
208
|
+
"user_id": 3207,
|
209
|
+
"duration": 154516,
|
210
|
+
"sharing": "public",
|
211
|
+
"tag_list": "",
|
212
|
+
"permalink": "field-recordings",
|
213
|
+
"description": "a couple of field recordings to test http://soundiverse.com.\r\n\r\nrecorded with the fire recorder: http://soundcloud.com/apps/fire",
|
214
|
+
"streamable": true,
|
215
|
+
"downloadable": true,
|
216
|
+
"genre": "",
|
217
|
+
"release": "",
|
218
|
+
"purchase_url": null,
|
219
|
+
"label_id": null,
|
220
|
+
"label_name": "",
|
221
|
+
"type": "other",
|
222
|
+
"playlist_type": "other",
|
223
|
+
"ean": "",
|
224
|
+
"title": "Field Recordings",
|
225
|
+
"release_year": null,
|
226
|
+
"release_month": null,
|
227
|
+
"release_day": null,
|
228
|
+
"license": "cc-by",
|
229
|
+
"uri": "http://api.soundcloud.com/playlists/405726",
|
230
|
+
"permalink_url": "http://soundcloud.com/jwagener/sets/field-recordings",
|
231
|
+
"artwork_url": null,
|
232
|
+
"user": {
|
233
|
+
"id": 3207,
|
234
|
+
"permalink": "jwagener",
|
235
|
+
"username": "Johannes Wagener",
|
236
|
+
"uri": "http://api.soundcloud.com/users/3207",
|
237
|
+
"permalink_url": "http://soundcloud.com/jwagener",
|
238
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000001552142-pbw8yd-large.jpg?142a848"
|
239
|
+
},
|
240
|
+
"tracks": [
|
241
|
+
{
|
242
|
+
"id": 6621631,
|
243
|
+
"created_at": "2010/11/02 09:08:43 +0000",
|
244
|
+
"user_id": 3207,
|
245
|
+
"duration": 27099,
|
246
|
+
"commentable": true,
|
247
|
+
"state": "finished",
|
248
|
+
"sharing": "public",
|
249
|
+
"tag_list": "Fieldrecording geo:lat=52.527544 geo:lon=13.402905",
|
250
|
+
"permalink": "coffee-machine",
|
251
|
+
"description": "",
|
252
|
+
"streamable": true,
|
253
|
+
"downloadable": true,
|
254
|
+
"genre": "",
|
255
|
+
"release": "",
|
256
|
+
"purchase_url": null,
|
257
|
+
"label_id": null,
|
258
|
+
"label_name": "",
|
259
|
+
"isrc": "",
|
260
|
+
"video_url": null,
|
261
|
+
"track_type": "",
|
262
|
+
"key_signature": "",
|
263
|
+
"bpm": null,
|
264
|
+
"title": "coffee machine",
|
265
|
+
"release_year": null,
|
266
|
+
"release_month": null,
|
267
|
+
"release_day": null,
|
268
|
+
"original_format": "wav",
|
269
|
+
"license": "cc-by",
|
270
|
+
"uri": "http://api.soundcloud.com/tracks/6621631",
|
271
|
+
"permalink_url": "http://soundcloud.com/jwagener/coffee-machine",
|
272
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000002863219-4zpxc0-large.jpg?142a848",
|
273
|
+
"waveform_url": "http://w1.sndcdn.com/Yva1Qimi7TVd_m.png",
|
274
|
+
"user": {
|
275
|
+
"id": 3207,
|
276
|
+
"permalink": "jwagener",
|
277
|
+
"username": "Johannes Wagener",
|
278
|
+
"uri": "http://api.soundcloud.com/users/3207",
|
279
|
+
"permalink_url": "http://soundcloud.com/jwagener",
|
280
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000001552142-pbw8yd-large.jpg?142a848"
|
281
|
+
},
|
282
|
+
"stream_url": "http://api.soundcloud.com/tracks/6621631/stream",
|
283
|
+
"download_url": "http://api.soundcloud.com/tracks/6621631/download",
|
284
|
+
"playback_count": 436,
|
285
|
+
"download_count": 40,
|
286
|
+
"favoritings_count": 9,
|
287
|
+
"comment_count": 0,
|
288
|
+
"created_with": {
|
289
|
+
"id": 64,
|
290
|
+
"name": "FiRe - Field Recorder",
|
291
|
+
"uri": "http://api.soundcloud.com/apps/64",
|
292
|
+
"permalink_url": "http://soundcloud.com/apps/fire"
|
293
|
+
},
|
294
|
+
"attachments_uri": "http://api.soundcloud.com/tracks/6621631/attachments"
|
295
|
+
},
|
296
|
+
{
|
297
|
+
"id": 6621549,
|
298
|
+
"created_at": "2010/11/02 09:00:23 +0000",
|
299
|
+
"user_id": 3207,
|
300
|
+
"duration": 65618,
|
301
|
+
"commentable": true,
|
302
|
+
"state": "finished",
|
303
|
+
"sharing": "public",
|
304
|
+
"tag_list": "Fieldrecording geo:lat=52.528181 geo:lon=13.412658",
|
305
|
+
"permalink": "tram-in-berlin",
|
306
|
+
"description": "",
|
307
|
+
"streamable": true,
|
308
|
+
"downloadable": true,
|
309
|
+
"genre": "",
|
310
|
+
"release": "",
|
311
|
+
"purchase_url": null,
|
312
|
+
"label_id": null,
|
313
|
+
"label_name": "",
|
314
|
+
"isrc": "",
|
315
|
+
"video_url": null,
|
316
|
+
"track_type": "recording",
|
317
|
+
"key_signature": "",
|
318
|
+
"bpm": null,
|
319
|
+
"title": "tram in berlin",
|
320
|
+
"release_year": null,
|
321
|
+
"release_month": null,
|
322
|
+
"release_day": null,
|
323
|
+
"original_format": "wav",
|
324
|
+
"license": "cc-by",
|
325
|
+
"uri": "http://api.soundcloud.com/tracks/6621549",
|
326
|
+
"permalink_url": "http://soundcloud.com/jwagener/tram-in-berlin",
|
327
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000002863163-6f2aqe-large.jpg?142a848",
|
328
|
+
"waveform_url": "http://w1.sndcdn.com/u04ibjx6FYdM_m.png",
|
329
|
+
"user": {
|
330
|
+
"id": 3207,
|
331
|
+
"permalink": "jwagener",
|
332
|
+
"username": "Johannes Wagener",
|
333
|
+
"uri": "http://api.soundcloud.com/users/3207",
|
334
|
+
"permalink_url": "http://soundcloud.com/jwagener",
|
335
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000001552142-pbw8yd-large.jpg?142a848"
|
336
|
+
},
|
337
|
+
"stream_url": "http://api.soundcloud.com/tracks/6621549/stream",
|
338
|
+
"download_url": "http://api.soundcloud.com/tracks/6621549/download",
|
339
|
+
"playback_count": 231,
|
340
|
+
"download_count": 36,
|
341
|
+
"favoritings_count": 3,
|
342
|
+
"comment_count": 1,
|
343
|
+
"created_with": {
|
344
|
+
"id": 64,
|
345
|
+
"name": "FiRe - Field Recorder",
|
346
|
+
"uri": "http://api.soundcloud.com/apps/64",
|
347
|
+
"permalink_url": "http://soundcloud.com/apps/fire"
|
348
|
+
},
|
349
|
+
"attachments_uri": "http://api.soundcloud.com/tracks/6621549/attachments"
|
350
|
+
},
|
351
|
+
{
|
352
|
+
"id": 6668072,
|
353
|
+
"created_at": "2010/11/03 19:47:11 +0000",
|
354
|
+
"user_id": 3207,
|
355
|
+
"duration": 21871,
|
356
|
+
"commentable": true,
|
357
|
+
"state": "finished",
|
358
|
+
"sharing": "public",
|
359
|
+
"tag_list": "geo:lat=52.527529 geo:lon=13.402961",
|
360
|
+
"permalink": "alex-playing-drums",
|
361
|
+
"description": "",
|
362
|
+
"streamable": true,
|
363
|
+
"downloadable": true,
|
364
|
+
"genre": null,
|
365
|
+
"release": "",
|
366
|
+
"purchase_url": null,
|
367
|
+
"label_id": null,
|
368
|
+
"label_name": "",
|
369
|
+
"isrc": "",
|
370
|
+
"video_url": null,
|
371
|
+
"track_type": "recording",
|
372
|
+
"key_signature": "",
|
373
|
+
"bpm": null,
|
374
|
+
"title": "alex playing drums",
|
375
|
+
"release_year": null,
|
376
|
+
"release_month": null,
|
377
|
+
"release_day": null,
|
378
|
+
"original_format": "wav",
|
379
|
+
"license": "cc-by",
|
380
|
+
"uri": "http://api.soundcloud.com/tracks/6668072",
|
381
|
+
"permalink_url": "http://soundcloud.com/jwagener/alex-playing-drums",
|
382
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000002888918-takbu6-large.jpg?142a848",
|
383
|
+
"waveform_url": "http://w1.sndcdn.com/MQnxWxIH94ai_m.png",
|
384
|
+
"user": {
|
385
|
+
"id": 3207,
|
386
|
+
"permalink": "jwagener",
|
387
|
+
"username": "Johannes Wagener",
|
388
|
+
"uri": "http://api.soundcloud.com/users/3207",
|
389
|
+
"permalink_url": "http://soundcloud.com/jwagener",
|
390
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000001552142-pbw8yd-large.jpg?142a848"
|
391
|
+
},
|
392
|
+
"stream_url": "http://api.soundcloud.com/tracks/6668072/stream",
|
393
|
+
"download_url": "http://api.soundcloud.com/tracks/6668072/download",
|
394
|
+
"playback_count": 179,
|
395
|
+
"download_count": 35,
|
396
|
+
"favoritings_count": 1,
|
397
|
+
"comment_count": 1,
|
398
|
+
"created_with": {
|
399
|
+
"id": 64,
|
400
|
+
"name": "FiRe - Field Recorder",
|
401
|
+
"uri": "http://api.soundcloud.com/apps/64",
|
402
|
+
"permalink_url": "http://soundcloud.com/apps/fire"
|
403
|
+
},
|
404
|
+
"attachments_uri": "http://api.soundcloud.com/tracks/6668072/attachments"
|
405
|
+
},
|
406
|
+
{
|
407
|
+
"id": 6698933,
|
408
|
+
"created_at": "2010/11/04 19:09:32 +0000",
|
409
|
+
"user_id": 3207,
|
410
|
+
"duration": 12726,
|
411
|
+
"commentable": true,
|
412
|
+
"state": "finished",
|
413
|
+
"sharing": "public",
|
414
|
+
"tag_list": "geo:lat=52.528450 geo:lon=13.404099",
|
415
|
+
"permalink": "typing",
|
416
|
+
"description": "",
|
417
|
+
"streamable": true,
|
418
|
+
"downloadable": true,
|
419
|
+
"genre": null,
|
420
|
+
"release": "",
|
421
|
+
"purchase_url": null,
|
422
|
+
"label_id": null,
|
423
|
+
"label_name": "",
|
424
|
+
"isrc": "",
|
425
|
+
"video_url": null,
|
426
|
+
"track_type": "recording",
|
427
|
+
"key_signature": "",
|
428
|
+
"bpm": null,
|
429
|
+
"title": "typing",
|
430
|
+
"release_year": null,
|
431
|
+
"release_month": null,
|
432
|
+
"release_day": null,
|
433
|
+
"original_format": "wav",
|
434
|
+
"license": "cc-by",
|
435
|
+
"uri": "http://api.soundcloud.com/tracks/6698933",
|
436
|
+
"permalink_url": "http://soundcloud.com/jwagener/typing",
|
437
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000002903990-le6t7d-large.jpg?142a848",
|
438
|
+
"waveform_url": "http://w1.sndcdn.com/ZSil4IqhP6Hh_m.png",
|
439
|
+
"user": {
|
440
|
+
"id": 3207,
|
441
|
+
"permalink": "jwagener",
|
442
|
+
"username": "Johannes Wagener",
|
443
|
+
"uri": "http://api.soundcloud.com/users/3207",
|
444
|
+
"permalink_url": "http://soundcloud.com/jwagener",
|
445
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000001552142-pbw8yd-large.jpg?142a848"
|
446
|
+
},
|
447
|
+
"stream_url": "http://api.soundcloud.com/tracks/6698933/stream",
|
448
|
+
"download_url": "http://api.soundcloud.com/tracks/6698933/download",
|
449
|
+
"playback_count": 132,
|
450
|
+
"download_count": 29,
|
451
|
+
"favoritings_count": 0,
|
452
|
+
"comment_count": 0,
|
453
|
+
"created_with": {
|
454
|
+
"id": 64,
|
455
|
+
"name": "FiRe - Field Recorder",
|
456
|
+
"uri": "http://api.soundcloud.com/apps/64",
|
457
|
+
"permalink_url": "http://soundcloud.com/apps/fire"
|
458
|
+
},
|
459
|
+
"attachments_uri": "http://api.soundcloud.com/tracks/6698933/attachments"
|
460
|
+
},
|
461
|
+
{
|
462
|
+
"id": 6770077,
|
463
|
+
"created_at": "2010/11/07 02:45:11 +0000",
|
464
|
+
"user_id": 3207,
|
465
|
+
"duration": 27202,
|
466
|
+
"commentable": true,
|
467
|
+
"state": "finished",
|
468
|
+
"sharing": "public",
|
469
|
+
"tag_list": "geo:lat=52.531203 geo:lon=13.412165",
|
470
|
+
"permalink": "bassy",
|
471
|
+
"description": "",
|
472
|
+
"streamable": true,
|
473
|
+
"downloadable": true,
|
474
|
+
"genre": "",
|
475
|
+
"release": "",
|
476
|
+
"purchase_url": null,
|
477
|
+
"label_id": null,
|
478
|
+
"label_name": "",
|
479
|
+
"isrc": "",
|
480
|
+
"video_url": null,
|
481
|
+
"track_type": "recording",
|
482
|
+
"key_signature": "",
|
483
|
+
"bpm": null,
|
484
|
+
"title": "bassy",
|
485
|
+
"release_year": null,
|
486
|
+
"release_month": null,
|
487
|
+
"release_day": null,
|
488
|
+
"original_format": "wav",
|
489
|
+
"license": "cc-by",
|
490
|
+
"uri": "http://api.soundcloud.com/tracks/6770077",
|
491
|
+
"permalink_url": "http://soundcloud.com/jwagener/bassy",
|
492
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000002938592-960ejc-large.jpg?142a848",
|
493
|
+
"waveform_url": "http://w1.sndcdn.com/bxaiyNJt3vWK_m.png",
|
494
|
+
"user": {
|
495
|
+
"id": 3207,
|
496
|
+
"permalink": "jwagener",
|
497
|
+
"username": "Johannes Wagener",
|
498
|
+
"uri": "http://api.soundcloud.com/users/3207",
|
499
|
+
"permalink_url": "http://soundcloud.com/jwagener",
|
500
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000001552142-pbw8yd-large.jpg?142a848"
|
501
|
+
},
|
502
|
+
"stream_url": "http://api.soundcloud.com/tracks/6770077/stream",
|
503
|
+
"download_url": "http://api.soundcloud.com/tracks/6770077/download",
|
504
|
+
"playback_count": 160,
|
505
|
+
"download_count": 20,
|
506
|
+
"favoritings_count": 0,
|
507
|
+
"comment_count": 1,
|
508
|
+
"created_with": {
|
509
|
+
"id": 64,
|
510
|
+
"name": "FiRe - Field Recorder",
|
511
|
+
"uri": "http://api.soundcloud.com/apps/64",
|
512
|
+
"permalink_url": "http://soundcloud.com/apps/fire"
|
513
|
+
},
|
514
|
+
"attachments_uri": "http://api.soundcloud.com/tracks/6770077/attachments"
|
515
|
+
}
|
516
|
+
]
|
517
|
+
}
|
518
|
+
JS
|
519
|
+
playlist: <<-JS.gsub(/\s+/, " "),
|
520
|
+
{
|
521
|
+
"id": 405726,
|
522
|
+
"tracks": [
|
523
|
+
{
|
524
|
+
"id": 6668072,
|
525
|
+
"downloadable": true,
|
526
|
+
"title": "alex playing drums",
|
527
|
+
"original_format": "wav",
|
528
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000002888918-takbu6-large.jpg?142a848",
|
529
|
+
"download_url": "http://api.soundcloud.com/tracks/6668072/download"
|
530
|
+
},
|
531
|
+
{
|
532
|
+
"id": 6698933,
|
533
|
+
"downloadable": true,
|
534
|
+
"title": "typing",
|
535
|
+
"original_format": "wav",
|
536
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000002903990-le6t7d-large.jpg?142a848",
|
537
|
+
"download_url": "http://api.soundcloud.com/tracks/6698933/download"
|
538
|
+
},
|
539
|
+
{
|
540
|
+
"id": 6770077,
|
541
|
+
"downloadable": true,
|
542
|
+
"title": "bassy",
|
543
|
+
"original_format": "wav",
|
544
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000002938592-960ejc-large.jpg?142a848",
|
545
|
+
"download_url": "http://api.soundcloud.com/tracks/6770077/download"
|
546
|
+
}
|
547
|
+
]
|
548
|
+
}
|
549
|
+
JS
|
550
|
+
|
551
|
+
group: <<-JS.gsub(/\s+/, " "),
|
552
|
+
{
|
553
|
+
"id": 3,
|
554
|
+
"created_at": "2009/06/18 15:46:46 +0000",
|
555
|
+
"permalink": "made-with-ableton-live",
|
556
|
+
"name": "Made with Ableton Live!",
|
557
|
+
"short_description": "tracks produced with Ableton Live! music software, no DJ mixes!",
|
558
|
+
"description": "send your tracks, no DJ mixes please!",
|
559
|
+
"uri": "http://api.soundcloud.com/groups/3",
|
560
|
+
"artwork_url": "http://i1.sndcdn.com/artworks-000000481400-f0ynk3-large.jpg?142a848",
|
561
|
+
"permalink_url": "http://soundcloud.com/groups/made-with-ableton-live",
|
562
|
+
"creator": {
|
563
|
+
"id": 1433,
|
564
|
+
"permalink": "matas",
|
565
|
+
"username": "matas",
|
566
|
+
"uri": "http://api.soundcloud.com/users/1433",
|
567
|
+
"permalink_url": "http://soundcloud.com/matas",
|
568
|
+
"avatar_url": "http://i1.sndcdn.com/avatars-000001548772-zay6dy-large.jpg?142a848"
|
569
|
+
}
|
570
|
+
}
|
571
|
+
JS
|
572
|
+
|
573
|
+
}
|
574
|
+
|
575
|
+
RESPONSE_HEADERS = { 'Content-Type' => 'application/json' }
|
576
|
+
|
577
|
+
STUBS = Faraday::Adapter::Test::Stubs.new do |stub|
|
578
|
+
stub.get('/me/playlists') { [200, RESPONSE_HEADERS.dup, "[#{SAMPLES[:playlist]}]"] }
|
579
|
+
stub.get('/me/playlists?offset=50') { [200, RESPONSE_HEADERS.dup, "[#{SAMPLES[:playlist]},#{SAMPLES[:playlist]}]"] }
|
580
|
+
stub.get('/me/tracks?filter=downloadable&offset=0') { [200, RESPONSE_HEADERS.dup, "[#{SAMPLES[:track]}]"] }
|
581
|
+
stub.get('/playlists/405726') { [200, RESPONSE_HEADERS.dup, "#{SAMPLES[:playlist]}"] }
|
582
|
+
stub.get('/me/followings?offset=0') { [200, RESPONSE_HEADERS.dup, "[#{SAMPLES[:user]}]"] }
|
583
|
+
stub.get('/users/1234/playlists?offset=0') { [200, RESPONSE_HEADERS.dup, "[#{SAMPLES[:playlist]},#{SAMPLES[:playlist]}]"] }
|
584
|
+
%w"playlist%5Btitle%5D=test%20set&playlist%5Bsharing%5D=public&
|
585
|
+
playlist%5Btitle%5D=test%20set&playlist%5Bsharing%5D=public
|
586
|
+
playlist%5Bsharing%5D=public&playlist%5Btitle%5D=test%20set&".each do |body|
|
587
|
+
stub.post("/playlists", body) do
|
588
|
+
[201, RESPONSE_HEADERS.dup, SAMPLES[:playlist].dup]
|
589
|
+
end
|
590
|
+
end
|
591
|
+
stub.delete("/playlists/405726") {[200, RESPONSE_HEADERS.dup, ""]}
|
592
|
+
stub.post "/tracks" do
|
593
|
+
[201, RESPONSE_HEADERS.dup, SAMPLES[:track].dup]
|
594
|
+
end
|
595
|
+
stub.put("/playlists/405726") {[200, RESPONSE_HEADERS.dup, ""]}
|
596
|
+
stub.get("/tracks/13158665") { [200, RESPONSE_HEADERS.dup, "#{SAMPLES[:track]}"] }
|
597
|
+
stub.get("/me/favorites?filter=downloadable&offset=0") { [200, RESPONSE_HEADERS.dup, JSON.dump(JSON.parse(SAMPLES[:playlist])["tracks"])] }
|
598
|
+
stub.get("/me/favorites?filter=downloadable&offset=50") { [200, RESPONSE_HEADERS.dup, JSON.dump(JSON.parse(SAMPLES[:playlist])["tracks"])] }
|
599
|
+
stub.put("/me/favorites/13158665") { [200, RESPONSE_HEADERS.dup, "#{SAMPLES[:track]}"] }
|
600
|
+
stub.get("/tracks") { [200, RESPONSE_HEADERS.dup, "[#{SAMPLES[:track]}]"] }
|
601
|
+
stub.get("/tracks/123") { [200, RESPONSE_HEADERS.dup, "#{SAMPLES[:track]}"] }
|
602
|
+
stub.get("/tracks/124") { [404, RESPONSE_HEADERS.dup, "{'error': 'not found', 'status': 404}"] }
|
603
|
+
stub.get("/users/bleh/playlists") { [503, {}, "{'error': 'service unavailable', 'status': 503}"] }
|
604
|
+
stub.get("/users/haproxy_error/playlists") do [503, {'Content-Type' => 'text/html'}, <<-HTML]
|
605
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
606
|
+
<html lang="en">
|
607
|
+
<head>
|
608
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
609
|
+
<title>We were unable to process your request in time - SoundCloud</title>
|
610
|
+
</head>
|
611
|
+
<body>
|
612
|
+
<div id="maintenance">
|
613
|
+
<h1> Yikes, we were unable <br /> to process your request <br /> in time. </h1>
|
614
|
+
<span> Please reload the page or try again in a moment. </span>
|
615
|
+
</div>
|
616
|
+
</body>
|
617
|
+
</html>
|
618
|
+
HTML
|
619
|
+
end
|
620
|
+
end
|