import AppKit import XCTest @testable import MacTools final class MenuBarStatusItemControllerTests: XCTestCase { func testNilEventDefaultsToComponentPanel() { XCTAssertEqual(MenuBarStatusItemInvocation.invocation(for: nil), .componentPanel) } func testLeftMouseDownOpensComponentPanelImmediately() { let event = NSEvent.mouseEvent( with: .leftMouseDown, location: .zero, modifierFlags: [], timestamp: 0, windowNumber: 0, context: nil, eventNumber: 0, clickCount: 1, pressure: 0 ) XCTAssertEqual(MenuBarStatusItemInvocation.invocation(for: event), .componentPanel) } func testLeftMouseUpStillOpensComponentPanelForProgrammaticFallback() { let event = NSEvent.mouseEvent( with: .leftMouseUp, location: .zero, modifierFlags: [], timestamp: 0, windowNumber: 0, context: nil, eventNumber: 0, clickCount: 1, pressure: 0 ) XCTAssertEqual(MenuBarStatusItemInvocation.invocation(for: event), .componentPanel) } func testRightMouseDownOpensFeaturePanelImmediately() { let event = NSEvent.mouseEvent( with: .rightMouseDown, location: .zero, modifierFlags: [], timestamp: 0, windowNumber: 0, context: nil, eventNumber: 0, clickCount: 1, pressure: 0 ) XCTAssertEqual(MenuBarStatusItemInvocation.invocation(for: event), .featurePanel) } func testRightMouseUpStillOpensFeaturePanelForProgrammaticFallback() { let event = NSEvent.mouseEvent( with: .rightMouseUp, location: .zero, modifierFlags: [], timestamp: 0, windowNumber: 0, context: nil, eventNumber: 0, clickCount: 1, pressure: 0 ) XCTAssertEqual(MenuBarStatusItemInvocation.invocation(for: event), .featurePanel) } func testModifierLeftClicksRouteOnlyOptionToRightClickAction() { XCTAssertEqual( MenuBarStatusItemInvocation.invocation(for: mouseEvent(.leftMouseUp, modifiers: [.control])), .componentPanel ) XCTAssertEqual( MenuBarStatusItemInvocation.invocation(for: mouseEvent(.leftMouseUp, modifiers: [.option])), .featurePanel ) } // MARK: - Swapped click behavior private func mouseEvent(_ type: NSEvent.EventType, modifiers: NSEvent.ModifierFlags = []) -> NSEvent? { NSEvent.mouseEvent( with: type, location: .zero, modifierFlags: modifiers, timestamp: 0, windowNumber: 0, context: nil, eventNumber: 0, clickCount: 1, pressure: 0 ) } func testSwappedLeftClickOpensFeaturePanel() { XCTAssertEqual( MenuBarStatusItemInvocation.invocation(for: mouseEvent(.leftMouseDown), swapped: true), .featurePanel ) } func testSwappedRightClickOpensComponentPanel() { XCTAssertEqual( MenuBarStatusItemInvocation.invocation(for: mouseEvent(.rightMouseDown), swapped: true), .componentPanel ) } func testSwappedNilEventOpensFeaturePanel() { XCTAssertEqual( MenuBarStatusItemInvocation.invocation(for: nil, swapped: true), .featurePanel ) } func testSwappedModifierLeftClicksRouteOnlyOptionToRightClickAction() { XCTAssertEqual( MenuBarStatusItemInvocation.invocation( for: mouseEvent(.leftMouseUp, modifiers: [.control]), swapped: true ), .featurePanel ) XCTAssertEqual( MenuBarStatusItemInvocation.invocation( for: mouseEvent(.leftMouseUp, modifiers: [.option]), swapped: true ), .componentPanel ) } func testClickBehaviorPreferenceDefaultsToStandard() { let suite = "MenuBarClickBehaviorPreferenceTests-\(UUID().uuidString)" let defaults = UserDefaults(suiteName: suite)! defer { defaults.removePersistentDomain(forName: suite) } XCTAssertEqual(MenuBarClickBehaviorPreference.current(defaults), .standard) XCTAssertFalse(MenuBarClickBehaviorPreference.current(defaults).isSwapped) defaults.set(MenuBarClickBehaviorPreference.swapped.rawValue, forKey: MenuBarClickBehaviorPreference.userDefaultsKey) XCTAssertEqual(MenuBarClickBehaviorPreference.current(defaults), .swapped) XCTAssertTrue(MenuBarClickBehaviorPreference.current(defaults).isSwapped) } func testExpandedSessionUsesOptionAsRightClickAction() { XCTAssertEqual( MenuBarStatusItemInvocation.invocationForExpandedSession( swapped: false, liveModifierFlags: [] ), .componentPanel ) XCTAssertEqual( MenuBarStatusItemInvocation.invocationForExpandedSession( swapped: false, liveModifierFlags: [.control] ), .componentPanel ) XCTAssertEqual( MenuBarStatusItemInvocation.invocationForExpandedSession( swapped: false, liveModifierFlags: [.option] ), .featurePanel ) XCTAssertEqual( MenuBarStatusItemInvocation.invocationForExpandedSession( swapped: true, liveModifierFlags: [.option] ), .componentPanel ) } }