From a36c20af5a625cf81cc7d05b4e682ec5ba7ebaba Mon Sep 17 00:00:00 2001 From: Nikitha Chettiar Date: Sun, 16 Aug 2020 01:11:37 -0700 Subject: [PATCH 1/9] Adding request options property to PageIterator --- src/tasks/PageIterator.ts | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/tasks/PageIterator.ts b/src/tasks/PageIterator.ts index 3fa90e4f8..0aa6f45da 100644 --- a/src/tasks/PageIterator.ts +++ b/src/tasks/PageIterator.ts @@ -10,6 +10,7 @@ */ import { Client } from "../index"; +import { MiddlewareOptions } from "../middleware/options/IMiddlewareOptions"; /** * Signature representing PageCollection @@ -25,6 +26,23 @@ export interface PageCollection { [Key: string]: any; } +/** + * Signature to define the header options as a key value pair + */ +export interface Headers { + [key: string]: string; +} + +/** + * Signature to define the options to be sent during request + * @property {Headers} headers - the header otpions for the request + * @property {MiddlewareOptions[]} middlewareoptions - The middleware options for the request + */ +export interface RequestOptions { + headers?: Headers; + middlewareOptions?: MiddlewareOptions[]; +} + /** * Signature representing callback for page iterator * @property {Function} callback - The callback function which should return boolean to continue the continue/stop the iteration. @@ -73,6 +91,11 @@ export class PageIterator { */ private complete: boolean; + /** + * Information to be added to the request + */ + private options: RequestOptions; + /** * @public * @constructor @@ -82,13 +105,14 @@ export class PageIterator { * @param {PageIteratorCallback} callBack - The callback function * @returns An instance of a PageIterator */ - public constructor(client: Client, pageCollection: PageCollection, callback: PageIteratorCallback) { + public constructor(client: Client, pageCollection: PageCollection, callback: PageIteratorCallback, options?: RequestOptions) { this.client = client; this.collection = pageCollection.value; this.nextLink = pageCollection["@odata.nextLink"]; this.deltaLink = pageCollection["@odata.deltaLink"]; this.callback = callback; this.complete = false; + this.options = options; } /** @@ -116,7 +140,14 @@ export class PageIterator { */ private async fetchAndUpdateNextPageData(): Promise { try { - const response: PageCollection = await this.client.api(this.nextLink).get(); + let graphRequest = this.client.api(this.nextLink); + if (this.options.headers) { + graphRequest = graphRequest.headers(this.options.headers); + } + if (this.options.middlewareOptions) { + graphRequest = graphRequest.middlewareOptions(this.options.middlewareOptions); + } + const response: PageCollection = await graphRequest.get(); this.collection = response.value; this.nextLink = response["@odata.nextLink"]; this.deltaLink = response["@odata.deltaLink"]; From fe2bf11597b1b3435cb72788fff771fefa394aca Mon Sep 17 00:00:00 2001 From: Nikitha Chettiar Date: Wed, 26 Aug 2020 16:58:39 -0700 Subject: [PATCH 2/9] Adding tests for page iterator task to test passing along the headers --- spec/development/workload/PageIterator.ts | 56 +++++++++++++++++++++++ src/tasks/PageIterator.ts | 34 ++++++++++---- 2 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 spec/development/workload/PageIterator.ts diff --git a/spec/development/workload/PageIterator.ts b/spec/development/workload/PageIterator.ts new file mode 100644 index 000000000..0d59edbfc --- /dev/null +++ b/spec/development/workload/PageIterator.ts @@ -0,0 +1,56 @@ +import { PageIterator, PageIteratorCallback } from "../../../src/tasks/PageIterator"; +import { Event } from "microsoft-graph"; +import { assert } from "chai"; +import { getClient } from "../test-helper"; + +const client = getClient(); +describe("PageIterator", function() { + describe("sameHeadersPassedWithPageIterator", () => { + it("verify same headers", async () => { + const response = await client + .api(`/me/events?$top=2`) + .headers({ Prefer: 'outlook.timezone= "pacific standard time"' }) + .select("id,start,end") + .get(); + + const callback: PageIteratorCallback = (eventResponse) => { + const event = eventResponse as Event; + assert.equal(event.start.timeZone, "Pacific Standard Time"); + return true; + }; + var requestOptions = { headers: { Prefer: 'outlook.timezone= "pacific standard time"' } }; + if (response["@odata.nextLink"]) { + const pageIterator = new PageIterator(client, response, callback, requestOptions); + await pageIterator.iterate(); + assert.isTrue(pageIterator.isComplete()); + } + }); + + it("differentHeadersPassedWithPageIterator", async () => { + const response = await client + .api(`/me/events?$top=4`) + .headers({ Prefer: 'outlook.timezone= "UTC"' }) + .select("id,start,end") + .get(); + + let counter = 0; + const callback: PageIteratorCallback = (eventResponse) => { + const event = eventResponse as Event; + if (counter < 4) { + assert.equal(event.start.timeZone, "UTC"); + counter++; + } else { + assert.equal(event.start.timeZone, "Pacific Standard Time"); + } + return true; + }; + + var requestOptions = { headers: { Prefer: 'outlook.timezone= "pacific standard time"' } }; + if (response["@odata.nextLink"]) { + const pageIterator = new PageIterator(client, response, callback, requestOptions); + await pageIterator.iterate(); + assert.isTrue(pageIterator.isComplete()); + } + }); + }); +}); diff --git a/src/tasks/PageIterator.ts b/src/tasks/PageIterator.ts index 0aa6f45da..39398fadd 100644 --- a/src/tasks/PageIterator.ts +++ b/src/tasks/PageIterator.ts @@ -9,8 +9,10 @@ * @module PageIterator */ +import { FetchOptions } from "../IFetchOptions"; import { Client } from "../index"; import { MiddlewareOptions } from "../middleware/options/IMiddlewareOptions"; +import { ResponseType } from "../ResponseType"; /** * Signature representing PageCollection @@ -34,13 +36,18 @@ export interface Headers { } /** - * Signature to define the options to be sent during request + * Signature to define the request options to be sent during request. + * The values of the RequestOptions properties are passed to the Graph Request object. * @property {Headers} headers - the header otpions for the request * @property {MiddlewareOptions[]} middlewareoptions - The middleware options for the request + * @property {FetchOptions} options - The fetch options for the request + * @property {ResponseType} responseType - The response type expected */ export interface RequestOptions { headers?: Headers; middlewareOptions?: MiddlewareOptions[]; + options?: FetchOptions; + responseType?: ResponseType; } /** @@ -94,7 +101,7 @@ export class PageIterator { /** * Information to be added to the request */ - private options: RequestOptions; + private requestOptions: RequestOptions; /** * @public @@ -105,14 +112,14 @@ export class PageIterator { * @param {PageIteratorCallback} callBack - The callback function * @returns An instance of a PageIterator */ - public constructor(client: Client, pageCollection: PageCollection, callback: PageIteratorCallback, options?: RequestOptions) { + public constructor(client: Client, pageCollection: PageCollection, callback: PageIteratorCallback, requestOptions?: RequestOptions) { this.client = client; this.collection = pageCollection.value; this.nextLink = pageCollection["@odata.nextLink"]; this.deltaLink = pageCollection["@odata.deltaLink"]; this.callback = callback; this.complete = false; - this.options = options; + this.requestOptions = requestOptions; } /** @@ -141,12 +148,21 @@ export class PageIterator { private async fetchAndUpdateNextPageData(): Promise { try { let graphRequest = this.client.api(this.nextLink); - if (this.options.headers) { - graphRequest = graphRequest.headers(this.options.headers); - } - if (this.options.middlewareOptions) { - graphRequest = graphRequest.middlewareOptions(this.options.middlewareOptions); + if (this.requestOptions) { + if (this.requestOptions.headers) { + graphRequest = graphRequest.headers(this.requestOptions.headers); + } + if (this.requestOptions.middlewareOptions) { + graphRequest = graphRequest.middlewareOptions(this.requestOptions.middlewareOptions); + } + if (this.requestOptions.responseType) { + graphRequest = graphRequest.responseType(this.requestOptions.responseType); + } + if (this.requestOptions.options) { + graphRequest = graphRequest.options(this.requestOptions.options); + } } + const response: PageCollection = await graphRequest.get(); this.collection = response.value; this.nextLink = response["@odata.nextLink"]; From 4ec6b14235e3132f55448569dc5bbb26333dc8b2 Mon Sep 17 00:00:00 2001 From: Nikitha Chettiar Date: Wed, 26 Aug 2020 18:59:47 -0700 Subject: [PATCH 3/9] using headersinit type for headers --- src/GraphRequest.ts | 6 ++---- src/tasks/PageIterator.ts | 9 +-------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/GraphRequest.ts b/src/GraphRequest.ts index c83f22399..5d5427697 100644 --- a/src/GraphRequest.ts +++ b/src/GraphRequest.ts @@ -79,9 +79,7 @@ export class GraphRequest { * @private * A member to hold custom header options for a request */ - private _headers: { - [key: string]: string; - }; + private _headers: HeadersInit; /** * @private @@ -431,7 +429,7 @@ export class GraphRequest { * @param {KeyValuePairObjectStringNumber} headers - The headers key value pair object * @returns The same GraphRequest instance that is being called with */ - public headers(headers: KeyValuePairObjectStringNumber): GraphRequest { + public headers(headers: KeyValuePairObjectStringNumber | HeadersInit): GraphRequest { for (const key in headers) { if (headers.hasOwnProperty(key)) { this._headers[key] = headers[key] as string; diff --git a/src/tasks/PageIterator.ts b/src/tasks/PageIterator.ts index 39398fadd..2e6e5b7bd 100644 --- a/src/tasks/PageIterator.ts +++ b/src/tasks/PageIterator.ts @@ -28,13 +28,6 @@ export interface PageCollection { [Key: string]: any; } -/** - * Signature to define the header options as a key value pair - */ -export interface Headers { - [key: string]: string; -} - /** * Signature to define the request options to be sent during request. * The values of the RequestOptions properties are passed to the Graph Request object. @@ -44,7 +37,7 @@ export interface Headers { * @property {ResponseType} responseType - The response type expected */ export interface RequestOptions { - headers?: Headers; + headers?: HeadersInit; middlewareOptions?: MiddlewareOptions[]; options?: FetchOptions; responseType?: ResponseType; From 2fa6bcece28a76df098e82f02524738cf02de57f Mon Sep 17 00:00:00 2001 From: Nikitha Chettiar Date: Fri, 28 Aug 2020 00:58:59 -0700 Subject: [PATCH 4/9] Specifying parameter definition --- src/tasks/PageIterator.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tasks/PageIterator.ts b/src/tasks/PageIterator.ts index 2e6e5b7bd..311ca13f6 100644 --- a/src/tasks/PageIterator.ts +++ b/src/tasks/PageIterator.ts @@ -31,7 +31,7 @@ export interface PageCollection { /** * Signature to define the request options to be sent during request. * The values of the RequestOptions properties are passed to the Graph Request object. - * @property {Headers} headers - the header otpions for the request + * @property {HeadersInit} headers - the header options for the request * @property {MiddlewareOptions[]} middlewareoptions - The middleware options for the request * @property {FetchOptions} options - The fetch options for the request * @property {ResponseType} responseType - The response type expected @@ -103,6 +103,7 @@ export class PageIterator { * @param {Client} client - The graph client instance * @param {PageCollection} pageCollection - The page collection object * @param {PageIteratorCallback} callBack - The callback function + * @param {RequestOptions} requestOptions - The request options * @returns An instance of a PageIterator */ public constructor(client: Client, pageCollection: PageCollection, callback: PageIteratorCallback, requestOptions?: RequestOptions) { From 20dee509af60dc604f6442b1b508f2760e24788b Mon Sep 17 00:00:00 2001 From: Nikitha Chettiar Date: Wed, 2 Sep 2020 00:58:12 -0700 Subject: [PATCH 5/9] using constants --- spec/development/workload/PageIterator.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/spec/development/workload/PageIterator.ts b/spec/development/workload/PageIterator.ts index 0d59edbfc..6f3858f32 100644 --- a/spec/development/workload/PageIterator.ts +++ b/spec/development/workload/PageIterator.ts @@ -1,24 +1,29 @@ -import { PageIterator, PageIteratorCallback } from "../../../src/tasks/PageIterator"; -import { Event } from "microsoft-graph"; import { assert } from "chai"; +import { Event } from "microsoft-graph"; + +import { PageIterator, PageIteratorCallback } from "../../../src/tasks/PageIterator"; import { getClient } from "../test-helper"; const client = getClient(); describe("PageIterator", function() { describe("sameHeadersPassedWithPageIterator", () => { + const pstHeader = { Prefer: 'outlook.timezone= "pacific standard time"' }; + const utc = "UTC"; + const pst = "Pacific Standard Time"; + it("verify same headers", async () => { const response = await client .api(`/me/events?$top=2`) - .headers({ Prefer: 'outlook.timezone= "pacific standard time"' }) + .headers(pstHeader) .select("id,start,end") .get(); const callback: PageIteratorCallback = (eventResponse) => { const event = eventResponse as Event; - assert.equal(event.start.timeZone, "Pacific Standard Time"); + assert.equal(event.start.timeZone, pst); return true; }; - var requestOptions = { headers: { Prefer: 'outlook.timezone= "pacific standard time"' } }; + var requestOptions = { headers: pstHeader }; if (response["@odata.nextLink"]) { const pageIterator = new PageIterator(client, response, callback, requestOptions); await pageIterator.iterate(); @@ -29,7 +34,7 @@ describe("PageIterator", function() { it("differentHeadersPassedWithPageIterator", async () => { const response = await client .api(`/me/events?$top=4`) - .headers({ Prefer: 'outlook.timezone= "UTC"' }) + .headers({ Prefer: `outlook.timezone= "${utc}"` }) .select("id,start,end") .get(); @@ -37,15 +42,15 @@ describe("PageIterator", function() { const callback: PageIteratorCallback = (eventResponse) => { const event = eventResponse as Event; if (counter < 4) { - assert.equal(event.start.timeZone, "UTC"); + assert.equal(event.start.timeZone, utc); counter++; } else { - assert.equal(event.start.timeZone, "Pacific Standard Time"); + assert.equal(event.start.timeZone, pst); } return true; }; - var requestOptions = { headers: { Prefer: 'outlook.timezone= "pacific standard time"' } }; + var requestOptions = { headers: pstHeader }; if (response["@odata.nextLink"]) { const pageIterator = new PageIterator(client, response, callback, requestOptions); await pageIterator.iterate(); From e9dfb1957a9bb486fb988e631a1218fd04b200c3 Mon Sep 17 00:00:00 2001 From: Nikitha Chettiar Date: Wed, 2 Sep 2020 01:13:37 -0700 Subject: [PATCH 6/9] Updating function documentation --- src/GraphRequest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GraphRequest.ts b/src/GraphRequest.ts index 5d5427697..237266359 100644 --- a/src/GraphRequest.ts +++ b/src/GraphRequest.ts @@ -426,7 +426,7 @@ export class GraphRequest { /** * @public * Sets the custom headers for a request - * @param {KeyValuePairObjectStringNumber} headers - The headers key value pair object + * @param {KeyValuePairObjectStringNumber | HeadersInit} headers - The request headers * @returns The same GraphRequest instance that is being called with */ public headers(headers: KeyValuePairObjectStringNumber | HeadersInit): GraphRequest { From 6c879fc2bbbe097cf5f0a921fac263ab221a8f93 Mon Sep 17 00:00:00 2001 From: Nikitha Chettiar Date: Tue, 8 Sep 2020 21:03:36 -0700 Subject: [PATCH 7/9] remove response type, test passing fetchoptions --- spec/development/workload/PageIterator.ts | 6 +++--- src/tasks/PageIterator.ts | 15 +++++---------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/spec/development/workload/PageIterator.ts b/spec/development/workload/PageIterator.ts index 6f3858f32..a01ca1073 100644 --- a/spec/development/workload/PageIterator.ts +++ b/spec/development/workload/PageIterator.ts @@ -1,7 +1,7 @@ import { assert } from "chai"; import { Event } from "microsoft-graph"; -import { PageIterator, PageIteratorCallback } from "../../../src/tasks/PageIterator"; +import { PageIterator, PageIteratorCallback, GraphRequestOptions } from "../../../src/tasks/PageIterator"; import { getClient } from "../test-helper"; const client = getClient(); @@ -23,13 +23,13 @@ describe("PageIterator", function() { assert.equal(event.start.timeZone, pst); return true; }; - var requestOptions = { headers: pstHeader }; + var requestOptions: GraphRequestOptions = { options: { headers: pstHeader } }; if (response["@odata.nextLink"]) { const pageIterator = new PageIterator(client, response, callback, requestOptions); await pageIterator.iterate(); assert.isTrue(pageIterator.isComplete()); } - }); + }).timeout(20 * 1000); it("differentHeadersPassedWithPageIterator", async () => { const response = await client diff --git a/src/tasks/PageIterator.ts b/src/tasks/PageIterator.ts index 311ca13f6..b23cc68a1 100644 --- a/src/tasks/PageIterator.ts +++ b/src/tasks/PageIterator.ts @@ -30,17 +30,15 @@ export interface PageCollection { /** * Signature to define the request options to be sent during request. - * The values of the RequestOptions properties are passed to the Graph Request object. + * The values of the GraphRequestOptions properties are passed to the Graph Request object. * @property {HeadersInit} headers - the header options for the request * @property {MiddlewareOptions[]} middlewareoptions - The middleware options for the request * @property {FetchOptions} options - The fetch options for the request - * @property {ResponseType} responseType - The response type expected */ -export interface RequestOptions { +export interface GraphRequestOptions { headers?: HeadersInit; middlewareOptions?: MiddlewareOptions[]; options?: FetchOptions; - responseType?: ResponseType; } /** @@ -94,7 +92,7 @@ export class PageIterator { /** * Information to be added to the request */ - private requestOptions: RequestOptions; + private requestOptions: GraphRequestOptions; /** * @public @@ -103,10 +101,10 @@ export class PageIterator { * @param {Client} client - The graph client instance * @param {PageCollection} pageCollection - The page collection object * @param {PageIteratorCallback} callBack - The callback function - * @param {RequestOptions} requestOptions - The request options + * @param {GraphRequestOptions} requestOptions - The request options * @returns An instance of a PageIterator */ - public constructor(client: Client, pageCollection: PageCollection, callback: PageIteratorCallback, requestOptions?: RequestOptions) { + public constructor(client: Client, pageCollection: PageCollection, callback: PageIteratorCallback, requestOptions?: GraphRequestOptions) { this.client = client; this.collection = pageCollection.value; this.nextLink = pageCollection["@odata.nextLink"]; @@ -149,9 +147,6 @@ export class PageIterator { if (this.requestOptions.middlewareOptions) { graphRequest = graphRequest.middlewareOptions(this.requestOptions.middlewareOptions); } - if (this.requestOptions.responseType) { - graphRequest = graphRequest.responseType(this.requestOptions.responseType); - } if (this.requestOptions.options) { graphRequest = graphRequest.options(this.requestOptions.options); } From 10e9c914b3aeb31e9b7a32bb81130b20f38dba6c Mon Sep 17 00:00:00 2001 From: Nikitha Chettiar Date: Thu, 24 Sep 2020 01:07:19 -0700 Subject: [PATCH 8/9] testing requestOptions set in pageiterator --- spec/development/workload/PageIterator.ts | 158 ++++++++++++------ src/middleware/ChaosHandler.ts | 16 +- src/middleware/options/ChaosHandlerOptions.ts | 16 +- 3 files changed, 133 insertions(+), 57 deletions(-) diff --git a/spec/development/workload/PageIterator.ts b/spec/development/workload/PageIterator.ts index a01ca1073..12e9063e1 100644 --- a/spec/development/workload/PageIterator.ts +++ b/spec/development/workload/PageIterator.ts @@ -1,61 +1,123 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + import { assert } from "chai"; import { Event } from "microsoft-graph"; -import { PageIterator, PageIteratorCallback, GraphRequestOptions } from "../../../src/tasks/PageIterator"; +import { PageIterator, PageIteratorCallback, GraphRequestOptions, PageCollection } from "../../../src/tasks/PageIterator"; import { getClient } from "../test-helper"; +import { ChaosHandler } from "../../../src/middleware/ChaosHandler"; +import { ChaosHandlerOptions } from "../../../src/middleware/options/ChaosHandlerOptions"; +import { ChaosStrategy } from "../../../src/middleware/options/ChaosStrategy"; +import { Client, ClientOptions } from "../../../src"; const client = getClient(); describe("PageIterator", function() { - describe("sameHeadersPassedWithPageIterator", () => { - const pstHeader = { Prefer: 'outlook.timezone= "pacific standard time"' }; - const utc = "UTC"; - const pst = "Pacific Standard Time"; - - it("verify same headers", async () => { - const response = await client - .api(`/me/events?$top=2`) - .headers(pstHeader) - .select("id,start,end") - .get(); - - const callback: PageIteratorCallback = (eventResponse) => { - const event = eventResponse as Event; + const pstHeader = { Prefer: 'outlook.timezone= "pacific standard time"' }; + const utc = "UTC"; + const pst = "Pacific Standard Time"; + const testURL = "/me/events"; + + before(async function() { + this.timeout(20000); + + const response = await client.api(testURL).get(); + const numberOfEvents = 4; + const existingEventsCount = response.value.length; + + if (existingEventsCount >= numberOfEvents) { + return; + } + const eventSubject = '"subject": "Test event '; + const eventTimeZone = '"timeZone": "UTC"'; + const eventStartDateTime = '"start": { "dateTime":"' + new Date().toISOString() + '",' + eventTimeZone + "}"; + const eventEndDateTime = '"end": { "dateTime":"' + new Date().toISOString() + '",' + eventTimeZone + "}"; + + for (let i = 1; i <= numberOfEvents - existingEventsCount; i++) { + const eventBody = "{" + eventSubject + "" + 1 + '",' + eventStartDateTime + "," + eventEndDateTime + "}"; + const response = await client.api(testURL).post(eventBody); + if (response.error) { + throw response.error; + } + } + }); + + it("same headers passed with pageIterator", async () => { + const response = await client + .api(`${testURL}?$top=2`) + .headers(pstHeader) + .select("id,start,end") + .get(); + + const callback: PageIteratorCallback = (eventResponse) => { + const event = eventResponse as Event; + assert.equal(event.start.timeZone, pst); + return true; + }; + var requestOptions: GraphRequestOptions = { options: { headers: pstHeader } }; + if (response["@odata.nextLink"]) { + const pageIterator = new PageIterator(client, response, callback, requestOptions); + await pageIterator.iterate(); + assert.isTrue(pageIterator.isComplete()); + } + }).timeout(30 * 1000); + + it("different headers passed with pageIterator", async () => { + const response = await client + .api(`${testURL}?$top=2`) + .headers({ Prefer: `outlook.timezone= "${utc}"` }) + .select("id,start,end") + .get(); + + let counter = 0; + const callback: PageIteratorCallback = (eventResponse) => { + const event = eventResponse as Event; + if (counter < 2) { + assert.equal(event.start.timeZone, utc); + counter++; + } else { assert.equal(event.start.timeZone, pst); - return true; - }; - var requestOptions: GraphRequestOptions = { options: { headers: pstHeader } }; - if (response["@odata.nextLink"]) { - const pageIterator = new PageIterator(client, response, callback, requestOptions); - await pageIterator.iterate(); - assert.isTrue(pageIterator.isComplete()); } - }).timeout(20 * 1000); - - it("differentHeadersPassedWithPageIterator", async () => { - const response = await client - .api(`/me/events?$top=4`) - .headers({ Prefer: `outlook.timezone= "${utc}"` }) - .select("id,start,end") - .get(); - - let counter = 0; - const callback: PageIteratorCallback = (eventResponse) => { - const event = eventResponse as Event; - if (counter < 4) { - assert.equal(event.start.timeZone, utc); - counter++; - } else { - assert.equal(event.start.timeZone, pst); - } - return true; + return true; + }; + + var requestOptions = { headers: pstHeader }; + if (response["@odata.nextLink"]) { + const pageIterator = new PageIterator(client, response, callback, requestOptions); + await pageIterator.iterate(); + assert.isTrue(pageIterator.isComplete()); + } + }).timeout(30 * 1000); + + it("setting middleware with pageIterator", async () => { + const middleware = new ChaosHandler(); + const getPageCollection = () => { + return { + value: [], + "@odata.nextLink": "nextURL", + additionalContent: "additional content", }; + }; + const clientOptions: ClientOptions = { + middleware, + }; + const responseBody = { value: [{ event1: "value1" }, { event2: "value2" }] }; + let counter = 1; + const callback: PageIteratorCallback = (data) => { + assert.equal(data["event" + counter], "value" + counter); + counter++; + return true; + }; - var requestOptions = { headers: pstHeader }; - if (response["@odata.nextLink"]) { - const pageIterator = new PageIterator(client, response, callback, requestOptions); - await pageIterator.iterate(); - assert.isTrue(pageIterator.isComplete()); - } - }); + const middlewareOptions = [new ChaosHandlerOptions(ChaosStrategy.MANUAL, 200, "middleware options for pageIterator", 0, responseBody)]; + const requestOptions = { middlewareOptions }; + + const client = Client.initWithMiddleware(clientOptions); + const pageIterator = new PageIterator(client, getPageCollection(), callback, requestOptions); + await pageIterator.iterate(); }); }); diff --git a/src/middleware/ChaosHandler.ts b/src/middleware/ChaosHandler.ts index c79252cd0..60795c298 100644 --- a/src/middleware/ChaosHandler.ts +++ b/src/middleware/ChaosHandler.ts @@ -91,15 +91,19 @@ export class ChaosHandler implements Middleware { * @param {string} statusMessage - the status message to be returned for the request * @param {string} requestID - request id * @param {string} requestDate - date of the request + * @param {string} requestBody - the request body to be returned for the request * @returns response body */ - private createResponseBody(statusCode: number, statusMessage: string, requestID: string, requestDate: string) { - let responseBody: any; + private createResponseBody(statusCode: number, statusMessage: string, requestID: string, requestDate: string, responseBody?: any) { + if (responseBody) { + return responseBody; + } + let body: any; if (statusCode >= 400) { const codeMessage: string = httpStatusCode[statusCode]; const errMessage: string = statusMessage; - responseBody = { + body = { error: { code: codeMessage, message: errMessage, @@ -110,9 +114,9 @@ export class ChaosHandler implements Middleware { }, }; } else { - responseBody = {}; + body = {}; } - return responseBody; + return body; } /** @@ -132,7 +136,7 @@ export class ChaosHandler implements Middleware { requestID = generateUUID(); requestDate = new Date(); responseHeader = this.createResponseHeaders(chaosHandlerOptions.statusCode, requestID, requestDate.toString()); - responseBody = this.createResponseBody(chaosHandlerOptions.statusCode, chaosHandlerOptions.statusMessage, requestID, requestDate.toString()); + responseBody = this.createResponseBody(chaosHandlerOptions.statusCode, chaosHandlerOptions.statusMessage, requestID, requestDate.toString(), chaosHandlerOptions.responseBody); const init: any = { url: requestURL, status: chaosHandlerOptions.statusCode, statusText: chaosHandlerOptions.statusMessage, headers: responseHeader }; context.response = new Response(responseBody, init); } catch (error) { diff --git a/src/middleware/options/ChaosHandlerOptions.ts b/src/middleware/options/ChaosHandlerOptions.ts index c74fe76cb..762705e67 100644 --- a/src/middleware/options/ChaosHandlerOptions.ts +++ b/src/middleware/options/ChaosHandlerOptions.ts @@ -48,20 +48,30 @@ export class ChaosHandlerOptions implements MiddlewareOptions { */ public chaosPercentage: number; + /** + * The response body to be returned in the response + * + * @public + */ + public responseBody: any; + /** * @public * @constructor * To create an instance of Testing Handler Options * @param {ChaosStrategy} ChaosStrategy - Specifies the startegy used for the Testing Handler -> RAMDOM/MANUAL - * @param {number?} statusCode - The Message to be returned in the response - * @param {string} - The Message to be returned in the response + * @param {number?} statusCode - The statusCode to be returned in the response + * @param {string} statusMessage - The Message to be returned in the response + * @param {number?} chaosPercentage - The percentage of randomness/chaos in the handler + * @param {any} responseBody - The response body to be returned in the response * @returns An instance of ChaosHandlerOptions */ - public constructor(chaosStrategy: ChaosStrategy = ChaosStrategy.RANDOM, statusCode?: number, statusMessage: string = "Some error Happened", chaosPercentage?: number) { + public constructor(chaosStrategy: ChaosStrategy = ChaosStrategy.RANDOM, statusCode?: number, statusMessage: string = "Some error Happened", chaosPercentage?: number, responseBody?: any) { this.chaosStrategy = chaosStrategy; this.statusCode = statusCode; this.statusMessage = statusMessage; this.chaosPercentage = chaosPercentage !== undefined ? chaosPercentage : 10; + this.responseBody = responseBody; if (this.chaosPercentage > 100) { throw new Error("Error Pecentage can not be more than 100"); } From 3cf70e33dda19c33309d6558ff1cf54e55a48fee Mon Sep 17 00:00:00 2001 From: Nikitha Chettiar Date: Fri, 25 Sep 2020 13:18:27 -0700 Subject: [PATCH 9/9] typos, optional parameters comments --- src/middleware/ChaosHandler.ts | 2 +- src/middleware/options/ChaosHandlerOptions.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/middleware/ChaosHandler.ts b/src/middleware/ChaosHandler.ts index 60795c298..5944cad79 100644 --- a/src/middleware/ChaosHandler.ts +++ b/src/middleware/ChaosHandler.ts @@ -91,7 +91,7 @@ export class ChaosHandler implements Middleware { * @param {string} statusMessage - the status message to be returned for the request * @param {string} requestID - request id * @param {string} requestDate - date of the request - * @param {string} requestBody - the request body to be returned for the request + * @param {any?} requestBody - the request body to be returned for the request * @returns response body */ private createResponseBody(statusCode: number, statusMessage: string, requestID: string, requestDate: string, responseBody?: any) { diff --git a/src/middleware/options/ChaosHandlerOptions.ts b/src/middleware/options/ChaosHandlerOptions.ts index 762705e67..1f3c0f6b1 100644 --- a/src/middleware/options/ChaosHandlerOptions.ts +++ b/src/middleware/options/ChaosHandlerOptions.ts @@ -20,7 +20,7 @@ import { MiddlewareOptions } from "./IMiddlewareOptions"; */ export class ChaosHandlerOptions implements MiddlewareOptions { /** - * Specifies the startegy used for the Testing Handler -> RAMDOM/MANUAL + * Specifies the startegy used for the Testing Handler -> RANDOM/MANUAL * * @public */ @@ -63,7 +63,7 @@ export class ChaosHandlerOptions implements MiddlewareOptions { * @param {number?} statusCode - The statusCode to be returned in the response * @param {string} statusMessage - The Message to be returned in the response * @param {number?} chaosPercentage - The percentage of randomness/chaos in the handler - * @param {any} responseBody - The response body to be returned in the response + * @param {any?} responseBody - The response body to be returned in the response * @returns An instance of ChaosHandlerOptions */ public constructor(chaosStrategy: ChaosStrategy = ChaosStrategy.RANDOM, statusCode?: number, statusMessage: string = "Some error Happened", chaosPercentage?: number, responseBody?: any) {