Skip to content

Commit c707204

Browse files
committed
Add tests
1 parent 46b9a6f commit c707204

File tree

8 files changed

+162
-5
lines changed

8 files changed

+162
-5
lines changed

HomeAssistant.xcodeproj/project.pbxproj

+30-2
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,8 @@
584584
4214388C2CF5F1D700E2D44D /* ServerFixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42F5CABB2B10AE1A00409816 /* ServerFixture.swift */; };
585585
4214388D2CF5F1D700E2D44D /* ServerFixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42F5CABB2B10AE1A00409816 /* ServerFixture.swift */; };
586586
421960702CA2AE1600F7134E /* WidgetAssistViewTintedWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4219606F2CA2AE1600F7134E /* WidgetAssistViewTintedWrapper.swift */; };
587+
42196ACD2DA5A47300BD501E /* MockBonjour.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42196ACC2DA5A47300BD501E /* MockBonjour.swift */; };
588+
42196ACE2DA5A49600BD501E /* Bonjour.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B25BCC2130CAB400678C2C /* Bonjour.swift */; };
587589
421B1C182BD6524E001ED18C /* WidgetBuilderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421B1C172BD6524E001ED18C /* WidgetBuilderViewModel.swift */; };
588590
421B1C1D2BD65C04001ED18C /* View+ConditionalModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421B1C1B2BD65BFA001ED18C /* View+ConditionalModifier.swift */; };
589591
4221ED352D009EF700BAE3EB /* AppDatabaseUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4221ED332D009BD000BAE3EB /* AppDatabaseUpdater.swift */; };
@@ -827,6 +829,8 @@
827829
42C131D02D66084C00AF48E6 /* PillView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C131CF2D66084C00AF48E6 /* PillView.swift */; };
828830
42C3737F2BC415AC00898990 /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C3737E2BC415AC00898990 /* UIViewController+Extensions.swift */; };
829831
42C373B22BC5382900898990 /* HostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C373B12BC5382900898990 /* HostingController.swift */; };
832+
42C65A562DA5A41500E14E87 /* OnboardingNavigationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C65A542DA5A41500E14E87 /* OnboardingNavigationTests.swift */; };
833+
42C65A572DA5A41500E14E87 /* OnboardingServersListViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C65A522DA5A41500E14E87 /* OnboardingServersListViewModelTests.swift */; };
830834
42CE8FA72B45D1E900C707F9 /* CoreStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42CE8FA52B45D1E900C707F9 /* CoreStrings.swift */; };
831835
42CE8FA82B45D1E900C707F9 /* CoreStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42CE8FA52B45D1E900C707F9 /* CoreStrings.swift */; };
832836
42CE8FA92B45D1E900C707F9 /* FrontendStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42CE8FA62B45D1E900C707F9 /* FrontendStrings.swift */; };
@@ -1089,7 +1093,6 @@
10891093
B60616BB1D1F117800249C11 /* US-EN-Daisy-Water-Heater-Leak.wav in Resources */ = {isa = PBXBuildFile; fileRef = B60615BA1D1F117700249C11 /* US-EN-Daisy-Water-Heater-Leak.wav */; };
10901094
B613936924F728F8002B8C5D /* InputOutputDeviceSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B613936824F728F8002B8C5D /* InputOutputDeviceSensor.swift */; };
10911095
B613936A24F728F8002B8C5D /* InputOutputDeviceSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B613936824F728F8002B8C5D /* InputOutputDeviceSensor.swift */; };
1092-
B616B299227ED68E00828165 /* Bonjour.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B25BCC2130CAB400678C2C /* Bonjour.swift */; };
10931096
B6221F6522266F9F00502A30 /* WebhookRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6221F6122266C4000502A30 /* WebhookRequest.swift */; };
10941097
B6221F6622266FA000502A30 /* WebhookRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6221F6122266C4000502A30 /* WebhookRequest.swift */; };
10951098
B626AAF11D8F972800A0D225 /* SettingsDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B626AAF01D8F972800A0D225 /* SettingsDetailViewController.swift */; };
@@ -1991,6 +1994,7 @@
19911994
421155222D354F3F00A71630 /* AppIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIcon.swift; sourceTree = "<group>"; };
19921995
421155242D355C6700A71630 /* WidgetBuilderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetBuilderView.swift; sourceTree = "<group>"; };
19931996
4219606F2CA2AE1600F7134E /* WidgetAssistViewTintedWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetAssistViewTintedWrapper.swift; sourceTree = "<group>"; };
1997+
42196ACC2DA5A47300BD501E /* MockBonjour.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBonjour.swift; sourceTree = "<group>"; };
19941998
421B1C172BD6524E001ED18C /* WidgetBuilderViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetBuilderViewModel.swift; sourceTree = "<group>"; };
19951999
421B1C1B2BD65BFA001ED18C /* View+ConditionalModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+ConditionalModifier.swift"; sourceTree = "<group>"; };
19962000
4221ED332D009BD000BAE3EB /* AppDatabaseUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDatabaseUpdater.swift; sourceTree = "<group>"; };
@@ -2231,6 +2235,8 @@
22312235
42C3737E2BC415AC00898990 /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extensions.swift"; sourceTree = "<group>"; };
22322236
42C373AF2BC536AA00898990 /* WatchApp-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WatchApp-Bridging-Header.h"; sourceTree = "<group>"; };
22332237
42C373B12BC5382900898990 /* HostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostingController.swift; sourceTree = "<group>"; };
2238+
42C65A522DA5A41500E14E87 /* OnboardingServersListViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingServersListViewModelTests.swift; sourceTree = "<group>"; };
2239+
42C65A542DA5A41500E14E87 /* OnboardingNavigationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingNavigationTests.swift; sourceTree = "<group>"; };
22342240
42CA28AD2B101D4D0093B31A /* HACornerRadius.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HACornerRadius.swift; sourceTree = "<group>"; };
22352241
42CA28AF2B101D6B0093B31A /* CardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardView.swift; sourceTree = "<group>"; };
22362242
42CA28B52B1022680093B31A /* HAButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HAButton.swift; sourceTree = "<group>"; };
@@ -4469,6 +4475,24 @@
44694475
path = Home;
44704476
sourceTree = "<group>";
44714477
};
4478+
42C65A532DA5A41500E14E87 /* ServersList */ = {
4479+
isa = PBXGroup;
4480+
children = (
4481+
42C65A522DA5A41500E14E87 /* OnboardingServersListViewModelTests.swift */,
4482+
);
4483+
path = ServersList;
4484+
sourceTree = "<group>";
4485+
};
4486+
42C65A552DA5A41500E14E87 /* Onboarding */ = {
4487+
isa = PBXGroup;
4488+
children = (
4489+
42196ACC2DA5A47300BD501E /* MockBonjour.swift */,
4490+
42C65A532DA5A41500E14E87 /* ServersList */,
4491+
42C65A542DA5A41500E14E87 /* OnboardingNavigationTests.swift */,
4492+
);
4493+
path = Onboarding;
4494+
sourceTree = "<group>";
4495+
};
44724496
42CA28AC2B101D320093B31A /* DesignSystem */ = {
44734497
isa = PBXGroup;
44744498
children = (
@@ -5086,6 +5110,7 @@
50865110
B657A8FF1CA646EB00121384 /* App */ = {
50875111
isa = PBXGroup;
50885112
children = (
5113+
42C65A552DA5A41500E14E87 /* Onboarding */,
50895114
42E3B8BB2D8ACDC100F5D084 /* Extensions */,
50905115
46F103242D7214F7002BC586 /* ClientEvents */,
50915116
422E626A2CDCF00000987BD0 /* Area */,
@@ -7335,7 +7360,6 @@
73357360
B68EDD05215F12C900DD6B28 /* NotificationActionConfigurator.swift in Sources */,
73367361
423B5E0D2D677BB90000CB95 /* WidgetContentMargin.swift in Sources */,
73377362
42462E782DA5421D00ECC8A7 /* CornerRadiusSizes.swift in Sources */,
7338-
B616B299227ED68E00828165 /* Bonjour.swift in Sources */,
73397363
420E2AE62C474710004921D8 /* WidgetBasicButtonView.swift in Sources */,
73407364
11A48D7F24CA7E820021BDD9 /* Action+Observation.swift in Sources */,
73417365
11195F6B267EFB1F003DF674 /* NotificationManagerLocalPushInterface.swift in Sources */,
@@ -7604,6 +7628,8 @@
76047628
11ED43A027279AFA00B5FD45 /* OnboardingAuthLoginImpl.test.swift in Sources */,
76057629
11EFD3BE27253504000AF78B /* OnboardingAuthStepConnectivity.test.swift in Sources */,
76067630
42E3B8C02D8ACE0400F5D084 /* OptionalsDefaultTests.swift in Sources */,
7631+
42C65A562DA5A41500E14E87 /* OnboardingNavigationTests.swift in Sources */,
7632+
42C65A572DA5A41500E14E87 /* OnboardingServersListViewModelTests.swift in Sources */,
76077633
42FCD0032B9B1CB70057783F /* ThreadCredentialsSharingViewModel.test.swift in Sources */,
76087634
42FCD0042B9B1CB70057783F /* ThreadCredentialsSharing.test.swift in Sources */,
76097635
4272B9A92CDCE15C008CC262 /* CarPlayConfig.test.swift in Sources */,
@@ -7617,6 +7643,7 @@
76177643
42A818E72BBEAAE80083D045 /* MockAssistService.swift in Sources */,
76187644
420E64BA2D676A5800A31E86 /* WidgetsSnapshot.test.swift in Sources */,
76197645
11EFD3C327264306000AF78B /* UIAlertAction+Additions.swift in Sources */,
7646+
42196ACD2DA5A47300BD501E /* MockBonjour.swift in Sources */,
76207647
11A71C8F24A5946B00D9565F /* FakeCLLocationManager.swift in Sources */,
76217648
11EF62DA24C3687D00BABB64 /* ZoneManagerRegionFilter.test.swift in Sources */,
76227649
11A71C8724A5074E00D9565F /* ZoneManager.test.swift in Sources */,
@@ -8006,6 +8033,7 @@
80068033
11C4629624B19FC700031902 /* URLSessionTask+WebhookPersisted.swift in Sources */,
80078034
11F2F25E25871D6000F61F7C /* NotificationAttachmentParserCamera.swift in Sources */,
80088035
11B63B0A2979A07000D908ED /* AssistIntentHandler.swift in Sources */,
8036+
42196ACE2DA5A49600BD501E /* Bonjour.swift in Sources */,
80098037
1133F59C25F1DA5D00AD776F /* CLLocation+Sanitize.swift in Sources */,
80108038
11AF4D1C249C8AA0006C74C0 /* BatterySensor.swift in Sources */,
80118039
D014EEA92128E192008EA6F5 /* ConnectionInfo.swift in Sources */,

Sources/App/Onboarding/API/Bonjour.swift

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import Foundation
2-
import Shared
32

43
public protocol BonjourObserver: AnyObject {
54
func bonjour(_ bonjour: Bonjour, didAdd instance: DiscoveredHomeAssistant)
65
func bonjour(_ bonjour: Bonjour, didRemoveInstanceWithName name: String)
76
}
87

9-
public class Bonjour: NSObject, NetServiceBrowserDelegate, NetServiceDelegate {
8+
public protocol BonjourProtocol {
9+
var observer: BonjourObserver? { get set }
10+
func start()
11+
func stop()
12+
}
13+
14+
public class Bonjour: NSObject, NetServiceBrowserDelegate, NetServiceDelegate, BonjourProtocol {
1015
public weak var observer: BonjourObserver?
1116

1217
private var browser: NetServiceBrowser

Sources/App/Onboarding/Screens/OnboardingServersList/OnboardingServersListViewModel.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ final class OnboardingServersListViewModel: ObservableObject {
2222
/// Indicator for manual input loading
2323
@Published var isLoading = false
2424

25-
private let discovery = Bonjour()
25+
private var discovery = Current.bonjour()
2626
private var cancellables = Set<AnyCancellable>()
2727

2828
init() {

Sources/Shared/Environment/Environment.swift

+6
Original file line numberDiff line numberDiff line change
@@ -437,4 +437,10 @@ public class AppEnvironment {
437437
public var userNotificationCenter: UNUserNotificationCenter {
438438
UNUserNotificationCenter.current()
439439
}
440+
441+
#if !os(watchOS)
442+
public var bonjour: () -> BonjourProtocol = {
443+
Bonjour()
444+
}
445+
#endif
440446
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Foundation
2+
import Shared
3+
4+
final class MockBonjour: BonjourProtocol {
5+
var observer: (any BonjourObserver)?
6+
7+
var startCalled = false
8+
var stopCalled = false
9+
10+
func start() {
11+
startCalled = true
12+
}
13+
14+
func stop() {
15+
stopCalled = true
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
@testable import HomeAssistant
2+
@testable import Shared
3+
import Testing
4+
5+
struct OnboardingNavigationTests {
6+
@Test func testOnboardingNavigationWhenNoServers() async throws {
7+
Current.servers = FakeServerManager(initial: 0)
8+
let result = OnboardingNavigation.requiredOnboardingStyle
9+
assert(result == .required(.full))
10+
}
11+
12+
@Test func testOnboardingNavigationWhenOneServers() async throws {
13+
Current.servers = FakeServerManager(initial: 1)
14+
let result = OnboardingNavigation.requiredOnboardingStyle
15+
assert(result == nil)
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
@testable import HomeAssistant
2+
@testable import Shared
3+
import Testing
4+
5+
@Suite(.serialized)
6+
struct OnboardingServersListViewModelTests {
7+
@Test func testInitAddsSelfAsObserver() async throws {
8+
let mockBonjour = MockBonjour()
9+
Current.bonjour = {
10+
mockBonjour
11+
}
12+
let sut = OnboardingServersListViewModel()
13+
assert(sut.discoveredInstances.isEmpty)
14+
assert((mockBonjour.observer as? OnboardingServersListViewModel) != nil)
15+
}
16+
17+
@Test func testStartDiscovery() async throws {
18+
let mockBonjour = MockBonjour()
19+
Current.bonjour = {
20+
mockBonjour
21+
}
22+
let sut = OnboardingServersListViewModel()
23+
24+
sut.startDiscovery()
25+
assert(sut.discoveredInstances.isEmpty)
26+
assert(mockBonjour.startCalled)
27+
}
28+
29+
@Test func testStopDiscovery() async throws {
30+
let mockBonjour = MockBonjour()
31+
Current.bonjour = {
32+
mockBonjour
33+
}
34+
let sut = OnboardingServersListViewModel()
35+
36+
sut.stopDiscovery()
37+
assert(mockBonjour.stopCalled)
38+
}
39+
40+
@Test func testSelectInstance() async throws {
41+
let mockBonjour = MockBonjour()
42+
Current.bonjour = {
43+
mockBonjour
44+
}
45+
let sut = OnboardingServersListViewModel()
46+
let instance = DiscoveredHomeAssistant(
47+
manualURL: URL(string: "http://192.168.0.1:8123")!,
48+
name: "Home"
49+
)
50+
let dummyController = await UIViewController()
51+
sut.selectInstance(instance, controller: dummyController)
52+
53+
assert(sut.currentlyInstanceLoading == instance)
54+
}
55+
56+
@Test func testResetFlow() async throws {
57+
let mockBonjour = MockBonjour()
58+
Current.bonjour = {
59+
mockBonjour
60+
}
61+
let sut = OnboardingServersListViewModel()
62+
63+
sut.resetFlow()
64+
assert(sut.currentlyInstanceLoading == nil)
65+
assert(sut.isLoading == false)
66+
}
67+
}

Tests/Mocks/MockBonjour.swift

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Foundation
2+
import Shared
3+
4+
final class MockBonjour: BonjourProtocol {
5+
var observer: (any BonjourObserver)?
6+
7+
var startCalled = false
8+
var stopCalled = false
9+
10+
func start() {
11+
startCalled = true
12+
}
13+
14+
func stop() {
15+
stopCalled = true
16+
}
17+
}

0 commit comments

Comments
 (0)