Christopher Hotchkiss Christopher Hotchkiss
Login

Code

remindwall / RWPureSwift / Tests / EditSettingsNewTests / Reminders / ReminderPartFeatureTests.swift

Back to remindwall — Current RemindWall

Download this file

//
//  ReminderPartFeatureTests.swift
//  
//
//  Created by Tests on 1/11/26.
//

import AppTypes
import ComposableArchitecture
import Testing

@testable import EditSettingsNew_Reminders

@MainActor
@Suite("ReminderPart Feature Tests")
struct ReminderPartFeatureTests {
    
    // MARK: - Hour Tests
    
    @Test("Increment hour wraps from 23 to 0")
    func incrementHourWrapsAround() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 23, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        await store.send(.incrementHour) {
            $0.$reminderPart.hour.withLock { $0 = 0 }
        }
        
        #expect(store.state.reminderPart.hour == 0)
    }
    
    @Test("Increment hour increases by 1")
    func incrementHourIncreasesValue() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 10, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        await store.send(.incrementHour) {
            $0.$reminderPart.hour.withLock { $0 = 11 }
        }
        
        #expect(store.state.reminderPart.hour == 11)
    }
    
    @Test("Decrement hour wraps from 0 to 23")
    func decrementHourWrapsAround() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 0, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        await store.send(.decrementHour) {
            $0.$reminderPart.hour.withLock { $0 = 23 }
        }
        
        #expect(store.state.reminderPart.hour == 23)
    }
    
    @Test("Decrement hour decreases by 1")
    func decrementHourDecreasesValue() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 10, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        await store.send(.decrementHour) {
            $0.$reminderPart.hour.withLock { $0 = 9 }
        }
        
        #expect(store.state.reminderPart.hour == 9)
    }
    
    // MARK: - Minute Tests
    
    @Test("Increment minute wraps from 45 to 0")
    func incrementMinuteWrapsAround() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 10, minute: 45))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }

        await store.send(.incrementMinute) {
            $0.$reminderPart.minute.withLock { $0 = 0 }
        }

        #expect(store.state.reminderPart.minute == 0)
    }

    @Test("Increment minute increases by 15")
    func incrementMinuteIncreasesValue() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 10, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }

        await store.send(.incrementMinute) {
            $0.$reminderPart.minute.withLock { $0 = 45 }
        }

        #expect(store.state.reminderPart.minute == 45)
    }

    @Test("Decrement minute wraps from 0 to 45")
    func decrementMinuteWrapsAround() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 10, minute: 0))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }

        await store.send(.decrementMinute) {
            $0.$reminderPart.minute.withLock { $0 = 45 }
        }

        #expect(store.state.reminderPart.minute == 45)
    }

    @Test("Decrement minute decreases by 15")
    func decrementMinuteDecreasesValue() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 10, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }

        await store.send(.decrementMinute) {
            $0.$reminderPart.minute.withLock { $0 = 15 }
        }

        #expect(store.state.reminderPart.minute == 15)
    }
    
    // MARK: - AM/PM Toggle Tests
    
    @Test("Toggle AM to PM adds 12 hours")
    func toggleAMtoPM() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 8, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        // Verify we're starting in AM
        #expect(store.state.isAM == true)
        
        await store.send(.toggleAMPM) {
            $0.$reminderPart.hour.withLock { $0 = 20 }
        }
        
        #expect(store.state.reminderPart.hour == 20)
        #expect(store.state.isAM == false)
    }
    
    @Test("Toggle PM to AM subtracts 12 hours")
    func togglePMtoAM() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 20, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        // Verify we're starting in PM
        #expect(store.state.isAM == false)
        
        await store.send(.toggleAMPM) {
            $0.$reminderPart.hour.withLock { $0 = 8 }
        }
        
        #expect(store.state.reminderPart.hour == 8)
        #expect(store.state.isAM == true)
    }
    
    @Test("Toggle at midnight (hour 0) switches to noon (hour 12)")
    func toggleMidnightToNoon() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 0, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        #expect(store.state.isAM == true)
        
        await store.send(.toggleAMPM) {
            $0.$reminderPart.hour.withLock { $0 = 12 }
        }
        
        #expect(store.state.reminderPart.hour == 12)
        #expect(store.state.isAM == false)
    }
    
    @Test("Toggle at noon (hour 12) switches to midnight (hour 0)")
    func toggleNoonToMidnight() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 12, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        #expect(store.state.isAM == false)
        
        await store.send(.toggleAMPM) {
            $0.$reminderPart.hour.withLock { $0 = 0 }
        }
        
        #expect(store.state.reminderPart.hour == 0)
        #expect(store.state.isAM == true)
    }
    
    // MARK: - Week Day Tests
    
    @Test("Set weekday to Sunday")
    func setWeekDaySunday() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 10, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        await store.send(.setWeekDay(.Sunday)) {
            $0.$reminderPart.weekDay.withLock { $0 = .Sunday }
        }
        
        #expect(store.state.reminderPart.weekDay == .Sunday)
    }
    
    @Test("Set weekday changes correctly")
    func setWeekDayChanges() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 10, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        for day in DaysOfWeek.allCases {
            await store.send(.setWeekDay(day)) {
                $0.$reminderPart.weekDay.withLock { $0 = day }
            }
            
            #expect(store.state.reminderPart.weekDay == day)
        }
    }
    
    // MARK: - Display Hour Tests
    
    @Test("Display hour shows 12 for hour 0 (midnight)")
    func displayHourMidnight() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 0, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        #expect(store.state.displayHour == 12)
    }
    
    @Test("Display hour shows 12 for hour 12 (noon)")
    func displayHourNoon() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 12, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        #expect(store.state.displayHour == 12)
    }
    
    @Test("Display hour converts 24-hour to 12-hour format correctly")
    func displayHour12HourConversion() async {
        let testCases: [(hour24: Int, expected12: Int)] = [
            (0, 12),   // 12 AM
            (1, 1),    // 1 AM
            (11, 11),  // 11 AM
            (12, 12),  // 12 PM
            (13, 1),   // 1 PM
            (23, 11)   // 11 PM
        ]
        
        for testCase in testCases {
            let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: testCase.hour24, minute: 0))
            let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
                ReminderPartFeature()
            }
            
            #expect(store.state.displayHour == testCase.expected12,
                   "Hour \(testCase.hour24) should display as \(testCase.expected12)")
        }
    }
    
    // MARK: - Combined Action Tests
    
    @Test("Multiple hour increments work correctly")
    func multipleHourIncrements() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 22, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        await store.send(.incrementHour) { $0.$reminderPart.hour.withLock { $0 = 23 } }
        await store.send(.incrementHour) { $0.$reminderPart.hour.withLock { $0 = 0 } }
        await store.send(.incrementHour) { $0.$reminderPart.hour.withLock { $0 = 1 } }
        
        #expect(store.state.reminderPart.hour == 1)
    }
    
    @Test("Multiple minute increments work correctly")
    func multipleMinuteIncrements() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 10, minute: 15))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }

        await store.send(.incrementMinute) { $0.$reminderPart.minute.withLock { $0 = 30 } }
        await store.send(.incrementMinute) { $0.$reminderPart.minute.withLock { $0 = 45 } }
        await store.send(.incrementMinute) { $0.$reminderPart.minute.withLock { $0 = 0 } }

        #expect(store.state.reminderPart.minute == 0)
    }
    
    @Test("Changing time and weekday together")
    func combinedTimeAndWeekdayChanges() async {
        let reminderPart = Shared(value: ReminderPart(weekDay: .Monday, hour: 8, minute: 30))
        let store = TestStore(initialState: ReminderPartFeature.State(reminderPart)) {
            ReminderPartFeature()
        }
        
        await store.send(.setWeekDay(.Friday)) {
            $0.$reminderPart.weekDay.withLock { $0 = .Friday }
        }
        
        await store.send(.incrementHour) {
            $0.$reminderPart.hour.withLock { $0 = 9 }
        }
        
        await store.send(.incrementMinute) {
            $0.$reminderPart.minute.withLock { $0 = 45 }
        }

        await store.send(.toggleAMPM) {
            $0.$reminderPart.hour.withLock { $0 = 21 }
        }

        #expect(store.state.reminderPart.weekDay == .Friday)
        #expect(store.state.reminderPart.hour == 21)
        #expect(store.state.reminderPart.minute == 45)
        #expect(store.state.isAM == false)
        #expect(store.state.displayHour == 9)
    }
}