@jskit-ai/users-web 0.1.53 → 0.1.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/package.descriptor.mjs +15 -53
  2. package/package.json +16 -11
  3. package/src/client/account-settings/sections.js +74 -0
  4. package/src/client/composables/account-settings/accountSettingsRuntimeHelpers.js +2 -38
  5. package/src/client/composables/crud/crudLookupFieldRuntime.js +2 -2
  6. package/src/client/composables/internal/crudListParentTitleSupport.js +1 -1
  7. package/src/client/composables/internal/useOperationScope.js +12 -12
  8. package/src/client/composables/records/useAddEdit.js +2 -2
  9. package/src/client/composables/records/useList.js +3 -3
  10. package/src/client/composables/records/useView.js +2 -2
  11. package/src/client/composables/support/scopeHelpers.js +19 -19
  12. package/src/client/composables/useAccess.js +3 -3
  13. package/src/client/composables/useAccountSettingsRuntime.js +8 -156
  14. package/src/client/composables/useCommand.js +2 -2
  15. package/src/client/composables/useCrudListParentTitle.js +2 -2
  16. package/src/client/composables/usePaths.js +50 -38
  17. package/src/client/composables/useScopeRuntime.js +55 -27
  18. package/src/client/composables/useSurfaceRouteContext.js +1 -7
  19. package/src/client/index.js +0 -1
  20. package/src/client/lib/bootstrap.js +0 -63
  21. package/src/client/lib/httpClient.js +2 -59
  22. package/src/client/lib/theme.js +12 -189
  23. package/src/client/providers/UsersWebClientProvider.js +2 -25
  24. package/src/client/providers/bootUsersWebClientProvider.js +28 -0
  25. package/src/shared/toolsOutletContracts.js +1 -8
  26. package/templates/src/components/account/settings/AccountSettingsClientElement.vue +33 -21
  27. package/test/accountSettingsSections.test.js +79 -0
  28. package/test/exportsContract.test.js +2 -2
  29. package/test/scopeHelpers.test.js +6 -6
  30. package/test/settingsPlacementContract.test.js +4 -11
  31. package/test/theme.test.js +0 -56
  32. package/src/client/components/MembersAdminClientElement.vue +0 -400
  33. package/src/client/components/UsersProfileSurfaceSwitchMenuItem.vue +0 -39
  34. package/src/client/components/UsersWorkspaceMembersMenuItem.vue +0 -36
  35. package/src/client/components/UsersWorkspacePermissionMenuItem.vue +0 -90
  36. package/src/client/components/UsersWorkspaceSelector.vue +0 -248
  37. package/src/client/components/UsersWorkspaceSettingsMenuItem.vue +0 -39
  38. package/src/client/components/UsersWorkspaceToolsWidget.vue +0 -12
  39. package/src/client/components/WorkspaceMembersClientElement.vue +0 -655
  40. package/src/client/components/WorkspaceProfileClientElement.vue +0 -116
  41. package/src/client/components/WorkspaceSettingsClientElement.vue +0 -102
  42. package/src/client/components/WorkspaceSettingsFieldsClientElement.vue +0 -265
  43. package/src/client/components/WorkspacesClientElement.vue +0 -509
  44. package/src/client/composables/account-settings/accountSettingsInvitesRuntime.js +0 -88
  45. package/src/client/composables/useBootstrapQuery.js +0 -52
  46. package/src/client/composables/useWorkspaceRouteContext.js +0 -28
  47. package/src/client/composables/useWorkspaceSurfaceId.js +0 -43
  48. package/src/client/lib/menuIcons.js +0 -201
  49. package/src/client/lib/profileSurfaceMenuLinks.js +0 -142
  50. package/src/client/lib/surfaceAccessPolicy.js +0 -350
  51. package/src/client/lib/workspaceLinkResolver.js +0 -207
  52. package/src/client/lib/workspaceSurfaceContext.js +0 -82
  53. package/src/client/lib/workspaceSurfacePaths.js +0 -163
  54. package/src/client/providers/UsersWorkspacesClientProvider.js +0 -24
  55. package/src/client/runtime/bootstrapPlacementRouteGuards.js +0 -371
  56. package/src/client/runtime/bootstrapPlacementRuntime.js +0 -463
  57. package/src/client/runtime/bootstrapPlacementRuntimeConstants.js +0 -28
  58. package/src/client/runtime/bootstrapPlacementRuntimeHelpers.js +0 -147
  59. package/src/client/support/menuLinkTarget.js +0 -93
  60. package/src/client/support/realtimeWorkspace.js +0 -21
  61. package/src/client/support/runtimeNormalization.js +0 -27
  62. package/src/client/support/workspaceQueryKeys.js +0 -15
  63. package/templates/src/components/account/settings/AccountSettingsInvitesSection.vue +0 -77
  64. package/test/bootstrapPlacementRuntime.test.js +0 -1095
  65. package/test/menuIcons.test.js +0 -34
  66. package/test/menuLinkTarget.test.js +0 -116
  67. package/test/profileSurfaceMenuLinks.test.js +0 -208
  68. package/test/surfaceAccessPolicy.test.js +0 -129
  69. package/test/workspaceLinkResolver.test.js +0 -61
  70. package/test/workspaceSurfacePaths.test.js +0 -39
@@ -1,34 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import {
4
- mdiAccountCogOutline,
5
- mdiCogOutline,
6
- mdiFolderOutline,
7
- mdiLogin,
8
- mdiShieldCrownOutline,
9
- mdiViewDashboardOutline,
10
- mdiViewListOutline
11
- } from "@mdi/js";
12
- import {
13
- resolveMenuLinkIcon,
14
- resolveSurfaceSwitchIcon
15
- } from "../src/client/lib/menuIcons.js";
16
-
17
- test("resolveSurfaceSwitchIcon prefers explicit icon and maps known surfaces", () => {
18
- assert.equal(resolveSurfaceSwitchIcon("admin"), mdiShieldCrownOutline);
19
- assert.equal(resolveSurfaceSwitchIcon("ops", "mdi-cog-outline"), mdiCogOutline);
20
- assert.equal(resolveSurfaceSwitchIcon("admin", "custom-icon"), "custom-icon");
21
- assert.equal(resolveSurfaceSwitchIcon("admin", "mdi-cog-outline"), mdiCogOutline);
22
- });
23
-
24
- test("resolveMenuLinkIcon resolves settings/login fallbacks and generic default", () => {
25
- assert.equal(resolveMenuLinkIcon({ icon: "mdi-cog-outline" }), mdiCogOutline);
26
- assert.equal(resolveMenuLinkIcon({ to: "/account" }), mdiAccountCogOutline);
27
- assert.equal(resolveMenuLinkIcon({ label: "Sign in" }), mdiLogin);
28
- assert.equal(resolveMenuLinkIcon({ label: "Go to admin" }), mdiShieldCrownOutline);
29
- assert.equal(resolveMenuLinkIcon({ label: "Workspace", to: "/w/acme" }), mdiViewDashboardOutline);
30
- assert.equal(resolveMenuLinkIcon({ to: "/projects" }), mdiFolderOutline);
31
- assert.equal(resolveMenuLinkIcon({ label: "Settings", to: "/workspace/settings" }), mdiCogOutline);
32
- assert.equal(resolveMenuLinkIcon({ label: "Anything else", to: "/foo" }), mdiFolderOutline);
33
- assert.equal(resolveMenuLinkIcon({ label: "Anything else" }), mdiViewListOutline);
34
- });
@@ -1,116 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import {
4
- normalizeMenuLinkPathname,
5
- resolveMenuLinkTarget
6
- } from "../src/client/support/menuLinkTarget.js";
7
-
8
- const WORKSPACE_PLACEMENT_CONTEXT = Object.freeze({
9
- surfaceConfig: {
10
- enabledSurfaceIds: ["admin"],
11
- surfacesById: {
12
- admin: {
13
- id: "admin",
14
- requiresWorkspace: true
15
- }
16
- }
17
- }
18
- });
19
-
20
- const MIXED_PLACEMENT_CONTEXT = Object.freeze({
21
- surfaceConfig: {
22
- enabledSurfaceIds: ["app", "admin"],
23
- surfacesById: {
24
- app: {
25
- id: "app",
26
- requiresWorkspace: false
27
- },
28
- admin: {
29
- id: "admin",
30
- requiresWorkspace: true
31
- }
32
- }
33
- }
34
- });
35
-
36
- function createPageResolver() {
37
- return function resolvePagePath(relativePath = "", options = {}) {
38
- return `page:${String(options.surface || "")}:${String(relativePath || "")}`;
39
- };
40
- }
41
-
42
- test("resolveMenuLinkTarget resolves suffix targets when no explicit to is provided", () => {
43
- assert.equal(
44
- resolveMenuLinkTarget({
45
- surface: "admin",
46
- placementContext: WORKSPACE_PLACEMENT_CONTEXT,
47
- workspaceSuffix: "/practice/vets",
48
- nonWorkspaceSuffix: "/practice/vets",
49
- resolvePagePath: createPageResolver()
50
- }),
51
- "page:admin:/practice/vets"
52
- );
53
- });
54
-
55
- test("resolveMenuLinkTarget resolves relative targets through suffix templates", () => {
56
- assert.equal(
57
- resolveMenuLinkTarget({
58
- to: "./notes",
59
- surface: "admin",
60
- placementContext: WORKSPACE_PLACEMENT_CONTEXT,
61
- workspaceSuffix: "/contacts/[contactId]/notes",
62
- nonWorkspaceSuffix: "/contacts/[contactId]/notes",
63
- routeParams: {
64
- contactId: 42
65
- },
66
- resolvePagePath: createPageResolver()
67
- }),
68
- "page:admin:/contacts/42/notes"
69
- );
70
- });
71
-
72
- test("resolveMenuLinkTarget returns empty string for unresolved relative targets", () => {
73
- assert.equal(
74
- resolveMenuLinkTarget({
75
- to: "./notes",
76
- surface: "admin",
77
- placementContext: WORKSPACE_PLACEMENT_CONTEXT,
78
- workspaceSuffix: "/contacts/[contactId]/notes",
79
- nonWorkspaceSuffix: "/contacts/[contactId]/notes",
80
- resolvePagePath: createPageResolver()
81
- }),
82
- ""
83
- );
84
- });
85
-
86
- test("resolveMenuLinkTarget keeps absolute targets unchanged", () => {
87
- assert.equal(
88
- resolveMenuLinkTarget({
89
- to: "/practice/vets",
90
- surface: "admin",
91
- placementContext: WORKSPACE_PLACEMENT_CONTEXT,
92
- workspaceSuffix: "/ignored",
93
- nonWorkspaceSuffix: "/ignored",
94
- resolvePagePath: createPageResolver()
95
- }),
96
- "/practice/vets"
97
- );
98
- });
99
-
100
- test("resolveMenuLinkTarget uses non-workspace suffix for non-workspace surfaces", () => {
101
- assert.equal(
102
- resolveMenuLinkTarget({
103
- surface: "app",
104
- currentSurfaceId: "admin",
105
- placementContext: MIXED_PLACEMENT_CONTEXT,
106
- workspaceSuffix: "/workspace-only",
107
- nonWorkspaceSuffix: "/public-page",
108
- resolvePagePath: createPageResolver()
109
- }),
110
- "page:app:/public-page"
111
- );
112
- });
113
-
114
- test("normalizeMenuLinkPathname removes query strings and hashes", () => {
115
- assert.equal(normalizeMenuLinkPathname("/practice/vets?tab=all#section"), "/practice/vets");
116
- });
@@ -1,208 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { mdiShieldCrownOutline } from "@mdi/js";
4
- import {
5
- hasWorkspaceMembership,
6
- resolvePrimarySurfaceSwitchLink,
7
- resolveProfileSurfaceMenuLinks
8
- } from "../src/client/lib/profileSurfaceMenuLinks.js";
9
-
10
- function createPlacementContext({
11
- workspace = null,
12
- workspaces = [],
13
- authenticated = true,
14
- opsOwner = false
15
- } = {}) {
16
- return {
17
- auth: {
18
- authenticated
19
- },
20
- workspace,
21
- workspaces,
22
- permissions: [],
23
- surfaceAccess: {
24
- opsowner: opsOwner
25
- },
26
- surfaceAccessPolicies: {
27
- public: {},
28
- workspace_member: {
29
- requireAuth: true,
30
- requireWorkspaceMembership: true
31
- },
32
- ops_owner: {
33
- requireAuth: true,
34
- requireFlagsAll: ["ops_owner"]
35
- }
36
- },
37
- surfaceConfig: {
38
- tenancyMode: "workspaces",
39
- defaultSurfaceId: "app",
40
- enabledSurfaceIds: ["home", "app", "admin", "ops"],
41
- surfacesById: {
42
- home: {
43
- id: "home",
44
- enabled: true,
45
- pagesRoot: "",
46
- routeBase: "/",
47
- requiresAuth: false,
48
- requiresWorkspace: false,
49
- accessPolicyId: "public"
50
- },
51
- app: {
52
- id: "app",
53
- enabled: true,
54
- pagesRoot: "w/[workspaceSlug]",
55
- routeBase: "/w/:workspaceSlug",
56
- requiresAuth: true,
57
- requiresWorkspace: true,
58
- accessPolicyId: "workspace_member"
59
- },
60
- admin: {
61
- id: "admin",
62
- enabled: true,
63
- pagesRoot: "w/[workspaceSlug]/admin",
64
- routeBase: "/w/:workspaceSlug/admin",
65
- requiresAuth: true,
66
- requiresWorkspace: true,
67
- accessPolicyId: "workspace_member"
68
- },
69
- ops: {
70
- id: "ops",
71
- enabled: true,
72
- pagesRoot: "ops",
73
- routeBase: "/ops",
74
- requiresAuth: true,
75
- requiresWorkspace: false,
76
- accessPolicyId: "ops_owner",
77
- icon: "mdi-cog-outline"
78
- }
79
- }
80
- }
81
- };
82
- }
83
-
84
- const originalWindow = globalThis.window;
85
-
86
- test.afterEach(() => {
87
- if (typeof originalWindow === "undefined") {
88
- delete globalThis.window;
89
- return;
90
- }
91
- globalThis.window = originalWindow;
92
- });
93
-
94
- test("hasWorkspaceMembership matches context.workspace slug", () => {
95
- const context = createPlacementContext({
96
- workspace: {
97
- id: 1,
98
- slug: "acme"
99
- },
100
- workspaces: []
101
- });
102
-
103
- assert.equal(hasWorkspaceMembership(context, "acme"), true);
104
- });
105
-
106
- test("hasWorkspaceMembership matches context.workspaces slug", () => {
107
- const context = createPlacementContext({
108
- workspace: null,
109
- workspaces: [
110
- {
111
- id: 1,
112
- slug: "acme"
113
- }
114
- ]
115
- });
116
-
117
- assert.equal(hasWorkspaceMembership(context, "acme"), true);
118
- });
119
-
120
- test("resolvePrimarySurfaceSwitchLink shows Go to admin only for member workspace", () => {
121
- const context = createPlacementContext({
122
- workspace: {
123
- id: 1,
124
- slug: "acme"
125
- },
126
- workspaces: [
127
- {
128
- id: 1,
129
- slug: "acme"
130
- }
131
- ]
132
- });
133
-
134
- const link = resolvePrimarySurfaceSwitchLink({
135
- context,
136
- surface: "app"
137
- });
138
-
139
- assert.deepEqual(link, {
140
- id: "surface-switch.admin",
141
- label: "Go to admin",
142
- icon: mdiShieldCrownOutline,
143
- to: "/w/acme/admin"
144
- });
145
- });
146
-
147
- test("resolvePrimarySurfaceSwitchLink hides workspace switch when slug is only in URL and user is not member", () => {
148
- globalThis.window = {
149
- location: {
150
- pathname: "/w/acme/admin",
151
- search: "",
152
- hash: ""
153
- }
154
- };
155
-
156
- const context = createPlacementContext({
157
- workspace: null,
158
- workspaces: []
159
- });
160
-
161
- const link = resolvePrimarySurfaceSwitchLink({
162
- context,
163
- surface: "admin"
164
- });
165
-
166
- assert.equal(link, null);
167
- });
168
-
169
- test("resolveProfileSurfaceMenuLinks includes gated non-workspace switches only for matching access flags", () => {
170
- const nonOwnerContext = createPlacementContext({
171
- workspace: {
172
- id: 1,
173
- slug: "acme"
174
- },
175
- workspaces: [
176
- {
177
- id: 1,
178
- slug: "acme"
179
- }
180
- ],
181
- opsOwner: false
182
- });
183
- const ownerContext = createPlacementContext({
184
- workspace: {
185
- id: 1,
186
- slug: "acme"
187
- },
188
- workspaces: [
189
- {
190
- id: 1,
191
- slug: "acme"
192
- }
193
- ],
194
- opsOwner: true
195
- });
196
-
197
- const nonOwnerLinks = resolveProfileSurfaceMenuLinks({
198
- context: nonOwnerContext,
199
- surface: "app"
200
- });
201
- const ownerLinks = resolveProfileSurfaceMenuLinks({
202
- context: ownerContext,
203
- surface: "app"
204
- });
205
-
206
- assert.equal(nonOwnerLinks.some((entry) => entry.id === "surface-switch.ops"), false);
207
- assert.equal(ownerLinks.some((entry) => entry.id === "surface-switch.ops"), true);
208
- });
@@ -1,129 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { evaluateSurfaceAccess } from "../src/client/lib/surfaceAccessPolicy.js";
4
-
5
- function createContext(overrides = {}) {
6
- return {
7
- auth: {
8
- authenticated: true
9
- },
10
- workspaces: [
11
- {
12
- id: 1,
13
- slug: "acme"
14
- }
15
- ],
16
- permissions: [],
17
- surfaceAccess: {
18
- opsowner: false
19
- },
20
- surfaceAccessPolicies: {
21
- public: {},
22
- workspace_member: {
23
- requireAuth: true,
24
- requireWorkspaceMembership: true
25
- },
26
- ops_owner: {
27
- requireAuth: true,
28
- requireFlagsAll: ["ops_owner"]
29
- }
30
- },
31
- surfaceConfig: {
32
- defaultSurfaceId: "home",
33
- enabledSurfaceIds: ["home", "app", "ops"],
34
- surfacesById: {
35
- home: {
36
- id: "home",
37
- enabled: true,
38
- routeBase: "/home",
39
- requiresWorkspace: false,
40
- accessPolicyId: "public"
41
- },
42
- app: {
43
- id: "app",
44
- enabled: true,
45
- routeBase: "/w/:workspaceSlug",
46
- requiresWorkspace: true,
47
- accessPolicyId: "workspace_member"
48
- },
49
- ops: {
50
- id: "ops",
51
- enabled: true,
52
- routeBase: "/ops",
53
- requiresWorkspace: false,
54
- accessPolicyId: "ops_owner"
55
- }
56
- }
57
- },
58
- ...overrides
59
- };
60
- }
61
-
62
- test("evaluateSurfaceAccess allows workspace member surfaces for accessible workspace", () => {
63
- const decision = evaluateSurfaceAccess({
64
- context: createContext(),
65
- surfaceId: "app",
66
- workspaceSlug: "acme"
67
- });
68
-
69
- assert.equal(decision.allowed, true);
70
- });
71
-
72
- test("evaluateSurfaceAccess denies workspace member surfaces for inaccessible workspace", () => {
73
- const decision = evaluateSurfaceAccess({
74
- context: createContext(),
75
- surfaceId: "app",
76
- workspaceSlug: "missing"
77
- });
78
-
79
- assert.equal(decision.allowed, false);
80
- assert.equal(decision.reason, "surface-access-workspace-membership-required");
81
- });
82
-
83
- test("evaluateSurfaceAccess allows unknown workspace membership when allowOnUnknown=true", () => {
84
- const context = createContext();
85
- delete context.workspaces;
86
-
87
- const decision = evaluateSurfaceAccess({
88
- context,
89
- surfaceId: "app",
90
- workspaceSlug: "acme",
91
- allowOnUnknown: true
92
- });
93
-
94
- assert.equal(decision.allowed, true);
95
- assert.equal(decision.pending, true);
96
- });
97
-
98
- test("evaluateSurfaceAccess enforces bootstrap surface access flags", () => {
99
- const deniedDecision = evaluateSurfaceAccess({
100
- context: createContext(),
101
- surfaceId: "ops"
102
- });
103
- assert.equal(deniedDecision.allowed, false);
104
-
105
- const allowedDecision = evaluateSurfaceAccess({
106
- context: createContext({
107
- surfaceAccess: {
108
- opsowner: true
109
- }
110
- }),
111
- surfaceId: "ops"
112
- });
113
- assert.equal(allowedDecision.allowed, true);
114
- });
115
-
116
- test("evaluateSurfaceAccess denies workspace route with not_found status", () => {
117
- const decision = evaluateSurfaceAccess({
118
- context: createContext({
119
- workspaceBootstrapStatuses: {
120
- acme: "not_found"
121
- }
122
- }),
123
- surfaceId: "app",
124
- workspaceSlug: "acme"
125
- });
126
-
127
- assert.equal(decision.allowed, false);
128
- assert.equal(decision.reason, "surface-access-workspace-not-found");
129
- });
@@ -1,61 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { resolveWorkspaceShellLinkPath } from "../src/client/lib/workspaceLinkResolver.js";
4
-
5
- function createContext({ defaultSurfaceId = "dashboard", enabledSurfaceIds = ["dashboard"], surfacesById = {} } = {}) {
6
- return {
7
- surfaceConfig: {
8
- defaultSurfaceId,
9
- enabledSurfaceIds,
10
- surfacesById
11
- }
12
- };
13
- }
14
-
15
- test("resolveWorkspaceShellLinkPath resolves workspace path for known workspace surfaces", () => {
16
- const context = {
17
- surfaceConfig: {
18
- defaultSurfaceId: "dashboard",
19
- enabledSurfaceIds: ["dashboard"],
20
- surfacesById: {
21
- dashboard: {
22
- routeBase: "/dashboard",
23
- requiresWorkspace: true
24
- }
25
- }
26
- }
27
- };
28
-
29
- const path = resolveWorkspaceShellLinkPath({
30
- context,
31
- surface: "dashboard",
32
- mode: "workspace",
33
- workspaceSlug: "acme"
34
- });
35
-
36
- assert.equal(path, "/w/acme");
37
- });
38
-
39
- test("resolveWorkspaceShellLinkPath returns empty path for unknown non-default workspace surface", () => {
40
- const context = createContext();
41
- const path = resolveWorkspaceShellLinkPath({
42
- context,
43
- surface: "admin",
44
- mode: "workspace",
45
- workspaceSlug: "acme"
46
- });
47
-
48
- assert.equal(path, "");
49
- });
50
-
51
- test("resolveWorkspaceShellLinkPath returns empty path for unknown non-workspace surface ids", () => {
52
- const context = createContext();
53
- const path = resolveWorkspaceShellLinkPath({
54
- context,
55
- surface: "ops",
56
- mode: "workspace",
57
- workspaceSlug: "acme"
58
- });
59
-
60
- assert.equal(path, "");
61
- });
@@ -1,39 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
-
4
- import {
5
- resolveAccountSettingsPathFromPlacementContext,
6
- resolveSurfaceWorkspacePathFromPlacementContext
7
- } from "../src/client/lib/workspaceSurfacePaths.js";
8
-
9
- test("resolveSurfaceWorkspacePathFromPlacementContext returns empty path without workspace slug", () => {
10
- const context = {
11
- surfaceConfig: {
12
- defaultSurfaceId: "home",
13
- enabledSurfaceIds: ["home", "app", "admin", "ops"],
14
- surfacesById: {
15
- home: { id: "home", routeBase: "/home", requiresWorkspace: false },
16
- app: { id: "app", routeBase: "/w/:workspaceSlug", requiresWorkspace: true },
17
- admin: { id: "admin", routeBase: "/w/:workspaceSlug/admin", requiresWorkspace: true },
18
- ops: { id: "ops", routeBase: "/ops", requiresWorkspace: false }
19
- }
20
- }
21
- };
22
-
23
- assert.equal(resolveSurfaceWorkspacePathFromPlacementContext(context, "app", "", "/"), "");
24
- });
25
-
26
- test("resolveAccountSettingsPathFromPlacementContext uses account surface route when available", () => {
27
- const context = {
28
- surfaceConfig: {
29
- defaultSurfaceId: "home",
30
- enabledSurfaceIds: ["home", "account"],
31
- surfacesById: {
32
- home: { id: "home", routeBase: "/home", requiresWorkspace: false },
33
- account: { id: "account", routeBase: "/profile", requiresWorkspace: false }
34
- }
35
- }
36
- };
37
-
38
- assert.equal(resolveAccountSettingsPathFromPlacementContext(context), "/profile");
39
- });