From 9aa0708fcf8a6a70bcdeafa68c8c773aa83b2ee7 Mon Sep 17 00:00:00 2001 From: Kevin McKee Date: Wed, 2 Jul 2025 11:16:27 -0700 Subject: [PATCH 1/2] Hoping these network tests pass on Github runners --- Sources/OAuthKit/Network/NetworkMonitor.swift | 14 +++++++------- Tests/OAuthKitTests/UtilityTests.swift | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/Sources/OAuthKit/Network/NetworkMonitor.swift b/Sources/OAuthKit/Network/NetworkMonitor.swift index 8b4b648..37b12b7 100644 --- a/Sources/OAuthKit/Network/NetworkMonitor.swift +++ b/Sources/OAuthKit/Network/NetworkMonitor.swift @@ -11,28 +11,28 @@ import Observation /// A type that broadcasts network reachability via Combine event publishing. @MainActor @Observable -final class NetworkMonitor { +public final class NetworkMonitor { @ObservationIgnored private let pathMonitor = NWPathMonitor() /// Returns true if the network has an available wifi interface. - var onWifi = false + public var onWifi = false /// Returns true if the network has an available cellular interface. - var onCellular = false + public var onCellular = false /// Returns true if the network has an wired ethernet interface. - var onWiredEthernet = false + public var onWiredEthernet = false /// Returns true if the network is online with any available interface. - var isOnline: Bool { + public var isOnline: Bool { onWifi || onCellular || onWiredEthernet } /// Initializer. - init() { } + public init() { } /// Starts the network monitor (conforms to AsyncSequence). - func start() async { + public func start() async { for await path in pathMonitor { handle(path: path) } diff --git a/Tests/OAuthKitTests/UtilityTests.swift b/Tests/OAuthKitTests/UtilityTests.swift index 895bddf..4b3b3ca 100644 --- a/Tests/OAuthKitTests/UtilityTests.swift +++ b/Tests/OAuthKitTests/UtilityTests.swift @@ -148,5 +148,23 @@ struct UtilityTests { let executed = try await task.value #expect(executed) } + + /// Tests the network monitor + @MainActor + @Test("Network Monitor") + func whenNetworkMonitoring() async throws { + let monitor = NetworkMonitor() + #expect(monitor.isOnline == false) + withObservationTracking { + _ = monitor.isOnline + } onChange: { + Task { @MainActor in + #expect(monitor.isOnline) + } + } + Task { + await monitor.start() + } + } } From d79bd2f7660d0bf50530c738109a3916d8c8f818 Mon Sep 17 00:00:00 2001 From: Kevin McKee Date: Wed, 2 Jul 2025 11:24:55 -0700 Subject: [PATCH 2/2] Code cleanup --- Sources/OAuthKit/OAuth+Request.swift | 9 +++------ Sources/OAuthKit/OAuth.swift | 22 +++++++--------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/Sources/OAuthKit/OAuth+Request.swift b/Sources/OAuthKit/OAuth+Request.swift index 155f3de..051388b 100644 --- a/Sources/OAuthKit/OAuth+Request.swift +++ b/Sources/OAuthKit/OAuth+Request.swift @@ -103,9 +103,7 @@ extension OAuth { /// - deviceCode: the device code data /// - Returns: a `/token` request that can be used for polling static func token(provider: Provider, deviceCode: DeviceCode) -> URLRequest? { - guard var urlComponents = URLComponents(string: provider.accessTokenURL.absoluteString) else { - return nil - } + guard var urlComponents = URLComponents(string: provider.accessTokenURL.absoluteString) else { return nil } urlComponents.queryItems = buildQueryItems(provider: provider, deviceCode: deviceCode) guard let url = urlComponents.url else { return nil } var request = URLRequest(url: url) @@ -144,9 +142,8 @@ extension OAuth { /// - provider: the oauth provider /// - Returns: the url request static func device(provider: Provider) -> URLRequest? { - guard let deviceCodeURL = provider.deviceCodeURL, var urlComponents = URLComponents(string: deviceCodeURL.absoluteString) else { - return nil - } + guard let deviceCodeURL = provider.deviceCodeURL, + var urlComponents = URLComponents(string: deviceCodeURL.absoluteString) else { return nil } urlComponents.queryItems = buildQueryItems(provider: provider, grantType: .deviceCode) guard let url = urlComponents.url else { return nil } var request = URLRequest(url: url) diff --git a/Sources/OAuthKit/OAuth.swift b/Sources/OAuthKit/OAuth.swift index 60e6dc3..8b8b7f6 100644 --- a/Sources/OAuthKit/OAuth.swift +++ b/Sources/OAuthKit/OAuth.swift @@ -382,9 +382,7 @@ extension OAuth { /// - Parameters: /// - provider: the provider to request a refresh token for func refreshToken(provider: Provider) async { - guard let auth: OAuth.Authorization = try? keychain.get(key: provider.id) else { - return - } + guard let auth: OAuth.Authorization = try? keychain.get(key: provider.id) else { return } // If we can't build a refresh request simply bail as no refresh token // was returned in the original auth request @@ -422,8 +420,7 @@ extension OAuth { func requestDeviceCode(provider: Provider) async { guard let request = Request.device(provider: provider) else { return } guard let (data, response) = try? await urlSession.data(for: request) else { - publish(state: .empty) - return + return publish(state: .empty) } if provider.debug { @@ -434,8 +431,7 @@ extension OAuth { // Decode the device code guard let deviceCode = try? decoder.decode(DeviceCode.self, from: data) else { - publish(state: .empty) - return + return publish(state: .empty) } // Publish the state @@ -448,8 +444,7 @@ extension OAuth { func requestClientCredentials(provider: Provider) async { guard let request = Request.token(provider: provider) else { return } guard let (data, response) = try? await urlSession.data(for: request) else { - publish(state: .empty) - return + return publish(state: .empty) } if provider.debug { @@ -479,13 +474,11 @@ extension OAuth { func poll(provider: Provider, deviceCode: DeviceCode) async { guard !deviceCode.isExpired, let request = Request.token(provider: provider, deviceCode: deviceCode) else { - publish(state: .empty) - return + return publish(state: .empty) } guard let (data, response) = try? await urlSession.data(for: request) else { - publish(state: .empty) - return + return publish(state: .empty) } if provider.debug { @@ -497,8 +490,7 @@ extension OAuth { /// If we received something other than a 200 response or we can't decode the token then restart the polling guard response.isOK, let token = try? decoder.decode(Token.self, from: data) else { // Reschedule the polling task - schedule(provider: provider, deviceCode: deviceCode) - return + return schedule(provider: provider, deviceCode: deviceCode) } // Store the authorization