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
Add support for cache:getClientId #14450
Conversation
…he-served pages without a viewer.
…he CCT-embedded implementations are just for the interim.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good! Needs unit tests for cache-cid-api.js.
src/service/cache-cid-api.js
Outdated
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* amp-lUSTQLTz0csodkt327ZRHm30PG-6sJOuZwTh-PPmzqRMGZrTCRBMJ8Pfdw8f_UGC | ||
* amp-lUSTQLTz0csodkt327ZRHm30PG-6sJOuZwTh-PPmzqRMGZrTCRBMJ8Pfdw8f_UGC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
src/service/cache-cid-api.js
Outdated
const TAG = 'CacheCidApi'; | ||
const CACHE_API_URL = 'https://ampcid.google.com/v1/cache:getClientId?key='; | ||
|
||
const TIMEOUT = 30000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add JSDoc for all of these constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/service/cache-cid-api.js
Outdated
*/ | ||
export class CacheCidApi { | ||
|
||
constructor(ampdoc) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSDoc please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/service/cache-cid-api.js
Outdated
* @return {!Promise<?string>} | ||
*/ | ||
getScopedCid(scope) { | ||
// promise for whether we do stuff at all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what this comment means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, it was a draft holdover from when the structure of the method was more confusing and I was starting comment stubs.
src/service/cache-cid-api.js
Outdated
// The client is still responsible for appending API keys to the URL. | ||
const alt = `${response['alternateUrl']}?key=${SERVICE_KEY_}`; | ||
return this.fetchCid_(dev().assertString(alt)) | ||
.then(altRes => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than dupe this logic, let's add an optional param to fetchCid_
that checks for alternateUrl
and defaults to true
. Then pass false
for this invocation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks.
src/service/cache-cid-api.js
Outdated
import {dict} from '../utils/object'; | ||
import {getSourceOrigin} from '../url'; | ||
|
||
const GOOGLE_CLIENT_ID_API_META_NAME = 'amp-google-client-id-api'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's be consistent wrt "CLIENT_ID" vs "CID" -- GOOGLE_CID_API_META_NAME
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/service/cache-cid-api.js
Outdated
* Returns scoped CID extracted from the fetched publisherCid. | ||
* @param {string} publisherCid | ||
* @param {string} scope | ||
* @return {?string} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This returns !Promise<string>
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks.
src/service/cache-cid-api.js
Outdated
* @return {?string} | ||
*/ | ||
scopeCid_(publisherCid, scope) { | ||
if (!publisherCid) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{string}
is non-nullable by default. Is it possible for this to be empty string or should we change the type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fetchCid_ returns a nullable string, which used to propagate to this method. I moved the null check to the call site.
src/service/cache-cid-api.js
Outdated
} | ||
|
||
/** | ||
* @return {!Object<string, string>} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a description with an example of what the <meta>
tag can looks like here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this what you meant?
BTW, an editor with eslint plugin configured will save a lot of time compared to |
Just merged #14224, please merge latest changes from master. |
src/service/cache-cid-api.js
Outdated
/** | ||
* @return {!Object<string, string>} | ||
*/ | ||
getOptedInScopes_() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this verbatim from viewer-cid-api.js
? Can it live in cid-impl.js
instead and be called at time of invocation of isScopeOptedIn
and passed in as a param?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall.
src/service/cache-cid-api.js
Outdated
* Returns scoped CID retrieved from the Viewer. | ||
* @param {string|undefined} apiKey | ||
* @param {string} scope | ||
* @return {!Promise<string>} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!Promise<?string>
src/service/cid-impl.js
Outdated
@@ -94,12 +123,20 @@ export class Cid { | |||
*/ | |||
this.externalCidCache_ = Object.create(null); | |||
|
|||
/** | |||
* @private {!CacheCidApi} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add @const
.
src/service/cid-impl.js
Outdated
@@ -175,8 +212,8 @@ export class Cid { | |||
const scope = getCidStruct.scope; | |||
/** @const {!Location} */ | |||
const url = parseUrl(this.ampdoc.win.location.href); | |||
const apiKey = this.isScopeOptedIn_(scope); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's only call this if necessary to avoid wasted work.
const SERVICE_KEY_ = 'AIzaSyDKtqGxnoeIqVM33Uf7hRSa3GJxuzR7mLc'; | ||
const API_KEY = 'AIzaSyA65lEHUEizIsNtlbNo-l2K18dT680nsaM'; | ||
const TEST_CID_ = | ||
'amp-mJW1ZjoviqBJydzRI8KnitWEpqyhQqDegGClrvvfkCif_N9oYLdZEB976uJDhYgL'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not use the actual keys in tests if possible. If we need to change them in the future then it would appear we'd need to update these tests too. Something readable like my-service-key
and my-api-key
would suffice.
return api.getScopedCid(API_KEY, 'AMP_ECID_GOOGLE').then(cid => { | ||
expect(cid).to.equal(TEST_CID_); | ||
expect(fetchJsonStub) | ||
.to.be.calledWith(`https://ampcid.google.com/v1/cache:getClientId?key=${SERVICE_KEY_}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just use the actual string literal for readability. ToTT issue 510. 😉
@@ -795,7 +800,8 @@ describes.realWin('cid', {amp: true}, env => { | |||
|
|||
beforeEach(() => { | |||
sandbox.stub(url, 'isProxyOrigin').returns(false); | |||
sandbox.stub(cid.viewerCidApi_, 'isScopeOptedIn').returns('api-key'); | |||
ampdoc.win.document.head.innerHTML += | |||
'<meta name="amp-google-client-id-api" content="googleanalytics">'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change (and line 821) necessary? It's better to avoid mutating the document during tests (e.g. can break other tests if you forget to revert in afterEach
).
I did notice that this is patterned off of test-viewer-cid-api.js.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don't think it'll be easy to avoid adding to the document, given that the behaviour under test is supposed to extract the configuration from it.
test/functional/test-cid.js
Outdated
@@ -44,6 +44,8 @@ import {stubServiceForDoc} from '../../testing/test-helper'; | |||
|
|||
const DAY = 24 * 3600 * 1000; | |||
|
|||
const API_KEY = 'AIzaSyA65lEHUEizIsNtlbNo-l2K18dT680nsaM'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove this and inline it in the original isScopedOptedIn_
tests you moved.
}); | ||
}); | ||
|
||
describe('getScopedCid', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing the timeout logic would be nice. You can use sinon's fake clock to simulate 30s passing synchronously.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, and this revealed a promise chaining bug (catch block didn't catch the timeout because it was chained to the XHR).
/cc @jridgewell Another unavoidable size bump FYI. We could move viewer-cid-api.js to amp-viewer-integration but I don't think it'll help much. What's interesting is that the browserify build increased by 0.1KB while the minified build increased by 0.26KB. Looks like the obfuscation impeded compressibility. |
From Travis, looks like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So much duplication between this and https://github.com/ampproject/amphtml/blob/9b101fa000b7dc911073cacdf3ccafb187c2012d/src/service/cid-api.js.
And, there are now 4 different CID api files:
- src/service/cid-api.js
- src/service/cid-impl.js
- src/service/viewer-cid-api.js
- src/service/cache-cid-api.js
What's the difference? What is the responsibility of each file?
/cc @lannka
if (this.cacheCidApi_.isSupported()) { | ||
const apiKey = this.isScopeOptedIn_(scope); | ||
if (!apiKey) { | ||
return /** @type {!Promise<?string>} */ (Promise.resolve(null)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't CCT fall back to normal cids?
*/ | ||
getScopedCid(scope) { | ||
if (!this.viewer_.isCctEmbedded()) { | ||
return /** @type {!Promise<?string>} */ (Promise.resolve(null)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throw an error.
body: payload, | ||
})).then(res => { | ||
return res.json().then(response => { | ||
if (response['optOut']) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This entire function's whitespace is borked.
// If an alternate url is provided, try again with the alternate url | ||
// The client is still responsible for appending API keys to the URL. | ||
const alt = `${response['alternateUrl']}?key=${SERVICE_KEY_}`; | ||
return this.fetchCid_(dev().assertString(alt), false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assertString
is unnecessary.
* Add a class to interface with the new Google CID API endpoint for cache-served pages without a viewer. * fix lint errors * assorted fixes based on testing * added TODOs to indicate that this will merge with #14224. The CCT-embedded implementations are just for the interim. * unit test stuff * add unit tests for cache cid api * documentation fixes * fix broken partial change * fix secretly broken unit test and copied naming and introduce a bunch of lint errors * fix lint errors * move isScopeOptedIn into cid-impl rather than duplicating for cache and viewer APIs * fix unit tests * Re-add lost size cap bump. * address comments and fix unit tests * fix type errors and missing viewer.isProxyOrigin * Update size caps again.
@jridgewell agree with you. This new file can be merged into cid-api.js The way the code was organized:
|
Fixes #13118