Skip to content

Commit 0b9465f

Browse files
fix: auto-populating groups in project creation (#1225)
1 parent 11c8a58 commit 0b9465f

File tree

2 files changed

+77
-20
lines changed

2 files changed

+77
-20
lines changed

packages/common/src/projects/HubProject.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import { cloneObject, maybePush } from "../util";
3636
import { createProject, editorToProject, updateProject } from "./edit";
3737
import { ProjectEditorType } from "./_internal/ProjectSchema";
3838
import { enrichEntity } from "../core/enrichEntity";
39+
import { getProp } from "../objects";
40+
import { IGroup } from "@esri/arcgis-rest-types";
3941

4042
/**
4143
* Hub Project Class
@@ -202,17 +204,30 @@ export class HubProject
202204
* on project creation, we want to pre-populate the sharing
203205
* field with the core and collaboration groups if the user
204206
* has the appropriate shareToGroup portal privilege
207+
*
208+
* TODO: we should re-evaluate this "auto-populate" pattern
205209
*/
206210
const { access: canShare } = this.checkPermission(
207211
"platform:portal:user:shareToGroup"
208212
);
209213
if (!editor.id && canShare) {
210-
// TODO: at what point can we remove this "auto-share" behavior?
211-
editor._groups = maybePush(editorContext.contentGroupId, editor._groups);
212-
editor._groups = maybePush(
214+
const currentUserGroups: IGroup[] =
215+
getProp(this.context, "currentUser.groups") || [];
216+
const defaultShareWithGroups = [
217+
editorContext.contentGroupId,
213218
editorContext.collaborationGroupId,
214-
editor._groups
215-
);
219+
].reduce((acc, groupId) => {
220+
const group = currentUserGroups.find((g: IGroup) => g.id === groupId);
221+
const canShareToGroup =
222+
!!group &&
223+
(!group.isViewOnly ||
224+
(group.isViewOnly &&
225+
["owner", "admin"].includes(group.memberType)));
226+
227+
canShareToGroup && acc.push(groupId);
228+
return acc;
229+
}, []);
230+
editor._groups = [...editor._groups, ...defaultShareWithGroups];
216231
}
217232

218233
return editor;

packages/common/test/projects/HubProject.test.ts

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import * as PortalModule from "@esri/arcgis-rest-portal";
2-
import { IHubProject, IResolvedMetric, getProp } from "../../src";
2+
import {
3+
IHubProject,
4+
IResolvedMetric,
5+
cloneObject,
6+
getProp,
7+
mergeObjects,
8+
} from "../../src";
39
import { Catalog } from "../../src/search";
410
import { ArcGISContextManager } from "../../src/ArcGISContextManager";
511
import { HubProject } from "../../src/projects/HubProject";
@@ -12,6 +18,25 @@ import * as ResolveMetricModule from "../../src/metrics/resolveMetric";
1218
import { HubItemEntity } from "../../src/core/HubItemEntity";
1319
import * as EnrichEntityModule from "../../src/core/enrichEntity";
1420

21+
const initContextManager = async (opts = {}) => {
22+
const defaults = {
23+
authentication: MOCK_AUTH,
24+
currentUser: {
25+
username: "casey",
26+
privileges: ["portal:user:shareToGroup"],
27+
} as unknown as PortalModule.IUser,
28+
portal: {
29+
name: "DC R&D Center",
30+
id: "BRXFAKE",
31+
urlKey: "fake-org",
32+
} as unknown as PortalModule.IPortal,
33+
portalUrl: "https://myserver.com",
34+
};
35+
return await ArcGISContextManager.create(
36+
mergeObjects(opts, defaults, ["currentUser"])
37+
);
38+
};
39+
1540
describe("HubProject Class:", () => {
1641
let authdCtxMgr: ArcGISContextManager;
1742
let unauthdCtxMgr: ArcGISContextManager;
@@ -20,19 +45,7 @@ describe("HubProject Class:", () => {
2045
// When we pass in all this information, the context
2146
// manager will not try to fetch anything, so no need
2247
// to mock those calls
23-
authdCtxMgr = await ArcGISContextManager.create({
24-
authentication: MOCK_AUTH,
25-
currentUser: {
26-
username: "casey",
27-
privileges: ["portal:user:shareToGroup"],
28-
} as unknown as PortalModule.IUser,
29-
portal: {
30-
name: "DC R&D Center",
31-
id: "BRXFAKE",
32-
urlKey: "fake-org",
33-
} as unknown as PortalModule.IPortal,
34-
portalUrl: "https://myserver.com",
35-
});
48+
authdCtxMgr = await initContextManager();
3649
});
3750

3851
describe("static methods:", () => {
@@ -363,7 +376,7 @@ describe("HubProject Class:", () => {
363376

364377
expect(enrichEntitySpy).toHaveBeenCalledTimes(1);
365378
});
366-
it("toEditor converst entity to correct structure", async () => {
379+
it("toEditor converts entity to correct structure", async () => {
367380
const chk = HubProject.fromJson(
368381
{
369382
id: "bc3",
@@ -381,6 +394,35 @@ describe("HubProject Class:", () => {
381394
);
382395
expect(result._groups).toEqual([]);
383396
});
397+
describe('auto-populating "shareWith" groups', () => {
398+
let projectInstance: any;
399+
beforeEach(async () => {
400+
const _authdCtxMgr = await initContextManager({
401+
currentUser: {
402+
groups: [
403+
{ id: "00a", isViewOnly: false },
404+
{ id: "00b", isViewOnly: true, memberType: "admin" },
405+
{ id: "00d", isViewOnly: false },
406+
] as PortalModule.IGroup[],
407+
},
408+
});
409+
projectInstance = HubProject.fromJson({}, _authdCtxMgr.context);
410+
});
411+
it('handles auto-populating "shareWith" groups that the current user can share to', async () => {
412+
const result = await projectInstance.toEditor({
413+
contentGroupId: "00a",
414+
collaborationGroupId: "00b",
415+
});
416+
expect(result._groups).toEqual(["00a", "00b"]);
417+
});
418+
it('does not auto-populate "shareWith" gruops that the current user cannot share to', async () => {
419+
const result = await projectInstance.toEditor({
420+
contentGroupId: "00e",
421+
collaborationGroupId: "00f",
422+
});
423+
expect(result._groups).toEqual([]);
424+
});
425+
});
384426
});
385427

386428
describe("fromEditor:", () => {

0 commit comments

Comments
 (0)