Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hub-common): add token to schedule api endpoints #1502

Merged
merged 2 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/common/src/content/_internal/internalContentUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -971,10 +971,10 @@ const isPortalFromUrl = (portalUrl: string): boolean => {

export function getSchedulerApiUrl(
itemId: string,
requestOptions: IRequestOptions
requestOptions: IUserRequestOptions
): string {
const hubApiUrlRoot = getHubApiUrlRoot(requestOptions);
return `${hubApiUrlRoot}/api/download/v1/items/${itemId}/schedule`;
return `${hubApiUrlRoot}/api/download/v1/items/${itemId}/schedule?token=${requestOptions.authentication.token}`;
}

export function getHubApiUrlRoot(requestOptions: IRequestOptions): string {
Expand Down
9 changes: 7 additions & 2 deletions packages/common/src/content/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { computeProps } from "./_internal/computeProps";
import { isHostedFeatureServiceItem } from "./hostedServiceUtils";
import { setProp } from "../objects";
import { getSchedule, isDownloadSchedulingAvailable } from "./manageSchedule";
import { IUserRequestOptions } from "@esri/arcgis-rest-auth";

const hasFeatures = (contentType: string) =>
["Feature Layer", "Table"].includes(contentType);
Expand Down Expand Up @@ -284,8 +285,12 @@ export const fetchHubContent = async (

if (isDownloadSchedulingAvailable(requestOptions, access)) {
// fetch schedule and add it to enrichments if it exists in schedule API
enrichments.schedule = (await getSchedule(item.id, requestOptions))
.schedule || { mode: "automatic" };
enrichments.schedule = (
await getSchedule(
item.id,
requestOptions as unknown as IUserRequestOptions
)
).schedule || { mode: "automatic" };
}

return modelToHubEditableContent(model, requestOptions, enrichments);
Expand Down
9 changes: 5 additions & 4 deletions packages/common/src/content/manageSchedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { cloneObject } from "../util";
import { deepEqual } from "../objects/deepEqual";
import { AccessLevel, IHubEditableContent } from "../core";
import { getSchedulerApiUrl } from "./_internal/internalContentUtils";
import { IUserRequestOptions } from "@esri/arcgis-rest-auth";

// Any code referencing these functions must first pass isDownloadSchedulingAvailable

Expand All @@ -15,7 +16,7 @@ import { getSchedulerApiUrl } from "./_internal/internalContentUtils";
*/
export const getSchedule = async (
itemId: string,
requestOptions: IRequestOptions
requestOptions: IUserRequestOptions
): Promise<IHubScheduleResponse> => {
const fetchResponse = await fetch(getSchedulerApiUrl(itemId, requestOptions));
const schedule = await fetchResponse.json();
Expand Down Expand Up @@ -65,7 +66,7 @@ export const getSchedule = async (
export const setSchedule = async (
itemId: string,
schedule: IHubSchedule,
requestOptions: IRequestOptions
requestOptions: IUserRequestOptions
): Promise<IHubScheduleResponse> => {
const body = cloneObject(schedule);
if (body.mode !== "manual") {
Expand Down Expand Up @@ -98,7 +99,7 @@ export const setSchedule = async (
*/
export const deleteSchedule = async (
itemId: string,
requestOptions: IRequestOptions
requestOptions: IUserRequestOptions
): Promise<IHubScheduleResponse> => {
const url = getSchedulerApiUrl(itemId, requestOptions);
const options = {
Expand All @@ -121,7 +122,7 @@ export const deleteSchedule = async (
*/
export const maybeUpdateSchedule = async (
content: IHubEditableContent,
requestOptions: IRequestOptions
requestOptions: IUserRequestOptions
): Promise<IHubScheduleResponse> => {
const scheduleResponse = await getSchedule(content.id, requestOptions);

Expand Down
90 changes: 62 additions & 28 deletions packages/common/test/content/manageSchedule.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ import { MOCK_HUB_REQOPTS } from "../mocks/mock-auth";
import { IHubEditableContent } from "../../src/core/types/IHubEditableContent";
import * as fetchMock from "fetch-mock";
import { getSchedulerApiUrl } from "../../src/content/_internal/internalContentUtils";
import { IUserRequestOptions } from "@esri/arcgis-rest-auth";

describe("manageSchedule", () => {
afterEach(() => {
fetchMock.restore();
});
it("getSchedulerApiUrl: returns the correct url when no version is attached on requestOptions", () => {
const url = getSchedulerApiUrl("123", MOCK_HUB_REQOPTS);
const url = getSchedulerApiUrl(
"123",
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(url).toEqual(
"https://hubqa.arcgis.com/api/download/v1/items/123/schedule"
"https://hubqa.arcgis.com/api/download/v1/items/123/schedule?token=fake-token"
);
});
it("getSchedulerApiUrl: returns the correct url when v3 is attached on requestOptions", () => {
Expand All @@ -29,15 +33,18 @@ describe("manageSchedule", () => {
hubApiUrl: "https://hubqa.arcgis.com/api/v3",
};

const url = getSchedulerApiUrl("123", requestOptions);
const url = getSchedulerApiUrl(
"123",
requestOptions as IUserRequestOptions
);
expect(url).toEqual(
"https://hubqa.arcgis.com/api/download/v1/items/123/schedule"
"https://hubqa.arcgis.com/api/download/v1/items/123/schedule?token=fake-token"
);
});
it("getSchedule: returns an error if no schedule is set", async () => {
const item = { id: "123" };
fetchMock.once(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
error: "Not Found",
message: `Download schedule for the item ${item.id} is not found.`,
Expand All @@ -46,7 +53,7 @@ describe("manageSchedule", () => {
);
const response: IHubScheduleResponse = await getSchedule(
item.id,
MOCK_HUB_REQOPTS
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.message).toEqual(
`Download schedule not found for item ${item.id}`
Expand All @@ -56,7 +63,7 @@ describe("manageSchedule", () => {
it("getSchedule: returns schedule of mode 'scheduled' if set", async () => {
const item = { id: "123" };
fetchMock.once(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
cadence: "daily",
hour: 0,
Expand All @@ -66,7 +73,7 @@ describe("manageSchedule", () => {
);
const response: IHubScheduleResponse = await getSchedule(
item.id,
MOCK_HUB_REQOPTS
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.schedule).toEqual({
mode: "scheduled",
Expand All @@ -79,15 +86,15 @@ describe("manageSchedule", () => {
it("getSchedule: returns schedule of mode 'manual' if set", async () => {
const item = { id: "123" };
fetchMock.once(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
mode: "manual",
itemId: "123",
}
);
const response: IHubScheduleResponse = await getSchedule(
item.id,
MOCK_HUB_REQOPTS
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.schedule).toEqual({
mode: "manual",
Expand All @@ -104,13 +111,17 @@ describe("manageSchedule", () => {
} as IHubSchedule;

fetchMock.post(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
message: "Download schedule set successfully.",
}
);

const response = await setSchedule(item.id, schedule, MOCK_HUB_REQOPTS);
const response = await setSchedule(
item.id,
schedule,
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.message).toEqual("Download schedule set successfully.");
expect(fetchMock.calls().length).toBe(1);
});
Expand All @@ -121,13 +132,17 @@ describe("manageSchedule", () => {
} as IHubSchedule;

fetchMock.post(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
message: "Download schedule set successfully.",
}
);

const response = await setSchedule(item.id, schedule, MOCK_HUB_REQOPTS);
const response = await setSchedule(
item.id,
schedule,
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.message).toEqual("Download schedule set successfully.");
expect(fetchMock.calls().length).toBe(1);
});
Expand All @@ -141,15 +156,19 @@ describe("manageSchedule", () => {
} as IHubSchedule;

fetchMock.post(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
title: "unit out of range",
message:
"you specified 26 (of type number) as a hour, which is invalid",
}
);

const response = await setSchedule(item.id, schedule, MOCK_HUB_REQOPTS);
const response = await setSchedule(
item.id,
schedule,
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.message).toEqual(
"you specified 26 (of type number) as a hour, which is invalid"
);
Expand All @@ -159,13 +178,16 @@ describe("manageSchedule", () => {
const item = { id: "123" };

fetchMock.delete(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
message: "Download schedule deleted successfully.",
}
);

const response = await deleteSchedule(item.id, MOCK_HUB_REQOPTS);
const response = await deleteSchedule(
item.id,
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.message).toEqual("Download schedule deleted successfully.");
expect(fetchMock.calls().length).toBe(1);
});
Expand All @@ -177,15 +199,18 @@ describe("manageSchedule", () => {
} as IHubEditableContent;

fetchMock.get(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
error: "Not Found",
message: `Download schedule for the item ${item.id} is not found.`,
statusCode: 404,
}
);

const response = await maybeUpdateSchedule(content, MOCK_HUB_REQOPTS);
const response = await maybeUpdateSchedule(
content,
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.message).toEqual(
`No schedule set, and incoming schedule is automatic.`
);
Expand All @@ -205,21 +230,24 @@ describe("manageSchedule", () => {

fetchMock
.get(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
error: "Not Found",
message: `Download schedule for the item ${item.id} is not found.`,
statusCode: 404,
}
)
.post(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
message: "Download schedule set successfully.",
}
);

const response = await maybeUpdateSchedule(content, MOCK_HUB_REQOPTS);
const response = await maybeUpdateSchedule(
content,
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.message).toEqual("Download schedule set successfully.");
expect(fetchMock.calls().length).toBe(2);
});
Expand All @@ -232,21 +260,24 @@ describe("manageSchedule", () => {

fetchMock
.get(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
cadence: "daily",
hour: 0,
timezone: "America/New_York",
}
)
.delete(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
message: "Download schedule deleted successfully.",
}
);

const response = await maybeUpdateSchedule(content, MOCK_HUB_REQOPTS);
const response = await maybeUpdateSchedule(
content,
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.message).toEqual("Download schedule deleted successfully.");
expect(fetchMock.calls().length).toBe(2);
});
Expand All @@ -263,15 +294,18 @@ describe("manageSchedule", () => {
} as IHubEditableContent;

fetchMock.get(
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule`,
`https://hubqa.arcgis.com/api/download/v1/items/${item.id}/schedule?token=fake-token`,
{
cadence: "daily",
hour: 0,
timezone: "America/New_York",
}
);

const response = await maybeUpdateSchedule(content, MOCK_HUB_REQOPTS);
const response = await maybeUpdateSchedule(
content,
MOCK_HUB_REQOPTS as IUserRequestOptions
);
expect(response.message).toEqual(
"No action needed as schedules deepEqual each other."
);
Expand Down
Loading