Repository navigation
Move the hotspot lifecycle into a tested HotspotSession - #25
Closed
viktor-svirsky wants to merge 2 commits into
Closed
viktor-svirsky wants to merge 2 commits into
viktor-svirsky wants to merge 2 commits into
Conversation
Model.swift isn't in TetherCore and needs UIKit, so the logic that starts and stops the server with the hotspot had no unit test. It now lives in HotspotSession, Foundation only, which takes the saved devices, the server, the keep-alive sound, the hotspot lookup and the clock as inputs. WireGuardServer and KeepAlive conform to two small protocols for that. Model keeps the timers, the scene observers and the demo hooks, and forwards the rest. The session announces each change before it happens, as @published does, so the screen redraws as before, and a demo launch can still set the state the UI tests expect. Interfaces moves along, with the hotspot filter split from getifaddrs so it can be tested on its own.
Table tests with a fake server, sound, hotspot and clock: the server following the hotspot on, off and to a new address, locked keys then unlocked, a start that fails and is tried again each round, a start error going with the hotspot, the setup problem showing first, the restart when the server refuses a device list, the 10-minute wait on and off screen, claiming the ready device in the background, the speeds, and the hotspot address filter. Fixes #14
There was a problem hiding this comment.
🟢 Approval recommended
The hotspot lifecycle extraction has no active review issues.
No open issues 🎉
What changed in this PR
Extracts the hotspot lifecycle from Model into a Foundation-only HotspotSession, making the logic testable through TetherCore and addressing #14 while preserving the existing UI-facing API.
Changes:
- Moves lifecycle decisions into a session with injected server, keep-alive sound, hotspot lookup, and clock.
- Keeps timers, scene observers, demo hooks, and SwiftUI notifications in
Model. - Adds 21 tests covering hotspot transitions, retries, device claiming, keep-alive timing, speeds, notifications, and address filtering.
| File | Description |
|---|---|
| Tests/HotspotSessionTests.swift | Adds lifecycle tests using fake dependencies and a controlled clock. |
| Sources/Model.swift | Delegates lifecycle behavior to the session while retaining app integration. |
| Sources/HotspotSession.swift | Introduces the testable lifecycle, dependency protocols, and extracted interface filter. |
| Package.swift | Includes HotspotSession.swift in TetherCore. |
Review effort: Balanced
Owner
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The hotspot lifecycle moves out of Model into HotspotSession, a Foundation-only type in TetherCore, so
swift testcovers it. It takes the saved devices, the server, the keep-alive sound, the hotspot lookup and the clock as inputs. WireGuardServer conforms to a small WireGuardServing protocol, KeepAlive to KeepAliveSound.Model stays what SwiftUI observes. It keeps the watcher, the sampler, the scene observers and the demo hooks, and forwards the rest. The session calls
willChangebefore each change it publishes, the way@Publisheddoes, and Model sendsobjectWillChangefrom it. So the screen redraws as before, and a demo launch can still setrunningand the rest directly.Interfaces moves along, with the hotspot filter split from getifaddrs so it has its own test.
This is a refactor: no behaviour change, and the existing unit and UI tests are unchanged. The Phase and WireGuardProblem enums from the issue are left out: the views and Shortcuts read
runningand the problem text, so the enums would only add a mapping back to the same strings.New tests (21, in Tests/HotspotSessionTests.swift), most of them tables of watcher rounds: the server following the hotspot on, off and to a new address, locked keys then unlocked, a start that fails and is tried again each round, a start error going with the hotspot, the setup problem showing first, a problem logged once, the restart when the server refuses a device list (and a restart that fails), the 10-minute wait on and off screen and after opening Tether, claiming the ready device in the background and on screen, what the Shortcuts actions read, the speeds, each change announced before it happens, and the hotspot address filter.
Tested:
scripts/build-wireguard.sh && swift test: 94 tests, 0 failures, 6 Keychain tests skipped as before. The first commit alone: 73, 0 failures.Fixes #14