Fix 8 audit items: remove force-unwraps, improve accessibility and concurrency

- Replace force-unwrap HK types with modern HKQuantityType(_:) initializer
- Replace Calendar.date force-unwraps with guard/let in HealthService, HeaderPercView, MoodStreakActivity, DayViewViewModel, MonthTotalTemplate
- Extract DayViewViewModel.countEntries into testable static method with safe flatMap
- Replace DispatchQueue.main.asyncAfter with Task.sleep in CelebrationAnimations
- Add .minimumScaleFactor(0.5) to SmallRollUpHeaderView for Dynamic Type
- Add VoiceOver accessibility labels to HeaderPercView mood percentages
- Fix @testable import iFeel → Feels in Tests_iOS.swift
- Add 4 unit tests for countEntries (TDD)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-17 11:42:16 -06:00
parent 277e277750
commit 7f27446b94
11 changed files with 168 additions and 76 deletions

View File

@@ -0,0 +1,42 @@
//
// DayViewViewModelTests.swift
// FeelsTests
//
// Unit tests for DayViewViewModel.countEntries verifies safe counting
// across various grouped dictionary shapes (TDD for force-unwrap fix).
//
import XCTest
import SwiftData
@testable import Feels
@MainActor
final class DayViewViewModelTests: XCTestCase {
func testCountEntries_EmptyGrouped() {
let grouped: [Int: [Int: [MoodEntryModel]]] = [:]
XCTAssertEqual(DayViewViewModel.countEntries(in: grouped), 0)
}
func testCountEntries_SingleYearSingleMonth() {
let entry = MoodEntryModel(forDate: Date(), mood: .great, entryType: .listView)
let grouped: [Int: [Int: [MoodEntryModel]]] = [2026: [2: [entry]]]
XCTAssertEqual(DayViewViewModel.countEntries(in: grouped), 1)
}
func testCountEntries_MultipleYearsAndMonths() {
let e1 = MoodEntryModel(forDate: Date(), mood: .great, entryType: .listView)
let e2 = MoodEntryModel(forDate: Date(), mood: .good, entryType: .listView)
let e3 = MoodEntryModel(forDate: Date(), mood: .bad, entryType: .listView)
let grouped: [Int: [Int: [MoodEntryModel]]] = [
2025: [12: [e1, e2]],
2026: [1: [e3], 2: [e1, e2, e3]]
]
XCTAssertEqual(DayViewViewModel.countEntries(in: grouped), 6)
}
func testCountEntries_YearWithEmptyMonth() {
let grouped: [Int: [Int: [MoodEntryModel]]] = [2026: [1: []]]
XCTAssertEqual(DayViewViewModel.countEntries(in: grouped), 0)
}
}