From fc55db0b9300f77da6518400e6cf92bc7fa26464 Mon Sep 17 00:00:00 2001 From: john gravois Date: Fri, 23 Feb 2018 11:23:53 -0800 Subject: [PATCH] fix(items): dont override user supplied parameters when updating items AFFECTS PACKAGES: @esri/arcgis-rest-items ISSUES CLOSED: #117 --- packages/arcgis-rest-items/src/items.ts | 25 +- packages/arcgis-rest-items/test/items.test.ts | 237 ++++++++++++++++++ 2 files changed, 258 insertions(+), 4 deletions(-) diff --git a/packages/arcgis-rest-items/src/items.ts b/packages/arcgis-rest-items/src/items.ts index 3d1941190d..728f9c48dc 100644 --- a/packages/arcgis-rest-items/src/items.ts +++ b/packages/arcgis-rest-items/src/items.ts @@ -145,7 +145,10 @@ export function createItemInFolder( } // serialize the item into something Portal will accept - requestOptions.params = serializeItem(requestOptions.item); + requestOptions.params = { + ...requestOptions.params, + ...serializeItem(requestOptions.item) + }; return request(url, requestOptions); } @@ -184,6 +187,7 @@ export function addItemJsonData( // a `text` form field. It can also be sent with the `.create` call by sending // a `.data` property. requestOptions.params = { + ...requestOptions.params, text: JSON.stringify(requestOptions.data) }; @@ -245,7 +249,10 @@ export function updateItem(requestOptions: IItemRequestOptions): Promise { }/items/${requestOptions.item.id}/update`; // serialize the item into something Portal will accept - requestOptions.params = serializeItem(requestOptions.item); + requestOptions.params = { + ...requestOptions.params, + ...serializeItem(requestOptions.item) + }; return request(url, requestOptions); } @@ -311,7 +318,11 @@ export function getItemResources( requestOptions.id }/resources`; - requestOptions.params = { num: 1000 }; + // mix in user supplied params + requestOptions.params = { + ...requestOptions.params, + num: 1000 + }; return request(url, requestOptions); } @@ -330,7 +341,9 @@ export function updateItemResource( requestOptions.id }/updateResources`; + // mix in user supplied params requestOptions.params = { + ...requestOptions.params, fileName: requestOptions.name, text: requestOptions.content }; @@ -352,7 +365,11 @@ export function removeItemResource( requestOptions.id }/removeResources`; - requestOptions.params = { resource: requestOptions.resource }; + // mix in user supplied params + requestOptions.params = { + ...requestOptions.params, + resource: requestOptions.resource + }; return request(url, requestOptions); } diff --git a/packages/arcgis-rest-items/test/items.test.ts b/packages/arcgis-rest-items/test/items.test.ts index b6d75d5111..589be07979 100644 --- a/packages/arcgis-rest-items/test/items.test.ts +++ b/packages/arcgis-rest-items/test/items.test.ts @@ -55,6 +55,7 @@ describe("search", () => { fail(e); }); }); + it("should take num, start, sortField, sortDir and construct the request", done => { fetchMock.once("*", SearchResponse); @@ -80,6 +81,7 @@ describe("search", () => { fail(e); }); }); + it("should return an item by id", done => { fetchMock.once("*", ItemResponse); @@ -246,6 +248,7 @@ describe("search", () => { fail(e); }); }); + it("should create an item in a folder", done => { fetchMock.once("*", ItemSuccessResponse); const fakeItem = { @@ -286,6 +289,52 @@ describe("search", () => { fail(e); }); }); + + it("should create an item in a folder and pass through arbitrary params", done => { + fetchMock.once("*", ItemSuccessResponse); + const fakeItem = { + owner: "dbouwman", + title: "my fake item", + description: "yep its fake", + snipped: "so very fake", + type: "Web Mapping Application", + typeKeywords: ["fake", "kwds"], + tags: ["fakey", "mcfakepants"] + }; + createItemInFolder({ + owner: "dbouwman", + item: fakeItem, + folder: "someFolder", + params: { + foo: "bar" + }, + ...MOCK_USER_REQOPTS + }) + .then(response => { + expect(fetchMock.called()).toEqual(true); + const [url, options]: [string, RequestInit] = fetchMock.lastCall("*"); + expect(url).toEqual( + "https://myorg.maps.arcgis.com/sharing/rest/content/users/dbouwman/someFolder/addItem" + ); + expect(options.method).toBe("POST"); + expect(options.body).toContain("f=json"); + expect(options.body).toContain(encodeParam("token", "fake-token")); + expect(options.body).toContain("owner=dbouwman"); + expect(options.body).toContain("foo=bar"); + // ensure the array props are serialized into strings + expect(options.body).toContain( + encodeParam("typeKeywords", "fake, kwds") + ); + expect(options.body).toContain( + encodeParam("tags", "fakey, mcfakepants") + ); + done(); + }) + .catch(e => { + fail(e); + }); + }); + it("should create an item in a folder when no owner is passed", done => { fetchMock.once("*", ItemSuccessResponse); const fakeItem = { @@ -358,6 +407,7 @@ describe("search", () => { fail(e); }); }); + it("should add data to an item, no owner passed", done => { fetchMock.once("*", ItemSuccessResponse); const fakeData = { @@ -391,6 +441,44 @@ describe("search", () => { fail(e); }); }); + + it("should add data to an item, extra parameters", done => { + fetchMock.once("*", ItemSuccessResponse); + const fakeData = { + values: { + key: "someValue" + } + }; + // addItemJsonData("3ef", "dbouwman", fakeData, MOCK_REQOPTS) + addItemJsonData({ + id: "3ef", + data: fakeData, + ...MOCK_USER_REQOPTS, + params: { + relationshipType: "WMA2Code" + } + }) + .then(response => { + expect(fetchMock.called()).toEqual(true); + const [url, options]: [string, RequestInit] = fetchMock.lastCall("*"); + expect(url).toEqual( + "https://myorg.maps.arcgis.com/sharing/rest/content/users/casey/items/3ef/update" + ); + expect(options.method).toBe("POST"); + expect(options.body).toContain("relationshipType=WMA2Code"); + expect(options.body).toContain("f=json"); + expect(options.body).toContain("token=fake-token"); + expect(options.body).toContain( + encodeParam("text", JSON.stringify(fakeData)) + ); + + done(); + }) + .catch(e => { + fail(e); + }); + }); + it("should update an item, including data", done => { fetchMock.once("*", ItemSuccessResponse); const fakeItem = { @@ -439,6 +527,71 @@ describe("search", () => { }); }); + it("should update an item, including data and service proxy params", done => { + fetchMock.once("*", ItemSuccessResponse); + const fakeItem = { + id: "5bc", + owner: "dbouwman", + title: "my fake item", + description: "yep its fake", + snipped: "so very fake", + type: "Web Mapping Application", + typeKeywords: ["fake", "kwds"], + tags: ["fakey", "mcfakepants"], + properties: { + key: "somevalue" + }, + serviceProxyParams: { + hitsPerInterval: 2, + intervalSeconds: 60, + referrers: ["http://"] + }, + data: { + values: { + key: "value" + } + } + }; + + updateItem({ + item: fakeItem, + params: { foo: "bar" }, + ...MOCK_USER_REQOPTS + }) + .then(response => { + expect(fetchMock.called()).toEqual(true); + const [url, options]: [string, RequestInit] = fetchMock.lastCall("*"); + expect(url).toEqual( + "https://myorg.maps.arcgis.com/sharing/rest/content/users/dbouwman/items/5bc/update" + ); + expect(options.method).toBe("POST"); + expect(options.body).toContain(encodeParam("f", "json")); + expect(options.body).toContain(encodeParam("token", "fake-token")); + expect(options.body).toContain(encodeParam("owner", "dbouwman")); + expect(options.body).toContain(encodeParam("foo", "bar")); + expect(options.body).toContain( + encodeParam( + "serviceProxyParams", + '{"hitsPerInterval":2,"intervalSeconds":60,"referrers":["http://"]}' + ) + ); + // ensure the array props are serialized into strings + expect(options.body).toContain( + encodeParam("typeKeywords", "fake, kwds") + ); + expect(options.body).toContain( + encodeParam("tags", "fakey, mcfakepants") + ); + expect(options.body).toContain( + encodeParam("text", JSON.stringify(fakeItem.data)) + ); + done(); + }) + .catch(e => { + fail(e); + }); + }); + it("should remove an item", done => { fetchMock.once("*", ItemSuccessResponse); removeItem({ @@ -588,6 +741,30 @@ describe("search", () => { }); }); + it("get item resources with extra parameters", done => { + fetchMock.once("*", GetItemResourcesResponse); + getItemResources({ + id: "3ef", + ...MOCK_USER_REQOPTS, + params: { + resourcesPrefix: "foolder" + } + }) + .then(response => { + const [url, options]: [string, RequestInit] = fetchMock.lastCall("*"); + expect(url).toEqual( + "https://myorg.maps.arcgis.com/sharing/rest/content/items/3ef/resources" + ); + expect(options.method).toBe("POST"); + expect(options.body).toContain("f=json"); + expect(options.body).toContain("resourcesPrefix=foolder"); + done(); + }) + .catch(e => { + fail(e); + }); + }); + it("update an item resource", done => { fetchMock.once("*", UpdateItemResourceResponse); updateItemResource({ @@ -643,6 +820,37 @@ describe("search", () => { }); }); + it("update an item resource with extra params", done => { + fetchMock.once("*", UpdateItemResourceResponse); + updateItemResource({ + id: "3ef", + name: "image/banner.png", + content: "jumbotron", + ...MOCK_USER_REQOPTS, + params: { + resourcesPrefix: "foolder" + } + }) + .then(response => { + const [url, options]: [string, RequestInit] = fetchMock.lastCall("*"); + expect(url).toEqual( + "https://myorg.maps.arcgis.com/sharing/rest/content/users/casey/items/3ef/updateResources" + ); + expect(options.method).toBe("POST"); + expect(options.body).toContain("f=json"); + expect(options.body).toContain( + encodeParam("fileName", "image/banner.png") + ); + expect(options.body).toContain("resourcesPrefix=foolder"); + expect(options.body).toContain(encodeParam("text", "jumbotron")); + expect(options.body).toContain(encodeParam("token", "fake-token")); + done(); + }) + .catch(e => { + fail(e); + }); + }); + it("should remove a resource", done => { fetchMock.once("*", RemoveItemResourceResponse); removeItemResource({ @@ -693,5 +901,34 @@ describe("search", () => { fail(e); }); }); + + it("should remove a resource with extra params", done => { + fetchMock.once("*", RemoveItemResourceResponse); + removeItemResource({ + id: "3ef", + resource: "image/banner.png", + ...MOCK_USER_REQOPTS, + params: { + deleteAll: true + } + }) + .then(response => { + const [url, options]: [string, RequestInit] = fetchMock.lastCall("*"); + expect(url).toEqual( + "https://myorg.maps.arcgis.com/sharing/rest/content/users/casey/items/3ef/removeResources" + ); + expect(options.method).toBe("POST"); + expect(options.body).toContain(encodeParam("f", "json")); + expect(options.body).toContain(encodeParam("deleteAll", "true")); + expect(options.body).toContain( + encodeParam("resource", "image/banner.png") + ); + expect(options.body).toContain(encodeParam("token", "fake-token")); + done(); + }) + .catch(e => { + fail(e); + }); + }); }); // auth requests });