Skip to content

Commit

Permalink
feat(hub-common): add getResultSiteRelativeLink so Hub Page results c…
Browse files Browse the repository at this point in the history
…an have slugs in siteRelative l (#1200)

affects: @esri/hub-common
  • Loading branch information
sonofflynn89 authored Sep 6, 2023
1 parent e090c4d commit 27e0740
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 1 deletion.
35 changes: 35 additions & 0 deletions packages/common/src/search/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ import {
ISearchGroupUsersOptions,
ISearchOptions,
} from "@esri/arcgis-rest-portal";
import { isPageType } from "../content/_internal/internalContentUtils";
import { IHubSite } from "../core";
import { getProp } from "../objects/get-prop";
import { ISearchResponse } from "../types";
import { cloneObject } from "../util";
import { IHubSearchResult } from "./types";
import { IPredicate, IQuery } from "./types/IHubCatalog";
import {
IMatchOptions,
Expand Down Expand Up @@ -294,3 +298,34 @@ export function getScopeGroupPredicate(scope: IQuery): IPredicate {
);
return groupFilter && groupFilter.predicates.find(isGroupPredicate);
}

/**
* Determines the canonical siteRelative link for a search result.
*
* We need to pass in `site` specifically for Hub Page items. Unfortunately
* for us, Hub Page items have their canonical slug stored in the corresponding
* site's data.json, not within the Hub Page item itself.
*
* NOTE: The slugs generated by indexer for Hub Page items are not canonical
* and should not be used for link generation.
*
* @param searchResult the search result we're calculating the link for
* @param site IHubSite that is related to the result
* @returns a canonical siteRelative link
*/
export function getResultSiteRelativeLink(
searchResult: IHubSearchResult,
site?: IHubSite
): string {
const { id, type, typeKeywords } = searchResult;
let siteRelativeLink = searchResult.links?.siteRelative;
if (siteRelativeLink && isPageType(type, typeKeywords)) {
const pages = site?.pages || [];
const targetPage = pages.find((p) => p.id === id);
const slug = targetPage?.slug;
if (slug) {
siteRelativeLink = siteRelativeLink.replace(id, slug);
}
}
return siteRelativeLink;
}
84 changes: 83 additions & 1 deletion packages/common/test/search/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IGroup, ISearchOptions, IUser } from "@esri/arcgis-rest-portal";
import { ISearchResponse } from "../../src";
import { IHubSite, ISearchResponse } from "../../src";
import { IHubSearchResult, IRelativeDate } from "../../src/search";
import {
expandApis,
Expand All @@ -9,6 +9,7 @@ import {
getGroupThumbnailUrl,
getNextFunction,
migrateToCollectionKey,
getResultSiteRelativeLink,
} from "../../src/search/utils";
import { MOCK_AUTH } from "../mocks/mock-auth";
import { mockUserSession } from "../test-helpers/fake-user-session";
Expand Down Expand Up @@ -336,4 +337,85 @@ describe("Search Utils:", () => {
expect(result).toBe("appAndMap");
});
});

describe("getResultSiteRelativeLink", () => {
it("returns undefined if result.links isn't present", () => {
const searchResult = {
id: "9001",
type: "Feature Service",
} as IHubSearchResult;
const result = getResultSiteRelativeLink(searchResult, null);
expect(result).toBeUndefined();
});
it("returns undefined if result.links.siteRelative isn't present", () => {
const searchResult = {
id: "9001",
type: "Feature Service",
links: {},
} as IHubSearchResult;
const result = getResultSiteRelativeLink(searchResult, null);
expect(result).toBeUndefined();
});
it("returns an unmodified siteRelative link if result isn't a Hub Page", () => {
const searchResult = {
id: "9001",
type: "Feature Service",
links: {
siteRelative: "/foo/9001",
},
} as IHubSearchResult;
const result = getResultSiteRelativeLink(searchResult, null);
expect(result).toBe("/foo/9001");
});
it("returns a Hub Page result's unmodified siteRelative link if no site is included", () => {
const searchResult = {
id: "9001",
type: "Hub Page",
links: {
siteRelative: "/foo/9001",
},
} as IHubSearchResult;
const result = getResultSiteRelativeLink(searchResult, null);
expect(result).toBe("/foo/9001");
});
it("returns a Hub Page result's unmodified siteRelative link if site has no pages", () => {
const searchResult = {
id: "9001",
type: "Hub Page",
links: {
siteRelative: "/foo/9001",
},
} as IHubSearchResult;
const result = getResultSiteRelativeLink(searchResult, {} as IHubSite);
expect(result).toBe("/foo/9001");
});
it("returns a Hub Page result's unmodified siteRelative link if matching page doesn't have a slug", () => {
const searchResult = {
id: "9001",
type: "Hub Page",
links: {
siteRelative: "/foo/9001",
},
} as IHubSearchResult;
const site = {
pages: [{ id: "9001" }],
} as IHubSite;
const result = getResultSiteRelativeLink(searchResult, site);
expect(result).toBe("/foo/9001");
});
it("substitutes the id in the siteRelative link for the matching page's slug", () => {
const searchResult = {
id: "9001",
type: "Hub Page",
links: {
siteRelative: "/foo/9001",
},
} as IHubSearchResult;
const site = {
pages: [{ id: "9001", slug: "bar" }],
} as IHubSite;
const result = getResultSiteRelativeLink(searchResult, site);
expect(result).toBe("/foo/bar");
});
});
});

0 comments on commit 27e0740

Please sign in to comment.