diff --git a/packages/common/src/core/_internal/computeItemLinks.ts b/packages/common/src/core/_internal/computeItemLinks.ts new file mode 100644 index 00000000000..608a696510d --- /dev/null +++ b/packages/common/src/core/_internal/computeItemLinks.ts @@ -0,0 +1,41 @@ +import { IItem } from "@esri/arcgis-rest-types"; +import { IRequestOptions } from "@esri/arcgis-rest-request"; +import { UserSession } from "@esri/arcgis-rest-auth"; +import { getItemHomeUrl } from "../../urls"; +import { IHubEntityLinks } from "../../core/types"; +import { getItemIdentifier } from "../../items"; +import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl"; +import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url"; +import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils"; + +/** + * Compute the links that get appended to a Hub Initiative + * search result and entity + * + * @param item + * @param requestOptions + */ +export function computeItemLinks( + item: IItem, + requestOptions: IRequestOptions +): IHubEntityLinks { + let token: string; + if (requestOptions.authentication) { + const session: UserSession = requestOptions.authentication as UserSession; + token = session.token; + } + + return { + self: getItemHomeUrl(item.id, requestOptions), + siteRelative: getHubRelativeUrl( + item.type, + // use slug if available, otherwise id + getItemIdentifier(item), + item.typeKeywords + ), + siteRelativeEntityType: getHubRelativeUrl(item.type), + // no SEO for workspace, so we always use id instead of slug + workspaceRelative: getRelativeWorkspaceUrl(item.type, item.id), + thumbnail: getItemThumbnailUrl(item, requestOptions, token), + }; +} diff --git a/packages/common/src/initiative-templates/_internal/computeLinks.ts b/packages/common/src/initiative-templates/_internal/computeLinks.ts index 27ab6f85475..08fef725b55 100644 --- a/packages/common/src/initiative-templates/_internal/computeLinks.ts +++ b/packages/common/src/initiative-templates/_internal/computeLinks.ts @@ -1,11 +1,7 @@ -import { UserSession } from "@esri/arcgis-rest-auth"; import { IRequestOptions } from "@esri/arcgis-rest-request"; import { IItem } from "@esri/arcgis-rest-types"; -import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils"; -import { getRelativeWorkspaceUrl, IHubEntityLinks } from "../../core"; -import { getItemIdentifier } from "../../items"; -import { getItemThumbnailUrl } from "../../resources"; -import { getItemHomeUrl } from "../../urls"; +import { IHubEntityLinks } from "../../core"; +import { computeItemLinks } from "../../core/_internal/computeItemLinks"; /** * Compute the links that get appended to a Hub Initiative Template @@ -19,20 +15,5 @@ export function computeLinks( item: IItem, requestOptions: IRequestOptions ): IHubEntityLinks { - let token: string; - if (requestOptions.authentication) { - const session: UserSession = requestOptions.authentication as UserSession; - token = session.token; - } - - return { - self: getItemHomeUrl(item.id, requestOptions), - siteRelative: getHubRelativeUrl(item.type, getItemIdentifier(item)), - siteRelativeEntityType: getHubRelativeUrl(item.type), - workspaceRelative: getRelativeWorkspaceUrl( - item.type, - getItemIdentifier(item) - ), - thumbnail: getItemThumbnailUrl(item, requestOptions, token), - }; + return computeItemLinks(item, requestOptions); } diff --git a/packages/common/src/initiatives/_internal/computeLinks.ts b/packages/common/src/initiatives/_internal/computeLinks.ts index e69abb6ca1e..b35eec51402 100644 --- a/packages/common/src/initiatives/_internal/computeLinks.ts +++ b/packages/common/src/initiatives/_internal/computeLinks.ts @@ -1,12 +1,7 @@ -import { IItem } from "@esri/arcgis-rest-types"; +import { computeItemLinks } from "../../core/_internal/computeItemLinks"; import { IRequestOptions } from "@esri/arcgis-rest-request"; -import { UserSession } from "@esri/arcgis-rest-auth"; -import { getItemHomeUrl } from "../../urls"; -import { IHubEntityLinks } from "../../core/types"; -import { getItemIdentifier } from "../../items"; -import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl"; -import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url"; -import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils"; +import { IItem } from "@esri/arcgis-rest-types"; +import { IHubEntityLinks } from "../../core"; /** * Compute the links that get appended to a Hub Initiative @@ -19,20 +14,5 @@ export function computeLinks( item: IItem, requestOptions: IRequestOptions ): IHubEntityLinks { - let token: string; - if (requestOptions.authentication) { - const session: UserSession = requestOptions.authentication as UserSession; - token = session.token; - } - - return { - self: getItemHomeUrl(item.id, requestOptions), - siteRelative: getHubRelativeUrl(item.type, getItemIdentifier(item)), - siteRelativeEntityType: getHubRelativeUrl(item.type), - workspaceRelative: getRelativeWorkspaceUrl( - item.type, - getItemIdentifier(item) - ), - thumbnail: getItemThumbnailUrl(item, requestOptions, token), - }; + return computeItemLinks(item, requestOptions); } diff --git a/packages/common/src/items/getItemIdentifier.ts b/packages/common/src/items/getItemIdentifier.ts index cc0adb35f73..158cf077541 100644 --- a/packages/common/src/items/getItemIdentifier.ts +++ b/packages/common/src/items/getItemIdentifier.ts @@ -1,12 +1,19 @@ import { IItem } from "@esri/arcgis-rest-portal"; import { keywordSlugToUriSlug } from "./_internal/slugConverters"; +import { appendIdToSlug } from "./slugs"; /** * Consistent means to get an item's identifier - either the slug or the id * @param item * @returns */ -export function getItemIdentifier(item: IItem): string { - const slug = item.properties?.slug; - return slug ? keywordSlugToUriSlug(slug) : item.id; +export function getItemIdentifier( + item: IItem, + includeIdInSlug = false +): string { + const { id, properties } = item; + const slug = properties?.slug; + return slug + ? keywordSlugToUriSlug(includeIdInSlug ? appendIdToSlug(slug, id) : slug) + : id; } diff --git a/packages/common/src/items/slugs.ts b/packages/common/src/items/slugs.ts index 0cad508489b..af5e01b55ec 100644 --- a/packages/common/src/items/slugs.ts +++ b/packages/common/src/items/slugs.ts @@ -4,6 +4,9 @@ import { IItem } from "@esri/arcgis-rest-types"; import { slugify } from "../utils"; import { TYPEKEYWORD_SLUG_PREFIX, truncateSlug } from "./_internal/slugs"; import { uriSlugToKeywordSlug } from "./_internal/slugConverters"; +import { isGuid } from "../utils/is-guid"; + +const SLUG_ID_SEPARATOR = "~"; /** * Create a slug, namespaced to an org and accounting for the 256 character limit @@ -61,6 +64,11 @@ export function getItemBySlug( slug: string, requestOptions: IRequestOptions ): Promise { + const id = parseIdFromSlug(slug); + if (id) { + // no need to do a typekeyword search if we have an id + return getItem(id, requestOptions); + } const slugKeyword = uriSlugToKeywordSlug(slug); return findItemsBySlug({ slug: slugKeyword }, requestOptions).then( (results) => { @@ -159,3 +167,24 @@ export function getUniqueSlug( throw Error(`Error in getUniqueSlug ${e}`); }); } + +/** + * parse out the id from a slug + * @param slug + * @returns + */ +export const parseIdFromSlug = (slug: string) => { + // try to parse the id from the slug + const parts = slug.split(SLUG_ID_SEPARATOR); + return parts.length === 2 && isGuid(parts[1]) ? parts[1] : undefined; +}; + +/** + * append an id to a slug + * @param slug + * @param id + * @returns + */ +export const appendIdToSlug = (slug: string, id: string) => { + return `${slug}${SLUG_ID_SEPARATOR}${id}`; +}; diff --git a/packages/common/src/pages/_internal/computeLinks.ts b/packages/common/src/pages/_internal/computeLinks.ts index 570e3d4d3ab..d915ba75214 100644 --- a/packages/common/src/pages/_internal/computeLinks.ts +++ b/packages/common/src/pages/_internal/computeLinks.ts @@ -1,12 +1,9 @@ import { IItem } from "@esri/arcgis-rest-types"; import { IRequestOptions } from "@esri/arcgis-rest-request"; -import { UserSession } from "@esri/arcgis-rest-auth"; import { IHubEntityLinks } from "../../core/types"; -import { getItemIdentifier } from "../../items"; -import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl"; -import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url"; +import { computeItemLinks } from "../../core/_internal/computeItemLinks"; import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils"; -import { getItemHomeUrl } from "../../urls"; +import { getItemIdentifier } from "../../items/getItemIdentifier"; /** * Compute the links that get appended to a Hub Site @@ -19,18 +16,20 @@ export function computeLinks( item: IItem, requestOptions: IRequestOptions ): IHubEntityLinks { - let token: string; - if (requestOptions.authentication) { - const session: UserSession = requestOptions.authentication as UserSession; - token = session.token; - } - + const links = computeItemLinks(item, requestOptions); + // re-compute the site relative link to include the id + // NOTE: when we expand this beyond pages we should drop this override + // and just pass true to getItemIdentifier in computeItemLinks + const siteRelative = getHubRelativeUrl( + item.type, + getItemIdentifier(item, true), + item.typeKeywords + ); return { - self: getItemHomeUrl(item.id, requestOptions), - siteRelative: getHubRelativeUrl(item.type, item.id, item.typeKeywords), - siteRelativeEntityType: getHubRelativeUrl("page"), + ...links, + // add id to site relative link + siteRelative, + // add the layout relative link layoutRelative: `/pages/${item.id}/edit`, - workspaceRelative: getRelativeWorkspaceUrl(item.type, item.id), - thumbnail: getItemThumbnailUrl(item, requestOptions, token), }; } diff --git a/packages/common/src/projects/_internal/computeLinks.ts b/packages/common/src/projects/_internal/computeLinks.ts index 9c88350d549..8931af2d983 100644 --- a/packages/common/src/projects/_internal/computeLinks.ts +++ b/packages/common/src/projects/_internal/computeLinks.ts @@ -1,12 +1,7 @@ -import { IItem } from "@esri/arcgis-rest-types"; +import { computeItemLinks } from "../../core/_internal/computeItemLinks"; import { IRequestOptions } from "@esri/arcgis-rest-request"; -import { UserSession } from "@esri/arcgis-rest-auth"; -import { getItemHomeUrl } from "../../urls"; -import { IHubEntityLinks } from "../../core/types"; -import { getItemIdentifier } from "../../items"; -import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils"; -import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl"; -import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url"; +import { IItem } from "@esri/arcgis-rest-types"; +import { IHubEntityLinks } from "../../core"; /** * Compute the links that get appended to a Hub Project @@ -14,25 +9,11 @@ import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url"; * * @param item * @param requestOptions + * @returns */ export function computeLinks( item: IItem, requestOptions: IRequestOptions ): IHubEntityLinks { - let token: string; - if (requestOptions.authentication) { - const session: UserSession = requestOptions.authentication as UserSession; - token = session.token; - } - - return { - self: getItemHomeUrl(item.id, requestOptions), - siteRelative: getHubRelativeUrl(item.type, getItemIdentifier(item)), - siteRelativeEntityType: getHubRelativeUrl(item.type), - workspaceRelative: getRelativeWorkspaceUrl( - item.type, - getItemIdentifier(item) - ), - thumbnail: getItemThumbnailUrl(item, requestOptions, token), - }; + return computeItemLinks(item, requestOptions); } diff --git a/packages/common/src/sites/_internal/computeLinks.ts b/packages/common/src/sites/_internal/computeLinks.ts index 960bd92983d..7f9c118b497 100644 --- a/packages/common/src/sites/_internal/computeLinks.ts +++ b/packages/common/src/sites/_internal/computeLinks.ts @@ -1,11 +1,8 @@ import { IItem } from "@esri/arcgis-rest-types"; import { IRequestOptions } from "@esri/arcgis-rest-request"; -import { UserSession } from "@esri/arcgis-rest-auth"; import { IHubEntityLinks } from "../../core/types"; -import { getItemIdentifier } from "../../items"; -import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl"; -import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url"; import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils"; +import { computeItemLinks } from "../../core/_internal/computeItemLinks"; /** * Compute the links that get appended to a Hub Site @@ -18,18 +15,12 @@ export function computeLinks( item: IItem, requestOptions: IRequestOptions ): IHubEntityLinks { - let token: string; - if (requestOptions.authentication) { - const session: UserSession = requestOptions.authentication as UserSession; - token = session.token; - } - + const links = computeItemLinks(item, requestOptions); return { + ...links, + // for sites we use the site's url as the self link self: item.url, - siteRelative: getHubRelativeUrl(item.type, item.id, item.typeKeywords), - siteRelativeEntityType: getHubRelativeUrl(item.type), + // add the layout relative link layoutRelative: "/edit", - workspaceRelative: getRelativeWorkspaceUrl(item.type, item.id), - thumbnail: getItemThumbnailUrl(item, requestOptions, token), }; } diff --git a/packages/common/src/templates/_internal/computeLinks.ts b/packages/common/src/templates/_internal/computeLinks.ts index fb3c8a05e26..5fd0144999a 100644 --- a/packages/common/src/templates/_internal/computeLinks.ts +++ b/packages/common/src/templates/_internal/computeLinks.ts @@ -1,12 +1,7 @@ import { IItem } from "@esri/arcgis-rest-types"; import { IRequestOptions } from "@esri/arcgis-rest-request"; -import { UserSession } from "@esri/arcgis-rest-auth"; -import { getItemHomeUrl } from "../../urls"; import { IHubEntityLinks } from "../../core/types"; -import { getItemIdentifier } from "../../items"; -import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils"; -import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl"; -import { getItemThumbnailUrl } from "../../resources/get-item-thumbnail-url"; +import { computeItemLinks } from "../../core/_internal/computeItemLinks"; /** * Compute the links that get appended to a Hub Template @@ -19,32 +14,22 @@ export function computeLinks( item: IItem, requestOptions: IRequestOptions ): IHubEntityLinks { - let token: string; - if (requestOptions.authentication) { - const session: UserSession = requestOptions.authentication as UserSession; - token = session.token; - } + const links = computeItemLinks(item, requestOptions); // If a solution template is deployed, we don't support // managing it in the workspace, so we kick users to AGO const isDeployed = item.typeKeywords?.includes("Deployed"); - const itemHomeUrl = getItemHomeUrl(item.id, requestOptions); - const siteRelativeUrl = getHubRelativeUrl( - item.type, - getItemIdentifier(item), - item.typeKeywords - ); + const { self, siteRelative, workspaceRelative } = links; + // templates have an advanced edit link + const advancedEditRelative = `${(siteRelative as string) + .split("/") + .slice(0, -1) + .join("/")}/edit/advanced`; return { - self: itemHomeUrl, - siteRelative: siteRelativeUrl, - siteRelativeEntityType: getHubRelativeUrl(item.type), - workspaceRelative: isDeployed - ? itemHomeUrl - : getRelativeWorkspaceUrl(item.type, getItemIdentifier(item)), - advancedEditRelative: `${siteRelativeUrl - .split("/") - .slice(0, -1) - .join("/")}/edit/advanced`, - thumbnail: getItemThumbnailUrl(item, requestOptions, token), + ...links, + // handle deployed templates + workspaceRelative: isDeployed ? self : workspaceRelative, + // add advanced edit relative link + advancedEditRelative, }; } diff --git a/packages/common/test/initiative-templates/_internal/computeLinks.test.ts b/packages/common/test/initiative-templates/_internal/computeLinks.test.ts deleted file mode 100644 index edbe9b1d199..00000000000 --- a/packages/common/test/initiative-templates/_internal/computeLinks.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { IItem, IUser } from "@esri/arcgis-rest-types"; -import { computeLinks } from "../../../src/initiative-templates/_internal/computeLinks"; -import { ArcGISContextManager, setProp } from "../../../src"; -import { MOCK_AUTH } from "../../mocks/mock-auth"; -import { IPortal } from "@esri/arcgis-rest-portal"; - -describe("computeLinks", () => { - let authdCtxMgr: ArcGISContextManager; - let item: IItem; - - beforeEach(async () => { - item = { - type: "Hub Initiative Template", - id: "00c", - } as IItem; - authdCtxMgr = await ArcGISContextManager.create({ - authentication: MOCK_AUTH, - currentUser: {} as IUser, - portal: { - name: "DC R&D Center", - id: "BRXFAKE", - urlKey: "fake-org", - properties: { - hub: { enabled: true }, - }, - } as unknown as IPortal, - portalUrl: "https://org.maps.arcgis.com", - }); - }); - - it("generates a links hash using the initiative template's slug", () => { - setProp("properties.slug", "mock-slug", item); - const chk = computeLinks(item, authdCtxMgr.context.requestOptions); - - expect(chk.siteRelative).toBe("/initiatives/templates/mock-slug/about"); - expect(chk.siteRelativeEntityType).toBe(""); - expect(chk.workspaceRelative).toBe( - "/workspace/initiativeTemplates/mock-slug" - ); - }); - it("generates a links hash using the initiaitve template's id when no slug is available", () => { - const chk = computeLinks(item, authdCtxMgr.context.requestOptions); - - expect(chk.siteRelative).toBe("/initiatives/templates/00c/about"); - expect(chk.workspaceRelative).toBe("/workspace/initiativeTemplates/00c"); - }); -}); diff --git a/packages/common/test/initiatives/_internal/computeLinks.test.ts b/packages/common/test/initiatives/_internal/computeLinks.test.ts deleted file mode 100644 index 4f40f2259e8..00000000000 --- a/packages/common/test/initiatives/_internal/computeLinks.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { IItem, IUser } from "@esri/arcgis-rest-types"; -import { computeLinks } from "../../../src/initiatives/_internal/computeLinks"; -import { ArcGISContextManager, setProp } from "../../../src"; -import { MOCK_AUTH } from "../../mocks/mock-auth"; -import { IPortal } from "@esri/arcgis-rest-portal"; - -describe("computeLinks", () => { - let authdCtxMgr: ArcGISContextManager; - let item: IItem; - - beforeEach(async () => { - item = { - type: "Hub Initiative", - id: "00c", - } as IItem; - authdCtxMgr = await ArcGISContextManager.create({ - authentication: MOCK_AUTH, - currentUser: {} as IUser, - portal: { - name: "DC R&D Center", - id: "BRXFAKE", - urlKey: "fake-org", - properties: { - hub: { enabled: true }, - }, - } as unknown as IPortal, - portalUrl: "https://org.maps.arcgis.com", - }); - }); - - it("generates a links hash using the initiative's slug", () => { - setProp("properties.slug", "mock-slug", item); - const chk = computeLinks(item, authdCtxMgr.context.requestOptions); - - expect(chk.siteRelative).toBe("/initiatives/mock-slug"); - expect(chk.siteRelativeEntityType).toBe("/initiatives"); - expect(chk.workspaceRelative).toBe("/workspace/initiatives/mock-slug"); - }); - it("generates a links hash using the initiative's id when no slug is available", () => { - const chk = computeLinks(item, authdCtxMgr.context.requestOptions); - - expect(chk.siteRelative).toBe("/initiatives/00c"); - expect(chk.siteRelativeEntityType).toBe("/initiatives"); - expect(chk.workspaceRelative).toBe("/workspace/initiatives/00c"); - }); -}); diff --git a/packages/common/test/items/getItemIdentifier.test.ts b/packages/common/test/items/getItemIdentifier.test.ts index 0008b374fcd..d69eb3e566e 100644 --- a/packages/common/test/items/getItemIdentifier.test.ts +++ b/packages/common/test/items/getItemIdentifier.test.ts @@ -2,19 +2,20 @@ import { IItem } from "@esri/arcgis-rest-portal"; import { getItemIdentifier } from "../../src"; describe("getItemIdentifier:", () => { + const item = { + id: "3ef", + } as unknown as IItem; + const properties = { + slug: "myorg|the-slug", + }; + const itemWithSlug = { ...item, properties }; it("returns id by default", () => { - const item = { - id: "3ef", - } as unknown as IItem; expect(getItemIdentifier(item)).toBe("3ef"); }); it("returns slug if defined", () => { - const item = { - id: "3ef", - properties: { - slug: "myorg|the-slug", - }, - } as unknown as IItem; - expect(getItemIdentifier(item)).toBe("myorg::the-slug"); + expect(getItemIdentifier(itemWithSlug)).toBe("myorg::the-slug"); + }); + it("injects id into slug if requested", () => { + expect(getItemIdentifier(itemWithSlug, true)).toBe("myorg::the-slug~3ef"); }); }); diff --git a/packages/common/test/items/slugs.test.ts b/packages/common/test/items/slugs.test.ts index dff0335e14a..969b48480e2 100644 --- a/packages/common/test/items/slugs.test.ts +++ b/packages/common/test/items/slugs.test.ts @@ -3,6 +3,9 @@ import * as slugModule from "../../src/items/slugs"; import { MOCK_AUTH } from "../groups/add-users-workflow/fixtures"; import { ISearchOptions } from "@esri/arcgis-rest-portal"; +// an id that is an actual guid +const guidId = "c90c8745f1854420b1c23e407941fd45"; + describe("slug utils: ", () => { describe("createSlug:", () => { it("combined org and dasherized title", () => { @@ -147,6 +150,30 @@ describe("slug utils: ", () => { expect(searchSpy.calls.count()).toBe(1); } }); + it("handles slug w/ an id", async () => { + const id = guidId; + const itemResult = { + id, + title: "Fake", + typeKeywords: ["one", "slug|foo-bar"], + orgId: "ghi", + } as any as portalModule.IItem; + const requestOptions = { + authentication: MOCK_AUTH, + }; + const getByIdSpy = spyOn(portalModule, "getItem").and.returnValue( + Promise.resolve(itemResult) + ); + + const result = await slugModule.getItemBySlug( + `foo-bar~${id}`, + requestOptions + ); + expect(result).toBe(itemResult); + // check if + expect(getByIdSpy).toHaveBeenCalledTimes(1); + expect(getByIdSpy).toHaveBeenCalledWith(id, requestOptions); + }); }); describe("findItemsBySlug:", () => { @@ -395,4 +422,31 @@ describe("slug utils: ", () => { } }); }); + describe("appendIdToSlug", () => { + it("appends id to slug", () => { + const slug = "foo-bar"; + const id = "3ef"; + const result = slugModule.appendIdToSlug(slug, id); + expect(result).toBe(`${slug}~${id}`); + }); + }); + describe("parseIdFromSlug", () => { + it("parses valid id from slug", () => { + const id = guidId; + const slug = `foo-bar~${id}`; + const result = slugModule.parseIdFromSlug(slug); + expect(result).toBe(id); + }); + it("returns undefined for invalid id", () => { + const id = "notaguid"; + const slug = `foo-bar~${id}`; + const result = slugModule.parseIdFromSlug(slug); + expect(result).toBeUndefined(); + }); + it("returns undefined for missing id", () => { + const slug = "foo-bar"; + const result = slugModule.parseIdFromSlug(slug); + expect(result).toBeUndefined(); + }); + }); }); diff --git a/packages/common/test/projects/_internal/computeLinks.test.ts b/packages/common/test/projects/_internal/computeLinks.test.ts deleted file mode 100644 index 8850031ede0..00000000000 --- a/packages/common/test/projects/_internal/computeLinks.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { IItem, IUser } from "@esri/arcgis-rest-types"; -import { computeLinks } from "../../../src/projects/_internal/computeLinks"; -import { ArcGISContextManager, setProp } from "../../../src"; -import { MOCK_AUTH } from "../../mocks/mock-auth"; -import { IPortal } from "@esri/arcgis-rest-portal"; - -describe("computeLinks", () => { - let authdCtxMgr: ArcGISContextManager; - let item: IItem; - - beforeEach(async () => { - item = { - type: "Hub Project", - id: "00c", - } as IItem; - authdCtxMgr = await ArcGISContextManager.create({ - authentication: MOCK_AUTH, - currentUser: {} as IUser, - portal: { - name: "DC R&D Center", - id: "BRXFAKE", - urlKey: "fake-org", - properties: { - hub: { enabled: true }, - }, - } as unknown as IPortal, - portalUrl: "https://org.maps.arcgis.com", - }); - }); - - it("generates a links hash using the project's slug", () => { - setProp("properties.slug", "mock-slug", item); - const chk = computeLinks(item, authdCtxMgr.context.requestOptions); - - expect(chk.siteRelative).toBe("/projects/mock-slug"); - expect(chk.workspaceRelative).toBe("/workspace/projects/mock-slug"); - }); - it("generates a links hash using the project's id when no slug is available", () => { - const chk = computeLinks(item, authdCtxMgr.context.requestOptions); - - expect(chk.siteRelative).toBe("/projects/00c"); - expect(chk.siteRelativeEntityType).toBe("/projects"); - expect(chk.workspaceRelative).toBe("/workspace/projects/00c"); - }); -}); diff --git a/packages/common/test/templates/_internal/computeLinks.test.ts b/packages/common/test/templates/_internal/computeLinks.test.ts index e27c9ced537..9b9eb70948d 100644 --- a/packages/common/test/templates/_internal/computeLinks.test.ts +++ b/packages/common/test/templates/_internal/computeLinks.test.ts @@ -37,7 +37,7 @@ describe("templates: computeLinks", () => { expect(chk.self).toBe("/some-item-home-url"); expect(chk.siteRelative).toBe("/templates/mock-slug/about"); - expect(chk.workspaceRelative).toBe("/workspace/templates/mock-slug"); + expect(chk.workspaceRelative).toBe("/workspace/templates/00c"); expect(chk.advancedEditRelative).toBe("/templates/mock-slug/edit/advanced"); expect(chk.thumbnail).toBe("/some-thumbnail-url"); });