@@ -165,6 +165,64 @@ - (void)testInitMigratesRemovableMediaSyncStateKeys {
165165 }];
166166}
167167
168+ - (void )testSyncBaseURLRejectsNonLocalhostHTTP {
169+ SNTConfigurator* sut = [[SNTConfigurator alloc ] init ];
170+
171+ // HTTPS is always allowed.
172+ sut.configState [@" SyncBaseURL" ] = @" https://example.com/api" ;
173+ XCTAssertNotNil (sut.syncBaseURL );
174+ XCTAssertEqualObjects (sut.syncBaseURL .host , @" example.com" );
175+
176+ // HTTP to localhost is allowed.
177+ sut.configState [@" SyncBaseURL" ] = @" http://localhost:8080/api" ;
178+ XCTAssertNotNil (sut.syncBaseURL );
179+ XCTAssertEqualObjects (sut.syncBaseURL .host , @" localhost" );
180+
181+ // HTTP to 127.0.0.1 is allowed.
182+ sut.configState [@" SyncBaseURL" ] = @" http://127.0.0.1:8080/api" ;
183+ XCTAssertNotNil (sut.syncBaseURL );
184+ XCTAssertEqualObjects (sut.syncBaseURL .host , @" 127.0.0.1" );
185+
186+ // HTTP to ::1 is allowed.
187+ sut.configState [@" SyncBaseURL" ] = @" http://[::1]:8080/api" ;
188+ XCTAssertNotNil (sut.syncBaseURL );
189+ XCTAssertEqualObjects (sut.syncBaseURL .host , @" ::1" );
190+
191+ // HTTP to a non-localhost host is rejected.
192+ sut.configState [@" SyncBaseURL" ] = @" http://example.com/api" ;
193+ XCTAssertNil (sut.syncBaseURL );
194+
195+ sut.configState [@" SyncBaseURL" ] = @" http://10.0.0.1/api" ;
196+ XCTAssertNil (sut.syncBaseURL );
197+
198+ // Empty and missing values return nil.
199+ sut.configState [@" SyncBaseURL" ] = @" " ;
200+ XCTAssertNil (sut.syncBaseURL );
201+
202+ sut.configState [@" SyncBaseURL" ] = nil ;
203+ XCTAssertNil (sut.syncBaseURL );
204+ }
205+
206+ - (void )testSyncBaseURLConfigured {
207+ SNTConfigurator* sut = [[SNTConfigurator alloc ] init ];
208+
209+ // A value is configured, even if syncBaseURL rejects it.
210+ sut.configState [@" SyncBaseURL" ] = @" http://example.com/api" ;
211+ XCTAssertNil (sut.syncBaseURL );
212+ XCTAssertTrue (sut.syncBaseURLConfigured );
213+
214+ // A valid value is also reported as configured.
215+ sut.configState [@" SyncBaseURL" ] = @" https://example.com/api" ;
216+ XCTAssertTrue (sut.syncBaseURLConfigured );
217+
218+ // Empty and missing values are not configured.
219+ sut.configState [@" SyncBaseURL" ] = @" " ;
220+ XCTAssertFalse (sut.syncBaseURLConfigured );
221+
222+ sut.configState [@" SyncBaseURL" ] = nil ;
223+ XCTAssertFalse (sut.syncBaseURLConfigured );
224+ }
225+
168226- (void )testTelemetryFilterExpressions {
169227 SNTConfigurator* sut = [[SNTConfigurator alloc ] init ];
170228
0 commit comments