Skip to content

Commit 961338e

Browse files
Add organizationFeaturesSchema with roomoteControlEnabled (#8085)
feat: add organizationFeaturesSchema with roomoteControlEnabled - Add organizationFeaturesSchema with optional roomoteControlEnabled boolean - Integrate features property into organizationSettingsSchema as optional - Add comprehensive tests for new schema validation - Maintain backward compatibility with existing organization settings Co-authored-by: Roo Code <[email protected]>
1 parent c837025 commit 961338e

File tree

2 files changed

+184
-0
lines changed

2 files changed

+184
-0
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
// npx vitest run src/__tests__/cloud.test.ts
2+
3+
import {
4+
organizationFeaturesSchema,
5+
organizationSettingsSchema,
6+
type OrganizationFeatures,
7+
type OrganizationSettings,
8+
} from "../cloud.js"
9+
10+
describe("organizationFeaturesSchema", () => {
11+
it("should validate empty object", () => {
12+
const result = organizationFeaturesSchema.safeParse({})
13+
expect(result.success).toBe(true)
14+
expect(result.data).toEqual({})
15+
})
16+
17+
it("should validate with roomoteControlEnabled as true", () => {
18+
const input = { roomoteControlEnabled: true }
19+
const result = organizationFeaturesSchema.safeParse(input)
20+
expect(result.success).toBe(true)
21+
expect(result.data).toEqual(input)
22+
})
23+
24+
it("should validate with roomoteControlEnabled as false", () => {
25+
const input = { roomoteControlEnabled: false }
26+
const result = organizationFeaturesSchema.safeParse(input)
27+
expect(result.success).toBe(true)
28+
expect(result.data).toEqual(input)
29+
})
30+
31+
it("should reject non-boolean roomoteControlEnabled", () => {
32+
const input = { roomoteControlEnabled: "true" }
33+
const result = organizationFeaturesSchema.safeParse(input)
34+
expect(result.success).toBe(false)
35+
})
36+
37+
it("should allow additional properties (for future extensibility)", () => {
38+
const input = { roomoteControlEnabled: true, futureProperty: "test" }
39+
const result = organizationFeaturesSchema.safeParse(input)
40+
expect(result.success).toBe(true)
41+
expect(result.data?.roomoteControlEnabled).toBe(true)
42+
// Note: Additional properties are stripped by Zod, which is expected behavior
43+
})
44+
45+
it("should have correct TypeScript type", () => {
46+
// Type-only test to ensure TypeScript compilation
47+
const features: OrganizationFeatures = {
48+
roomoteControlEnabled: true,
49+
}
50+
expect(features.roomoteControlEnabled).toBe(true)
51+
52+
const emptyFeatures: OrganizationFeatures = {}
53+
expect(emptyFeatures.roomoteControlEnabled).toBeUndefined()
54+
})
55+
})
56+
57+
describe("organizationSettingsSchema with features", () => {
58+
const validBaseSettings = {
59+
version: 1,
60+
defaultSettings: {},
61+
allowList: {
62+
allowAll: true,
63+
providers: {},
64+
},
65+
}
66+
67+
it("should validate without features property", () => {
68+
const result = organizationSettingsSchema.safeParse(validBaseSettings)
69+
expect(result.success).toBe(true)
70+
expect(result.data?.features).toBeUndefined()
71+
})
72+
73+
it("should validate with empty features object", () => {
74+
const input = {
75+
...validBaseSettings,
76+
features: {},
77+
}
78+
const result = organizationSettingsSchema.safeParse(input)
79+
expect(result.success).toBe(true)
80+
expect(result.data?.features).toEqual({})
81+
})
82+
83+
it("should validate with features.roomoteControlEnabled as true", () => {
84+
const input = {
85+
...validBaseSettings,
86+
features: {
87+
roomoteControlEnabled: true,
88+
},
89+
}
90+
const result = organizationSettingsSchema.safeParse(input)
91+
expect(result.success).toBe(true)
92+
expect(result.data?.features?.roomoteControlEnabled).toBe(true)
93+
})
94+
95+
it("should validate with features.roomoteControlEnabled as false", () => {
96+
const input = {
97+
...validBaseSettings,
98+
features: {
99+
roomoteControlEnabled: false,
100+
},
101+
}
102+
const result = organizationSettingsSchema.safeParse(input)
103+
expect(result.success).toBe(true)
104+
expect(result.data?.features?.roomoteControlEnabled).toBe(false)
105+
})
106+
107+
it("should reject invalid features object", () => {
108+
const input = {
109+
...validBaseSettings,
110+
features: {
111+
roomoteControlEnabled: "invalid",
112+
},
113+
}
114+
const result = organizationSettingsSchema.safeParse(input)
115+
expect(result.success).toBe(false)
116+
})
117+
118+
it("should have correct TypeScript type for features", () => {
119+
// Type-only test to ensure TypeScript compilation
120+
const settings: OrganizationSettings = {
121+
version: 1,
122+
defaultSettings: {},
123+
allowList: {
124+
allowAll: true,
125+
providers: {},
126+
},
127+
features: {
128+
roomoteControlEnabled: true,
129+
},
130+
}
131+
expect(settings.features?.roomoteControlEnabled).toBe(true)
132+
133+
const settingsWithoutFeatures: OrganizationSettings = {
134+
version: 1,
135+
defaultSettings: {},
136+
allowList: {
137+
allowAll: true,
138+
providers: {},
139+
},
140+
}
141+
expect(settingsWithoutFeatures.features).toBeUndefined()
142+
})
143+
144+
it("should maintain all existing properties", () => {
145+
const input = {
146+
version: 1,
147+
cloudSettings: {
148+
recordTaskMessages: true,
149+
enableTaskSharing: false,
150+
},
151+
defaultSettings: {},
152+
allowList: {
153+
allowAll: false,
154+
providers: {
155+
openai: {
156+
allowAll: true,
157+
models: ["gpt-4"],
158+
},
159+
},
160+
},
161+
features: {
162+
roomoteControlEnabled: true,
163+
},
164+
hiddenMcps: ["test-mcp"],
165+
hideMarketplaceMcps: true,
166+
mcps: [],
167+
providerProfiles: {},
168+
}
169+
const result = organizationSettingsSchema.safeParse(input)
170+
expect(result.success).toBe(true)
171+
expect(result.data).toEqual(input)
172+
})
173+
})

packages/types/src/cloud.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ export const organizationCloudSettingsSchema = z.object({
133133

134134
export type OrganizationCloudSettings = z.infer<typeof organizationCloudSettingsSchema>
135135

136+
/**
137+
* OrganizationFeatures
138+
*/
139+
140+
export const organizationFeaturesSchema = z.object({
141+
roomoteControlEnabled: z.boolean().optional(),
142+
})
143+
144+
export type OrganizationFeatures = z.infer<typeof organizationFeaturesSchema>
145+
136146
/**
137147
* OrganizationSettings
138148
*/
@@ -142,6 +152,7 @@ export const organizationSettingsSchema = z.object({
142152
cloudSettings: organizationCloudSettingsSchema.optional(),
143153
defaultSettings: organizationDefaultSettingsSchema,
144154
allowList: organizationAllowListSchema,
155+
features: organizationFeaturesSchema.optional(),
145156
hiddenMcps: z.array(z.string()).optional(),
146157
hideMarketplaceMcps: z.boolean().optional(),
147158
mcps: z.array(mcpMarketplaceItemSchema).optional(),

0 commit comments

Comments
 (0)