remindwall / RWPureSwift / Tests / EditSettingsNewTests / TopLevel / AlbumPickerTests.swift
Back to remindwall — Current RemindWall
import AppTypes
import ComposableArchitecture
import Dao
import DependenciesTestSupport
import Foundation
import Photos
import PhotoKitAsync
import Testing
@testable import EditSettingsNew_TopLevel
@MainActor
@Suite("AlbumPicker Feature Tests", .dependencies {
// .syncedSetting backs the album descriptor: reads the database at State
// init, stamps lastModified on descriptor writes.
$0.defaultDatabase = try! $0.appDatabase()
$0.uuid = .incrementing
$0.date = .constant(Date(timeIntervalSince1970: 0))
})
struct AlbumPickerTests {
@Test("onAppear when not authorized shows authorize button state")
func onAppearNotAuthorized() async {
let store = TestStore(initialState: AlbumPickerFeature.State()) {
AlbumPickerFeature()
} withDependencies: {
$0.photoKitAlbums.libraryAccess = { .notDetermined }
}
await store.send(.onAppear)
}
@Test("onAppear when denied shows denied state")
func onAppearDenied() async {
let store = TestStore(initialState: AlbumPickerFeature.State()) {
AlbumPickerFeature()
} withDependencies: {
$0.photoKitAlbums.libraryAccess = { .denied }
}
await store.send(.onAppear) {
$0.photoStatus = .denied
}
}
@Test("onAppear when authorized loads album list")
func onAppearAuthorized() async {
let store = TestStore(initialState: AlbumPickerFeature.State()) {
AlbumPickerFeature()
} withDependencies: {
$0.photoKitAlbums.libraryAccess = { .authorized }
$0.photoKitAlbums.availableAlbums = { nil }
}
await store.send(.onAppear) {
$0.photoStatus = .authorized
}
await store.receive(\.loadListComplete)
}
@Test("onAppear when restricted loads album list")
func onAppearRestricted() async {
let store = TestStore(initialState: AlbumPickerFeature.State()) {
AlbumPickerFeature()
} withDependencies: {
$0.photoKitAlbums.libraryAccess = { .restricted }
$0.photoKitAlbums.availableAlbums = { nil }
}
await store.send(.onAppear) {
$0.photoStatus = .restricted
}
await store.receive(\.loadListComplete)
}
@Test("tapOpenSettings triggers openPhotoSettings")
func tapOpenSettings() async {
let store = TestStore(initialState: AlbumPickerFeature.State()) {
AlbumPickerFeature()
} withDependencies: {
$0.photoKitAlbums.openPhotoSettings = {}
}
await store.send(.tapOpenSettings)
}
@Test("tapAuthorizeAccess requests authorization and refreshes on grant")
func tapAuthorizeAccessGranted() async {
let store = TestStore(initialState: AlbumPickerFeature.State()) {
AlbumPickerFeature()
} withDependencies: {
$0.photoKitAlbums.requestAuthorization = {}
$0.photoKitAlbums.libraryAccess = { .authorized }
$0.photoKitAlbums.availableAlbums = { nil }
}
await store.send(.tapAuthorizeAccess)
await store.receive(\.authorizationComplete) {
$0.photoStatus = .authorized
}
await store.receive(\.loadListComplete)
}
@Test("tapAuthorizeAccess requests authorization and updates status on deny")
func tapAuthorizeAccessDenied() async {
let store = TestStore(initialState: AlbumPickerFeature.State()) {
AlbumPickerFeature()
} withDependencies: {
$0.photoKitAlbums.requestAuthorization = {}
$0.photoKitAlbums.libraryAccess = { .denied }
}
await store.send(.tapAuthorizeAccess)
await store.receive(\.authorizationComplete) {
$0.photoStatus = .denied
}
}
@Test("loadListComplete sets available albums")
func loadListComplete() async {
var state = AlbumPickerFeature.State()
state.photoStatus = .authorized
let store = TestStore(initialState: state) {
AlbumPickerFeature()
}
await store.send(.loadListComplete(nil))
}
@Test("selectAlbum updates shared state")
func selectAlbumUpdatesState() async {
let store = TestStore(initialState: AlbumPickerFeature.State()) {
AlbumPickerFeature()
}
await store.send(.selectAlbum(AlbumLocalId("test-album-id"))) {
$0.$selectedAlbum.withLock { $0 = AlbumLocalId("test-album-id") }
}
}
@Test("selectAlbum with a loaded list syncs the album title")
func selectAlbumWritesDescriptor() async {
let album = PHAssetCollectionMock(title: "Wall Photos")
let albums = PHFetchResultCollectionMock<PHAssetCollection>([album])
let store = TestStore(initialState: AlbumPickerFeature.State()) {
AlbumPickerFeature()
}
await store.send(.loadListComplete(albums)) {
$0.availibleAlbums = albums
}
await store.send(.selectAlbum(AlbumLocalId(album.localIdentifier))) {
$0.$selectedAlbum.withLock { $0 = AlbumLocalId(album.localIdentifier) }
$0.$albumDescriptor.withLock { $0 = AlbumDescriptor("Wall Photos") }
}
}
@Test("selectAlbum(nil) clears the synced descriptor")
func selectAlbumNilClearsDescriptor() async {
let store = TestStore(initialState: AlbumPickerFeature.State()) {
AlbumPickerFeature()
}
store.state.$albumDescriptor.withLock { $0 = AlbumDescriptor("Old Pick") }
await store.send(.selectAlbum(nil)) {
$0.$albumDescriptor.withLock { $0 = nil }
}
}
@Test("needsRePick flags a descriptor with no local resolution")
func needsRePick() async {
let state = AlbumPickerFeature.State()
#expect(!state.needsRePick)
state.$albumDescriptor.withLock { $0 = AlbumDescriptor("Wall Photos") }
#expect(state.needsRePick)
state.$selectedAlbum.withLock { $0 = AlbumLocalId("resolved") }
#expect(!state.needsRePick)
}
}