bbc_redux 0.4.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +8 -0
- data/COPYING +212 -0
- data/Gemfile +3 -0
- data/README.md +174 -0
- data/Rakefile +47 -0
- data/bbc_redux.gemspec +61 -0
- data/lib/bbc/redux/asset.rb +119 -0
- data/lib/bbc/redux/channel.rb +45 -0
- data/lib/bbc/redux/channel_category.rb +36 -0
- data/lib/bbc/redux/client.rb +302 -0
- data/lib/bbc/redux/end_points.rb +78 -0
- data/lib/bbc/redux/key.rb +73 -0
- data/lib/bbc/redux/media_url.rb +123 -0
- data/lib/bbc/redux/search_results.rb +82 -0
- data/lib/bbc/redux/serializers.rb +101 -0
- data/lib/bbc/redux/user.rb +107 -0
- data/lib/bbc/redux/version.rb +8 -0
- data/lib/bbc/redux.rb +10 -0
- data/spec/bbc/redux/asset_spec.rb +45 -0
- data/spec/bbc/redux/channel_category_spec.rb +23 -0
- data/spec/bbc/redux/channel_spec.rb +24 -0
- data/spec/bbc/redux/client_spec.rb +279 -0
- data/spec/bbc/redux/key_spec.rb +66 -0
- data/spec/bbc/redux/media_url_spec.rb +151 -0
- data/spec/bbc/redux/search_results_spec.rb +69 -0
- data/spec/bbc/redux/user_spec.rb +37 -0
- data/spec/fixtures/asset.json +24 -0
- data/spec/fixtures/channel_categories.json +28 -0
- data/spec/fixtures/channels.json +51 -0
- data/spec/fixtures/search_results.json +172 -0
- data/spec/fixtures/user.json +22 -0
- data/spec/integration/bbc_redux_spec.rb +78 -0
- data/spec/spec_helper.rb +24 -0
- metadata +227 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'representable'
|
2
|
+
require 'representable/json'
|
3
|
+
require 'representable/json/collection'
|
4
|
+
|
5
|
+
require_relative 'channel'
|
6
|
+
|
7
|
+
module BBC
|
8
|
+
module Redux
|
9
|
+
|
10
|
+
# @private
|
11
|
+
module Serializers
|
12
|
+
|
13
|
+
class Asset < Representable::Decorator
|
14
|
+
include Representable::JSON
|
15
|
+
|
16
|
+
property :description
|
17
|
+
property :access_key, :as => :key
|
18
|
+
property :name
|
19
|
+
property :reference
|
20
|
+
property :uuid
|
21
|
+
|
22
|
+
nested :timing do
|
23
|
+
property :duration
|
24
|
+
property :start
|
25
|
+
end
|
26
|
+
|
27
|
+
property :channel, :class => BBC::Redux::Channel do
|
28
|
+
property :name
|
29
|
+
property :display_name
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Channel < Representable::Decorator
|
34
|
+
include Representable::JSON
|
35
|
+
property :category_id, :as => :category
|
36
|
+
property :display_name, :as => :longname
|
37
|
+
property :name
|
38
|
+
property :sortorder
|
39
|
+
end
|
40
|
+
|
41
|
+
class Channels < Representable::Decorator
|
42
|
+
include Representable::JSON::Collection
|
43
|
+
items extend: Channel, class: BBC::Redux::Channel
|
44
|
+
end
|
45
|
+
|
46
|
+
class ChannelCategory < Representable::Decorator
|
47
|
+
include Representable::JSON
|
48
|
+
property :description
|
49
|
+
property :id
|
50
|
+
property :priority
|
51
|
+
end
|
52
|
+
|
53
|
+
class ChannelCategories < Representable::Decorator
|
54
|
+
include Representable::JSON::Collection
|
55
|
+
items extend: ChannelCategory, class: BBC::Redux::ChannelCategory
|
56
|
+
end
|
57
|
+
|
58
|
+
class SearchResults < Representable::Decorator
|
59
|
+
include Representable::JSON
|
60
|
+
property :created_at, :as => :time
|
61
|
+
property :offset
|
62
|
+
property :query
|
63
|
+
property :query_time, :as => :elapsed
|
64
|
+
property :total, :as => :total_found
|
65
|
+
property :total_returned
|
66
|
+
|
67
|
+
nested :results do
|
68
|
+
collection :assets, :extend => Asset, :class => BBC::Redux::Asset
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class User < Representable::Decorator
|
73
|
+
include Representable::JSON
|
74
|
+
|
75
|
+
property :can_invite
|
76
|
+
property :created
|
77
|
+
property :id
|
78
|
+
property :uuid
|
79
|
+
|
80
|
+
collection :permitted_services
|
81
|
+
|
82
|
+
nested :details do
|
83
|
+
property :department
|
84
|
+
property :division
|
85
|
+
property :email
|
86
|
+
property :name
|
87
|
+
property :username
|
88
|
+
end
|
89
|
+
|
90
|
+
nested :legal do
|
91
|
+
property :legal_accepted, :as => :accepted
|
92
|
+
property :legal_html
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
|
3
|
+
module BBC
|
4
|
+
module Redux
|
5
|
+
|
6
|
+
# Redux API User Object
|
7
|
+
#
|
8
|
+
# @example Properties of the user object
|
9
|
+
#
|
10
|
+
# user = redux_client.user
|
11
|
+
#
|
12
|
+
# user.can_invite? #=> Boolean
|
13
|
+
# user.created #=> DateTime
|
14
|
+
# user.email #=> String
|
15
|
+
# user.first_name #=> String
|
16
|
+
# user.id #=> Integer
|
17
|
+
# user.last_name #=> String
|
18
|
+
# user.username #=> String
|
19
|
+
# user.uuid #=> String
|
20
|
+
#
|
21
|
+
# @example Check if user can proceed or needs to sign T&C's
|
22
|
+
#
|
23
|
+
# if user.must_sign_terms?
|
24
|
+
# puts "Hey #{user.name}, you need to sign these terms"
|
25
|
+
# puts user.legal_html
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# @author Matt Haynes <matt.haynes@bbc.co.uk>
|
29
|
+
class User
|
30
|
+
|
31
|
+
include Virtus.value_object
|
32
|
+
|
33
|
+
# @!attribute [r] can_invite
|
34
|
+
# @return [Boolean] whether the user has ability to invite others to Redux
|
35
|
+
attribute :can_invite, Boolean
|
36
|
+
|
37
|
+
alias :can_invite? :can_invite
|
38
|
+
|
39
|
+
# @!attribute [r] created
|
40
|
+
# @return [DateTime] the date on which user account was created
|
41
|
+
attribute :created, DateTime
|
42
|
+
|
43
|
+
# @!attribute [r] department
|
44
|
+
# @return [String] the user's organisational department
|
45
|
+
attribute :department, String, :default => ''
|
46
|
+
|
47
|
+
# @!attribute [r] division
|
48
|
+
# @return [String] the user's organisational division
|
49
|
+
attribute :division, String, :default => ''
|
50
|
+
|
51
|
+
# @!attribute [r] email
|
52
|
+
# @return [String] the user's email
|
53
|
+
attribute :email, String, :default => ''
|
54
|
+
|
55
|
+
# @!attribute [r] id
|
56
|
+
# @return [Integer] the user's id
|
57
|
+
attribute :id, Integer
|
58
|
+
|
59
|
+
# @!attribute [r] legal_accepted
|
60
|
+
# @see User#must_sign_terms?
|
61
|
+
# @return [String] whether the user has accepted the T&C's
|
62
|
+
attribute :legal_accepted, Boolean, :default => true
|
63
|
+
|
64
|
+
# @!attribute [r] legal_html
|
65
|
+
# @return [String] a blob of T&C's HTML that the user may need to accept
|
66
|
+
attribute :legal_html, String, :default => ''
|
67
|
+
|
68
|
+
# @!attribute [r] name
|
69
|
+
# @return [String] the user's full name
|
70
|
+
attribute :name, String, :default => ''
|
71
|
+
|
72
|
+
# @!attribute [r] permitted_services
|
73
|
+
# @return [Array<String>] a list of services user has access to
|
74
|
+
attribute :permitted_services, Array[String], :default => []
|
75
|
+
|
76
|
+
# @!attribute [r] username
|
77
|
+
# @return [String] the user's username
|
78
|
+
attribute :username, String, :default => ''
|
79
|
+
|
80
|
+
# @!attribute [r] uuid
|
81
|
+
# @return [String] the user's uuid
|
82
|
+
attribute :uuid, String
|
83
|
+
|
84
|
+
# @!attribute [r] first_name
|
85
|
+
# @return [String] the user's first name
|
86
|
+
def first_name
|
87
|
+
name.split(' ').first
|
88
|
+
end
|
89
|
+
|
90
|
+
# @!attribute [r] last_name
|
91
|
+
# @return [String] the user's last name
|
92
|
+
def last_name
|
93
|
+
name.split(' ').last
|
94
|
+
end
|
95
|
+
|
96
|
+
# @!attribute [r] must_sign_terms?
|
97
|
+
# @see User#legal_accepted
|
98
|
+
# @see User#legal_html
|
99
|
+
# @return [String] whether the user must sign some T&C's before proceeding
|
100
|
+
def must_sign_terms?
|
101
|
+
!legal_accepted
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
data/lib/bbc/redux.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative 'redux/asset'
|
2
|
+
require_relative 'redux/channel'
|
3
|
+
require_relative 'redux/channel_category'
|
4
|
+
require_relative 'redux/client'
|
5
|
+
require_relative 'redux/end_points'
|
6
|
+
require_relative 'redux/key'
|
7
|
+
require_relative 'redux/media_url'
|
8
|
+
require_relative 'redux/search_results'
|
9
|
+
require_relative 'redux/serializers'
|
10
|
+
require_relative 'redux/user'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BBC::Redux::Asset do
|
4
|
+
|
5
|
+
let(:json) { read_fixture 'asset.json' }
|
6
|
+
|
7
|
+
let(:asset) { described_class.new }
|
8
|
+
|
9
|
+
let(:mapper) { BBC::Redux::Serializers::Asset }
|
10
|
+
|
11
|
+
subject { mapper.new(asset).from_json(json) }
|
12
|
+
|
13
|
+
{
|
14
|
+
|
15
|
+
# attribute => expected_value
|
16
|
+
'channel.class' => BBC::Redux::Channel,
|
17
|
+
'channel.display_name' => 'CBeebies',
|
18
|
+
'channel.name' => 'cbeebies',
|
19
|
+
:access_key => '1-1397227462-ba632af7af1ad',
|
20
|
+
:description => 'Animated adventures of Pingu. [S]',
|
21
|
+
:disk_reference => '5966413090093319525',
|
22
|
+
:duration => 300,
|
23
|
+
:key => BBC::Redux::Key.new('1-1397227462-ba632af7af1ad'),
|
24
|
+
:name => 'Pingu',
|
25
|
+
:reference => '5966413090093319525',
|
26
|
+
:start => DateTime.parse('2014-01-08 06:50:00 +0000'),
|
27
|
+
:title => 'Pingu',
|
28
|
+
:uuid => '26a141fc-8511-4fef-aa2b-af1d1de5a75a',
|
29
|
+
|
30
|
+
}.each_pair do |attribute, value|
|
31
|
+
its(attribute) { should eq(value) }
|
32
|
+
end
|
33
|
+
|
34
|
+
BBC::Redux::MediaUrl::TEMPLATES.each do |type|
|
35
|
+
describe "##{type}_url" do
|
36
|
+
it 'returns url of the correct type using the asset reference and key' do
|
37
|
+
url = subject.send(:"#{type}_url")
|
38
|
+
expect(url.type).to eq(type)
|
39
|
+
expect(url.identifier).to eq(subject.reference)
|
40
|
+
expect(url.key).to eq(subject.key)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BBC::Redux::ChannelCategory do
|
4
|
+
|
5
|
+
let(:json) { read_fixture 'channel_categories.json' }
|
6
|
+
|
7
|
+
let(:mapper) { BBC::Redux::Serializers::ChannelCategories }
|
8
|
+
|
9
|
+
subject { mapper.new([]).from_json(json) }
|
10
|
+
|
11
|
+
{
|
12
|
+
|
13
|
+
# attr / method => expected_value
|
14
|
+
'size' => 5,
|
15
|
+
'first.description' => 'BBC TV',
|
16
|
+
'first.id' => 1,
|
17
|
+
'first.priority' => 1000,
|
18
|
+
|
19
|
+
}.each_pair do |attribute, value|
|
20
|
+
its(attribute) { should eq(value) }
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BBC::Redux::Channel do
|
4
|
+
|
5
|
+
let(:json) { read_fixture 'channels.json' }
|
6
|
+
|
7
|
+
let(:mapper) { BBC::Redux::Serializers::Channels }
|
8
|
+
|
9
|
+
subject { mapper.new([]).from_json(json) }
|
10
|
+
|
11
|
+
{
|
12
|
+
|
13
|
+
# attr / method => expected_value
|
14
|
+
'size' => 8,
|
15
|
+
'first.name' => 'bbcone',
|
16
|
+
'first.display_name' => 'BBC One',
|
17
|
+
'first.category_id' => 1,
|
18
|
+
'first.sort_order' => 1010,
|
19
|
+
|
20
|
+
}.each_pair do |attribute, value|
|
21
|
+
its(attribute) { should eq(value) }
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,279 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BBC::Redux::Client do
|
4
|
+
|
5
|
+
let(:http_client) { double('http_client') }
|
6
|
+
let(:token) { 'SOME-TOKEN' }
|
7
|
+
let(:instance) {
|
8
|
+
described_class.new(:token => token, :http => http_client)
|
9
|
+
}
|
10
|
+
|
11
|
+
shared_examples_for 'a json based http method' do
|
12
|
+
let(:unknown_response) { double('http_resp', :code => rand(200..399)) }
|
13
|
+
|
14
|
+
let(:badjson_exception) { BBC::Redux::Client::JsonParseException }
|
15
|
+
let(:badjson_response) { double('http_resp', :code => 200, :body => '') }
|
16
|
+
|
17
|
+
let(:fivexx_exception) { BBC::Redux::Client::HttpException }
|
18
|
+
let(:fivexx_response) { double('http_resp', :code => rand(500..505)) }
|
19
|
+
|
20
|
+
let(:forbidden_exception) { BBC::Redux::Client::ForbiddenException }
|
21
|
+
let(:forbidden_response) { double('http_resp', :code => 403) }
|
22
|
+
|
23
|
+
it 'should raise forbidden exception when HTTP API returns 403' do
|
24
|
+
expect(http_client).to receive(:post).and_return(forbidden_response)
|
25
|
+
expect { subject }.to raise_exception(forbidden_exception)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should raise and http exception when HTTP API returns 5XX' do
|
29
|
+
expect(http_client).to receive(:post).and_return(fivexx_response)
|
30
|
+
expect { subject }.to raise_exception(fivexx_exception)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should raise a generic exception with an unknown http status' do
|
34
|
+
expect(http_client).to receive(:post).and_return(unknown_response)
|
35
|
+
expect { subject }.to raise_exception
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should raise a json parse error when backend returns junk' do
|
39
|
+
expect(http_client).to receive(:post).and_return(badjson_response)
|
40
|
+
expect { subject }.to raise_exception(badjson_exception)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'initialized with username / password' do
|
45
|
+
subject { described_class.new({
|
46
|
+
:http => http_client, :username => 'foo', :password => 'bar'
|
47
|
+
}) }
|
48
|
+
|
49
|
+
it_behaves_like 'a json based http method'
|
50
|
+
|
51
|
+
it 'connects to redux api to get token' do
|
52
|
+
resp = double(:resp, :code => 200, :body => '{"token":"TOKEN"}')
|
53
|
+
|
54
|
+
expect(http_client).to \
|
55
|
+
receive(:post).with('https://i.bbcredux.com/user/login', {
|
56
|
+
:body => {
|
57
|
+
:username => 'foo',
|
58
|
+
:password => 'bar',
|
59
|
+
:token => nil,
|
60
|
+
},
|
61
|
+
:followlocation => true
|
62
|
+
}).and_return(resp)
|
63
|
+
|
64
|
+
expect(subject.token).to eq("TOKEN")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'initialized with token' do
|
69
|
+
it 'should be ready to go' do
|
70
|
+
expect(instance.token).to eq(token)
|
71
|
+
expect(instance.http).to eq(http_client)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'initialized with neither token or username / password' do
|
76
|
+
it 'raises an error' do
|
77
|
+
expect { described_class.new }.to raise_error
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#asset' do
|
82
|
+
subject { instance.asset(reference) }
|
83
|
+
|
84
|
+
let(:resp) {
|
85
|
+
double(:http_resp, :code => 200, :body => read_fixture('asset.json'))
|
86
|
+
}
|
87
|
+
|
88
|
+
let(:reference) { '5966413090093319525' }
|
89
|
+
let(:uuid) { '26a141fc-8511-4fef-aa2b-af1d1de5a75a' }
|
90
|
+
|
91
|
+
it_behaves_like 'a json based http method'
|
92
|
+
|
93
|
+
it 'takes json from the backend HTTP API and generates an asset object' do
|
94
|
+
expect(http_client).to \
|
95
|
+
receive(:post).with('https://i.bbcredux.com/asset/details', {
|
96
|
+
:body => { :reference => reference, :token => token },
|
97
|
+
:followlocation => true,
|
98
|
+
}).and_return(resp)
|
99
|
+
|
100
|
+
expect(subject.class).to eq(BBC::Redux::Asset)
|
101
|
+
expect(subject.name).to eq('Pingu')
|
102
|
+
expect(subject.channel.name).to eq('cbeebies')
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'works when given a UUID rather than a disk reference' do
|
106
|
+
expect(http_client).to \
|
107
|
+
receive(:post).with('https://i.bbcredux.com/asset/details', {
|
108
|
+
:body => { :uuid => uuid, :token => token },
|
109
|
+
:followlocation => true,
|
110
|
+
}).and_return(resp)
|
111
|
+
|
112
|
+
asset = instance.asset(uuid)
|
113
|
+
|
114
|
+
expect(asset.class).to eq(BBC::Redux::Asset)
|
115
|
+
expect(asset.name).to eq('Pingu')
|
116
|
+
expect(asset.channel.name).to eq('cbeebies')
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#channels' do
|
121
|
+
subject { instance.channels }
|
122
|
+
|
123
|
+
let(:resp) {
|
124
|
+
double(:http_resp, :code => 200, :body => read_fixture('channels.json'))
|
125
|
+
}
|
126
|
+
|
127
|
+
it_behaves_like 'a json based http method'
|
128
|
+
|
129
|
+
it 'takes json from the backend HTTP API and generates list of channels' do
|
130
|
+
expect(http_client).to \
|
131
|
+
receive(:post).with('https://i.bbcredux.com/asset/channel/available', {
|
132
|
+
:body => { :token => token },
|
133
|
+
:followlocation => true,
|
134
|
+
}).and_return(resp)
|
135
|
+
|
136
|
+
expect(subject.size).to eq(8)
|
137
|
+
expect(subject.first.class).to eq(BBC::Redux::Channel)
|
138
|
+
expect(subject.first.name).to eq('bbcone')
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '#channel_categories' do
|
144
|
+
subject { instance.channel_categories }
|
145
|
+
|
146
|
+
let(:resp) {
|
147
|
+
double(:http_resp, :code => 200,
|
148
|
+
:body => read_fixture('channel_categories.json')) }
|
149
|
+
|
150
|
+
it_behaves_like 'a json based http method'
|
151
|
+
|
152
|
+
it 'takes json from the backend HTTP API, generates list of categories' do
|
153
|
+
expect(http_client).to \
|
154
|
+
receive(:post).with('https://i.bbcredux.com/asset/channel/categories', {
|
155
|
+
:body => { :token => token },
|
156
|
+
:followlocation => true,
|
157
|
+
}).and_return(resp)
|
158
|
+
|
159
|
+
expect(subject.size).to eq(5)
|
160
|
+
expect(subject.first.class).to eq(BBC::Redux::ChannelCategory)
|
161
|
+
expect(subject.first.description).to eq('BBC TV')
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
describe '#logout' do
|
167
|
+
subject { instance.logout }
|
168
|
+
|
169
|
+
let(:resp) { double(:http_resp, :code => 200, :body => '{}') }
|
170
|
+
|
171
|
+
it_behaves_like 'a json based http method'
|
172
|
+
|
173
|
+
it 'posts to logout endpoint' do
|
174
|
+
expect(http_client).to \
|
175
|
+
receive(:post).with('https://i.bbcredux.com/user/logout', {
|
176
|
+
:body => { :token => token },
|
177
|
+
:followlocation => true,
|
178
|
+
}).and_return(resp)
|
179
|
+
|
180
|
+
expect(subject).to eq(nil)
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
describe '#search' do
|
186
|
+
subject { instance.search }
|
187
|
+
|
188
|
+
let(:resp) {
|
189
|
+
double(:resp, :code => 200, :body => read_fixture('search_results.json'))
|
190
|
+
}
|
191
|
+
it_behaves_like 'a json based http method'
|
192
|
+
|
193
|
+
it 'passes params to backend HTTP API and generates results object' do
|
194
|
+
expect(http_client).to \
|
195
|
+
receive(:post).with('https://i.bbcredux.com/asset/search', {
|
196
|
+
:body => { :q => 'foo', :longer => '200', :token => token },
|
197
|
+
:followlocation => true,
|
198
|
+
}).and_return(resp)
|
199
|
+
|
200
|
+
results = instance.search(:q => 'foo', :longer => 200)
|
201
|
+
|
202
|
+
expect(results.class).to be(BBC::Redux::SearchResults)
|
203
|
+
expect(results.query).to eq(:q => 'foo', :longer => 200)
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'channel object based parameters' do
|
207
|
+
|
208
|
+
let(:bbcone) { BBC::Redux::Channel.new(:name => 'bbcone') }
|
209
|
+
|
210
|
+
it 'formats them correctly' do
|
211
|
+
expect(http_client).to \
|
212
|
+
receive(:post).with('https://i.bbcredux.com/asset/search', {
|
213
|
+
:body => { :channel => 'bbcone', :token => token },
|
214
|
+
:followlocation => true,
|
215
|
+
}).and_return(resp)
|
216
|
+
|
217
|
+
results = instance.search(:channel => bbcone)
|
218
|
+
|
219
|
+
expect(results.class).to be(BBC::Redux::SearchResults)
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'handles an array correctly' do
|
223
|
+
url = 'https://i.bbcredux.com/asset/search?channel=bbcone&channel=bbctwo'
|
224
|
+
|
225
|
+
expect(http_client).to \
|
226
|
+
receive(:post).with(url, {
|
227
|
+
:body => { :token => token },
|
228
|
+
:followlocation => true,
|
229
|
+
}).and_return(resp)
|
230
|
+
|
231
|
+
results = instance.search(:channel => [ bbcone, 'bbctwo' ])
|
232
|
+
|
233
|
+
expect(results.class).to be(BBC::Redux::SearchResults)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context 'date / time based parameters' do
|
238
|
+
it 'formats them correctly' do
|
239
|
+
[ Time.now, Date.today, DateTime.now ].each do |datey|
|
240
|
+
formatted = datey.strftime('%Y-%m-%dT%H:%M:%S')
|
241
|
+
|
242
|
+
expect(http_client).to \
|
243
|
+
receive(:post).with('https://i.bbcredux.com/asset/search', {
|
244
|
+
:body => { :date => formatted, :token => token },
|
245
|
+
:followlocation => true,
|
246
|
+
}).and_return(resp)
|
247
|
+
|
248
|
+
results = instance.search(:date => datey)
|
249
|
+
|
250
|
+
expect(results.class).to be(BBC::Redux::SearchResults)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
describe '#user' do
|
258
|
+
subject { instance.user }
|
259
|
+
|
260
|
+
let(:resp) {
|
261
|
+
double(:http_resp, :code => 200, :body => read_fixture('user.json'))
|
262
|
+
}
|
263
|
+
|
264
|
+
it_behaves_like 'a json based http method'
|
265
|
+
|
266
|
+
it 'takes json from the backend HTTP API and generates a user object' do
|
267
|
+
expect(http_client).to \
|
268
|
+
receive(:post).with('https://i.bbcredux.com/user/details', {
|
269
|
+
:body => { :token => token },
|
270
|
+
:followlocation => true,
|
271
|
+
}).and_return(resp)
|
272
|
+
|
273
|
+
expect(subject.class).to eq(BBC::Redux::User)
|
274
|
+
expect(subject.name).to eq('Jane Smith')
|
275
|
+
end
|
276
|
+
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BBC::Redux::Key do
|
4
|
+
|
5
|
+
let(:value) { '1-1397227462-ba632af7af1adb6f96dbeceb83331ad6' }
|
6
|
+
|
7
|
+
subject { described_class.new(value) }
|
8
|
+
|
9
|
+
{
|
10
|
+
|
11
|
+
# attr/method => expected_value
|
12
|
+
:value => '1-1397227462-ba632af7af1adb6f96dbeceb83331ad6',
|
13
|
+
:to_s => '1-1397227462-ba632af7af1adb6f96dbeceb83331ad6',
|
14
|
+
:expires_at => DateTime.parse('2014-04-11 15:44:22 +0100'),
|
15
|
+
|
16
|
+
}.each_pair do |attribute, value|
|
17
|
+
its(attribute) { should eq(value) }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#expired?' do
|
21
|
+
it 'should be true when expires_at is in the past' do
|
22
|
+
expect(generate_key(Time.now - 300).expired?).to be(true)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should be false when expires_at is in the future' do
|
26
|
+
expect(generate_key(Time.now + 300).expired?).to be(false)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#live?' do
|
31
|
+
it 'should be false when expires_at is in the past' do
|
32
|
+
expect(generate_key(Time.now - 300).live?).to be(false)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should be true when expires_at is in the future' do
|
36
|
+
expect(generate_key(Time.now + 300).live?).to be(true)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#ttl' do
|
41
|
+
it 'should return the key\'s TLL in seconds' do
|
42
|
+
expect(generate_key.ttl).to be_within(1).of(0)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#==' do
|
47
|
+
it 'should be true if keys have same values' do
|
48
|
+
expect(subject).to eq(described_class.new(value))
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should be false if keys have different values' do
|
52
|
+
expect(subject).to_not eq(generate_key)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should be false if other key is something else' do
|
56
|
+
expect(subject).to_not eq(:something_else)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def generate_key(expires_at = Time.now)
|
63
|
+
described_class.new "1-#{expires_at.to_i}-ba632af7af1adb6f96dbeceb83331ad6"
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|