mirror of
https://github.com/home-assistant/iOS.git
synced 2026-02-08 15:45:13 -06:00
## Summary Converted `ConnectionURLViewController` from UIKit/Eureka forms to native SwiftUI (`ConnectionURLView`) with snapshot test coverage. **Changes:** - **ConnectionURLView.swift** (new): SwiftUI implementation with Form-based UI - URL input with validation (internal/external/cloud toggle) - Dynamic SSID/hardware address lists with add/delete - Location permission checks (iOS 14+ accuracy support) - Local push configuration with doc link - Promise-based save with error handling - **ConnectionSettingsViewController.swift**: Push SwiftUI view via `UIHostingController` instead of `ButtonRowWithPresent` - **ConnectionURLView.test.swift** (new): Snapshot tests for internal/external URL types in light/dark modes - **ConnectionURLViewController.swift**: Removed (393 lines) Net: -2 lines, modernized architecture, improved maintainability. ## Screenshots <!-- If this is a user-facing change not in the frontend, please include screenshots in light and dark mode. --> ## Link to pull request in Documentation repository <!-- Pull requests that add, change or remove functionality must have a corresponding pull request in the Companion App Documentation repository (https://github.com/home-assistant/companion.home-assistant). Please add the number of this pull request after the "#" --> Documentation: home-assistant/companion.home-assistant# ## Any other notes All functionality preserved from original implementation. Snapshot tests will generate reference images on first run. <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > Convert ConnectionURLViewController to SwiftUI and add snapshot tests </details> <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/home-assistant/iOS/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com>
81 lines
2.8 KiB
Swift
81 lines
2.8 KiB
Swift
import CoreLocation
|
|
import Foundation
|
|
@testable @preconcurrency import Shared
|
|
import Testing
|
|
|
|
// MARK: - Mock LocationManager for Testing
|
|
|
|
final class MockLocationManager: LocationManagerProtocol {
|
|
var mockPermissionState: LocationPermissionState = .notDetermined
|
|
var mockAccuracyAuthorization: CLAccuracyAuthorization = .fullAccuracy
|
|
var mockLocationServicesEnabled: Bool = true
|
|
var requestLocationPermissionCalled = false
|
|
|
|
var currentPermissionState: LocationPermissionState {
|
|
mockPermissionState
|
|
}
|
|
|
|
var accuracyAuthorization: CLAccuracyAuthorization {
|
|
mockAccuracyAuthorization
|
|
}
|
|
|
|
var isLocationServicesEnabled: Bool {
|
|
mockLocationServicesEnabled
|
|
}
|
|
|
|
func requestLocationPermission() {
|
|
requestLocationPermissionCalled = true
|
|
}
|
|
|
|
// Helper method to simulate permission state changes
|
|
func simulatePermissionStateChange(to newState: LocationPermissionState) {
|
|
mockPermissionState = newState
|
|
let userInfo = ["permissionState": newState]
|
|
NotificationCenter.default.post(
|
|
name: .locationPermissionDidChange,
|
|
object: self,
|
|
userInfo: userInfo
|
|
)
|
|
}
|
|
}
|
|
|
|
// MARK: - Tests
|
|
|
|
@Suite("LocationManager Tests")
|
|
struct LocationManagerTests {
|
|
@Test("LocationPermissionState initialization from CLAuthorizationStatus")
|
|
func locationPermissionStateInitialization() async throws {
|
|
#expect(LocationPermissionState(from: .notDetermined) == .notDetermined)
|
|
#expect(LocationPermissionState(from: .denied) == .denied)
|
|
#expect(LocationPermissionState(from: .restricted) == .restricted)
|
|
#expect(LocationPermissionState(from: .authorizedWhenInUse) == .authorizedWhenInUse)
|
|
#expect(LocationPermissionState(from: .authorizedAlways) == .authorizedAlways)
|
|
}
|
|
|
|
@Test("MockLocationManager returns correct permission state")
|
|
func mockLocationManagerPermissionState() async throws {
|
|
let mockManager = MockLocationManager()
|
|
mockManager.mockPermissionState = .authorizedWhenInUse
|
|
|
|
#expect(mockManager.currentPermissionState == .authorizedWhenInUse)
|
|
}
|
|
|
|
@Test("MockLocationManager tracks method calls")
|
|
func mockLocationManagerMethodCalls() async throws {
|
|
let mockManager = MockLocationManager()
|
|
|
|
#expect(!mockManager.requestLocationPermissionCalled)
|
|
|
|
mockManager.requestLocationPermission()
|
|
#expect(mockManager.requestLocationPermissionCalled)
|
|
}
|
|
|
|
@Test("MockLocationManager returns correct accuracy authorization")
|
|
func mockLocationManagerAccuracyAuthorization() async throws {
|
|
let mockManager = MockLocationManager()
|
|
mockManager.mockAccuracyAuthorization = .reducedAccuracy
|
|
|
|
#expect(mockManager.accuracyAuthorization == .reducedAccuracy)
|
|
}
|
|
}
|