From 8bfcaa90c63f2a6e6d19946b6905593f5c265677 Mon Sep 17 00:00:00 2001 From: Lennon Manchester Date: Tue, 19 May 2020 10:44:50 +0200 Subject: [PATCH 01/27] Fix Jenkins file to deply only on master --- Jenkinsfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 5e39456..b7d014d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -18,12 +18,20 @@ pipeline { } } stage('Build Production') { + when { + branch "master" + } + steps { sh "npm run clean" sh "npm run build:demo" } } stage('Deploy Production') { + when { + branch "master" + } + steps { sh "rsync -e 'ssh -o StrictHostKeyChecking=no' -va --rsync-path='mkdir -p /home/dashboard/web-sdk-demo/current/public/ && rsync' --delete ./demo/ dashboard@jenkins-2.adjust.com://home/dashboard/web-sdk-demo/current/public/" } From e6820eb05f420f20dbf40f4f3f8b14943293abcc Mon Sep 17 00:00:00 2001 From: Huiyan Date: Fri, 17 Jul 2020 13:57:42 +0200 Subject: [PATCH 02/27] Update README.md (#51) --- docs/korean/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/korean/README.md b/docs/korean/README.md index 534ec46..3e0764d 100644 --- a/docs/korean/README.md +++ b/docs/korean/README.md @@ -147,8 +147,8 @@ Track event 메서드에는 이 파라미터가 필요하므로 올바른 이벤 ```js Adjust.trackEvent({ // ... 필수 파라미터를 포함하는 다른 파라미터가 여기에 들어갑니다 - 매출: 110, - 통화: 'EUR' + revenue: 110, + currency: 'EUR' }) ``` From f09b437d64b0394fd58234a1e6e97fee570a26dc Mon Sep 17 00:00:00 2001 From: YaroslavnaMatkova Date: Mon, 27 Jul 2020 11:56:01 +0300 Subject: [PATCH 03/27] Tests fixes (#54) * Fixed array comparion * Lint issues fix * main-disabled.general test suite fixes * main suite fixes * Used return-promise approach for async tests --- jest.config.js | 4 ++ src/sdk/__tests__/_matchers.js | 13 ++++ src/sdk/__tests__/global-params.spec.js | 6 +- .../__tests__/main/main-disabled.gdpr.spec.js | 41 ++++++----- .../main/main-disabled.general.spec.js | 50 +++++++------- .../__tests__/main/main-enabled.gdpr.spec.js | 46 ++++++------- .../main/main-enabled.general.spec.js | 68 +++++++++---------- .../main/main-gdpr-disabled.gdpr.spec.js | 35 +++++----- .../main/main.storage-available.spec.js | 8 +-- src/sdk/__tests__/main/main.suite.js | 24 +++---- src/sdk/__tests__/storage/storage.suite.js | 8 +-- 11 files changed, 159 insertions(+), 144 deletions(-) create mode 100644 src/sdk/__tests__/_matchers.js diff --git a/jest.config.js b/jest.config.js index 9fbfa0b..30f9710 100644 --- a/jest.config.js +++ b/jest.config.js @@ -8,6 +8,7 @@ module.exports = { coveragePathIgnorePatterns: [ '/node_modules/', '/src/sdk/__tests__/_utils.js', + '/src/sdk/__tests__/_matchers.js', '/src/sdk/__tests__/main/main.suite.js', '/src/sdk/__tests__/storage/storage.suite.js' ], @@ -15,6 +16,9 @@ module.exports = { 'jest-localstorage-mock', '/src/sdk/__tests__/_utils.js' ], + setupFilesAfterEnv: [ + '/src/sdk/__tests__/_matchers.js' + ], globals: { __ADJUST__NAMESPACE: 'adjust-sdk', __ADJUST__SDK_VERSION: 'TEST' diff --git a/src/sdk/__tests__/_matchers.js b/src/sdk/__tests__/_matchers.js new file mode 100644 index 0000000..fb06b12 --- /dev/null +++ b/src/sdk/__tests__/_matchers.js @@ -0,0 +1,13 @@ +expect.extend({ + toEqualArrayIgnoringOrder (_received, _expected) { + const received = [..._received] + const expected = [..._expected] + const pass = this.equals(received.sort(), expected.sort()) && !this.not + + const message = pass + ? () => `Arrays expected to be not equal\n\tReceived: ${this.utils.printReceived(received)}` + : () => `Arrays are not equal\n\tExpected: ${this.utils.printExpected(expected)}\n\tReceived: ${this.utils.printReceived(received)}` + + return {message, pass} + }, +}) diff --git a/src/sdk/__tests__/global-params.spec.js b/src/sdk/__tests__/global-params.spec.js index 9165a86..de4fabd 100644 --- a/src/sdk/__tests__/global-params.spec.js +++ b/src/sdk/__tests__/global-params.spec.js @@ -80,7 +80,7 @@ describe('global parameters functionality', () => { {key: 'key1', value: 'last value1'} ], 'callback') .then(result => { - expect(result).toEqual([ + expect(result).toEqualArrayIgnoringOrder([ ['key1', 'callback'], ['key2', 'callback'] ]) @@ -250,7 +250,7 @@ describe('global parameters functionality', () => { .then(() => GlobalParams.add(partnerParams, 'partner')) .then(() => GlobalParams.removeAll('callback')) .then(result => { - expect(result).toEqual(callbackParams.map(p => [p.key, 'callback'])) + expect(result).toEqualArrayIgnoringOrder(callbackParams.map(p => [p.key, 'callback'])) return GlobalParams.get() }) .then(({callbackParams, partnerParams}) => { @@ -263,7 +263,7 @@ describe('global parameters functionality', () => { return GlobalParams.removeAll('partner') }) .then(result => { - expect(result).toEqual(partnerParams.map(p => [p.key, 'partner'])) + expect(result).toEqualArrayIgnoringOrder(partnerParams.map(p => [p.key, 'partner'])) return GlobalParams.get() }) .then(({callbackParams, partnerParams}) => { diff --git a/src/sdk/__tests__/main/main-disabled.gdpr.spec.js b/src/sdk/__tests__/main/main-disabled.gdpr.spec.js index 6272e4f..a08bc27 100644 --- a/src/sdk/__tests__/main/main-disabled.gdpr.spec.js +++ b/src/sdk/__tests__/main/main-disabled.gdpr.spec.js @@ -100,27 +100,26 @@ describe('main entry point - test GDPR-Forget-Me when in initially disabled stat it('flush forget-me event but ignores it', () => { const a1 = suite.expectNotGdprForgetMeCallback() - const a2 = suite.expectNotClearAndDestroy() + const a2 = suite.expectNotClearAndDestroy_Async() - expect.assertions(a1.assertions + a2.assertions) - - return a2.promise + return a2.promise.then(() => { + expect.assertions(a1.assertions + a2.assertions) + }) }) it('enables sdk with restart', () => { AdjustInstance.restart() - const a = suite.expectStart() - - expect.assertions(3 + a.assertions) - expect(Logger.default.log).toHaveBeenCalledTimes(1) expect(Logger.default.log).toHaveBeenCalledWith('Adjust SDK has been enabled') expect(Disable.restore).toHaveBeenCalled() - return a.promise + const a = suite.expectStart_Async() + return a.promise.then(() => { + expect.assertions(3 + a.assertions) + }) }) }) @@ -138,11 +137,11 @@ describe('main entry point - test GDPR-Forget-Me when in initially disabled stat Logger.default.log.mockClear() const a1 = suite.expectNotGdprForgetMeCallback() - const a2 = suite.expectNotClearAndDestroy() + const a2 = suite.expectNotClearAndDestroy_Async() - expect.assertions(1 + a1.assertions + a2.assertions) - - return a2.promise + return a2.promise.then(() => { + expect.assertions(1 + a1.assertions + a2.assertions) + }) }) it('prevents running all static methods and track event', () => { @@ -186,11 +185,11 @@ describe('main entry point - test GDPR-Forget-Me when in initially disabled stat it('flush forget-me event but ignores it', () => { const a1 = suite.expectNotGdprForgetMeCallback() - const a2 = suite.expectNotClearAndDestroy() - - expect.assertions(a1.assertions + a2.assertions) + const a2 = suite.expectNotClearAndDestroy_Async() - return a2.promise + return a2.promise.then(() => { + expect.assertions(a1.assertions + a2.assertions) + }) }) }) @@ -204,11 +203,11 @@ describe('main entry point - test GDPR-Forget-Me when in initially disabled stat it('flush forget-me event but ignores it', () => { const a1 = suite.expectNotGdprForgetMeCallback() - const a2 = suite.expectNotClearAndDestroy() - - expect.assertions(a1.assertions + a2.assertions) + const a2 = suite.expectNotClearAndDestroy_Async() - return a2.promise + return a2.promise.then(() => { + expect.assertions(a1.assertions + a2.assertions) + }) }) it('initiates but prevents all static methods and track event and fails to run forget-me request', () => { diff --git a/src/sdk/__tests__/main/main-disabled.general.spec.js b/src/sdk/__tests__/main/main-disabled.general.spec.js index 8908954..5b337de 100644 --- a/src/sdk/__tests__/main/main-disabled.general.spec.js +++ b/src/sdk/__tests__/main/main-disabled.general.spec.js @@ -99,15 +99,15 @@ describe('main entry point - test disable/enable when in initially disabled stat AdjustInstance.restart() - const a = suite.expectStart() - - expect.assertions(3 + a.assertions) - expect(Logger.default.log).toHaveBeenCalledTimes(1) expect(Logger.default.log).toHaveBeenCalledWith('Adjust SDK has been enabled') expect(Disable.restore).toHaveBeenCalled() - return a.promise + const a = suite.expectStart_Async() + + return a.promise.then(()=>{ + expect.assertions(3 + a.assertions) + }) }) }) @@ -136,12 +136,12 @@ describe('main entry point - test disable/enable when in initially disabled stat expect(Disable.restore).toHaveBeenCalled() const a1 = suite.expectRunningStatic() - const a2 = suite.expectDelayedTrackEvent() - const a3 = suite.expectStart() + const a2 = suite.expectDelayedTrackEvent_Async() + const a3 = suite.expectStart_Async() - expect.assertions(3 + a1.assertions + a2.assertions + a3.assertions) - - return a2.promise + return Promise.all([a2.promise, a3.promise]).then(()=>{ + expect.assertions(3 + a1.assertions + a2.assertions + a3.assertions) + }) }) it('fails to enable already enabled sdk', () => { @@ -242,15 +242,15 @@ describe('main entry point - test disable/enable when in initially disabled stat AdjustInstance.restart() - const a = suite.expectStart() - - expect.assertions(3 + a.assertions) - expect(Logger.default.log).toHaveBeenCalledTimes(1) expect(Logger.default.log).toHaveBeenCalledWith('Adjust SDK has been enabled') expect(Disable.restore).toHaveBeenCalled() - return a.promise + const a = suite.expectStart_Async() + + return a.promise.then(()=>{ + expect.assertions(3 + a.assertions) + }) }) }) @@ -283,12 +283,12 @@ describe('main entry point - test disable/enable when in initially disabled stat AdjustInstance.initSdk(suite.config) const a1 = suite.expectRunningStatic() - const a2 = suite.expectDelayedTrackEvent() - const a3 = suite.expectStart() + const a2 = suite.expectDelayedTrackEvent_Async() + const a3 = suite.expectStart_Async() - expect.assertions(a1.assertions + a2.assertions + a3.assertions) - - return a2.promise + return Promise.all([a2.promise, a3.promise]).then(()=>{ + expect.assertions(a1.assertions + a2.assertions + a3.assertions) + }) }) it('fails to enable already enabled sdk', () => { @@ -367,12 +367,12 @@ describe('main entry point - test disable/enable when in initially disabled stat AdjustInstance.initSdk(suite.config) const a1 = suite.expectRunningStatic() - const a2 = suite.expectDelayedTrackEvent() - const a3 = suite.expectStart() - - expect.assertions(a1.assertions + a2.assertions + a3.assertions) + const a2 = suite.expectDelayedTrackEvent_Async() + const a3 = suite.expectStart_Async() - return a2.promise + return Promise.all([a2.promise, a3.promise]).then(()=>{ + expect.assertions(a1.assertions + a2.assertions + a3.assertions) + }) }) }) diff --git a/src/sdk/__tests__/main/main-enabled.gdpr.spec.js b/src/sdk/__tests__/main/main-enabled.gdpr.spec.js index e9f53c8..16ef2b6 100644 --- a/src/sdk/__tests__/main/main-enabled.gdpr.spec.js +++ b/src/sdk/__tests__/main/main-enabled.gdpr.spec.js @@ -83,12 +83,12 @@ describe('main entry point - test GDPR-Forget-Me when in initially enabled state AdjustInstance.initSdk(suite.config) const a1 = suite.expectRunningStatic() - const a2 = suite.expectDelayedTrackEvent() - const a3 = suite.expectStart() + const a2 = suite.expectDelayedTrackEvent_Async() + const a3 = suite.expectStart_Async() - expect.assertions(a1.assertions + a2.assertions + a3.assertions) - - return a2.promise + return Promise.all([a2.promise, a3.promise]).then(()=>{ + expect.assertions(a1.assertions + a2.assertions + a3.assertions) + }) }) it('runs forget-me request and flush', () => { @@ -98,14 +98,14 @@ describe('main entry point - test GDPR-Forget-Me when in initially enabled state const a1 = suite.expectPartialShutDown() const a2 = suite.expectGdprRequest() const a3 = suite.expectGdprForgetMeCallback(true) - const a4 = suite.expectClearAndDestroy(true) + const a4 = suite.expectClearAndDestroy_Async(true) expect.assertions(a1.assertions + a2.assertions + a3.assertions + a4.assertions) return Utils.flushPromises() .then(() => { suite.expectGdprForgetMeCallback() - return suite.expectClearAndDestroy().promise + return suite.expectClearAndDestroy_Async().promise }) }) @@ -140,11 +140,11 @@ describe('main entry point - test GDPR-Forget-Me when in initially enabled state it('flush forget-me event but ignores it', () => { const a1 = suite.expectNotGdprForgetMeCallback() - const a2 = suite.expectNotClearAndDestroy() + const a2 = suite.expectNotClearAndDestroy_Async() - expect.assertions(a1.assertions + a2.assertions) - - return a2.promise + return a2.promise.then(() => { + expect.assertions(a1.assertions + a2.assertions) + }) }) it('runs forget-me request and flush', () => { @@ -153,14 +153,14 @@ describe('main entry point - test GDPR-Forget-Me when in initially enabled state const a1 = suite.expectPartialShutDown() const a2 = suite.expectGdprRequest() const a3 = suite.expectGdprForgetMeCallback(true) - const a4 = suite.expectClearAndDestroy(true) + const a4 = suite.expectClearAndDestroy_Async(true) expect.assertions(a1.assertions + a2.assertions + a3.assertions + a4.assertions) return Utils.flushPromises() .then(() => { suite.expectGdprForgetMeCallback() - return suite.expectClearAndDestroy().promise + return suite.expectClearAndDestroy_Async().promise }) }) }) @@ -186,22 +186,22 @@ describe('main entry point - test GDPR-Forget-Me when in initially enabled state AdjustInstance.initSdk(suite.config) - const a1 = suite.expectPartialStartWithGdprRequest() + const a1 = suite.expectPartialStartWithGdprRequest_Async() const a2 = suite.expectNotRunningStatic() const a3 = suite.expectNotRunningTrackEvent() - expect.assertions(a1.assertions + a2.assertions + a3.assertions) - - return a1.promise + return a1.promise.then(() => { + expect.assertions(a1.assertions + a2.assertions + a3.assertions) + }) }) it('flush forget-me event does clear and instance destroy', () => { const a1 = suite.expectGdprForgetMeCallback(false, true) - const a2 = suite.expectClearAndDestroy() + const a2 = suite.expectClearAndDestroy_Async() - expect.assertions(a1.assertions + a2.assertions) - - return a2.promise + return a2.promise.then(() => { + expect.assertions(a1.assertions + a2.assertions) + }) }) }) @@ -218,7 +218,7 @@ describe('main entry point - test GDPR-Forget-Me when in initially enabled state it('flush forget-me event but ignores it', () => { const a1 = suite.expectNotGdprForgetMeCallback() - const a2 = suite.expectNotClearAndDestroy() + const a2 = suite.expectNotClearAndDestroy_Async() expect.assertions(a1.assertions + a2.assertions) @@ -229,7 +229,7 @@ describe('main entry point - test GDPR-Forget-Me when in initially enabled state AdjustInstance.initSdk(suite.config) - const a1 = suite.expectPartialStartWithGdprRequest() + const a1 = suite.expectPartialStartWithGdprRequest_Async() const a2 = suite.expectNotRunningStatic() const a3 = suite.expectNotRunningTrackEvent() diff --git a/src/sdk/__tests__/main/main-enabled.general.spec.js b/src/sdk/__tests__/main/main-enabled.general.spec.js index 2aac4f4..0c704e0 100644 --- a/src/sdk/__tests__/main/main-enabled.general.spec.js +++ b/src/sdk/__tests__/main/main-enabled.general.spec.js @@ -77,12 +77,12 @@ describe('main entry point - test enable/disable when in initially enabled state AdjustInstance.initSdk(suite.config) const a1 = suite.expectRunningStatic() - const a2 = suite.expectDelayedTrackEvent() - const a3 = suite.expectStart() + const a2 = suite.expectDelayedTrackEvent_Async() + const a3 = suite.expectStart_Async() - expect.assertions(a1.assertions + a2.assertions + a3.assertions) - - return a2.promise + return Promise.all([a2.promise, a3.promise]).then(()=>{ + expect.assertions(a1.assertions + a2.assertions + a3.assertions) + }) }) it('disables sdk with shutdown', () => { @@ -113,15 +113,15 @@ describe('main entry point - test enable/disable when in initially enabled state AdjustInstance.restart() - const a = suite.expectStart() - - expect.assertions(3 + a.assertions) - expect(Logger.default.log).toHaveBeenCalledTimes(1) expect(Logger.default.log).toHaveBeenCalledWith('Adjust SDK has been enabled') expect(Disable.restore).toHaveBeenCalled() - return a.promise + const a = suite.expectStart_Async() + + return a.promise.then(() => { + expect.assertions(3 + a.assertions) + }) }) }) @@ -149,11 +149,11 @@ describe('main entry point - test enable/disable when in initially enabled state }) it('ensures that everything is up', () => { - const a = suite.expectAllUp() - - expect.assertions(a.assertions) + const a = suite.expectAllUp_Async() - return a.promise + return a.promise.then(() => { + expect.assertions(a.assertions) + }) }) }) @@ -167,12 +167,12 @@ describe('main entry point - test enable/disable when in initially enabled state AdjustInstance.initSdk(suite.config) const a1 = suite.expectRunningStatic() - const a2 = suite.expectDelayedTrackEvent() - const a3 = suite.expectStart() - - expect.assertions(a1.assertions + a2.assertions + a3.assertions) + const a2 = suite.expectDelayedTrackEvent_Async() + const a3 = suite.expectStart_Async() - return a2.promise + return Promise.all([a2.promise, a3.promise]).then(()=>{ + expect.assertions(a1.assertions + a2.assertions + a3.assertions) + }) }) it('fails to enable already enabled sdk', () => { @@ -245,15 +245,15 @@ describe('main entry point - test enable/disable when in initially enabled state AdjustInstance.restart() - const a = suite.expectStart() - - expect.assertions(3 + a.assertions) - expect(Logger.default.log).toHaveBeenCalledTimes(1) expect(Logger.default.log).toHaveBeenCalledWith('Adjust SDK has been enabled') expect(Disable.restore).toHaveBeenCalled() - return a.promise + const a = suite.expectStart_Async() + + return a.promise.then(() => { + expect.assertions(3 + a.assertions) + }) }) }) @@ -285,12 +285,12 @@ describe('main entry point - test enable/disable when in initially enabled state AdjustInstance.initSdk(suite.config) const a1 = suite.expectRunningStatic() - const a2 = suite.expectDelayedTrackEvent() - const a3 = suite.expectStart() + const a2 = suite.expectDelayedTrackEvent_Async() + const a3 = suite.expectStart_Async() - expect.assertions(a1.assertions + a2.assertions + a3.assertions) - - return a2.promise + return Promise.all([a2.promise, a3.promise]).then(()=>{ + expect.assertions(a1.assertions + a2.assertions + a3.assertions) + }) }) it('fails again to enable already enabled sdk', () => { @@ -368,12 +368,12 @@ describe('main entry point - test enable/disable when in initially enabled state AdjustInstance.initSdk(suite.config) const a1 = suite.expectRunningStatic() - const a2 = suite.expectDelayedTrackEvent() - const a3 = suite.expectStart() - - expect.assertions(a1.assertions + a2.assertions + a3.assertions) + const a2 = suite.expectDelayedTrackEvent_Async() + const a3 = suite.expectStart_Async() - return a2.promise + return Promise.all([a2.promise, a3.promise]).then(()=>{ + expect.assertions(a1.assertions + a2.assertions + a3.assertions) + }) }) }) diff --git a/src/sdk/__tests__/main/main-gdpr-disabled.gdpr.spec.js b/src/sdk/__tests__/main/main-gdpr-disabled.gdpr.spec.js index 6efce6d..2886b27 100644 --- a/src/sdk/__tests__/main/main-gdpr-disabled.gdpr.spec.js +++ b/src/sdk/__tests__/main/main-gdpr-disabled.gdpr.spec.js @@ -99,11 +99,11 @@ describe('main entry point - test GDPR-Forget-Me when in initially GDPR disabled it('flush forget-me event but ignores it', () => { const a1 = suite.expectNotGdprForgetMeCallback() - const a2 = suite.expectNotClearAndDestroy() + const a2 = suite.expectNotClearAndDestroy_Async() - expect.assertions(a1.assertions + a2.assertions) - - return a2.promise + return a2.promise.then(() => { + expect.assertions(a1.assertions + a2.assertions) + }) }) it('fails to enable sdk', () => { @@ -126,14 +126,14 @@ describe('main entry point - test GDPR-Forget-Me when in initially GDPR disabled expect(Logger.default.log).toHaveBeenLastCalledWith('Adjust SDK is disabled, can not start the sdk') - Logger.default.log.mockClear() + // Logger.default.log.mockClear() const a1 = suite.expectNotGdprForgetMeCallback() - const a2 = suite.expectNotClearAndDestroy() - - expect.assertions(1 + a1.assertions + a2.assertions) + const a2 = suite.expectNotClearAndDestroy_Async() - return a2.promise + return a2.promise.then(() => { + expect.assertions(1 + a1.assertions + a2.assertions) + }) }) it('prevents running all static methods and track event', () => { @@ -177,11 +177,11 @@ describe('main entry point - test GDPR-Forget-Me when in initially GDPR disabled it('flush forget-me event but ignores it', () => { const a1 = suite.expectNotGdprForgetMeCallback() - const a2 = suite.expectNotClearAndDestroy() - - expect.assertions(a1.assertions + a2.assertions) + const a2 = suite.expectNotClearAndDestroy_Async() - return a2.promise + return a2.promise.then(() => { + expect.assertions(a1.assertions + a2.assertions) + }) }) }) @@ -195,11 +195,11 @@ describe('main entry point - test GDPR-Forget-Me when in initially GDPR disabled it('flush forget-me event but ignores it', () => { const a1 = suite.expectNotGdprForgetMeCallback() - const a2 = suite.expectNotClearAndDestroy() + const a2 = suite.expectNotClearAndDestroy_Async() - expect.assertions(a1.assertions + a2.assertions) - - return a2.promise + return a2.promise.then(() => { + expect.assertions(a1.assertions + a2.assertions) + }) }) it('initiates but prevents all static methods and track event and fails to run forget-me request', () => { @@ -219,5 +219,4 @@ describe('main entry point - test GDPR-Forget-Me when in initially GDPR disabled }) }) - }) diff --git a/src/sdk/__tests__/main/main.storage-available.spec.js b/src/sdk/__tests__/main/main.storage-available.spec.js index 9fa1dcc..14f7cc6 100644 --- a/src/sdk/__tests__/main/main.storage-available.spec.js +++ b/src/sdk/__tests__/main/main.storage-available.spec.js @@ -419,11 +419,11 @@ describe('main entry point - test instance initiation when storage is available' it('sets basic configuration', () => { - const a = suite.expectStart() + const a = suite.expectStart_Async() - expect.assertions(a.assertions) - - return a.promise + return a.promise.then(() => { + expect.assertions(a.assertions) + }) }) it('calls client-defined attribution callback when attribution is changed', () => { diff --git a/src/sdk/__tests__/main/main.suite.js b/src/sdk/__tests__/main/main.suite.js index fb74215..2b25636 100644 --- a/src/sdk/__tests__/main/main.suite.js +++ b/src/sdk/__tests__/main/main.suite.js @@ -49,7 +49,7 @@ function _startFirstPart () { return Utils.flushPromises() } -function expectStart () { +function expectStart_Async () { const promise = _startFirstPart() .then(() => { expect(GdprForgetDevice.check).toHaveBeenCalledTimes(1) @@ -63,7 +63,7 @@ function expectStart () { return {assertions: 16, promise} } -function expectPartialStartWithGdprRequest () { +function expectPartialStartWithGdprRequest_Async () { const promise = _startFirstPart() .then(() => { expect(GdprForgetDevice.check).toHaveBeenCalledTimes(1) @@ -95,7 +95,7 @@ function expectNotStart (restart) { } -function expectDelayedTrackEvent () { +function expectDelayedTrackEvent_Async () { _instance.trackEvent({eventToken: 'bla123'}) @@ -344,7 +344,7 @@ function _expectNotDestroy () { expect(Logger.default.log).not.toHaveBeenCalledWith('Adjust SDK instance has been destroyed') } -function expectClearAndDestroy (onlyNumOfAssertions) { +function expectClearAndDestroy_Async (onlyNumOfAssertions) { const assertions = 14 if (onlyNumOfAssertions) { @@ -360,7 +360,7 @@ function expectClearAndDestroy (onlyNumOfAssertions) { return {assertions, promise} } -function expectNotClearAndDestroy () { +function expectNotClearAndDestroy_Async () { expect(Identity.clear).not.toHaveBeenCalled() expect(GlobalParams.clear).not.toHaveBeenCalled() expect(Queue.clear).not.toHaveBeenCalled() @@ -403,7 +403,7 @@ function expectNotGdprForgetMeCallback () { return {assertions: 1} } -function expectAllUp () { +function expectAllUp_Async () { const baseParams = Config.default.getBaseParams() expect(baseParams.appToken).toEqual('some-app-token') @@ -494,10 +494,10 @@ export default function Suite (instance) { return { config, - expectStart, - expectPartialStartWithGdprRequest, + expectStart_Async, + expectPartialStartWithGdprRequest_Async, expectNotStart, - expectDelayedTrackEvent, + expectDelayedTrackEvent_Async, expectRunningTrackEvent, expectNotRunningTrackEvent, expectNotRunningTrackEventWhenNoInstance, @@ -510,11 +510,11 @@ export default function Suite (instance) { expectShutDown, expectPartialShutDown, expectNotShutDown, - expectClearAndDestroy, - expectNotClearAndDestroy, + expectClearAndDestroy_Async, + expectNotClearAndDestroy_Async, expectGdprForgetMeCallback, expectNotGdprForgetMeCallback, - expectAllUp, + expectAllUp_Async, expectAllDown, expectGdprRequest, expectNotGdprRequest, diff --git a/src/sdk/__tests__/storage/storage.suite.js b/src/sdk/__tests__/storage/storage.suite.js index 7eb62ff..c80fa41 100644 --- a/src/sdk/__tests__/storage/storage.suite.js +++ b/src/sdk/__tests__/storage/storage.suite.js @@ -588,7 +588,7 @@ export default function Suite (Storage) { return Storage.deleteBulk('globalParams', 'partner') }) .then(deleted => { - expect(deleted).toEqual([ + expect(deleted).toEqualArrayIgnoringOrder([ ['key1', 'partner'], ['key2', 'partner'] ]) @@ -606,7 +606,7 @@ export default function Suite (Storage) { return Storage.deleteBulk('globalParams', 'callback') }) .then(deleted => { - expect(deleted).toEqual([ + expect(deleted).toEqualArrayIgnoringOrder([ ['key1', 'callback'], ['key2', 'callback'], ['key3', 'callback'], @@ -817,7 +817,7 @@ export default function Suite (Storage) { return Storage.addBulk('globalParams', globalParamsSet1) .then(result => { - expect(result).toEqual([ + expect(result).toEqualArrayIgnoringOrder([ ['bla', 'callback'], ['key1', 'callback'], ['eto', 'partner'] @@ -874,7 +874,7 @@ export default function Suite (Storage) { return Storage.addBulk('globalParams', globalParamsSet2, true) }) .then(result => { - expect(result).toEqual([ + expect(result).toEqualArrayIgnoringOrder([ ['key1', 'callback'], ['par', 'partner'], ['bla', 'partner'], From 60f09492484667b01f41a7e7f7313b18e1843973 Mon Sep 17 00:00:00 2001 From: Milica Kadic Date: Mon, 27 Jul 2020 11:22:16 +0200 Subject: [PATCH 04/27] Flow types finishing (#50) * cover logger with types * remove circular dep by using separate global constants module * cover pub-sub module with types * cover time module with types --- src/sdk/__tests__/config.spec.js | 30 -- src/sdk/__tests__/gdpr-forget-device.spec.js | 2 +- src/sdk/__tests__/globals.spec.js | 27 ++ src/sdk/__tests__/http.spec.js | 6 +- src/sdk/__tests__/logger.spec.js | 377 ++++++++++--------- src/sdk/__tests__/main/main.suite.js | 4 +- src/sdk/__tests__/preferences.spec.js | 2 +- src/sdk/config.js | 8 +- src/sdk/gdpr-forget-device.js | 2 +- src/sdk/globals.js | 16 + src/sdk/http.js | 7 +- src/sdk/logger.js | 79 ++-- src/sdk/preferences.js | 2 +- src/sdk/pub-sub.js | 41 +- src/sdk/session.js | 4 +- src/sdk/storage/indexeddb.js | 4 +- src/sdk/storage/quick-storage.js | 4 +- src/sdk/time.js | 14 +- 18 files changed, 327 insertions(+), 302 deletions(-) create mode 100644 src/sdk/__tests__/globals.spec.js create mode 100644 src/sdk/globals.js diff --git a/src/sdk/__tests__/config.spec.js b/src/sdk/__tests__/config.spec.js index 9e7c28f..141fc33 100644 --- a/src/sdk/__tests__/config.spec.js +++ b/src/sdk/__tests__/config.spec.js @@ -159,34 +159,4 @@ describe('test global config', () => { }) }) - describe('global constants not available', () => { - const oldNamespace = global.__ADJUST__NAMESPACE - const oldSdkVersion = global.__ADJUST__SDK_VERSION - - global.__ADJUST__NAMESPACE = undefined - global.__ADJUST__SDK_VERSION = undefined - - afterAll(() => { - global.__ADJUST__NAMESPACE = oldNamespace - global.__ADJUST__SDK_VERSION = oldSdkVersion - }) - - jest.isolateModules(() => { - const Config = require('../config') - - it('falls back to default values', () => { - - const appOptions = { - appToken: '123abc', - environment: 'sandbox' - } - - Config.default.set(appOptions) - - expect(Config.default.namespace).toEqual('adjust-sdk') - expect(Config.default.version).toEqual('0.0.0') - }) - }) - }) - }) diff --git a/src/sdk/__tests__/gdpr-forget-device.spec.js b/src/sdk/__tests__/gdpr-forget-device.spec.js index 49a3ec4..f500040 100644 --- a/src/sdk/__tests__/gdpr-forget-device.spec.js +++ b/src/sdk/__tests__/gdpr-forget-device.spec.js @@ -104,7 +104,7 @@ describe('GDPR forget device functionality', () => { return Utils.flushPromises() .then(() => { - expect(PubSub.publish).toHaveBeenCalledWith('sdk:gdpr-forget-me', true) + expect(PubSub.publish).toHaveBeenCalledWith('sdk:gdpr-forget-me') }) }) diff --git a/src/sdk/__tests__/globals.spec.js b/src/sdk/__tests__/globals.spec.js new file mode 100644 index 0000000..078c41b --- /dev/null +++ b/src/sdk/__tests__/globals.spec.js @@ -0,0 +1,27 @@ +describe('test global constants', () => { + describe('test default values', () => { + jest.isolateModules(() => { + global.__ADJUST__NAMESPACE = undefined + global.__ADJUST__SDK_VERSION = undefined + const Globals = require('../globals') + + it('falls back to default values', () => { + expect(Globals.default.namespace).toEqual('adjust-sdk') + expect(Globals.default.version).toEqual('5.0.0') + }) + }) + }) + + describe('test globally set values', () => { + jest.isolateModules(() => { + global.__ADJUST__NAMESPACE = 'adjust-web-sdk' + global.__ADJUST__SDK_VERSION = '6.0.0' + const Globals = require('../globals') + + it('sets global values', () => { + expect(Globals.default.namespace).toEqual('adjust-web-sdk') + expect(Globals.default.version).toEqual('6.0.0') + }) + }) + }) +}) diff --git a/src/sdk/__tests__/http.spec.js b/src/sdk/__tests__/http.spec.js index bf7733c..d356ca6 100644 --- a/src/sdk/__tests__/http.spec.js +++ b/src/sdk/__tests__/http.spec.js @@ -572,7 +572,7 @@ describe('perform api requests', () => { }) expect(PubSub.publish).not.toHaveBeenCalledWith('attribution:check', result) expect(PubSub.publish).not.toHaveBeenCalledWith('session:finished', result) - expect(PubSub.publish).toHaveBeenCalledWith('sdk:gdpr-forget-me', true) + expect(PubSub.publish).toHaveBeenCalledWith('sdk:gdpr-forget-me') }) return Utils.flushPromises() @@ -713,7 +713,7 @@ describe('perform api requests', () => { }) expect(PubSub.publish).not.toHaveBeenCalledWith('attribution:check', result) expect(PubSub.publish).not.toHaveBeenCalledWith('session:finished', result) - expect(PubSub.publish).toHaveBeenCalledWith('sdk:gdpr-forget-me', true) + expect(PubSub.publish).toHaveBeenCalledWith('sdk:gdpr-forget-me') }) return Utils.flushPromises() @@ -760,7 +760,7 @@ describe('perform api requests', () => { expect(result).toEqual({ status: 'success' }) - expect(PubSub.publish).toHaveBeenCalledWith('sdk:third-party-sharing-opt-out', true) + expect(PubSub.publish).toHaveBeenCalledWith('sdk:third-party-sharing-opt-out') }) return Utils.flushPromises() diff --git a/src/sdk/__tests__/logger.spec.js b/src/sdk/__tests__/logger.spec.js index 2f2237e..ff10e2d 100644 --- a/src/sdk/__tests__/logger.spec.js +++ b/src/sdk/__tests__/logger.spec.js @@ -1,10 +1,7 @@ /* eslint-disable */ -import * as Logger from '../logger' - const _origDate = global.Date describe('test Logger functionality', () => { - const today = '2019-10-14T00:00:00.000Z' beforeAll(() => { @@ -20,295 +17,303 @@ describe('test Logger functionality', () => { }) afterAll(() => { - global.process.env.NODE_ENV = 'test' global.Date = _origDate - Logger.default.setLogLevel() }) - it('prints info/error message when changing log level', () => { + describe('default behaviour', () => { + jest.isolateModules(() => { + const Logger = require('../logger') - Logger.default.setLogLevel() - expect(console.info).toHaveBeenLastCalledWith('[adjust-sdk]', today, 'INFO:', 'Log level set to verbose') + it('prints info/error message when changing log level', () => { - Logger.default.setLogLevel('error') - expect(console.info).toHaveBeenLastCalledWith('[adjust-sdk]', today, 'INFO:', 'Log level set to error') + Logger.default.setLogLevel() + expect(console.info).toHaveBeenLastCalledWith('[adjust-sdk]', today, 'INFO: ', 'Log level set to verbose') - Logger.default.setLogLevel('not-existing-level') - expect(console.error).toHaveBeenLastCalledWith('[adjust-sdk]', today, 'ERROR:', 'You must set one of the available log levels: verbose, info, error or none') + Logger.default.setLogLevel('error') + expect(console.info).toHaveBeenLastCalledWith('[adjust-sdk]', today, 'INFO: ', 'Log level set to error') - Logger.default.setLogLevel() - }) + Logger.default.setLogLevel('not-existing-level') + expect(console.error).toHaveBeenLastCalledWith('[adjust-sdk]', today, 'ERROR:', 'You must set one of the available log levels: verbose, info, error or none') - it('prints multiple messages passed to each method', () => { + Logger.default.setLogLevel() + }) - Logger.default.log('Some', 'message') - expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG:', 'Some', 'message') + it('prints multiple messages passed to each method', () => { - Logger.default.info('Some', 'info') - expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO:', 'Some', 'info') + Logger.default.log('Some', 'message') + expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG: ', 'Some', 'message') - Logger.default.error('Some', 'error', 'message') - expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some', 'error', 'message') + Logger.default.info('Some', 'info') + expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some', 'info') + Logger.default.error('Some', 'error', 'message') + expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some', 'error', 'message') + + }) + }) }) describe('verbose log level by default in test environment', () => { + jest.isolateModules(() => { + const Logger = require('../logger') - it('prints verbose messages', () => { - Logger.default.log('Some message with looooong explanation') - expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG:', 'Some message with looooong explanation') + it('prints verbose messages', () => { + Logger.default.log('Some message with looooong explanation') + expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG: ', 'Some message with looooong explanation') - }) + }) - it('prints info messages', () => { - Logger.default.info('Some message') - expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO:', 'Some message') - }) + it('prints info messages', () => { + Logger.default.info('Some message') + expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some message') + }) - it('prints error messages', () => { - Logger.default.error('Some error message') - expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + it('prints error messages', () => { + Logger.default.error('Some error message') + expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + }) }) - }) describe('verbose log level by default in development environment', () => { - - beforeAll(() => { + jest.isolateModules(() => { global.process.env.NODE_ENV = 'development' - Logger.default.setLogLevel() - }) + const Logger = require('../logger') - afterAll(() => { - global.process.env.NODE_ENV = 'test' - }) + beforeAll(() => { + Logger.default.setLogLevel() + }) - it('prints verbose messages', () => { - Logger.default.log('Some message with looooong explanation') - expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG:', 'Some message with looooong explanation') + it('prints verbose messages', () => { + Logger.default.log('Some message with looooong explanation') + expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG: ', 'Some message with looooong explanation') - }) + }) - it('prints info messages', () => { - Logger.default.info('Some message') - expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO:', 'Some message') - }) + it('prints info messages', () => { + Logger.default.info('Some message') + expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some message') + }) - it('prints error messages', () => { - Logger.default.error('Some error message') - expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + it('prints error messages', () => { + Logger.default.error('Some error message') + expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + }) }) - }) describe('error log level by default in production environment', () => { - - beforeAll(() => { + jest.isolateModules(() => { global.process.env.NODE_ENV = 'production' - Logger.default.setLogLevel() - }) + const Logger = require('../logger') - afterAll(() => { - global.process.env.NODE_ENV = 'test' - }) + beforeAll(() => { + Logger.default.setLogLevel() + }) - it('does not print verbose messages', () => { - Logger.default.log('Some message with looooong explanation') - expect(console.log).not.toHaveBeenCalled() + it('does not print verbose messages', () => { + Logger.default.log('Some message with looooong explanation') + expect(console.log).not.toHaveBeenCalled() - }) + }) - it('does not print info messages', () => { - Logger.default.info('Some message') - expect(console.info).not.toHaveBeenCalled() - }) + it('does not print info messages', () => { + Logger.default.info('Some message') + expect(console.info).not.toHaveBeenCalled() + }) - it('prints error messages', () => { - Logger.default.error('Some error message') - expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + it('prints error messages', () => { + Logger.default.error('Some error message') + expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + }) }) - }) describe('error log level by default in unknown environment', () => { + jest.isolateModules(() => { + const Logger = require('../logger') - beforeAll(() => { - global.process.env.NODE_ENV = 'unknown-env' - Logger.default.setLogLevel() - }) - - afterAll(() => { - global.process.env.NODE_ENV = 'test' - }) + beforeAll(() => { + Logger.default.setLogLevel() + }) - it('does not print verbose messages', () => { - Logger.default.log('Some message with looooong explanation') - expect(console.log).not.toHaveBeenCalled() + it('does not print verbose messages', () => { + Logger.default.log('Some message with looooong explanation') + expect(console.log).not.toHaveBeenCalled() - }) + }) - it('does not print info messages', () => { - Logger.default.info('Some message') - expect(console.info).not.toHaveBeenCalled() - }) + it('does not print info messages', () => { + Logger.default.info('Some message') + expect(console.info).not.toHaveBeenCalled() + }) - it('prints error messages', () => { - Logger.default.error('Some error message') - expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + it('prints error messages', () => { + Logger.default.error('Some error message') + expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + }) }) - }) describe('explicit verbose log level', () => { + jest.isolateModules(() => { + const Logger = require('../logger') - beforeAll(() => { - Logger.default.setLogLevel('verbose') - }) + beforeAll(() => { + Logger.default.setLogLevel('verbose') + }) - it('prints verbose messages', () => { - Logger.default.log('Some message with looooong explanation') - expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG:', 'Some message with looooong explanation') + it('prints verbose messages', () => { + Logger.default.log('Some message with looooong explanation') + expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG: ', 'Some message with looooong explanation') - }) + }) - it('prints info messages', () => { - Logger.default.info('Some message') - expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO:', 'Some message') - }) + it('prints info messages', () => { + Logger.default.info('Some message') + expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some message') + }) - it('prints error messages', () => { - Logger.default.error('Some error message') - expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + it('prints error messages', () => { + Logger.default.error('Some error message') + expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + }) }) - }) describe('explicit info log level', () => { + jest.isolateModules(() => { + const Logger = require('../logger') - beforeAll(() => { - Logger.default.setLogLevel('info') - }) + beforeAll(() => { + Logger.default.setLogLevel('info') + }) - it('does not print verbose messages', () => { - Logger.default.log('Some message with looooong explanation') - expect(console.log).not.toHaveBeenCalled() + it('does not print verbose messages', () => { + Logger.default.log('Some message with looooong explanation') + expect(console.log).not.toHaveBeenCalled() - }) + }) - it('prints info messages', () => { - Logger.default.info('Some message') - expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO:', 'Some message') - }) + it('prints info messages', () => { + Logger.default.info('Some message') + expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some message') + }) - it('prints error messages', () => { - Logger.default.error('Some error message') - expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + it('prints error messages', () => { + Logger.default.error('Some error message') + expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + }) }) - }) describe('explicit error log level', () => { + jest.isolateModules(() => { + const Logger = require('../logger') - beforeAll(() => { - Logger.default.setLogLevel('error') - }) + beforeAll(() => { + Logger.default.setLogLevel('error') + }) - it('does not print verbose messages', () => { - Logger.default.log('Some message with looooong explanation') - expect(console.log).not.toHaveBeenCalled() + it('does not print verbose messages', () => { + Logger.default.log('Some message with looooong explanation') + expect(console.log).not.toHaveBeenCalled() - }) + }) - it('does not print info messages', () => { - Logger.default.info('Some message') - expect(console.log).not.toHaveBeenCalled() - }) + it('does not print info messages', () => { + Logger.default.info('Some message') + expect(console.log).not.toHaveBeenCalled() + }) - it('prints error messages', () => { - Logger.default.error('Some error message') - expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + it('prints error messages', () => { + Logger.default.error('Some error message') + expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + }) }) - }) describe('explicit none log level', () => { + jest.isolateModules(() => { + const Logger = require('../logger') - beforeAll(() => { - Logger.default.setLogLevel('none') - }) + beforeAll(() => { + Logger.default.setLogLevel('none') + }) - it('does not print verbose messages', () => { - Logger.default.log('Some message with looooong explanation') - expect(console.log).not.toHaveBeenCalled() + it('does not print verbose messages', () => { + Logger.default.log('Some message with looooong explanation') + expect(console.log).not.toHaveBeenCalled() - }) + }) - it('does not print info messages', () => { - Logger.default.info('Some message') - expect(console.log).not.toHaveBeenCalled() - }) + it('does not print info messages', () => { + Logger.default.info('Some message') + expect(console.log).not.toHaveBeenCalled() + }) - it('prints error messages', () => { - Logger.default.error('Some error message') - expect(console.error).not.toHaveBeenCalled() + it('prints error messages', () => { + Logger.default.error('Some error message') + expect(console.error).not.toHaveBeenCalled() + }) }) - }) describe('output logs into specified container', () => { - let logContainer - let history = [] + jest.isolateModules(() => { + const Logger = require('../logger') - beforeAll(() => { - logContainer = document.createElement('div') - logContainer.setAttribute('id', 'log') - document.getElementsByTagName('body')[0].appendChild(logContainer) + let logContainer + let history = [] - Logger.default.setLogLevel('verbose', '#log') + beforeAll(() => { + logContainer = document.createElement('div') + logContainer.setAttribute('id', 'log') + document.getElementsByTagName('body')[0].appendChild(logContainer) - history.push(`[adjust-sdk] ${today} INFO: Log level set to verbose`) - }) + Logger.default.setLogLevel('verbose', '#log') - it('prints verbose messages', () => { - Logger.default.log('Some message with looooong explanation') + history.push(`[adjust-sdk] ${today} INFO: Log level set to verbose`) + }) - history.push(`[adjust-sdk] ${today} LOG: Some message with looooong explanation`) + it('prints verbose messages', () => { + Logger.default.log('Some message with looooong explanation') - expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG:', 'Some message with looooong explanation') - expect(logContainer.textContent).toEqual(history.join('\n') + '\n') + history.push(`[adjust-sdk] ${today} LOG: Some message with looooong explanation`) - }) + expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG: ', 'Some message with looooong explanation') + expect(logContainer.textContent).toEqual(history.join('\n') + '\n') - it('prints info messages', () => { - Logger.default.info('Some message') + }) - history.push(`[adjust-sdk] ${today} INFO: Some message`) + it('prints info messages', () => { + Logger.default.info('Some message') - expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO:', 'Some message') - expect(logContainer.textContent).toEqual(history.join('\n') + '\n') - }) + history.push(`[adjust-sdk] ${today} INFO: Some message`) - it('prints error messages', () => { - Logger.default.error('Some error message') + expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some message') + expect(logContainer.textContent).toEqual(history.join('\n') + '\n') + }) - history.push(`[adjust-sdk] ${today} ERROR: Some error message`) + it('prints error messages', () => { + Logger.default.error('Some error message') - expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') - expect(logContainer.textContent).toEqual(history.join('\n') + '\n') - }) + history.push(`[adjust-sdk] ${today} ERROR: Some error message`) - it('prints multiple messages that might be json', () => { - const json = {info: 'look at the info'} + expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + expect(logContainer.textContent).toEqual(history.join('\n') + '\n') + }) - Logger.default.log('Some info', json) + it('prints multiple messages that might be json', () => { + const json = {info: 'look at the info'} - history.push(`[adjust-sdk] ${today} LOG: Some info ${JSON.stringify(json)}`) + Logger.default.log('Some info', json) - expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG:', 'Some info', json) - expect(logContainer.textContent).toEqual(history.join('\n') + '\n') + history.push(`[adjust-sdk] ${today} LOG: Some info ${JSON.stringify(json)}`) + expect(console.log).toHaveBeenCalledWith('[adjust-sdk]', today, 'LOG: ', 'Some info', json) + expect(logContainer.textContent).toEqual(history.join('\n') + '\n') + }) }) - }) - }) diff --git a/src/sdk/__tests__/main/main.suite.js b/src/sdk/__tests__/main/main.suite.js index 2b25636..88ee9f9 100644 --- a/src/sdk/__tests__/main/main.suite.js +++ b/src/sdk/__tests__/main/main.suite.js @@ -380,7 +380,7 @@ function expectGdprForgetMeCallback (onlyNumOfAssertions, asyncPublish) { const oldState = Preferences.getDisabled() if (asyncPublish) { - PubSub.publish('sdk:gdpr-forget-me', true) + PubSub.publish('sdk:gdpr-forget-me') } jest.runOnlyPendingTimers() @@ -394,7 +394,7 @@ function expectGdprForgetMeCallback (onlyNumOfAssertions, asyncPublish) { function expectNotGdprForgetMeCallback () { const oldState = Preferences.getDisabled() - PubSub.publish('sdk:gdpr-forget-me', true) + PubSub.publish('sdk:gdpr-forget-me') jest.runOnlyPendingTimers() diff --git a/src/sdk/__tests__/preferences.spec.js b/src/sdk/__tests__/preferences.spec.js index 99f2ea7..3a4132d 100644 --- a/src/sdk/__tests__/preferences.spec.js +++ b/src/sdk/__tests__/preferences.spec.js @@ -110,7 +110,7 @@ describe('activity state functionality', () => { Preferences.reload() - expect(PubSub.publish).toHaveBeenCalledWith('sdk:shutdown', true) + expect(PubSub.publish).toHaveBeenCalledWith('sdk:shutdown') expect(Preferences.getDisabled()).toEqual({ reason: 'gdpr', pending: true diff --git a/src/sdk/config.js b/src/sdk/config.js index 807bba7..95a4ece 100644 --- a/src/sdk/config.js +++ b/src/sdk/config.js @@ -1,7 +1,4 @@ // @flow -declare var __ADJUST__NAMESPACE: string -declare var __ADJUST__SDK_VERSION: string - import { type BaseParamsT, type CustomConfigT, @@ -10,6 +7,7 @@ import { type BaseParamsMandatoryListT, type CustomConfigListT } from './types' +import Globals from './globals' import {MINUTE, SECOND, DAY} from './constants' import {buildList, reducer} from './utilities' import Logger from './logger' @@ -81,12 +79,10 @@ const _allowedConfig: CustomConfigListT = [ * }} */ const _baseConfig = { - namespace: __ADJUST__NAMESPACE || 'adjust-sdk', - version: __ADJUST__SDK_VERSION || '0.0.0', sessionWindow: 30 * MINUTE, sessionTimerWindow: 60 * SECOND, requestValidityWindow: 28 * DAY, - baseUrl: process.env.NODE_ENV === 'test' + baseUrl: Globals.env === 'test' ? {app: 'app', gdpr: 'gdpr'} : {app: 'https://app.adjust.com', gdpr: 'https://gdpr.adjust.com'} } diff --git a/src/sdk/gdpr-forget-device.js b/src/sdk/gdpr-forget-device.js index 38ac5a9..18bd5dd 100644 --- a/src/sdk/gdpr-forget-device.js +++ b/src/sdk/gdpr-forget-device.js @@ -54,7 +54,7 @@ function forget (force?: boolean): boolean { _request.send({ params: {...ActivityState.getParams()} }).then(() => { - publish('sdk:gdpr-forget-me', true) + publish('sdk:gdpr-forget-me') }) return true diff --git a/src/sdk/globals.js b/src/sdk/globals.js new file mode 100644 index 0000000..8b8f090 --- /dev/null +++ b/src/sdk/globals.js @@ -0,0 +1,16 @@ +// @flow +declare var __ADJUST__NAMESPACE: string +declare var __ADJUST__SDK_VERSION: string +declare var process: {| + env: {| + NODE_ENV: 'development' | 'production' | 'test' + |} +|} + +const Globals = { + namespace: __ADJUST__NAMESPACE || 'adjust-sdk', + version: __ADJUST__SDK_VERSION || '5.0.0', + env: process.env.NODE_ENV +} + +export default Globals diff --git a/src/sdk/http.js b/src/sdk/http.js index ad94b21..6a450ea 100644 --- a/src/sdk/http.js +++ b/src/sdk/http.js @@ -9,6 +9,7 @@ import { } from './types' import {HTTP_ERRORS} from './constants' import Config from './config' +import Globals from './globals' import Logger from './logger' import {isObject, isValidJson, isRequest, entries, isEmptyEntry, reducer} from './utilities' import {publish} from './pub-sub' @@ -195,7 +196,7 @@ function _prepareUrlAndParams ({url, method, params}: HttpRequestParamsT, defaul function _prepareHeaders (xhr: XMLHttpRequest, method: $PropertyType): void { const logHeader = 'REQUEST HEADERS:' const headers = [ - ['Client-SDK', `js${Config.version}`], + ['Client-SDK', `js${Globals.version}`], ['Content-Type', method === 'POST' ? 'application/x-www-form-urlencoded' : 'application/json'] ] @@ -269,7 +270,7 @@ function _interceptSuccess (result: HttpSuccessResponseT, url): HttpSuccessRespo const optedOut = result.tracking_state === 'opted_out' if (!isGdprRequest && optedOut) { - publish('sdk:gdpr-forget-me', true) + publish('sdk:gdpr-forget-me') return result } @@ -282,7 +283,7 @@ function _interceptSuccess (result: HttpSuccessResponseT, url): HttpSuccessRespo } if (isThirdPartySharingOptOutRequest) { - publish('sdk:third-party-sharing-opt-out', true) + publish('sdk:third-party-sharing-opt-out') return result } diff --git a/src/sdk/logger.js b/src/sdk/logger.js index 4656d51..a6354c1 100644 --- a/src/sdk/logger.js +++ b/src/sdk/logger.js @@ -1,5 +1,10 @@ -import Config from './config' +// @flow +import Globals from './globals' import {isObject} from './utilities' +import {type LogOptionsT} from './types' + +type LogLevelT = $PropertyType +type MethodNameT = 'log' | 'info' | 'error' | 'warn' const LEVEL_NONE = 'none' const LEVEL_ERROR = 'error' @@ -35,18 +40,6 @@ const _envLogLevels = { test: LEVEL_VERBOSE } -/** - * Available logger methods - * - * @type {Array} - * @private - */ -const _methods = [ - {name: 'log', level: LEVEL_VERBOSE}, - {name: 'info', level: LEVEL_INFO}, - {name: 'error', level: LEVEL_ERROR} -] - /** * Current logger level */ @@ -66,8 +59,8 @@ let _output = '' * @returns {string} * @private */ -function _getDefaultLogLevel () { - return _envLogLevels[process.env.NODE_ENV] || LEVEL_ERROR +function _getDefaultLogLevel (): LogLevelT { + return _envLogLevels[Globals.env] || LEVEL_ERROR } /** @@ -76,57 +69,65 @@ function _getDefaultLogLevel () { * @param {string=} logLevel * @param {string=} logOutput */ -function setLogLevel (logLevel, logOutput) { - +function setLogLevel (logLevel: LogLevelT, logOutput: string): void { const exists = !logLevel || Object.keys(_levels).indexOf(logLevel) !== -1 if (!exists) { - _log('error', 'You must set one of the available log levels: verbose, info, error or none') + _log('error', 'error', 'You must set one of the available log levels: verbose, info, error or none') return } _level = logLevel || _getDefaultLogLevel() _output = logOutput - _log('info', `Log level set to ${_level}`) + _log('info', logLevel, `Log level set to ${_level}`) } /** * Output the message to the console * * @param {string} methodName - * @param {string} args + * @param {string} logLevel + * @param {Array} args * @private */ -function _log (methodName, ...args) { - const now = (new Date()).toISOString() - const message = [`[${Config.namespace}]`, now, `${methodName.toUpperCase()}:`, ...args] +function _log (methodName: MethodNameT, logLevel: LogLevelT, ...args: Array): void { + if (_levels[_level] < _levels[logLevel]) { + return + } + + const time = (new Date()).toISOString() + const spaces = methodName === 'log' ? ' ' : (methodName === 'info' ? ' ' : '') + const messagePrefix = [`[${Globals.namespace}]`, time, `${methodName.toUpperCase()}:${spaces}`] const outputContainer = _output ? document.querySelector(_output) : null - console[methodName].apply(null, message) // eslint-disable-line + console[methodName].apply(null, [...messagePrefix, ...args]) // eslint-disable-line if (outputContainer) { - const [namespace, time, prefix, ...rest] = message - const spaces = methodName === 'log' ? ' ' : (methodName === 'info' ? ' ' : '') - outputContainer.textContent += `${namespace} ${time} ${prefix}${spaces} ${rest.map(m => isObject(m) ? JSON.stringify(m) : m).join(' ')}\n` + outputContainer.textContent += `${messagePrefix.join(' ')} ${args.map(m => isObject(m) ? JSON.stringify(m) : m).join(' ')}\n` outputContainer.scrollTop = outputContainer.scrollHeight } +} +/** + * Apply predefined log level and return log method + * + * @param {string} name + * @param {string} logLevel + * @returns {Array} args + * @private + */ +function _applyLevel (name: MethodNameT, logLevel: LogLevelT) { + return (...args: Array) => { + _log(name, logLevel, ...args) + } } const Logger = { - setLogLevel + setLogLevel, + log: _applyLevel('log', LEVEL_VERBOSE), + info: _applyLevel('info', LEVEL_INFO), + error: _applyLevel('error', LEVEL_ERROR) } -_methods.forEach(method => { - Object.defineProperty(Logger, method.name, { - writable: false, - value: (...message) => { - if (_levels[_level] >= _levels[method.level]) { - _log(method.name, ...message) - } - } - }) -}) - export default Logger diff --git a/src/sdk/preferences.js b/src/sdk/preferences.js index 773c07f..6feb957 100644 --- a/src/sdk/preferences.js +++ b/src/sdk/preferences.js @@ -115,7 +115,7 @@ function reload (): void { const sdkDisabled: ?SdkDisabledT = (_preferences || {}).sdkDisabled || null if (stored.sdkDisabled && !sdkDisabled) { - publish('sdk:shutdown', true) + publish('sdk:shutdown') } _setPreferences() diff --git a/src/sdk/pub-sub.js b/src/sdk/pub-sub.js index 1b9552f..fced6af 100644 --- a/src/sdk/pub-sub.js +++ b/src/sdk/pub-sub.js @@ -1,5 +1,11 @@ +// @flow import {entries} from './utilities' +type CallbackT = {| + id: string, + cb: (string, T) => mixed +|} + /** * List of events with subscribed callbacks * @@ -22,7 +28,7 @@ let _timeoutIds = [] * @returns {string} * @private */ -function _getId () { +function _getId (): string { return 'id' + Math.random().toString(36).substr(2, 16) } @@ -33,17 +39,15 @@ function _getId () { * @param {Function} cb * @returns {string} */ -function subscribe (name, cb) { +function subscribe (name: string, cb: $PropertyType, 'cb'>): string { const id = _getId() + const callback: CallbackT = {id, cb} if (!_list[name]) { _list[name] = [] } - _list[name].push({ - id: id, - cb: cb - }) + _list[name].push(callback) return id } @@ -53,12 +57,14 @@ function subscribe (name, cb) { * * @param {string} id */ -function unsubscribe (id) { - if (!id) { return } +function unsubscribe (id: string): void { + if (!id) { + return + } entries(_list) .some(([, callbacks]) => callbacks - .some((callback, i) => { + .some((callback: CallbackT, i: number) => { if (callback.id === id) { callbacks.splice(i, 1) return true @@ -73,22 +79,23 @@ function unsubscribe (id) { * @param {*} args * @returns {Array} */ -function publish (name, args) { +function publish (name: string, args: T): void { if (!_list[name]) { - return [] + return } - _list[name].forEach(item => { - if (typeof item.cb === 'function') { - _timeoutIds.push(setTimeout(() => item.cb(name, args))) - } - }) + _list[name] + .forEach((item: CallbackT) => { + if (typeof item.cb === 'function') { + _timeoutIds.push(setTimeout(() => item.cb(name, args))) + } + }) } /** * Destroy all registered events with their callbacks */ -function destroy () { +function destroy (): void { _timeoutIds.forEach(clearTimeout) _timeoutIds = [] _list = {} diff --git a/src/sdk/session.js b/src/sdk/session.js index 65f7b0e..fa60d6f 100644 --- a/src/sdk/session.js +++ b/src/sdk/session.js @@ -164,12 +164,12 @@ function _handleVisibilityChange (): void { /** * Handle session request finish; update installed state * - * @param {Object} e + * @param {string} e * @param {Object} result * @returns {Promise|void} * @private */ -function _handleSessionRequestFinish (e, result: HttpSuccessResponseT | HttpErrorResponseT): ?Promise { +function _handleSessionRequestFinish (e: string, result: HttpSuccessResponseT | HttpErrorResponseT): ?Promise { if (result && result.status === 'error') { Logger.error('Session was not successful, error was returned from the server:', result.response) return diff --git a/src/sdk/storage/indexeddb.js b/src/sdk/storage/indexeddb.js index 37dd725..eeef6dc 100644 --- a/src/sdk/storage/indexeddb.js +++ b/src/sdk/storage/indexeddb.js @@ -1,4 +1,4 @@ -import Config from '../config' +import Globals from '../globals' import SchemeMap from './scheme-map' import ActivityState from '../activity-state' import QuickStorage from '../storage/quick-storage' @@ -7,7 +7,7 @@ import {recover as recoverPreferences} from '../preferences' import {isEmpty, isObject, entries} from '../utilities' import {convertRecord, convertStoreName} from './converter' -const _dbName = Config.namespace +const _dbName = Globals.namespace const _dbVersion = 1 let _db diff --git a/src/sdk/storage/quick-storage.js b/src/sdk/storage/quick-storage.js index 0093000..af20bf7 100644 --- a/src/sdk/storage/quick-storage.js +++ b/src/sdk/storage/quick-storage.js @@ -1,9 +1,9 @@ import {convertRecord} from './converter' import {entries} from '../utilities' -import Config from '../config' +import Globals from '../globals' import SchemeMap from './scheme-map' -const _storageName = Config.namespace +const _storageName = Globals.namespace const _storeNames = SchemeMap.storeNames.left /** diff --git a/src/sdk/time.js b/src/sdk/time.js index 3f64c9e..d65d902 100644 --- a/src/sdk/time.js +++ b/src/sdk/time.js @@ -1,3 +1,4 @@ +// @flow /** * Prepend zero to be used in certain format * @@ -6,7 +7,7 @@ * @returns {string} * @private */ -function _prependZero (value, power = 1) { +function _prependZero (value: number, power: number = 1): string { let formatted = value + '' for (let i = 1; i <= power; i += 1) { @@ -20,11 +21,12 @@ function _prependZero (value, power = 1) { /** * Get formatted date (YYYY-MM-DD) + * * @param date * @returns {string} * @private */ -function _getDate (date) { +function _getDate (date: Date): string { const day = _prependZero(date.getDate()) const month = _prependZero(date.getMonth() + 1) const year = date.getFullYear() @@ -39,7 +41,7 @@ function _getDate (date) { * @returns {string} * @private */ -function _getTime (date) { +function _getTime (date: Date): string { const hours = _prependZero(date.getHours(), 1) const minutes = _prependZero(date.getMinutes()) const seconds = _prependZero(date.getSeconds()) @@ -55,7 +57,7 @@ function _getTime (date) { * @returns {string} * @private */ -function _getTimezone (date) { +function _getTimezone (date: Date): string { const offsetInMinutes = date.getTimezoneOffset() const hoursOffset = _prependZero(Math.floor(Math.abs(offsetInMinutes) / 60)) const minutesOffset = _prependZero(Math.abs(offsetInMinutes) % 60) @@ -70,7 +72,7 @@ function _getTimezone (date) { * @param {number=} timestamp * @returns {string} */ -function getTimestamp (timestamp) { +function getTimestamp (timestamp?: number): string { const d = timestamp ? new Date(timestamp) : new Date() const date = _getDate(d) const time = _getTime(d) @@ -86,7 +88,7 @@ function getTimestamp (timestamp) { * @param {number} d2 * @returns {number} */ -function timePassed (d1, d2) { +function timePassed (d1: number, d2: number): number { if (isNaN(d1) || isNaN(d2)) { return 0 } From 1df6574e89c8ef9a8f9e307018370b3253bec55b Mon Sep 17 00:00:00 2001 From: YaroslavnaMatkova Date: Mon, 27 Jul 2020 13:20:18 +0300 Subject: [PATCH 05/27] ADAPP-4627: External device id (#52) * Added external_device_id param * fixed typo * moved external_device_id into BaseParams * added an input field to set external_device_id in demo app * Version increment. Docs updates * reword CHANGELOG update * Updated tests * added vscode path to gitignore * Revert readme Co-authored-by: ugi --- .gitignore | 1 + CHANGELOG.md | 6 +++++ VERSION | 2 +- package.json | 2 +- src/demo.html | 3 ++- src/demo/tabs/tabs.html | 9 +++++-- src/demo/tabs/tabs.js | 1 + src/index.js | 3 ++- src/sdk/__tests__/config.spec.js | 4 ++- src/sdk/__tests__/http.spec.js | 44 ++++++++++++++++++++++++++++++++ src/sdk/config.js | 4 ++- src/sdk/main.js | 5 ++-- src/sdk/types.js | 4 ++- 13 files changed, 77 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index e13c7f2..833d261 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea/ +.vscode/ *.log *.DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md index 07cb70e..629a796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### Version 5.1.0 (xxth July 2020) +#### Added +- Added external device ID support. + +--- + ### Version 5.0.0 (15th May 2020) #### Added - New major SDK update. diff --git a/VERSION b/VERSION index 0062ac9..831446c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.0.0 +5.1.0 diff --git a/package.json b/package.json index bc04063..1421790 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@adjustcom/adjust-web-sdk", - "version": "5.0.0", + "version": "5.1.0", "description": "This is the guide to the Javascript SDK of Adjust™ for web sites or web apps. You can read more about Adjust™ at [adjust.com].", "scripts": { "build:demo": "webpack --mode production --config webpack.demo.config.js", diff --git a/src/demo.html b/src/demo.html index b36ffb3..6b5f14e 100644 --- a/src/demo.html +++ b/src/demo.html @@ -24,7 +24,8 @@ logLevel: 'verbose', // optional, default is 'error', other options are 'none', 'error', 'info', 'verbose' logOutput: '#output', // optional, outputs logs from sdk into provided container // defaultTracker: 'YOUR_DEFAULT_TRACKER_TOKEN', // optional - // customUrl: 'YOUR_CUSTOM_URL' // optional + // externalDeviceId: 'YOUR_EXTERNAL_DEVICE_ID', // optional + // customUrl: 'YOUR_CUSTOM_URL', // optional // eventDeduplicationListLimit: 'YOUR_EVENT_DEDUPLICATION_LIST_LIMIT' // optional, default set to 10 }); diff --git a/src/demo/tabs/tabs.html b/src/demo/tabs/tabs.html index 8714bb5..ade3847 100644 --- a/src/demo/tabs/tabs.html +++ b/src/demo/tabs/tabs.html @@ -31,12 +31,17 @@
- - + +
+
+ + +
+
+ diff --git a/src/sdk/__mocks__/logger.js b/src/sdk/__mocks__/logger.js index 0d2fafd..2f19a7c 100644 --- a/src/sdk/__mocks__/logger.js +++ b/src/sdk/__mocks__/logger.js @@ -2,5 +2,6 @@ export default { setLogLevel () {}, log () {}, info () {}, + warn () {}, error () {} } diff --git a/src/sdk/__tests__/logger.spec.js b/src/sdk/__tests__/logger.spec.js index ff10e2d..a83532b 100644 --- a/src/sdk/__tests__/logger.spec.js +++ b/src/sdk/__tests__/logger.spec.js @@ -7,6 +7,7 @@ describe('test Logger functionality', () => { beforeAll(() => { jest.spyOn(console, 'log').mockImplementation(() => {}) jest.spyOn(console, 'info').mockImplementation(() => {}) + jest.spyOn(console, 'warn').mockImplementation(() => {}) jest.spyOn(console, 'error').mockImplementation(() => {}) Utils.mockDate(new Date(2019, 9, 14)) @@ -33,7 +34,7 @@ describe('test Logger functionality', () => { expect(console.info).toHaveBeenLastCalledWith('[adjust-sdk]', today, 'INFO: ', 'Log level set to error') Logger.default.setLogLevel('not-existing-level') - expect(console.error).toHaveBeenLastCalledWith('[adjust-sdk]', today, 'ERROR:', 'You must set one of the available log levels: verbose, info, error or none') + expect(console.error).toHaveBeenLastCalledWith('[adjust-sdk]', today, 'ERROR:', 'You must set one of the available log levels: verbose, info, warning, error or none') Logger.default.setLogLevel() }) @@ -46,6 +47,9 @@ describe('test Logger functionality', () => { Logger.default.info('Some', 'info') expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some', 'info') + Logger.default.warn('Some', 'warning', 'message') + expect(console.warn).toHaveBeenCalledWith('[adjust-sdk]', today, 'WARN: ', 'Some', 'warning', 'message') + Logger.default.error('Some', 'error', 'message') expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some', 'error', 'message') @@ -68,6 +72,11 @@ describe('test Logger functionality', () => { expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some message') }) + it('prints warning messages', () => { + Logger.default.warn('Some warning') + expect(console.warn).toHaveBeenCalledWith('[adjust-sdk]', today, 'WARN: ', 'Some warning') + }) + it('prints error messages', () => { Logger.default.error('Some error message') expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') @@ -95,6 +104,11 @@ describe('test Logger functionality', () => { expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some message') }) + it('prints warning messages', () => { + Logger.default.warn('Some warning') + expect(console.warn).toHaveBeenCalledWith('[adjust-sdk]', today, 'WARN: ', 'Some warning') + }) + it('prints error messages', () => { Logger.default.error('Some error message') expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') @@ -122,6 +136,11 @@ describe('test Logger functionality', () => { expect(console.info).not.toHaveBeenCalled() }) + it('does not print warning messages', () => { + Logger.default.warn('Some warning') + expect(console.warn).not.toHaveBeenCalled() + }) + it('prints error messages', () => { Logger.default.error('Some error message') expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') @@ -148,6 +167,11 @@ describe('test Logger functionality', () => { expect(console.info).not.toHaveBeenCalled() }) + it('does not print warning messages', () => { + Logger.default.warn('Some warning') + expect(console.warn).not.toHaveBeenCalled() + }) + it('prints error messages', () => { Logger.default.error('Some error message') expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') @@ -174,6 +198,11 @@ describe('test Logger functionality', () => { expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some message') }) + it('prints warning messages', () => { + Logger.default.warn('Some warning') + expect(console.warn).toHaveBeenCalledWith('[adjust-sdk]', today, 'WARN: ', 'Some warning') + }) + it('prints error messages', () => { Logger.default.error('Some error message') expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') @@ -200,6 +229,42 @@ describe('test Logger functionality', () => { expect(console.info).toHaveBeenCalledWith('[adjust-sdk]', today, 'INFO: ', 'Some message') }) + it('prints warning messages', () => { + Logger.default.warn('Some warning') + expect(console.warn).toHaveBeenCalledWith('[adjust-sdk]', today, 'WARN: ', 'Some warning') + }) + + it('prints error messages', () => { + Logger.default.error('Some error message') + expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') + }) + }) + }) + + describe('explicit warning log level', () => { + jest.isolateModules(() => { + const Logger = require('../logger') + + beforeAll(() => { + Logger.default.setLogLevel('warning') + }) + + it('does not print verbose messages', () => { + Logger.default.log('Some message with looooong explanation') + expect(console.log).not.toHaveBeenCalled() + + }) + + it('does not print info messages', () => { + Logger.default.info('Some message') + expect(console.log).not.toHaveBeenCalled() + }) + + it('prints warning messages', () => { + Logger.default.warn('Some warning') + expect(console.warn).toHaveBeenCalledWith('[adjust-sdk]', today, 'WARN: ', 'Some warning') + }) + it('prints error messages', () => { Logger.default.error('Some error message') expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') @@ -226,6 +291,11 @@ describe('test Logger functionality', () => { expect(console.log).not.toHaveBeenCalled() }) + it('does not prints warning messages', () => { + Logger.default.warn('Some warning') + expect(console.warn).not.toHaveBeenCalled() + }) + it('prints error messages', () => { Logger.default.error('Some error message') expect(console.error).toHaveBeenCalledWith('[adjust-sdk]', today, 'ERROR:', 'Some error message') @@ -252,6 +322,11 @@ describe('test Logger functionality', () => { expect(console.log).not.toHaveBeenCalled() }) + it('does not prints warning messages', () => { + Logger.default.warn('Some warning') + expect(console.warn).not.toHaveBeenCalled() + }) + it('prints error messages', () => { Logger.default.error('Some error message') expect(console.error).not.toHaveBeenCalled() @@ -295,6 +370,15 @@ describe('test Logger functionality', () => { expect(logContainer.textContent).toEqual(history.join('\n') + '\n') }) + it('prints warning messages', () => { + Logger.default.warn('Some warning') + + history.push(`[adjust-sdk] ${today} WARN: Some warning`) + + expect(console.warn).toHaveBeenCalledWith('[adjust-sdk]', today, 'WARN: ', 'Some warning') + expect(logContainer.textContent).toEqual(history.join('\n') + '\n') + }) + it('prints error messages', () => { Logger.default.error('Some error message') diff --git a/src/sdk/__tests__/storage/indexeddb.spec.js b/src/sdk/__tests__/storage/indexeddb.spec.js index d9507e5..a8ce090 100644 --- a/src/sdk/__tests__/storage/indexeddb.spec.js +++ b/src/sdk/__tests__/storage/indexeddb.spec.js @@ -17,7 +17,7 @@ describe('IndexedDB usage', () => { global.IDBKeyRange = IDBKeyRange beforeAll(() => { - jest.spyOn(Logger.default, 'error') + jest.spyOn(Logger.default, 'warn') }) afterAll(() => { @@ -29,14 +29,14 @@ describe('IndexedDB usage', () => { let supported = IndexedDB.isSupported() expect(supported).toBeTruthy() - expect(Logger.default.error).not.toHaveBeenCalled() + expect(Logger.default.warn).not.toHaveBeenCalled() delete global.indexedDB supported = IndexedDB.isSupported() expect(supported).toBeFalsy() - expect(Logger.default.error).toHaveBeenCalledWith('IndexedDB is not supported in this browser') + expect(Logger.default.warn).toHaveBeenCalledWith('IndexedDB is not supported in this browser') global.indexedDB = fakeIDB @@ -51,7 +51,7 @@ describe('IndexedDB usage', () => { platformSpy.mockReturnValue('iPhone') expect(IndexedDB.isSupported()).toBeFalsy() - expect(Logger.default.error).toHaveBeenCalledWith('IndexedDB is not supported in this browser') + expect(Logger.default.warn).toHaveBeenCalledWith('IndexedDB is not supported in this browser') IndexedDB.getAll('activityState') .catch(error => { diff --git a/src/sdk/__tests__/storage/localstorage.spec.js b/src/sdk/__tests__/storage/localstorage.spec.js index 3f8bf51..d1aeeca 100644 --- a/src/sdk/__tests__/storage/localstorage.spec.js +++ b/src/sdk/__tests__/storage/localstorage.spec.js @@ -10,7 +10,7 @@ jest.mock('../../logger') describe('LocalStorage usage', () => { beforeAll(() => { - jest.spyOn(Logger.default, 'error') + jest.spyOn(Logger.default, 'warn') }) afterAll(() => { @@ -25,14 +25,14 @@ describe('LocalStorage usage', () => { let supported = LocalStorage.isSupported() expect(supported).toBeTruthy() - expect(Logger.default.error).not.toHaveBeenCalled() + expect(Logger.default.warn).not.toHaveBeenCalled() delete global.localStorage supported = LocalStorage.isSupported() expect(supported).toBeFalsy() - expect(Logger.default.error).toHaveBeenCalledWith('LocalStorage is not supported in this browser') + expect(Logger.default.warn).toHaveBeenCalledWith('LocalStorage is not supported in this browser') return Storage.default.getItem('activityState') .catch(error => { diff --git a/src/sdk/logger.js b/src/sdk/logger.js index a551d87..f947e6b 100644 --- a/src/sdk/logger.js +++ b/src/sdk/logger.js @@ -8,6 +8,7 @@ type MethodNameT = 'log' | 'info' | 'error' | 'warn' const LEVEL_NONE = 'none' const LEVEL_ERROR = 'error' +const LEVEL_WARNING = 'warning' const LEVEL_INFO = 'info' const LEVEL_VERBOSE = 'verbose' @@ -24,8 +25,22 @@ const LEVEL_VERBOSE = 'verbose' const _levels = { [LEVEL_NONE]: -1, [LEVEL_ERROR]: 0, - [LEVEL_INFO]: 1, - [LEVEL_VERBOSE]: 2 + [LEVEL_WARNING]: 1, + [LEVEL_INFO]: 2, + [LEVEL_VERBOSE]: 3 +} + +/** + * Spaces placed after log level tag in console to align messages. + * + * @type {Object} + * @private + */ +const _spaces = { + 'log': ' ', + 'info': ' ', + 'warn': ' ', + 'error': '' } /** @@ -73,7 +88,7 @@ function setLogLevel (logLevel: LogLevelT, logOutput: string): void { const exists = !logLevel || Object.keys(_levels).indexOf(logLevel) !== -1 if (!exists) { - _log('error', 'error', 'You must set one of the available log levels: verbose, info, error or none') + _log('error', 'error', 'You must set one of the available log levels: verbose, info, warning, error or none') return } @@ -97,7 +112,7 @@ function _log (methodName: MethodNameT, logLevel: LogLevelT, ...args: Array> export type LogOptionsT = $ReadOnly<$Shape<{| - logLevel: 'none' | 'error' | 'info' | 'verbose', + logLevel: 'none' | 'error' | 'warning' | 'info' | 'verbose', logOutput: string |}>> From 1c7e212bd8bb15182ff092e67993ca236f182d65 Mon Sep 17 00:00:00 2001 From: YaroslavnaMatkova Date: Tue, 6 Oct 2020 13:47:42 +0300 Subject: [PATCH 11/27] Event tracking 404 (#61) * Fixed ActivityState.lastActive value update when going foreground * Delay public methods until session package sent * Updated delaying mechanism logic in tests * Fixed test --- .../main/main.storage-available.spec.js | 97 ++++++++++++++++--- src/sdk/__tests__/main/main.suite.js | 23 +++-- src/sdk/__tests__/session.spec.js | 23 ++++- src/sdk/identity.js | 12 ++- src/sdk/main.js | 26 ++++- src/sdk/session.js | 11 ++- 6 files changed, 158 insertions(+), 34 deletions(-) diff --git a/src/sdk/__tests__/main/main.storage-available.spec.js b/src/sdk/__tests__/main/main.storage-available.spec.js index 14f7cc6..e3db8a6 100644 --- a/src/sdk/__tests__/main/main.storage-available.spec.js +++ b/src/sdk/__tests__/main/main.storage-available.spec.js @@ -88,45 +88,85 @@ describe('main entry point - test instance initiation when storage is available' expect(Logger.default.error).toHaveBeenLastCalledWith('Adjust SDK can not track event, sdk instance is not initialized') }) - it('runs session first and then sdk-click request and track event', () => { + it('runs session first and then sdk-click request and track event after sdk was installed', () => { global.history.pushState({}, '', '?adjust_referrer=param%3Dvalue&something=else') + expect.assertions(6) + AdjustInstance.initSdk(suite.config) + expect(PubSub.subscribe).toHaveBeenCalledWith('sdk:installed', expect.any(Function)) + AdjustInstance.trackEvent({eventToken: 'bla123'}) + expect(Logger.default.log).toHaveBeenLastCalledWith('Running track event is delayed until Adjust SDK is up') + + return Utils.flushPromises() + .then(() => { + + let requests = Queue.push.mock.calls.map(call => call[0].url) + + expect(requests[0]).toEqual('/session') + expect(requests[1]).toEqual('/sdk_click') + + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + + expect(Logger.default.log).toHaveBeenLastCalledWith('Delayed track event task is running now') + + return Utils.flushPromises() + .then(() => { + requests = Queue.push.mock.calls.map(call => call[0].url) + expect(requests[2]).toEqual('/event') + + global.history.pushState({}, '', '?') + }) + }) + }) - expect.assertions(3) + it('runs session first and then sdk-click request', () => { + + global.history.pushState({}, '', '?adjust_referrer=param%3Dvalue&something=else') + + AdjustInstance.initSdk(suite.config) + + expect.assertions(2) return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() const requests = Queue.push.mock.calls.map(call => call[0].url) expect(requests[0]).toEqual('/session') expect(requests[1]).toEqual('/sdk_click') - expect(requests[2]).toEqual('/event') global.history.pushState({}, '', '?') }) }) it('respect the order of events tracked', () => { + expect.assertions(9) AdjustInstance.initSdk(suite.config) - AdjustInstance.trackEvent({eventToken: 'bla1'}) - AdjustInstance.trackEvent({eventToken: 'bla2'}) - - expect.assertions(9) - return Utils.flushPromises() .then(() => { - - AdjustInstance.trackEvent({eventToken: 'bla3'}) - AdjustInstance.trackEvent({eventToken: 'bla4'}) - AdjustInstance.trackEvent({eventToken: 'bla5'}) + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + + AdjustInstance.trackEvent({eventToken: 'bla1'}) + AdjustInstance.trackEvent({eventToken: 'bla2'}) return Utils.flushPromises() + .then(() => { + + AdjustInstance.trackEvent({eventToken: 'bla3'}) + AdjustInstance.trackEvent({eventToken: 'bla4'}) + AdjustInstance.trackEvent({eventToken: 'bla5'}) + + return Utils.flushPromises() + }) }) .then(() => { const requests = Queue.push.mock.calls @@ -164,6 +204,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + // for example disable has been done in another tab PubSub.publish('sdk:shutdown') @@ -205,6 +248,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + const requests = Queue.push.mock.calls expect(requests.length).toBe(2) @@ -223,6 +269,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + const requests = Queue.push.mock.calls expect(requests.length).toBe(2) @@ -239,6 +288,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + AdjustInstance.disableThirdPartySharing() const requests = Queue.push.mock.calls @@ -257,6 +309,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + const requests = Queue.push.mock.calls expect(requests.length).toBe(2) @@ -280,6 +335,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + const requests = Queue.push.mock.calls expect(Logger.default.log).toHaveBeenCalledWith('Adjust SDK is running pending third-party sharing opt-out request') @@ -302,6 +360,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + const requests = Queue.push.mock.calls expect(Logger.default.log).toHaveBeenCalledWith('Delayed disable third-party sharing task is running now') @@ -327,6 +388,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + const requests = Queue.push.mock.calls expect(Logger.default.log).toHaveBeenCalledWith('Adjust SDK is running pending third-party sharing opt-out request') @@ -350,6 +414,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + AdjustInstance.disableThirdPartySharing() const requests = Queue.push.mock.calls @@ -373,6 +440,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + AdjustInstance.disableThirdPartySharing() const requests = Queue.push.mock.calls @@ -395,6 +465,9 @@ describe('main entry point - test instance initiation when storage is available' return Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + AdjustInstance.disableThirdPartySharing() AdjustInstance.disableThirdPartySharing() diff --git a/src/sdk/__tests__/main/main.suite.js b/src/sdk/__tests__/main/main.suite.js index 88ee9f9..a707d7a 100644 --- a/src/sdk/__tests__/main/main.suite.js +++ b/src/sdk/__tests__/main/main.suite.js @@ -37,12 +37,13 @@ function _startFirstPart () { expect(Listeners.register).toHaveBeenCalledTimes(1) - expect(PubSub.subscribe.mock.calls[0][0]).toEqual('sdk:shutdown') - expect(PubSub.subscribe.mock.calls[1][0]).toEqual('sdk:gdpr-forget-me') - expect(PubSub.subscribe.mock.calls[2][0]).toEqual('sdk:third-party-sharing-opt-out') - expect(PubSub.subscribe.mock.calls[3][0]).toEqual('attribution:check') - expect(PubSub.subscribe.mock.calls[4][0]).toEqual('attribution:change') - expect(PubSub.subscribe.mock.calls[4][1]).toEqual(config.attributionCallback) + expect(PubSub.subscribe.mock.calls[0][0]).toEqual('sdk:installed') + expect(PubSub.subscribe.mock.calls[1][0]).toEqual('sdk:shutdown') + expect(PubSub.subscribe.mock.calls[2][0]).toEqual('sdk:gdpr-forget-me') + expect(PubSub.subscribe.mock.calls[3][0]).toEqual('sdk:third-party-sharing-opt-out') + expect(PubSub.subscribe.mock.calls[4][0]).toEqual('attribution:check') + expect(PubSub.subscribe.mock.calls[5][0]).toEqual('attribution:change') + expect(PubSub.subscribe.mock.calls[5][1]).toEqual(config.attributionCallback) expect(Identity.start).toHaveBeenCalledTimes(1) @@ -57,7 +58,6 @@ function expectStart_Async () { expect(Queue.run).toHaveBeenCalledWith({cleanUp: true}) expect(Session.watch).toHaveBeenCalledTimes(1) expect(sdkClick.default).toHaveBeenCalledTimes(1) - expect(Scheduler.flush).toHaveBeenCalledTimes(1) }) return {assertions: 16, promise} @@ -74,7 +74,7 @@ function expectPartialStartWithGdprRequest_Async () { expectGdprRequest() }) - return {assertions: 17, promise} + return {assertions: 18, promise} } function expectNotStart (restart) { @@ -104,10 +104,15 @@ function expectDelayedTrackEvent_Async () { const promise = Utils.flushPromises() .then(() => { + PubSub.publish('sdk:installed') + jest.runOnlyPendingTimers() + + expect(Logger.default.log).toHaveBeenLastCalledWith('Delayed track event task is running now') + expect(event.default).toHaveBeenCalledWith({eventToken: 'bla123'}, expect.any(Number)) }) - return {assertions: 3, promise} + return {assertions: 4, promise} } function expectRunningTrackEvent () { diff --git a/src/sdk/__tests__/session.spec.js b/src/sdk/__tests__/session.spec.js index f3e10c5..34a7bef 100644 --- a/src/sdk/__tests__/session.spec.js +++ b/src/sdk/__tests__/session.spec.js @@ -52,6 +52,7 @@ describe('test session functionality', () => { jest.spyOn(PubSub, 'publish') jest.spyOn(PubSub, 'subscribe') jest.spyOn(ActivityState.default, 'updateInstalled') + jest.spyOn(ActivityState.default, 'updateSessionLength') pvaSpy = jest.spyOn(Listeners, 'getVisibilityApiAccess') }) @@ -564,7 +565,7 @@ describe('test session functionality', () => { activityState = ActivityState.default.current - expect.assertions(68) + expect.assertions(76) expect(setInterval).toHaveBeenCalledTimes(1) // from initial _checkSession call expect(clearInterval).toHaveBeenCalledTimes(1) expect(activityState.timeSpent).toEqual(0) @@ -665,6 +666,10 @@ describe('test session functionality', () => { return Utils.flushPromises() }) .then(() => { + expect(Identity.sync).toHaveBeenCalledTimes(1) + expect(ActivityState.default.updateSessionLength).toHaveBeenCalledTimes(1) + + expect(ActivityState.default.current.lastInterval).toEqual(1740) // 29m expect(setInterval).toHaveBeenCalledTimes(2) expect(clearInterval).toHaveBeenCalledTimes(3) @@ -723,16 +728,24 @@ describe('test session functionality', () => { return Utils.flushPromises() }) .then(() => { - goToForeground() - activityState = ActivityState.default.current expect(Identity.persist).toHaveBeenCalledTimes(15) expect(activityState.timeSpent).toEqual(720) // 2m + 4m + 6m expect(activityState.sessionLength).toEqual(2460) // 2m + (5m + 10m + 14m) + 4m + 6m - expect(activityState.lastInterval).toEqual(1860) // 31m - return Utils.flushPromises() + goToForeground() // immediately resolves Identity.sync promise + expect(Identity.sync).toHaveBeenCalledTimes(2) // it's a second time when going foreground + + return Promise.resolve() // resolving second promise from chain (corresponds to Identity.sync().then()) + .then(() => { + expect(ActivityState.default.updateSessionLength).toHaveBeenCalledTimes(2) + expect(ActivityState.default.current.lastActive).toEqual(currentTime) + expect(ActivityState.default.current.timeSpent).toEqual(720) // 2m + 4m + 6m + expect(ActivityState.default.current.sessionLength).toEqual(2460) // 2m + (5m + 10m + 14m) + 4m + 6m + expect(ActivityState.default.current.lastInterval).toEqual(1860) // 31m + }) + .then(Utils.flushPromises) // resolving pending promises }) .then(() => Storage.default.getFirst('activityState')) .then(record => { diff --git a/src/sdk/identity.js b/src/sdk/identity.js index c11fa30..d47301e 100644 --- a/src/sdk/identity.js +++ b/src/sdk/identity.js @@ -6,6 +6,7 @@ import {reload as reloadPreferences} from './preferences' import {REASON_GDPR} from './constants' import {isEmpty} from './utilities' import {disable, status} from './disable' +import {publish} from './pub-sub' type InterceptT = {| exists: boolean, @@ -133,9 +134,18 @@ function persist (): Promise { function sync (): Promise { return Storage.getFirst(_storeName) .then((activityState: ActivityStateMapT) => { - const lastActive = ActivityState.current.lastActive || 0 + const current = ActivityState.current + const lastActive = current.lastActive || 0 if (_isLive() && lastActive < activityState.lastActive) { + + // Checking if another SDK instance was installed while this one was in backgound + const installedUpdated = !current.installed && activityState.installed + const sessionCountUpdated = (current.sessionCount || 0) < (activityState.sessionCount || 0) + if (installedUpdated || sessionCountUpdated) { + publish('sdk:installed') + } + ActivityState.current = activityState reloadPreferences() } diff --git a/src/sdk/main.js b/src/sdk/main.js index 63a3ab9..f9247ac 100644 --- a/src/sdk/main.js +++ b/src/sdk/main.js @@ -11,7 +11,7 @@ import Config from './config' import Storage from './storage/storage' import Logger from './logger' import {run as queueRun, setOffline, clear as queueClear, destroy as queueDestroy} from './queue' -import {subscribe, destroy as pubSubDestroy} from './pub-sub' +import {subscribe, unsubscribe, destroy as pubSubDestroy} from './pub-sub' import {watch as sessionWatch, destroy as sessionDestroy} from './session' import {start, clear as identityClear, destroy as identityDestroy} from './identity' import {add, remove, removeAll, clear as globalParamsClear} from './global-params' @@ -43,6 +43,14 @@ let _options: ?InitOptionsT = null */ let _isStarted: boolean = false +/** + * Flag to mark if sdk is installed to delay public methods until SDK is ready to perform them + * + * @type {boolean} + * @private + */ +let _isInstalled: boolean = false + /** * Initiate the instance with parameters * @@ -326,11 +334,23 @@ function _continue (activityState: ActivityStateMapT): Promise { _isStarted = true if (isInstalled) { + _handleSdkInstalled() sharingDisableCheck() } }) } +/** + * Handles SDK installed and runs delayed tasks + */ +function _handleSdkInstalled () { + _isInstalled = true + + flush() + + unsubscribe('sdk:installed') +} + /** * Handle error coming from the chain of commands * @@ -382,6 +402,7 @@ function _start (options: InitOptionsT): void { listenersRegister() + subscribe('sdk:installed', _handleSdkInstalled) subscribe('sdk:shutdown', () => _shutdown(true)) subscribe('sdk:gdpr-forget-me', _handleGdprForgetMe) subscribe('sdk:third-party-sharing-opt-out', sharingDisableFinish) @@ -394,7 +415,6 @@ function _start (options: InitOptionsT): void { start() .then(_continue) .then(sdkClick) - .then(flush) .catch(_error) } @@ -423,7 +443,7 @@ function _preCheck (description: string, callback: () => mixed, {schedule, stopB } if (typeof callback === 'function') { - if (schedule && !_isStarted && (stopBeforeInit || Config.isInitialised())) { + if (schedule && !(_isInstalled && _isStarted) && (stopBeforeInit || Config.isInitialised())) { delay(callback, description) Logger.log(`Running ${description} is delayed until Adjust SDK is up`) } else { diff --git a/src/sdk/session.js b/src/sdk/session.js index fa60d6f..a560abe 100644 --- a/src/sdk/session.js +++ b/src/sdk/session.js @@ -142,10 +142,12 @@ function _handleBackground (): Promise { * @private */ function _handleForeground (): Promise { - ActivityState.updateSessionLength() - ActivityState.toForeground() - - return sync().then(_checkSession) + return sync() + .then(() => { + ActivityState.updateSessionLength() + ActivityState.toForeground() + }) + .then(_checkSession) } /** @@ -176,6 +178,7 @@ function _handleSessionRequestFinish (e: string, result: HttpSuccessResponseT | } ActivityState.updateInstalled() + publish('sdk:installed') return persist() } From e890c24e030873bec9382b5d643e80ae0dd6ebae Mon Sep 17 00:00:00 2001 From: YaroslavnaMatkova Date: Fri, 20 Nov 2020 16:32:56 +0300 Subject: [PATCH 12/27] Added an anchor link to the loading snippet (#64) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 130b952..4b7da20 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ This SDK can be used to track installs, sessions and events. Simply add the Adju Our sdk is exposed under all module definitions, so it works under CommonJS and AMD environments and is also available through global `Adjust` when loaded through CDN. -To lazy load the Adjust Web SDK through CDN paste the following snippet into the `` tag: +To lazy load the Adjust Web SDK through CDN paste the following snippet into the `` tag: ```html