-
-
Notifications
You must be signed in to change notification settings - Fork 314
Expand file tree
/
Copy pathMockWeatherAPIClient.swift
More file actions
44 lines (36 loc) · 1.66 KB
/
Copy pathMockWeatherAPIClient.swift
File metadata and controls
44 lines (36 loc) · 1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import Foundation
struct MockWeatherAPIClient: WeatherAPIClient, Sendable {
private let fixtures: MockWeatherDTOFixtures
init(fixtures: MockWeatherDTOFixtures = MockWeatherDTOFixtures()) {
self.fixtures = fixtures
}
func defaultLocations() async throws -> [WeatherLocationDTO] {
fixtures.locations
}
func weather(for locationID: WeatherLocation.ID) async throws -> WeatherReportDTO {
guard let scenario = fixtures.scenarioByLocationID[locationID] else {
throw MockWeatherAPIClientError.unknownLocation
}
return WeatherReportDTO(
current: CurrentWeatherDTO.mock(for: scenario),
hourly: HourlyForecastDTO.mockForecast(for: scenario),
daily: DailyForecastDTO.mockForecast(for: scenario),
precipitationDetailCurrent: CurrentWeatherDTO.mock(for: .rainy)
)
}
func searchLocations(matching query: String) async throws -> [WeatherLocationDTO] {
let trimmed = query.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { return [] }
let needle = trimmed.localizedLowercase
var seenLocationIDs = Set<WeatherLocation.ID>()
return (fixtures.locations + fixtures.searchPool).filter { location in
guard seenLocationIDs.insert(location.id).inserted else { return false }
return location.name.localizedLowercase.contains(needle)
|| location.subtitle.localizedLowercase.contains(needle)
|| (location.country?.localizedLowercase.contains(needle) ?? false)
}
}
}
private enum MockWeatherAPIClientError: Error {
case unknownLocation
}