tvdb_client 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/.rubyversion +1 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +2 -0
- data/Guardfile +20 -0
- data/README.md +43 -0
- data/Rakefile +9 -0
- data/conf/settings.example.yml +7 -0
- data/lib/tvdb_client.rb +13 -0
- data/lib/tvdb_client/authorization.rb +46 -0
- data/lib/tvdb_client/client.rb +30 -0
- data/lib/tvdb_client/connection.rb +98 -0
- data/lib/tvdb_client/series.rb +54 -0
- data/lib/tvdb_client/series/base.rb +32 -0
- data/lib/tvdb_client/series/series_episodes.rb +18 -0
- data/lib/tvdb_client/series/series_filter.rb +21 -0
- data/lib/tvdb_client/series/series_images.rb +14 -0
- data/lib/tvdb_client/service/threading.rb +8 -0
- data/lib/tvdb_client/service/threading/threaded_request.rb +51 -0
- data/lib/tvdb_client/settings.rb +10 -0
- data/lib/tvdb_client/version.rb +3 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/support/fake_TVDB.rb +118 -0
- data/spec/support/fixtures/responses/login.json +3 -0
- data/spec/support/fixtures/responses/refresh_token.json +3 -0
- data/spec/support/fixtures/responses/series.json +33 -0
- data/spec/support/fixtures/responses/series_episodes_page_1.json +56 -0
- data/spec/support/fixtures/responses/series_episodes_page_2.json +56 -0
- data/spec/support/fixtures/responses/series_episodes_page_n.json +41 -0
- data/spec/support/fixtures/responses/series_episodes_query_airedSeason.json +41 -0
- data/spec/support/fixtures/responses/series_episodes_query_params.json +12 -0
- data/spec/support/fixtures/responses/series_episodes_summary.json +26 -0
- data/spec/support/fixtures/responses/series_filter.json +5 -0
- data/spec/support/fixtures/responses/series_filter_params.json +27 -0
- data/spec/support/fixtures/responses/series_images.json +9 -0
- data/spec/support/fixtures/responses/series_images_query.json +35 -0
- data/spec/support/fixtures/responses/series_images_query_params.json +60 -0
- data/spec/support/fixtures/settings.example.yml +6 -0
- data/spec/support/shared_contexts/authentication.rb +13 -0
- data/spec/support/shared_contexts/connection.rb +20 -0
- data/spec/support/shared_contexts/credentials.rb +20 -0
- data/spec/support/shared_contexts/series_subclass.rb +19 -0
- data/spec/tvdb_client/authorization_spec.rb +69 -0
- data/spec/tvdb_client/client_spec.rb +45 -0
- data/spec/tvdb_client/connection_spec.rb +159 -0
- data/spec/tvdb_client/series/base_spec.rb +13 -0
- data/spec/tvdb_client/series/series_episodes_spec.rb +55 -0
- data/spec/tvdb_client/series/series_filter_spec.rb +45 -0
- data/spec/tvdb_client/series/series_images_spec.rb +43 -0
- data/spec/tvdb_client/series_spec.rb +69 -0
- data/spec/tvdb_client/service/threading/threaded_request_spec.rb +54 -0
- data/spec/tvdb_client/version_spec.rb +12 -0
- data/tasks/version_bump.rake +102 -0
- data/templates/changelog_entry_template.md.erb +3 -0
- data/templates/version.rb.erb +3 -0
- data/tvdb_client.gemspec +41 -0
- metadata +412 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
{
|
2
|
+
"errors": null,
|
3
|
+
"links": {
|
4
|
+
"first": 1,
|
5
|
+
"last": 1,
|
6
|
+
"next": null,
|
7
|
+
"prev": null
|
8
|
+
},
|
9
|
+
"data": [
|
10
|
+
{
|
11
|
+
"absoluteNumber": "749",
|
12
|
+
"airedEpisodeNumber": 6,
|
13
|
+
"airedSeason": "15",
|
14
|
+
"dvdEpisodeNumber": null,
|
15
|
+
"dvdSeason": null,
|
16
|
+
"episodeName": "Jostling for the Junior Cup!",
|
17
|
+
"firstAired": "2012-08-02",
|
18
|
+
"id": 4359831,
|
19
|
+
"language": {
|
20
|
+
"episodeName": "en",
|
21
|
+
"overview": "en"
|
22
|
+
},
|
23
|
+
"overview": "Ash and his friends arrive in Lacunosa Town for the Junior Cup. The Cup begins with an exhibition match between Cynthia and Caitlyn. Iris and Georgia face off against each other but Iris’ newly caught Dragonite refuses to listen to Iris’ commands."
|
24
|
+
},
|
25
|
+
{
|
26
|
+
"absoluteNumber": null,
|
27
|
+
"airedEpisodeNumber": 6,
|
28
|
+
"airedSeason": "15",
|
29
|
+
"dvdEpisodeNumber": null,
|
30
|
+
"dvdSeason": null,
|
31
|
+
"episodeName": "Battling on thin ice!",
|
32
|
+
"firstAired": "2013-11-14",
|
33
|
+
"id": 4709580,
|
34
|
+
"language": {
|
35
|
+
"episodeName": "en",
|
36
|
+
"overview": "en"
|
37
|
+
},
|
38
|
+
"overview": "Ash challenges Viola to a rematch, now ready for Surskit's freezing strategy. "
|
39
|
+
}
|
40
|
+
]
|
41
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"data": {
|
3
|
+
"airedSeasons": [
|
4
|
+
"12",
|
5
|
+
"1",
|
6
|
+
"2",
|
7
|
+
"0",
|
8
|
+
"3",
|
9
|
+
"4",
|
10
|
+
"5",
|
11
|
+
"6",
|
12
|
+
"7",
|
13
|
+
"8",
|
14
|
+
"14",
|
15
|
+
"9",
|
16
|
+
"10",
|
17
|
+
"11",
|
18
|
+
"13",
|
19
|
+
"15",
|
20
|
+
"16"
|
21
|
+
],
|
22
|
+
"airedEpisodes": "923",
|
23
|
+
"dvdSeasons": [],
|
24
|
+
"dvdEpisodes": "0"
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
{
|
2
|
+
"data": {
|
3
|
+
"params": [
|
4
|
+
"id",
|
5
|
+
"seriesName",
|
6
|
+
"banner",
|
7
|
+
"status",
|
8
|
+
"runtime",
|
9
|
+
"lastUpdated",
|
10
|
+
"zap2itId",
|
11
|
+
"aliases",
|
12
|
+
"seriesId",
|
13
|
+
"actors",
|
14
|
+
"airsDayOfWeek",
|
15
|
+
"imdbId",
|
16
|
+
"added",
|
17
|
+
"firstAired",
|
18
|
+
"network",
|
19
|
+
"genre",
|
20
|
+
"overview",
|
21
|
+
"rating",
|
22
|
+
"addedBy",
|
23
|
+
"networkId",
|
24
|
+
"airsTime"
|
25
|
+
]
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
{
|
2
|
+
"data": [
|
3
|
+
{
|
4
|
+
"id": 24665,
|
5
|
+
"keyType": "fanart",
|
6
|
+
"subKey": "",
|
7
|
+
"fileName": "fanart/original/76703-1.jpg",
|
8
|
+
"resolution": "1280x720",
|
9
|
+
"ratingsInfo": {
|
10
|
+
"average": 6
|
11
|
+
}
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"id": 42154,
|
15
|
+
"keyType": "fanart",
|
16
|
+
"subKey": "",
|
17
|
+
"fileName": "fanart/original/76703-2.jpg",
|
18
|
+
"resolution": "1280x720",
|
19
|
+
"ratingsInfo": {
|
20
|
+
"average": 6.2
|
21
|
+
}
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"id": 42155,
|
25
|
+
"keyType": "fanart",
|
26
|
+
"subKey": "",
|
27
|
+
"fileName": "fanart/original/76703-3.jpg",
|
28
|
+
"resolution": "1280x720",
|
29
|
+
"ratingsInfo": {
|
30
|
+
"average": 6.375
|
31
|
+
}
|
32
|
+
}
|
33
|
+
],
|
34
|
+
"errors": null
|
35
|
+
}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
{
|
2
|
+
"data": [
|
3
|
+
{
|
4
|
+
"keyType": "fanart",
|
5
|
+
"resolution": [
|
6
|
+
"1920x1080",
|
7
|
+
"1280x720"
|
8
|
+
],
|
9
|
+
"subKey": [
|
10
|
+
"graphical",
|
11
|
+
"text"
|
12
|
+
]
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"keyType": "poster",
|
16
|
+
"resolution": "680x1000",
|
17
|
+
"subKey": null
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"keyType": "season",
|
21
|
+
"resolution": null,
|
22
|
+
"subKey": [
|
23
|
+
"13",
|
24
|
+
"7",
|
25
|
+
"6",
|
26
|
+
"5",
|
27
|
+
"4",
|
28
|
+
"3",
|
29
|
+
"2",
|
30
|
+
"1",
|
31
|
+
"14",
|
32
|
+
"15",
|
33
|
+
"8",
|
34
|
+
"9",
|
35
|
+
"10",
|
36
|
+
"16",
|
37
|
+
"12",
|
38
|
+
"11",
|
39
|
+
"0"
|
40
|
+
]
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"keyType": "seasonwide",
|
44
|
+
"resolution": null,
|
45
|
+
"subKey": [
|
46
|
+
"10",
|
47
|
+
"1"
|
48
|
+
]
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"keyType": "series",
|
52
|
+
"resolution": null,
|
53
|
+
"subKey": [
|
54
|
+
"graphical",
|
55
|
+
"blank",
|
56
|
+
"text"
|
57
|
+
]
|
58
|
+
}
|
59
|
+
]
|
60
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
shared_context "Authentication" do
|
5
|
+
include_context "Credentials"
|
6
|
+
include_context "Connection"
|
7
|
+
|
8
|
+
def authenticate_connection
|
9
|
+
valid_creds[:connection] = connection
|
10
|
+
|
11
|
+
TVDB::Authorization.new( valid_creds ).login
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
shared_context "Connection" do
|
5
|
+
let( :connection_options ) {
|
6
|
+
{
|
7
|
+
host_url: "https://api.thetvdb.localhost.com"
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
let( :connection ) {
|
12
|
+
TVDB::Connection.new( host_url: connection_options[:host_url] )
|
13
|
+
}
|
14
|
+
|
15
|
+
def authenticate_connection
|
16
|
+
valid_creds[:connection] = connection
|
17
|
+
|
18
|
+
TVDB::Authorization.new( valid_creds ).login
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
shared_context "Credentials" do
|
5
|
+
let( :valid_creds ) {
|
6
|
+
{
|
7
|
+
:username => "validuser",
|
8
|
+
:userpass => "validpass",
|
9
|
+
:apikey => "validapikey"
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
let( :invalid_creds ) {
|
14
|
+
{
|
15
|
+
:username => "invaliduser",
|
16
|
+
:userpass => "invalidpass",
|
17
|
+
:apikey => "invalidapikey"
|
18
|
+
}
|
19
|
+
}
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
shared_context "Series Subclass" do
|
5
|
+
include_context "Authentication"
|
6
|
+
|
7
|
+
before( :each ) do
|
8
|
+
authenticate_connection
|
9
|
+
end
|
10
|
+
|
11
|
+
let( :series_id ) { '76703' }
|
12
|
+
|
13
|
+
let( :series_opts ) {
|
14
|
+
{
|
15
|
+
connection: connection,
|
16
|
+
series_id: series_id,
|
17
|
+
}
|
18
|
+
}
|
19
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe "TVDB::Authorization" do
|
5
|
+
|
6
|
+
include_context "Connection"
|
7
|
+
include_context "Credentials"
|
8
|
+
|
9
|
+
let( :valid_init_options ) {
|
10
|
+
valid_creds[:connection] = connection
|
11
|
+
valid_creds
|
12
|
+
}
|
13
|
+
|
14
|
+
let( :invalid_init_options ) {
|
15
|
+
invalid_creds[:connection] = connection
|
16
|
+
invalid_creds
|
17
|
+
}
|
18
|
+
|
19
|
+
subject { TVDB::Authorization.new( valid_init_options ) }
|
20
|
+
|
21
|
+
describe "initialization" do
|
22
|
+
it "should create a TVDB::Authorization object" do
|
23
|
+
expect( subject ).to be_a_kind_of( TVDB::Authorization )
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should have a connection accessor" do
|
27
|
+
expect( subject ).to respond_to( :connection )
|
28
|
+
|
29
|
+
subject.connection.token = "pudding"
|
30
|
+
expect( subject.connection.token ).to eq( "pudding" )
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "Authentication" do
|
35
|
+
context 'Logging in' do
|
36
|
+
it "should be able to log in" do
|
37
|
+
expect( subject ).to respond_to( :login )
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should set a token on the connection object upon successful login" do
|
41
|
+
subject.login
|
42
|
+
|
43
|
+
expect( subject.connection.token ).to be_a_kind_of( String )
|
44
|
+
expect( subject.connection.token.length > 1 ).to be( true )
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should not set a token upon failed login" do
|
48
|
+
failure = TVDB::Authorization.new( invalid_init_options )
|
49
|
+
failure.login
|
50
|
+
|
51
|
+
expect( failure.connection.token.length > 1 ).to be( false )
|
52
|
+
expect( failure.login.code ).to be( 401 )
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'Refreshing tokens' do
|
57
|
+
it "should refresh a valid token" do
|
58
|
+
subject.login
|
59
|
+
old_token = subject.connection.token
|
60
|
+
|
61
|
+
subject.refresh_token
|
62
|
+
new_token = subject.connection.token
|
63
|
+
|
64
|
+
expect( old_token ).not_to eq( new_token )
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe "TVDB::Client" do
|
5
|
+
|
6
|
+
include_context "Credentials"
|
7
|
+
|
8
|
+
subject { TVDB::Client.new( valid_creds ) }
|
9
|
+
|
10
|
+
describe "Initialization" do
|
11
|
+
it "should require user credentials" do
|
12
|
+
expect { TVDB::Client.new( invalid_creds ) }.to raise_error( RuntimeError )
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should authenticate the user and set a token" do
|
16
|
+
expect( subject.connection.token ).to be_a_kind_of( String )
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should set an auth accessor" do
|
20
|
+
expect( subject.auth ).to be_a_kind_of( TVDB::Authorization )
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "Authentication" do
|
25
|
+
it "should refresh the user's token" do
|
26
|
+
old_token = subject.connection.token
|
27
|
+
subject.refresh_token
|
28
|
+
|
29
|
+
expect( subject.connection.token ).not_to eq( old_token )
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "Functionality" do
|
34
|
+
context 'Series' do
|
35
|
+
it "should return a series object" do
|
36
|
+
pokemon = subject.series( '76703')
|
37
|
+
|
38
|
+
expect( pokemon ).to be_a_kind_of( TVDB::Series )
|
39
|
+
expect( pokemon.data ).to be_a_kind_of( Hash )
|
40
|
+
expect( pokemon.data ).to have_key( "data" )
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe "TVDB::Connection" do
|
5
|
+
|
6
|
+
include_context "Connection"
|
7
|
+
|
8
|
+
let( :convenience_headers ) {
|
9
|
+
{:language => "derp", :version => "12345", :modified_since => "Tuesday"}
|
10
|
+
}
|
11
|
+
|
12
|
+
subject { TVDB::Connection.new( connection_options ) }
|
13
|
+
|
14
|
+
describe "Initialization" do
|
15
|
+
|
16
|
+
it "should createa a connection and set attrs" do
|
17
|
+
expect( subject.connection ).to be_a_kind_of( Faraday::Connection )
|
18
|
+
expect( subject.host_url ).to eq( connection_options[:host_url] )
|
19
|
+
expect( subject.token ).to eq( "" )
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should setup a Response struct" do
|
23
|
+
expect( subject.response_struct ).to be_a_kind_of( Class )
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "Ancillary operations" do
|
29
|
+
|
30
|
+
context 'headers' do
|
31
|
+
it "should set default headers for requests" do
|
32
|
+
expect( subject.set_default_headers( {} ) ).to be_a_kind_of( Hash )
|
33
|
+
expect( subject.set_default_headers( {} )["Content-Type"] ).to eq( "application/json" )
|
34
|
+
expect( subject.set_default_headers( {} )["Authorization"] ).to eq( "Bearer " )
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should override default headers " do
|
38
|
+
custom_header = { :headers => { "Content-Type" => "text/html" } }
|
39
|
+
|
40
|
+
expect( subject.set_default_headers( custom_header )["Content-Type"] ).to eq( "text/html" )
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should apply custom headers" do
|
44
|
+
custom_header = { :headers => { "howdy" => "g'day mate" } }
|
45
|
+
|
46
|
+
expect( subject.set_default_headers( custom_header )["howdy"] ).to eq( "g'day mate" )
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should set the langauge or version if passed in" do
|
50
|
+
subject.set_convenience_headers( convenience_headers )
|
51
|
+
|
52
|
+
expect( subject.language ).to eq( "derp" )
|
53
|
+
expect( subject.version ).to eq( "12345" )
|
54
|
+
expect( subject.modified_since ).to eq( "Tuesday" )
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'responses' do
|
59
|
+
let( :route ) { "/login" }
|
60
|
+
let( :response ) { subject.post( route, body: {} ) }
|
61
|
+
|
62
|
+
it "should store responses in a struct" do
|
63
|
+
expect( response ).to be_a_kind_of( Struct )
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should set a code accessor" do
|
67
|
+
expect( response ).to respond_to( :code )
|
68
|
+
expect( response.code ).to eq( 401 )
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should set a body accessor" do
|
72
|
+
expect( response ).to respond_to( :body )
|
73
|
+
expect( response.body ).to eq( {"Error"=>"API Key Required"} )
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should set a headers accessor" do
|
77
|
+
expect( response ).to respond_to( :headers )
|
78
|
+
expect( response.headers ).to be_a_kind_of( Hash )
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should set a request_url accessor" do
|
82
|
+
expect( response ).to respond_to( :request_url )
|
83
|
+
expect( response.request_url ).to eq( "#{connection_options[:host_url]}#{route}")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "REST operations" do
|
89
|
+
include_context "Credentials"
|
90
|
+
|
91
|
+
describe 'POSTing' do
|
92
|
+
|
93
|
+
let( :post_params ) {
|
94
|
+
{
|
95
|
+
:body => { :bacon => "tasty" }
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
it "should be able to POST json to a route" do
|
100
|
+
expect( subject ).to respond_to( :post )
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'Authorized requests' do
|
104
|
+
let( :successful_post ) {
|
105
|
+
subject.post( '/login', body: valid_creds )
|
106
|
+
}
|
107
|
+
|
108
|
+
it "should return a 200 upon successful POST" do
|
109
|
+
expect( successful_post.code ).to be( 200 )
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should return response headers" do
|
113
|
+
expect( successful_post.headers["content-type"] ).to eq( "application/json" )
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'Unauthorized requests' do
|
118
|
+
it "should return a 401 if unathorized" do
|
119
|
+
expect( subject.post( '/login', post_params ).code ).to be( 401 )
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "GETing" do
|
126
|
+
it "should be able to GET a route" do
|
127
|
+
expect( subject ).to respond_to( :get )
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should take optional parameters" do
|
131
|
+
param_req = subject.get( '/series/1234', :page => 1 )
|
132
|
+
expect( param_req.request_url ).to match( 'page=1' )
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should override existing convenience headers" do
|
136
|
+
subject.get( '/series/1234', convenience_headers )
|
137
|
+
|
138
|
+
convenience_headers.each do |accessor, value|
|
139
|
+
expect( subject.send( accessor ) ).to eq( value )
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'Unauthorized requests' do
|
144
|
+
it "should return a 401 if unathorized" do
|
145
|
+
expect( subject.get( '/series/1234' ).code ).to be( 401 )
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context '304 response' do
|
150
|
+
it "should an empty body for a 304 (not modified) response" do
|
151
|
+
expect( subject.get( '/not/modified' ).code ).to be( 304 )
|
152
|
+
expect( subject.get( '/not/modified' ).body ).to be( nil )
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|