mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Set map tiler URL from well known if available (#5633)
This commit is contained in:
@@ -350,7 +350,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
accountProvisioningHost: appSettings.accountProvisioningHost,
|
||||
bugReportApplicationID: appSettings.bugReportApplicationID,
|
||||
analyticsTermsURL: appSettings.analyticsTermsURL,
|
||||
mapTilerConfiguration: appSettings.mapTilerConfiguration)
|
||||
mapTilerConfiguration: AppSettings.bundledMapTilerConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -397,7 +397,7 @@ struct LocationSharingScreenViewModelTests {
|
||||
let appSettings = AppSettings.volatile()
|
||||
|
||||
viewModel = LocationSharingScreenViewModel(interactionMode: .viewLive(sender: nil, initialLiveLocationShare: nil),
|
||||
mapURLBuilder: appSettings.mapTilerConfiguration,
|
||||
mapURLBuilder: appSettings.mapTilerSettings.publisher.value,
|
||||
roomProxy: roomProxyMock,
|
||||
timelineController: MockTimelineController(timelineProxy: TimelineProxyMock(.init())),
|
||||
liveLocationManager: LiveLocationManagerMock(.init()),
|
||||
@@ -432,7 +432,7 @@ struct LocationSharingScreenViewModelTests {
|
||||
let appSettings = AppSettings.volatile()
|
||||
timelineProxy = TimelineProxyMock(.init())
|
||||
viewModel = LocationSharingScreenViewModel(interactionMode: .picker(shouldShowLiveLocationOption: true),
|
||||
mapURLBuilder: appSettings.mapTilerConfiguration,
|
||||
mapURLBuilder: appSettings.mapTilerSettings.publisher.value,
|
||||
roomProxy: JoinedRoomProxyMock(.init(members: members)),
|
||||
timelineController: MockTimelineController(timelineProxy: timelineProxy),
|
||||
liveLocationManager: LiveLocationManagerMock(liveLocationManagerConfiguration),
|
||||
@@ -447,7 +447,7 @@ struct LocationSharingScreenViewModelTests {
|
||||
let appSettings = AppSettings.volatile()
|
||||
timelineProxy = TimelineProxyMock(.init())
|
||||
viewModel = LocationSharingScreenViewModel(interactionMode: .picker(shouldShowLiveLocationOption: true),
|
||||
mapURLBuilder: appSettings.mapTilerConfiguration,
|
||||
mapURLBuilder: appSettings.mapTilerSettings.publisher.value,
|
||||
roomProxy: JoinedRoomProxyMock(.init(members: members)),
|
||||
timelineController: MockTimelineController(timelineProxy: timelineProxy),
|
||||
liveLocationManager: liveLocationManagerMock,
|
||||
@@ -469,7 +469,7 @@ struct LocationSharingScreenViewModelTests {
|
||||
roomProxyMock.makeLiveLocationServiceReturnValue = liveLocationServiceMock
|
||||
|
||||
viewModel = LocationSharingScreenViewModel(interactionMode: .viewLive(sender: sender, initialLiveLocationShare: initialShare),
|
||||
mapURLBuilder: appSettings.mapTilerConfiguration,
|
||||
mapURLBuilder: appSettings.mapTilerSettings.publisher.value,
|
||||
roomProxy: roomProxyMock,
|
||||
timelineController: MockTimelineController(timelineProxy: TimelineProxyMock(.init())),
|
||||
liveLocationManager: LiveLocationManagerMock(.init()),
|
||||
|
||||
@@ -19,10 +19,10 @@ struct MapTilerURLBuilderTests {
|
||||
var builder: MapTilerURLBuilderProtocol
|
||||
|
||||
init() {
|
||||
builder = MapTilerConfiguration(baseURL: Self.baseURL,
|
||||
apiKey: Self.apiKey,
|
||||
lightStyleID: Self.lightStyleID,
|
||||
darkStyleID: Self.darkStyleID)
|
||||
builder = MapTilerSettings.configuration(.init(baseURL: Self.baseURL,
|
||||
apiKey: Self.apiKey,
|
||||
lightStyleID: Self.lightStyleID,
|
||||
darkStyleID: Self.darkStyleID))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -58,10 +58,10 @@ struct MapTilerURLBuilderTests {
|
||||
|
||||
@Test
|
||||
mutating func nilAPIKey() {
|
||||
let configuration = MapTilerConfiguration(baseURL: Self.baseURL,
|
||||
apiKey: nil,
|
||||
lightStyleID: Self.lightStyleID,
|
||||
darkStyleID: Self.darkStyleID)
|
||||
let configuration = MapTilerSettings.configuration(.init(baseURL: Self.baseURL,
|
||||
apiKey: nil,
|
||||
lightStyleID: Self.lightStyleID,
|
||||
darkStyleID: Self.darkStyleID))
|
||||
#expect(!configuration.isEnabled)
|
||||
|
||||
builder = configuration
|
||||
@@ -76,4 +76,66 @@ struct MapTilerURLBuilderTests {
|
||||
let dynamicMapURL = builder.interactiveMapURL(for: .light)
|
||||
#expect(dynamicMapURL == nil)
|
||||
}
|
||||
|
||||
// MARK: - Override URL
|
||||
|
||||
@Test
|
||||
mutating func overrideInteractiveMap() {
|
||||
let overrideURL: URL = "https://maps.example.com/maps/streets-v2/style.json?key=server_key"
|
||||
let configuration = MapTilerSettings.url(overrideURL)
|
||||
#expect(configuration.isEnabled)
|
||||
|
||||
builder = configuration
|
||||
|
||||
// The override is returned as-is for the interactive map, ignoring light/dark.
|
||||
#expect(builder.interactiveMapURL(for: .light) == overrideURL)
|
||||
#expect(builder.interactiveMapURL(for: .dark) == overrideURL)
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func overrideStaticMapPreservesQueryItems() {
|
||||
// The override includes an embedded API key as a query item — it must be preserved
|
||||
// when deriving the static map URL.
|
||||
let overrideURL: URL = "https://maps.example.com/maps/streets-v2/style.json?key=server_key"
|
||||
builder = MapTilerSettings.url(overrideURL)
|
||||
|
||||
let url = builder.staticMapTileImageURL(for: .light,
|
||||
coordinates: .init(latitude: 1, longitude: 2),
|
||||
zoomLevel: 5,
|
||||
size: .init(width: 300, height: 200),
|
||||
attribution: .topLeft)
|
||||
|
||||
let expectedURL: URL = "https://maps.example.com/maps/streets-v2/static/2.000000,1.000000,5.000000/300x200@2x.png?key=server_key&attribution=topleft"
|
||||
#expect(url == expectedURL)
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func overrideStaticMapWithoutQueryItems() {
|
||||
// An override without a key (e.g. self-hosted server proxying the key) still works.
|
||||
let overrideURL: URL = "https://maps.example.com/maps/streets-v2/style.json"
|
||||
builder = MapTilerSettings.url(overrideURL)
|
||||
|
||||
let url = builder.staticMapTileImageURL(for: .dark,
|
||||
coordinates: .init(latitude: 1, longitude: 2),
|
||||
zoomLevel: 5,
|
||||
size: .init(width: 300, height: 200),
|
||||
attribution: .hidden)
|
||||
|
||||
let expectedURL: URL = "https://maps.example.com/maps/streets-v2/static/2.000000,1.000000,5.000000/300x200@2x.png?attribution=false"
|
||||
#expect(url == expectedURL)
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func overrideMissingStyleJSONFails() {
|
||||
// If the override URL doesn't end in /style.json we can't derive a static URL.
|
||||
let overrideURL: URL = "https://maps.example.com/maps/streets-v2/"
|
||||
builder = MapTilerSettings.url(overrideURL)
|
||||
|
||||
let url = builder.staticMapTileImageURL(for: .light,
|
||||
coordinates: .init(latitude: 1, longitude: 2),
|
||||
zoomLevel: 5,
|
||||
size: .init(width: 300, height: 200),
|
||||
attribution: .topLeft)
|
||||
#expect(url == nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
@testable import ElementX
|
||||
import Foundation
|
||||
import MatrixRustSDKMocks
|
||||
import Testing
|
||||
|
||||
/// Exercises ``ClientProtocol.updateMapTilerSettings(in:)``. The SDK is now the
|
||||
/// source of truth for parsing the matrix client well-known and exposing the
|
||||
/// `tile_server` field as a typed ``TileServerInfo``; these tests just check
|
||||
/// that we forward it into ``AppSettings`` correctly.
|
||||
struct MatrixClientWellKnownTests {
|
||||
private static let mapStyleURLString = "https://maps.example.com/maps/streets-v2/style.json?key=server"
|
||||
|
||||
@Test
|
||||
func mapStyleURLIsApplied() async throws {
|
||||
let appSettings = AppSettings.volatile()
|
||||
let client = ClientSDKMock(.init(tileServerMapStyleURL: Self.mapStyleURLString))
|
||||
|
||||
await client.updateMapTilerSettings(in: appSettings)
|
||||
|
||||
#expect(appSettings.mapTilerSettings.isRemotelyConfigured)
|
||||
let expectedURL = try #require(URL(string: Self.mapStyleURLString))
|
||||
#expect(appSettings.mapTilerSettings.publisher.value == .url(expectedURL))
|
||||
}
|
||||
|
||||
@Test
|
||||
func missingTileServerClearsExistingOverride() async throws {
|
||||
let appSettings = AppSettings.volatile()
|
||||
let expectedURL = try #require(URL(string: Self.mapStyleURLString))
|
||||
appSettings.mapTilerSettings.applyRemoteValue(.url(expectedURL))
|
||||
#expect(appSettings.mapTilerSettings.isRemotelyConfigured)
|
||||
|
||||
// The SDK returns nil when the homeserver hasn't advertised a tile server.
|
||||
let client = ClientSDKMock(.init())
|
||||
await client.updateMapTilerSettings(in: appSettings)
|
||||
|
||||
#expect(!appSettings.mapTilerSettings.isRemotelyConfigured)
|
||||
}
|
||||
|
||||
@Test
|
||||
func invalidMapStyleURLClearsOverride() async throws {
|
||||
let appSettings = AppSettings.volatile()
|
||||
let expectedURL = try #require(URL(string: Self.mapStyleURLString))
|
||||
appSettings.mapTilerSettings.applyRemoteValue(.url(expectedURL))
|
||||
|
||||
// The SDK returns the string verbatim — if it isn't a valid URL we just
|
||||
// drop any previous override rather than crash.
|
||||
let client = ClientSDKMock(.init(tileServerMapStyleURL: ""))
|
||||
await client.updateMapTilerSettings(in: appSettings)
|
||||
|
||||
#expect(!appSettings.mapTilerSettings.isRemotelyConfigured)
|
||||
}
|
||||
|
||||
@Test
|
||||
func mapTilerSettingsResolveToOverride() async {
|
||||
let appSettings = AppSettings.volatile()
|
||||
let client = ClientSDKMock(.init(tileServerMapStyleURL: Self.mapStyleURLString))
|
||||
|
||||
await client.updateMapTilerSettings(in: appSettings)
|
||||
|
||||
switch appSettings.mapTilerSettings.publisher.value {
|
||||
case .url(let url):
|
||||
#expect(url.absoluteString == Self.mapStyleURLString)
|
||||
case .configuration:
|
||||
Issue.record("Expected the resolved settings to be .url")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,7 +339,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
accountProvisioningHost: appSettings.accountProvisioningHost,
|
||||
bugReportApplicationID: appSettings.bugReportApplicationID,
|
||||
analyticsTermsURL: appSettings.analyticsTermsURL,
|
||||
mapTilerConfiguration: appSettings.mapTilerConfiguration)
|
||||
mapTilerConfiguration: AppSettings.bundledMapTilerConfiguration)
|
||||
mode = .picker(appSettings.accountProviders)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user