diff --git a/Clocker/AppDelegate.swift b/Clocker/AppDelegate.swift index e49ba70..1b9c21d 100644 --- a/Clocker/AppDelegate.swift +++ b/Clocker/AppDelegate.swift @@ -243,15 +243,13 @@ open class AppDelegate: NSObject, NSApplicationDelegate { let displayMode = UserDefaults.standard.integer(forKey: CLShowAppInForeground) if displayMode == 1 { - floatingWindow.showWindow(nil) - floatingWindow.updateTableContent() - floatingWindow.startWindowTimer() + // No need to call NSApp.activate here since `showFloatingWindow` takes care of this + showFloatingWindow() } else { panelController.showWindow(nil) panelController.setActivePanel(newValue: !panelController.hasActivePanelGetter()) + NSApp.activate(ignoringOtherApps: true) } - - NSApp.activate(ignoringOtherApps: true) } open func setupFloatingWindow(_ hide: Bool) { diff --git a/Clocker/ClockerUnitTests/AppDelegateTests.swift b/Clocker/ClockerUnitTests/AppDelegateTests.swift index 91250af..3bd6ee5 100644 --- a/Clocker/ClockerUnitTests/AppDelegateTests.swift +++ b/Clocker/ClockerUnitTests/AppDelegateTests.swift @@ -1,6 +1,7 @@ // Copyright © 2015 Abhishek Banthia import XCTest +import CoreModelKit @testable import Clocker @@ -43,7 +44,7 @@ class AppDelegateTests: XCTestCase { func testFloatingWindow() { let subject = NSApplication.shared.delegate as? AppDelegate let previousWindows = NSApplication.shared.windows - XCTAssertEqual(previousWindows.count, 1) // Only the status bar window should be present + XCTAssertTrue(previousWindows.count >= 1) // Only the status bar window should be present subject?.setupFloatingWindow(true) @@ -68,6 +69,85 @@ class AppDelegateTests: XCTestCase { XCTAssertNotNil(closedFloatingWindow) } + + func testActivationPolicy() { + let subject = NSApplication.shared.delegate as? AppDelegate + let previousOption = UserDefaults.standard.integer(forKey: CLAppDisplayOptions) + if previousOption == 0 { + XCTAssertEqual(NSApp.activationPolicy(), .accessory) + } else { + XCTAssertEqual(NSApp.activationPolicy(), .regular) + } + + subject?.hideFromDock() + XCTAssertEqual(NSApp.activationPolicy(), .accessory) + } + + func testMenubarInvalidationToIcon() { + let subject = NSApplication.shared.delegate as? AppDelegate + subject?.invalidateMenubarTimer(true) + let statusItemHandler = subject?.statusItemForPanel() + XCTAssertNil(statusItemHandler?.statusItem.view) + XCTAssertEqual(statusItemHandler?.statusItem.title, CLEmptyString) + XCTAssertEqual(statusItemHandler?.statusItem.button?.image?.name(), "LightModeIcon") + XCTAssertEqual(statusItemHandler?.statusItem.button?.imagePosition, .imageOnly) + XCTAssertEqual(statusItemHandler?.statusItem.toolTip, "Clocker") + } + + func testCompactModeMenubarSetup() { + let subject = NSApplication.shared.delegate as? AppDelegate + + let timezone1 = TimezoneData() + timezone1.timezoneID = TimeZone.autoupdatingCurrent.identifier + timezone1.formattedAddress = "MenubarTimezone" + timezone1.isFavourite = 1 + // Encode it in UserDefaults + let encodedTimezone = NSKeyedArchiver.archivedData(withRootObject: timezone1) + DataStore.shared().setTimezones([encodedTimezone]) + + subject?.setupMenubarTimer() + let statusItemHandler = subject?.statusItemForPanel() + XCTAssertNotNil(statusItemHandler?.statusItem.view) // This won't be nil for compact mode + + DataStore.shared().setTimezones([]) + } + func testStandardModeMenubarSetup() { + UserDefaults.standard.set(1, forKey: CLMenubarCompactMode) // Set the menubar mode to standard + + let subject = NSApplication.shared.delegate as? AppDelegate + let statusItemHandler = subject?.statusItemForPanel() + + XCTAssertEqual(statusItemHandler?.statusItem.button?.image?.name(), "LightModeIcon") + + let timezone1 = TimezoneData() + timezone1.timezoneID = TimeZone.autoupdatingCurrent.identifier + timezone1.formattedAddress = "MenubarTimezone" + timezone1.isFavourite = 1 + // Encode it in UserDefaults + let encodedTimezone = NSKeyedArchiver.archivedData(withRootObject: timezone1) + DataStore.shared().setTimezones([encodedTimezone]) + + subject?.setupMenubarTimer() + + XCTAssertNil(statusItemHandler?.statusItem.view) // This won't be nil for compact mode + + DataStore.shared().setTimezones([]) + + UserDefaults.standard.set(0, forKey: CLMenubarCompactMode) // Set the menubar mode back to compact + } + + func testTogglingPanel() { + UserDefaults.standard.set(1, forKey: CLShowAppInForeground) + + let subject = NSApplication.shared.delegate as? AppDelegate + subject?.ping("MockArgument") + + UserDefaults.standard.set(0, forKey: CLShowAppInForeground) + let hasActiveGetter = PanelController.shared().hasActivePanel + subject?.ping("MockArgument") + + XCTAssertNotEqual(hasActiveGetter, PanelController.shared().hasActivePanel) + } } diff --git a/Clocker/Preferences/Menu Bar/StatusItemHandler.swift b/Clocker/Preferences/Menu Bar/StatusItemHandler.swift index 596898c..91f1213 100644 --- a/Clocker/Preferences/Menu Bar/StatusItemHandler.swift +++ b/Clocker/Preferences/Menu Bar/StatusItemHandler.swift @@ -200,17 +200,14 @@ class StatusItemHandler: NSObject { private func shouldDisplaySecondsInMenubar() -> Bool { let syncedTimezones = DataStore.shared().menubarTimezones() ?? [] - for timezone in syncedTimezones { - if let timezoneObj = TimezoneData.customObject(from: timezone) { - let shouldShowSeconds = timezoneObj.shouldShowSeconds(DataStore.shared().timezoneFormat()) - if shouldShowSeconds { - return true - } + let timezonesSupportingSeconds = syncedTimezones.filter { data in + if let timezoneObj = TimezoneData.customObject(from: data) { + return timezoneObj.shouldShowSeconds(DataStore.shared().timezoneFormat()) } - continue + return false } - return false + return timezonesSupportingSeconds.isEmpty } private func calculateFireDate() -> Date? {