Files
Cable/CableTests/ComponentLibraryItemTests.swift
Stefan Lange-Hegermann 8b30fabaa2 Route all affiliate links through voltplan.app
Replace client-side Amazon affiliate resolution with server-side
redirects via voltplan.app/{componentId} and voltplan.app/search?q=.
Remove AmazonAffiliate, affiliate link fetching, and per-model
affiliate fields in favor of a single componentID.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-22 10:39:46 +02:00

144 lines
4.4 KiB
Swift

import Foundation
import Testing
@testable import Cable
struct ComponentLibraryItemTests {
@Test func localizedNameUsesExactLocaleMatch() async throws {
let item = ComponentLibraryItem(
id: "component-1",
name: "Anchor Winch",
translations: ["de_DE": "Ankerwinde"],
voltageIn: nil,
voltageOut: nil,
watt: nil,
dutyCyclePercent: nil,
defaultUtilizationFactorPercent: nil,
iconURL: nil,
)
let german = Foundation.Locale(identifier: "de_DE")
#expect(item.localizedName(for: german) == "Ankerwinde")
}
@Test func localizedNameFallsBackToBaseName() async throws {
let item = ComponentLibraryItem(
id: "component-2",
name: "Anchor Winch",
translations: [:],
voltageIn: nil,
voltageOut: nil,
watt: nil,
dutyCyclePercent: nil,
defaultUtilizationFactorPercent: nil,
iconURL: nil,
)
let french = Foundation.Locale(identifier: "fr_FR")
#expect(item.localizedName(for: french) == "Anchor Winch")
}
@Test func localizedNameDoesNotFallbackToSecondaryLanguages() async throws {
let item = ComponentLibraryItem(
id: "component-5",
name: "Anchor Winch",
translations: [
"es_ES": "Molinete",
"de_DE": "Ankerwinde"
],
voltageIn: nil,
voltageOut: nil,
watt: nil,
dutyCyclePercent: nil,
defaultUtilizationFactorPercent: nil,
iconURL: nil,
)
let languages = ["fr-FR", "de-DE", "es-ES"]
#expect(item.localizedName(usingPreferredLanguages: languages) == nil)
}
@Test func localizedNameUsesLanguageOnlyMatch() async throws {
let item = ComponentLibraryItem(
id: "component-3",
name: "Anchor Winch",
translations: ["es": "Molinete"],
voltageIn: nil,
voltageOut: nil,
watt: nil,
dutyCyclePercent: nil,
defaultUtilizationFactorPercent: nil,
iconURL: nil,
)
let spanishMexico = Foundation.Locale(identifier: "es_MX")
#expect(item.localizedName(for: spanishMexico) == "Molinete")
}
@Test func localizedNameFallsBackToMatchingLanguageFromRegionalEntry() async throws {
let item = ComponentLibraryItem(
id: "component-6",
name: "Anchor Winch",
translations: ["de_DE": "Ankerwinde"],
voltageIn: nil,
voltageOut: nil,
watt: nil,
dutyCyclePercent: nil,
defaultUtilizationFactorPercent: nil,
iconURL: nil,
)
let germanSwitzerland = Foundation.Locale(identifier: "de_CH")
#expect(item.localizedName(for: germanSwitzerland) == "Ankerwinde")
}
@Test func localizedNameHandlesHyphenatedKeys() async throws {
let item = ComponentLibraryItem(
id: "component-4",
name: "Anchor Winch",
translations: ["fr-FR": "Guindeau"],
voltageIn: nil,
voltageOut: nil,
watt: nil,
dutyCyclePercent: nil,
defaultUtilizationFactorPercent: nil,
iconURL: nil,
)
let french = Foundation.Locale(identifier: "fr_FR")
#expect(item.localizedName(for: french) == "Guindeau")
}
@Test func normalizedDutyCycleTreatsZeroAsFullUsage() async throws {
let item = ComponentLibraryItem(
id: "component-7",
name: "Compressor",
translations: [:],
voltageIn: nil,
voltageOut: nil,
watt: nil,
dutyCyclePercent: 0,
defaultUtilizationFactorPercent: nil,
iconURL: nil,
)
#expect(item.normalizedDutyCyclePercent == 100)
}
@Test func defaultDailyUsageHoursConvertsPercentToHours() async throws {
let item = ComponentLibraryItem(
id: "component-8",
name: "Heater",
translations: [:],
voltageIn: nil,
voltageOut: nil,
watt: nil,
dutyCyclePercent: nil,
defaultUtilizationFactorPercent: 50,
iconURL: nil,
)
#expect(item.defaultDailyUsageHours == 12)
}
}