From e540ddd03c39c75276db8d30ae51dc20e3e0b9ed Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Fri, 13 Nov 2020 14:35:14 -0500 Subject: [PATCH 1/2] fix(rc): Fix Version update time parsing failure --- src/remote-config/remote-config.ts | 12 ++++++------ test/unit/remote-config/remote-config.spec.ts | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index d8d194d26e..ba25f9c011 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -366,16 +366,12 @@ class VersionImpl implements Version { // as UTC date strings. If a developer uses a previously obtained template with UTC timestamps // we could still validate it below. if (typeof version.updateTime !== 'undefined') { - if (!validator.isISODateString(version.updateTime) && - !validator.isUTCDateString(version.updateTime)) { + if (!this.isValidTimestamp(version.updateTime)) { throw new FirebaseRemoteConfigError( 'invalid-argument', 'Version update time must be a valid date string'); } - if (validator.isISODateString(version.updateTime)) { - // timestamps in output `Version` obtained from the API should be in UTC. - this.updateTime = new Date(version.updateTime).toUTCString(); - } + this.updateTime = new Date(version.updateTime).toUTCString(); } } @@ -394,4 +390,8 @@ class VersionImpl implements Version { updateTime: this.updateTime, } } + + private isValidTimestamp(timestamp: string): boolean { + return validator.isNonEmptyString(timestamp) && (new Date(timestamp)).getTime() > 0; + } } diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index d884a515cf..996302aa9c 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -64,7 +64,7 @@ describe('RemoteConfig', () => { email: 'firebase-adminsdk@gserviceaccount.com' }, description: 'production version', - updateTime: '2020-06-15T16:45:03.000Z' + updateTime: '2020-06-15T16:45:03.541527Z' }; const REMOTE_CONFIG_RESPONSE: { @@ -123,7 +123,7 @@ describe('RemoteConfig', () => { versions: [ { versionNumber: '78', - updateTime: '2020-05-07T18:46:09.495Z', + updateTime: '2020-05-07T18:46:09.495234Z', updateUser: { email: 'user@gmail.com', imageUrl: 'https://photo.jpg' From e6e9e83c2d0ad5fb021916c6bfb863c47f7d52e7 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Fri, 13 Nov 2020 15:57:16 -0500 Subject: [PATCH 2/2] Add test cases for 3 and 6 ms places --- test/unit/remote-config/remote-config.spec.ts | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index 996302aa9c..462d46341e 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -680,5 +680,57 @@ describe('RemoteConfig', () => { expect(parsed).deep.equals(expectedTemplate); }); }); + + it('should resolve with template when Version updateTime contains only 3 ms places', () => { + const response = deepCopy(REMOTE_CONFIG_RESPONSE); + const versionInfo = deepCopy(VERSION_INFO); + versionInfo.updateTime = '2020-11-03T20:24:15.203Z'; + response.version = versionInfo; + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response); + stubs.push(stub); + + return rcOperation() + .then((template) => { + expect(template.etag).to.equal('etag-123456789012-5'); + + const version = template.version!; + expect(version.versionNumber).to.equal('86'); + expect(version.updateOrigin).to.equal('ADMIN_SDK_NODE'); + expect(version.updateType).to.equal('INCREMENTAL_UPDATE'); + expect(version.updateUser).to.deep.equal({ + email: 'firebase-adminsdk@gserviceaccount.com' + }); + expect(version.description).to.equal('production version'); + expect(version.updateTime).to.equal('Tue, 03 Nov 2020 20:24:15 GMT'); + }); + }); + + it('should resolve with template when Version updateTime contains 6 ms places', () => { + const response = deepCopy(REMOTE_CONFIG_RESPONSE); + const versionInfo = deepCopy(VERSION_INFO); + versionInfo.updateTime = '2020-11-13T17:01:36.541527Z'; + response.version = versionInfo; + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response); + stubs.push(stub); + + return rcOperation() + .then((template) => { + expect(template.etag).to.equal('etag-123456789012-5'); + + const version = template.version!; + expect(version.versionNumber).to.equal('86'); + expect(version.updateOrigin).to.equal('ADMIN_SDK_NODE'); + expect(version.updateType).to.equal('INCREMENTAL_UPDATE'); + expect(version.updateUser).to.deep.equal({ + email: 'firebase-adminsdk@gserviceaccount.com' + }); + expect(version.description).to.equal('production version'); + expect(version.updateTime).to.equal('Fri, 13 Nov 2020 17:01:36 GMT'); + }); + }); } });