Skip to content

Commit

Permalink
feat(getContentFromPortal): return item metadata parsed as XML if it …
Browse files Browse the repository at this point in the history
…exists

AFFECTS PACKAGES:
@esri/hub-content
  • Loading branch information
tomwayson committed Sep 15, 2020
1 parent 796686d commit 7bbce07
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 56 deletions.
18 changes: 14 additions & 4 deletions packages/content/src/portal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
cloneObject
} from "@esri/hub-common";
import { parseDatasetId } from "./slugs";
import { getContentMetadata } from "./metadata";

function itemExtentToBoundary(extent: IBBox): IHubGeography {
return (
Expand Down Expand Up @@ -129,9 +130,18 @@ export function getContentFromPortal(
const { itemId } = parseDatasetId(id);
return getItem(itemId, requestOptions).then(item => {
const content = withPortalUrls(itemToContent(item), requestOptions);
// TODO: fetch remaining content properties (i.e. recordCount, etc) based on hubType. Examples:
// - if hubType is 'dataset', then fetch recordCount
// - if hubType is 'document', do nothing?
return content;
// TODO: provide some API to let consumers opt out of making these additional requests
return getContentMetadata(itemId, requestOptions)
.then(metadata => {
content.metadata = metadata;
// TODO: fetch remaining content properties (i.e. recordCount, etc) based on hubType. Examples:
// - if hubType is 'dataset', then fetch recordCount
// - if hubType is 'document', do nothing?
return content;
})
.catch(() => {
// TODO: update the content's errors
return content;
});
});
}
139 changes: 87 additions & 52 deletions packages/content/test/portal.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,70 @@
import * as fetchMock from "fetch-mock";
import { IItem } from "@esri/arcgis-rest-portal";
import { IEnvelope } from "@esri/arcgis-rest-types";
import { IHubRequestOptions, cloneObject } from "@esri/hub-common";
import { IHubRequestOptions, cloneObject, IHubContent } from "@esri/hub-common";
import * as commonModule from "@esri/hub-common";
import {
getContentFromPortal,
itemToContent,
getItemHubType
} from "../src/index";
import * as metadataModule from "../src/metadata";
import * as itemJson from "./mocks/items/map-service.json";
import { mockUserSession } from "./test-helpers/fake-user-session";

function validateContentFromPortal(content: IHubContent, item: IItem) {
// should include all item properties
Object.keys(item).forEach(key => {
// we check name below
if (key === "name") {
return;
}
expect(content[key]).toEqual(item[key]);
});
// name should be title
expect(content.name).toBe(item.title);
// should include derived properties
expect(content.hubId).toBe(item.id);
expect(content.hubType).toBe("map");
expect(content.summary).toBe(item.snippet);
expect(content.publisher).toEqual({
name: item.owner,
username: item.owner
});
expect(content.permissions.visibility).toBe(item.access);
// no itemControl returned w/ this item, expect default
expect(content.permissions.control).toBe("view");
// this item has no properties
expect(content.actionLinks).toBeNull();
expect(content.hubActions).toBeNull();
expect(content.metrics).toBeNull();
const geometry: IEnvelope = {
xmin: -2.732,
ymin: 53.4452,
xmax: -2.4139,
ymax: 53.6093,
spatialReference: {
wkid: 4326
}
};
expect(content.boundary).toEqual({ geometry });
expect(content.license).toEqual({
name: "Custom License",
description: item.accessInformation
});
const createdDate = new Date(item.created);
expect(content.createdDate).toEqual(createdDate);
expect(content.createdDateSource).toEqual("item.created");
expect(content.publishedDate).toEqual(createdDate);
expect(content.publishedDateSource).toEqual("item.created");
expect(content.updatedDate).toEqual(new Date(item.modified));
expect(content.updatedDateSource).toEqual("item.modified");
expect(typeof content.portalHomeUrl).toBe("string");
expect(typeof content.portalApiUrl).toBe("string");
expect(typeof content.portalDataUrl).toBe("string");
expect(typeof content.thumbnailUrl).toBe("string");
}

describe("item to content", () => {
let item: IItem;
beforeEach(() => {
Expand Down Expand Up @@ -72,8 +126,13 @@ describe("get content from portal", () => {
};
});
afterEach(fetchMock.restore);
it("should fetch a portal item and return content", done => {
it("should fetch a portal item and return content w/o metadata", done => {
fetchMock.once("*", itemJson);
// emulate no metadata exists for this item
const getContentMetadataSpy = spyOn(
metadataModule,
"getContentMetadata"
).and.returnValue(Promise.reject());
const item = itemJson as IItem;
const id = item.id;
getContentFromPortal(id, requestOpts).then(content => {
Expand All @@ -82,56 +141,32 @@ describe("get content from portal", () => {
expect(url).toBe(
"https://vader.maps.arcgis.com/sharing/rest/content/items/7a153563b0c74f7eb2b3eae8a66f2fbb?f=json&token=fake-token"
);
// should include all item properties
Object.keys(item).forEach(key => {
// we check name below
if (key === "name") {
return;
}
expect(content[key]).toEqual(item[key]);
});
// name should be title
expect(content.name).toBe(item.title);
// should include derived properties
expect(content.hubId).toBe(id);
expect(content.hubType).toBe("map");
expect(content.summary).toBe(item.snippet);
expect(content.publisher).toEqual({
name: item.owner,
username: item.owner
});
expect(content.permissions.visibility).toBe(item.access);
// no itemControl returned w/ this item, expect default
expect(content.permissions.control).toBe("view");
// this item has no properties
expect(content.actionLinks).toBeNull();
expect(content.hubActions).toBeNull();
expect(content.metrics).toBeNull();
const geometry: IEnvelope = {
xmin: -2.732,
ymin: 53.4452,
xmax: -2.4139,
ymax: 53.6093,
spatialReference: {
wkid: 4326
}
};
expect(content.boundary).toEqual({ geometry });
expect(content.license).toEqual({
name: "Custom License",
description: item.accessInformation
});
const createdDate = new Date(item.created);
expect(content.createdDate).toEqual(createdDate);
expect(content.createdDateSource).toEqual("item.created");
expect(content.publishedDate).toEqual(createdDate);
expect(content.publishedDateSource).toEqual("item.created");
expect(content.updatedDate).toEqual(new Date(item.modified));
expect(content.updatedDateSource).toEqual("item.modified");
expect(typeof content.portalHomeUrl).toBe("string");
expect(typeof content.portalApiUrl).toBe("string");
expect(typeof content.portalDataUrl).toBe("string");
expect(typeof content.thumbnailUrl).toBe("string");
// verify that we attempted to fetch the metadata
expect(getContentMetadataSpy.calls.argsFor(0)[0]).toBe(id);
validateContentFromPortal(content, item);
done();
});
});
it("should fetch a portal item and return content w/ metadata", done => {
fetchMock.once("*", itemJson);
// emulate no metadata exists for this item
const mockMetadata = { Esri: { CreaDate: 20200305 } };
const getContentMetadataSpy = spyOn(
metadataModule,
"getContentMetadata"
).and.returnValue(Promise.resolve(mockMetadata));
const item = itemJson as IItem;
const id = item.id;
getContentFromPortal(id, requestOpts).then(content => {
// verify that we attempted to fetch from the portal API
const [url] = fetchMock.calls()[0];
expect(url).toBe(
"https://vader.maps.arcgis.com/sharing/rest/content/items/7a153563b0c74f7eb2b3eae8a66f2fbb?f=json&token=fake-token"
);
// verify that we attempted to fetch the metadata
expect(getContentMetadataSpy.calls.argsFor(0)[0]).toBe(id);
expect(content.metadata).toEqual(mockMetadata);
validateContentFromPortal(content, item);
done();
});
});
Expand Down

0 comments on commit 7bbce07

Please sign in to comment.