Skip to content

Commit 9046aa9

Browse files
committed
fix(session-management): session-set-defaults clears mutually exclusive counterparts before merge to prevent invalid store state; add tests
1 parent e1c4629 commit 9046aa9

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

src/mcp/tools/session-management/__tests__/session_set_defaults.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,37 @@ describe('session-set-defaults tool', () => {
5656
expect(result.content[0].text).toContain('Parameter validation failed');
5757
expect(result.content[0].text).toContain('useLatestOS');
5858
});
59+
60+
it('should clear workspacePath when projectPath is set', async () => {
61+
sessionStore.setDefaults({ workspacePath: '/old/App.xcworkspace' });
62+
await sessionSetDefaultsLogic({ projectPath: '/new/App.xcodeproj' });
63+
const current = sessionStore.getAll();
64+
expect(current.projectPath).toBe('/new/App.xcodeproj');
65+
expect(current.workspacePath).toBeUndefined();
66+
});
67+
68+
it('should clear projectPath when workspacePath is set', async () => {
69+
sessionStore.setDefaults({ projectPath: '/old/App.xcodeproj' });
70+
await sessionSetDefaultsLogic({ workspacePath: '/new/App.xcworkspace' });
71+
const current = sessionStore.getAll();
72+
expect(current.workspacePath).toBe('/new/App.xcworkspace');
73+
expect(current.projectPath).toBeUndefined();
74+
});
75+
76+
it('should clear simulatorName when simulatorId is set', async () => {
77+
sessionStore.setDefaults({ simulatorName: 'iPhone 16' });
78+
await sessionSetDefaultsLogic({ simulatorId: 'SIM-UUID' });
79+
const current = sessionStore.getAll();
80+
expect(current.simulatorId).toBe('SIM-UUID');
81+
expect(current.simulatorName).toBeUndefined();
82+
});
83+
84+
it('should clear simulatorId when simulatorName is set', async () => {
85+
sessionStore.setDefaults({ simulatorId: 'SIM-UUID' });
86+
await sessionSetDefaultsLogic({ simulatorName: 'iPhone 16' });
87+
const current = sessionStore.getAll();
88+
expect(current.simulatorName).toBe('iPhone 16');
89+
expect(current.simulatorId).toBeUndefined();
90+
});
5991
});
6092
});

src/mcp/tools/session-management/session_set_defaults.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ const schemaObj = z.object({
1919
type Params = z.infer<typeof schemaObj>;
2020

2121
export async function sessionSetDefaultsLogic(params: Params): Promise<ToolResponse> {
22+
// Clear mutually exclusive counterparts before merging new defaults
23+
const toClear = new Set<keyof SessionDefaults>();
24+
if (Object.prototype.hasOwnProperty.call(params, 'projectPath')) toClear.add('workspacePath');
25+
if (Object.prototype.hasOwnProperty.call(params, 'workspacePath')) toClear.add('projectPath');
26+
if (Object.prototype.hasOwnProperty.call(params, 'simulatorId')) toClear.add('simulatorName');
27+
if (Object.prototype.hasOwnProperty.call(params, 'simulatorName')) toClear.add('simulatorId');
28+
29+
if (toClear.size > 0) {
30+
sessionStore.clear(Array.from(toClear));
31+
}
32+
2233
sessionStore.setDefaults(params as Partial<SessionDefaults>);
2334
const current = sessionStore.getAll();
2435
return {

0 commit comments

Comments
 (0)