@jskit-ai/users-core 0.1.47 → 0.1.49

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 (104) hide show
  1. package/package.descriptor.mjs +9 -46
  2. package/package.json +8 -19
  3. package/src/server/UsersCoreServiceProvider.js +0 -4
  4. package/src/server/common/registerCommonRepositories.js +0 -5
  5. package/src/server/common/services/authProfileSyncService.js +28 -7
  6. package/src/server/common/support/realtimeServiceEvents.js +1 -59
  7. package/src/server/profileSyncLifecycleContributorRegistry.js +56 -0
  8. package/src/server/registerUsersBootstrap.js +1 -3
  9. package/src/server/registerUsersCore.js +2 -14
  10. package/src/server/usersBootstrapContributor.js +10 -85
  11. package/src/shared/index.js +2 -99
  12. package/src/shared/settings.js +1 -119
  13. package/templates/migrations/users_core_generic_initial.cjs +0 -16
  14. package/test/authProfileSyncService.test.js +19 -10
  15. package/test/registerServiceRealtimeEvents.test.js +0 -94
  16. package/test/registerUsersCore.test.js +6 -19
  17. package/test/repositoryContracts.test.js +1 -11
  18. package/test/resourcesCanonical.test.js +1 -19
  19. package/test/settingsFieldRegistriesSingleton.test.js +0 -10
  20. package/test/usersBootstrapContributor.test.js +20 -38
  21. package/test/usersRouteRequestInputValidator.test.js +2 -43
  22. package/test/usersRouteResources.test.js +2 -20
  23. package/test-support/registerDefaultSettingsFields.js +0 -1
  24. package/src/server/UsersWorkspacesServiceProvider.js +0 -44
  25. package/src/server/common/contributors/workspaceActionContextContributor.js +0 -88
  26. package/src/server/common/contributors/workspaceAuthPolicyContextResolver.js +0 -34
  27. package/src/server/common/contributors/workspaceRouteVisibilityResolver.js +0 -78
  28. package/src/server/common/formatters/workspaceFormatter.js +0 -53
  29. package/src/server/common/repositories/workspaceInvitesRepository.js +0 -208
  30. package/src/server/common/repositories/workspaceMembershipsRepository.js +0 -190
  31. package/src/server/common/repositories/workspacesRepository.js +0 -202
  32. package/src/server/common/services/workspaceContextService.js +0 -281
  33. package/src/server/common/support/workspaceRoutePaths.js +0 -17
  34. package/src/server/common/validators/routeParamsValidator.js +0 -62
  35. package/src/server/consoleSettings/bootConsoleSettingsRoutes.js +0 -63
  36. package/src/server/consoleSettings/consoleService.js +0 -36
  37. package/src/server/consoleSettings/consoleSettingsActions.js +0 -55
  38. package/src/server/consoleSettings/consoleSettingsRepository.js +0 -115
  39. package/src/server/consoleSettings/consoleSettingsService.js +0 -40
  40. package/src/server/consoleSettings/registerConsoleSettings.js +0 -56
  41. package/src/server/registerWorkspaceBootstrap.js +0 -27
  42. package/src/server/registerWorkspaceCore.js +0 -73
  43. package/src/server/registerWorkspaceRepositories.js +0 -26
  44. package/src/server/support/resolveWorkspace.js +0 -16
  45. package/src/server/support/workspaceActionSurfaces.js +0 -135
  46. package/src/server/support/workspaceInvitationsPolicy.js +0 -45
  47. package/src/server/support/workspaceRouteInput.js +0 -22
  48. package/src/server/workspaceBootstrapContributor.js +0 -211
  49. package/src/server/workspaceDirectory/bootWorkspaceDirectoryRoutes.js +0 -133
  50. package/src/server/workspaceDirectory/registerWorkspaceDirectory.js +0 -19
  51. package/src/server/workspaceDirectory/workspaceDirectoryActions.js +0 -133
  52. package/src/server/workspaceMembers/bootWorkspaceMembers.js +0 -236
  53. package/src/server/workspaceMembers/registerWorkspaceMembers.js +0 -108
  54. package/src/server/workspaceMembers/workspaceMembersActions.js +0 -186
  55. package/src/server/workspaceMembers/workspaceMembersService.js +0 -222
  56. package/src/server/workspacePendingInvitations/bootWorkspacePendingInvitations.js +0 -62
  57. package/src/server/workspacePendingInvitations/registerWorkspacePendingInvitations.js +0 -119
  58. package/src/server/workspacePendingInvitations/workspacePendingInvitationsActions.js +0 -74
  59. package/src/server/workspacePendingInvitations/workspacePendingInvitationsService.js +0 -138
  60. package/src/server/workspaceSettings/bootWorkspaceSettings.js +0 -76
  61. package/src/server/workspaceSettings/registerWorkspaceSettings.js +0 -62
  62. package/src/server/workspaceSettings/workspaceSettingsActions.js +0 -72
  63. package/src/server/workspaceSettings/workspaceSettingsRepository.js +0 -154
  64. package/src/server/workspaceSettings/workspaceSettingsService.js +0 -66
  65. package/src/shared/resources/consoleSettingsFields.js +0 -54
  66. package/src/shared/resources/consoleSettingsResource.js +0 -119
  67. package/src/shared/resources/workspaceMembersResource.js +0 -354
  68. package/src/shared/resources/workspacePendingInvitationsResource.js +0 -82
  69. package/src/shared/resources/workspaceResource.js +0 -176
  70. package/src/shared/resources/workspaceSettingsFields.js +0 -59
  71. package/src/shared/resources/workspaceSettingsResource.js +0 -169
  72. package/src/shared/roles.js +0 -161
  73. package/src/shared/support/usersApiPaths.js +0 -43
  74. package/src/shared/support/usersVisibility.js +0 -42
  75. package/src/shared/support/workspacePathModel.js +0 -145
  76. package/src/shared/tenancyMode.js +0 -35
  77. package/src/shared/tenancyProfile.js +0 -73
  78. package/templates/migrations/users_core_console_owner.cjs +0 -37
  79. package/templates/packages/main/src/shared/resources/consoleSettingsFields.js +0 -11
  80. package/test/consoleService.test.js +0 -57
  81. package/test/consoleSettingsService.test.js +0 -86
  82. package/test/registerWorkspaceDirectory.test.js +0 -31
  83. package/test/registerWorkspaceSettings.test.js +0 -40
  84. package/test/roles.test.js +0 -159
  85. package/test/tenancyProfile.test.js +0 -67
  86. package/test/usersApiPaths.test.js +0 -49
  87. package/test/usersRouteValidators.test.js +0 -49
  88. package/test/usersVisibility.test.js +0 -27
  89. package/test/workspaceActionContextContributor.test.js +0 -344
  90. package/test/workspaceActionSurfaces.test.js +0 -105
  91. package/test/workspaceAuthPolicyContextResolver.test.js +0 -119
  92. package/test/workspaceBootstrapContributor.test.js +0 -154
  93. package/test/workspaceInvitationsPolicy.test.js +0 -71
  94. package/test/workspaceInvitesRepository.test.js +0 -111
  95. package/test/workspaceMembersService.test.js +0 -398
  96. package/test/workspacePathModel.test.js +0 -93
  97. package/test/workspacePendingInvitationsResource.test.js +0 -38
  98. package/test/workspacePendingInvitationsService.test.js +0 -151
  99. package/test/workspaceRouteVisibilityResolver.test.js +0 -83
  100. package/test/workspaceService.test.js +0 -546
  101. package/test/workspaceSettingsActions.test.js +0 -52
  102. package/test/workspaceSettingsRepository.test.js +0 -202
  103. package/test/workspaceSettingsResource.test.js +0 -169
  104. package/test/workspaceSettingsService.test.js +0 -140
@@ -1,202 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import "../test-support/registerDefaultSettingsFields.js";
4
- import { toIsoString } from "@jskit-ai/database-runtime/shared";
5
- import { resolveWorkspaceThemePalettes } from "../src/shared/settings.js";
6
- import { createRepository } from "../src/server/workspaceSettings/workspaceSettingsRepository.js";
7
-
8
- function createDefaultWorkspaceSettings() {
9
- return true;
10
- }
11
-
12
- const DEFAULT_WORKSPACE_THEME = resolveWorkspaceThemePalettes({});
13
- const STUB_CREATED_AT = "2026-03-09 00:26:35.710";
14
-
15
- function createKnexStub(rowOverrides = {}) {
16
- const state = {
17
- insertedRow: null,
18
- updatePayload: null,
19
- row: {
20
- workspace_id: 1,
21
- light_primary_color: DEFAULT_WORKSPACE_THEME.light.color,
22
- light_secondary_color: DEFAULT_WORKSPACE_THEME.light.secondaryColor,
23
- light_surface_color: DEFAULT_WORKSPACE_THEME.light.surfaceColor,
24
- light_surface_variant_color: DEFAULT_WORKSPACE_THEME.light.surfaceVariantColor,
25
- dark_primary_color: DEFAULT_WORKSPACE_THEME.dark.color,
26
- dark_secondary_color: DEFAULT_WORKSPACE_THEME.dark.secondaryColor,
27
- dark_surface_color: DEFAULT_WORKSPACE_THEME.dark.surfaceColor,
28
- dark_surface_variant_color: DEFAULT_WORKSPACE_THEME.dark.surfaceVariantColor,
29
- invites_enabled: 1,
30
- created_at: STUB_CREATED_AT,
31
- updated_at: STUB_CREATED_AT,
32
- ...rowOverrides
33
- }
34
- };
35
-
36
- function tableBuilder(tableName) {
37
- assert.equal(tableName, "workspace_settings");
38
-
39
- return {
40
- insert(payload) {
41
- state.insertedRow = { ...payload };
42
- state.row = {
43
- workspace_id: payload.workspace_id,
44
- light_primary_color: payload.light_primary_color,
45
- light_secondary_color: payload.light_secondary_color,
46
- light_surface_color: payload.light_surface_color,
47
- light_surface_variant_color: payload.light_surface_variant_color,
48
- dark_primary_color: payload.dark_primary_color,
49
- dark_secondary_color: payload.dark_secondary_color,
50
- dark_surface_color: payload.dark_surface_color,
51
- dark_surface_variant_color: payload.dark_surface_variant_color,
52
- invites_enabled: payload.invites_enabled,
53
- created_at: "2026-03-10 00:00:00.000",
54
- updated_at: "2026-03-10 00:00:00.000"
55
- };
56
- return Promise.resolve([1]);
57
- },
58
- where(criteria) {
59
- assert.equal(typeof criteria, "object");
60
-
61
- return {
62
- first() {
63
- return Promise.resolve(state.row ? { ...state.row } : null);
64
- },
65
- update(payload) {
66
- state.updatePayload = payload;
67
- if (Object.hasOwn(payload, "invites_enabled")) {
68
- state.row.invites_enabled = payload.invites_enabled;
69
- }
70
- if (Object.hasOwn(payload, "light_primary_color")) {
71
- state.row.light_primary_color = payload.light_primary_color;
72
- }
73
- if (Object.hasOwn(payload, "light_secondary_color")) {
74
- state.row.light_secondary_color = payload.light_secondary_color;
75
- }
76
- if (Object.hasOwn(payload, "light_surface_color")) {
77
- state.row.light_surface_color = payload.light_surface_color;
78
- }
79
- if (Object.hasOwn(payload, "light_surface_variant_color")) {
80
- state.row.light_surface_variant_color = payload.light_surface_variant_color;
81
- }
82
- if (Object.hasOwn(payload, "dark_primary_color")) {
83
- state.row.dark_primary_color = payload.dark_primary_color;
84
- }
85
- if (Object.hasOwn(payload, "dark_secondary_color")) {
86
- state.row.dark_secondary_color = payload.dark_secondary_color;
87
- }
88
- if (Object.hasOwn(payload, "dark_surface_color")) {
89
- state.row.dark_surface_color = payload.dark_surface_color;
90
- }
91
- if (Object.hasOwn(payload, "dark_surface_variant_color")) {
92
- state.row.dark_surface_variant_color = payload.dark_surface_variant_color;
93
- }
94
- if (Object.hasOwn(payload, "updated_at")) {
95
- state.row.updated_at = payload.updated_at;
96
- }
97
- return Promise.resolve(1);
98
- }
99
- };
100
- }
101
- };
102
- }
103
-
104
- return { knexStub: tableBuilder, state };
105
- }
106
-
107
- test("workspaceSettingsRepository.findByWorkspaceId maps the stored row", async () => {
108
- const { knexStub } = createKnexStub();
109
- const repository = createRepository(knexStub, {
110
- defaultInvitesEnabled: createDefaultWorkspaceSettings()
111
- });
112
-
113
- const record = await repository.findByWorkspaceId("1");
114
-
115
- assert.deepEqual(record, {
116
- workspaceId: "1",
117
- lightPrimaryColor: DEFAULT_WORKSPACE_THEME.light.color,
118
- lightSecondaryColor: DEFAULT_WORKSPACE_THEME.light.secondaryColor,
119
- lightSurfaceColor: DEFAULT_WORKSPACE_THEME.light.surfaceColor,
120
- lightSurfaceVariantColor: DEFAULT_WORKSPACE_THEME.light.surfaceVariantColor,
121
- darkPrimaryColor: DEFAULT_WORKSPACE_THEME.dark.color,
122
- darkSecondaryColor: DEFAULT_WORKSPACE_THEME.dark.secondaryColor,
123
- darkSurfaceColor: DEFAULT_WORKSPACE_THEME.dark.surfaceColor,
124
- darkSurfaceVariantColor: DEFAULT_WORKSPACE_THEME.dark.surfaceVariantColor,
125
- invitesEnabled: true,
126
- createdAt: toIsoString(STUB_CREATED_AT),
127
- updatedAt: toIsoString(STUB_CREATED_AT)
128
- });
129
- });
130
-
131
- test("workspaceSettingsRepository.updateSettingsByWorkspaceId updates invitesEnabled only", async () => {
132
- const { knexStub, state } = createKnexStub();
133
- const repository = createRepository(knexStub, {
134
- defaultInvitesEnabled: createDefaultWorkspaceSettings()
135
- });
136
-
137
- const updated = await repository.updateSettingsByWorkspaceId("1", {
138
- invitesEnabled: false
139
- });
140
-
141
- assert.equal(state.updatePayload.invites_enabled, false);
142
- assert.equal(updated.invitesEnabled, false);
143
- });
144
-
145
- test("workspaceSettingsRepository.ensureForWorkspaceId inserts the injected defaults exactly", async () => {
146
- const { knexStub, state } = createKnexStub();
147
- state.row = null;
148
- const repository = createRepository(knexStub, {
149
- defaultInvitesEnabled: false
150
- });
151
-
152
- const record = await repository.ensureForWorkspaceId("5");
153
-
154
- assert.equal(state.insertedRow.workspace_id, "5");
155
- assert.equal(state.insertedRow.light_primary_color, DEFAULT_WORKSPACE_THEME.light.color);
156
- assert.equal(state.insertedRow.light_secondary_color, DEFAULT_WORKSPACE_THEME.light.secondaryColor);
157
- assert.equal(state.insertedRow.light_surface_color, DEFAULT_WORKSPACE_THEME.light.surfaceColor);
158
- assert.equal(
159
- state.insertedRow.light_surface_variant_color,
160
- DEFAULT_WORKSPACE_THEME.light.surfaceVariantColor
161
- );
162
- assert.equal(state.insertedRow.dark_primary_color, DEFAULT_WORKSPACE_THEME.dark.color);
163
- assert.equal(state.insertedRow.dark_secondary_color, DEFAULT_WORKSPACE_THEME.dark.secondaryColor);
164
- assert.equal(state.insertedRow.dark_surface_color, DEFAULT_WORKSPACE_THEME.dark.surfaceColor);
165
- assert.equal(
166
- state.insertedRow.dark_surface_variant_color,
167
- DEFAULT_WORKSPACE_THEME.dark.surfaceVariantColor
168
- );
169
- assert.equal(state.insertedRow.invites_enabled, false);
170
- assert.equal(record.lightPrimaryColor, DEFAULT_WORKSPACE_THEME.light.color);
171
- assert.equal(record.lightSecondaryColor, DEFAULT_WORKSPACE_THEME.light.secondaryColor);
172
- assert.equal(record.lightSurfaceColor, DEFAULT_WORKSPACE_THEME.light.surfaceColor);
173
- assert.equal(record.lightSurfaceVariantColor, DEFAULT_WORKSPACE_THEME.light.surfaceVariantColor);
174
- assert.equal(record.darkPrimaryColor, DEFAULT_WORKSPACE_THEME.dark.color);
175
- assert.equal(record.darkSecondaryColor, DEFAULT_WORKSPACE_THEME.dark.secondaryColor);
176
- assert.equal(record.darkSurfaceColor, DEFAULT_WORKSPACE_THEME.dark.surfaceColor);
177
- assert.equal(record.darkSurfaceVariantColor, DEFAULT_WORKSPACE_THEME.dark.surfaceVariantColor);
178
- assert.equal(record.invitesEnabled, false);
179
- assert.equal(record.workspaceId, "5");
180
- });
181
-
182
- test("workspaceSettingsRepository.updateSettingsByWorkspaceId updates workspace settings columns", async () => {
183
- const { knexStub, state } = createKnexStub();
184
- const repository = createRepository(knexStub, {
185
- defaultInvitesEnabled: true
186
- });
187
-
188
- const updated = await repository.updateSettingsByWorkspaceId("1", {
189
- lightPrimaryColor: "#123abc"
190
- });
191
-
192
- assert.equal(state.updatePayload.light_primary_color, "#123ABC");
193
- assert.equal(updated.lightPrimaryColor, "#123ABC");
194
- });
195
-
196
- test("workspaceSettingsRepository can be constructed without validating app config shape", () => {
197
- const { knexStub } = createKnexStub();
198
-
199
- const repository = createRepository(knexStub);
200
-
201
- assert.ok(repository);
202
- });
@@ -1,169 +0,0 @@
1
- import test from "node:test";
2
- import assert from "node:assert/strict";
3
- import { validateOperationSection } from "@jskit-ai/http-runtime/shared/validators/operationValidation";
4
- import "../test-support/registerDefaultSettingsFields.js";
5
- import { resolveWorkspaceThemePalettes } from "../src/shared/settings.js";
6
- import { workspaceSettingsResource } from "../src/shared/resources/workspaceSettingsResource.js";
7
- import { createWorkspaceRoleCatalog } from "../src/shared/roles.js";
8
-
9
- function createRoleCatalog() {
10
- return createWorkspaceRoleCatalog({
11
- roleCatalog: {
12
- workspace: {
13
- defaultInviteRole: "member"
14
- },
15
- roles: {
16
- owner: {
17
- assignable: false,
18
- permissions: ["*"]
19
- },
20
- admin: {
21
- assignable: true,
22
- permissions: [
23
- "workspace.roles.view",
24
- "workspace.settings.view",
25
- "workspace.settings.update",
26
- "workspace.members.view",
27
- "workspace.members.invite",
28
- "workspace.members.manage",
29
- "workspace.invites.revoke"
30
- ]
31
- },
32
- member: {
33
- assignable: true,
34
- permissions: ["workspace.settings.view"]
35
- }
36
- }
37
- }
38
- });
39
- }
40
-
41
- function parseBody(operation, payload = {}) {
42
- return validateOperationSection({
43
- operation,
44
- section: "bodyValidator",
45
- value: payload
46
- });
47
- }
48
-
49
- test("workspace settings patch body normalizes valid payload before validation", () => {
50
- const parsed = parseBody(workspaceSettingsResource.operations.patch, {
51
- lightPrimaryColor: "#0f6b54",
52
- lightSecondaryColor: "#0b4d3c",
53
- lightSurfaceColor: "#eef5f3",
54
- lightSurfaceVariantColor: "#ddeae7",
55
- darkPrimaryColor: "#123456",
56
- darkSecondaryColor: "#234567",
57
- darkSurfaceColor: "#345678",
58
- darkSurfaceVariantColor: "#456789",
59
- invitesEnabled: false
60
- });
61
-
62
- assert.equal(parsed.ok, true);
63
- assert.deepEqual(parsed.fieldErrors, {});
64
- assert.deepEqual(parsed.value, {
65
- lightPrimaryColor: "#0F6B54",
66
- lightSecondaryColor: "#0B4D3C",
67
- lightSurfaceColor: "#EEF5F3",
68
- lightSurfaceVariantColor: "#DDEAE7",
69
- darkPrimaryColor: "#123456",
70
- darkSecondaryColor: "#234567",
71
- darkSurfaceColor: "#345678",
72
- darkSurfaceVariantColor: "#456789",
73
- invitesEnabled: false
74
- });
75
- });
76
-
77
- test("workspace settings patch body ignores unknown fields after normalization", () => {
78
- const parsed = parseBody(workspaceSettingsResource.operations.patch, {
79
- avatarUrl: "https://example.com/avatar.png"
80
- });
81
-
82
- assert.equal(parsed.ok, true);
83
- assert.deepEqual(parsed.fieldErrors, {});
84
- assert.deepEqual(parsed.value, {});
85
- });
86
-
87
- test("workspace settings create body requires full-write fields", () => {
88
- const parsed = parseBody(workspaceSettingsResource.operations.create, {});
89
-
90
- assert.equal(parsed.ok, false);
91
- assert.equal(parsed.fieldErrors.lightPrimaryColor, "Light primary color is required.");
92
- assert.equal(parsed.fieldErrors.lightSecondaryColor, "Light secondary color is required.");
93
- assert.equal(parsed.fieldErrors.lightSurfaceColor, "Light surface color is required.");
94
- assert.equal(parsed.fieldErrors.lightSurfaceVariantColor, "Light surface variant color is required.");
95
- assert.equal(parsed.fieldErrors.darkPrimaryColor, "Dark primary color is required.");
96
- assert.equal(parsed.fieldErrors.darkSecondaryColor, "Dark secondary color is required.");
97
- assert.equal(parsed.fieldErrors.darkSurfaceColor, "Dark surface color is required.");
98
- assert.equal(parsed.fieldErrors.darkSurfaceVariantColor, "Dark surface variant color is required.");
99
- assert.equal(parsed.fieldErrors.invitesEnabled, "invitesEnabled is required.");
100
- });
101
-
102
- test("workspace settings output normalizes raw service payloads", () => {
103
- const expectedTheme = resolveWorkspaceThemePalettes({
104
- lightPrimaryColor: "#0F6B54"
105
- });
106
- const normalized = workspaceSettingsResource.operations.view.outputValidator.normalize({
107
- workspace: {
108
- id: "7",
109
- slug: " mercury ",
110
- ownerUserId: "9"
111
- },
112
- settings: {
113
- lightPrimaryColor: "#0f6b54",
114
- invitesEnabled: false
115
- },
116
- roleCatalog: createRoleCatalog()
117
- });
118
-
119
- assert.deepEqual(normalized, {
120
- workspace: {
121
- id: "7",
122
- slug: "mercury",
123
- ownerUserId: "9"
124
- },
125
- settings: {
126
- lightPrimaryColor: "#0F6B54",
127
- lightSecondaryColor: expectedTheme.light.secondaryColor,
128
- lightSurfaceColor: expectedTheme.light.surfaceColor,
129
- lightSurfaceVariantColor: expectedTheme.light.surfaceVariantColor,
130
- darkPrimaryColor: expectedTheme.dark.color,
131
- darkSecondaryColor: expectedTheme.dark.secondaryColor,
132
- darkSurfaceColor: expectedTheme.dark.surfaceColor,
133
- darkSurfaceVariantColor: expectedTheme.dark.surfaceVariantColor,
134
- invitesEnabled: false,
135
- invitesAvailable: true,
136
- invitesEffective: false
137
- },
138
- roleCatalog: {
139
- collaborationEnabled: true,
140
- defaultInviteRole: "member",
141
- roles: [
142
- {
143
- id: "owner",
144
- assignable: false,
145
- permissions: ["*"]
146
- },
147
- {
148
- id: "admin",
149
- assignable: true,
150
- permissions: [
151
- "workspace.roles.view",
152
- "workspace.settings.view",
153
- "workspace.settings.update",
154
- "workspace.members.view",
155
- "workspace.members.invite",
156
- "workspace.members.manage",
157
- "workspace.invites.revoke"
158
- ]
159
- },
160
- {
161
- id: "member",
162
- assignable: true,
163
- permissions: ["workspace.settings.view"]
164
- }
165
- ],
166
- assignableRoleIds: ["admin", "member"]
167
- }
168
- });
169
- });
@@ -1,140 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import "../test-support/registerDefaultSettingsFields.js";
4
- import { resolveWorkspaceThemePalettes } from "../src/shared/settings.js";
5
- import { createService } from "../src/server/workspaceSettings/workspaceSettingsService.js";
6
-
7
- function authorizedOptions(permissions = []) {
8
- return {
9
- context: {
10
- actor: {
11
- id: 1
12
- },
13
- permissions
14
- }
15
- };
16
- }
17
-
18
- function createFixture({ workspaceInvitationsEnabled = true } = {}) {
19
- const defaultTheme = resolveWorkspaceThemePalettes({
20
- lightPrimaryColor: "#0F6B54"
21
- });
22
- const state = {
23
- settingsPatch: null,
24
- workspace: {
25
- id: 7,
26
- slug: "tonymobily3",
27
- name: "TonyMobily3",
28
- ownerUserId: 9
29
- },
30
- settings: {
31
- lightPrimaryColor: defaultTheme.light.color,
32
- lightSecondaryColor: defaultTheme.light.secondaryColor,
33
- lightSurfaceColor: defaultTheme.light.surfaceColor,
34
- lightSurfaceVariantColor: defaultTheme.light.surfaceVariantColor,
35
- darkPrimaryColor: defaultTheme.dark.color,
36
- darkSecondaryColor: defaultTheme.dark.secondaryColor,
37
- darkSurfaceColor: defaultTheme.dark.surfaceColor,
38
- darkSurfaceVariantColor: defaultTheme.dark.surfaceVariantColor,
39
- invitesEnabled: true
40
- }
41
- };
42
-
43
- const service = createService({
44
- workspaceInvitationsEnabled,
45
- workspaceSettingsRepository: {
46
- async ensureForWorkspaceId(workspaceId) {
47
- assert.equal(Number(workspaceId), 7);
48
- return { ...state.settings };
49
- },
50
- async updateSettingsByWorkspaceId(workspaceId, patch) {
51
- assert.equal(Number(workspaceId), 7);
52
- state.settingsPatch = { ...patch };
53
- state.settings = {
54
- ...state.settings,
55
- ...patch
56
- };
57
- return state.settings;
58
- }
59
- }
60
- });
61
-
62
- return { service, state };
63
- }
64
-
65
- test("workspaceSettingsService.getWorkspaceSettings returns the stored invitesEnabled flag", async () => {
66
- const { service, state } = createFixture();
67
-
68
- const response = await service.getWorkspaceSettings(
69
- state.workspace,
70
- authorizedOptions(["workspace.settings.view"])
71
- );
72
-
73
- assert.deepEqual(response.settings, {
74
- lightPrimaryColor: "#0F6B54",
75
- lightSecondaryColor: "#48A9A6",
76
- lightSurfaceColor: "#FFFFFF",
77
- lightSurfaceVariantColor: "#424242",
78
- darkPrimaryColor: "#2196F3",
79
- darkSecondaryColor: "#54B6B2",
80
- darkSurfaceColor: "#212121",
81
- darkSurfaceVariantColor: "#C8C8C8",
82
- invitesEnabled: true,
83
- invitesAvailable: true,
84
- invitesEffective: true
85
- });
86
- });
87
-
88
- test("workspaceSettingsService.updateWorkspaceSettings writes editable fields through workspaceSettingsRepository only", async () => {
89
- const { service, state } = createFixture();
90
-
91
- const response = await service.updateWorkspaceSettings(
92
- state.workspace,
93
- {
94
- invitesEnabled: false
95
- },
96
- authorizedOptions(["workspace.settings.update"])
97
- );
98
-
99
- assert.deepEqual(state.settingsPatch, {
100
- invitesEnabled: false
101
- });
102
- assert.deepEqual(response.settings, {
103
- lightPrimaryColor: "#0F6B54",
104
- lightSecondaryColor: "#48A9A6",
105
- lightSurfaceColor: "#FFFFFF",
106
- lightSurfaceVariantColor: "#424242",
107
- darkPrimaryColor: "#2196F3",
108
- darkSecondaryColor: "#54B6B2",
109
- darkSurfaceColor: "#212121",
110
- darkSurfaceVariantColor: "#C8C8C8",
111
- invitesEnabled: false,
112
- invitesAvailable: true,
113
- invitesEffective: false
114
- });
115
- });
116
-
117
- test("workspaceSettingsService disables invite settings in output when app policy disables invitations", async () => {
118
- const { service, state } = createFixture({
119
- workspaceInvitationsEnabled: false
120
- });
121
-
122
- const response = await service.getWorkspaceSettings(
123
- state.workspace,
124
- authorizedOptions(["workspace.settings.view"])
125
- );
126
-
127
- assert.deepEqual(response.settings, {
128
- lightPrimaryColor: "#0F6B54",
129
- lightSecondaryColor: "#48A9A6",
130
- lightSurfaceColor: "#FFFFFF",
131
- lightSurfaceVariantColor: "#424242",
132
- darkPrimaryColor: "#2196F3",
133
- darkSecondaryColor: "#54B6B2",
134
- darkSurfaceColor: "#212121",
135
- darkSurfaceVariantColor: "#C8C8C8",
136
- invitesEnabled: false,
137
- invitesAvailable: false,
138
- invitesEffective: false
139
- });
140
- });