yt 0.14.0 → 0.14.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e12f9ef5c2b615833df8d63a3a821aadd397a3b
4
- data.tar.gz: e79d293fdbaaeaf10c2c6bc5fc594363e31909a2
3
+ metadata.gz: db4db84624546717fdc851f9686077c0926798ac
4
+ data.tar.gz: 69322165d6a6a13484613c7d1f3e3fda0c3c79d4
5
5
  SHA512:
6
- metadata.gz: 8c2d5f5ff6825b5f844903ffec97c794c40b75d44489736b9ba8116d838adceadff3fff0fad0d8f641937c76c27476ed5e322f5e232119483d486420bb60e3c4
7
- data.tar.gz: d44fc9bcb26d18178da67a651419ca69e3be7bce825cedfc68b22dc2b996b84728b9cf483e152da2947db6a2c4b6ce1691201b443a2675d7bdd6bac2cfad6d6a
6
+ metadata.gz: fe0e64e30469c9539c4e5441e6d691bf91f6bf3f66e5d1cfbf6aa4a790a79e21aeeea6a4c2e02eb4d147817467e052409789054bd369268cba906759563fd655
7
+ data.tar.gz: c4e6b9bbab1327dcc20acbdd65260d83b6ec06723a21a098efcb0bbb6fc5ef9555a6897d1a86dd48b120e86ee58857b051c383089f1503a49c48bce8659098be
data/CHANGELOG.md CHANGED
@@ -6,6 +6,15 @@ For more information about changelogs, check
6
6
  [Keep a Changelog](http://keepachangelog.com) and
7
7
  [Vandamme](http://tech-angels.github.io/vandamme).
8
8
 
9
+ ## 0.14.1 - 2015-03-30
10
+
11
+ * [FEATURE] New `monetized playbacks` report for channels.
12
+ * [FEATURE] New `estimated watched minutes` report for videos.
13
+ * [FEATURE] New video reports: `average_view_duration`, `average_view_percentage`.
14
+ * [FEATURE] New `by: :playlist` option for reports, to return views and estimated watched minutes (channels) by playlist.
15
+ * [FEATURE] New playlist reports: `views`, `playlist_starts`, `average_time_in_playlist`, `views_per_playlist_start`.
16
+
17
+
9
18
  ## 0.14.0 - 2015-03-25
10
19
 
11
20
  * [FEATURE] New `by: :traffic_source` option for reports, to return views (channels/videos) and estimated watched minutes (channels) by traffic source.
data/Gemfile CHANGED
@@ -1,6 +1,4 @@
1
1
  source 'https://rubygems.org'
2
- gem 'pry'
3
- gem 'pry-nav'
4
2
 
5
3
  # Specify your gem's dependencies in yt.gemspec
6
4
  gemspec
data/README.md CHANGED
@@ -41,7 +41,7 @@ To install on your system, run
41
41
 
42
42
  To use inside a bundled Ruby project, add this line to the Gemfile:
43
43
 
44
- gem 'yt', '~> 0.13.11'
44
+ gem 'yt', '~> 0.14.1'
45
45
 
46
46
  Since the gem follows [Semantic Versioning](http://semver.org),
47
47
  indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
@@ -150,6 +150,8 @@ Use [Yt::Channel](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models/Chan
150
150
  * delete playlists from a channel
151
151
  * retrieve the daily earnings, views, comments, likes, dislikes, shares, subscribers gained/lost, estimated/average video watch and impressions of a channel by day
152
152
  * retrieve the views and estimated minutes watched by traffic source
153
+ * retrieve the views and estimated minutes watched by video
154
+ * retrieve the views and estimated minutes watched by playlist
153
155
  * retrieve the viewer percentage of a channel by gender and age group
154
156
 
155
157
  ```ruby
@@ -214,6 +216,12 @@ channel.viewer_percentage(gender: :male) #=> 49.12
214
216
 
215
217
  channel.views since: 7.days.ago, by: :traffic_source #=> {advertising: 10.0, related_video: 20.0, promoted: 5.0, subscriber: 1.0, channel: 3.0, other: 7.0}
216
218
  channel.estimated_minutes_watched since: 7.days.ago, by: :traffic_source #=> {annotation: 10.0, external_app: 20.0, external_url: 5.0, embedded: 1.0, search: 3.0}
219
+
220
+ channel.views since: 7.days.ago, by: :video #=> {#<Yt::Models::Video @id=...>: 10.0, #<Yt::Models::Video @id=...>: 20.0, …}
221
+ channel.estimated_minutes_watched since: 7.days.ago, by: :video #=> {#<Yt::Models::Video @id=...>: 10.0, #<Yt::Models::Video @id=...>: 20.0, …}
222
+
223
+ channel.views since: 7.days.ago, by: :playlist #=> {#<Yt::Models::Playlist @id=...>: 10.0, #<Yt::Models::Playlist @id=...>: 20.0, …}
224
+ channel.estimated_minutes_watched since: 7.days.ago, by: :playlist #=> {#<Yt::Models::Playlist @id=...>: 10.0, #<Yt::Models::Playlist @id=...>: 20.0, …}
217
225
  ```
218
226
 
219
227
  *The methods above require to be authenticated as the channel’s account (see below).*
@@ -238,6 +246,11 @@ channel.viewer_percentages #=> {female: {'18-24' => 12.12, '25-34' => 16.16,…}
238
246
  channel.viewer_percentage(gender: :female) #=> 49.12
239
247
  channel.views since: 7.days.ago, by: :traffic_source #=> {advertising: 10.0, related_video: 20.0, promoted: 5.0, subscriber: 1.0, channel: 3.0, other: 7.0}
240
248
  channel.estimated_minutes_watched since: 7.days.ago, by: :traffic_source #=> {annotation: 10.0, external_app: 20.0, external_url: 5.0, embedded: 1.0, search: 3.0}
249
+ channel.views since: 7.days.ago, by: :video #=> {#<Yt::Models::Video @id=...>: 10.0, #<Yt::Models::Video @id=...>: 20.0, …}
250
+ channel.estimated_minutes_watched since: 7.days.ago, by: :video #=> {#<Yt::Models::Video @id=...>: 10.0, #<Yt::Models::Video @id=...>: 20.0, …}
251
+ channel.views since: 7.days.ago, by: :playlist #=> {#<Yt::Models::Playlist @id=...>: 10.0, #<Yt::Models::Playlist @id=...>: 20.0, …}
252
+ channel.estimated_minutes_watched since: 7.days.ago, by: :playlist #=> {#<Yt::Models::Playlist @id=...>: 10.0, #<Yt::Models::Playlist @id=...>: 20.0, …}
253
+ channel.monetized_playbacks_on 5.days.ago #=> 123.0
241
254
 
242
255
  channel.content_owner #=> 'CMSname'
243
256
  channel.linked_at #=> Wed, 28 May 2014
@@ -350,6 +363,11 @@ video.dislikes to: 2.days.ago #=> {Tue, 27 May 2014 => 0.0, Wed, 28 May 2014 =>
350
363
  video.shares since: 7.days.ago, until: 7.days.ago #=> {Wed, 28 May 2014 => 3.0}
351
364
  video.subscribers_gained from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>1.0, Sun, 31 Aug 2014=>0.0}
352
365
  video.subscribers_lost from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>0.0, Sun, 31 Aug 2014=>0.0}
366
+ video.favorites_added from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>1.0, Sun, 31 Aug 2014=>0.0}
367
+ video.favorites_removed from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>0.0, Sun, 31 Aug 2014=>0.0}
368
+ video.average_view_duration #=> {Sun, 22 Feb 2015=>329.0, Mon, 23 Feb 2015=>326.0, …}
369
+ video.average_view_percentage # {Sun, 22 Feb 2015=>38.858253094977265, Mon, 23 Feb 2015=>37.40014235438217, …}
370
+ video.estimated_minutes_watched #=> {Sun, 22 Feb 2015=>2433258.0, Mon, 23 Feb 2015=>2634360.0, …}
353
371
  video.viewer_percentages #=> {female: {'18-24' => 12.12, '25-34' => 16.16,…}…}
354
372
  video.viewer_percentage(gender: :female) #=> 49.12
355
373
 
@@ -372,6 +390,11 @@ video.dislikes to: 2.days.ago #=> {Tue, 27 May 2014 => 0.0, Wed, 28 May 2014 =>
372
390
  video.shares since: 7.days.ago, until: 7.days.ago #=> {Wed, 28 May 2014 => 3.0}
373
391
  video.subscribers_gained from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>1.0, Sun, 31 Aug 2014=>0.0}
374
392
  video.subscribers_lost from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>0.0, Sun, 31 Aug 2014=>0.0}
393
+ video.favorites_added from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>1.0, Sun, 31 Aug 2014=>0.0}
394
+ video.favorites_removed from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>0.0, Sun, 31 Aug 2014=>0.0}
395
+ video.average_view_duration #=> {Sun, 22 Feb 2015=>329.0, Mon, 23 Feb 2015=>326.0, …}
396
+ video.average_view_percentage # {Sun, 22 Feb 2015=>38.858253094977265, Mon, 23 Feb 2015=>37.40014235438217, …}
397
+ video.estimated_minutes_watched #=> {Sun, 22 Feb 2015=>2433258.0, Mon, 23 Feb 2015=>2634360.0, …}
375
398
  video.impressions_on 5.days.ago #=> 157.0
376
399
  video.monetized_playbacks_on 5.days.ago #=> 123.0
377
400
 
@@ -395,6 +418,7 @@ Use [Yt::Playlist](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models/Pla
395
418
  * access the items of a playlist
396
419
  * add one or multiple videos to a playlist
397
420
  * delete items from a playlist
421
+ * retrieve the views, playlist starts, average time in playlist and views per playlist start of a playlist by day
398
422
 
399
423
  ```ruby
400
424
  # Playlists can be initialized with ID or URL
@@ -421,6 +445,19 @@ playlist.update title: 'A <title> with angle brackets', description: 'desc', tag
421
445
  playlist.add_video 'MESycYJytkU', position: 2
422
446
  playlist.add_videos ['MESycYJytkU', 'MESycYJytkU']
423
447
  playlist.delete_playlist_items title: 'Fullscreen Creator Platform' #=> [true]
448
+
449
+ playlist.views_on 5.days.ago #=> 12.0
450
+ playlist.views since: 7.days.ago #=> {Wed, 28 May 2014 => 12.0, Thu, 29 May 2014 => 3.0, …}
451
+
452
+ playlist.playlist_starts_on 5.days.ago #=> 12.0
453
+ playlist.playlist_starts since: 7.days.ago #=> {Wed, 28 May 2014 => 12.0, Thu, 29 May 2014 => 3.0, …}
454
+
455
+ playlist.average_time_in_playlist_on 5.days.ago #=> 12.0
456
+ playlist.average_time_in_playlist since: 7.days.ago #=> {Wed, 28 May 2014 => 12.0, Thu, 29 May 2014 => 3.0, …}
457
+
458
+ playlist.views_per_playlist_start_on 5.days.ago #=> 12.0
459
+ playlist.views_per_playlist_start since: 7.days.ago #=> {Wed, 28 May 2014 => 12.0, Thu, 29 May 2014 => 3.0, …}
460
+
424
461
  ```
425
462
 
426
463
  *The methods above require to be authenticated as the playlist’s owner (see below).*
@@ -6,6 +6,7 @@ module Yt
6
6
  DIMENSIONS = Hash.new({name: 'day', parse: -> (day) {Date.iso8601 day} }).tap do |hash|
7
7
  hash[:traffic_source] = {name: 'insightTrafficSourceType', parse: -> (type) {TRAFFIC_SOURCES.key type} }
8
8
  hash[:video] = {name: 'video', parse: -> (video_id) { Yt::Video.new id: video_id, auth: @auth } }
9
+ hash[:playlist] = {name: 'playlist', parse: -> (playlist_id) { Yt::Playlist.new id: playlist_id, auth: @auth } }
9
10
  end
10
11
 
11
12
  # @see https://developers.google.com/youtube/analytics/v1/dimsmets/dims#Traffic_Source_Dimensions
@@ -64,7 +65,9 @@ module Yt
64
65
  params['metrics'] = @metric.to_s.camelize(:lower)
65
66
  params['dimensions'] = DIMENSIONS[@dimension][:name]
66
67
  params['max-results'] = 10 if @dimension == :video
67
- params['sort'] = "-#{@metric.to_s.camelize(:lower)}" if @dimension == :video
68
+ params['max-results'] = 200 if @dimension == :playlist
69
+ params['sort'] = "-#{@metric.to_s.camelize(:lower)}" if @dimension.in? [:video, :playlist]
70
+ params[:filters] = ((params[:filters] || '').split(';') + ['isCurated==1']).compact.uniq.join(';') if @dimension == :playlist
68
71
  end
69
72
  end
70
73
 
@@ -55,6 +55,9 @@ module Yt
55
55
  # @macro has_report
56
56
  has_report :impressions
57
57
 
58
+ # @macro has_report
59
+ has_report :monetized_playbacks
60
+
58
61
  # @macro has_viewer_percentages
59
62
  has_viewer_percentages
60
63
 
@@ -11,6 +11,18 @@ module Yt
11
11
  # @return [Yt::Collections::PlaylistItems] the playlist’s items.
12
12
  has_many :playlist_items
13
13
 
14
+ # @macro has_report
15
+ has_report :views
16
+
17
+ # @macro has_report
18
+ has_report :playlist_starts
19
+
20
+ # @macro has_report
21
+ has_report :average_time_in_playlist
22
+
23
+ # @macro has_report
24
+ has_report :views_per_playlist_start
25
+
14
26
  # Deletes the playlist.
15
27
  #
16
28
  # This method requires {Resource#auth auth} to return an authenticated
@@ -57,6 +69,21 @@ module Yt
57
69
  playlist_items.delete_all attrs
58
70
  end
59
71
 
72
+ # @private
73
+ # Tells `has_reports` to retrieve the reports from YouTube Analytics API
74
+ # either as a Channel or as a Content Owner.
75
+ # @see https://developers.google.com/youtube/analytics/v1/reports
76
+ def reports_params
77
+ {}.tap do |params|
78
+ if auth.owner_name
79
+ params[:ids] = "contentOwner==#{auth.owner_name}"
80
+ else
81
+ params[:ids] = "channel==#{channel_id}"
82
+ end
83
+ params[:filters] = "playlist==#{id};isCurated==1"
84
+ end
85
+ end
86
+
60
87
  private
61
88
 
62
89
  # @see https://developers.google.com/youtube/v3/docs/playlists/update
@@ -74,6 +74,15 @@ module Yt
74
74
  # @macro has_report
75
75
  has_report :favorites_removed
76
76
 
77
+ # @macro has_report
78
+ has_report :estimated_minutes_watched
79
+
80
+ # @macro has_report
81
+ has_report :average_view_duration
82
+
83
+ # @macro has_report
84
+ has_report :average_view_percentage
85
+
77
86
  # @macro has_report
78
87
  has_report :impressions
79
88
 
data/lib/yt/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.14.0'
2
+ VERSION = '0.14.1'
3
3
  end
@@ -139,6 +139,7 @@ describe Yt::Channel, :device_app do
139
139
  expect{channel.average_view_percentage}.not_to raise_error
140
140
  expect{channel.earnings}.to raise_error Yt::Errors::Unauthorized
141
141
  expect{channel.impressions}.to raise_error Yt::Errors::Unauthorized
142
+ expect{channel.monetized_playbacks}.to raise_error Yt::Errors::Unauthorized
142
143
 
143
144
  expect{channel.views_on 3.days.ago}.not_to raise_error
144
145
  expect{channel.comments_on 3.days.ago}.not_to raise_error
@@ -175,4 +175,20 @@ describe Yt::Playlist, :device_app do
175
175
  end
176
176
  end
177
177
  end
178
+
179
+ context 'given one of my own playlists that I want to get reports for' do
180
+ let(:id) { $account.channel.playlists.first.id }
181
+
182
+ it 'returns valid reports for playlist-related metrics' do
183
+ expect{playlist.views}.not_to raise_error
184
+ expect{playlist.playlist_starts}.not_to raise_error
185
+ expect{playlist.average_time_in_playlist}.not_to raise_error
186
+ expect{playlist.views_per_playlist_start}.not_to raise_error
187
+
188
+ expect{playlist.views_on 3.days.ago}.not_to raise_error
189
+ expect{playlist.playlist_starts_on 3.days.ago}.not_to raise_error
190
+ expect{playlist.average_time_in_playlist_on 3.days.ago}.not_to raise_error
191
+ expect{playlist.views_per_playlist_start_on 3.days.ago}.not_to raise_error
192
+ end
193
+ end
178
194
  end
@@ -289,6 +289,9 @@ describe Yt::Video, :device_app do
289
289
  expect{video.subscribers_lost}.not_to raise_error
290
290
  expect{video.favorites_added}.not_to raise_error
291
291
  expect{video.favorites_removed}.not_to raise_error
292
+ expect{video.estimated_minutes_watched}.not_to raise_error
293
+ expect{video.average_view_duration}.not_to raise_error
294
+ expect{video.average_view_percentage}.not_to raise_error
292
295
  expect{video.earnings}.to raise_error Yt::Errors::Unauthorized
293
296
  expect{video.impressions}.to raise_error Yt::Errors::Unauthorized
294
297
  expect{video.monetized_playbacks}.to raise_error Yt::Errors::Unauthorized
@@ -303,6 +306,9 @@ describe Yt::Video, :device_app do
303
306
  expect{video.subscribers_lost_on 3.days.ago}.not_to raise_error
304
307
  expect{video.favorites_added_on 3.days.ago}.not_to raise_error
305
308
  expect{video.favorites_removed_on 3.days.ago}.not_to raise_error
309
+ expect{video.estimated_minutes_watched_on 3.days.ago}.not_to raise_error
310
+ expect{video.average_view_duration_on 3.days.ago}.not_to raise_error
311
+ expect{video.average_view_percentage_on 3.days.ago}.not_to raise_error
306
312
  expect{video.earnings_on 3.days.ago}.to raise_error Yt::Errors::Unauthorized
307
313
  expect{video.impressions_on 3.days.ago}.to raise_error Yt::Errors::Unauthorized
308
314
  end
@@ -1,6 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  require 'spec_helper'
3
3
  require 'yt/models/channel'
4
+ require 'yt/models/playlist'
4
5
 
5
6
  describe Yt::Channel, :partner do
6
7
  subject(:channel) { Yt::Channel.new id: id, auth: $content_owner }
@@ -120,6 +121,15 @@ describe Yt::Channel, :partner do
120
121
  end
121
122
  end
122
123
 
124
+ describe 'views can be grouped by playlist' do
125
+ let(:range) { {since: 4.days.ago, until: 3.days.ago} }
126
+
127
+ specify 'with the :by option set to :playlist' do
128
+ views = channel.views range.merge by: :playlist
129
+ expect(views.keys).to all(be_instance_of Yt::Playlist)
130
+ end
131
+ end
132
+
123
133
  describe 'comments can be retrieved for a specific day' do
124
134
  context 'in which the channel was partnered' do
125
135
  let(:comments) { channel.comments_on 5.days.ago}
@@ -562,6 +572,15 @@ describe Yt::Channel, :partner do
562
572
  end
563
573
  end
564
574
 
575
+ describe 'estimated minutes watched can be grouped by playlist' do
576
+ let(:range) { {since: 4.days.ago, until: 3.days.ago} }
577
+
578
+ specify 'with the :by option set to :playlist' do
579
+ estimated_minutes_watched = channel.estimated_minutes_watched range.merge by: :playlist
580
+ expect(estimated_minutes_watched.keys).to all(be_instance_of Yt::Playlist)
581
+ end
582
+ end
583
+
565
584
  describe 'average view duration can be retrieved for a specific day' do
566
585
  context 'in which the channel was partnered' do
567
586
  let(:average_view_duration) { channel.average_view_duration_on 5.days.ago}
@@ -703,6 +722,53 @@ describe Yt::Channel, :partner do
703
722
  end
704
723
  end
705
724
 
725
+ describe 'monetized playbacks can be retrieved for a specific day' do
726
+ context 'in which the channel was partnered' do
727
+ let(:monetized_playbacks) { channel.monetized_playbacks_on 20.days.ago}
728
+ it { expect(monetized_playbacks).to be_a Float }
729
+ end
730
+
731
+ context 'in which the channel was not partnered' do
732
+ let(:monetized_playbacks) { channel.monetized_playbacks_on 20.years.ago}
733
+ it { expect(monetized_playbacks).to be_nil }
734
+ end
735
+ end
736
+
737
+ describe 'monetized playbacks can be retrieved for a range of days' do
738
+ let(:date) { 4.days.ago }
739
+
740
+ specify 'with a given start (:since option)' do
741
+ expect(channel.monetized_playbacks(since: date).keys.min).to eq date.to_date
742
+ end
743
+
744
+ specify 'with a given end (:until option)' do
745
+ expect(channel.monetized_playbacks(until: date).keys.max).to eq date.to_date
746
+ end
747
+
748
+ specify 'with a given start (:from option)' do
749
+ expect(channel.monetized_playbacks(from: date).keys.min).to eq date.to_date
750
+ end
751
+
752
+ specify 'with a given end (:to option)' do
753
+ expect(channel.monetized_playbacks(to: date).keys.max).to eq date.to_date
754
+ end
755
+ end
756
+
757
+ describe 'monetized_playbacks can be grouped by day' do
758
+ let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
759
+ let(:keys) { range.values }
760
+
761
+ specify 'without a :by option (default)' do
762
+ monetized_playbacks = channel.monetized_playbacks range
763
+ expect(monetized_playbacks.keys).to eq range.values
764
+ end
765
+
766
+ specify 'with the :by option set to :day' do
767
+ monetized_playbacks = channel.monetized_playbacks range.merge by: :day
768
+ expect(monetized_playbacks.keys).to eq range.values
769
+ end
770
+ end
771
+
706
772
  specify 'viewer percentages by gender and age range can be retrieved' do
707
773
  expect(channel.viewer_percentages[:female]['18-24']).to be_a Float
708
774
  expect(channel.viewer_percentages[:female]['25-34']).to be_a Float
@@ -0,0 +1,213 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+ require 'yt/models/channel'
4
+ require 'yt/models/playlist'
5
+
6
+ describe Yt::Playlist, :partner do
7
+ subject(:playlist) { Yt::Playlist.new id: id, auth: $content_owner }
8
+
9
+ context 'given a playlist of a partnered channel', :partner do
10
+ context 'managed by the authenticated Content Owner' do
11
+ let(:id) { ENV['YT_TEST_PARTNER_PLAYLIST_ID'] }
12
+
13
+ describe 'views can be retrieved for a specific day' do
14
+ context 'in which the playlist was viewed' do
15
+ let(:views) { playlist.views_on ENV['YT_TEST_PARTNER_PLAYLIST_DATE']}
16
+ it { expect(views).to be_a Float }
17
+ end
18
+
19
+ context 'in which the playlist was not viewed' do
20
+ let(:views) { playlist.views_on 20.years.ago}
21
+ it { expect(views).to be_nil }
22
+ end
23
+ end
24
+
25
+ describe 'views can be retrieved for a range of days' do
26
+ let(:date) { 4.days.ago }
27
+
28
+ specify 'with a given start (:since option)' do
29
+ expect(playlist.views(since: date).keys.min).to eq date.to_date
30
+ end
31
+
32
+ specify 'with a given end (:until option)' do
33
+ expect(playlist.views(until: date).keys.max).to eq date.to_date
34
+ end
35
+
36
+ specify 'with a given start (:from option)' do
37
+ expect(playlist.views(from: date).keys.min).to eq date.to_date
38
+ end
39
+
40
+ specify 'with a given end (:to option)' do
41
+ expect(playlist.views(to: date).keys.max).to eq date.to_date
42
+ end
43
+ end
44
+
45
+ describe 'views can be grouped by day' do
46
+ let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
47
+ let(:keys) { range.values }
48
+
49
+ specify 'without a :by option (default)' do
50
+ views = playlist.views range
51
+ expect(views.keys).to eq range.values
52
+ end
53
+
54
+ specify 'with the :by option set to :day' do
55
+ views = playlist.views range.merge by: :day
56
+ expect(views.keys).to eq range.values
57
+ end
58
+ end
59
+
60
+ describe 'playlist starts can be retrieved for a specific day' do
61
+ context 'in which the playlist was viewed' do
62
+ let(:playlist_starts) { playlist.playlist_starts_on ENV['YT_TEST_PARTNER_PLAYLIST_DATE']}
63
+ it { expect(playlist_starts).to be_a Float }
64
+ end
65
+
66
+ context 'in which the playlist was not viewed' do
67
+ let(:playlist_starts) { playlist.playlist_starts_on 20.years.ago}
68
+ it { expect(playlist_starts).to be_nil }
69
+ end
70
+ end
71
+
72
+ describe 'playlist starts can be retrieved for a range of days' do
73
+ let(:date) { 4.days.ago }
74
+
75
+ specify 'with a given start (:since option)' do
76
+ expect(playlist.playlist_starts(since: date).keys.min).to eq date.to_date
77
+ end
78
+
79
+ specify 'with a given end (:until option)' do
80
+ expect(playlist.playlist_starts(until: date).keys.max).to eq date.to_date
81
+ end
82
+
83
+ specify 'with a given start (:from option)' do
84
+ expect(playlist.playlist_starts(from: date).keys.min).to eq date.to_date
85
+ end
86
+
87
+ specify 'with a given end (:to option)' do
88
+ expect(playlist.playlist_starts(to: date).keys.max).to eq date.to_date
89
+ end
90
+ end
91
+
92
+ describe 'playlist starts can be grouped by day' do
93
+ let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
94
+ let(:keys) { range.values }
95
+
96
+ specify 'without a :by option (default)' do
97
+ playlist_starts = playlist.playlist_starts range
98
+ expect(playlist_starts.keys).to eq range.values
99
+ end
100
+
101
+ specify 'with the :by option set to :day' do
102
+ playlist_starts = playlist.playlist_starts range.merge by: :day
103
+ expect(playlist_starts.keys).to eq range.values
104
+ end
105
+ end
106
+
107
+ describe 'average time in playlist can be retrieved for a specific day' do
108
+ context 'in which the playlist was viewed' do
109
+ let(:average_time_in_playlist) { playlist.average_time_in_playlist_on ENV['YT_TEST_PARTNER_PLAYLIST_DATE']}
110
+ it { expect(average_time_in_playlist).to be_a Float }
111
+ end
112
+
113
+ context 'in which the playlist was not viewed' do
114
+ let(:average_time_in_playlist) { playlist.average_time_in_playlist_on 20.years.ago}
115
+ it { expect(average_time_in_playlist).to be_nil }
116
+ end
117
+ end
118
+
119
+ describe 'average time in playlist can be retrieved for a range of days' do
120
+ let(:date) { 4.days.ago }
121
+
122
+ specify 'with a given start (:since option)' do
123
+ expect(playlist.average_time_in_playlist(since: date).keys.min).to eq date.to_date
124
+ end
125
+
126
+ specify 'with a given end (:until option)' do
127
+ expect(playlist.average_time_in_playlist(until: date).keys.max).to eq date.to_date
128
+ end
129
+
130
+ specify 'with a given start (:from option)' do
131
+ expect(playlist.average_time_in_playlist(from: date).keys.min).to eq date.to_date
132
+ end
133
+
134
+ specify 'with a given end (:to option)' do
135
+ expect(playlist.average_time_in_playlist(to: date).keys.max).to eq date.to_date
136
+ end
137
+ end
138
+
139
+ describe 'average time in playlist can be grouped by day' do
140
+ let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
141
+ let(:keys) { range.values }
142
+
143
+ specify 'without a :by option (default)' do
144
+ average_time_in_playlist = playlist.average_time_in_playlist range
145
+ expect(average_time_in_playlist.keys).to eq range.values
146
+ end
147
+
148
+ specify 'with the :by option set to :day' do
149
+ average_time_in_playlist = playlist.average_time_in_playlist range.merge by: :day
150
+ expect(average_time_in_playlist.keys).to eq range.values
151
+ end
152
+ end
153
+
154
+ describe 'views per playlist start can be retrieved for a specific day' do
155
+ context 'in which the playlist was viewed' do
156
+ let(:views_per_playlist_start) { playlist.views_per_playlist_start_on ENV['YT_TEST_PARTNER_PLAYLIST_DATE']}
157
+ it { expect(views_per_playlist_start).to be_a Float }
158
+ end
159
+
160
+ context 'in which the playlist was not viewed' do
161
+ let(:views_per_playlist_start) { playlist.views_per_playlist_start_on 20.years.ago}
162
+ it { expect(views_per_playlist_start).to be_nil }
163
+ end
164
+ end
165
+
166
+ describe 'views per playlist start can be retrieved for a range of days' do
167
+ let(:date) { 4.days.ago }
168
+
169
+ specify 'with a given start (:since option)' do
170
+ expect(playlist.views_per_playlist_start(since: date).keys.min).to eq date.to_date
171
+ end
172
+
173
+ specify 'with a given end (:until option)' do
174
+ expect(playlist.views_per_playlist_start(until: date).keys.max).to eq date.to_date
175
+ end
176
+
177
+ specify 'with a given start (:from option)' do
178
+ expect(playlist.views_per_playlist_start(from: date).keys.min).to eq date.to_date
179
+ end
180
+
181
+ specify 'with a given end (:to option)' do
182
+ expect(playlist.views_per_playlist_start(to: date).keys.max).to eq date.to_date
183
+ end
184
+ end
185
+
186
+ describe 'views per playlist start can be grouped by day' do
187
+ let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
188
+ let(:keys) { range.values }
189
+
190
+ specify 'without a :by option (default)' do
191
+ views_per_playlist_start = playlist.views_per_playlist_start range
192
+ expect(views_per_playlist_start.keys).to eq range.values
193
+ end
194
+
195
+ specify 'with the :by option set to :day' do
196
+ views_per_playlist_start = playlist.views_per_playlist_start range.merge by: :day
197
+ expect(views_per_playlist_start.keys).to eq range.values
198
+ end
199
+ end
200
+ end
201
+
202
+ context 'not managed by the authenticated Content Owner' do
203
+ let(:id) { 'PLbpi6ZahtOH6J5oPGySZcmbRfT7Hyq1sZ' }
204
+
205
+ specify 'playlist starts cannot be retrieved' do
206
+ expect{playlist.views}.to raise_error Yt::Errors::Forbidden
207
+ expect{playlist.playlist_starts}.to raise_error Yt::Errors::Forbidden
208
+ expect{playlist.average_time_in_playlist}.to raise_error Yt::Errors::Forbidden
209
+ expect{playlist.views_per_playlist_start}.to raise_error Yt::Errors::Forbidden
210
+ end
211
+ end
212
+ end
213
+ end
@@ -7,7 +7,7 @@ describe Yt::Video, :partner do
7
7
 
8
8
  context 'given a video of a partnered channel', :partner do
9
9
  context 'managed by the authenticated Content Owner' do
10
- let(:id) { ENV['YT_TEST_VIDEO_CHANNEL_ID'] }
10
+ let(:id) { ENV['YT_TEST_PARTNER_VIDEO_ID'] }
11
11
 
12
12
  describe 'advertising options can be retrieved' do
13
13
  it { expect{video.advertising_options_set}.not_to raise_error }
@@ -478,6 +478,157 @@ describe Yt::Video, :partner do
478
478
  end
479
479
  end
480
480
 
481
+ describe 'estimated minutes watched can be retrieved for a specific day' do
482
+ context 'in which the video was partnered' do
483
+ let(:estimated_minutes_watched) { video.estimated_minutes_watched_on 5.days.ago}
484
+ it { expect(estimated_minutes_watched).to be_a Float }
485
+ end
486
+
487
+ context 'in which the video was not partnered' do
488
+ let(:estimated_minutes_watched) { video.estimated_minutes_watched_on 20.years.ago}
489
+ it { expect(estimated_minutes_watched).to be_nil }
490
+ end
491
+ end
492
+
493
+ describe 'estimated minutes watched can be retrieved for a range of days' do
494
+ let(:date) { 4.days.ago }
495
+
496
+ specify 'with a given start (:since option)' do
497
+ expect(video.estimated_minutes_watched(since: date).keys.min).to eq date.to_date
498
+ end
499
+
500
+ specify 'with a given end (:until option)' do
501
+ expect(video.estimated_minutes_watched(until: date).keys.max).to eq date.to_date
502
+ end
503
+
504
+ specify 'with a given start (:from option)' do
505
+ expect(video.estimated_minutes_watched(from: date).keys.min).to eq date.to_date
506
+ end
507
+
508
+ specify 'with a given end (:to option)' do
509
+ expect(video.estimated_minutes_watched(to: date).keys.max).to eq date.to_date
510
+ end
511
+ end
512
+
513
+ describe 'estimated minutes watched can be grouped by day' do
514
+ let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
515
+ let(:keys) { range.values }
516
+
517
+ specify 'without a :by option (default)' do
518
+ estimated_minutes_watched = video.estimated_minutes_watched range
519
+ expect(estimated_minutes_watched.keys).to eq range.values
520
+ end
521
+
522
+ specify 'with the :by option set to :day' do
523
+ estimated_minutes_watched = video.estimated_minutes_watched range.merge by: :day
524
+ expect(estimated_minutes_watched.keys).to eq range.values
525
+ end
526
+ end
527
+
528
+ describe 'estimated minutes watched can be grouped by traffic source' do
529
+ let(:range) { {since: 4.days.ago, until: 3.days.ago} }
530
+ let(:keys) { Yt::Collections::Reports::TRAFFIC_SOURCES.keys }
531
+
532
+ specify 'with the :by option set to :traffic_source' do
533
+ estimated_minutes_watched = video.estimated_minutes_watched range.merge by: :traffic_source
534
+ expect(estimated_minutes_watched.keys - keys).to be_empty
535
+ end
536
+ end
537
+
538
+ describe 'average view duration can be retrieved for a specific day' do
539
+ context 'in which the video was partnered' do
540
+ let(:average_view_duration) { video.average_view_duration_on 5.days.ago}
541
+ it { expect(average_view_duration).to be_a Float }
542
+ end
543
+
544
+ context 'in which the video was not partnered' do
545
+ let(:average_view_duration) { video.average_view_duration_on 20.years.ago}
546
+ it { expect(average_view_duration).to be_nil }
547
+ end
548
+ end
549
+
550
+ describe 'average view duration can be retrieved for a range of days' do
551
+ let(:date) { 4.days.ago }
552
+
553
+ specify 'with a given start (:since option)' do
554
+ expect(video.average_view_duration(since: date).keys.min).to eq date.to_date
555
+ end
556
+
557
+ specify 'with a given end (:until option)' do
558
+ expect(video.average_view_duration(until: date).keys.max).to eq date.to_date
559
+ end
560
+
561
+ specify 'with a given start (:from option)' do
562
+ expect(video.average_view_duration(from: date).keys.min).to eq date.to_date
563
+ end
564
+
565
+ specify 'with a given end (:to option)' do
566
+ expect(video.average_view_duration(to: date).keys.max).to eq date.to_date
567
+ end
568
+ end
569
+
570
+ describe 'average view duration can be grouped by day' do
571
+ let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
572
+ let(:keys) { range.values }
573
+
574
+ specify 'without a :by option (default)' do
575
+ average_view_duration = video.average_view_duration range
576
+ expect(average_view_duration.keys).to eq range.values
577
+ end
578
+
579
+ specify 'with the :by option set to :day' do
580
+ average_view_duration = video.average_view_duration range.merge by: :day
581
+ expect(average_view_duration.keys).to eq range.values
582
+ end
583
+ end
584
+
585
+ describe 'average view percentage can be retrieved for a specific day' do
586
+ context 'in which the video was partnered' do
587
+ let(:average_view_percentage) { video.average_view_percentage_on 5.days.ago}
588
+ it { expect(average_view_percentage).to be_a Float }
589
+ end
590
+
591
+ context 'in which the video was not partnered' do
592
+ let(:average_view_percentage) { video.average_view_percentage_on 20.years.ago}
593
+ it { expect(average_view_percentage).to be_nil }
594
+ end
595
+ end
596
+
597
+ describe 'average view percentage can be retrieved for a range of days' do
598
+ let(:date) { 4.days.ago }
599
+
600
+ specify 'with a given start (:since option)' do
601
+ expect(video.average_view_percentage(since: date).keys.min).to eq date.to_date
602
+ end
603
+
604
+ specify 'with a given end (:until option)' do
605
+ expect(video.average_view_percentage(until: date).keys.max).to eq date.to_date
606
+ end
607
+
608
+ specify 'with a given start (:from option)' do
609
+ expect(video.average_view_percentage(from: date).keys.min).to eq date.to_date
610
+ end
611
+
612
+ specify 'with a given end (:to option)' do
613
+ expect(video.average_view_percentage(to: date).keys.max).to eq date.to_date
614
+ end
615
+ end
616
+
617
+ describe 'average view percentage can be grouped by day' do
618
+ let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
619
+ let(:keys) { range.values }
620
+
621
+ specify 'without a :by option (default)' do
622
+ average_view_percentage = video.average_view_percentage range
623
+ expect(average_view_percentage.keys).to eq range.values
624
+ end
625
+
626
+ specify 'with the :by option set to :day' do
627
+ average_view_percentage = video.average_view_percentage range.merge by: :day
628
+ expect(average_view_percentage.keys).to eq range.values
629
+ end
630
+ end
631
+
481
632
  describe 'impressions can be retrieved for a specific day' do
482
633
  context 'in which the video was partnered' do
483
634
  let(:impressions) { video.impressions_on 20.days.ago}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Baccigalupo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-25 00:00:00.000000000 Z
11
+ date: 2015-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -267,6 +267,7 @@ files:
267
267
  - spec/requests/as_content_owner/content_owner_spec.rb
268
268
  - spec/requests/as_content_owner/match_policy_spec.rb
269
269
  - spec/requests/as_content_owner/ownership_spec.rb
270
+ - spec/requests/as_content_owner/playlist_spec.rb
270
271
  - spec/requests/as_content_owner/video_spec.rb
271
272
  - spec/requests/as_content_owner/viewer_percentages_spec.rb
272
273
  - spec/requests/as_server_app/channel_spec.rb
@@ -364,6 +365,7 @@ test_files:
364
365
  - spec/requests/as_content_owner/content_owner_spec.rb
365
366
  - spec/requests/as_content_owner/match_policy_spec.rb
366
367
  - spec/requests/as_content_owner/ownership_spec.rb
368
+ - spec/requests/as_content_owner/playlist_spec.rb
367
369
  - spec/requests/as_content_owner/video_spec.rb
368
370
  - spec/requests/as_content_owner/viewer_percentages_spec.rb
369
371
  - spec/requests/as_server_app/channel_spec.rb