Skip to content

✨[amp-consent] block buildcallback through granular consent#32990

Merged
micajuine-ho merged 6 commits intoampproject:masterfrom
micajuine-ho:granularPolicyManager
Mar 3, 2021
Merged

✨[amp-consent] block buildcallback through granular consent#32990
micajuine-ho merged 6 commits intoampproject:masterfrom
micajuine-ho:granularPolicyManager

Conversation

@micajuine-ho
Copy link
Copy Markdown
Contributor

Partial for #31607

Add the runtime check for the data-block-on-consent-purposes attribute, and block if not all the purpose consents have been collected and are accepted.

Since our UI prompts if we don't have all the consents gathered, don't start the check to unblock elements that are blocked by granular consent until the UI closes and we have the purpose consents or we relying on the sync.

For syncing, if we already have all the purpose consents stored, then the UI won't show and we should unblock. If we don't have the consent purposes stored, we will store them through the update, and this will allow the policy manager to signal to runtime which element to unblock.

This notion of waiting until we collect the purpose consents is handled by the consent state manager since it communicates with amp-consent (UI and syncing) and the policy manager.

@micajuine-ho micajuine-ho requested a review from dmanek March 1, 2021 20:07
@amp-owners-bot amp-owners-bot bot requested a review from rcebulko March 1, 2021 20:07
@micajuine-ho micajuine-ho force-pushed the granularPolicyManager branch from e3c864e to 35388d7 Compare March 1, 2021 20:18
Copy link
Copy Markdown
Contributor

@rcebulko rcebulko left a comment

Choose a reason for hiding this comment

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

/cc @samouri as I'm less familiar with some of the callback details

}
return true;
})
.then((hasPurposeConsents) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As far as I can tell, nothing in the above .then handler is asynchronous or returning a promise. Rather than extending the promise chain, this chunk could live in the function/handler above

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Just thought it would be cleaning to separate these ideas, but I can fix and also insure clarity.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Another option if you wanted separation/clarity without extra promises might be defining hasPurposeConsents(purposeConsentsRequired) as its own method and making the full promise handler

.then((purposeConsentsRequired) => {
  if (hasPurposeConsents(purposeConsentsRequired) {
    this.consentStateManager_.hasAllPurposeConsents();
    return true;
  }
  return false;
});

Feel free to ignore this, just offering alternative

}
return true;
})
.then((hasPurposeConsents) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1

@micajuine-ho micajuine-ho force-pushed the granularPolicyManager branch 2 times, most recently from 842ce95 to da447c2 Compare March 2, 2021 21:19
@micajuine-ho micajuine-ho force-pushed the granularPolicyManager branch from da447c2 to efad544 Compare March 2, 2021 22:26
});

afterEach(() => {
toggleExperiment(win, 'amp-consent-granular-consent', false);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

FMI: do we explicitly need to toggle experiments off or are they reset each time anyway?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Explicit is better to avoid memory leaks.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any particular reason for doing beforeEach/afterEach instead of beforeAll/afterAll?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We are not allowed to use beforeAll/afterAll

Copy link
Copy Markdown
Member

@samouri samouri left a comment

Choose a reason for hiding this comment

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

Changes to custom-element LGTM

* Wait for initial consent information to be transmitted,
* then get consent state for this purpose.
*
* Note: Even if we have some intiial consent info, wait until all
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

typo: intiial

* when to resolve the promis (via update() or directly).
* @return {!Promise}
*/
whenHasAllPurposeConsents() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: rename this method? Perhaps just getHasAllPurposeConsents?

Copy link
Copy Markdown
Contributor

@rcebulko rcebulko Mar 3, 2021

Choose a reason for hiding this comment

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

I agree the naming here can add some confusion (esp. since hasFooBar is frequently used for boolean flags/checks rather than mutation functions). WDYT about something like:

constructor() {
  ...
  this.hasAllPurposeConsentsDeferred = new Deferred();
  ...
}

get hasAllPurposeConsents() {
  return this.hasAllPurposeConsentsDeferred.promise;
}
get hasAllPurposeConsentsResolver() {
  return this.hasAllPurposeConsentsDeferred.resolve;
} 

A bit more verbose, but maybe being explicit could make it clearer?

});

afterEach(() => {
toggleExperiment(win, 'amp-consent-granular-consent', false);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any particular reason for doing beforeEach/afterEach instead of beforeAll/afterAll?

* when to resolve the promis (via update() or directly).
* @return {!Promise}
*/
whenHasAllPurposeConsents() {
Copy link
Copy Markdown
Contributor

@rcebulko rcebulko Mar 3, 2021

Choose a reason for hiding this comment

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

I agree the naming here can add some confusion (esp. since hasFooBar is frequently used for boolean flags/checks rather than mutation functions). WDYT about something like:

constructor() {
  ...
  this.hasAllPurposeConsentsDeferred = new Deferred();
  ...
}

get hasAllPurposeConsents() {
  return this.hasAllPurposeConsentsDeferred.promise;
}
get hasAllPurposeConsentsResolver() {
  return this.hasAllPurposeConsentsDeferred.resolve;
} 

A bit more verbose, but maybe being explicit could make it clearer?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants