bbc_redux 0.4.0.pre
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/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
|