Files
clipbored/tests/clipboredtests/AppDelegateTests.swift

209 lines
7.5 KiB
Swift
Raw Normal View History

2026-06-30 01:12:19 -07:00
import AppKit
import XCTest
@testable import ClipBored
final class AppDelegateTests: XCTestCase {
2026-06-30 02:25:52 -07:00
func testPresentationPlanMapsDockPreferenceToActivationPolicy() {
let dockless = AppDelegate.presentationPlan(
showMenuBarIcon: true,
showDockIcon: false,
changedSurface: nil
)
XCTAssertTrue(dockless.showMenuBarIcon)
XCTAssertFalse(dockless.showDockIcon)
XCTAssertEqual(dockless.activationPolicy, .accessory)
let dockVisible = AppDelegate.presentationPlan(
showMenuBarIcon: true,
showDockIcon: true,
changedSurface: nil
)
XCTAssertTrue(dockVisible.showMenuBarIcon)
XCTAssertTrue(dockVisible.showDockIcon)
XCTAssertEqual(dockVisible.activationPolicy, .regular)
}
func testPresentationPlanKeepsOneVisibleEntryPoint() {
let hidingMenuBar = AppDelegate.presentationPlan(
showMenuBarIcon: false,
showDockIcon: false,
changedSurface: .menuBar
)
XCTAssertFalse(hidingMenuBar.showMenuBarIcon)
XCTAssertTrue(hidingMenuBar.showDockIcon)
XCTAssertEqual(hidingMenuBar.activationPolicy, .regular)
let hidingDock = AppDelegate.presentationPlan(
showMenuBarIcon: false,
showDockIcon: false,
changedSurface: .dock
)
XCTAssertTrue(hidingDock.showMenuBarIcon)
XCTAssertFalse(hidingDock.showDockIcon)
XCTAssertEqual(hidingDock.activationPolicy, .accessory)
}
2026-06-30 01:12:19 -07:00
func testStatusItemMenuRoutingSeparatesLeftAndRightClick() {
XCTAssertFalse(AppDelegate.shouldOpenStatusMenu(eventType: .leftMouseUp, modifierFlags: []))
XCTAssertTrue(AppDelegate.shouldOpenStatusMenu(eventType: .rightMouseUp, modifierFlags: []))
XCTAssertTrue(AppDelegate.shouldOpenStatusMenu(eventType: .leftMouseUp, modifierFlags: .control))
XCTAssertTrue(AppDelegate.shouldOpenStatusMenu(eventType: .otherMouseUp, modifierFlags: []))
XCTAssertFalse(AppDelegate.shouldOpenStatusMenu(eventType: .leftMouseDragged, modifierFlags: .control))
}
func testStatusMenuIncludesStateRowsAndBoundedActions() {
let settingsTitle = "Settings\u{2026}"
let presentation = AppDelegate.statusMenuPresentation(
historyCount: 42,
isCapturePaused: false,
captureStatus: "Captured text from Safari.",
pasteStatus: "",
shortcutStatus: "",
accessibilityStatus: "",
launchAtLoginStatus: ""
)
let menu = AppDelegate.makeStatusMenu(
presentation: presentation,
isCapturePaused: false,
openShortcut: AppConfiguration.defaultOpenShortcut,
settingsShortcut: AppConfiguration.defaultSettingsShortcut,
target: nil
)
XCTAssertEqual(
menu.items.map { $0.isSeparatorItem ? "-" : $0.title },
[
"ClipBored",
"Capture Running - 42 clips",
"Captured text from Safari.",
"-",
"Show Clipboard",
2026-07-08 01:13:02 -04:00
"New Collection",
"Stack Capture",
2026-06-30 01:12:19 -07:00
settingsTitle,
"-",
"Pause Capture",
2026-07-08 01:13:02 -04:00
"Pause for 5 Minutes",
"Pause for 30 Minutes",
"Pause for 1 Hour",
2026-06-30 01:12:19 -07:00
"-",
"Quit ClipBored"
]
)
let showClipboard = menu.items.first { $0.title == "Show Clipboard" }
XCTAssertEqual(showClipboard?.keyEquivalent, "v")
XCTAssertTrue(showClipboard?.keyEquivalentModifierMask.contains(.command) == true)
XCTAssertTrue(showClipboard?.keyEquivalentModifierMask.contains(.option) == true)
2026-07-08 01:13:02 -04:00
XCTAssertNil(menu.items.first { $0.title == "New Text Clip" })
let newCollection = menu.items.first { $0.title == "New Collection" }
XCTAssertEqual(newCollection?.keyEquivalent, "n")
XCTAssertTrue(newCollection?.keyEquivalentModifierMask.contains(.command) == true)
XCTAssertTrue(newCollection?.keyEquivalentModifierMask.contains(.shift) == true)
let stackCapture = menu.items.first { $0.title == "Stack Capture" }
XCTAssertEqual(stackCapture?.keyEquivalent, "c")
XCTAssertTrue(stackCapture?.keyEquivalentModifierMask.contains(.command) == true)
XCTAssertTrue(stackCapture?.keyEquivalentModifierMask.contains(.shift) == true)
2026-06-30 01:12:19 -07:00
let settings = menu.items.first { $0.title == settingsTitle }
XCTAssertEqual(settings?.keyEquivalent, ",")
XCTAssertTrue(settings?.keyEquivalentModifierMask.contains(.command) == true)
2026-07-08 01:13:02 -04:00
let pauseCapture = menu.items.first { $0.title == "Pause Capture" }
XCTAssertEqual(pauseCapture?.keyEquivalent, "t")
XCTAssertTrue(pauseCapture?.keyEquivalentModifierMask.contains(.command) == true)
2026-06-30 01:12:19 -07:00
}
func testStatusMenuPausedStateTakesPriorityOverOlderCaptureStatus() {
let presentation = AppDelegate.statusMenuPresentation(
historyCount: 1,
isCapturePaused: true,
captureStatus: "Captured link from Safari.",
pasteStatus: "Copied",
shortcutStatus: "",
accessibilityStatus: "",
launchAtLoginStatus: ""
)
let menu = AppDelegate.makeStatusMenu(
presentation: presentation,
isCapturePaused: true,
openShortcut: AppConfiguration.defaultOpenShortcut,
settingsShortcut: AppConfiguration.defaultSettingsShortcut,
target: nil
)
XCTAssertEqual(presentation.summary, "Capture Paused - 1 clip")
XCTAssertEqual(presentation.detail, "Capture is paused.")
2026-07-08 01:13:02 -04:00
let resumeCapture = menu.items.first { $0.title == "Resume Capture" }
XCTAssertEqual(resumeCapture?.state, .on)
XCTAssertEqual(resumeCapture?.keyEquivalent, "t")
XCTAssertTrue(resumeCapture?.keyEquivalentModifierMask.contains(.command) == true)
2026-06-30 01:12:19 -07:00
XCTAssertNil(menu.items.first { $0.title == "Pause Capture" })
2026-07-08 01:13:02 -04:00
XCTAssertNil(menu.items.first { $0.title == "Pause for 5 Minutes" })
}
func testStatusMenuPresentationShowsTimedPauseRemainingBeforeOlderStatuses() {
let now = Date(timeIntervalSince1970: 1_000)
let presentation = AppDelegate.statusMenuPresentation(
historyCount: 12,
isCapturePaused: true,
pauseCaptureUntil: now.addingTimeInterval(5 * 60),
now: now,
captureStatus: "Captured text from Safari.",
pasteStatus: "",
shortcutStatus: "",
accessibilityStatus: "",
launchAtLoginStatus: ""
)
XCTAssertEqual(presentation.summary, "Capture Paused - 12 clips")
XCTAssertEqual(presentation.detail, "Capture is paused for 5 more minutes.")
}
func testCapturePauseExpiryOnlyAppliesToExpiredTimedPauses() {
let now = Date(timeIntervalSince1970: 1_000)
XCTAssertTrue(AppDelegate.shouldResumeExpiredCapturePause(
isCapturePaused: true,
pauseCaptureUntil: now,
now: now
))
XCTAssertFalse(AppDelegate.shouldResumeExpiredCapturePause(
isCapturePaused: true,
pauseCaptureUntil: now.addingTimeInterval(1),
now: now
))
XCTAssertFalse(AppDelegate.shouldResumeExpiredCapturePause(
isCapturePaused: false,
pauseCaptureUntil: now.addingTimeInterval(-1),
now: now
))
XCTAssertFalse(AppDelegate.shouldResumeExpiredCapturePause(
isCapturePaused: true,
pauseCaptureUntil: nil,
now: now
))
2026-06-30 01:12:19 -07:00
}
func testStatusMenuPresentationTruncatesLongStatusText() {
let presentation = AppDelegate.statusMenuPresentation(
historyCount: 2000,
isCapturePaused: false,
captureStatus: "Skipped:\n" + String(repeating: "A very long ignored source application name ", count: 4),
pasteStatus: "",
shortcutStatus: "",
accessibilityStatus: "",
launchAtLoginStatus: ""
)
XCTAssertEqual(presentation.summary, "Capture Running - 2000 clips")
XCTAssertNotNil(presentation.detail)
XCTAssertLessThanOrEqual(presentation.detail?.count ?? 0, 68)
XCTAssertTrue(presentation.detail?.hasSuffix("...") == true)
XCTAssertFalse(presentation.detail?.contains("\n") == true)
}
}