Skip to content

Commit

Permalink
feat: user card result to card (#1144)
Browse files Browse the repository at this point in the history
* feat: user result to card model

* chore: rebase

* feat: comments
  • Loading branch information
benstoltz authored Aug 3, 2023
1 parent 90082ba commit 866fbe7
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 84 additions & 0 deletions packages/common/src/users/view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { IHubSearchResult } from "..";
import { ResultToCardModelFn } from "../core";
import {
IConvertToCardModelOpts,
IHubCardViewModel,
} from "../core/types/IHubCardViewModel";
import { getCardModelUrlFromResult } from "../urls/getCardModelUrl";

/**
* Convert a user hub search result into a card view model that
* can be consumed by the suite of hub gallery components
*
* @param searchResult hub user search result
* @param opts view model options
*/
export const userResultToCardModel: ResultToCardModelFn = (
searchResult: IHubSearchResult,
opts?: IConvertToCardModelOpts
): IHubCardViewModel => {
const {
actionLinks = [],
baseUrl = "",
locale = "en-US",
target = "self",
} = opts || {};

const titleUrl = getCardModelUrlFromResult(searchResult, target, baseUrl);
return {
...getSharedUserCardModel(searchResult, locale),
actionLinks,
...(searchResult.index && { index: searchResult.index }),
titleUrl,
...(searchResult.links.thumbnail && {
thumbnailUrl: searchResult.links.thumbnail,
}),
};
};

/**
* Given a hub search result, construct the
* users card view model properties
*
* @param user user search result
* @param locale internationalization locale
*/
const getSharedUserCardModel = (
user: IHubSearchResult,
locale: string
): IHubCardViewModel => {
const additionalInfo = [
{
i18nKey: "org",
value: user.orgName,
},
{
i18nKey: "type",
value: user.type,
},
...(user.tags?.length
? [
{
i18nKey: "tags",
value: user.tags.join(", "),
},
]
: []),
{
i18nKey: "dateUpdated",
value: user.updatedDate.toLocaleDateString(locale),
},
];

return {
access: user.access,
badges: [],
family: user.family,
id: user.id,
source: user.name ? `@${user.id}` : undefined,
summary: user.summary,
title: user.name || `@${user.id}`,
type: user.type,
additionalInfo,
};
};
58 changes: 58 additions & 0 deletions packages/common/test/users/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { IUser } from "@esri/arcgis-rest-types";
import { ArcGISContext, IHubSearchResult } from "../../src";
import { MOCK_AUTH } from "../mocks/mock-auth";
import { IPortal } from "@esri/arcgis-rest-portal";

const USER: IUser = {
username: "mock_user",
fullName: "Mock User",
firstName: "Mock",
lastName: "User",
preferredView: null,
description: "You may also know me as Mock User.",
email: "mock_user@esri.com",
orgId: "org_id_1",
role: "org_admin",
privileges: [],
roleId: "role_id_1",
access: "public",
created: 1558412566000,
modified: 1616690771000,
provider: "arcgis",
};

export const CONTEXT: ArcGISContext = new ArcGISContext({
id: 123,
currentUser: USER,
portalUrl: "https://qaext.arcgis.com/sharing/rest",
authentication: MOCK_AUTH,
portalSelf: {
id: "123",
name: "My org",
isPortal: false,
urlKey: "www",
} as IPortal,
});

export const USER_HUB_SEARCH_RESULT: IHubSearchResult = {
access: "org",
id: "dbouwman_dc",
type: "User",
name: "Dave Bouwman",
owner: "dbouwman_dc",
summary: "Just a dude slinging javascript",
createdDate: new Date(1652819949000),
createdDateSource: "item.created",
updatedDate: new Date(1652819949000),
updatedDateSource: "item.modified",
family: "people",
links: {
self: "https://mock-home-url.com",
siteRelative: "/mock-hub-relative-url",
thumbnail: "https://thumbnail/mock-thumbnail.png",
},
orgName: "Washington, DC R&D Center (QA)",
index: 2,
typeKeywords: ["User"],
tags: ["tag1", "tag2"],
};
84 changes: 84 additions & 0 deletions packages/common/test/users/view.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { cloneObject } from "../../src/util";
import { CONTEXT, USER_HUB_SEARCH_RESULT } from "./fixtures";
import * as internalContentUtils from "../../src/content/_internal/internalContentUtils";
import * as titleUrlModule from "../../src/urls/getCardModelUrl";
import { userResultToCardModel } from "../../src/users/view";

describe("user view module:", () => {
let getShortenedCategoriesSpy: any;

beforeEach(() => {
getShortenedCategoriesSpy = spyOn(
internalContentUtils,
"getShortenedCategories"
).and.returnValue(["category1", "category2"]);
});

describe("userResultToCardModel", () => {
let getCardModelUrlFromResultSpy: any;

beforeEach(() => {
getCardModelUrlFromResultSpy = spyOn(
titleUrlModule,
"getCardModelUrlFromResult"
).and.returnValue("https://mock-title-url.com");
});

it("returns the card view model from the hub search result", () => {
const result = userResultToCardModel(USER_HUB_SEARCH_RESULT);

expect(getCardModelUrlFromResultSpy).toHaveBeenCalledTimes(1);
expect(getCardModelUrlFromResultSpy).toHaveBeenCalledWith(
USER_HUB_SEARCH_RESULT,
"self",
""
);

expect(result).toEqual({
access: USER_HUB_SEARCH_RESULT.access,
actionLinks: [],
badges: [],
id: USER_HUB_SEARCH_RESULT.id,
index: USER_HUB_SEARCH_RESULT.index,
family: "people",
source: `@${USER_HUB_SEARCH_RESULT.owner}`,
summary: USER_HUB_SEARCH_RESULT.summary,
title: USER_HUB_SEARCH_RESULT.name,
titleUrl: "https://mock-title-url.com",
thumbnailUrl: USER_HUB_SEARCH_RESULT.links?.thumbnail,
type: USER_HUB_SEARCH_RESULT.type,
additionalInfo: [
{ i18nKey: "org", value: USER_HUB_SEARCH_RESULT.orgName },
{ i18nKey: "type", value: USER_HUB_SEARCH_RESULT.type },
{
i18nKey: "tags",
value: USER_HUB_SEARCH_RESULT.tags?.join(", ") as string,
},
{
i18nKey: "dateUpdated",
value:
USER_HUB_SEARCH_RESULT.updatedDate.toLocaleDateString("en-US"),
},
],
});
});
it("does not include tags/categories in the view model's additional info if none are defined", () => {
const modifiedSearchResult = cloneObject(USER_HUB_SEARCH_RESULT);
modifiedSearchResult.tags = undefined;
modifiedSearchResult.categories = undefined;

const result = userResultToCardModel(modifiedSearchResult);

expect(result.additionalInfo?.length).toBe(3);
});
it("title and source fall back to expected default vals", () => {
const modifiedSearchResult = cloneObject(USER_HUB_SEARCH_RESULT);
modifiedSearchResult.name = undefined as any;

const result = userResultToCardModel(modifiedSearchResult);

expect(result.title).toBe(`@${USER_HUB_SEARCH_RESULT.owner}`);
expect(result.source).toBeFalsy();
});
});
});

0 comments on commit 866fbe7

Please sign in to comment.