actv 1.3.11 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,18 @@
1
1
  require 'faraday'
2
2
  require 'actv/article'
3
3
  require 'actv/article_search_results'
4
+ require 'actv/article_validator'
5
+ require 'actv/asset_validator'
4
6
  require 'actv/asset'
7
+ require 'actv/asset_factory'
8
+ require 'actv/author'
9
+ require 'actv/author_validator'
5
10
  require 'actv/configurable'
6
11
  require 'actv/error/forbidden'
7
12
  require 'actv/error/not_found'
8
13
  require 'actv/event'
9
14
  require 'actv/event_result'
15
+ require 'actv/event_validator'
10
16
  require 'actv/asset_stats_result'
11
17
  require 'actv/evergreen'
12
18
  require 'actv/sub_event'
@@ -53,33 +59,10 @@ module ACTV
53
59
  end
54
60
  alias search assets
55
61
 
56
- # Returns an asset with the specified ID in an array
57
- #
58
- # @authentication_required No
59
- # @return [ACTV::Asset] The requested asset.
60
- # @param id [String] An assset ID.
61
- # @param options [Hash] A customizable set of options.
62
- # @example Return the asset with the id BA288960-2718-4B20-B380-8F939596B123
63
- # ACTV.asset("BA288960-2718-4B20-B380-8F939596B123")
64
- def asset(id, params={})
65
- is_preview, params = params_include_preview? params
66
-
67
- if is_preview
68
- request_string = "/v2/assets/#{id}/preview"
69
- response = get("#{request_string}.json", params)
70
- else
71
- request_string = "/v2/assets"
72
- params = params.merge :id => id
73
- response = post("#{request_string}.json", params)
74
- end
75
-
76
- if response[:body].is_a? Array
77
- response[:body].map do |item|
78
- ACTV::Asset.from_response body: item
79
- end
80
- else
81
- [ACTV::Asset.from_response(response)]
82
- end
62
+ def asset id, params={}
63
+ is_preview = params.delete(:preview) == "true"
64
+ response = request_response id, params, is_preview
65
+ asset_from_response response
83
66
  end
84
67
 
85
68
  # Returns an organizer with the specified ID
@@ -380,6 +363,39 @@ module ACTV
380
363
 
381
364
  private
382
365
 
366
+ def request_response id, params, is_preview
367
+ if is_preview
368
+ asset_response_with_preview id, params
369
+ else
370
+ asset_response_without_preview id, params
371
+ end
372
+ end
373
+
374
+ def asset_response_with_preview id, params
375
+ request_string = "/v2/assets/#{id}/preview"
376
+ get "#{request_string}.json", params
377
+ end
378
+
379
+ def asset_response_without_preview id, params
380
+ request_string = "/v2/assets"
381
+ params = params.merge :id => id
382
+ post "#{request_string}.json", params
383
+ end
384
+
385
+ def asset_from_response response
386
+ if response[:body].is_a? Array
387
+ collect_assets response
388
+ else
389
+ Array(ACTV::Asset.from_response response)
390
+ end
391
+ end
392
+
393
+ def collect_assets response
394
+ response[:body].map do |response|
395
+ ACTV::Asset.from_response body: response
396
+ end
397
+ end
398
+
383
399
  def find_by_endurance_id_params endurance_id
384
400
  awe_legacy_guid = 'DFAA997A-D591-44CA-9FB7-BF4A4C8984F1'
385
401
  params = {
@@ -405,6 +421,5 @@ module ACTV
405
421
  params = params.with_indifferent_access
406
422
  return params.delete(:preview) == "true", params
407
423
  end
408
-
409
424
  end
410
425
  end
@@ -1,11 +1,15 @@
1
1
  require 'actv/asset'
2
2
 
3
3
  module ACTV
4
- class Event < ACTV::Asset
4
+ class Event < Asset
5
5
  attr_reader :salesStartDate, :salesEndDate, :activityStartDate, :activityEndDate
6
6
  alias sales_start_date salesStartDate
7
7
  alias sales_end_date salesEndDate
8
8
 
9
+ def self.valid? response
10
+ ACTV::EventValidator.new(response).valid?
11
+ end
12
+
9
13
  def online_registration_available?
10
14
  if is_present?(self.registrationUrlAdr)
11
15
  if is_present?(self.legacy_data) && is_present?(self.legacy_data.onlineRegistration)
@@ -120,8 +124,6 @@ module ACTV
120
124
  place.timezoneOffset + place.timezoneDST
121
125
  end
122
126
 
123
- ############
124
-
125
127
  def image_url
126
128
  defaultImage = 'http://www.active.com/images/events/hotrace.gif'
127
129
  image = ''
@@ -141,6 +143,10 @@ module ACTV
141
143
  image
142
144
  end
143
145
 
146
+ def is_event?
147
+ true
148
+ end
149
+
144
150
  alias online_registration? online_registration_available?
145
151
  alias reg_open? registration_open?
146
152
  alias reg_closed? registration_closed?
@@ -204,7 +210,6 @@ module ACTV
204
210
  return nil if time_string.nil? or time_string.empty?
205
211
  return Time.parse(time_string).utc
206
212
  end
207
-
208
213
  end
209
214
  end
210
215
 
@@ -0,0 +1,8 @@
1
+ require 'actv/asset_validator'
2
+ module ACTV
3
+ class EventValidator < AssetValidator
4
+ def valid?
5
+ category_is?('event') || taxonomy_has?('event')
6
+ end
7
+ end
8
+ end
@@ -1,3 +1,3 @@
1
1
  module ACTV
2
- VERSION = "1.3.11"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -1,44 +1,154 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ACTV::Article do
4
- context "shoulda matchers" do
5
- subject { ACTV::Article.new(assetGuid: 1) }
6
-
7
- it { should respond_to :summary }
8
- it { should respond_to :description }
9
- it { should respond_to :by_line }
10
- it { should respond_to :author_bio }
11
- it { should respond_to :author_photo }
12
- it { should respond_to :source }
13
- it { should respond_to :type }
14
- it { should respond_to :image }
15
- it { should respond_to :subtitle }
16
- it { should respond_to :footer }
17
- it { should respond_to :inline_ad }
18
- it { should respond_to :inline_ad? }
4
+ let(:descriptions) { [ { description: "article source", descriptionType: { descriptionTypeId: "1", descriptionTypeName: "articleSource" } },
5
+ { description: "article subtitle", descriptionType: { descriptionTypeId: "2", descriptionTypeName: "subtitle" } },
6
+ { description: "by Yason", descriptionType: { descriptionTypeId: "3", descriptionTypeName: "articleByLine" } },
7
+ { description: "article footer", descriptionType: { descriptionTypeId: "4", descriptionTypeName: "footer" } } ] }
8
+ let(:asset_images) { [] }
9
+ let(:asset_categories) { [] }
10
+ let(:asset_tags) { [] }
11
+ let(:asset_references) { [] }
12
+ let(:response) { { assetGuid: 1,
13
+ assetDescriptions: descriptions,
14
+ assetTags: asset_tags,
15
+ assetImages: asset_images,
16
+ assetCategories: asset_categories,
17
+ assetReferences: asset_references } }
18
+ subject(:article) { ACTV::Article.new response }
19
+
20
+ describe '#self.valid?' do
21
+ subject(:valid?) { ACTV::Article.valid? response }
22
+ context 'when the category name is articles' do
23
+ let(:asset_categories) { [ { category: { categoryName: "Articles", categoryTaxonomy: "" } } ] }
24
+ it { should be_true }
25
+ end
26
+ context 'when the category taxonomy is articles' do
27
+ let(:asset_categories) { [ { category: { categoryName: "", categoryTaxonomy: "Creative Work/Articles" } } ] }
28
+ it { should be_true }
29
+ end
30
+ context 'when there is no category taxonomy or name' do
31
+ it { should be_false }
32
+ end
19
33
  end
20
34
 
21
- describe '#inline_ad?' do
22
- context 'if inlindead is set to true' do
23
- let(:article) { ACTV::Article.new(assetGuid: 1, assetTags: [ { tag: { tagId: '1', tagName: 'true', tagDescription: 'inlinead' } } ]) }
24
- it 'should return true' do
25
- article.inline_ad?.should eq true
35
+ describe '#source' do
36
+ context 'when an articleSource description exists' do
37
+ its(:source) { should eq "article source" }
38
+ end
39
+ context 'when an articleSource description does not exist' do
40
+ let(:descriptions) { [] }
41
+ its(:source) { should be_nil }
42
+ end
43
+ end
44
+
45
+ describe '#type' do
46
+ context 'when an articleType tag description exists' do
47
+ let(:asset_tags) { [ { tag: { tagId: '2', tagName: 'mediagallery', tagDescription: 'articleType' } } ] }
48
+ its(:type) { should eq "mediagallery" }
49
+ end
50
+ context 'when an articleType tag description does not exist' do
51
+ its(:type) { should be_nil }
52
+ end
53
+ end
54
+
55
+ describe '#media_gallery?' do
56
+ context 'when the articleType tag is mediagallery' do
57
+ let(:asset_tags) { [ { tag: { tagId: '2', tagName: 'mediagallery', tagDescription: 'articleType' } } ] }
58
+ its(:media_gallery?) { should be_true }
59
+ end
60
+ context 'when the articleType tag is not mediagallery' do
61
+ its(:media_gallery?) { should be_false }
62
+ end
63
+ end
64
+
65
+ describe '#image' do
66
+ context 'when article has an image named image2' do
67
+ let(:asset_images) { [ { imageName: "image2" } ] }
68
+ it 'returns the image' do
69
+ expect(article.image).to be_a ACTV::AssetImage
26
70
  end
27
71
  end
72
+ context 'when article does not have an image named image2' do
73
+ it 'returns nil' do
74
+ expect(article.image).to be_nil
75
+ end
76
+ end
77
+ end
28
78
 
79
+ describe '#subtitle' do
80
+ context 'when a subtitle description exists' do
81
+ its(:subtitle) { should eq "article subtitle" }
82
+ end
83
+ context 'when a subtitle description does not exist' do
84
+ let(:descriptions) { [] }
85
+ its(:subtitle) { should be_nil }
86
+ end
87
+ end
88
+
89
+ describe '#footer' do
90
+ context 'when a footer description exists' do
91
+ its(:footer) { should eq "article footer" }
92
+ end
93
+ context 'when a footer description does not exist' do
94
+ let(:descriptions) { [] }
95
+ its(:footer) { should be_nil }
96
+ end
97
+ end
98
+
99
+ describe '#inline_ad?' do
100
+ context 'if inlindead is set to true' do
101
+ let(:asset_tags) { [ { tag: { tagId: '1', tagName: 'true', tagDescription: 'inlinead' } } ] }
102
+ its(:inline_ad?) { should be_true }
103
+ end
29
104
  context 'if inlindead is set to false' do
30
- let(:article) { ACTV::Article.new(assetGuid: 1, assetTags: [ { tag: { tagId: '1', tagName: 'false', tagDescription: 'inlinead' } } ]) }
31
- it 'should return false' do
32
- article.inline_ad?.should eq false
105
+ let(:asset_tags) { [ { tag: { tagId: '2', tagName: 'false', tagDescription: 'inlinead' } } ] }
106
+ its(:inline_ad?) { should be_false }
107
+ end
108
+ context 'if inlindead is not set' do
109
+ its(:inline_ad?) { should be_true }
110
+ end
111
+ end
112
+
113
+ describe '#author' do
114
+ context 'when an author reference exists' do
115
+ let(:asset_references) { [ { referenceAsset: { assetGuid: "123" }, referenceType: { referenceTypeName: "author" } } ] }
116
+ before do
117
+ stub_request(:post, "http://api.amp.active.com/v2/assets.json").
118
+ to_return(body: fixture("valid_author.json"))
33
119
  end
120
+ context 'when the author exists in a3pi' do
121
+ its(:author) { should be_a ACTV::Author }
122
+ end
123
+ context 'when the author does not exist in a3pi' do
124
+ before do
125
+ allow(ACTV).to receive(:asset).and_raise ACTV::Error::NotFound
126
+ end
127
+ its(:author) { should be_a ACTV::Author }
128
+ end
129
+ end
130
+ context 'when an author reference does not exist' do
131
+ its(:author) { should be_a ACTV::Author }
34
132
  end
133
+ end
35
134
 
36
- context 'if inlindead is not set' do
37
- let(:article) { ACTV::Article.new assetGuid: 1 }
135
+ describe '#is_article?' do
136
+ its(:is_article?) { should be_true }
137
+ end
38
138
 
39
- it 'should return true' do
40
- article.inline_ad?.should eq true
139
+ describe '#author_from_by_line' do
140
+ context 'when a by line is present' do
141
+ context 'when a match is found' do
142
+ its(:author_name_from_by_line) { should eq "Yason" }
41
143
  end
144
+ context 'when a match is not found' do
145
+ let(:descriptions) { [] }
146
+ its(:author_name_from_by_line) { should be_nil }
147
+ end
148
+ end
149
+ context 'when a by line is not present' do
150
+ let(:descriptions) { [] }
151
+ its(:author_name_from_by_line) { should be_nil }
42
152
  end
43
153
  end
44
- end
154
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe ACTV::ArticleValidator do
4
+ let(:asset_categories) { [] }
5
+ let(:response) { { assetGuid: 1, assetCategories: asset_categories } }
6
+ subject(:validator) { ACTV::ArticleValidator.new(response).valid? }
7
+
8
+ describe '#valid?' do
9
+ context 'when the response is valid' do
10
+ context 'because the category name is valid' do
11
+ let(:asset_categories) { [ { category: { categoryName: "Articles", categoryTaxonomy: "" } } ] }
12
+ it { should be_true }
13
+ end
14
+ context 'because the category taxonomy is valid' do
15
+ let(:asset_categories) { [ { category: { categoryName: "", categoryTaxonomy: "Person/Articles" } } ] }
16
+ it { should be_true }
17
+ end
18
+ end
19
+ context 'when the response is not valid' do
20
+ it { should be_false }
21
+ end
22
+ end
23
+ end
@@ -8,11 +8,10 @@ describe ACTV::AssetComponent do
8
8
  describe "#prices" do
9
9
  before(:each) do
10
10
  stub_post("/v2/assets.json").with(:body => {"id"=>true}).
11
- to_return(body: fixture("valid_component_asset.json"), headers: { content_type: "application/json; charset=utf-8" })
11
+ to_return(body: fixture("valid_component_asset.json"), headers: { content_type: "application/json; charset=utf-8" })
12
12
  end
13
13
 
14
14
  it 'returns the prices associated with the component' do
15
- expect(subject.prices).to be_an(Array)
16
15
  expect(subject.prices.first).to be_an(ACTV::AssetPrice)
17
16
  end
18
17
  end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe ACTV::AssetFactory do
4
+ let(:category_name) { "" }
5
+ let(:category_taxonomy) { "" }
6
+ let(:response) { {assetGuid: "111",
7
+ assetCategories: [{category: {categoryName: category_name,
8
+ categoryTaxonomy: category_taxonomy}}]} }
9
+ subject(:asset) { ACTV::AssetFactory.new(response).asset }
10
+
11
+ describe '#asset' do
12
+ context 'the response is not an author, event or article' do
13
+ it { should be_a ACTV::Asset }
14
+ end
15
+ context 'the response has an article category' do
16
+ let(:category_name) { "Articles" }
17
+ it { should be_a ACTV::Article }
18
+ end
19
+ context 'the response has an article taxonomy' do
20
+ let(:category_taxonomy) { "Running/Articles" }
21
+ it { should be_a ACTV::Article }
22
+ end
23
+ context 'the response has an event category' do
24
+ let(:category_name) { "Event" }
25
+ it { should be_a ACTV::Event }
26
+ end
27
+ context 'the response has an event taxonomy' do
28
+ let(:category_taxonomy) { "Race/Event" }
29
+ it { should be_a ACTV::Event }
30
+ end
31
+ context 'the response has an author category' do
32
+ let(:category_name) { "Author" }
33
+ it { should be_a ACTV::Author }
34
+ end
35
+ context 'the response has an author taxonomy' do
36
+ let(:category_taxonomy) { "Running/Author" }
37
+ it { should be_a ACTV::Author }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ describe ACTV::AssetReference do
3
+ let(:asset_guid) { "123" }
4
+ let(:reference_type_name) { "Meow" }
5
+ let(:reference_hash) { {referenceAsset: {assetGuid: asset_guid},
6
+ referenceType: {referenceTypeName: reference_type_name}} }
7
+ subject(:asset_reference) { ACTV::AssetReference.new reference_hash }
8
+
9
+ describe '#id' do
10
+ it 'returns a guid' do
11
+ expect(asset_reference.id).to eq asset_guid
12
+ end
13
+ end
14
+
15
+ describe '#type' do
16
+ it 'returns a type' do
17
+ expect(asset_reference.type).to eq reference_type_name
18
+ end
19
+ end
20
+ end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'pry'
3
2
 
4
3
  describe ACTV::Asset do
5
4
 
@@ -190,6 +189,32 @@ describe ACTV::Asset do
190
189
  end
191
190
  end
192
191
 
192
+ describe "is_event?" do
193
+ before(:each) do
194
+ stub_post("/v2/assets.json").with(:body => {"id"=>"valid_event"}).
195
+ to_return(body: fixture("valid_event.json"))
196
+ end
197
+
198
+ it "should return true if the asset has Events as an assetCategory" do
199
+ asset = ACTV.asset('valid_event').first
200
+ asset.is_event?.should be_true
201
+ end
202
+
203
+ it "should return true if the asset has no assetCategories but the sourceSystem is Active.com Articles" do
204
+ asset = ACTV.asset('valid_event').first
205
+ asset.stub(:assetCategories).and_return([])
206
+ asset.is_event?.should be_true
207
+ end
208
+
209
+ it "should return false if no assetCategory of Event" do
210
+ stub_post("/v2/assets.json").with(:body => {"id"=>"valid_article"}).
211
+ to_return(body: fixture("valid_article.json"))
212
+
213
+ asset = ACTV.asset('valid_article').first
214
+ asset.is_event?.should be_false
215
+ end
216
+ end
217
+
193
218
  describe "is_article?" do
194
219
  before(:each) do
195
220
  stub_post("/v2/assets.json").with(:body => {"id"=>"valid_article"}).
@@ -282,7 +307,7 @@ describe ACTV::Asset do
282
307
  end
283
308
  end
284
309
 
285
- context "and articles_source? returns true" do
310
+ context "and acm? returns true" do
286
311
  let(:asset) { ACTV::Asset.new assetGuid: 1, sourceSystem: {legacyGuid: "CA4EA0B1-7377-470D-B20D-BF6BEA23F040"} }
287
312
 
288
313
  context 'and kids_interest? is true' do
@@ -309,7 +334,7 @@ describe ACTV::Asset do
309
334
  asset.stub activenet?: false
310
335
  asset.stub awcamps?: false
311
336
  asset.stub awcamps30?: false
312
- asset.stub articles_source?: false
337
+ asset.stub acm?: false
313
338
  end
314
339
 
315
340
  it 'evaluates to false' do
@@ -485,4 +510,27 @@ describe ACTV::Asset do
485
510
  end
486
511
  end
487
512
 
513
+ describe '#references' do
514
+ let(:asset_references) { [] }
515
+ let(:response) { { assetGuid: 1, assetReferences: asset_references } }
516
+ let(:asset) { ACTV::Asset.new response }
517
+ context 'when there are asset references' do
518
+ let(:asset_references) { [ { referenceAsset: { assetGuid: "123" },
519
+ referenceType: { referenceTypeName: "author" } } ] }
520
+ it 'returns an array of asset reference objects' do
521
+ expect(asset.references.first).to be_a ACTV::AssetReference
522
+ end
523
+ end
524
+ context 'when there are no asset references' do
525
+ it 'returns an empty array' do
526
+ expect(asset.references).to be_empty
527
+ end
528
+ end
529
+ context 'when there is no asset references field' do
530
+ let(:response) { { assetGuid: 1 } }
531
+ it 'returns an empty array' do
532
+ expect(asset.references).to be_empty
533
+ end
534
+ end
535
+ end
488
536
  end