From d219a41dd09298bcc43f5907309267e6bca2034d Mon Sep 17 00:00:00 2001 From: austinpower1258 Date: Fri, 20 Mar 2026 19:27:37 -0700 Subject: [PATCH] Add pinned workspace close regression tests --- cmuxTests/TabManagerUnitTests.swift | 26 +++++++++++++ ...erminalControllerSocketSecurityTests.swift | 38 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/cmuxTests/TabManagerUnitTests.swift b/cmuxTests/TabManagerUnitTests.swift index d6942378..fc5fbc1c 100644 --- a/cmuxTests/TabManagerUnitTests.swift +++ b/cmuxTests/TabManagerUnitTests.swift @@ -304,6 +304,32 @@ final class TabManagerCloseCurrentPanelTests: XCTestCase { XCTAssertTrue(secondWorkspace.panels.isEmpty) } + func testCloseCurrentPanelKeepsPinnedWorkspaceOpenWhenItOwnsTheLastSurface() { + let manager = TabManager() + _ = manager.tabs[0] + let pinnedWorkspace = manager.addWorkspace() + manager.setPinned(pinnedWorkspace, pinned: true) + manager.selectWorkspace(pinnedWorkspace) + + guard let pinnedPanelId = pinnedWorkspace.focusedPanelId else { + XCTFail("Expected focused panel in pinned workspace") + return + } + + XCTAssertEqual(manager.selectedTabId, pinnedWorkspace.id) + XCTAssertEqual(pinnedWorkspace.panels.count, 1) + + manager.closeCurrentPanelWithConfirmation() + drainMainQueue() + drainMainQueue() + + XCTAssertEqual(manager.tabs.count, 2) + XCTAssertTrue(manager.tabs.contains(where: { $0.id == pinnedWorkspace.id })) + XCTAssertEqual(manager.selectedTabId, pinnedWorkspace.id) + XCTAssertNotNil(pinnedWorkspace.panels[pinnedPanelId]) + XCTAssertEqual(pinnedWorkspace.panels.count, 1) + } + func testCloseCurrentPanelKeepsWorkspaceOpenWhenKeepWorkspaceOpenPreferenceIsEnabled() { let defaults = UserDefaults.standard let originalSetting = defaults.object(forKey: lastSurfaceCloseShortcutDefaultsKey) diff --git a/cmuxTests/TerminalControllerSocketSecurityTests.swift b/cmuxTests/TerminalControllerSocketSecurityTests.swift index 10ace119..35a0ff70 100644 --- a/cmuxTests/TerminalControllerSocketSecurityTests.swift +++ b/cmuxTests/TerminalControllerSocketSecurityTests.swift @@ -216,6 +216,44 @@ final class TerminalControllerSocketSecurityTests: XCTestCase { XCTAssertFalse(store.hasUnreadNotification(forTabId: workspace.id, surfaceId: focusedPanelId)) } + func testWorkspaceCloseRejectsPinnedWorkspace() async throws { + let socketPath = makeSocketPath("close-pinned") + let manager = TabManager() + let pinnedWorkspace = manager.addWorkspace(select: false) + manager.setPinned(pinnedWorkspace, pinned: true) + + TerminalController.shared.start( + tabManager: manager, + socketPath: socketPath, + accessMode: .allowAll + ) + try waitForSocket(at: socketPath) + + let response = try await withCheckedThrowingContinuation { continuation in + DispatchQueue.global(qos: .userInitiated).async { + do { + let response = try self.sendV2Request( + method: "workspace.close", + params: ["workspace_id": pinnedWorkspace.id.uuidString], + to: socketPath + ) + continuation.resume(returning: response) + } catch { + continuation.resume(throwing: error) + } + } + } + + XCTAssertEqual(response["ok"] as? Bool, false, "Unexpected JSON-RPC response: \(response)") + let error = try XCTUnwrap(response["error"] as? [String: Any], "Unexpected JSON-RPC response: \(response)") + XCTAssertEqual(error["code"] as? String, "protected") + + let data = try XCTUnwrap(error["data"] as? [String: Any], "Expected error data payload") + XCTAssertEqual(data["workspace_id"] as? String, pinnedWorkspace.id.uuidString) + XCTAssertEqual(data["pinned"] as? Bool, true) + XCTAssertTrue(manager.tabs.contains(where: { $0.id == pinnedWorkspace.id })) + } + private func waitForSocket(at path: String, timeout: TimeInterval = 2.0) throws { let expectation = XCTNSPredicateExpectation( predicate: NSPredicate { _, _ in