chore: initial ui wiring, swiftlint
Signed-off-by: Alan Brault <alan.brault@visus.io>
This commit is contained in:
+9
-3
@@ -51,7 +51,9 @@ struct OpenMeteoApiClient: WeatherApiClient {
|
||||
}
|
||||
|
||||
func request(latitude: Double, longitude: Double) async throws -> WeatherApiResponseContract? {
|
||||
var components = URLComponents(url: Self.baseURL, resolvingAgainstBaseURL: false)!
|
||||
guard var components = URLComponents(url: Self.baseURL, resolvingAgainstBaseURL: false) else {
|
||||
throw WeatherApiClientError.invalidURL
|
||||
}
|
||||
components.queryItems = [
|
||||
URLQueryItem(name: "latitude", value: String(latitude)),
|
||||
URLQueryItem(name: "longitude", value: String(longitude)),
|
||||
@@ -62,13 +64,17 @@ struct OpenMeteoApiClient: WeatherApiClient {
|
||||
URLQueryItem(name: "precipitation_unit", value: precipitationUnit)
|
||||
]
|
||||
|
||||
let (data, response) = try await session.data(from: components.url!)
|
||||
guard let url = components.url else {
|
||||
throw WeatherApiClientError.invalidURL
|
||||
}
|
||||
|
||||
let (data, response) = try await session.data(from: url)
|
||||
|
||||
guard let httpResponse = response as? HTTPURLResponse,
|
||||
(200...299).contains(httpResponse.statusCode) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
return try decoder.decode(WeatherApiResponseContract.self, from: data)
|
||||
} catch let error as DecodingError {
|
||||
|
||||
+1
@@ -3,5 +3,6 @@ protocol WeatherApiClient: Sendable {
|
||||
}
|
||||
|
||||
enum WeatherApiClientError: Error {
|
||||
case invalidURL
|
||||
case decodingFailed(DecodingError)
|
||||
}
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public actor DefaultForecastRepository: ForecastRepository {
|
||||
let cutoff = Date().addingTimeInterval(-Self.cacheDuration)
|
||||
|
||||
return records
|
||||
.max(by: { $0.fetchedAt < $1.fetchedAt })
|
||||
.max { $0.fetchedAt < $1.fetchedAt }
|
||||
.flatMap { $0.fetchedAt >= cutoff ? $0 : nil }
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import TempestasInfrastructure
|
||||
import Testing
|
||||
|
||||
@Suite struct OpenMeteoDateDecodingTests {
|
||||
private static let json = """
|
||||
@@ -27,7 +27,7 @@ import Testing
|
||||
"""
|
||||
|
||||
@Test func decodesTruncatedIso8601SunriseInRequestedTimeZone() throws {
|
||||
let timeZone = TimeZone(identifier: "Asia/Tokyo")!
|
||||
let timeZone = try #require(TimeZone(identifier: "Asia/Tokyo"))
|
||||
let decoder = OpenMeteoDateDecoding.decoder(timeZone: timeZone)
|
||||
let contract = try decoder.decode(WeatherApiResponseContract.self, from: Data(Self.json.utf8))
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import Testing
|
||||
@testable import TempestasInfrastructure
|
||||
import Testing
|
||||
|
||||
@Test func example() async throws {
|
||||
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
|
||||
|
||||
+4
-3
@@ -1,7 +1,7 @@
|
||||
import Foundation
|
||||
import SwiftData
|
||||
import Testing
|
||||
@testable import TempestasInfrastructure
|
||||
import Testing
|
||||
|
||||
@Suite struct WeatherResponseRecordMapperTests {
|
||||
private static let json = """
|
||||
@@ -28,7 +28,8 @@ import Testing
|
||||
"""
|
||||
|
||||
private func makeContract() throws -> WeatherApiResponseContract {
|
||||
let decoder = OpenMeteoDateDecoding.decoder(timeZone: TimeZone(identifier: "America/Toronto")!)
|
||||
let timeZone = try #require(TimeZone(identifier: "America/Toronto"))
|
||||
let decoder = OpenMeteoDateDecoding.decoder(timeZone: timeZone)
|
||||
return try decoder.decode(WeatherApiResponseContract.self, from: Data(Self.json.utf8))
|
||||
}
|
||||
|
||||
@@ -57,7 +58,7 @@ import Testing
|
||||
#expect(fetched.count == 1)
|
||||
#expect(fetched.first?.dailyForecasts.count == 2)
|
||||
|
||||
let firstDay = fetched.first?.dailyForecasts.sorted { $0.day < $1.day }.first
|
||||
let firstDay = fetched.first?.dailyForecasts.min { $0.day < $1.day }
|
||||
#expect(firstDay?.year == 2026)
|
||||
#expect(firstDay?.month == 8)
|
||||
#expect(firstDay?.day == 5)
|
||||
|
||||
Reference in New Issue
Block a user