Christopher Hotchkiss Christopher Hotchkiss
Login

Code

remindwall / RWPureSwift / Tests / EditSettingsNewTests / BusSettings / AlertsSettingsTests.swift

Back to remindwall โ€” Current RemindWall

Download this file

import AppTypes
import ComposableArchitecture
import Dao
import DependenciesTestSupport
import Foundation
import Testing
import TrafficAPI

@testable import EditSettingsNew_BusSettings

@MainActor
@Suite("AlertsSettings Feature Tests", .dependencies {
    $0.defaultDatabase = try! $0.appDatabase()
    $0.uuid = .incrementing
    $0.date = .constant(Date(timeIntervalSince1970: 0))
})
struct AlertsSettingsTests {

    @discardableResult
    private func seedStop(sortOrder: Int = 0) async -> MonitoredStop.ID {
        @Dependency(\.defaultDatabase) var database
        @Dependency(\.uuid) var uuid
        let id = MonitoredStop.ID(uuid())
        try! await database.write { db in
            try MonitoredStop.insert {
                MonitoredStop(
                    id: id, label: "School bus", stopId: "1_75403", routeId: "1_100224",
                    routeShortName: "12", sortOrder: sortOrder
                )
            }.execute(db)
        }
        return id
    }

    @discardableResult
    private func seedRoute(sortOrder: Int = 0) async -> MonitoredRoute.ID {
        @Dependency(\.defaultDatabase) var database
        @Dependency(\.uuid) var uuid
        let id = MonitoredRoute.ID(uuid())
        try! await database.write { db in
            try MonitoredRoute.insert {
                MonitoredRoute(
                    id: id, label: "School run",
                    destinationLatitude: 47.5423, destinationLongitude: -122.3866,
                    destinationName: "Maple Elementary", normalMinutes: 12, sortOrder: sortOrder
                )
            }.execute(db)
        }
        return id
    }

    @Test("the watch list holds bus stops and driving routes as peers")
    func watchesUnify() async {
        await seedStop()
        await seedRoute()

        let state = AlertsSettingsFeature.State()
        #expect(state.watches.count == 2)
        #expect(state.watches[0].chipText == "12")
        #expect(state.watches[1].chipText == "๐Ÿš—")
        #expect(state.watches[1].whereText == "to Maple Elementary")
        let allEnabled = state.watches.allSatisfy(\.enabled)
        #expect(allEnabled)
    }

    @Test("toggling a watch writes its enabled column")
    func toggleWrites() async throws {
        let stopId = await seedStop()
        @Dependency(\.defaultDatabase) var database

        let store = TestStore(initialState: AlertsSettingsFeature.State()) {
            AlertsSettingsFeature()
        }
        store.exhaustivity = .off

        await store.send(.watchToggled(.bus(stopId), false))
        await store.finish()

        let stored = try await database.read { db in
            try MonitoredStop.find(stopId).fetchOne(db)
        }
        #expect(stored?.enabled == false)
        #expect(store.state.watches.first?.enabled == false)
    }

    @Test("a saved drive draft inserts a route with per-watch defaults")
    func addDriveInserts() async throws {
        @Dependency(\.defaultDatabase) var database

        let store = TestStore(initialState: AlertsSettingsFeature.State()) {
            AlertsSettingsFeature()
        }
        store.exhaustivity = .off

        await store.send(.addDriveTapped)
        await store.send(.destination(.presented(.addDrive(.delegate(.saveRoute(
            MonitoredRoute.Draft(
                label: "School run",
                destinationLatitude: 47.5423, destinationLongitude: -122.3866,
                destinationName: "Maple Elementary", normalMinutes: 12, sortOrder: 0,
                window: nil, enabled: true
            )
        ))))))
        await store.finish()

        let routes = try await database.read { db in
            try MonitoredRoute.all.fetchAll(db)
        }
        #expect(routes.count == 1)
        #expect(routes.first?.enabled == true)
        #expect(routes.first?.window == nil)
        #expect(store.state.watches.count == 1)
    }

    @Test("a detail remove request deletes the row and closes the sheet")
    func removeDeletes() async throws {
        let stopId = await seedStop()
        @Dependency(\.defaultDatabase) var database

        let store = TestStore(initialState: AlertsSettingsFeature.State()) {
            AlertsSettingsFeature()
        }
        store.exhaustivity = .off

        await store.send(.watchTapped(.bus(stopId)))
        #expect(store.state.destination != nil)

        await store.send(.destination(.presented(.detail(.delegate(.removeRequested(.bus(stopId)))))))
        await store.finish()

        #expect(store.state.destination == nil)
        let remaining = try await database.read { db in
            try MonitoredStop.all.fetchAll(db)
        }
        #expect(remaining.isEmpty)
        #expect(store.state.watches.isEmpty)
    }

    @Test("windowSummary self-describes the row")
    func windowSummary() {
        let watch = Watch.bus(MonitoredStop(
            id: MonitoredStop.ID(UUID()), label: "School bus", stopId: "1_1",
            routeId: "1_a", routeShortName: "12", sortOrder: 0
        ))
        // nil window reads as the default Mon-Fri 6:30-9:00.
        #expect(watch.windowSummary == "MTWTF ยท 6:30 AMโ€“9:00 AM")
    }
}