From 72909c8d54fc0d342f454e6081c7151508c6b5a8 Mon Sep 17 00:00:00 2001 From: Karlie Li Date: Tue, 20 May 2025 09:57:41 -0700 Subject: [PATCH 1/3] update --- .../Tests/Unit/src/dbprovider.tests.ts | 1453 ++++++++--------- .../Unit/src/offlinebatchhandler.tests.ts | 1203 +++++++------- common/config/rush/npm-shrinkwrap.json | 997 +++-------- 3 files changed, 1433 insertions(+), 2220 deletions(-) diff --git a/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts b/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts index b805d84f3..fbbe6d1dd 100644 --- a/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts +++ b/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts @@ -65,10 +65,10 @@ export class OfflineDbProviderTests extends AITestClass { } }); - this.testCaseAsync({ + this.testCase({ name: "IndexedDbProvider: init with auto clean set to true", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: ()=>{ let provider = new IndexedDbProvider(); let itemCtx = this.core.getProcessTelContext(); let storageConfig = createDynamicConfig({autoClean: true}).cfg; @@ -83,26 +83,27 @@ export class OfflineDbProviderTests extends AITestClass { doAwait(provider.teardown(), () => { this.ctx.isclosed = true; }); - - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for init response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + return true; + } + return false; + }, "Wait for init response" + new Date().toISOString(), 200, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + + } }); - this.testCaseAsync({ + this.testCase({ name: "IndexedDbProvider: addEvent with no previous stored events", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); let itemCtx = this.core.getProcessTelContext(); @@ -115,67 +116,65 @@ export class OfflineDbProviderTests extends AITestClass { let evt = TestHelper.mockEvent(endpoint, 3, false); doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; + doAwait(provider.addEvent("", evt, itemCtx), (item) => { + this.ctx.evt = item; + Assert.deepEqual(item, evt, "should add expected item"); + Assert.ok(evt.id, "should add id to the item"); + this.preEvts.push(evt); + doAwait(provider.getNextBatch(), (item) => { + this.ctx.getEvt = item; + Assert.equal(item && item.length, 1, "should have one item"); + Assert.deepEqual((item as any)[0], evt, "should add expected item"); + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + }, (reason) => { + this.ctx.getEvtErr = reason; + Assert.ok(false, "error for get event") + }); + }, (reason) => { + this.ctx.addEventErr = reason; + Assert.ok(false, "error for add event"); + }); }, (reason)=> { this.ctx.initErr = reason; Assert.ok(false, "error for init"); }); - - doAwait(provider.addEvent("", evt, itemCtx), (item) => { - this.ctx.evt = item; - Assert.deepEqual(item, evt, "should add expected item"); - Assert.ok(evt.id, "should add id to the item"); - this.preEvts.push(evt); - }, (reason) => { - this.ctx.addEventErr = reason; - Assert.ok(false, "error for add event"); - }); - doAwait(provider.getNextBatch(), (item) => { - this.ctx.getEvt = item; - Assert.equal(item && item.length, 1, "should have one item"); - Assert.deepEqual((item as any)[0], evt, "should add expected item"); - }, (reason) => { - this.ctx.getEvtErr = reason; - Assert.ok(false, "error for get event") - }); - - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.evt; - if (item) { - return true; - } - - return false; - }, "Wait for add Event response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.getEvt; - if (item) { - return true; - } + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + return true; + } + return false; + }, "Wait for init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.evt; + if (item) { + return true; + } - return false; - }, "Wait for get Event response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000) as any) + return false; + }, "Wait for add Event response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.getEvt; + if (item) { + return true; + } + + return false; + }, "Wait for get Event response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + } }); - - this.testCaseAsync({ + + this.testCase({ name: "IndexedDbProvider: addEvent with previous stored events", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); let itemCtx = this.core.getProcessTelContext(); @@ -189,172 +188,163 @@ export class OfflineDbProviderTests extends AITestClass { let evt = TestHelper.mockEvent(endpoint, 3, false); doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; + doAwait(provider.getAllEvents(), (val) => { + this.ctx.preEvts = val; + Assert.equal(val && val.length, 1 , "should have the event from the previous test"); + Assert.equal((val as any)[0].id, this.preEvts[0].id, "should get back expected previous events"); + doAwait(provider.addEvent("", evt, itemCtx), (item) => { + this.ctx.evt = item; + Assert.equal(item, evt, "should have one event"); + doAwait(provider.getAllEvents(), (val) => { + this.ctx.allEvts = val; + Assert.equal(val && val.length, 2 , "should have the two events"); + Assert.deepEqual((val as any)[1], evt, "should get back expected added events"); + let evt1 = TestHelper.mockEvent(endpoint, 1, false); + let evt2 = TestHelper.mockEvent(endpoint, 2, false); + doAwait(provider.addEvent("", evt1, itemCtx), (item) => { + this.ctx.evt1 = item; + Assert.deepEqual(item, evt1, "should have expected event1"); + doAwait(provider.addEvent("", evt2, itemCtx), (item) => { + this.ctx.evt2 = item; + Assert.deepEqual(item, evt2, "should have expected event2"); + doAwait(provider.getAllEvents(), (val) => { + this.ctx.allEvts1 = val; + Assert.equal(val && (val as any).length, 4, "should have four events"); + doAwait(provider.getNextBatch(), (val) => { + this.ctx.nextBatch = val; + Assert.equal(val && (val as any).length, 1, "should return one event"); + Assert.deepEqual((val as any)[0], this.preEvts[0], "should have return the earliest event"); + doAwait(provider.getAllEvents(2), (val) => { + this.ctx.twoEvts = val; + Assert.equal(val && (val as any).length, 2, "should return two events"); + Assert.deepEqual((val as any)[0], this.preEvts[0], "should have return the earliest event1"); + doAwait(provider.clear(), (val) => { + this.ctx.clear = val; + Assert.equal(val && (val as any).length, 4, "should clear all events"); + this.preEvts = []; + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + }, (reason)=> { + this.ctx.clearErr = reason; + Assert.ok(false, "clear error"); + }); + + }, (reason)=> { + this.ctx.twoEvtsErr = reason; + Assert.ok(false, "get two events error"); + }); + }, (reason)=> { + this.ctx.nextBatchErr = reason; + Assert.ok(false, "get next batch error"); + }); + }, (reason)=> { + this.ctx.oneEvtsErr = reason; + Assert.ok(false, "get all events1 error"); + }); + }, (reason) => { + this.ctx.addEvent2Err = reason; + Assert.ok(false, "add event2 error"); + }); + }, (reason) => { + this.ctx.addEvent1Err = reason; + Assert.ok(false, "add event1 error"); + }); + }, (reason)=> { + this.ctx.allEvtsErr = reason; + Assert.ok(false, "get all events error"); + }); + }, (reason) => { + this.ctx.addEventErr = reason; + Assert.ok(false, "add event error"); + }); + }, (reason)=> { + this.ctx.preEvtsErr = reason; + Assert.ok(false, "get previous events error"); + }); + }, (reason)=> { this.ctx.initErr = reason; Assert.ok(false, "init error"); }); - doAwait(provider.getAllEvents(), (val) => { - this.ctx.preEvts = val; - Assert.equal(val && val.length, 1 , "should have the event from the previous test"); - Assert.equal((val as any)[0].id, this.preEvts[0].id, "should get back expected previous events"); - }, (reason)=> { - this.ctx.preEvtsErr = reason; - Assert.ok(false, "get previous events error"); - }); - - - doAwait(provider.addEvent("", evt, itemCtx), (item) => { - this.ctx.evt = item; - Assert.equal(item, evt, "should have one event"); - }, (reason) => { - this.ctx.addEventErr = reason; - Assert.ok(false, "add event error"); - }); - doAwait(provider.getAllEvents(), (val) => { - this.ctx.allEvts = val; - Assert.equal(val && val.length, 2 , "should have the two events"); - Assert.deepEqual((val as any)[1], evt, "should get back expected added events"); - }, (reason)=> { - this.ctx.allEvtsErr = reason; - Assert.ok(false, "get all events error"); - }); - - - let evt1 = TestHelper.mockEvent(endpoint, 1, false); - let evt2 = TestHelper.mockEvent(endpoint, 2, false); - doAwait(provider.addEvent("", evt1, itemCtx), (item) => { - this.ctx.evt1 = item; - Assert.deepEqual(item, evt1, "should have expected event1"); - }, (reason) => { - this.ctx.addEvent1Err = reason; - Assert.ok(false, "add event1 error"); - }); - doAwait(provider.addEvent("", evt2, itemCtx), (item) => { - this.ctx.evt2 = item; - Assert.deepEqual(item, evt2, "should have expected event2"); - }, (reason) => { - this.ctx.addEvent2Err = reason; - Assert.ok(false, "add event2 error"); - }); - - doAwait(provider.getAllEvents(), (val) => { - this.ctx.allEvts1 = val; - Assert.equal(val && (val as any).length, 4, "should have four events"); - }, (reason)=> { - this.ctx.oneEvtsErr = reason; - Assert.ok(false, "get all events1 error"); - }); - - doAwait(provider.getNextBatch(), (val) => { - this.ctx.nextBatch = val; - Assert.equal(val && (val as any).length, 1, "should return one event"); - Assert.deepEqual((val as any)[0], this.preEvts[0], "should have return the earliest event"); - }, (reason)=> { - this.ctx.nextBatchErr = reason; - Assert.ok(false, "get next batch error"); - }); - - doAwait(provider.getAllEvents(2), (val) => { - this.ctx.twoEvts = val; - Assert.equal(val && (val as any).length, 2, "should return two events"); - Assert.deepEqual((val as any)[0], this.preEvts[0], "should have return the earliest event1"); - }, (reason)=> { - this.ctx.twoEvtsErr = reason; - Assert.ok(false, "get two events error"); - }); + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + return true; + } + return false; + }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.preEvts; + if (item) { + return true; + } + + return false; + }, "Wait for get previous Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.evt; + if (item) { + return true; + } + + return false; + }, "Wait for add Event response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.allEvts; + if (item) { + return true; + } + + return false; + }, "Wait for get all Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item1 = this.ctx.evt1; + let item2 = this.ctx.evt2; + if (item1 && item2) { + return true; + } + + return false; + }, "Wait for add all Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let items = this.ctx.allEvts1; + if (items) { + return true; + } + + return false; + }, "Wait for get all Events1 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let items = this.ctx.nextBatch; + if (items && items.length == 1) { + return true; + } + + return false; + }, "Wait for get next Batch response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let items = this.ctx.twoEvts; + if (items && items.length == 2) { + return true; + } + + return false; + }, "Wait for get two Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.clear; + if (item) { + return true; + } + return false; + }, "Wait for clear response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + } - doAwait(provider.clear(), (val) => { - this.ctx.clear = val; - Assert.equal(val && (val as any).length, 4, "should clear all events"); - this.preEvts = []; - }, (reason)=> { - this.ctx.clearErr = reason; - Assert.ok(false, "clear error"); - }); - - - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.preEvts; - if (item) { - return true; - } - - return false; - }, "Wait for get previous Events response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.evt; - if (item) { - return true; - } - - return false; - }, "Wait for add Event response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.allEvts; - if (item) { - return true; - } - - return false; - }, "Wait for get all Events response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item1 = this.ctx.evt1; - let item2 = this.ctx.evt2; - if (item1 && item2) { - return true; - } - - return false; - }, "Wait for add all Events response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let items = this.ctx.allEvts1; - if (items) { - return true; - } - - return false; - }, "Wait for get all Events1 response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let items = this.ctx.nextBatch; - if (items && items.length == 1) { - return true; - } - - return false; - }, "Wait for get next Batch response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let items = this.ctx.twoEvts; - if (items && items.length == 2) { - return true; - } - - return false; - }, "Wait for get two Events response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.clear; - if (item) { - return true; - } - return false; - }, "Wait for clear response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000) as any) }); - - - this.testCaseAsync({ + this.testCase({ name: "IndexedDbProvider: getAllEvents should handle cursor errors", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); let itemCtx = this.core.getProcessTelContext(); @@ -367,81 +357,85 @@ export class OfflineDbProviderTests extends AITestClass { let evt = TestHelper.mockEvent(endpoint, 3, false); doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; + doAwait(provider.addEvent("", evt, itemCtx), (item) => { + this.ctx.evt = item; + let ctx = provider["_getDbgPlgTargets"](); + let db = ctx[3]; + this.sandbox.stub(db as any, "openDb").callsFake((name, ver, func, change?) => { + return createAsyncPromise((resolve, reject)=> { + try { + let openDbCtx = { + openCursor: (var1, var2, var3?) => { + return createAsyncRejectedPromise(new Error("open cursor mock error")); + } + } + // Database has been opened + doAwait(func(openDbCtx), resolve, reject); + } catch (e) { + reject(e); + } + }); + }); + doAwait(provider.getNextBatch(), (val) => { + this.ctx.nextBatch = val; + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + }, (reason)=> { + this.ctx.nextBatchErr = reason; + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + }); + }, (reason) => { + this.ctx.addEventErr = reason; + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + }) }, (reason)=> { this.ctx.initErr = reason; Assert.ok(false, "error for init"); - }); - - doAwait(provider.addEvent("", evt, itemCtx), (item) => { - this.ctx.evt = item; - }, (reason) => { - this.ctx.addEventErr = reason; - }); - - let ctx = provider["_getDbgPlgTargets"](); - let db = ctx[3]; - this.sandbox.stub(db as any, "openDb").callsFake((name, ver, func, change?) => { - return createAsyncPromise((resolve, reject)=> { - try { - let openDbCtx = { - openCursor: (var1, var2, var3?) => { - return createAsyncRejectedPromise(new Error("open cursor mock error")); - } - } - // Database has been opened - doAwait(func(openDbCtx), resolve, reject); - } catch (e) { - reject(e); - } - + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; }); }); - doAwait(provider.getNextBatch(), (val) => { - this.ctx.nextBatch = val; - }, (reason)=> { - this.ctx.nextBatchErr = reason; - }); - - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.evt; - if (item) { - return true; - } - - return false; - }, "Wait for add Event response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.nextBatchErr; - if (item) { - Assert.equal(item.message, "open cursor mock error"); - return true; - } - - return false; - }, "Wait for handle error response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + return true; + } + return false; + }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.evt; + if (item) { + return true; + } + + return false; + }, "Wait for add Event response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.nextBatchErr; + if (item) { + Assert.equal(item.message, "open cursor mock error"); + return true; + } + + return false; + }, "Wait for handle error response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + } }); - - this.testCaseAsync({ + this.testCase({ name: "IndexedDbProvider: removeEvents should delete expected events", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { this.core.addNotificationListener({ offlineBatchDrop: (cnt, reason)=> { this.batchDrop.push({cnt: cnt, reason: reason}); @@ -460,142 +454,139 @@ export class OfflineDbProviderTests extends AITestClass { let evt = TestHelper.mockEvent(endpoint, 3, false); doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; - }, (reason)=> { - this.ctx.initErr = reason; - Assert.ok(false, "error for init"); - }); - - doAwait(provider.removeEvents([evt]), (item) => { - this.ctx.removeEvts = item; - Assert.deepEqual(item && item.length, 0,"should not delete any events"); - }, (reason) => { - this.ctx.removeEvtsErr = reason; - Assert.ok(false, "error for remove events"); - }); - - let evt1 = TestHelper.mockEvent(endpoint, 1, false); - let evt2 = TestHelper.mockEvent(endpoint, 2, false); - let evt4 = TestHelper.mockEvent(endpoint, 4, false); - doAwait(provider.addEvent("", evt, itemCtx), (item) => { - this.ctx.evt = item; - Assert.deepEqual(item, evt, "should add exepcted evt"); - doAwait(provider.addEvent("", evt1, itemCtx), (item) => { - this.ctx.evt1 = item; - Assert.deepEqual(item, evt1, "should add exepcted evt1"); - doAwait(provider.addEvent("", evt2, itemCtx), (item) => { - this.ctx.evt2 = item; - Assert.deepEqual(item, evt2, "should add exepcted evt2"); - doAwait(provider.getAllEvents(), (val) => { - this.ctx.allEvts = val; - Assert.deepEqual(val && val.length, 3, "should have all expected 3 events"); - doAwait(provider.removeEvents([evt4]), (item) => { - this.ctx.removeEvts1 = item; - Assert.deepEqual(item && item.length, 0, "should not delete event1"); - doAwait(provider.removeEvents([evt, evt1]), (item) => { - this.ctx.removeEvts2 = item; - Assert.deepEqual(item && item.length, 2, "should delete all expected events"); - Assert.deepEqual((item as any)[0], evt, "should have deleted all event"); - Assert.deepEqual((item as any)[1], evt1, "should have deleted all event1"); - doAwait(provider.getAllEvents(), (val) => { - this.ctx.allEvts1 = val; - Assert.deepEqual(val && val.length, 1, "should have one event remaining"); - Assert.deepEqual((val as any)[0], evt2, "should have evt2"); - }, (reason)=> { - this.ctx.allEvts1Err = reason; - Assert.ok(false, "error for get all evts1"); + doAwait(provider.removeEvents([evt]), (item) => { + this.ctx.removeEvts = item; + Assert.deepEqual(item && item.length, 0,"should not delete any events"); + let evt1 = TestHelper.mockEvent(endpoint, 1, false); + let evt2 = TestHelper.mockEvent(endpoint, 2, false); + let evt4 = TestHelper.mockEvent(endpoint, 4, false); + doAwait(provider.addEvent("", evt, itemCtx), (item) => { + this.ctx.evt = item; + Assert.deepEqual(item, evt, "should add exepcted evt"); + doAwait(provider.addEvent("", evt1, itemCtx), (item) => { + this.ctx.evt1 = item; + Assert.deepEqual(item, evt1, "should add exepcted evt1"); + doAwait(provider.addEvent("", evt2, itemCtx), (item) => { + this.ctx.evt2 = item; + Assert.deepEqual(item, evt2, "should add exepcted evt2"); + doAwait(provider.getAllEvents(), (val) => { + this.ctx.allEvts = val; + Assert.deepEqual(val && val.length, 3, "should have all expected 3 events"); + doAwait(provider.removeEvents([evt4]), (item) => { + this.ctx.removeEvts1 = item; + Assert.deepEqual(item && item.length, 0, "should not delete event1"); + doAwait(provider.removeEvents([evt, evt1]), (item) => { + this.ctx.removeEvts2 = item; + Assert.deepEqual(item && item.length, 2, "should delete all expected events"); + Assert.deepEqual((item as any)[0], evt, "should have deleted all event"); + Assert.deepEqual((item as any)[1], evt1, "should have deleted all event1"); + doAwait(provider.getAllEvents(), (val) => { + this.ctx.allEvts1 = val; + Assert.deepEqual(val && val.length, 1, "should have one event remaining"); + Assert.deepEqual((val as any)[0], evt2, "should have evt2"); + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + }, (reason)=> { + this.ctx.allEvts1Err = reason; + Assert.ok(false, "error for get all evts1"); + }); + }, (reason) => { + this.ctx.removeEvts2Err = reason; + Assert.ok(false, "error for remove events2"); + }); + }, (reason) => { + this.ctx.removeEvts1Err = reason; + Assert.ok(false, "error for remove events1"); }); - }, (reason) => { - this.ctx.removeEvts2Err = reason; - Assert.ok(false, "error for remove events2"); + }, (reason)=> { + this.ctx.allEvtsErr = reason; + Assert.ok(false, "error for get all events"); + }); }, (reason) => { - this.ctx.removeEvts1Err = reason; - Assert.ok(false, "error for remove events1"); + this.ctx.addEvent2Err = reason; + Assert.ok(false, "error for add event 2"); }); - }, (reason)=> { - this.ctx.allEvtsErr = reason; - Assert.ok(false, "error for get all events"); - + }, (reason) => { + this.ctx.addEvent1Err = reason; + Assert.ok(false, "error for add event 1"); }); }, (reason) => { - this.ctx.addEvent2Err = reason; - Assert.ok(false, "error for add event 2"); + this.ctx.addEventErr = reason; + Assert.ok(false, "error for add events"); }); + }, (reason) => { - this.ctx.addEvent1Err = reason; - Assert.ok(false, "error for add event 1"); + this.ctx.removeEvtsErr = reason; + Assert.ok(false, "error for remove events"); }); - }, (reason) => { - this.ctx.addEventErr = reason; - Assert.ok(false, "error for add events"); - }); - - - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; + }, (reason)=> { + this.ctx.initErr = reason; + Assert.ok(false, "error for init"); }); + + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + return true; + } + return false; + }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let items = this.ctx.removeEvts; - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let items = this.ctx.removeEvts; - - if (items) { - return true; - } - - return false; - }, "Wait for remove evt response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let items = this.ctx.allEvts; + if (items) { + return true; + } + + return false; + }, "Wait for remove evt response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let items = this.ctx.allEvts; - if (items) { - return true; - } - - return false; - }, "Wait for get Events response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item1 = this.ctx.removeEvts1; - if (item1) { - return true; - } - - return false; - }, "Wait for remove Event1 response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let items2 = this.ctx.removeEvts2; + if (items) { + return true; + } + + return false; + }, "Wait for get Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item1 = this.ctx.removeEvts1; + if (item1) { + return true; + } + + return false; + }, "Wait for remove Event1 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let items2 = this.ctx.removeEvts2; - if (items2) { - return true; - } - - return false; - }, "Wait for remove event2 response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let items = this.ctx.allEvts1; - - if (items ) { - return true; - } - - return false; - }, "Wait for get Events1 response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - Assert.equal(this.batchDrop.length, 1, "notification should be called once"); // sent in clean process during initialization - Assert.equal(this.batchDrop[0].reason, 3, "notification should be called with expected reason time exceeded"); - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000) as any) + if (items2) { + return true; + } + + return false; + }, "Wait for remove event2 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let items = this.ctx.allEvts1; + + if (items ) { + return true; + } + + return false; + }, "Wait for get Events1 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + Assert.equal(this.batchDrop.length, 1, "notification should be called once"); // sent in clean process during initialization + Assert.equal(this.batchDrop[0].reason, 3, "notification should be called with expected reason time exceeded"); + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + } }); - - this.testCaseAsync({ + this.testCase({ name: "IndexedDbProvider: clear should delete all events", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); let itemCtx = this.core.getProcessTelContext(); @@ -608,96 +599,90 @@ export class OfflineDbProviderTests extends AITestClass { doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; + let evt = TestHelper.mockEvent(endpoint, 3, false); + let evt1 = TestHelper.mockEvent(endpoint, 1, false); + let evt2 = TestHelper.mockEvent(endpoint, 2, false); + doAwait(provider.addEvent("", evt, itemCtx), (item) => { + this.ctx.evt = item; + Assert.deepEqual(item, evt, "should add evt"); + doAwait(provider.addEvent("", evt1, itemCtx), (item) => { + this.ctx.evt1 = item; + Assert.deepEqual(item, evt1, "should add evt1"); + doAwait(provider.addEvent("", evt2, itemCtx), (item) => { + this.ctx.evt2 = item; + Assert.deepEqual(item, evt2, "should add evt2"); + doAwait(provider.clear(), (val)=> { + this.ctx.clearEvts = val; + Assert.ok(val && val.length >= 3, "should clear events"); // may have the events from previous test + doAwait(provider.getAllEvents(), (val) => { + this.ctx.allEvts1 = val; + Assert.equal(val && val.length, 0, "should not have any events" ); + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + }, (reason)=> { + this.ctx.allEvts1Err = reason; + Assert.ok(false, "get events error"); + }); + }, (reason)=> { + this.ctx.clearEvtsErr = reason; + Assert.ok(false, "error for clear"); + + }); + }, (reason) => { + this.ctx.addEvent2Err = reason; + Assert.ok(false, "error for add evt2"); + }); + }, (reason) => { + this.ctx.addEvent1Err = reason; + Assert.ok(false, "error for add evt1"); + }); + }, (reason) => { + this.ctx.addEventErr = reason; + Assert.ok(false, "error for add evt"); + }); }, (reason)=> { this.ctx.initErr = reason; Assert.ok(false, "error for init"); }); - - - let evt = TestHelper.mockEvent(endpoint, 3, false); - let evt1 = TestHelper.mockEvent(endpoint, 1, false); - let evt2 = TestHelper.mockEvent(endpoint, 2, false); - doAwait(provider.addEvent("", evt, itemCtx), (item) => { - this.ctx.evt = item; - Assert.deepEqual(item, evt, "should add evt"); - }, (reason) => { - this.ctx.addEventErr = reason; - Assert.ok(false, "error for add evt"); - }); - doAwait(provider.addEvent("", evt1, itemCtx), (item) => { - this.ctx.evt1 = item; - Assert.deepEqual(item, evt1, "should add evt1"); - }, (reason) => { - this.ctx.addEvent1Err = reason; - Assert.ok(false, "error for add evt1"); - }); - doAwait(provider.addEvent("", evt2, itemCtx), (item) => { - this.ctx.evt2 = item; - Assert.deepEqual(item, evt2, "should add evt2"); - }, (reason) => { - this.ctx.addEvent2Err = reason; - Assert.ok(false, "error for add evt2"); - }); - - - doAwait(provider.clear(), (val)=> { - this.ctx.clearEvts = val; - Assert.ok(val && val.length >= 3, "should clear events"); // may have the events from previous test - }, (reason)=> { - this.ctx.clearEvtsErr = reason; - Assert.ok(false, "error for clear"); - - }); - - doAwait(provider.getAllEvents(), (val) => { - this.ctx.allEvts1 = val; - Assert.equal(val && val.length, 0, "should not have any evnets" ); - }, (reason)=> { - this.ctx.allEvts1Err = reason; - Assert.ok(false, "get events error"); - }); - - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.evt; - let item1 = this.ctx.evt1; - let item2 = this.ctx.evt2; - if (item && item1 && item2) { - return true; - } - - return false; - }, "Wait for get Events response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let items = this.ctx.allEvts1; - - if (items && items.length == 0) { - return true; - } - - return false; - }, "Wait for get Events1 response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + return true; + } + return false; + }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.evt; + let item1 = this.ctx.evt1; + let item2 = this.ctx.evt2; + if (item && item1 && item2) { + return true; + } + + return false; + }, "Wait for get Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let items = this.ctx.allEvts1; + + if (items && items.length == 0) { + return true; + } + + return false; + }, "Wait for get Events1 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "IndexedDbProvider: clean should delete all events that exist longer than max storage time", - stepDelay: 100, + pollDelay: 100, useFakeTimers: true, - steps: [() => { + test: () => { this.core.addNotificationListener({ offlineBatchDrop: (cnt, reason)=> { this.batchDrop.push({cnt: cnt, reason: reason}); @@ -713,7 +698,7 @@ export class OfflineDbProviderTests extends AITestClass { endpoint: endpoint, notificationMgr: this.core.getNotifyMgr() }; - + doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; }, (reason)=> { @@ -774,180 +759,61 @@ export class OfflineDbProviderTests extends AITestClass { Assert.ok(false, "get all events error") }); - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let items = this.ctx.allEvts; - let cnt = 0; - if (items && items.length == 3) { - arrForEach(items, (item) => { - cnt += item.criticalCnt; - }) - Assert.equal(cnt, 6, "should get expected three events"); - return true; - } - - return false; - }, "Wait for get Events response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.cleanEvts; - - if (item) { - return true; - } - - return false; - }, "Wait for clean Events response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let items = this.ctx.allEvts1; - - if (items) { - return true; - } - - return false; - }, "Wait for get Events1 response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - Assert.equal(this.batchDrop.length, 1, "notification should be called once"); - Assert.equal(this.batchDrop[0].cnt, 2, "notification should be called with 2 count"); - Assert.equal(this.batchDrop[0].reason, 3, "notification should be called with expected reason clean time exceeded"); - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + return true; + } + return false; + }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let items = this.ctx.allEvts; + let cnt = 0; + if (items && items.length == 3) { + arrForEach(items, (item) => { + cnt += item.criticalCnt; + }) + Assert.equal(cnt, 6, "should get expected three events"); + return true; + } + + return false; + }, "Wait for get Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.cleanEvts; + + if (item) { + return true; + } + + return false; + }, "Wait for clean Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let items = this.ctx.allEvts1; + + if (items) { + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + return true; + } + + return false; + }, "Wait for get Events1 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + Assert.equal(this.batchDrop.length, 1, "notification should be called once"); + Assert.equal(this.batchDrop[0].cnt, 2, "notification should be called with 2 count"); + Assert.equal(this.batchDrop[0].reason, 3, "notification should be called with expected reason clean time exceeded"); + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "IndexedDbProvider: Error handle should handle open errors", - stepDelay: 100, - steps: [() => { - let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; - let provider = new IndexedDbProvider(); - let itemCtx = this.core.getProcessTelContext(); - let storageConfig = createDynamicConfig({autoClean: true}).cfg; - let providerCxt = { - itemCtx: itemCtx, - storageConfig: storageConfig, - endpoint: endpoint - }; - let evt = TestHelper.mockEvent(endpoint, 3, false); - doAwait(provider.initialize(providerCxt), (val) => { - this.ctx.isInit = val; - }, (reason)=> { - this.ctx.initErr = reason; - Assert.ok(false, "error for init"); - }); - let ctx = provider["_getDbgPlgTargets"](); - let db = ctx[3]; - this.sandbox.stub(db as any, "openDb").callsFake((key) => { - return createAsyncRejectedPromise(new Error("open db mock error")) - }); - - - doAwait(provider.addEvent("", evt, itemCtx), (item) => { - this.ctx.evt = item; - }, (reason) => { - this.ctx.addEventErr = reason; - }); - - doAwait(provider.removeEvents([evt]), (item) => { - this.ctx.removeEvt = item; - Assert.deepEqual(item, [], "should return []"); - }, (reason) => { - this.ctx.removeEvtErr = reason; - Assert.ok(false, "error for remove events"); - }); - - doAwait(provider.getAllEvents(), (item) => { - this.ctx.getEvts = item; - }, (reason) => { - this.ctx.getEvtsErr = reason; - }); - - doAwait(provider.clean(), (item) => { - this.ctx.cleanEvts = item; - Assert.ok(!item, "should not clean"); - }, (reason) => { - this.ctx.cleanEvtsErr = reason; - Assert.ok(false, "error for clean"); - }); - - doAwait(provider.clear(), (item) => { - this.ctx.clearEvts = item; - Assert.deepEqual(item, [], "should not clear"); - }, (reason) => { - this.ctx.clearEvtsErr = reason; - Assert.ok(false, "error for clean"); - }); - - - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.addEventErr; - if (item) { - Assert.equal(item.message, "open db mock error"); - return true; - } - - return false; - }, "Wait for add Event handle error response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.removeEvt; - if (item) { - return true; - } - - return false; - }, "Wait for remove Event handle error response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.getEvtsErr; - if (item) { - Assert.equal(item.message, "open db mock error"); - return true; - } - - return false; - }, "Wait for get all events handle error response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.cleanEvts; - if (item !== null) { - return true; - } - - return false; - }, "Wait for get clean events handle error response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.clearEvts; - if (item) { - return true; - } - - return false; - }, "Wait for get clear events handle error response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000) as any) - }); - - this.testCaseAsync({ - name: "IndexedDbProvider: Error handle should handle cursor errors", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + useFakeTimers: true, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); let itemCtx = this.core.getProcessTelContext(); @@ -960,139 +826,136 @@ export class OfflineDbProviderTests extends AITestClass { let evt = TestHelper.mockEvent(endpoint, 3, false); doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; - }, (reason)=> { - this.ctx.initErr = reason; - Assert.ok(false, "error for init"); - }); - - - - let ctx = provider["_getDbgPlgTargets"](); - let db = ctx[3]; - this.sandbox.stub(db as any, "openDb").callsFake((name, ver, func, change?) => { - return createAsyncPromise((resolve, reject)=> { - try { - let openDbCtx = { - openCursor: (var1, var2, var3?) => { - return createAsyncRejectedPromise(new Error("open cursor mock error")); - }, - openStore: (var1, var2, var3) => { - return createAsyncRejectedPromise(new Error("open store mock error")); + let ctx = provider["_getDbgPlgTargets"](); + let db = ctx[3]; + this.sandbox.stub(db as any, "openDb").callsFake((name, ver, func, change?) => { + return createAsyncPromise((resolve, reject)=> { + try { + let openDbCtx = { + openCursor: (var1, var2, var3?) => { + return createAsyncRejectedPromise(new Error("open cursor mock error")); + }, + openStore: (var1, var2, var3) => { + return createAsyncRejectedPromise(new Error("open store mock error")); + } } + // Database has been opened + doAwait(func(openDbCtx), resolve, reject); + } catch (e) { + reject(e); } - // Database has been opened - doAwait(func(openDbCtx), resolve, reject); - } catch (e) { - reject(e); - } + }); }); - }); - - doAwait(provider.addEvent("", evt, itemCtx), (item) => { - Assert.ok(false, "should handle add event error"); - }, (reason) => { - this.ctx.addEvent = reason; - Assert.equal(reason.message, "open store mock error", "add event message"); - }); - - doAwait(provider.getNextBatch(), (val) => { - Assert.ok(false, "should handle get next batch error") - }, (reason)=> { - this.ctx.nextBatch = reason; - Assert.equal(reason.message, "open cursor mock error", "get next batch message"); - }); - doAwait(provider.getAllEvents(), (val) => { - Assert.ok(false, "should handle get all events error") - }, (reason)=> { - this.ctx.allEvts = reason; - Assert.equal(reason.message, "open cursor mock error", "get all events message"); - }); - - doAwait(provider.removeEvents([evt]), (val) => { - this.ctx.removeEvts = val; - Assert.deepEqual([], val, "should handle remove events error") - }, (reason)=> { - this.ctx.removeEvtsErr = reason; - Assert.ok(false, "error for get next batch"); - }); - - doAwait(provider.clear(), (val) => { - this.ctx.clear = val; - Assert.deepEqual([], val, "should handle clear error") - }, (reason)=> { - this.ctx.clearErr = reason; - Assert.ok(false, "error for clear"); - }); - - doAwait(provider.clean(), (val) => { - this.ctx.clean = val; - Assert.ok(!val, "should handle clean error") + doAwait(provider.addEvent("", evt, itemCtx), (item) => { + this.ctx.evt = item; + Assert.ok(false, "should handle add event error"); + }, (reason) => { + this.ctx.addEvent = reason; + Assert.equal(reason.message, "open store mock error", "add event message"); + doAwait(provider.getNextBatch(), (val) => { + Assert.ok(false, "should handle get next batch error") + }, (reason)=> { + this.ctx.nextBatch = reason; + Assert.equal(reason.message, "open cursor mock error", "get next batch message"); + doAwait(provider.getAllEvents(), (val) => { + Assert.ok(false, "should handle get all events error") + }, (reason)=> { + this.ctx.allEvts = reason; + Assert.equal(reason.message, "open cursor mock error", "get all events message") + doAwait(provider.removeEvents([evt]), (val) => { + this.ctx.removeEvts = val; + Assert.deepEqual([], val, "should handle remove events error") + doAwait(provider.clear(), (val) => { + this.ctx.clear = val; + Assert.deepEqual([], val, "should handle clear error") + doAwait(provider.clean(), (val) => { + this.ctx.clean = val; + Assert.ok(!val, "should handle clean error") + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + }, (reason)=> { + this.ctx.cleanErr = reason; + Assert.ok(false, "error for clean"); + }); + }, (reason)=> { + this.ctx.clearErr = reason; + Assert.ok(false, "error for clear"); + }); + }, (reason)=> { + this.ctx.removeEvtsErr = reason; + Assert.ok(false, "error for get next batch"); + }); + }); + }); + + }) }, (reason)=> { - this.ctx.cleanErr = reason; - Assert.ok(false, "error for clean"); - }); - - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; + this.ctx.initErr = reason; + Assert.ok(false, "error for init"); + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); }); - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.addEvent; - if (item) { - return true; - } - - return false; - }, "Wait for add Event response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.nextBatch ; - if (item) { - return true; - } - - return false; - }, "Wait for next batch response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.allEvts; - if (item) { - return true; - } - - return false; - }, "Wait for all events response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.removeEvts; - if (item) { - return true; - } - - return false; - }, "Wait for remove events response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.clear; - if (item) { - return true; - } - - return false; - }, "Wait for clear response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.clean; - if (item !== null) { - return true; - } - - return false; - }, "Wait for clean response" + new Date().toISOString(), 30, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + return true; + } + return false; + }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.addEvent; + if (item) { + return true; + } + + return false; + }, "Wait for add Event response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.nextBatch; + if (item) { + return true; + } + + return false; + }, "Wait for next batch response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.allEvts; + if (item) { + return true; + } + + return false; + }, "Wait for all events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.removeEvts; + if (item) { + return true; + } + + return false; + }, "Wait for remove events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.clear; + if (item) { + return true; + } + + return false; + }, "Wait for clear response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.clean; + if (item !== null) { + return true; + } + + return false; + }, "Wait for clean response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + } }); } diff --git a/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts b/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts index f28efe5fa..40ddcd4e1 100644 --- a/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts +++ b/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts @@ -64,10 +64,10 @@ export class OfflineBatchHandlerTests extends AITestClass { } }); - this.testCaseAsync({ + this.testCase({ name: "Offline Batch Handler: init with IndexedDB storge provider", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.IndexedDb], autoClean: true, inStorageMaxTime: 1 } as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -86,33 +86,34 @@ export class OfflineBatchHandlerTests extends AITestClass { let isInit = items[1]; Assert.ok(provider, "provider is initialized"); Assert.ok(isInit, "initialization is successful"); + doAwait(batchHandler.teardown(),(res) => { + this.ctx.isclosed = true; + }); }); - doAwait(batchHandler.teardown(),(res) => { - this.ctx.isclosed = true; - }); - + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + + return true; + } + return false; + }, "Wait for init response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 15, 1000)) - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - - return true; - } - return false; - }, "Wait for init response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000) as any) + } + }); - this.testCaseAsync({ + this.testCase({ name: "Store Batch: store batch with web storge provider", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true } as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -142,56 +143,53 @@ export class OfflineBatchHandlerTests extends AITestClass { doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { this.ctx.storeBatch = true; this.ctx.result = result; + doAwait(batchHandler.hasStoredBatch(),(res) => { + this.ctx.hasBatch = res; + doAwait( batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }); + }); }); + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let storeBatch = this.ctx.storeBatch; + if (storeBatch) { + let res = this.ctx.result[0]; + let state = res.state == eBatchStoreStatus.Success; + Assert.ok(state, "state should be ok"); + let item = res.item; + Assert.ok(item.id, "item id should be set"); + Assert.equal(item.criticalCnt, 1, "expected item should be returned"); - doAwait(batchHandler.hasStoredBatch(),(res) => { - this.ctx.hasBatch = res; - }); - - - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch) { - let res = this.ctx.result[0]; - let state = res.state == eBatchStoreStatus.Success; - Assert.ok(state, "state should be ok"); - let item = res.item; - Assert.ok(item.id, "item id should be set"); - Assert.equal(item.criticalCnt, 1, "expected item should be returned"); - - let storageKey = "AIOffline_1_dc.services.visualstudio.com"; - let storageStr = AITestClass.orgLocalStorage.getItem(storageKey) as any; - let storageObject = JSON.parse(storageStr); - let storageEvts = storageObject.evts; - Assert.deepEqual(Object.keys(storageEvts).length, 1, "storgae should only have one event"); - Assert.ok(storageEvts[item.id], "storgae should contain expected item"); - - return true; - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let hasBatch = this.ctx.hasBatch; - if (hasBatch) { - return true; - } - return false; - }, "Wait for has batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000) as any) + let storageKey = "AIOffline_1_dc.services.visualstudio.com"; + let storageStr = AITestClass.orgLocalStorage.getItem(storageKey) as any; + let storageObject = JSON.parse(storageStr); + let storageEvts = storageObject.evts; + Assert.deepEqual(Object.keys(storageEvts).length, 1, "storgae should only have one event"); + Assert.ok(storageEvts[item.id], "storgae should contain expected item"); + + return true; + } + return false; + }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let hasBatch = this.ctx.hasBatch; + if (hasBatch) { + return true; + } + return false; + }, "Wait for has batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 15, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "Store Batch: store batch with indexedDB storge provider", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.IndexedDb], autoClean: true, inStorageMaxTime:1} as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -210,69 +208,63 @@ export class OfflineBatchHandlerTests extends AITestClass { let isInit = items[1]; Assert.ok(provider, "provider is initialized"); Assert.ok(isInit, "initialization is successful"); + let result:any[] = []; + let cb = (res) => { + this.ctx.storeBatch = true; + result.push(res); + } + let evt = TestHelper.mockEvent(endpoint, 1, false); + batchHandler.storeBatch(evt, cb); + doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { + this.ctx.storeBatch = true; + this.ctx.result = result; + doAwait(batchHandler.hasStoredBatch(),(res) => { + this.ctx.hasBatch = res; + doAwait( batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }); + }); + }); }); - - - let result:any[] = []; - let cb = (res) => { - this.ctx.storeBatch = true; - result.push(res); - } - let evt = TestHelper.mockEvent(endpoint, 1, false); - batchHandler.storeBatch(evt, cb); - doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { - this.ctx.storeBatch = true; - this.ctx.result = result; - }); - - - doAwait(batchHandler.hasStoredBatch(),(res) => { - this.ctx.hasBatch = res; - }); - - - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for init response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch) { - let res = this.ctx.result[0]; - let state = res.state == eBatchStoreStatus.Success; - Assert.ok(state, "state should be ok"); - let item = res.item; - Assert.ok(item.id, "item id should be set"); - Assert.equal(item.criticalCnt, 1, "expected item should be returned"); - - return true; - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let hasBatch = this.ctx.hasBatch; - if (hasBatch) { - return true; - } - return false; - }, "Wait for has batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + return true; + } + return false; + }, "Wait for init response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.asyncTaskPollingAssert(() => { + let storeBatch = this.ctx.storeBatch; + if (storeBatch) { + let res = this.ctx.result[0]; + let state = res.state == eBatchStoreStatus.Success; + Assert.ok(state, "state should be ok"); + let item = res.item; + Assert.ok(item.id, "item id should be set"); + Assert.equal(item.criticalCnt, 1, "expected item should be returned"); + + return true; + } + return false; + }, "Wait for store batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.asyncTaskPollingAssert(() => { + let hasBatch = this.ctx.hasBatch; + if (hasBatch) { + return true; + } + return false; + }, "Wait for has batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 15, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "Clean Batch: clean batch with web storge provider", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, inStorageMaxTime:1} as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -302,87 +294,80 @@ export class OfflineBatchHandlerTests extends AITestClass { doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { this.ctx.storeBatch = 1; this.ctx.result = result; - }); - - let evt1 = TestHelper.mockEvent(endpoint, 2, false); - doAwait(batchHandler.storeBatch(evt1, cb) as any,(res) => { - this.ctx.storeBatch = 2; - this.ctx.result = result; - }); - - let evt2 = TestHelper.mockEvent(endpoint, 3, false); - doAwait(batchHandler.storeBatch(evt2, cb) as any,(res) => { - this.ctx.storeBatch = 3; - this.ctx.result = result; - - }); - let storageKey = "AIOffline_1_dc.services.visualstudio.com"; - let storageStr = AITestClass.orgLocalStorage.getItem(storageKey) as any; - let storageObject = JSON.parse(storageStr); - let storageEvts = storageObject.evts; - Assert.deepEqual(Object.keys(storageEvts).length, 3, "storage should have three events"); - - let cb1 = (res) => { - this.ctx.hasBatch = res; - } - doAwait(batchHandler.hasStoredBatch(cb1),(res) => { + let evt1 = TestHelper.mockEvent(endpoint, 2, false); + doAwait(batchHandler.storeBatch(evt1, cb) as any,(res) => { + this.ctx.storeBatch = 2; + this.ctx.result = result; + let evt2 = TestHelper.mockEvent(endpoint, 3, false); + doAwait(batchHandler.storeBatch(evt2, cb) as any,(res) => { + this.ctx.storeBatch = 3; + this.ctx.result = result; + let storageKey = "AIOffline_1_dc.services.visualstudio.com"; + let storageStr = AITestClass.orgLocalStorage.getItem(storageKey) as any; + let storageObject = JSON.parse(storageStr); + let storageEvts = storageObject.evts; + Assert.deepEqual(Object.keys(storageEvts).length, 3, "storage should have three events"); + + let cb1 = (res) => { + this.ctx.hasBatch = res; + } + doAwait(batchHandler.hasStoredBatch(cb1),(res) => { + let cb2 = (res) => { + this.ctx.cleanBatch = true; + this.ctx.cleanBatchRes = res; + } + doAwait(batchHandler.cleanStorage(cb2) as any,(res) => { + doAwait( batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }); + }); + }); + }); + }); }); - - let cb2 = (res) => { - this.ctx.cleanBatch = true; - this.ctx.cleanBatchRes = res; - } - doAwait(batchHandler.cleanStorage(cb2) as any,(res) => { - - }); - - - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch && storeBatch > 2) { - Assert.equal(storeBatch, 3, "should have three response"); - let res = this.ctx.result; - Assert.equal(res.length, 3, "response should have three items"); - return true - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let hasBatch = this.ctx.hasBatch; - if (hasBatch) { - return true; - } - return false; - }, "Wait for has batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let cleanBatch = this.ctx.cleanBatch; - if (cleanBatch) { - let res = this.ctx.cleanBatchRes; - Assert.equal(res.batchCnt, 3, "should clean all three items"); - let storageKey = "AIOffline_1_dc.services.visualstudio.com"; - let storageStr = AITestClass.orgLocalStorage.getItem(storageKey) as any; - let storageObject = JSON.parse(storageStr); - let storageEvts = storageObject.evts; - Assert.deepEqual(Object.keys(storageEvts).length, 0, "storgae should not only have any event"); - return true; - } - return false; - }, "Wait for clean batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let storeBatch = this.ctx.storeBatch; + if (storeBatch && storeBatch > 2) { + Assert.equal(storeBatch, 3, "should have three response"); + let res = this.ctx.result; + Assert.equal(res.length, 3, "response should have three items"); + return true + } + return false; + }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let hasBatch = this.ctx.hasBatch; + if (hasBatch) { + return true; + } + return false; + }, "Wait for has batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let cleanBatch = this.ctx.cleanBatch; + if (cleanBatch) { + let res = this.ctx.cleanBatchRes; + Assert.equal(res.batchCnt, 3, "should clean all three items"); + let storageKey = "AIOffline_1_dc.services.visualstudio.com"; + let storageStr = AITestClass.orgLocalStorage.getItem(storageKey) as any; + let storageObject = JSON.parse(storageStr); + let storageEvts = storageObject.evts; + Assert.deepEqual(Object.keys(storageEvts).length, 0, "storgae should not only have any event"); + return true; + } + return false; + }, "Wait for clean batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 15, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "Clean Batch: clean batch with IndexedDB storge provider", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.IndexedDb], autoClean: true, inStorageMaxTime:1} as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -403,109 +388,100 @@ export class OfflineBatchHandlerTests extends AITestClass { let isInit = items[1]; Assert.ok(provider, "provider is initialized"); Assert.ok(isInit, "initialization is successful"); + let result:any[] = []; + let cb = (res) => { + result.push(res); + } + let evt = TestHelper.mockEvent(endpoint, 1, false); + doAwait(batchHandler.storeBatch(evt, cb),(res) => { + this.ctx.storeBatch = 1; + this.ctx.result = result; + let evt1 = TestHelper.mockEvent(endpoint, 2, false); + doAwait(batchHandler.storeBatch(evt1, cb),(res) => { + this.ctx.storeBatch = 2; + this.ctx.result = result; + let evt2 = TestHelper.mockEvent(endpoint, 3, false); + doAwait(batchHandler.storeBatch(evt2, cb),(res) => { + this.ctx.storeBatch = 3; + this.ctx.result = result; + let cb1 = (res) => { + this.ctx.hasBatch = res; + } + doAwait(batchHandler.hasStoredBatch(cb1),(res) => { + let cb2 = (res) => { + this.ctx.cleanBatch = true; + this.ctx.cleanBatchRes = res; + } + doAwait(batchHandler.cleanStorage(cb2),(res) => { + let cb3 = (res) => { + this.ctx.hasBatch1Called = true; + this.ctx.hasBatch1 = res; + } + doAwait(batchHandler.hasStoredBatch(cb3),(res) => { + doAwait( batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }); + }); + + }); + + }); + + }); + }); + }); }); - - let result:any[] = []; - let cb = (res) => { - result.push(res); - } - let evt = TestHelper.mockEvent(endpoint, 1, false); - doAwait(batchHandler.storeBatch(evt, cb),(res) => { - this.ctx.storeBatch = 1; - this.ctx.result = result; - }); - - let evt1 = TestHelper.mockEvent(endpoint, 2, false); - doAwait(batchHandler.storeBatch(evt1, cb),(res) => { - this.ctx.storeBatch = 2; - this.ctx.result = result; - }); - - let evt2 = TestHelper.mockEvent(endpoint, 3, false); - doAwait(batchHandler.storeBatch(evt2, cb),(res) => { - this.ctx.storeBatch = 3; - this.ctx.result = result; - - }); - - let cb1 = (res) => { - this.ctx.hasBatch = res; - } - doAwait(batchHandler.hasStoredBatch(cb1),(res) => { - - }); - - let cb2 = (res) => { - this.ctx.cleanBatch = true; - this.ctx.cleanBatchRes = res; - } - doAwait(batchHandler.cleanStorage(cb2),(res) => { - - }); - - let cb3 = (res) => { - this.ctx.hasBatch1Called = true; - this.ctx.hasBatch1 = res; - } - doAwait(batchHandler.hasStoredBatch(cb3),(res) => { - - }); - - - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for int response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch && storeBatch > 2) { - Assert.equal(storeBatch, 3, "should have three response"); - let res = this.ctx.result; - Assert.equal(res.length, 3, "response should have three items"); - return true - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let hasBatch = this.ctx.hasBatch; - if (hasBatch) { - return true; - } - return false; - }, "Wait for has batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let cleanBatch = this.ctx.cleanBatch; - if (cleanBatch) { - let res = this.ctx.cleanBatchRes; - Assert.equal(res.batchCnt, 3, "should clean all three items"); - return true; - } - return false; - }, "Wait for clean batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let hasBatch1Called = this.ctx.hasBatch1Called; - if (hasBatch1Called) { - let hasBatch = this.ctx.hasBatch1; - Assert.equal(hasBatch, false, "should not contain any events") - return true; - } - return false; - }, "Wait for has batch1 response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let isInit = this.ctx.isInit; + if (isInit) { + return true; + } + return false; + }, "Wait for int response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let storeBatch = this.ctx.storeBatch; + if (storeBatch && storeBatch > 2) { + Assert.equal(storeBatch, 3, "should have three response"); + let res = this.ctx.result; + Assert.equal(res.length, 3, "response should have three items"); + return true + } + return false; + }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let hasBatch = this.ctx.hasBatch; + if (hasBatch) { + return true; + } + return false; + }, "Wait for has batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let cleanBatch = this.ctx.cleanBatch; + if (cleanBatch) { + let res = this.ctx.cleanBatchRes; + Assert.equal(res.batchCnt, 3, "should clean all three items"); + return true; + } + return false; + }, "Wait for clean batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let hasBatch1Called = this.ctx.hasBatch1Called; + if (hasBatch1Called) { + let hasBatch = this.ctx.hasBatch1; + Assert.equal(hasBatch, false, "should not contain any events") + return true; + } + return false; + }, "Wait for has batch1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 15, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "Send Next Batch: send Next Batch with web storge provider", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -532,161 +508,154 @@ export class OfflineBatchHandlerTests extends AITestClass { let evt2 = TestHelper.mockEvent(endpoint, 3, false); doAwait(batchHandler.storeBatch(evt),(res) => { this.ctx.storeBatch = 1; + doAwait(batchHandler.storeBatch(evt1),(res) => { + this.ctx.storeBatch = 2; + doAwait(batchHandler.storeBatch(evt2),(res) => { + this.ctx.storeBatch = 3; + let sender1Payload: any[] = [] + let sender1 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { + sender1Payload.push(payload); + oncomplete(400, {}); + } + // 200 should be called first, in some case, re-try will be added back (sender2) and event2 will be returned again + // This is to guarantee the test gets events in order + let sender2Payload: any[] = [] + let sender2 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { + sender2Payload.push(payload); + oncomplete(200, {}); + } + let sender3Payload: any[] = [] + let sender3 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { + sender3Payload.push(payload); + oncomplete(500, {}); + } + + let res1: any[] = []; + let cb1 = (res) => { + res1.push(res); + } + doAwait(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { + this.ctx.sendBatch1 = true; + this.ctx.sendBatch1Res = res1; + this.ctx.sendBatch1Pd = sender1Payload; + let res2: any[] = []; + let cb2 = (res) => { + res2.push(res); + } + + doAwait(batchHandler.sendNextBatch(cb2, false, {sendPOST: sender2}) as any,(res) => { + this.ctx.sendBatch2 = true; + this.ctx.sendBatch2Res = res2; + this.ctx.sendBatch2Pd = sender2Payload; + let res3: any[] = []; + let cb3 = (res) => { + res3.push(res); + } + doAwait(batchHandler.sendNextBatch(cb3, false, {sendPOST: sender3}) as any,(res) => { + this.ctx.sendBatch3 = true; + this.ctx.sendBatch3Res = res3; + this.ctx.sendBatch3Pd = sender3Payload; + let cb4 = (res) => { + this.ctx.hasBatch1Called = true; + this.ctx.hasBatch1 = res && res.length >= 1; + } + doAwait(batchHandler.hasStoredBatch(cb4),(res) => { + doAwait( batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }); + }); + }); + }); + }); + }); + }); }); - doAwait(batchHandler.storeBatch(evt1),(res) => { - this.ctx.storeBatch = 2; - }); - doAwait(batchHandler.storeBatch(evt2),(res) => { - this.ctx.storeBatch = 3; - }); - - let sender1Payload: any[] = [] - let sender1 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { - sender1Payload.push(payload); - oncomplete(400, {}); - } - // 200 should be called first, in some case, re-try will be added back (sender2) and event2 will be returned again - // This is to guarantee the test gets events in order - let sender2Payload: any[] = [] - let sender2 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { - sender2Payload.push(payload); - oncomplete(200, {}); - } - let sender3Payload: any[] = [] - let sender3 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { - sender3Payload.push(payload); - oncomplete(500, {}); - } - - let res1: any[] = []; - let cb1 = (res) => { - res1.push(res); - } - doAwait(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { - this.ctx.sendBatch1 = true; - this.ctx.sendBatch1Res = res1; - this.ctx.sendBatch1Pd = sender1Payload; - }); - - let res2: any[] = []; - let cb2 = (res) => { - res2.push(res); - } - - doAwait(batchHandler.sendNextBatch(cb2, false, {sendPOST: sender2}) as any,(res) => { - this.ctx.sendBatch2 = true; - this.ctx.sendBatch2Res = res2; - this.ctx.sendBatch2Pd = sender2Payload; - }); - - let res3: any[] = []; - let cb3 = (res) => { - res3.push(res); - } - doAwait(batchHandler.sendNextBatch(cb3, false, {sendPOST: sender3}) as any,(res) => { - this.ctx.sendBatch3 = true; - this.ctx.sendBatch3Res = res3; - this.ctx.sendBatch3Pd = sender3Payload; - }); - - - - let cb4 = (res) => { - this.ctx.hasBatch1Called = true; - this.ctx.hasBatch1 = res && res.length >= 1; - } - doAwait(batchHandler.hasStoredBatch(cb4),(res) => { + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let storeBatch = this.ctx.storeBatch; + if (storeBatch && storeBatch == 3) { + return true; + } + return false; + }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let sendBatch = this.ctx.sendBatch1; + let res = this.ctx.sendBatch1Res; + let payload = this.ctx.sendBatch1Pd - }); - - - - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch && storeBatch == 3) { - return true; - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let sendBatch = this.ctx.sendBatch1; - let res = this.ctx.sendBatch1Res; - let payload = this.ctx.sendBatch1Pd - - if (sendBatch) { - Assert.equal(res.length, 1, "response 1 should be called once"); - let res1 = res[0]; - Assert.equal(res1.state, eBatchSendStatus.Drop, "response 1 state should be drop"); - Assert.ok(res1.data, "response 1 should have data"); - Assert.equal(res1.data.criticalCnt, 1 ,"response 1 should have expected data"); - - Assert.equal(payload.length, 1, "payload 1 should be called once"); - let payload1 = payload[0]; - Assert.equal(payload1.criticalCnt, 1 , "payload 1 should be contain expected item"); - return true; - } - return false; - }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let sendBatch = this.ctx.sendBatch2; - let res = this.ctx.sendBatch2Res; - let payload = this.ctx.sendBatch2Pd - - if (sendBatch) { - Assert.equal(res.length, 1, "response 2 should be called once"); - let res1 = res[0]; - Assert.equal(res1.state, eBatchSendStatus.Complete, "response 2 state should be retry"); - Assert.ok(res1.data, "response 2 should have data"); - Assert.equal(res1.data.criticalCnt, 2 ,"response 2 should have expected data"); - - Assert.equal(payload.length, 1, "payload 2 should be called once"); - let payload1 = payload[0]; - Assert.equal(payload1.criticalCnt, 2 , "payload 2 should be contain expected item"); + if (sendBatch) { + Assert.equal(res.length, 1, "response 1 should be called once"); + let res1 = res[0]; + Assert.equal(res1.state, eBatchSendStatus.Drop, "response 1 state should be drop"); + Assert.ok(res1.data, "response 1 should have data"); + Assert.equal(res1.data.criticalCnt, 1 ,"response 1 should have expected data"); + + Assert.equal(payload.length, 1, "payload 1 should be called once"); + let payload1 = payload[0]; + Assert.equal(payload1.criticalCnt, 1 , "payload 1 should be contain expected item"); + return true; + } + return false; + }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let sendBatch = this.ctx.sendBatch2; + let res = this.ctx.sendBatch2Res; + let payload = this.ctx.sendBatch2Pd - return true; - } - return false; - }, "Wait for send batch 2 response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let sendBatch = this.ctx.sendBatch3; - let res = this.ctx.sendBatch3Res; - let payload = this.ctx.sendBatch3Pd - - if (sendBatch) { - Assert.equal(res.length, 1, "response 3 should be called once"); - let res1 = res[0]; - Assert.equal(res1.state, eBatchSendStatus.Retry, "response 3 state should be complete"); - Assert.ok(res1.data, "response 3 should have data"); - Assert.equal(res1.data.criticalCnt, 3 ,"response 3 should have expected data"); + if (sendBatch) { + Assert.equal(res.length, 1, "response 2 should be called once"); + let res1 = res[0]; + Assert.equal(res1.state, eBatchSendStatus.Complete, "response 2 state should be retry"); + Assert.ok(res1.data, "response 2 should have data"); + Assert.equal(res1.data.criticalCnt, 2 ,"response 2 should have expected data"); + + Assert.equal(payload.length, 1, "payload 2 should be called once"); + let payload1 = payload[0]; + Assert.equal(payload1.criticalCnt, 2 , "payload 2 should be contain expected item"); + + return true; + } + return false; + }, "Wait for send batch 2 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let sendBatch = this.ctx.sendBatch3; + let res = this.ctx.sendBatch3Res; + let payload = this.ctx.sendBatch3Pd + + if (sendBatch) { + Assert.equal(res.length, 1, "response 3 should be called once"); + let res1 = res[0]; + Assert.equal(res1.state, eBatchSendStatus.Retry, "response 3 state should be complete"); + Assert.ok(res1.data, "response 3 should have data"); + Assert.equal(res1.data.criticalCnt, 3 ,"response 3 should have expected data"); + + Assert.equal(payload.length, 1, "payload 3 nshould be called once"); + let payload1 = payload[0]; + Assert.equal(payload1.criticalCnt, 3 , "payload 3 should be contain expected item"); + return true; + } + return false; + }, "Wait for send batch 3 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let hasBatch1Called = this.ctx.hasBatch1Called; + if (hasBatch1Called) { + let hasBatch = this.ctx.hasBatch1; + Assert.equal(hasBatch, false, "should not contain any events") + return true; + } + return false; + }, "Wait for has batch1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let isclosed = this.ctx.isclosed; + if (isclosed) { + return true; + } + return false; + }, "Wait for close response" + new Date().toISOString(), 15, 1000)) - Assert.equal(payload.length, 1, "payload 3 nshould be called once"); - let payload1 = payload[0]; - Assert.equal(payload1.criticalCnt, 3 , "payload 3 should be contain expected item"); - return true; - } - return false; - }, "Wait for send batch 3 response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let hasBatch1Called = this.ctx.hasBatch1Called; - if (hasBatch1Called) { - let hasBatch = this.ctx.hasBatch1; - Assert.equal(hasBatch, false, "should not contain any events") - return true; - } - return false; - }, "Wait for has batch1 response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000) as any) + } + }); - this.testCaseAsync({ + + this.testCase({ name: "Send Next Batch: send Next Batch with IndexedDB provider", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: ()=> { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.IndexedDb], autoClean: false, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -714,72 +683,71 @@ export class OfflineBatchHandlerTests extends AITestClass { let evt2 = TestHelper.mockEvent(endpoint, 3, false); doAwait(batchHandler.storeBatch(evt),(res) => { this.ctx.storeBatch = 1; - }); - doAwait(batchHandler.storeBatch(evt1),(res) => { - this.ctx.storeBatch = 2; - }); - doAwait(batchHandler.storeBatch(evt2),(res) => { - this.ctx.storeBatch = 3; - }); - - let sender1Payload: any[] = [] - let sender1 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { - sender1Payload.push(payload); - oncomplete(400, {}); - } - let res1: any[] = []; - - let cb1 = (res) => { - res1.push(res); - } - - - doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { - this.ctx.sendBatch1 = true; - this.ctx.sendBatch1Res = res1; - this.ctx.sendBatch1Pd = sender1Payload; - Assert.equal(res.value.state, eBatchSendStatus.Drop, "should have drop status"); - doAwaitResponse(provider.getAllEvents(), (res)=> { - this.ctx.getAll = true; - let val = res.value; - Assert.equal(val && val.length, 2, "should have 2 events"); - let sentcriticalCnt = res1[0].data.criticalCnt; - arrForEach(val, (item) => { - Assert.ok(sentcriticalCnt !== item.criticalCnt, "should not contain deleted item"); + doAwait(batchHandler.storeBatch(evt1),(res) => { + this.ctx.storeBatch = 2; + doAwait(batchHandler.storeBatch(evt2),(res) => { + this.ctx.storeBatch = 3; + let sender1Payload: any[] = [] + let sender1 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { + sender1Payload.push(payload); + oncomplete(400, {}); + } + let res1: any[] = []; + + let cb1 = (res) => { + res1.push(res); + } + + doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { + this.ctx.sendBatch1 = true; + this.ctx.sendBatch1Res = res1; + this.ctx.sendBatch1Pd = sender1Payload; + Assert.equal(res.value.state, eBatchSendStatus.Drop, "should have drop status"); + doAwaitResponse(provider.getAllEvents(), (res)=> { + this.ctx.getAll = true; + let val = res.value; + Assert.equal(val && val.length, 2, "should have 2 events"); + let sentcriticalCnt = res1[0].data.criticalCnt; + arrForEach(val, (item) => { + Assert.ok(sentcriticalCnt !== item.criticalCnt, "should not contain deleted item"); + }); + }); + + }); }); }); - }); - - }].concat(PollingAssert.createPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch && storeBatch == 3) { - return true; - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let sendBatch = this.ctx.sendBatch1; + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let storeBatch = this.ctx.storeBatch; + if (storeBatch && storeBatch == 3) { + return true; + } + return false; + }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let sendBatch = this.ctx.sendBatch1; + + if (sendBatch) { - if (sendBatch) { - - return true; - } - return false; - }, "Wait for send send batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.getAll; - - if (item) { - - return true; - } - return false; - }, "Wait for get all response" + new Date().toISOString(), 15, 1000) as any) + return true; + } + return false; + }, "Wait for send send batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.getAll; + + if (item) { + + return true; + } + return false; + }, "Wait for get all response" + new Date().toISOString(), 15, 1000)) + + } }); - this.testCaseAsync({ + this.testCase({ name: "Send Next Batch: send Next Batch with IndexedDB provider test1 with retry code", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let batchHandler = this.batchHandler; this.ctx.isInit = true; this.ctx.handler = batchHandler; @@ -824,29 +792,29 @@ export class OfflineBatchHandlerTests extends AITestClass { }); }); + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { - - }].concat(PollingAssert.createPollingAssert(() => { - let sendBatch = this.ctx.sendBatch1; - - if (sendBatch) { - return true; - } - return false; - }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.getAll; - - if (item) { - return true; - } - return false; - }, "Wait for get all response" + new Date().toISOString(), 15, 1000) as any) + let sendBatch = this.ctx.sendBatch1; + + if (sendBatch) { + return true; + } + return false; + }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.getAll; + + if (item) { + return true; + } + return false; + }, "Wait for get all response" + new Date().toISOString(), 15, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "Send Next Batch: send Next Batch with IndexedDB provider test1 with 200", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let batchHandler = this.batchHandler; this.ctx.isInit = true; this.ctx.handler = batchHandler; @@ -885,29 +853,28 @@ export class OfflineBatchHandlerTests extends AITestClass { }); }); - - - }].concat(PollingAssert.createPollingAssert(() => { - let sendBatch = this.ctx.sendBatch1; - - if (sendBatch) { - return true; - } - return false; - }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.getAll; - - if (item) { - return true; - } - return false; - }, "Wait for get all response" + new Date().toISOString(), 15, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let sendBatch = this.ctx.sendBatch1; + + if (sendBatch) { + return true; + } + return false; + }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.getAll; + + if (item) { + return true; + } + return false; + }, "Wait for get all response" + new Date().toISOString(), 15, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "Send Next Batch: send Next Batch with IndexedDB provider test1 with unload events", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageKey = "AIOffline_1_dc.services.visualstudio.com"; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; @@ -965,29 +932,29 @@ export class OfflineBatchHandlerTests extends AITestClass { }); }); - - }].concat(PollingAssert.createPollingAssert(() => { - let sendBatch = this.ctx.sendBatch1; - - if (sendBatch) { - return true; - } - return false; - }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.getAll; - - if (item) { - return true; - } - return false; - }, "Wait for get all response" + new Date().toISOString(), 15, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let sendBatch = this.ctx.sendBatch1; + + if (sendBatch) { + return true; + } + return false; + }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.getAll; + + if (item) { + return true; + } + return false; + }, "Wait for get all response" + new Date().toISOString(), 15, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "Send Next Batch: Error handle store batch", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -1030,21 +997,21 @@ export class OfflineBatchHandlerTests extends AITestClass { }); - - }].concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.storeBatch; - - if (item) { - return true; - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.storeBatch; + + if (item) { + return true; + } + return false; + }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "Send Next Batch: Error handle clean batch", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -1083,26 +1050,25 @@ export class OfflineBatchHandlerTests extends AITestClass { Assert.equal(item?.batchCnt, 0, "should have expected state"); Assert.equal(res1.length, 1, "should call callback"); Assert.equal(res1[0].batchCnt, item?.batchCnt, "should call callback with expected response"); + batchHandler.teardown(); }); - batchHandler.teardown(); - - - }].concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.clearBatch; - - if (item) { - return true; - } - return false; - }, "Wait for clear batch response" + new Date().toISOString(), 15, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.clearBatch; + + if (item) { + return true; + } + return false; + }, "Wait for clear batch response" + new Date().toISOString(), 15, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "Send Next Batch: Error handle add batch with remove error", - stepDelay: 100, - steps: [() => { + pollDelay: 1000, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -1151,25 +1117,23 @@ export class OfflineBatchHandlerTests extends AITestClass { Assert.equal(item?.data.message, "remove mock error" , "should have expected message"); Assert.equal(res1.length, 1, "should call callback"); Assert.equal(res1[0].state, item?.state, "should call callback with expected response"); + batchHandler.teardown(); }); - batchHandler.teardown(); - - - }].concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.addBatch; - - if (item) { - return true; - } - return false; - }, "Wait for add batch response" + new Date().toISOString(), 15, 1000) as any) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.addBatch; + if (item) { + return true; + } + return false; + }, "Wait for add batch response" + new Date().toISOString(), 15, 1000)) + } }); - this.testCaseAsync({ + this.testCase({ name: "Send Next Batch: Error handle add batch", - stepDelay: 100, - steps: [() => { + pollDelay: 100, + test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; let storageConfig = createDynamicConfig(storageObj).cfg; @@ -1213,21 +1177,20 @@ export class OfflineBatchHandlerTests extends AITestClass { Assert.equal(item?.data.message, "get mock error" , "should have expected message"); Assert.equal(res1.length, 1, "should call callback again"); Assert.equal(res1[0].state, item?.state, "should call callback with expected response"); + batchHandler.teardown(); }); - batchHandler.teardown(); - - - }].concat(PollingAssert.createPollingAssert(() => { - let item = this.ctx.getBatch; - - if (item) { - return true; - } - return false; - }, "Wait for get batch response" + new Date().toISOString(), 15, 1000) as any) + + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + let item = this.ctx.getBatch; + + if (item) { + return true; + } + return false; + }, "Wait for get batch response" + new Date().toISOString(), 15, 1000)) + } }); - } } diff --git a/common/config/rush/npm-shrinkwrap.json b/common/config/rush/npm-shrinkwrap.json index 01878bf24..be79f5b8a 100644 --- a/common/config/rush/npm-shrinkwrap.json +++ b/common/config/rush/npm-shrinkwrap.json @@ -243,9 +243,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", "peer": true, "dependencies": { "@types/json-schema": "^7.0.15" @@ -293,6 +293,15 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "peer": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -312,12 +321,15 @@ } }, "node_modules/@eslint/js": { - "version": "9.26.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", - "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.27.0.tgz", + "integrity": "sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==", "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { @@ -330,12 +342,12 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", + "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", "peer": true, "dependencies": { - "@eslint/core": "^0.13.0", + "@eslint/core": "^0.14.0", "levn": "^0.4.1" }, "engines": { @@ -409,9 +421,9 @@ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@microsoft/api-extractor": { - "version": "7.52.7", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.7.tgz", - "integrity": "sha512-YLdPS644MfbLJt4hArP1WcldcaEUBh9wnFjcLEcQnVG0AMznbLh2sdE0F5Wr+w6+Lyp5/XUPvRAg3sYGSP3GCw==", + "version": "7.52.8", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.8.tgz", + "integrity": "sha512-cszYIcjiNscDoMB1CIKZ3My61+JOhpERGlGr54i6bocvGLrcL/wo9o+RNXMBrb7XgLtKaizZWUpqRduQuHQLdg==", "dependencies": { "@microsoft/api-extractor-model": "7.30.6", "@microsoft/tsdoc": "~0.15.1", @@ -477,27 +489,6 @@ "resolve": "~1.22.2" } }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.1.tgz", - "integrity": "sha512-9LfmxKTb1v+vUS1/emSk1f5ePmTLkb9Le9AxOB5T0XM59EUumwcS45z05h7aiZx3GI0Bl7mjb3FMEglYj+acuQ==", - "peer": true, - "dependencies": { - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.3", - "eventsource": "^3.0.2", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@nevware21/grunt-eslint-ts": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/@nevware21/grunt-eslint-ts/-/grunt-eslint-ts-0.2.5.tgz", @@ -544,9 +535,9 @@ } }, "node_modules/@nevware21/ts-utils": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.12.3.tgz", - "integrity": "sha512-3GQDdX2Xmy1smEyR/U4FUTGEaL7fbGT8kU5tyfRz1CLZ+bM1smhKMth0NvVQNAh+qfYEtUBGCAWrARe4iMq5iQ==" + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.12.4.tgz", + "integrity": "sha512-+q7Do/7RvVU3IpM1AzHJ3BePyPXZNXXe1FVJcWqndKzMUGo20TFbu9hR+3KY0dbRwO1OR6QAmQqB1J/T+zJ4KQ==" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -601,9 +592,9 @@ } }, "node_modules/@puppeteer/browsers/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "bin": { "semver": "bin/semver.js" }, @@ -1772,18 +1763,18 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.0.tgz", - "integrity": "sha512-/jU9ettcntkBFmWUzzGgsClEi2ZFiikMX5eEQsmxIAWMOn4H3D4rvHssstmAHGVvrYnaMqdWWWg0b5M6IN/MTQ==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz", + "integrity": "sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==", "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.32.0", - "@typescript-eslint/type-utils": "8.32.0", - "@typescript-eslint/utils": "8.32.0", - "@typescript-eslint/visitor-keys": "8.32.0", + "@typescript-eslint/scope-manager": "8.32.1", + "@typescript-eslint/type-utils": "8.32.1", + "@typescript-eslint/utils": "8.32.1", + "@typescript-eslint/visitor-keys": "8.32.1", "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, @@ -1801,15 +1792,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.0.tgz", - "integrity": "sha512-B2MdzyWxCE2+SqiZHAjPphft+/2x2FlO9YBx7eKE1BCb+rqBlQdhtAEhzIEdozHd55DXPmxBdpMygFJjfjjA9A==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz", + "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.32.0", - "@typescript-eslint/types": "8.32.0", - "@typescript-eslint/typescript-estree": "8.32.0", - "@typescript-eslint/visitor-keys": "8.32.0", + "@typescript-eslint/scope-manager": "8.32.1", + "@typescript-eslint/types": "8.32.1", + "@typescript-eslint/typescript-estree": "8.32.1", + "@typescript-eslint/visitor-keys": "8.32.1", "debug": "^4.3.4" }, "engines": { @@ -1825,13 +1816,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.0.tgz", - "integrity": "sha512-jc/4IxGNedXkmG4mx4nJTILb6TMjL66D41vyeaPWvDUmeYQzF3lKtN15WsAeTr65ce4mPxwopPSo1yUUAWw0hQ==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz", + "integrity": "sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==", "peer": true, "dependencies": { - "@typescript-eslint/types": "8.32.0", - "@typescript-eslint/visitor-keys": "8.32.0" + "@typescript-eslint/types": "8.32.1", + "@typescript-eslint/visitor-keys": "8.32.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1842,13 +1833,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.0.tgz", - "integrity": "sha512-t2vouuYQKEKSLtJaa5bB4jHeha2HJczQ6E5IXPDPgIty9EqcJxpr1QHQ86YyIPwDwxvUmLfP2YADQ5ZY4qddZg==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz", + "integrity": "sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==", "peer": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.32.0", - "@typescript-eslint/utils": "8.32.0", + "@typescript-eslint/typescript-estree": "8.32.1", + "@typescript-eslint/utils": "8.32.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -1865,9 +1856,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.0.tgz", - "integrity": "sha512-O5Id6tGadAZEMThM6L9HmVf5hQUXNSxLVKeGJYWNhhVseps/0LddMkp7//VDkzwJ69lPL0UmZdcZwggj9akJaA==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.1.tgz", + "integrity": "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==", "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1878,13 +1869,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.0.tgz", - "integrity": "sha512-pU9VD7anSCOIoBFnhTGfOzlVFQIA1XXiQpH/CezqOBaDppRwTglJzCC6fUQGpfwey4T183NKhF1/mfatYmjRqQ==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz", + "integrity": "sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==", "peer": true, "dependencies": { - "@typescript-eslint/types": "8.32.0", - "@typescript-eslint/visitor-keys": "8.32.0", + "@typescript-eslint/types": "8.32.1", + "@typescript-eslint/visitor-keys": "8.32.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -1928,9 +1919,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "peer": true, "bin": { "semver": "bin/semver.js" @@ -1940,15 +1931,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.32.0.tgz", - "integrity": "sha512-8S9hXau6nQ/sYVtC3D6ISIDoJzS1NsCK+gluVhLN2YkBPX+/1wkwyUiDKnxRh15579WoOIyVWnoyIf3yGI9REw==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.32.1.tgz", + "integrity": "sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==", "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.32.0", - "@typescript-eslint/types": "8.32.0", - "@typescript-eslint/typescript-estree": "8.32.0" + "@typescript-eslint/scope-manager": "8.32.1", + "@typescript-eslint/types": "8.32.1", + "@typescript-eslint/typescript-estree": "8.32.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1963,12 +1954,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.0.tgz", - "integrity": "sha512-1rYQTCLFFzOI5Nl0c8LUpJT8HxpwVRn9E4CkMsYfuN6ctmQqExjSTzzSk0Tz2apmXy7WU6/6fyaZVVA/thPN+w==", + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz", + "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==", "peer": true, "dependencies": { - "@typescript-eslint/types": "8.32.0", + "@typescript-eslint/types": "8.32.1", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -2001,19 +1992,6 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "peer": true, - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/acorn": { "version": "8.14.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", @@ -2169,6 +2147,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/archiver-utils/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, "node_modules/archiver-utils/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2307,9 +2290,9 @@ "optional": true }, "node_modules/bare-fs": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.4.tgz", - "integrity": "sha512-r8+26Voz8dGX3AYpJdFb1ZPaUSM8XOLCZvy+YGpRTmwPHIxA7Z3Jov/oMPtV7hfRQbOnH8qGlLTzQAbgtdNN0Q==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.5.tgz", + "integrity": "sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==", "optional": true, "dependencies": { "bare-events": "^2.5.4", @@ -2404,26 +2387,6 @@ "readable-stream": "^3.4.0" } }, - "node_modules/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "peer": true, - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2506,44 +2469,6 @@ "node": "*" } }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2553,9 +2478,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001717", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001717.tgz", - "integrity": "sha512-auPpttCq6BDEG8ZAuHJIplGw6GODhjw+/11e7IjpnYCxZcW/ONgPs0KVBJ0d1bY3e2+7PRe5RCLyP+PfwVgkYw==", + "version": "1.0.30001718", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", + "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", "funding": [ { "type": "opencollective", @@ -2719,63 +2644,11 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "node_modules/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "peer": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "peer": true, - "engines": { - "node": ">=6.6.0" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "peer": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/cosmiconfig": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", @@ -2860,9 +2733,9 @@ } }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dependencies": { "ms": "^2.1.3" }, @@ -2979,29 +2852,15 @@ "node": ">=8" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.5.151", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.151.tgz", - "integrity": "sha512-Rl6uugut2l9sLojjS4H4SAr3A4IgACMLgpuEMPYCVcKydzfyPrn5absNRju38IhQOf/NwjJY8OGWjlteqYeBCA==" + "version": "1.5.155", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.155.tgz", + "integrity": "sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -3056,36 +2915,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -3132,23 +2961,22 @@ } }, "node_modules/eslint": { - "version": "9.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", - "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.27.0.tgz", + "integrity": "sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==", "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.20.0", "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.13.0", + "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.26.0", - "@eslint/plugin-kit": "^0.2.8", + "@eslint/js": "9.27.0", + "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", - "@modelcontextprotocol/sdk": "^1.8.0", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -3172,8 +3000,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "zod": "^3.24.2" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" @@ -3276,6 +3103,15 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "peer": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3393,27 +3229,6 @@ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==" }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", - "peer": true, - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz", - "integrity": "sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==", - "peer": true, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -3433,95 +3248,6 @@ "node": ">=0.10.0" } }, - "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "peer": true, - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", - "peer": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": "^4.11 || 5 || ^5.0.0-beta.1" - } - }, - "node_modules/express/node_modules/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", - "peer": true, - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "peer": true, - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3759,22 +3485,12 @@ "node": ">=0.10.0" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "peer": true, + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { - "node": ">= 0.8" + "node": ">= 0.6" } }, "node_modules/fs-constants": { @@ -3800,6 +3516,19 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3816,43 +3545,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "peer": true, - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -4013,23 +3705,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "engines": { + "node": ">= 4" + } + }, "node_modules/globrex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4231,18 +3919,6 @@ "node": ">=8" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -4386,9 +4062,10 @@ ] }, "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.4.tgz", + "integrity": "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==", + "peer": true, "engines": { "node": ">= 4" } @@ -4467,15 +4144,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "peer": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", @@ -4558,12 +4226,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "peer": true - }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -4603,9 +4265,9 @@ } }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "node_modules/isexe": { "version": "2.0.0", @@ -4730,6 +4392,11 @@ "node": ">= 0.6.3" } }, + "node_modules/lazystream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, "node_modules/lazystream/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -4943,15 +4610,6 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/mdast-util-to-hast": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", @@ -4977,27 +4635,6 @@ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" }, - "node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5124,27 +4761,6 @@ "node": ">=4" } }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "peer": true, - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", @@ -5172,15 +4788,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "peer": true }, - "node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/netmask": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", @@ -5201,11 +4808,6 @@ "path-to-regexp": "^1.7.0" } }, - "node_modules/nise/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, "node_modules/nise/node_modules/lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", @@ -5214,14 +4816,6 @@ "@sinonjs/commons": "^1.7.0" } }, - "node_modules/nise/node_modules/path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "dependencies": { - "isarray": "0.0.1" - } - }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -5275,18 +4869,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", @@ -5569,12 +5151,11 @@ } }, "node_modules/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "peer": true, - "engines": { - "node": ">=16" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "dependencies": { + "isarray": "0.0.1" } }, "node_modules/path-type": { @@ -5614,15 +5195,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pkce-challenge": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", - "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", - "peer": true, - "engines": { - "node": ">=16.20.0" - } - }, "node_modules/postcss": { "version": "7.0.39", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", @@ -5680,19 +5252,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "peer": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/proxy-agent": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", @@ -5777,21 +5336,6 @@ "node": ">=18" } }, - "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "peer": true, - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5835,21 +5379,6 @@ "node": ">= 0.6" } }, - "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "peer": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -6131,6 +5660,14 @@ "node": ">=8" } }, + "node_modules/rollup-plugin-copy/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "engines": { + "node": ">= 4" + } + }, "node_modules/rollup-plugin-copy/node_modules/is-plain-object": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", @@ -6253,22 +5790,6 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==" }, - "node_modules/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "peer": true, - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -6364,63 +5885,6 @@ } }, "node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "peer": true, - "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-static/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-static/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/serve-static/node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static/node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", @@ -6443,7 +5907,20 @@ "node": ">= 0.8.0" } }, - "node_modules/serve-static/node_modules/send/node_modules/encodeurl": { + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", @@ -6451,6 +5928,20 @@ "node": ">= 0.8" } }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -6492,78 +5983,6 @@ "@types/hast": "^3.0.4" } }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/sinon": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.5.0.tgz", @@ -6924,20 +6343,6 @@ "node": ">=4" } }, - "node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "peer": true, - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/typed-query-selector": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", @@ -7189,15 +6594,6 @@ "node": ">= 10.13.0" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", @@ -7302,14 +6698,14 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", - "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" } }, "node_modules/yargs": { @@ -7430,15 +6826,6 @@ "url": "https://github.com/sponsors/colinhacks" } }, - "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "peer": true, - "peerDependencies": { - "zod": "^3.24.1" - } - }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", From 79eda533926e3d76ee38887777fc30e1b7d056bd Mon Sep 17 00:00:00 2001 From: Karlie Li Date: Wed, 21 May 2025 09:23:46 -0700 Subject: [PATCH 2/3] update --- .../Tests/Unit/src/dbprovider.tests.ts | 775 +++++++++--------- .../Unit/src/offlinebatchhandler.tests.ts | 473 ++++++----- 2 files changed, 631 insertions(+), 617 deletions(-) diff --git a/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts b/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts index fbbe6d1dd..6a96b4d3b 100644 --- a/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts +++ b/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts @@ -80,12 +80,12 @@ export class OfflineDbProviderTests extends AITestClass { this.ctx.isInit = provider.initialize(providerCxt); this.ctx.provider = provider; - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { let isInit = this.ctx.isInit; if (isInit) { + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }) return true; } return false; @@ -102,7 +102,6 @@ export class OfflineDbProviderTests extends AITestClass { this.testCase({ name: "IndexedDbProvider: addEvent with no previous stored events", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); @@ -114,66 +113,51 @@ export class OfflineDbProviderTests extends AITestClass { endpoint: endpoint }; let evt = TestHelper.mockEvent(endpoint, 3, false); - doAwait(provider.initialize(providerCxt), (val) => { - this.ctx.isInit = val; + + return this._asyncQueue().add(() =>{ + doAwait(provider.initialize(providerCxt), (val) => { + this.ctx.isInit = val; + }, (reason)=> { + this.ctx.initErr = reason; + Assert.ok(false, "error for init"); + }); + + }).add(() => { doAwait(provider.addEvent("", evt, itemCtx), (item) => { this.ctx.evt = item; Assert.deepEqual(item, evt, "should add expected item"); Assert.ok(evt.id, "should add id to the item"); this.preEvts.push(evt); - doAwait(provider.getNextBatch(), (item) => { - this.ctx.getEvt = item; - Assert.equal(item && item.length, 1, "should have one item"); - Assert.deepEqual((item as any)[0], evt, "should add expected item"); - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - }, (reason) => { - this.ctx.getEvtErr = reason; - Assert.ok(false, "error for get event") - }); }, (reason) => { this.ctx.addEventErr = reason; - Assert.ok(false, "error for add event"); + Assert.ok(false, "error for addEvt"); }); - }, (reason)=> { - this.ctx.initErr = reason; - Assert.ok(false, "error for init"); - }); - - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.evt; - if (item) { - return true; - } - - return false; - }, "Wait for add Event response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.getEvt; - if (item) { - return true; - } - - return false; - }, "Wait for get Event response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + }).add(() => { + doAwait(provider.getNextBatch(), (item) => { + this.ctx.getEvt = item; + Assert.equal(item && item.length, 1, "should have one item"); + Assert.deepEqual((item as any)[0], evt, "should add expected item"); + }, (reason) => { + this.ctx.getEvtErr = reason; + Assert.ok(false, "error for get event"); + }); + }).add(() => { + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + Assert.ok(true, "should teardown provider"); + }); + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let isclosed = this.ctx.isclosed; if (isclosed) { return true; } return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + }, "Wait for close response" + new Date().toISOString(), 30, 1000)); } }); - + this.testCase({ name: "IndexedDbProvider: addEvent with previous stored events", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); @@ -184,166 +168,117 @@ export class OfflineDbProviderTests extends AITestClass { storageConfig: storageConfig, endpoint: endpoint }; - // should have the event added by the previous test + let evt = TestHelper.mockEvent(endpoint, 3, false); - doAwait(provider.initialize(providerCxt), (val) => { - this.ctx.isInit = val; + let evt1 = TestHelper.mockEvent(endpoint, 1, false); + let evt2 = TestHelper.mockEvent(endpoint, 2, false); + + return this._asyncQueue().add(() =>{ + doAwait(provider.initialize(providerCxt), (val) => { + this.ctx.isInit = val; + }, (reason)=> { + this.ctx.initErr = reason; + Assert.ok(false, "error for init"); + }); + + }).add(() => { doAwait(provider.getAllEvents(), (val) => { this.ctx.preEvts = val; Assert.equal(val && val.length, 1 , "should have the event from the previous test"); + Assert.ok((val as any)[0].id, "should have id"); Assert.equal((val as any)[0].id, this.preEvts[0].id, "should get back expected previous events"); - doAwait(provider.addEvent("", evt, itemCtx), (item) => { - this.ctx.evt = item; - Assert.equal(item, evt, "should have one event"); - doAwait(provider.getAllEvents(), (val) => { - this.ctx.allEvts = val; - Assert.equal(val && val.length, 2 , "should have the two events"); - Assert.deepEqual((val as any)[1], evt, "should get back expected added events"); - let evt1 = TestHelper.mockEvent(endpoint, 1, false); - let evt2 = TestHelper.mockEvent(endpoint, 2, false); - doAwait(provider.addEvent("", evt1, itemCtx), (item) => { - this.ctx.evt1 = item; - Assert.deepEqual(item, evt1, "should have expected event1"); - doAwait(provider.addEvent("", evt2, itemCtx), (item) => { - this.ctx.evt2 = item; - Assert.deepEqual(item, evt2, "should have expected event2"); - doAwait(provider.getAllEvents(), (val) => { - this.ctx.allEvts1 = val; - Assert.equal(val && (val as any).length, 4, "should have four events"); - doAwait(provider.getNextBatch(), (val) => { - this.ctx.nextBatch = val; - Assert.equal(val && (val as any).length, 1, "should return one event"); - Assert.deepEqual((val as any)[0], this.preEvts[0], "should have return the earliest event"); - doAwait(provider.getAllEvents(2), (val) => { - this.ctx.twoEvts = val; - Assert.equal(val && (val as any).length, 2, "should return two events"); - Assert.deepEqual((val as any)[0], this.preEvts[0], "should have return the earliest event1"); - doAwait(provider.clear(), (val) => { - this.ctx.clear = val; - Assert.equal(val && (val as any).length, 4, "should clear all events"); - this.preEvts = []; - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - }, (reason)=> { - this.ctx.clearErr = reason; - Assert.ok(false, "clear error"); - }); - - }, (reason)=> { - this.ctx.twoEvtsErr = reason; - Assert.ok(false, "get two events error"); - }); - }, (reason)=> { - this.ctx.nextBatchErr = reason; - Assert.ok(false, "get next batch error"); - }); - }, (reason)=> { - this.ctx.oneEvtsErr = reason; - Assert.ok(false, "get all events1 error"); - }); - }, (reason) => { - this.ctx.addEvent2Err = reason; - Assert.ok(false, "add event2 error"); - }); - }, (reason) => { - this.ctx.addEvent1Err = reason; - Assert.ok(false, "add event1 error"); - }); - }, (reason)=> { - this.ctx.allEvtsErr = reason; - Assert.ok(false, "get all events error"); - }); - }, (reason) => { - this.ctx.addEventErr = reason; - Assert.ok(false, "add event error"); - }); }, (reason)=> { this.ctx.preEvtsErr = reason; Assert.ok(false, "get previous events error"); }); - }, (reason)=> { - this.ctx.initErr = reason; - Assert.ok(false, "init error"); - }); - - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.preEvts; - if (item) { - return true; - } - - return false; - }, "Wait for get previous Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.evt; - if (item) { - return true; - } - - return false; - }, "Wait for add Event response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.allEvts; - if (item) { - return true; - } - - return false; - }, "Wait for get all Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item1 = this.ctx.evt1; - let item2 = this.ctx.evt2; - if (item1 && item2) { - return true; - } - - return false; - }, "Wait for add all Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let items = this.ctx.allEvts1; - if (items) { - return true; - } - - return false; - }, "Wait for get all Events1 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let items = this.ctx.nextBatch; - if (items && items.length == 1) { - return true; - } - - return false; - }, "Wait for get next Batch response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let items = this.ctx.twoEvts; - if (items && items.length == 2) { - return true; - } - - return false; - }, "Wait for get two Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.clear; - if (item) { - return true; - } - return false; - }, "Wait for clear response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { + }).add(() => { + doAwait(provider.addEvent("", evt, itemCtx), (item) => { + this.ctx.evt = item; + Assert.equal(item, evt, "should have one event"); + }, (reason)=> { + this.ctx.preEvtsErr = reason; + Assert.ok(false, "get previous events error"); + }); + }).add(() => { + doAwait(provider.getAllEvents(), (val) => { + this.ctx.allEvts = val; + Assert.equal(val && val.length, 2 , "should have the two events"); + Assert.deepEqual((val as any)[1], evt, "should get back expected added events"); + }, (reason) => { + this.ctx.addEventErr = reason; + Assert.ok(false, "add event error"); + }); + }).add(() => { + doAwait(provider.addEvent("", evt1, itemCtx), (item) => { + this.ctx.evt1 = item; + Assert.deepEqual(item, evt1, "should have expected event1"); + }, (reason) => { + this.ctx.addEvent1Err = reason; + Assert.ok(false, "add event1 error"); + }); + }).add(() => { + doAwait(provider.addEvent("", evt2, itemCtx), (item) => { + this.ctx.evt2 = item; + Assert.deepEqual(item, evt2, "should have expected event2"); + }, (reason) => { + this.ctx.addEvent2Err = reason; + Assert.ok(false, "add event2 error"); + }); + + }).add(() => { + doAwait(provider.getAllEvents(), (val) => { + this.ctx.allEvts1 = val; + Assert.equal(val && (val as any).length, 4, "should have four events"); + }, (reason)=> { + this.ctx.oneEvtsErr = reason; + Assert.ok(false, "get all events1 error"); + }); + + }).add(() => { + doAwait(provider.getNextBatch(), (val) => { + this.ctx.nextBatch = val; + Assert.equal(val && (val as any).length, 1, "should return one event"); + Assert.deepEqual((val as any)[0], this.preEvts[0], "should have return the earliest event"); + }, (reason)=> { + this.ctx.nextBatchErr = reason; + Assert.ok(false, "get next batch error"); + }); + }).add(() => { + doAwait(provider.getAllEvents(2), (val) => { + this.ctx.twoEvts = val; + Assert.equal(val && (val as any).length, 2, "should return two events"); + Assert.deepEqual((val as any)[0], this.preEvts[0], "should have return the earliest event1"); + }, (reason)=> { + this.ctx.twoEvtsErr = reason; + Assert.ok(false, "get two events error"); + }); + }).add(() => { + doAwait(provider.clear(), (val) => { + this.ctx.clear = val; + Assert.equal(val && (val as any).length, 4, "should clear all events"); + }, (reason)=> { + this.ctx.twoEvtsErr = reason; + Assert.ok(false, "get two events error"); + }); + }).add(() => { + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let isclosed = this.ctx.isclosed; if (isclosed) { + this.preEvts = [] return true; } return false; }, "Wait for close response" + new Date().toISOString(), 30, 1000)) } - }); + this.testCase({ name: "IndexedDbProvider: getAllEvents should handle cursor errors", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); @@ -355,53 +290,56 @@ export class OfflineDbProviderTests extends AITestClass { endpoint: endpoint }; let evt = TestHelper.mockEvent(endpoint, 3, false); - doAwait(provider.initialize(providerCxt), (val) => { - this.ctx.isInit = val; + + return this._asyncQueue().add(() =>{ + doAwait(provider.initialize(providerCxt), (val) => { + this.ctx.isInit = val; + }, (reason)=> { + this.ctx.initErr = reason; + Assert.ok(false, "error for init"); + }); + + }).add(() => { doAwait(provider.addEvent("", evt, itemCtx), (item) => { this.ctx.evt = item; - let ctx = provider["_getDbgPlgTargets"](); - let db = ctx[3]; - this.sandbox.stub(db as any, "openDb").callsFake((name, ver, func, change?) => { - return createAsyncPromise((resolve, reject)=> { - try { - let openDbCtx = { - openCursor: (var1, var2, var3?) => { - return createAsyncRejectedPromise(new Error("open cursor mock error")); - } - } - // Database has been opened - doAwait(func(openDbCtx), resolve, reject); - } catch (e) { - reject(e); - } - }); - }); - doAwait(provider.getNextBatch(), (val) => { - this.ctx.nextBatch = val; - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - }, (reason)=> { - this.ctx.nextBatchErr = reason; - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - }); }, (reason) => { this.ctx.addEventErr = reason; + Assert.ok(false, "add evt error"); doAwait(provider.teardown(), () => { this.ctx.isclosed = true; }); }) - }, (reason)=> { - this.ctx.initErr = reason; - Assert.ok(false, "error for init"); + + }).add(() => { + let ctx = provider["_getDbgPlgTargets"](); + let db = ctx[3]; + this.sandbox.stub(db as any, "openDb").callsFake((name, ver, func, change?) => { + return createAsyncPromise((resolve, reject)=> { + try { + let openDbCtx = { + openCursor: (var1, var2, var3?) => { + return createAsyncRejectedPromise(new Error("open cursor mock error")); + } + } + // Database has been opened + doAwait(func(openDbCtx), resolve, reject); + } catch (e) { + reject(e); + } + }); + }); + doAwait(provider.getNextBatch(), (val) => { + this.ctx.nextBatch = val; + Assert.ok(false, "should handle errors"); + }, (reason)=> { + this.ctx.nextBatchErr = reason; + }); + + }).add(() => { doAwait(provider.teardown(), () => { this.ctx.isclosed = true; }); - }); - - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let isInit = this.ctx.isInit; if (isInit) { return true; @@ -432,9 +370,9 @@ export class OfflineDbProviderTests extends AITestClass { } }); + this.testCase({ name: "IndexedDbProvider: removeEvents should delete expected events", - pollDelay: 1000, test: () => { this.core.addNotificationListener({ offlineBatchDrop: (cnt, reason)=> { @@ -452,81 +390,104 @@ export class OfflineDbProviderTests extends AITestClass { notificationMgr: this.core.getNotifyMgr() }; let evt = TestHelper.mockEvent(endpoint, 3, false); - doAwait(provider.initialize(providerCxt), (val) => { - this.ctx.isInit = val; + let evt1 = TestHelper.mockEvent(endpoint, 1, false); + let evt2 = TestHelper.mockEvent(endpoint, 2, false); + let evt4 = TestHelper.mockEvent(endpoint, 4, false); + + return this._asyncQueue().add(() => { + doAwait(provider.initialize(providerCxt), (val) => { + this.ctx.isInit = val; + }, (reason)=> { + this.ctx.initErr = reason; + Assert.ok(false, "error for init"); + }); + + }).add(() => { doAwait(provider.removeEvents([evt]), (item) => { this.ctx.removeEvts = item; Assert.deepEqual(item && item.length, 0,"should not delete any events"); - let evt1 = TestHelper.mockEvent(endpoint, 1, false); - let evt2 = TestHelper.mockEvent(endpoint, 2, false); - let evt4 = TestHelper.mockEvent(endpoint, 4, false); - doAwait(provider.addEvent("", evt, itemCtx), (item) => { - this.ctx.evt = item; - Assert.deepEqual(item, evt, "should add exepcted evt"); - doAwait(provider.addEvent("", evt1, itemCtx), (item) => { - this.ctx.evt1 = item; - Assert.deepEqual(item, evt1, "should add exepcted evt1"); - doAwait(provider.addEvent("", evt2, itemCtx), (item) => { - this.ctx.evt2 = item; - Assert.deepEqual(item, evt2, "should add exepcted evt2"); - doAwait(provider.getAllEvents(), (val) => { - this.ctx.allEvts = val; - Assert.deepEqual(val && val.length, 3, "should have all expected 3 events"); - doAwait(provider.removeEvents([evt4]), (item) => { - this.ctx.removeEvts1 = item; - Assert.deepEqual(item && item.length, 0, "should not delete event1"); - doAwait(provider.removeEvents([evt, evt1]), (item) => { - this.ctx.removeEvts2 = item; - Assert.deepEqual(item && item.length, 2, "should delete all expected events"); - Assert.deepEqual((item as any)[0], evt, "should have deleted all event"); - Assert.deepEqual((item as any)[1], evt1, "should have deleted all event1"); - doAwait(provider.getAllEvents(), (val) => { - this.ctx.allEvts1 = val; - Assert.deepEqual(val && val.length, 1, "should have one event remaining"); - Assert.deepEqual((val as any)[0], evt2, "should have evt2"); - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - }, (reason)=> { - this.ctx.allEvts1Err = reason; - Assert.ok(false, "error for get all evts1"); - }); - }, (reason) => { - this.ctx.removeEvts2Err = reason; - Assert.ok(false, "error for remove events2"); - }); - }, (reason) => { - this.ctx.removeEvts1Err = reason; - Assert.ok(false, "error for remove events1"); - }); - }, (reason)=> { - this.ctx.allEvtsErr = reason; - Assert.ok(false, "error for get all events"); - - }); - }, (reason) => { - this.ctx.addEvent2Err = reason; - Assert.ok(false, "error for add event 2"); - }); - }, (reason) => { - this.ctx.addEvent1Err = reason; - Assert.ok(false, "error for add event 1"); - }); - }, (reason) => { - this.ctx.addEventErr = reason; - Assert.ok(false, "error for add events"); - }); - }, (reason) => { this.ctx.removeEvtsErr = reason; Assert.ok(false, "error for remove events"); }); - }, (reason)=> { - this.ctx.initErr = reason; - Assert.ok(false, "error for init"); - }); - - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + + }).add(() => { + doAwait(provider.addEvent("", evt, itemCtx), (item) => { + this.ctx.evt = item; + Assert.deepEqual(item, evt, "should add exepcted evt"); + }, (reason) => { + this.ctx.addEventErr = reason; + Assert.ok(false, "error for add events"); + }); + }).add(() => { + doAwait(provider.addEvent("", evt1, itemCtx), (item) => { + this.ctx.evt1 = item; + Assert.deepEqual(item, evt1, "should add exepcted evt1"); + }, (reason) => { + this.ctx.addEvent1Err = reason; + Assert.ok(false, "error for add event 1"); + }); + }).add(() => { + doAwait(provider.addEvent("", evt2, itemCtx), (item) => { + this.ctx.evt2 = item; + Assert.deepEqual(item, evt2, "should add exepcted evt2"); + }, (reason) => { + this.ctx.addEvent2Err = reason; + Assert.ok(false, "error for add event 2"); + }); + + }).add(() => { + doAwait(provider.getAllEvents(), (val) => { + this.ctx.allEvts = val; + Assert.deepEqual(val && val.length, 3, "should have all expected 3 events"); + }, (reason)=> { + this.ctx.allEvtsErr = reason; + Assert.ok(false, "error for get all events"); + + }); + + }).add(() => { + doAwait(provider.removeEvents([evt4]), (item) => { + this.ctx.removeEvts1 = item; + Assert.deepEqual(item && item.length, 0, "should not delete event1"); + }, (reason) => { + this.ctx.removeEvts1Err = reason; + Assert.ok(false, "error for remove events1"); + }); + + }).add(()=> { + doAwait(provider.removeEvents([evt, evt1]), (item) => { + this.ctx.removeEvts2 = item; + Assert.deepEqual(item && item.length, 2, "should delete all expected events"); + let item1 = (item as any)[0]; + let item2 = (item as any)[1]; + if (item1.id == evt1.id) { + Assert.deepEqual(item1, evt1, "should have deleted all event"); + Assert.deepEqual(item2, evt, "should have deleted all event1"); + } else { + Assert.deepEqual(item1, evt, "should have deleted all event"); + Assert.deepEqual(item2, evt1, "should have deleted all event1"); + } + }, (reason) => { + this.ctx.removeEvts2Err = reason; + Assert.ok(false, "error for remove events2"); + }); + + }).add(() => { + doAwait(provider.getAllEvents(), (val) => { + this.ctx.allEvts1 = val; + Assert.deepEqual(val && val.length, 1, "should have one event remaining"); + Assert.deepEqual((val as any)[0], evt2, "should have evt2"); + }, (reason)=> { + this.ctx.allEvts1Err = reason; + Assert.ok(false, "error for get all evts1"); + }); + }).add(() => { + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let isInit = this.ctx.isInit; if (isInit) { return true; @@ -583,9 +544,9 @@ export class OfflineDbProviderTests extends AITestClass { } }); + this.testCase({ name: "IndexedDbProvider: clear should delete all events", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); @@ -596,56 +557,68 @@ export class OfflineDbProviderTests extends AITestClass { storageConfig: storageConfig, endpoint: endpoint }; + let evt = TestHelper.mockEvent(endpoint, 3, false); + let evt1 = TestHelper.mockEvent(endpoint, 1, false); + let evt2 = TestHelper.mockEvent(endpoint, 2, false); - doAwait(provider.initialize(providerCxt), (val) => { - this.ctx.isInit = val; - let evt = TestHelper.mockEvent(endpoint, 3, false); - let evt1 = TestHelper.mockEvent(endpoint, 1, false); - let evt2 = TestHelper.mockEvent(endpoint, 2, false); + return this._asyncQueue().add(() => { + doAwait(provider.initialize(providerCxt), (val) => { + this.ctx.isInit = val; + }, (reason)=> { + this.ctx.initErr = reason; + Assert.ok(false, "error for init"); + }); + + }).add(() => { doAwait(provider.addEvent("", evt, itemCtx), (item) => { this.ctx.evt = item; Assert.deepEqual(item, evt, "should add evt"); - doAwait(provider.addEvent("", evt1, itemCtx), (item) => { - this.ctx.evt1 = item; - Assert.deepEqual(item, evt1, "should add evt1"); - doAwait(provider.addEvent("", evt2, itemCtx), (item) => { - this.ctx.evt2 = item; - Assert.deepEqual(item, evt2, "should add evt2"); - doAwait(provider.clear(), (val)=> { - this.ctx.clearEvts = val; - Assert.ok(val && val.length >= 3, "should clear events"); // may have the events from previous test - doAwait(provider.getAllEvents(), (val) => { - this.ctx.allEvts1 = val; - Assert.equal(val && val.length, 0, "should not have any events" ); - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - }, (reason)=> { - this.ctx.allEvts1Err = reason; - Assert.ok(false, "get events error"); - }); - }, (reason)=> { - this.ctx.clearEvtsErr = reason; - Assert.ok(false, "error for clear"); - - }); - }, (reason) => { - this.ctx.addEvent2Err = reason; - Assert.ok(false, "error for add evt2"); - }); - }, (reason) => { - this.ctx.addEvent1Err = reason; - Assert.ok(false, "error for add evt1"); - }); }, (reason) => { this.ctx.addEventErr = reason; Assert.ok(false, "error for add evt"); }); - }, (reason)=> { - this.ctx.initErr = reason; - Assert.ok(false, "error for init"); - }); - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + }).add(() => { + doAwait(provider.addEvent("", evt1, itemCtx), (item) => { + this.ctx.evt1 = item; + Assert.deepEqual(item, evt1, "should add evt1"); + }, (reason) => { + this.ctx.addEvent1Err = reason; + Assert.ok(false, "error for add evt1"); + }); + + }).add(() => { + doAwait(provider.addEvent("", evt2, itemCtx), (item) => { + this.ctx.evt2 = item; + Assert.deepEqual(item, evt2, "should add evt2"); + }, (reason) => { + this.ctx.addEvent2Err = reason; + Assert.ok(false, "error for add evt2"); + }); + + }).add(() => { + doAwait(provider.clear(), (val)=> { + this.ctx.clearEvts = val; + Assert.ok(val && val.length >= 3, "should clear events"); // may have the events from previous test + }, (reason)=> { + this.ctx.clearEvtsErr = reason; + Assert.ok(false, "error for clear"); + + }); + + }).add(() => { + doAwait(provider.getAllEvents(), (val) => { + this.ctx.allEvts1 = val; + Assert.equal(val && val.length, 0, "should not have any events" ); + }, (reason)=> { + this.ctx.allEvts1Err = reason; + Assert.ok(false, "get events error"); + }); + }).add(() => { + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + }); + + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let isInit = this.ctx.isInit; if (isInit) { return true; @@ -811,7 +784,6 @@ export class OfflineDbProviderTests extends AITestClass { this.testCase({ name: "IndexedDbProvider: Error handle should handle open errors", - pollDelay: 1000, useFakeTimers: true, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; @@ -824,83 +796,94 @@ export class OfflineDbProviderTests extends AITestClass { endpoint: endpoint }; let evt = TestHelper.mockEvent(endpoint, 3, false); - doAwait(provider.initialize(providerCxt), (val) => { - this.ctx.isInit = val; - let ctx = provider["_getDbgPlgTargets"](); - let db = ctx[3]; - this.sandbox.stub(db as any, "openDb").callsFake((name, ver, func, change?) => { - return createAsyncPromise((resolve, reject)=> { - try { - let openDbCtx = { - openCursor: (var1, var2, var3?) => { - return createAsyncRejectedPromise(new Error("open cursor mock error")); - }, - openStore: (var1, var2, var3) => { - return createAsyncRejectedPromise(new Error("open store mock error")); + + return this._asyncQueue().add(() => { + doAwait(provider.initialize(providerCxt), (val) => { + this.ctx.isInit = val; + let ctx = provider["_getDbgPlgTargets"](); + let db = ctx[3]; + this.sandbox.stub(db as any, "openDb").callsFake((name, ver, func, change?) => { + return createAsyncPromise((resolve, reject)=> { + try { + let openDbCtx = { + openCursor: (var1, var2, var3?) => { + return createAsyncRejectedPromise(new Error("open cursor mock error")); + }, + openStore: (var1, var2, var3) => { + return createAsyncRejectedPromise(new Error("open store mock error")); + } } + // Database has been opened + doAwait(func(openDbCtx), resolve, reject); + } catch (e) { + reject(e); } - // Database has been opened - doAwait(func(openDbCtx), resolve, reject); - } catch (e) { - reject(e); - } + }); }); + }, (reason)=> { + this.ctx.initErr = reason; + Assert.ok(false, "error for init"); }); + }).add(() => { doAwait(provider.addEvent("", evt, itemCtx), (item) => { this.ctx.evt = item; Assert.ok(false, "should handle add event error"); }, (reason) => { this.ctx.addEvent = reason; Assert.equal(reason.message, "open store mock error", "add event message"); - doAwait(provider.getNextBatch(), (val) => { - Assert.ok(false, "should handle get next batch error") - }, (reason)=> { - this.ctx.nextBatch = reason; - Assert.equal(reason.message, "open cursor mock error", "get next batch message"); - doAwait(provider.getAllEvents(), (val) => { - Assert.ok(false, "should handle get all events error") - }, (reason)=> { - this.ctx.allEvts = reason; - Assert.equal(reason.message, "open cursor mock error", "get all events message") - doAwait(provider.removeEvents([evt]), (val) => { - this.ctx.removeEvts = val; - Assert.deepEqual([], val, "should handle remove events error") - doAwait(provider.clear(), (val) => { - this.ctx.clear = val; - Assert.deepEqual([], val, "should handle clear error") - doAwait(provider.clean(), (val) => { - this.ctx.clean = val; - Assert.ok(!val, "should handle clean error") - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }); - }, (reason)=> { - this.ctx.cleanErr = reason; - Assert.ok(false, "error for clean"); - }); - }, (reason)=> { - this.ctx.clearErr = reason; - Assert.ok(false, "error for clear"); - }); - }, (reason)=> { - this.ctx.removeEvtsErr = reason; - Assert.ok(false, "error for get next batch"); - }); - }); - }); - - }) - }, (reason)=> { - this.ctx.initErr = reason; - Assert.ok(false, "error for init"); + }); + + }).add(() => { + doAwait(provider.getNextBatch(), (val) => { + Assert.ok(false, "should handle get next batch error") + }, (reason)=> { + this.ctx.nextBatch = reason; + Assert.equal(reason.message, "open cursor mock error", "get next batch message"); + }); + + }).add(() => { + doAwait(provider.getAllEvents(), (val) => { + Assert.ok(false, "should handle get all events error") + }, (reason)=> { + this.ctx.allEvts = reason; + Assert.equal(reason.message, "open cursor mock error", "get all events message") + }); + + }).add(() => { + doAwait(provider.removeEvents([evt]), (val) => { + this.ctx.removeEvts = val; + Assert.deepEqual([], val, "should handle remove events error") + }, (reason)=> { + this.ctx.removeEvtsErr = reason; + Assert.ok(false, "error for get next batch"); + }); + + }).add(() => { + doAwait(provider.clear(), (val) => { + this.ctx.clear = val; + Assert.deepEqual([], val, "should handle clear error") + }, (reason)=> { + this.ctx.clearErr = reason; + Assert.ok(false, "error for clear"); + }); + + }).add(() => { + doAwait(provider.clean(), (val) => { + this.ctx.clean = val; + Assert.ok(!val, "should handle clean error") + }, (reason)=> { + this.ctx.cleanErr = reason; + Assert.ok(false, "error for clean"); + }); + + }).add(() => { doAwait(provider.teardown(), () => { this.ctx.isclosed = true; }); - }); - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let isInit = this.ctx.isInit; if (isInit) { return true; diff --git a/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts b/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts index 40ddcd4e1..1ba0a9303 100644 --- a/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts +++ b/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts @@ -66,7 +66,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Offline Batch Handler: init with IndexedDB storge provider", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.IndexedDb], autoClean: true, inStorageMaxTime: 1 } as IOfflineChannelConfiguration; @@ -112,7 +111,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Store Batch: store batch with web storge provider", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true } as IOfflineChannelConfiguration; @@ -140,17 +138,28 @@ export class OfflineBatchHandlerTests extends AITestClass { result.push(res); } let evt = TestHelper.mockEvent(endpoint, 1, false); - doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { - this.ctx.storeBatch = true; - this.ctx.result = result; + + return this._asyncQueue().add(() => { + doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { + this.ctx.storeBatch = true; + this.ctx.result = result; + }, (reason) => { + Assert.ok(false, "init error"); + }); + + }).add(() => { doAwait(batchHandler.hasStoredBatch(),(res) => { this.ctx.hasBatch = res; - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); + }, (reason) => { + Assert.ok(false, "hasStoreBatch error") }); - }); - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + + }).add(() => { + doAwait( batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }); + + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let storeBatch = this.ctx.storeBatch; if (storeBatch) { let res = this.ctx.result[0]; @@ -188,7 +197,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Store Batch: store batch with indexedDB storge provider", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.IndexedDb], autoClean: true, inStorageMaxTime:1} as IOfflineChannelConfiguration; @@ -201,32 +209,40 @@ export class OfflineBatchHandlerTests extends AITestClass { endpoint: endpoint } let batchHandler = new OfflineBatchHandler(); - doAwait(batchHandler.initialize(providerCxt),(res) => { - this.ctx.isInit = true; - let items = batchHandler["_getDbgPlgTargets"](); - let provider = items[0]; - let isInit = items[1]; - Assert.ok(provider, "provider is initialized"); - Assert.ok(isInit, "initialization is successful"); - let result:any[] = []; - let cb = (res) => { - this.ctx.storeBatch = true; - result.push(res); - } - let evt = TestHelper.mockEvent(endpoint, 1, false); - batchHandler.storeBatch(evt, cb); + let result:any[] = []; + let cb = (res) => { + this.ctx.storeBatch = true; + result.push(res); + } + let evt = TestHelper.mockEvent(endpoint, 1, false); + + return this._asyncQueue().add(() => { + doAwait(batchHandler.initialize(providerCxt),(res) => { + this.ctx.isInit = true; + let items = batchHandler["_getDbgPlgTargets"](); + let provider = items[0]; + let isInit = items[1]; + Assert.ok(provider, "provider is initialized"); + Assert.ok(isInit, "initialization is successful"); + }); + + }).add(() => { doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { this.ctx.storeBatch = true; this.ctx.result = result; - doAwait(batchHandler.hasStoredBatch(),(res) => { - this.ctx.hasBatch = res; - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - }); }); - }); - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + + }).add(() => { + doAwait(batchHandler.hasStoredBatch(),(res) => { + this.ctx.hasBatch = res; + }); + + }).add(() => { + doAwait( batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }); + + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let isInit = this.ctx.isInit; if (isInit) { return true; @@ -290,43 +306,53 @@ export class OfflineBatchHandlerTests extends AITestClass { let cb = (res) => { result.push(res); } + let cb1 = (res) => { + this.ctx.hasBatch = res; + } + let cb2 = (res) => { + this.ctx.cleanBatch = true; + this.ctx.cleanBatchRes = res; + } let evt = TestHelper.mockEvent(endpoint, 1, false); - doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { - this.ctx.storeBatch = 1; - this.ctx.result = result; - - let evt1 = TestHelper.mockEvent(endpoint, 2, false); + let evt1 = TestHelper.mockEvent(endpoint, 2, false); + let evt2 = TestHelper.mockEvent(endpoint, 3, false); + + return this._asyncQueue().add(() => { + doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { + this.ctx.storeBatch = 1; + this.ctx.result = result; + }); + + }).add(() => { doAwait(batchHandler.storeBatch(evt1, cb) as any,(res) => { this.ctx.storeBatch = 2; this.ctx.result = result; - let evt2 = TestHelper.mockEvent(endpoint, 3, false); - doAwait(batchHandler.storeBatch(evt2, cb) as any,(res) => { - this.ctx.storeBatch = 3; - this.ctx.result = result; - let storageKey = "AIOffline_1_dc.services.visualstudio.com"; - let storageStr = AITestClass.orgLocalStorage.getItem(storageKey) as any; - let storageObject = JSON.parse(storageStr); - let storageEvts = storageObject.evts; - Assert.deepEqual(Object.keys(storageEvts).length, 3, "storage should have three events"); - - let cb1 = (res) => { - this.ctx.hasBatch = res; - } - doAwait(batchHandler.hasStoredBatch(cb1),(res) => { - let cb2 = (res) => { - this.ctx.cleanBatch = true; - this.ctx.cleanBatchRes = res; - } - doAwait(batchHandler.cleanStorage(cb2) as any,(res) => { - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - }); - }); - }); }); - }); - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + + }).add(() => { + doAwait(batchHandler.storeBatch(evt2, cb) as any,(res) => { + this.ctx.storeBatch = 3; + this.ctx.result = result; + let storageKey = "AIOffline_1_dc.services.visualstudio.com"; + let storageStr = AITestClass.orgLocalStorage.getItem(storageKey) as any; + let storageObject = JSON.parse(storageStr); + let storageEvts = storageObject.evts; + Assert.deepEqual(Object.keys(storageEvts).length, 3, "storage should have three events"); + }); + + }).add(() => { + doAwait(batchHandler.hasStoredBatch(cb1),(res) => { + }); + + }).add(() => { + doAwait(batchHandler.cleanStorage(cb2) as any,(res) => {}); + + }).add(() => { + doAwait( batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }); + + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let storeBatch = this.ctx.storeBatch; if (storeBatch && storeBatch > 2) { Assert.equal(storeBatch, 3, "should have three response"); @@ -366,7 +392,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Clean Batch: clean batch with IndexedDB storge provider", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.IndexedDb], autoClean: true, inStorageMaxTime:1} as IOfflineChannelConfiguration; @@ -381,57 +406,61 @@ export class OfflineBatchHandlerTests extends AITestClass { } let batchHandler = new OfflineBatchHandler(); let provider; - doAwait(batchHandler.initialize(providerCxt),(res) => { - this.ctx.isInit = true; - let items = batchHandler["_getDbgPlgTargets"](); - provider = items[0]; - let isInit = items[1]; - Assert.ok(provider, "provider is initialized"); - Assert.ok(isInit, "initialization is successful"); - let result:any[] = []; - let cb = (res) => { - result.push(res); - } - let evt = TestHelper.mockEvent(endpoint, 1, false); - doAwait(batchHandler.storeBatch(evt, cb),(res) => { + let result:any[] = []; + let cb = (res) => { + result.push(res); + } + let cb1 = (res) => { + this.ctx.hasBatch = res; + } + let cb2 = (res) => { + this.ctx.cleanBatch = true; + this.ctx.cleanBatchRes = res; + } + let cb3 = (res) => { + this.ctx.hasBatch1Called = true; + this.ctx.hasBatch1 = res; + } + let evt = TestHelper.mockEvent(endpoint, 1, false); + let evt1 = TestHelper.mockEvent(endpoint, 2, false); + let evt2 = TestHelper.mockEvent(endpoint, 3, false); + + return this._asyncQueue().add(() => { + doAwait(batchHandler.initialize(providerCxt),(res) => { + this.ctx.isInit = true; + let items = batchHandler["_getDbgPlgTargets"](); + provider = items[0]; + let isInit = items[1]; + Assert.ok(provider, "provider is initialized"); + Assert.ok(isInit, "initialization is successful"); + }); + + }).add(() => { + doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { this.ctx.storeBatch = 1; this.ctx.result = result; - let evt1 = TestHelper.mockEvent(endpoint, 2, false); - doAwait(batchHandler.storeBatch(evt1, cb),(res) => { - this.ctx.storeBatch = 2; - this.ctx.result = result; - let evt2 = TestHelper.mockEvent(endpoint, 3, false); - doAwait(batchHandler.storeBatch(evt2, cb),(res) => { - this.ctx.storeBatch = 3; - this.ctx.result = result; - let cb1 = (res) => { - this.ctx.hasBatch = res; - } - doAwait(batchHandler.hasStoredBatch(cb1),(res) => { - let cb2 = (res) => { - this.ctx.cleanBatch = true; - this.ctx.cleanBatchRes = res; - } - doAwait(batchHandler.cleanStorage(cb2),(res) => { - let cb3 = (res) => { - this.ctx.hasBatch1Called = true; - this.ctx.hasBatch1 = res; - } - doAwait(batchHandler.hasStoredBatch(cb3),(res) => { - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - }); - - }); - - }); - - }); - }); }); - }); - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + }).add(() => { + doAwait(batchHandler.storeBatch(evt1, cb) as any,(res) => { + this.ctx.storeBatch = 2; + this.ctx.result = result; + }); + }).add(() => { + doAwait(batchHandler.storeBatch(evt2, cb) as any,(res) => { + this.ctx.storeBatch = 3; + this.ctx.result = result; + }); + }).add(() => { + doAwait(batchHandler.hasStoredBatch(cb1),(res) => {}); + }).add(() => { + doAwait(batchHandler.cleanStorage(cb2) as any,(res) => {}); + }).add(() => { + doAwait(batchHandler.hasStoredBatch(cb3),(res) => {}); + }).add(() => { + doAwait(batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }); + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let isInit = this.ctx.isInit; if (isInit) { return true; @@ -480,7 +509,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Send Next Batch: send Next Batch with web storge provider", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; @@ -506,71 +534,81 @@ export class OfflineBatchHandlerTests extends AITestClass { let evt = TestHelper.mockEvent(endpoint, 1, false); let evt1 = TestHelper.mockEvent(endpoint, 2, false); let evt2 = TestHelper.mockEvent(endpoint, 3, false); - doAwait(batchHandler.storeBatch(evt),(res) => { - this.ctx.storeBatch = 1; - doAwait(batchHandler.storeBatch(evt1),(res) => { + + let sender1Payload: any[] = [] + let sender1 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { + sender1Payload.push(payload); + oncomplete(400, {}); + } + let sender2Payload: any[] = [] + let sender2 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { + sender2Payload.push(payload); + oncomplete(200, {}); + } + let sender3Payload: any[] = [] + let sender3 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { + sender3Payload.push(payload); + oncomplete(500, {}); + } + + let res1: any[] = []; + let cb1 = (res) => { + res1.push(res); + } + let res2: any[] = []; + let cb2 = (res) => { + res2.push(res); + } + let res3: any[] = []; + let cb3 = (res) => { + res3.push(res); + } + let cb4 = (res) => { + this.ctx.hasBatch1Called = true; + this.ctx.hasBatch1 = res && res.length >= 1; + } + + return this._asyncQueue().add(() => { + doAwait(batchHandler.storeBatch(evt), (res) => { + this.ctx.storeBatch = 1; + }); + }).add(() => { + doAwait(batchHandler.storeBatch(evt1), (res) => { this.ctx.storeBatch = 2; - doAwait(batchHandler.storeBatch(evt2),(res) => { - this.ctx.storeBatch = 3; - let sender1Payload: any[] = [] - let sender1 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { - sender1Payload.push(payload); - oncomplete(400, {}); - } - // 200 should be called first, in some case, re-try will be added back (sender2) and event2 will be returned again - // This is to guarantee the test gets events in order - let sender2Payload: any[] = [] - let sender2 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { - sender2Payload.push(payload); - oncomplete(200, {}); - } - let sender3Payload: any[] = [] - let sender3 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { - sender3Payload.push(payload); - oncomplete(500, {}); - } - - let res1: any[] = []; - let cb1 = (res) => { - res1.push(res); - } - doAwait(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { - this.ctx.sendBatch1 = true; - this.ctx.sendBatch1Res = res1; - this.ctx.sendBatch1Pd = sender1Payload; - let res2: any[] = []; - let cb2 = (res) => { - res2.push(res); - } - - doAwait(batchHandler.sendNextBatch(cb2, false, {sendPOST: sender2}) as any,(res) => { - this.ctx.sendBatch2 = true; - this.ctx.sendBatch2Res = res2; - this.ctx.sendBatch2Pd = sender2Payload; - let res3: any[] = []; - let cb3 = (res) => { - res3.push(res); - } - doAwait(batchHandler.sendNextBatch(cb3, false, {sendPOST: sender3}) as any,(res) => { - this.ctx.sendBatch3 = true; - this.ctx.sendBatch3Res = res3; - this.ctx.sendBatch3Pd = sender3Payload; - let cb4 = (res) => { - this.ctx.hasBatch1Called = true; - this.ctx.hasBatch1 = res && res.length >= 1; - } - doAwait(batchHandler.hasStoredBatch(cb4),(res) => { - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - }); - }); - }); - }); - }); }); - }); - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + }).add(() => { + doAwait(batchHandler.storeBatch(evt2), (res) => { + this.ctx.storeBatch = 3; + }); + }).add(() => { + doAwait(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any, (res) => { + this.ctx.sendBatch1 = true; + this.ctx.sendBatch1Res = res1; + this.ctx.sendBatch1Pd = sender1Payload; + }); + }).add(() => { + doAwait(batchHandler.sendNextBatch(cb2, false, {sendPOST: sender2}) as any, (res) => { + // 200 should be called first, in some case, re-try will be added back (sender2) and event2 will be returned again + // This is to guarantee the test gets events in order + this.ctx.sendBatch2 = true; + this.ctx.sendBatch2Res = res2; + this.ctx.sendBatch2Pd = sender2Payload; + }); + }).add(() => { + doAwait(batchHandler.sendNextBatch(cb3, false, {sendPOST: sender3}) as any, (res) => { + this.ctx.sendBatch3 = true; + this.ctx.sendBatch3Res = res3; + this.ctx.sendBatch3Pd = sender3Payload; + }); + }).add(() => { + doAwait(batchHandler.hasStoredBatch(cb4), (res) => { + }); + }).add(() => { + doAwait(batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }); + + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let storeBatch = this.ctx.storeBatch; if (storeBatch && storeBatch == 3) { return true; @@ -651,10 +689,8 @@ export class OfflineBatchHandlerTests extends AITestClass { }); - this.testCase({ name: "Send Next Batch: send Next Batch with IndexedDB provider", - pollDelay: 1000, test: ()=> { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.IndexedDb], autoClean: false, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; @@ -681,43 +717,46 @@ export class OfflineBatchHandlerTests extends AITestClass { let evt = TestHelper.mockEvent(endpoint, 1, false); let evt1 = TestHelper.mockEvent(endpoint, 2, false); let evt2 = TestHelper.mockEvent(endpoint, 3, false); - doAwait(batchHandler.storeBatch(evt),(res) => { - this.ctx.storeBatch = 1; - doAwait(batchHandler.storeBatch(evt1),(res) => { + + return this._asyncQueue().add(() => { + doAwait(batchHandler.storeBatch(evt), (res) => { + this.ctx.storeBatch = 1; + }); + }).add(() => { + doAwait(batchHandler.storeBatch(evt1), (res) => { this.ctx.storeBatch = 2; - doAwait(batchHandler.storeBatch(evt2),(res) => { - this.ctx.storeBatch = 3; - let sender1Payload: any[] = [] - let sender1 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { - sender1Payload.push(payload); - oncomplete(400, {}); - } - let res1: any[] = []; - - let cb1 = (res) => { - res1.push(res); - } - - doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { - this.ctx.sendBatch1 = true; - this.ctx.sendBatch1Res = res1; - this.ctx.sendBatch1Pd = sender1Payload; - Assert.equal(res.value.state, eBatchSendStatus.Drop, "should have drop status"); - doAwaitResponse(provider.getAllEvents(), (res)=> { - this.ctx.getAll = true; - let val = res.value; - Assert.equal(val && val.length, 2, "should have 2 events"); - let sentcriticalCnt = res1[0].data.criticalCnt; - arrForEach(val, (item) => { - Assert.ok(sentcriticalCnt !== item.criticalCnt, "should not contain deleted item"); - }); - }); - + }); + }).add(() => { + doAwait(batchHandler.storeBatch(evt2), (res) => { + this.ctx.storeBatch = 3; + }); + }).add(() => { + let sender1Payload: any[] = []; + let sender1 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { + sender1Payload.push(payload); + oncomplete(400, {}); + }; + let res1: any[] = []; + let cb1 = (res) => { + res1.push(res); + }; + doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any, (res) => { + this.ctx.sendBatch1 = true; + this.ctx.sendBatch1Res = res1; + this.ctx.sendBatch1Pd = sender1Payload; + Assert.equal(res.value.state, eBatchSendStatus.Drop, "should have drop status"); + doAwaitResponse(provider.getAllEvents(), (res)=> { + this.ctx.getAll = true; + let val = res.value; + Assert.equal(val && val.length, 2, "should have 2 events"); + let sentcriticalCnt = res1[0].data.criticalCnt; + arrForEach(val, (item) => { + Assert.ok(sentcriticalCnt !== item.criticalCnt, "should not contain deleted item"); }); }); + }); - }); - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { + }).concat(PollingAssert.asyncTaskPollingAssert(() => { let storeBatch = this.ctx.storeBatch; if (storeBatch && storeBatch == 3) { return true; @@ -746,7 +785,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Send Next Batch: send Next Batch with IndexedDB provider test1 with retry code", - pollDelay: 1000, test: () => { let batchHandler = this.batchHandler; this.ctx.isInit = true; @@ -813,7 +851,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Send Next Batch: send Next Batch with IndexedDB provider test1 with 200", - pollDelay: 1000, test: () => { let batchHandler = this.batchHandler; this.ctx.isInit = true; @@ -831,7 +868,6 @@ export class OfflineBatchHandlerTests extends AITestClass { oncomplete(200, {}); } - let res1: any[] = []; let cb1 = (res) => { res1.push(res); @@ -873,7 +909,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Send Next Batch: send Next Batch with IndexedDB provider test1 with unload events", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageKey = "AIOffline_1_dc.services.visualstudio.com"; @@ -953,7 +988,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Send Next Batch: Error handle store batch", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; @@ -1010,7 +1044,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Send Next Batch: Error handle clean batch", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; @@ -1067,7 +1100,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Send Next Batch: Error handle add batch with remove error", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; @@ -1132,7 +1164,6 @@ export class OfflineBatchHandlerTests extends AITestClass { this.testCase({ name: "Send Next Batch: Error handle add batch", - pollDelay: 100, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, senderCfg:{retryCodes: [500]}, maxRetry: 2} as IOfflineChannelConfiguration; From 9133c5f6eb58d9e65d5f939521b165d9b66fb1bb Mon Sep 17 00:00:00 2001 From: Karlie Li Date: Wed, 28 May 2025 10:33:07 -0700 Subject: [PATCH 3/3] update --- .../Tests/Unit/src/dbprovider.tests.ts | 425 ++++-------- .../Unit/src/offlinebatchhandler.tests.ts | 616 ++++++------------ 2 files changed, 339 insertions(+), 702 deletions(-) diff --git a/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts b/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts index 6a96b4d3b..5b970ebc9 100644 --- a/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts +++ b/channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts @@ -1,6 +1,6 @@ import { AITestClass, Assert, PollingAssert } from "@microsoft/ai-test-framework"; import { IndexedDbProvider } from "../../../src/Providers/IndexDbProvider"; -import { createAsyncPromise, createAsyncRejectedPromise, doAwait } from "@nevware21/ts-async"; +import { createAsyncPromise, createAsyncRejectedPromise, createSyncPromise, doAwait, doAwaitResponse } from "@nevware21/ts-async"; import { arrForEach, strSubstr } from "@nevware21/ts-utils"; import { TestChannel } from "./TestHelper"; import { AppInsightsCore, IConfiguration, createDynamicConfig, generateW3CId, newGuid } from "@microsoft/applicationinsights-core-js"; @@ -67,36 +67,33 @@ export class OfflineDbProviderTests extends AITestClass { this.testCase({ name: "IndexedDbProvider: init with auto clean set to true", - pollDelay: 1000, - test: ()=>{ + test: () => { + let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); let itemCtx = this.core.getProcessTelContext(); let storageConfig = createDynamicConfig({autoClean: true}).cfg; let providerCxt = { itemCtx: itemCtx, storageConfig: storageConfig, - endpoint:DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH - } - this.ctx.isInit = provider.initialize(providerCxt); - this.ctx.provider = provider; + endpoint: endpoint + }; - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - doAwait(provider.teardown(), () => { - this.ctx.isclosed = true; - }) - return true; - } - return false; - }, "Wait for init response" + new Date().toISOString(), 200, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000)) - + return this._asyncQueue().add(() => + doAwait(provider.initialize(providerCxt), (val) => { + this.ctx.isInit = val; + Assert.ok(val, "init process is successful"); + }, (reason)=> { + this.ctx.initErr = reason; + Assert.ok(false, "error for init"); + }) + ).add(() => + doAwait(provider.teardown(), () => { + this.ctx.isclosed = true; + Assert.ok(true, "should teardown provider"); + }, (reason) => { + Assert.ok(false, "error for teardown"); + }) + ); } }); @@ -114,15 +111,14 @@ export class OfflineDbProviderTests extends AITestClass { }; let evt = TestHelper.mockEvent(endpoint, 3, false); - return this._asyncQueue().add(() =>{ + return this._asyncQueue().add(() => doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; }, (reason)=> { this.ctx.initErr = reason; Assert.ok(false, "error for init"); - }); - - }).add(() => { + }) + ).add(() => doAwait(provider.addEvent("", evt, itemCtx), (item) => { this.ctx.evt = item; Assert.deepEqual(item, evt, "should add expected item"); @@ -131,8 +127,8 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason) => { this.ctx.addEventErr = reason; Assert.ok(false, "error for addEvt"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.getNextBatch(), (item) => { this.ctx.getEvt = item; Assert.equal(item && item.length, 1, "should have one item"); @@ -140,19 +136,15 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason) => { this.ctx.getEvtErr = reason; Assert.ok(false, "error for get event"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.teardown(), () => { this.ctx.isclosed = true; Assert.ok(true, "should teardown provider"); - }); - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000)); + },(reason) => { + Assert.ok(false, "error for teardown"); + }) + ); } }); @@ -173,15 +165,15 @@ export class OfflineDbProviderTests extends AITestClass { let evt1 = TestHelper.mockEvent(endpoint, 1, false); let evt2 = TestHelper.mockEvent(endpoint, 2, false); - return this._asyncQueue().add(() =>{ + return this._asyncQueue().add(() => doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; }, (reason)=> { this.ctx.initErr = reason; Assert.ok(false, "error for init"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.getAllEvents(), (val) => { this.ctx.preEvts = val; Assert.equal(val && val.length, 1 , "should have the event from the previous test"); @@ -190,17 +182,17 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason)=> { this.ctx.preEvtsErr = reason; Assert.ok(false, "get previous events error"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.addEvent("", evt, itemCtx), (item) => { this.ctx.evt = item; Assert.equal(item, evt, "should have one event"); }, (reason)=> { this.ctx.preEvtsErr = reason; Assert.ok(false, "get previous events error"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.getAllEvents(), (val) => { this.ctx.allEvts = val; Assert.equal(val && val.length, 2 , "should have the two events"); @@ -208,34 +200,34 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason) => { this.ctx.addEventErr = reason; Assert.ok(false, "add event error"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.addEvent("", evt1, itemCtx), (item) => { this.ctx.evt1 = item; Assert.deepEqual(item, evt1, "should have expected event1"); }, (reason) => { this.ctx.addEvent1Err = reason; Assert.ok(false, "add event1 error"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.addEvent("", evt2, itemCtx), (item) => { this.ctx.evt2 = item; Assert.deepEqual(item, evt2, "should have expected event2"); }, (reason) => { this.ctx.addEvent2Err = reason; Assert.ok(false, "add event2 error"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.getAllEvents(), (val) => { this.ctx.allEvts1 = val; Assert.equal(val && (val as any).length, 4, "should have four events"); }, (reason)=> { this.ctx.oneEvtsErr = reason; Assert.ok(false, "get all events1 error"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.getNextBatch(), (val) => { this.ctx.nextBatch = val; Assert.equal(val && (val as any).length, 1, "should return one event"); @@ -243,8 +235,8 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason)=> { this.ctx.nextBatchErr = reason; Assert.ok(false, "get next batch error"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.getAllEvents(2), (val) => { this.ctx.twoEvts = val; Assert.equal(val && (val as any).length, 2, "should return two events"); @@ -252,27 +244,23 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason)=> { this.ctx.twoEvtsErr = reason; Assert.ok(false, "get two events error"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.clear(), (val) => { this.ctx.clear = val; Assert.equal(val && (val as any).length, 4, "should clear all events"); }, (reason)=> { this.ctx.twoEvtsErr = reason; Assert.ok(false, "get two events error"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.teardown(), () => { this.ctx.isclosed = true; - }); - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - this.preEvts = [] - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + }, (reason) => { + Assert.ok(false, "teardown error"); + + }) + ) } }); @@ -291,15 +279,15 @@ export class OfflineDbProviderTests extends AITestClass { }; let evt = TestHelper.mockEvent(endpoint, 3, false); - return this._asyncQueue().add(() =>{ + return this._asyncQueue().add(() => doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; }, (reason)=> { this.ctx.initErr = reason; Assert.ok(false, "error for init"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.addEvent("", evt, itemCtx), (item) => { this.ctx.evt = item; }, (reason) => { @@ -310,7 +298,7 @@ export class OfflineDbProviderTests extends AITestClass { }); }) - }).add(() => { + ).add(() => { let ctx = provider["_getDbgPlgTargets"](); let db = ctx[3]; this.sandbox.stub(db as any, "openDb").callsFake((name, ver, func, change?) => { @@ -328,45 +316,21 @@ export class OfflineDbProviderTests extends AITestClass { } }); }); - doAwait(provider.getNextBatch(), (val) => { + return doAwait(provider.getNextBatch(), (val) => { this.ctx.nextBatch = val; Assert.ok(false, "should handle errors"); }, (reason)=> { this.ctx.nextBatchErr = reason; + Assert.equal(reason.message, "open cursor mock error"); }); - }).add(() => { + }).add(() => doAwait(provider.teardown(), () => { this.ctx.isclosed = true; - }); - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.evt; - if (item) { - return true; - } - - return false; - }, "Wait for add Event response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.nextBatchErr; - if (item) { - Assert.equal(item.message, "open cursor mock error"); - return true; - } - - return false; - }, "Wait for handle error response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + },(reason) => { + Assert.ok(false, "teardown errors"); + }) + ) } }); @@ -394,49 +358,49 @@ export class OfflineDbProviderTests extends AITestClass { let evt2 = TestHelper.mockEvent(endpoint, 2, false); let evt4 = TestHelper.mockEvent(endpoint, 4, false); - return this._asyncQueue().add(() => { + return this._asyncQueue().add(() => doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; }, (reason)=> { this.ctx.initErr = reason; Assert.ok(false, "error for init"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.removeEvents([evt]), (item) => { this.ctx.removeEvts = item; Assert.deepEqual(item && item.length, 0,"should not delete any events"); }, (reason) => { this.ctx.removeEvtsErr = reason; Assert.ok(false, "error for remove events"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.addEvent("", evt, itemCtx), (item) => { this.ctx.evt = item; Assert.deepEqual(item, evt, "should add exepcted evt"); }, (reason) => { this.ctx.addEventErr = reason; Assert.ok(false, "error for add events"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.addEvent("", evt1, itemCtx), (item) => { this.ctx.evt1 = item; Assert.deepEqual(item, evt1, "should add exepcted evt1"); }, (reason) => { this.ctx.addEvent1Err = reason; Assert.ok(false, "error for add event 1"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.addEvent("", evt2, itemCtx), (item) => { this.ctx.evt2 = item; Assert.deepEqual(item, evt2, "should add exepcted evt2"); }, (reason) => { this.ctx.addEvent2Err = reason; Assert.ok(false, "error for add event 2"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.getAllEvents(), (val) => { this.ctx.allEvts = val; Assert.deepEqual(val && val.length, 3, "should have all expected 3 events"); @@ -444,18 +408,18 @@ export class OfflineDbProviderTests extends AITestClass { this.ctx.allEvtsErr = reason; Assert.ok(false, "error for get all events"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.removeEvents([evt4]), (item) => { this.ctx.removeEvts1 = item; Assert.deepEqual(item && item.length, 0, "should not delete event1"); }, (reason) => { this.ctx.removeEvts1Err = reason; Assert.ok(false, "error for remove events1"); - }); + }) - }).add(()=> { + ).add(() => doAwait(provider.removeEvents([evt, evt1]), (item) => { this.ctx.removeEvts2 = item; Assert.deepEqual(item && item.length, 2, "should delete all expected events"); @@ -471,9 +435,9 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason) => { this.ctx.removeEvts2Err = reason; Assert.ok(false, "error for remove events2"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.getAllEvents(), (val) => { this.ctx.allEvts1 = val; Assert.deepEqual(val && val.length, 1, "should have one event remaining"); @@ -481,66 +445,18 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason)=> { this.ctx.allEvts1Err = reason; Assert.ok(false, "error for get all evts1"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.teardown(), () => { this.ctx.isclosed = true; - }); - - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let items = this.ctx.removeEvts; - - if (items) { - return true; - } - - return false; - }, "Wait for remove evt response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let items = this.ctx.allEvts; - - if (items) { - return true; - } - - return false; - }, "Wait for get Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item1 = this.ctx.removeEvts1; - if (item1) { - return true; - } - - return false; - }, "Wait for remove Event1 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let items2 = this.ctx.removeEvts2; - - if (items2) { - return true; - } - - return false; - }, "Wait for remove event2 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let items = this.ctx.allEvts1; - - if (items ) { - return true; - } - - return false; - }, "Wait for get Events1 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { Assert.equal(this.batchDrop.length, 1, "notification should be called once"); // sent in clean process during initialization Assert.equal(this.batchDrop[0].reason, 3, "notification should be called with expected reason time exceeded"); - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + },(reason) => { + Assert.ok(false, "teardown error"); + + }) + + ) } }); @@ -561,41 +477,41 @@ export class OfflineDbProviderTests extends AITestClass { let evt1 = TestHelper.mockEvent(endpoint, 1, false); let evt2 = TestHelper.mockEvent(endpoint, 2, false); - return this._asyncQueue().add(() => { + return this._asyncQueue().add(() => doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; }, (reason)=> { this.ctx.initErr = reason; Assert.ok(false, "error for init"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.addEvent("", evt, itemCtx), (item) => { this.ctx.evt = item; Assert.deepEqual(item, evt, "should add evt"); }, (reason) => { this.ctx.addEventErr = reason; Assert.ok(false, "error for add evt"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.addEvent("", evt1, itemCtx), (item) => { this.ctx.evt1 = item; Assert.deepEqual(item, evt1, "should add evt1"); }, (reason) => { this.ctx.addEvent1Err = reason; Assert.ok(false, "error for add evt1"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.addEvent("", evt2, itemCtx), (item) => { this.ctx.evt2 = item; Assert.deepEqual(item, evt2, "should add evt2"); }, (reason) => { this.ctx.addEvent2Err = reason; Assert.ok(false, "error for add evt2"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.clear(), (val)=> { this.ctx.clearEvts = val; Assert.ok(val && val.length >= 3, "should clear events"); // may have the events from previous test @@ -603,51 +519,23 @@ export class OfflineDbProviderTests extends AITestClass { this.ctx.clearEvtsErr = reason; Assert.ok(false, "error for clear"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.getAllEvents(), (val) => { this.ctx.allEvts1 = val; Assert.equal(val && val.length, 0, "should not have any events" ); }, (reason)=> { this.ctx.allEvts1Err = reason; Assert.ok(false, "get events error"); - }); - }).add(() => { + }) + ).add(() => doAwait(provider.teardown(), () => { this.ctx.isclosed = true; - }); - - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.evt; - let item1 = this.ctx.evt1; - let item2 = this.ctx.evt2; - if (item && item1 && item2) { - return true; - } - - return false; - }, "Wait for get Events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let items = this.ctx.allEvts1; - - if (items && items.length == 0) { - return true; - } - - return false; - }, "Wait for get Events1 response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + },(reason) => { + Assert.ok(false, "teardown error"); + }) + ) } }); @@ -782,9 +670,9 @@ export class OfflineDbProviderTests extends AITestClass { } }); + this.testCase({ name: "IndexedDbProvider: Error handle should handle open errors", - useFakeTimers: true, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let provider = new IndexedDbProvider(); @@ -797,7 +685,7 @@ export class OfflineDbProviderTests extends AITestClass { }; let evt = TestHelper.mockEvent(endpoint, 3, false); - return this._asyncQueue().add(() => { + return this._asyncQueue().add(() => doAwait(provider.initialize(providerCxt), (val) => { this.ctx.isInit = val; let ctx = provider["_getDbgPlgTargets"](); @@ -824,16 +712,18 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason)=> { this.ctx.initErr = reason; Assert.ok(false, "error for init"); - }); + }) - }).add(() => { - doAwait(provider.addEvent("", evt, itemCtx), (item) => { + ).add(() => { + + return doAwait(provider.addEvent("", evt, itemCtx), (item) => { this.ctx.evt = item; Assert.ok(false, "should handle add event error"); }, (reason) => { this.ctx.addEvent = reason; Assert.equal(reason.message, "open store mock error", "add event message"); - }); + }) + }).add(() => { doAwait(provider.getNextBatch(), (val) => { @@ -841,7 +731,7 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason)=> { this.ctx.nextBatch = reason; Assert.equal(reason.message, "open cursor mock error", "get next batch message"); - }); + }) }).add(() => { doAwait(provider.getAllEvents(), (val) => { @@ -849,7 +739,7 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason)=> { this.ctx.allEvts = reason; Assert.equal(reason.message, "open cursor mock error", "get all events message") - }); + }) }).add(() => { doAwait(provider.removeEvents([evt]), (val) => { @@ -858,86 +748,33 @@ export class OfflineDbProviderTests extends AITestClass { }, (reason)=> { this.ctx.removeEvtsErr = reason; Assert.ok(false, "error for get next batch"); - }); + }) - }).add(() => { + }).add(() => doAwait(provider.clear(), (val) => { this.ctx.clear = val; Assert.deepEqual([], val, "should handle clear error") }, (reason)=> { this.ctx.clearErr = reason; Assert.ok(false, "error for clear"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.clean(), (val) => { this.ctx.clean = val; Assert.ok(!val, "should handle clean error") }, (reason)=> { this.ctx.cleanErr = reason; Assert.ok(false, "error for clean"); - }); + }) - }).add(() => { + ).add(() => doAwait(provider.teardown(), () => { this.ctx.isclosed = true; - }); - - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for Init response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.addEvent; - if (item) { - return true; - } - - return false; - }, "Wait for add Event response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.nextBatch; - if (item) { - return true; - } - - return false; - }, "Wait for next batch response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.allEvts; - if (item) { - return true; - } - - return false; - }, "Wait for all events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.removeEvts; - if (item) { - return true; - } - - return false; - }, "Wait for remove events response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.clear; - if (item) { - return true; - } - - return false; - }, "Wait for clear response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.clean; - if (item !== null) { - return true; - } - - return false; - }, "Wait for clean response" + new Date().toISOString(), 30, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 30, 1000)) + },(reason) => { + Assert.ok(false, "teardown error"); + }) + ) } }); diff --git a/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts b/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts index 1ba0a9303..779c89abd 100644 --- a/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts +++ b/channels/offline-channel-js/Tests/Unit/src/offlinebatchhandler.tests.ts @@ -78,32 +78,25 @@ export class OfflineBatchHandlerTests extends AITestClass { endpoint: endpoint } let batchHandler = new OfflineBatchHandler(); - doAwait(batchHandler.initialize(providerCxt),(res) => { - this.ctx.isInit = true; - let items = batchHandler["_getDbgPlgTargets"](); - let provider = items[0]; - let isInit = items[1]; - Assert.ok(provider, "provider is initialized"); - Assert.ok(isInit, "initialization is successful"); + return this._asyncQueue().add(() => + doAwait(batchHandler.initialize(providerCxt),(res) => { + this.ctx.isInit = true; + let items = batchHandler["_getDbgPlgTargets"](); + let provider = items[0]; + let isInit = items[1]; + Assert.ok(provider, "provider is initialized"); + Assert.ok(isInit, "initialization is successful"); + + },(reason) => { + Assert.ok(false, "init errors"); + }) + ).add(() => doAwait(batchHandler.teardown(),(res) => { this.ctx.isclosed = true; - }); - }); - - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - - return true; - } - return false; - }, "Wait for init response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000)) + },(reason) => { + Assert.ok(false, "teardown errors"); + }) + ) } @@ -139,30 +132,11 @@ export class OfflineBatchHandlerTests extends AITestClass { } let evt = TestHelper.mockEvent(endpoint, 1, false); - return this._asyncQueue().add(() => { - doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { + return this._asyncQueue().add(() => + doAwait(batchHandler.storeBatch(evt, cb) as any,(storeRes) => { this.ctx.storeBatch = true; this.ctx.result = result; - }, (reason) => { - Assert.ok(false, "init error"); - }); - - }).add(() => { - doAwait(batchHandler.hasStoredBatch(),(res) => { - this.ctx.hasBatch = res; - }, (reason) => { - Assert.ok(false, "hasStoreBatch error") - }); - - }).add(() => { - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch) { - let res = this.ctx.result[0]; + let res = result[0]; let state = res.state == eBatchStoreStatus.Success; Assert.ok(state, "state should be ok"); let item = res.item; @@ -176,22 +150,25 @@ export class OfflineBatchHandlerTests extends AITestClass { Assert.deepEqual(Object.keys(storageEvts).length, 1, "storgae should only have one event"); Assert.ok(storageEvts[item.id], "storgae should contain expected item"); - return true; - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let hasBatch = this.ctx.hasBatch; - if (hasBatch) { - return true; - } - return false; - }, "Wait for has batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000)) + + }, (reason) => { + Assert.ok(false, "init error"); + }) + + ).add(() => + doAwait(batchHandler.hasStoredBatch(),(res) => { + this.ctx.hasBatch = res; + }, (reason) => { + Assert.ok(false, "hasStoreBatch error") + }) + + ).add(() => + doAwait( batchHandler.teardown(), () => { + this.ctx.isclosed = true; + },(reason) => { + Assert.ok(false, "teardown errors") + }) + ) } }); @@ -216,7 +193,7 @@ export class OfflineBatchHandlerTests extends AITestClass { } let evt = TestHelper.mockEvent(endpoint, 1, false); - return this._asyncQueue().add(() => { + return this._asyncQueue().add(() => doAwait(batchHandler.initialize(providerCxt),(res) => { this.ctx.isInit = true; let items = batchHandler["_getDbgPlgTargets"](); @@ -224,62 +201,38 @@ export class OfflineBatchHandlerTests extends AITestClass { let isInit = items[1]; Assert.ok(provider, "provider is initialized"); Assert.ok(isInit, "initialization is successful"); - }); + },(reason) => { + Assert.ok(false, "init errors") + }) - }).add(() => { + ).add(() => doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { this.ctx.storeBatch = true; this.ctx.result = result; - }); + }, (reason) => { + Assert.ok(false, "storebatch error") + }) - }).add(() => { + ).add(() => doAwait(batchHandler.hasStoredBatch(),(res) => { this.ctx.hasBatch = res; - }); + }, (reason) => { + Assert.ok(false, "hasbatch error"); + }) - }).add(() => { + ).add(() => doAwait( batchHandler.teardown(), () => { this.ctx.isclosed = true; - }); + }, (reason) => { + Assert.ok(false, "teardown error") + }) - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for init response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.asyncTaskPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch) { - let res = this.ctx.result[0]; - let state = res.state == eBatchStoreStatus.Success; - Assert.ok(state, "state should be ok"); - let item = res.item; - Assert.ok(item.id, "item id should be set"); - Assert.equal(item.criticalCnt, 1, "expected item should be returned"); - - return true; - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.asyncTaskPollingAssert(() => { - let hasBatch = this.ctx.hasBatch; - if (hasBatch) { - return true; - } - return false; - }, "Wait for has batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000)) + ) } }); this.testCase({ name: "Clean Batch: clean batch with web storge provider", - pollDelay: 1000, test: () => { let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH; let storageObj = {providers:[eStorageProviders.LocalStorage], autoClean: true, inStorageMaxTime:1} as IOfflineChannelConfiguration; @@ -317,19 +270,23 @@ export class OfflineBatchHandlerTests extends AITestClass { let evt1 = TestHelper.mockEvent(endpoint, 2, false); let evt2 = TestHelper.mockEvent(endpoint, 3, false); - return this._asyncQueue().add(() => { + return this._asyncQueue().add(() => doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { this.ctx.storeBatch = 1; this.ctx.result = result; - }); + },(reason) => { + Assert.ok(false, "init errors"); + }) - }).add(() => { + ).add(() => doAwait(batchHandler.storeBatch(evt1, cb) as any,(res) => { this.ctx.storeBatch = 2; this.ctx.result = result; - }); + },(reason) => { + Assert.ok(false, "store batch errors"); + }) - }).add(() => { + ).add(() => doAwait(batchHandler.storeBatch(evt2, cb) as any,(res) => { this.ctx.storeBatch = 3; this.ctx.result = result; @@ -338,38 +295,18 @@ export class OfflineBatchHandlerTests extends AITestClass { let storageObject = JSON.parse(storageStr); let storageEvts = storageObject.evts; Assert.deepEqual(Object.keys(storageEvts).length, 3, "storage should have three events"); - }); + },(reason) => { + Assert.ok(false, "storebatch error") + }) - }).add(() => { + ).add(() => doAwait(batchHandler.hasStoredBatch(cb1),(res) => { - }); - - }).add(() => { - doAwait(batchHandler.cleanStorage(cb2) as any,(res) => {}); - - }).add(() => { - doAwait( batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); + }, (reason) => { + Assert.ok(false, "hasstoredbatch error"); + }) - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch && storeBatch > 2) { - Assert.equal(storeBatch, 3, "should have three response"); - let res = this.ctx.result; - Assert.equal(res.length, 3, "response should have three items"); - return true - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let hasBatch = this.ctx.hasBatch; - if (hasBatch) { - return true; - } - return false; - }, "Wait for has batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let cleanBatch = this.ctx.cleanBatch; - if (cleanBatch) { + ).add(() => + doAwait(batchHandler.cleanStorage(cb2) as any,(cleanRes) => { let res = this.ctx.cleanBatchRes; Assert.equal(res.batchCnt, 3, "should clean all three items"); let storageKey = "AIOffline_1_dc.services.visualstudio.com"; @@ -377,16 +314,18 @@ export class OfflineBatchHandlerTests extends AITestClass { let storageObject = JSON.parse(storageStr); let storageEvts = storageObject.evts; Assert.deepEqual(Object.keys(storageEvts).length, 0, "storgae should not only have any event"); - return true; - } - return false; - }, "Wait for clean batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000)) + },(reason) => { + Assert.ok(false, "clean storage errors") + }) + + ).add(() => + doAwait( batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }, (reason) => { + Assert.ok(false, "teardown error") + }) + + ) } }); @@ -425,7 +364,7 @@ export class OfflineBatchHandlerTests extends AITestClass { let evt1 = TestHelper.mockEvent(endpoint, 2, false); let evt2 = TestHelper.mockEvent(endpoint, 3, false); - return this._asyncQueue().add(() => { + return this._asyncQueue().add(() => doAwait(batchHandler.initialize(providerCxt),(res) => { this.ctx.isInit = true; let items = batchHandler["_getDbgPlgTargets"](); @@ -433,77 +372,59 @@ export class OfflineBatchHandlerTests extends AITestClass { let isInit = items[1]; Assert.ok(provider, "provider is initialized"); Assert.ok(isInit, "initialization is successful"); - }); + }, (reason) => { + Assert.ok(false, "init errors") + }) - }).add(() => { + ).add(() => doAwait(batchHandler.storeBatch(evt, cb) as any,(res) => { this.ctx.storeBatch = 1; this.ctx.result = result; - }); - }).add(() => { + }, (reason) => { + Assert.ok(false, "store batch errors") + }) + ).add(() => doAwait(batchHandler.storeBatch(evt1, cb) as any,(res) => { this.ctx.storeBatch = 2; this.ctx.result = result; - }); - }).add(() => { + }, (reason) => { + Assert.ok(false, "store batch error 1") + }) + ).add(() => doAwait(batchHandler.storeBatch(evt2, cb) as any,(res) => { this.ctx.storeBatch = 3; this.ctx.result = result; - }); - }).add(() => { - doAwait(batchHandler.hasStoredBatch(cb1),(res) => {}); - }).add(() => { - doAwait(batchHandler.cleanStorage(cb2) as any,(res) => {}); - }).add(() => { - doAwait(batchHandler.hasStoredBatch(cb3),(res) => {}); - }).add(() => { - doAwait(batchHandler.teardown(), () => { - this.ctx.isclosed = true; - }); - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isInit = this.ctx.isInit; - if (isInit) { - return true; - } - return false; - }, "Wait for int response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch && storeBatch > 2) { - Assert.equal(storeBatch, 3, "should have three response"); - let res = this.ctx.result; - Assert.equal(res.length, 3, "response should have three items"); - return true - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let hasBatch = this.ctx.hasBatch; - if (hasBatch) { - return true; - } - return false; - }, "Wait for has batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let cleanBatch = this.ctx.cleanBatch; - if (cleanBatch) { + Assert.equal(result.length, 3, "response should have three items"); + }, (reason) => { + Assert.ok(false, "store batch error 2") + }) + ).add(() => + doAwait(batchHandler.hasStoredBatch(cb1),(res) => {},(reason) => { + Assert.ok(false, "has store batch error") + }) + ).add(() => + doAwait(batchHandler.cleanStorage(cb2) as any,(cleanRes) => { let res = this.ctx.cleanBatchRes; Assert.equal(res.batchCnt, 3, "should clean all three items"); - return true; - } - return false; - }, "Wait for clean batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let hasBatch1Called = this.ctx.hasBatch1Called; - if (hasBatch1Called) { + },(reason) => { + Assert.ok(false, "clean store batch error") + }) + ).add(() => + doAwait(batchHandler.hasStoredBatch(cb3),(res) => { let hasBatch = this.ctx.hasBatch1; Assert.equal(hasBatch, false, "should not contain any events") - return true; - } - return false; - }, "Wait for has batch1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000)) + },(reason) => { + Assert.ok(false, "has store store batch error") + + }) + ).add(() => + doAwait(batchHandler.teardown(), () => { + this.ctx.isclosed = true; + }, (reason) => { + Assert.ok(false, "teardown error") + + }) + ) } }); @@ -567,123 +488,61 @@ export class OfflineBatchHandlerTests extends AITestClass { this.ctx.hasBatch1Called = true; this.ctx.hasBatch1 = res && res.length >= 1; } - + return this._asyncQueue().add(() => { doAwait(batchHandler.storeBatch(evt), (res) => { this.ctx.storeBatch = 1; + }, (reason) => { + Assert.ok(false, "storeBatch 1 error: " + (reason && reason.message)); }); }).add(() => { doAwait(batchHandler.storeBatch(evt1), (res) => { this.ctx.storeBatch = 2; + }, (reason) => { + Assert.ok(false, "storeBatch 2 error: " + (reason && reason.message)); }); }).add(() => { doAwait(batchHandler.storeBatch(evt2), (res) => { this.ctx.storeBatch = 3; + }, (reason) => { + Assert.ok(false, "storeBatch 3 error: " + (reason && reason.message)); }); }).add(() => { doAwait(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any, (res) => { this.ctx.sendBatch1 = true; this.ctx.sendBatch1Res = res1; this.ctx.sendBatch1Pd = sender1Payload; + }, (reason) => { + Assert.ok(false, "sendNextBatch 1 error: " + (reason && reason.message)); }); }).add(() => { doAwait(batchHandler.sendNextBatch(cb2, false, {sendPOST: sender2}) as any, (res) => { - // 200 should be called first, in some case, re-try will be added back (sender2) and event2 will be returned again - // This is to guarantee the test gets events in order this.ctx.sendBatch2 = true; this.ctx.sendBatch2Res = res2; this.ctx.sendBatch2Pd = sender2Payload; + }, (reason) => { + Assert.ok(false, "sendNextBatch 2 error: " + (reason && reason.message)); }); }).add(() => { doAwait(batchHandler.sendNextBatch(cb3, false, {sendPOST: sender3}) as any, (res) => { this.ctx.sendBatch3 = true; this.ctx.sendBatch3Res = res3; this.ctx.sendBatch3Pd = sender3Payload; + }, (reason) => { + Assert.ok(false, "sendNextBatch 3 error: " + (reason && reason.message)); }); }).add(() => { doAwait(batchHandler.hasStoredBatch(cb4), (res) => { + }, (reason) => { + Assert.ok(false, "hasStoredBatch error: " + (reason && reason.message)); }); }).add(() => { doAwait(batchHandler.teardown(), () => { this.ctx.isclosed = true; + }, (reason) => { + Assert.ok(false, "teardown error: " + (reason && reason.message)); }); - - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch && storeBatch == 3) { - return true; - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let sendBatch = this.ctx.sendBatch1; - let res = this.ctx.sendBatch1Res; - let payload = this.ctx.sendBatch1Pd - - if (sendBatch) { - Assert.equal(res.length, 1, "response 1 should be called once"); - let res1 = res[0]; - Assert.equal(res1.state, eBatchSendStatus.Drop, "response 1 state should be drop"); - Assert.ok(res1.data, "response 1 should have data"); - Assert.equal(res1.data.criticalCnt, 1 ,"response 1 should have expected data"); - - Assert.equal(payload.length, 1, "payload 1 should be called once"); - let payload1 = payload[0]; - Assert.equal(payload1.criticalCnt, 1 , "payload 1 should be contain expected item"); - return true; - } - return false; - }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let sendBatch = this.ctx.sendBatch2; - let res = this.ctx.sendBatch2Res; - let payload = this.ctx.sendBatch2Pd - - if (sendBatch) { - Assert.equal(res.length, 1, "response 2 should be called once"); - let res1 = res[0]; - Assert.equal(res1.state, eBatchSendStatus.Complete, "response 2 state should be retry"); - Assert.ok(res1.data, "response 2 should have data"); - Assert.equal(res1.data.criticalCnt, 2 ,"response 2 should have expected data"); - - Assert.equal(payload.length, 1, "payload 2 should be called once"); - let payload1 = payload[0]; - Assert.equal(payload1.criticalCnt, 2 , "payload 2 should be contain expected item"); - - return true; - } - return false; - }, "Wait for send batch 2 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let sendBatch = this.ctx.sendBatch3; - let res = this.ctx.sendBatch3Res; - let payload = this.ctx.sendBatch3Pd - - if (sendBatch) { - Assert.equal(res.length, 1, "response 3 should be called once"); - let res1 = res[0]; - Assert.equal(res1.state, eBatchSendStatus.Retry, "response 3 state should be complete"); - Assert.ok(res1.data, "response 3 should have data"); - Assert.equal(res1.data.criticalCnt, 3 ,"response 3 should have expected data"); - - Assert.equal(payload.length, 1, "payload 3 nshould be called once"); - let payload1 = payload[0]; - Assert.equal(payload1.criticalCnt, 3 , "payload 3 should be contain expected item"); - return true; - } - return false; - }, "Wait for send batch 3 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let hasBatch1Called = this.ctx.hasBatch1Called; - if (hasBatch1Called) { - let hasBatch = this.ctx.hasBatch1; - Assert.equal(hasBatch, false, "should not contain any events") - return true; - } - return false; - }, "Wait for has batch1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let isclosed = this.ctx.isclosed; - if (isclosed) { - return true; - } - return false; - }, "Wait for close response" + new Date().toISOString(), 15, 1000)) + }) } @@ -717,29 +576,37 @@ export class OfflineBatchHandlerTests extends AITestClass { let evt = TestHelper.mockEvent(endpoint, 1, false); let evt1 = TestHelper.mockEvent(endpoint, 2, false); let evt2 = TestHelper.mockEvent(endpoint, 3, false); - - return this._asyncQueue().add(() => { + + let sender1Payload: any[] = []; + let sender1 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { + sender1Payload.push(payload); + oncomplete(400, {}); + }; + let res1: any[] = []; + let cb1 = (res) => { + res1.push(res); + }; + + return this._asyncQueue().add(() => doAwait(batchHandler.storeBatch(evt), (res) => { this.ctx.storeBatch = 1; - }); - }).add(() => { + }, (reason) => { + Assert.ok(false, "storeBatch 1 error: " + (reason && reason.message)); + }) + ).add(() => doAwait(batchHandler.storeBatch(evt1), (res) => { this.ctx.storeBatch = 2; - }); - }).add(() => { + }, (reason) => { + Assert.ok(false, "storeBatch 2 error: " + (reason && reason.message)); + }) + ).add(() => doAwait(batchHandler.storeBatch(evt2), (res) => { this.ctx.storeBatch = 3; - }); - }).add(() => { - let sender1Payload: any[] = []; - let sender1 = (payload: IPayloadData, oncomplete: OnCompleteCallback, sync?: boolean) => { - sender1Payload.push(payload); - oncomplete(400, {}); - }; - let res1: any[] = []; - let cb1 = (res) => { - res1.push(res); - }; + }, (reason) => { + Assert.ok(false, "storeBatch 3 error: " + (reason && reason.message)); + }) + ).add(() => + doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any, (res) => { this.ctx.sendBatch1 = true; this.ctx.sendBatch1Res = res1; @@ -754,32 +621,8 @@ export class OfflineBatchHandlerTests extends AITestClass { Assert.ok(sentcriticalCnt !== item.criticalCnt, "should not contain deleted item"); }); }); - - }); - }).concat(PollingAssert.asyncTaskPollingAssert(() => { - let storeBatch = this.ctx.storeBatch; - if (storeBatch && storeBatch == 3) { - return true; - } - return false; - }, "Wait for store batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let sendBatch = this.ctx.sendBatch1; - - if (sendBatch) { - - return true; - } - return false; - }, "Wait for send send batch response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.getAll; - - if (item) { - - return true; - } - return false; - }, "Wait for get all response" + new Date().toISOString(), 15, 1000)) - + }) + ) } }); @@ -808,12 +651,14 @@ export class OfflineBatchHandlerTests extends AITestClass { res1.push(res); } - doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { - this.ctx.sendBatch1 = true; - this.ctx.sendBatch1Res = res1; - this.ctx.sendBatch1Pd = sender1Payload; - Assert.equal(res.value.state, eBatchSendStatus.Retry, "should have retry status"); - + return this._asyncQueue().add(() => + doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { + this.ctx.sendBatch1 = true; + this.ctx.sendBatch1Res = res1; + this.ctx.sendBatch1Pd = sender1Payload; + Assert.equal(res.value.state, eBatchSendStatus.Retry, "should have retry status"); + }) + ).add(()=> doAwaitResponse(provider.getAllEvents(), (res)=> { this.ctx.getAll = true; let val = res.value; @@ -827,25 +672,8 @@ export class OfflineBatchHandlerTests extends AITestClass { let storageObject = JSON.parse(storageStr); let storageEvts = storageObject.evts; Assert.deepEqual(Object.keys(storageEvts).length, 1, "storgae should only have one event"); - }); - - }); - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { - - let sendBatch = this.ctx.sendBatch1; - - if (sendBatch) { - return true; - } - return false; - }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.getAll; - - if (item) { - return true; - } - return false; - }, "Wait for get all response" + new Date().toISOString(), 15, 1000)) + }) + ) } }); @@ -873,12 +701,14 @@ export class OfflineBatchHandlerTests extends AITestClass { res1.push(res); } - doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { - this.ctx.sendBatch1 = true; - this.ctx.sendBatch1Res = res1; - this.ctx.sendBatch1Pd = sender1Payload; - Assert.equal(res.value.state, eBatchSendStatus.Complete, "should have complete status"); - + return this._asyncQueue().add(() => + doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { + this.ctx.sendBatch1 = true; + this.ctx.sendBatch1Res = res1; + this.ctx.sendBatch1Pd = sender1Payload; + Assert.equal(res.value.state, eBatchSendStatus.Complete, "should have complete status"); + }) + ).add(() => doAwaitResponse(provider.getAllEvents(), (res)=> { this.ctx.getAll = true; let val = res.value; @@ -886,24 +716,8 @@ export class OfflineBatchHandlerTests extends AITestClass { let storageKey = "AIOffline_1_dc.services.visualstudio.com"; let storageStr = AITestClass.orgLocalStorage.getItem(storageKey) as any; Assert.deepEqual(storageStr, null, "storgae should not have one event"); - }); - - }); - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { - let sendBatch = this.ctx.sendBatch1; - - if (sendBatch) { - return true; - } - return false; - }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.getAll; - - if (item) { - return true; - } - return false; - }, "Wait for get all response" + new Date().toISOString(), 15, 1000)) + }) + ) } }); @@ -949,14 +763,17 @@ export class OfflineBatchHandlerTests extends AITestClass { let cb1 = (res) => { res1.push(res); } - - doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { - this.ctx.sendBatch1 = true; - this.ctx.sendBatch1Res = res1; - this.ctx.sendBatch1Pd = sender1Payload; - Assert.equal(res.value.state, eBatchSendStatus.Complete, "should have complete status"); - Assert.equal(res.value.data.id, evt.id, "should have expected event"); - + + + return this._asyncQueue().add(() => + doAwaitResponse(batchHandler.sendNextBatch(cb1, false, {sendPOST: sender1}) as any,(res) => { + this.ctx.sendBatch1 = true; + this.ctx.sendBatch1Res = res1; + this.ctx.sendBatch1Pd = sender1Payload; + Assert.equal(res.value.state, eBatchSendStatus.Complete, "should have complete status"); + Assert.equal(res.value.data.id, evt.id, "should have expected event"); + }) + ).add(() => doAwaitResponse(provider.getAllEvents(), (res)=> { this.ctx.getAll = true; let val = res.value; @@ -964,25 +781,8 @@ export class OfflineBatchHandlerTests extends AITestClass { let storageStr = AITestClass.orgLocalStorage.getItem(storageKey) as any; let evts = JSON.parse(storageStr).evts; Assert.deepEqual(evts, {}, "storage should not have one event"); - }); - - }); - - return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { - let sendBatch = this.ctx.sendBatch1; - - if (sendBatch) { - return true; - } - return false; - }, "Wait for send batch 1 response" + new Date().toISOString(), 15, 1000)).concat(PollingAssert.asyncTaskPollingAssert(() => { - let item = this.ctx.getAll; - - if (item) { - return true; - } - return false; - }, "Wait for get all response" + new Date().toISOString(), 15, 1000)) + }) + ) } }); @@ -1016,21 +816,21 @@ export class OfflineBatchHandlerTests extends AITestClass { }); let evt = TestHelper.mockEvent(endpoint, 1, false); + doAwaitResponse(batchHandler.storeBatch(evt, cb1),(res) => { this.ctx.storeBatch = true; if (res.rejected) { Assert.ok(false, "error should be catched"); return; } - + let item = res.value; Assert.equal(item?.state, eBatchStoreStatus.Failure, "should have expected state"); Assert.equal(item?.item.message, "add event mock error" , "should have expected message"); Assert.equal(res1.length, 1, "should call callback"); Assert.equal(res1[0].state, item?.state, "should call callback with expected response"); - - }); - + }) + return this._asyncQueue().concat(PollingAssert.asyncTaskPollingAssert(() => { let item = this.ctx.storeBatch;