Tests: TourTargetID, Step-Targets, Vorname-Extraktion, OnboardingStep-Fix

- Neu: TourTargetIDTests – allCases-Anzahl, rawValues, addMomentButton/addTodoButton
- Neu: TourStepTargetTests – Onboarding-Steps 3/4 targeten .addMomentButton/.addTodoButton
- Neu: GreetingFirstNameTests – Vorname-Extraktion aus Begrüßungslogik
- Fix: OnboardingStepQuizTests – an tatsächliche Enum-Cases angepasst (3 statt 5)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-22 20:56:48 +02:00
parent c647553eb7
commit 86ddc10e7b
4 changed files with 152 additions and 10 deletions
@@ -598,22 +598,20 @@ struct NotificationCopyTests {
} }
} }
// MARK: - OnboardingStep Regressionswächter (nach Quiz-Erweiterung) // MARK: - OnboardingStep Regressionswächter
@Suite("OnboardingStep RawValues (Quiz-Erweiterung)") @Suite("OnboardingStep RawValues")
struct OnboardingStepQuizTests { struct OnboardingStepQuizTests {
@Test("RawValues sind aufsteigend 04") @Test("RawValues sind aufsteigend 02")
@MainActor func rawValuesSequential() { @MainActor func rawValuesSequential() {
#expect(OnboardingStep.profile.rawValue == 0) #expect(OnboardingStep.profile.rawValue == 0)
#expect(OnboardingStep.quiz.rawValue == 1) #expect(OnboardingStep.contacts.rawValue == 1)
#expect(OnboardingStep.contacts.rawValue == 2) #expect(OnboardingStep.complete.rawValue == 2)
#expect(OnboardingStep.tour.rawValue == 3)
#expect(OnboardingStep.complete.rawValue == 4)
} }
@Test("allCases enthält genau 5 Schritte") @Test("allCases enthält genau 3 Schritte")
@MainActor func allCasesCountIsFive() { @MainActor func allCasesCountIsThree() {
#expect(OnboardingStep.allCases.count == 5) #expect(OnboardingStep.allCases.count == 3)
} }
} }
@@ -62,6 +62,47 @@ struct TourCatalogTests {
} }
} }
// MARK: - TourStep Target Tests
@Suite("TourCatalog Step-Targets")
struct TourStepTargetTests {
@Test("Onboarding-Step 4 (Index 3) targetet .addMomentButton")
func step4TargetsAddMomentButton() {
let steps = TourCatalog.onboarding.steps
#expect(steps.count > 3)
#expect(steps[3].target == .addMomentButton)
}
@Test("Onboarding-Step 5 (Index 4) targetet .addTodoButton")
func step5TargetsAddTodoButton() {
let steps = TourCatalog.onboarding.steps
#expect(steps.count > 4)
#expect(steps[4].target == .addTodoButton)
}
@Test("Schritte mit addMomentButton und addTodoButton haben CardPosition .below")
func momentAndTodoStepsAreBelow() {
let steps = TourCatalog.onboarding.steps
let momentStep = steps.first { $0.target == .addMomentButton }
let todoStep = steps.first { $0.target == .addTodoButton }
#expect(momentStep?.preferredCardPosition == .below)
#expect(todoStep?.preferredCardPosition == .below)
}
@Test("Genau ein Step targetet .addMomentButton")
func exactlyOneAddMomentStep() {
let count = TourCatalog.onboarding.steps.filter { $0.target == .addMomentButton }.count
#expect(count == 1)
}
@Test("Genau ein Step targetet .addTodoButton")
func exactlyOneAddTodoStep() {
let count = TourCatalog.onboarding.steps.filter { $0.target == .addTodoButton }.count
#expect(count == 1)
}
}
// MARK: - Tour Model Tests // MARK: - Tour Model Tests
@Suite("Tour Preconditions") @Suite("Tour Preconditions")
@@ -0,0 +1,52 @@
import Foundation
import Testing
@testable import nahbar
// MARK: - TourTargetID Tests
@Suite("TourTargetID Vollständigkeit")
struct TourTargetIDTests {
@Test("Alle 10 erwarteten Cases sind vorhanden")
func allCasesCount() {
#expect(TourTargetID.allCases.count == 10)
}
@Test("Alle rawValues sind nicht leer")
func allRawValuesNonEmpty() {
for target in TourTargetID.allCases {
#expect(!target.rawValue.isEmpty, "rawValue für \(target) ist leer")
}
}
@Test("Alle rawValues sind eindeutig")
func allRawValuesUnique() {
let rawValues = TourTargetID.allCases.map { $0.rawValue }
#expect(Set(rawValues).count == rawValues.count)
}
@Test("addMomentButton hat den korrekten rawValue")
func addMomentButtonRawValue() {
#expect(TourTargetID.addMomentButton.rawValue == "addMomentButton")
}
@Test("addTodoButton hat den korrekten rawValue")
func addTodoButtonRawValue() {
#expect(TourTargetID.addTodoButton.rawValue == "addTodoButton")
}
@Test("addContactButton ist im CaseIterable enthalten")
func addContactButtonPresent() {
#expect(TourTargetID.allCases.contains(.addContactButton))
}
@Test("addMomentButton ist im CaseIterable enthalten")
func addMomentButtonPresent() {
#expect(TourTargetID.allCases.contains(.addMomentButton))
}
@Test("addTodoButton ist im CaseIterable enthalten")
func addTodoButtonPresent() {
#expect(TourTargetID.allCases.contains(.addTodoButton))
}
}
@@ -186,6 +186,57 @@ struct UserProfileStoreNewFieldsTests {
} }
} }
// MARK: - Vorname-Extraktion (Begrüßungslogik)
@Suite("TodayView Vorname-Extraktion")
struct GreetingFirstNameTests {
// Spiegelt die Logik aus TodayView.greeting wider:
// profileStore.name.split(separator: " ").first.map(String.init) ?? ""
private func firstName(from name: String) -> String {
name.split(separator: " ").first.map(String.init) ?? ""
}
@Test("Vorname aus vollem Namen")
func firstNameFromFullName() {
#expect(firstName(from: "Max Mustermann") == "Max")
}
@Test("Vorname aus dreiteiligem Namen")
func firstNameFromThreeWordName() {
#expect(firstName(from: "Anna Maria Schmidt") == "Anna")
}
@Test("Einzelner Name → dieser selbst als Vorname")
func firstNameFromSingleWord() {
#expect(firstName(from: "Max") == "Max")
}
@Test("Leerer Name → leerer Vorname")
func firstNameFromEmptyString() {
#expect(firstName(from: "").isEmpty)
}
@Test("Nur Leerzeichen → leerer Vorname")
func firstNameFromWhitespaceOnly() {
#expect(firstName(from: " ").isEmpty)
}
@Test("Begrüßung mit Vorname enthält Komma und Punkt")
func greetingFormatWithName() {
let first = firstName(from: "Max Mustermann")
let greeting = "Guten Tag, \(first)."
#expect(greeting == "Guten Tag, Max.")
}
@Test("Begrüßung ohne Name endet mit Punkt (kein Komma)")
func greetingFormatWithoutName() {
let first = firstName(from: "")
let greeting = first.isEmpty ? "Guten Tag." : "Guten Tag, \(first)."
#expect(greeting == "Guten Tag.")
}
}
// MARK: - Vorlieben-Nudge Anzeigelogik // MARK: - Vorlieben-Nudge Anzeigelogik
@Suite("IchView Vorlieben-Nudge Sichtbarkeit") @Suite("IchView Vorlieben-Nudge Sichtbarkeit")