Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ad state refactor #315

Merged
merged 51 commits into from
Feb 23, 2018
Merged

Ad state refactor #315

merged 51 commits into from
Feb 23, 2018

Conversation

incompl
Copy link
Contributor

@incompl incompl commented Jan 2, 2018

No description provided.

Copy link
Contributor

@ldayananda ldayananda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking pretty exciting. I have to come back to review the test changes again.

README.md Outdated
@@ -66,7 +66,7 @@ And here are the interaction points you use to send information to the ads plugi
* `adplaying` (EVENT) - Trigger this event when an ads starts playing. If your integration triggers `playing` event when an ad begins, it will automatically be redispatched as `adplaying`.
* `adscanceled` (EVENT) — Trigger this event after starting up the player or setting a new video to skip ads entirely. This event is optional; if you always plan on displaying ads, you don't need to worry about triggering it.
* `adserror` (EVENT) - Trigger this event to indicate that an error in the ad integration has ocurred and any ad states should abort so that content can resume.
* `nopreroll` (EVENT) - Trigger this event to indicate that there will be no preroll ad. Otherwise, the player will wait until a timeout occurs before playing content. This event is optional, but can improve user experience.
* `nopreroll` (EVENT) - Trigger this event to indicate that there will be no preroll ads to skip the preroll process completely. This event is optional, but can improve user experience. It is ignored if it is seen after `readyforpreroll`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I understand the first part of this sentence

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like something got pasted wrong. Fixing

README.md Outdated
@@ -437,9 +437,9 @@ player.src('movie-high.mp4');
### disableNextSnapshotRestore
Prevents videojs-contrib-ads from restoring the previous video source

If you need to change the video source during ad playback, you can use _disableNextSnapshotRestore_ to prevent videojs-contrib-ads to restore to the previous video source.
If you need to change the video source during an ad break, you can use _disableNextSnapshotRestore_ to prevent videojs-contrib-ads to restore to the previous video source.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to prevent videojs-contrib-ads to restore --> to prevent videojs-contrib-ads from restoring the snapshot saved from the previous video source.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making this change

README.md Outdated
```js
if (player.ads.state === 'ad-playback') {
if (player.ads.inAdBreak()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a definition for inAdBreak too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating docs

@@ -100,7 +100,7 @@
}

player.on('contentended', function() {
if (!state.postrollPlayed && player.ads.state === 'postroll?' && playPostroll) {
if (!state.postrollPlayed && playPostroll) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this check for isInAdMode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, contentended cannot happen in ad mode.

@@ -40,7 +40,7 @@ export default {
}]
],
plugins: [
// 'external-helpers',
'external-helpers',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an intended change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Pat suggested it was probably not commented out on purpose.

startLinearAdMode() {
const player = this.player;

if (!player.ads.isAdPlaying() && !this.contentResuming) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

old name isAdPlaying should be changed, and use the method for content resuming too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating

*
*/
onAdStarted(player) {
player.removeClass('vjs-ad-loading');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this go in the AdState class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vjs-ad-loading management is very different for prerolls and postrolls, so to keep it as clear as possible I isolated it to those classes rather than trying to share code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am updating the empty comment here though.

}
}

abort() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why this is so different to the other AdState subclasses?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It just evolved to be this way based on what this class was doing. I'm open to other ideas, but this doesn't seem problematic per se.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily problematic, it just seemed to me at first glance that most of what is in abort () can go in cleanup(). Except for the contentResuming change and triggering ended, I suppose.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ideally it would all go in cleanup, but I'm hesitant to change the ended event more than necessary, just to keep the risk of this PR to a minimum. Definitely something to consider in the future.

}

onNoPostroll(player) {
if (!this.contentResuming && !player.ads.inAdBreak()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another place to switch to the methods

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating

*/
startLinearAdMode() {
videojs.log.warn('Unexpected startLinearAdMode invocation (AdsDone)');
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It logically makes sense to trigger ended in this state to me...what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it's safe to do that. For example, one of the ended events happens in a 1 millisecond timeout, but not others. I think this is a good area of future improvement, but I don't think it can be safely changed in this PR without lots of re-testing.

README.md Outdated

#### inAdBreak()

This method returns true during the time between startLinearAdMode and endLinearAdMode where an integratino may play ads. This is part of ad mode.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo integratino

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing

@@ -155,7 +133,7 @@ const contribAdsPlugin = function(options) {

// Replace the plugin constructor with the ad namespace
player.ads = {
state: 'content-set',
settings,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, and that state is no longer available and should not have been relied on

@@ -92,7 +92,7 @@
// initialize the ads plugin, passing in any relevant options
player.ads(options);

// request ad inventory whenever the player gets new content to play
// request ad inventory whenever the player gets content to play
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this listener should be updated to listen to contentchanged?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally I didn't change it because it seems to run on the initial contentupdate. Now that I look at it again it seems like it might request ads twice sometimes as it is? I am going to update it.

@@ -17,7 +17,6 @@ export default class Midroll extends AdState {
const player = this.player;

if (!this.inAdBreak() && !this.isContentResuming()) {
player.ads.debug('startLinearAdMode (Midroll)');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove this log?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had added it in a relatively recent commit and found it's basically redundant with the "Starting ad break" log.

@@ -43,7 +43,6 @@ export default class Postroll extends AdState {
const player = this.player;

if (!player.ads.isAdPlaying() && !this.contentResuming) {
player.ads.debug('startLinearAdMode (Postroll)');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove this log?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had added it in a relatively recent commit and found it's basically redundant with the "Starting ad break" log.

@@ -106,8 +106,8 @@ export default class State {
this.onAdTimeout(player);
} else if (type === 'ads-ad-started') {
this.onAdStarted(player);
} else if (type === 'contentupdate') {
this.onContentUpdate(player);
} else if (type === 'contentchanged') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just for confirmation: contentupdate will no longer be used for state transitions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct

};

QUnit.module('Ad Framework', window.sharedModuleHooks());

QUnit.test('begins in content-set', function(assert) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like a good test to replace rather than delete

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't hurt

@@ -47,29 +41,26 @@ QUnit.test('pauses to wait for prerolls when the plugin loads AFTER play', funct
QUnit.test('stops canceling play events when an ad is playing', function(assert) {
var setTimeoutSpy = sinon.spy(window, 'setTimeout');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should probably change this to spy on the the player.setTimeout method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

player.setTimeout ultimately calls window.setTimeout so it ends up being the same. I think a better improvement for this test would be to test the functionality more directly. The test description says "stops canceling play events when an ad is playing". A better test would start an ad playing and see if play events get canceled. There are tons of improvements that could be made to these tests, so I had to pick my battles as I updated these.


this.player.trigger('adsready');
assert.strictEqual(setTimeoutSpy.callCount, 3, '`adTimeoutTimeout` was re-scheduled');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this line was intentionally removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the implementation changed without the behavior changing and this assertion started failing without an underlying defect in the code. I removed it to help our tests focus more on tests of functionality and reduce false positives.

this.clock.tick(1);
this.player.ads.startLinearAdMode();
this.player.ads.endLinearAdMode();
assert.notOk(timerExists(this, this.player.ads.cancelPlayTimeout), '`cancelPlayTimeout` was canceled');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test message seems wrong - play was canceled ? Or do we want the timeout to not exist?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's saying that the timeout named "cancelPlayTimeout" was canceled, confirmed by the fact that the variable saving the timeout ID was deleted.

test/test.ads.js Outdated

this.clock.tick(1);
assert.strictEqual(this.player.ads.state, 'content-playback');
this.clock.tick(1000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can go back to 1 now, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah changing it back

this.player.trigger('playing');
assert.strictEqual(this.player.ads.state, 'content-playback');
assert.strictEqual(spy.getCall(0).args[0].type, 'adend', 'adend should be fired when we enter content-playback from adserror');
assert.strictEqual(adendSpy.callCount, 0, 'no adend yet');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this test testing now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this test to do what it says it should

assert.strictEqual(sawAdpause.callCount, 1, 'adpause fired');
assert.strictEqual(sawAdended.callCount, 1, 'adended fired');
assert.strictEqual(sawAdfirstplay.callCount, 1, 'adfirstplay fired');
assert.strictEqual(sawAdloadedalldata.callCount, 1, 'adloadedalldata fired');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that firstplay, loadstart, playing, loadedalldata, pause, ended were meant to be checked as well to make sure that they were canceled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like those are there, above this line.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah missed that 🆒

test/test.ads.js Outdated
});

QUnit.test('ad impl can notify contrib-ads there is no preroll', function(assert) {

this.player.ads.state = 'preroll?';
this.player.trigger('loadstart');
this.player.trigger('nopreroll');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if nopreroll is triggered after the first of play or adsready? i.e loadstart -> play -> nopreroll

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added two more tests to cover these variants.

test/test.ads.js Outdated
this.player.trigger('contentended');

this.clock.tick(10000);

assert.ok(ended.calledOnce, 'Ended triggered');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like this is a duplicate of the previous test now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing the duplicate test

test/test.ads.js Outdated
@@ -1062,7 +887,8 @@ QUnit.test('Check incorrect addition of vjs-live during ad-playback', function(a

QUnit.test('Check for existence of vjs-live after ad-end for LIVE videos',
function(assert) {
this.player.trigger('adstart');
this.player.trigger('adsready');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loadstart?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating

@incompl incompl changed the title [WIP] Ad state refactor Ad state refactor Feb 13, 2018
var endedEvents = 0;

this.player.ads.settings.postrollTimeout = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why was this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test times out otherwise. This is just so the test runs faster basically. I'll add a comment.

README.md Outdated

If you are loading `videojs-contrib-ads` using modules, do this:

TODO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This TODO still meant to be here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I want to link to the example from #312 once that is merged. Was planning to do that in rebase. I'll add more info.

README.md Outdated
to end without an ad starting, in which case the spinner stays up the whole time.
* Integration calls `player.ads.endLinearAdMode()` (METHOD) -- This ends an ad break. As a result, content will play.
* Content plays.
* To play a Midroll ad, start an end an ad break with `player.ads.startLinearAdMode()` and `player.ads.endLinearAdMode()` at any time during content playback.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo start an end an ad break start and end an ad break

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

README.md Outdated
* Content plays.
* To play a Midroll ad, start an end an ad break with `player.ads.startLinearAdMode()` and `player.ads.endLinearAdMode()` at any time during content playback.
* Contrib Ads triggers `contentended` (EVENT) -- This event means that it's time to play a postroll ad.
* To play a Postroll ad, start an end an ad break with `player.ads.startLinearAdMode()` and `player.ads.endLinearAdMode()`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

README.md Outdated
This is the basic flow for a simple use case, but there are other things the integration can do:

* `skipLinearAdMode` (METHOD) -- At a time when `startLinearAdMode` is expected, calling `skipLinearAdMode` will immediately resume content playback instead.
* `nopreroll` (EVENT) -- You can trigger this event even before `readyforpreroll` to indicate that no preroll will play. The ad plugin will not check for prerolls and will instead immediately begin content playback after the `play` event (or immidiately, if playback was already requested).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo immidiately.

Also I would delete the first immediately in this sentence

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

README.md Outdated
* `skipLinearAdMode` (METHOD) -- At a time when `startLinearAdMode` is expected, calling `skipLinearAdMode` will immediately resume content playback instead.
* `nopreroll` (EVENT) -- You can trigger this event even before `readyforpreroll` to indicate that no preroll will play. The ad plugin will not check for prerolls and will instead immediately begin content playback after the `play` event (or immidiately, if playback was already requested).
* `nopostroll` (EVENT) -- Similar to `nopreroll`, you can trigger this event even before `contentended` to indicate that no postroll will play. The ad plugin will not wait for a postroll to play and will instead immediately trigger the `ended` event.
* `adserror` (EVENT) -- This event skips prerolls when seen before a preroll ad break. It skips postrolls if called after contentended and before a postroll ad break. It ends linear ad mode if seen during an ad break.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should say when the integration should trigger this event

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is a clear answer to that, it depends on if you want the extra behavior or not. I think we need to change how adserror works. For now, just want to make it clear what it does.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, for prerolls and postrolls the break is skipped if it is triggered before ad mode or before the ad break is started? I think that's not clear for prerolls

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It says before the ad break, which is exactly accurate.

README.md Outdated
Note: A `contentplayback` event is sent but should not be used as it is being removed. The `playing` event has the same meaning and is far more reliable.

And here are the interaction points you use to send information to the ads plugin:
* `contentchanged` (EVENT) -- Fires when a new content video has been loaded in the player (specially, at the same time as the `loadstart` media event for the new source). This means the ad workflow has restarted from the beginning. Your integration will need to trigger `adsready` again, for example. Note that when changing sources, the playback state of the player is retained: if the previous source was playing, the new source will also be playing and the ad workflow will not wait for a new `play` event.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

specially? Or specifically?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to specifically

README.md Outdated

In addition, video.js provides a number of events and APIs that might be useful to you.
For example, the `ended` event signals that the content video has played to completion.
* `contentplayback` (EVENT) -- The `playing` media event has the same meaning and is far more reliable.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I like these descriptions, they seem to fit better in the migration guide. I would then link to the most recent migration guide in this section

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, since we're removing it in this version we can move it from "deprecated" to the migration guide.


#### isInAdMode()

Returns true if player is in ad mode.
Returns true if the player is in ad mode.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't this change to be isInAdBreak?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ad mode includes loading ads and content resuming. The ad break is just a part of that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, keep getting confused

README.md Outdated

### adskip
The player is skipping a linear ad opportunity and content-playback should resume immediately. This event is fired directly as a consequence of calling `skipLinearAdMode()`. It can indicate that an ad response was made but returned no linear ad content or that no ad call is going to be made at either the preroll or postroll timeout opportunities.
The player is skipping a linear ad opportunity and content-playback should resume immediately. This event is fired directly as a consequence of calling `skipLinearAdMode()`. As examples, it can indicate that an ad response was made but returned no linear ad content or that no ad call is going to be made due to an error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As For example? Also I think you meant ad request?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating this

Copy link
Contributor

@ldayananda ldayananda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks mostly good, I'll wait for the tests to pass before approving

README.md Outdated
* `skipLinearAdMode` (METHOD) -- At a time when `startLinearAdMode` is expected, calling `skipLinearAdMode` will immediately resume content playback instead.
* `nopreroll` (EVENT) -- You can trigger this event even before `readyforpreroll` to indicate that no preroll will play. The ad plugin will not check for prerolls and will instead immediately begin content playback after the `play` event (or immidiately, if playback was already requested).
* `nopostroll` (EVENT) -- Similar to `nopreroll`, you can trigger this event even before `contentended` to indicate that no postroll will play. The ad plugin will not wait for a postroll to play and will instead immediately trigger the `ended` event.
* `adserror` (EVENT) -- This event skips prerolls when seen before a preroll ad break. It skips postrolls if called after contentended and before a postroll ad break. It ends linear ad mode if seen during an ad break.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, for prerolls and postrolls the break is skipped if it is triggered before ad mode or before the ad break is started? I think that's not clear for prerolls

README.md Outdated

Deprecated events:

* `contentplayback` (EVENT) -- The `playing` media event has the same meaning and is far more reliable.
* `contentupdate` (EVENT) -- Replaced by `contentchanged`, which is more reliable.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant for these two lines to move to the migration guide as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a "deprecation" section to the migration guide and will leave this here so there is still a deprecation warning in the readme.

Copy link
Contributor

@ldayananda ldayananda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor comments, overall really liking the new tests


this.adState = new AdState(this.player);
this.adState.transitionTo = (newState) => {
this.transitionTo = newState.name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think transitionTo is a confusing name since it sounds like a method. Maybe transitionedTo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was also considering transitionedTo and newState, newState is probably the most obvious

this.contentState.onContentChanged(this.player);
assert.equal(this.transitionTo, 'Preroll');
assert.equal(this.player.pause.callCount, 1, 'paused player');
assert.equal(this.player.ads._pausedOnContentupdate, true, 'set _pausedOnContentupdate');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should have been checked on the last test, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's extra, might as well add it

this.player.ads._cancelledPlay = false;
this.player.ads._pausedOnContentupdate = false;
this.contentPlayback.init(this.player);
assert.equal(this.played, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't seem right since paused() -> false

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe played should be playTriggered

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changing it


QUnit.test('ends an ad break on endLinearAdMode', function(assert) {
this.midroll.init(this.player);
this.player.ads._inLinearAdMode = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you have to hardcode this? could we do this as part of the stub?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted the stub to reflect an "initial" state and have each test advance it forward to the necessary state, rather than having the stub be kind of a random assortment of properties.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Would calling startLinearAdMode be equivalent then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, originally I wanted to limit the test to only calling one function, but looking back on it now, using startLinearAdMode is a more solid test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake. startLinearAdMode is not defined in Midroll.js, so that's not an option.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this.player.ads._inLinearAdMode is always mocked in this test file. I suppose that is fine then

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! Just realized that when you enter the Midroll state, _inLinearAdMode would always be true, so it make sense for this to change in the mock. We've gone full circle on this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

this.postroll.init(this.player);
this.player.ads.inAdBreak = () => false;
this.postroll.onAdsError(this.player);
assert.equal(this.player.ads.endLinearAdMode.callCount, 0, 'linear ad mode ended');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does ended get called?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might as well assert not

Copy link
Contributor Author

@incompl incompl Feb 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry the other way, we assert that ended is still triggered

assert.equal(this.preroll.inAdBreak(), false, 'not in ad break');

this.preroll.startLinearAdMode();
this.player.ads._inLinearAdMode = true; // Because adBreak.start is mocked.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comments should go on the line above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changing

this.preroll.startLinearAdMode();
this.player.ads._inLinearAdMode = true; // Because adBreak.start is mocked.
assert.equal(this.adBreakStartStub.callCount, 1, 'ad break started');
assert.equal(this.player.ads.adType, 'preroll', 'adType is preroll');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did we have one of these for postroll?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adding one

@ldayananda
Copy link
Contributor

Also, this comment got hidden: #315 (comment)

@incompl
Copy link
Contributor Author

incompl commented Feb 21, 2018 via email

Copy link
Contributor

@ldayananda ldayananda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you actually got the comment that was hidden.

@@ -57,7 +57,7 @@ export default class BeforePreroll extends ContentState {
*/
onNoPreroll() {
this.player.ads.debug('Skipping prerolls due to nopreroll event (BeforePreroll)');
this.transitionTo(Preroll, this.adsReady);
this.transitionTo(ContentPlayback);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

* `skipLinearAdMode` (METHOD) -- At a time when `startLinearAdMode` is expected, calling `skipLinearAdMode` will immediately resume content playback instead.
* `nopreroll` (EVENT) -- You can trigger this event even before `readyforpreroll` to indicate that no preroll will play. The ad plugin will not check for prerolls and will instead begin content playback after the `play` event (or immediately, if playback was already requested).
* `nopostroll` (EVENT) -- Similar to `nopreroll`, you can trigger this event even before `contentended` to indicate that no postroll will play. The ad plugin will not wait for a postroll to play and will instead immediately trigger the `ended` event.
* `adserror` (EVENT) -- This event skips prerolls when seen before a preroll ad break. It skips postrolls if called after contentended and before a postroll ad break. It ends linear ad mode if seen during an ad break.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thread might get a bit convoluted so I'll just summarize: for prerolls, if you trigger adserror in BeforePreroll, will it skip ads?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup


QUnit.test('ends an ad break on endLinearAdMode', function(assert) {
this.midroll.init(this.player);
this.player.ads._inLinearAdMode = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Would calling startLinearAdMode be equivalent then?

Copy link
Contributor

@ldayananda ldayananda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@incompl incompl merged commit d11ef39 into master Feb 23, 2018
@incompl incompl deleted the ad-state-refactor branch February 23, 2018 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants