Skip to content

Commit

Permalink
Allows platforms to register on free pages (#27556)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisAntaki committed Apr 6, 2020
1 parent 49dea74 commit 3c8db36
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 76 deletions.
79 changes: 44 additions & 35 deletions extensions/amp-subscriptions/0.1/amp-subscriptions.js
Expand Up @@ -144,12 +144,11 @@ export class SubscriptionService {
// If the page is not locked then we treat it as granted and show any
// subscriptions content sections.
this.processGrantState_(true);
return;
}

if (this.doesViewerProvideAuth_) {
this.delegateAuthToViewer_();
this.startAuthorizationFlow_(false);
this.startAuthorizationFlow_(false /** doPlatformSelection */);
return;
}

Expand Down Expand Up @@ -276,6 +275,7 @@ export class SubscriptionService {
*
* @param {string} serviceId
* @param {function(!JsonObject, !ServiceAdapter):!SubscriptionPlatform} subscriptionPlatformFactory
* @return {!Promise}
*/
registerPlatform(serviceId, subscriptionPlatformFactory) {
return this.initialize_().then(() => {
Expand Down Expand Up @@ -324,26 +324,29 @@ export class SubscriptionService {
/**
* Reset all platforms and re-fetch entitlements after an
* external event (for example a login)
* @return {!Promise}
*/
resetPlatforms() {
this.platformStore_ = this.platformStore_.resetPlatformStore();
this.renderer_.toggleLoading(true);
return this.initialize_().then(() => {
this.platformStore_ = this.platformStore_.resetPlatformStore();
this.renderer_.toggleLoading(true);

this.platformStore_
.getAvailablePlatforms()
.forEach((subscriptionPlatform) => {
this.fetchEntitlements_(subscriptionPlatform);
});
this.subscriptionAnalytics_.serviceEvent(
SubscriptionAnalyticsEvents.PLATFORM_REAUTHORIZED,
''
);
// deprecated event fired for backward compatibility
this.subscriptionAnalytics_.serviceEvent(
SubscriptionAnalyticsEvents.PLATFORM_REAUTHORIZED_DEPRECATED,
''
);
this.startAuthorizationFlow_();
this.platformStore_
.getAvailablePlatforms()
.forEach((subscriptionPlatform) => {
this.fetchEntitlements_(subscriptionPlatform);
});
this.subscriptionAnalytics_.serviceEvent(
SubscriptionAnalyticsEvents.PLATFORM_REAUTHORIZED,
''
);
// deprecated event fired for backward compatibility
this.subscriptionAnalytics_.serviceEvent(
SubscriptionAnalyticsEvents.PLATFORM_REAUTHORIZED_DEPRECATED,
''
);
this.startAuthorizationFlow_();
});
}

/**
Expand Down Expand Up @@ -454,20 +457,26 @@ export class SubscriptionService {
* @private
*/
processGrantState_(grantState) {
this.renderer_.toggleLoading(false);
/*
* If the viewer is providing a paywall we don't want the publisher
* paywall to render in the case of no grant so we leave the page
* in the original "unknown" state.
*/
if (grantState || !this.doesViewerProvidePaywall_) {
this.renderer_.setGrantState(grantState);
// Don't show paywalls on free pages.
if (this.isPageUnlocked_()) {
grantState = true;
}

// Hide loading animation.
this.renderer_.toggleLoading(false);

// Track view.
this.viewTrackerPromise_ = this.viewerTracker_.scheduleView(2000);
if (grantState === false) {
// TODO(@prateekbh): Show UI that no eligible entitlement found

// If the viewer is providing a paywall we don't want the publisher
// paywall to render in the case of no grant so we leave the page
// in the original "unknown" state.
if (this.doesViewerProvidePaywall_ && !grantState) {
return;
}

// Update UI.
this.renderer_.setGrantState(grantState);
}

/**
Expand Down Expand Up @@ -519,6 +528,11 @@ export class SubscriptionService {
* @return {!Promise}
*/
fetchEntitlements_(subscriptionPlatform) {
// Don't fetch entitlements on free pages.
if (this.isPageUnlocked_()) {
return Promise.resolve();
}

let timeout = ENTITLEMENTS_REQUEST_TIMEOUT;
if (getMode().development || getMode().localDev) {
timeout = ENTITLEMENTS_REQUEST_TIMEOUT * 2;
Expand Down Expand Up @@ -700,12 +714,7 @@ export class SubscriptionService {
* @private
*/
isPageUnlocked_() {
return (
!this.pageConfig_.isLocked() ||
// If a service marks `alwaysGrant` as true, it will unlock the page
// unless the viewer provides auth.
(this.platformConfig_['alwaysGrant'] && !this.doesViewerProvideAuth_)
);
return !this.pageConfig_.isLocked() || this.platformConfig_['alwaysGrant'];
}
}

Expand Down
133 changes: 92 additions & 41 deletions extensions/amp-subscriptions/0.1/test/test-amp-subscriptions.js
Expand Up @@ -215,39 +215,6 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
expect(processStateStub).to.be.calledWith(true);
});

it(
'should not skip everything and unlock document for alwaysGrant ' +
'if viewer provides authorization',
async () => {
const processStateStub = env.sandbox.stub(
subscriptionService,
'processGrantState_'
);
const authFlowStub = env.sandbox.stub(
subscriptionService,
'startAuthorizationFlow_'
);
const delegateStub = env.sandbox.stub(
subscriptionService,
'delegateAuthToViewer_'
);
env.sandbox.stub(subscriptionService, 'initialize_').callsFake(() => {
subscriptionService.platformConfig_ = {
alwaysGrant: true,
};
subscriptionService.pageConfig_ = pageConfig;
subscriptionService.doesViewerProvideAuth_ = true;
return Promise.resolve();
});
subscriptionService.start();

await subscriptionService.initialize_();
expect(authFlowStub.withArgs(false)).to.be.calledOnce;
expect(delegateStub).to.be.calledOnce;
expect(processStateStub).to.not.be.called;
}
);

it('should delay the platform selection and activation if story', async () => {
isStory = true;

Expand Down Expand Up @@ -594,6 +561,7 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
subscriptionService,
'performPingback_'
);
await subscriptionService.initialize_();
subscriptionService.startAuthorizationFlow_();
expect(getGrantStatusStub).to.be.calledOnce;
expect(selectAndActivateStub).to.be.calledOnce;
Expand All @@ -617,6 +585,34 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
});
});

describe('processGrantState_', () => {
let setGrantStateStub;

beforeEach(async () => {
setGrantStateStub = env.sandbox.stub(
subscriptionService.renderer_,
'setGrantState'
);
await subscriptionService.initialize_();
});

it('can process grant state of false', () => {
subscriptionService.processGrantState_(false);
expect(setGrantStateStub).to.be.calledWith(false);
});

it('forces grant state to true for free pages', () => {
// Mark page as free.
subscriptionService.platformConfig_ = {
alwaysGrant: true,
services: [{'serviceId': 'platform1'}],
};

subscriptionService.processGrantState_(false);
expect(setGrantStateStub).to.be.calledWith(true);
});
});

describe('fetchEntitlements_', () => {
let platform;
let serviceAdapter;
Expand Down Expand Up @@ -647,10 +643,13 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
subscriptionService.platformStore_,
'reportPlatformFailureAndFallback'
);
subscriptionService.fetchEntitlements_(platform).catch(() => {
expect(failureStub).to.be.calledOnce;
done();
});
subscriptionService
.initialize_()
.then(() => subscriptionService.fetchEntitlements_(platform))
.catch(() => {
expect(failureStub).to.be.calledOnce;
done();
});
}).timeout(7000);

it('should report failure if platform reject promise', (done) => {
Expand All @@ -662,7 +661,8 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
'reportPlatformFailureAndFallback'
);
const promise = subscriptionService
.fetchEntitlements_(platform)
.initialize_()
.then(() => subscriptionService.fetchEntitlements_(platform))
.catch(() => {
expect(failureStub).to.be.calledOnce;
done();
Expand All @@ -684,6 +684,7 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
subscriptionService.platformStore_,
'resolveEntitlement'
);
await subscriptionService.initialize_();

await subscriptionService.fetchEntitlements_(platform);
expect(resolveStub).to.be.calledOnce;
Expand All @@ -696,7 +697,7 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
);
});

it('should reset platform on re-authorization', () => {
it('should reset platform on re-authorization', async () => {
const service = serviceConfig.services[0];
subscriptionService.serviceAdapter_ = new ServiceAdapter(
subscriptionService
Expand All @@ -712,7 +713,7 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
);
env.sandbox.stub(subscriptionService, 'startAuthorizationFlow_');
const origPlatforms = subscriptionService.platformStore_.serviceIds_;
subscriptionService.resetPlatforms();
await subscriptionService.resetPlatforms();
expect(resetSubscriptionPlatformSpy).to.be.calledOnce;
expect(subscriptionService.platformStore_.serviceIds_).to.equal(
origPlatforms
Expand All @@ -732,10 +733,37 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
env.sandbox
.stub(subscriptionService.cryptoHandler_, 'isDocumentEncrypted')
.callsFake(() => true);
await subscriptionService.initialize_();

const ent = await subscriptionService.fetchEntitlements_(platform);
expect(ent).to.be.deep.equal(Entitlement.empty('local'));
});

it('should fetch entitlements on paid pages', async () => {
const getEntitlementsStub = env.sandbox
.stub(subscriptionService, 'getEntitlements_')
.returns(Promise.resolve(new Entitlement.empty('local')));
await subscriptionService.initialize_();

await subscriptionService.fetchEntitlements_(platform);
expect(getEntitlementsStub).to.be.called;
});

it('should not fetch entitlements on free pages', async () => {
const getEntitlementsStub = env.sandbox.stub(
subscriptionService,
'getEntitlements_'
);
await subscriptionService.initialize_();
// Mark page as free.
subscriptionService.platformConfig_ = {
alwaysGrant: true,
services: [{'serviceId': 'platform1'}],
};

await subscriptionService.fetchEntitlements_(platform);
expect(getEntitlementsStub).to.not.be.called;
});
});

describe('getEntitlements_', () => {
Expand Down Expand Up @@ -806,6 +834,29 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
});
});

describe('registerPlatform', () => {
it('should work on free pages', async () => {
const platformFactoryStub = env.sandbox.stub().callsFake(() => ({
getServiceId: () => 'platform1',
}));
env.sandbox.stub(subscriptionService, 'initialize_').callsFake(() => {
subscriptionService.platformConfig_ = {
alwaysGrant: true,
services: [{'serviceId': 'platform1'}],
};
subscriptionService.pageConfig_ = pageConfig;
return Promise.resolve();
});
subscriptionService.start();

await subscriptionService.registerPlatform(
'platform1',
platformFactoryStub
);
expect(platformFactoryStub).to.be.called;
});
});

describe('viewer authorization', () => {
let fetchEntitlementsStub;
let sendMessageAwaitResponsePromise;
Expand Down Expand Up @@ -1197,7 +1248,7 @@ describes.fakeWin('AmpSubscriptions', {amp: true}, (env) => {
.eventually.be.undefined;
});

it('should resolve authdata on an unlocked page', async () => {
it('should resolve authdata on free pages', async () => {
env.sandbox.stub(subscriptionService, 'initialize_').callsFake(() => {
subscriptionService.platformConfig_ = {
alwaysGrant: false,
Expand Down

0 comments on commit 3c8db36

Please sign in to comment.