Christopher Hotchkiss Christopher Hotchkiss
Login

Code

remindwall / RWPureSwift / Tests / EditSettingsNewTests / TopLevel / SettingsResolverTests.swift

Back to remindwall — Current RemindWall

Download this file

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

@testable import EditSettingsNew_TopLevel

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

    @Test("start reconciles the current album descriptor into a cached id")
    func startResolvesAlbum() async {
        let store = TestStore(initialState: SettingsResolverFeature.State()) {
            SettingsResolverFeature()
        } withDependencies: {
            $0.photoKitAlbums.libraryAccess = { .authorized }
            $0.photoKitAlbums.findAlbum = { descriptor in
                descriptor == "Wall Photos" ? AlbumLocalId("local-123") : nil
            }
            $0.calendarAsync.calendarAccess = { .notDetermined }
        }
        store.exhaustivity = .off

        store.state.$albumDescriptor.withLock { $0 = AlbumDescriptor("Wall Photos") }

        await store.send(.start)
        await store.receive(\._albumDescriptorChanged)
        await store.receive(\._setAlbum)
        #expect(store.state.selectedAlbum == AlbumLocalId("local-123"))

        await store.send(.stop)
        await store.finish()
    }

    @Test("album descriptor with no local match clears the stale cached id")
    func albumNoMatchClearsId() async {
        let store = TestStore(initialState: SettingsResolverFeature.State()) {
            SettingsResolverFeature()
        } withDependencies: {
            $0.photoKitAlbums.libraryAccess = { .authorized }
            $0.photoKitAlbums.findAlbum = { _ in nil }
        }
        store.state.$selectedAlbum.withLock { $0 = AlbumLocalId("stale-id") }

        await store.send(._albumDescriptorChanged(AlbumDescriptor("Renamed Album")))
        await store.receive(\._setAlbum) {
            $0.$selectedAlbum.withLock { $0 = nil }
        }
    }

    @Test("cached album id backfills an absent descriptor")
    func albumBackfill() async {
        let store = TestStore(initialState: SettingsResolverFeature.State()) {
            SettingsResolverFeature()
        } withDependencies: {
            $0.photoKitAlbums.libraryAccess = { .authorized }
            $0.photoKitAlbums.albumDescriptor = { albumId in
                albumId == AlbumLocalId("kiosk-album") ? AlbumDescriptor("Wall Photos") : nil
            }
        }
        store.state.$selectedAlbum.withLock { $0 = AlbumLocalId("kiosk-album") }

        await store.send(._albumDescriptorChanged(nil))
        await store.receive(\._setAlbumDescriptor) {
            $0.$albumDescriptor.withLock { $0 = AlbumDescriptor("Wall Photos") }
        }
    }

    @Test("unauthorized library never touches the cached id")
    func unauthorizedSkips() async {
        let store = TestStore(initialState: SettingsResolverFeature.State()) {
            SettingsResolverFeature()
        } withDependencies: {
            $0.photoKitAlbums.libraryAccess = { .denied }
        }
        store.state.$selectedAlbum.withLock { $0 = AlbumLocalId("keep-me") }

        await store.send(._albumDescriptorChanged(AlbumDescriptor("Elsewhere")))
        #expect(store.state.selectedAlbum == AlbumLocalId("keep-me"))
    }

    @Test("calendar descriptor resolves by title and source")
    func calendarResolves() async {
        let store = TestStore(initialState: SettingsResolverFeature.State()) {
            SettingsResolverFeature()
        } withDependencies: {
            $0.calendarAsync.calendarAccess = { .fullAccess }
            $0.calendarAsync.findCalendar = { descriptor in
                descriptor == CalendarDescriptor(title: "Family", sourceTitle: "iCloud")
                    ? CalendarId("local-cal") : nil
            }
        }

        await store.send(._calendarDescriptorChanged(CalendarDescriptor(title: "Family", sourceTitle: "iCloud")))
        await store.receive(\._setCalendar) {
            $0.$selectedCalendar.withLock { $0 = CalendarId("local-cal") }
        }
    }

    @Test("a synced None clears the cached calendar instead of backfilling")
    func calendarNoSelectionClears() async {
        let store = TestStore(initialState: SettingsResolverFeature.State()) {
            SettingsResolverFeature()
        } withDependencies: {
            $0.calendarAsync.calendarAccess = { .fullAccess }
        }
        store.state.$selectedCalendar.withLock { $0 = CalendarId("was-picked") }

        await store.send(._calendarDescriptorChanged(.noSelection))
        await store.receive(\._setCalendar) {
            $0.$selectedCalendar.withLock { $0 = nil }
        }
    }

    @Test("cached calendar id backfills an absent descriptor")
    func calendarBackfill() async {
        let store = TestStore(initialState: SettingsResolverFeature.State()) {
            SettingsResolverFeature()
        } withDependencies: {
            $0.calendarAsync.calendarAccess = { .fullAccess }
            $0.calendarAsync.calendarDescriptor = { calendarId in
                calendarId == CalendarId("kiosk-cal")
                    ? CalendarDescriptor(title: "Family", sourceTitle: "iCloud") : nil
            }
        }
        store.state.$selectedCalendar.withLock { $0 = CalendarId("kiosk-cal") }

        await store.send(._calendarDescriptorChanged(nil))
        await store.receive(\._setCalendarDescriptor) {
            $0.$calendarDescriptor.withLock {
                $0 = CalendarDescriptor(title: "Family", sourceTitle: "iCloud")
            }
        }
    }

    @Test("resolving to the already-cached id writes nothing")
    func equalIdNoWrite() async {
        let store = TestStore(initialState: SettingsResolverFeature.State()) {
            SettingsResolverFeature()
        } withDependencies: {
            $0.photoKitAlbums.libraryAccess = { .authorized }
            $0.photoKitAlbums.findAlbum = { _ in AlbumLocalId("same-id") }
        }
        store.state.$selectedAlbum.withLock { $0 = AlbumLocalId("same-id") }

        await store.send(._albumDescriptorChanged(AlbumDescriptor("Wall Photos")))
        // _setAlbum arrives but the state assertion block is empty: no change.
        await store.receive(\._setAlbum)
    }
}