153 lines · 6.6 KB · Swift
RawDownload
import CodexBarCoreimport Foundationimport Testing@testable import CodexBar @Suite(.serialized)@MainActorstruct CodexSystemPromotionUITests {    @Test    func `promotion coordinator promotes immediately`() async throws {        let container = try CodexAccountPromotionTestContainer(            suiteName: "CodexSystemPromotionUITests-coordinator-immediate")        defer { container.tearDown() }         let target = try container.createManagedAccount(            persistedEmail: "managed@example.com",            authAccountID: "acct-managed")        try container.persistAccounts([target])        _ = try container.writeLiveOAuthAuthFile(email: "live@example.com", accountID: "acct-live")         let managedVisibleAccountID = try #require(container.settings.codexVisibleAccountProjection.visibleAccounts            .first(where: { $0.storedAccountID == target.id })?            .id)        let coordinator = CodexAccountPromotionCoordinator(service: container.makeService())         let result = await coordinator.promote(managedAccountID: target.id)         let promotionResult: CodexAccountPromotionResult        switch result {        case let .success(value):            promotionResult = value        case let .failure(error):            Issue.record("Expected successful promotion, got \(error)")            throw PromotionTestError.unexpectedDisposition        }         #expect(promotionResult.outcome == .promoted)        #expect(container.settings.codexActiveSource == .liveSystem)        #expect(container.settings.codexVisibleAccountProjection.liveVisibleAccountID == managedVisibleAccountID)        #expect(coordinator.userFacingError == nil)    }     @Test    func `promotion coordinator blocks while live reauthentication is running`() async throws {        let container = try CodexAccountPromotionTestContainer(            suiteName: "CodexSystemPromotionUITests-coordinator-live-reauth")        defer { container.tearDown() }         let target = try container.createManagedAccount(            persistedEmail: "managed@example.com",            authAccountID: "acct-managed")        try container.persistAccounts([target])        _ = try container.writeLiveOAuthAuthFile(email: "live@example.com", accountID: "acct-live")        container.settings.codexActiveSource = .managedAccount(id: target.id)         let coordinator = CodexAccountPromotionCoordinator(service: container.makeService())        coordinator.setLiveReauthenticationInProgress(true)         let result = await coordinator.promote(managedAccountID: target.id)         let error: CodexSystemAccountPromotionUserFacingError        switch result {        case .success:            Issue.record("Expected blocked promotion while live reauthentication is running")            throw PromotionTestError.unexpectedDisposition        case let .failure(value):            error = value        }         #expect(error.title == "Could not switch system account")        #expect(error.message == "Finish the current managed account change before switching the system account.")        #expect(coordinator.userFacingError == error)        #expect(coordinator.isInteractionBlocked())        #expect(container.settings.codexActiveSource == .managedAccount(id: target.id))    }     @Test    func `codex menu descriptor includes system account submenu`() throws {        let container = try CodexAccountPromotionTestContainer(            suiteName: "CodexSystemPromotionUITests-menu-descriptor")        defer { container.tearDown() }         let managedAccountID = UUID()        let managedAccount = try container.createManagedAccount(            id: managedAccountID,            persistedEmail: "managed@example.com",            authAccountID: "acct-managed")        try container.persistAccounts([managedAccount])        container.settings._test_liveSystemCodexAccount = ObservedSystemCodexAccount(            email: "live@example.com",            codexHomePath: container.liveHomeURL.path,            observedAt: Date())         let descriptor = MenuDescriptor.build(            provider: .codex,            store: container.usageStore,            settings: container.settings,            account: UsageFetcher().loadAccountInfo(),            managedCodexAccountCoordinator: ManagedCodexAccountCoordinator(),            codexAccountPromotionCoordinator: CodexAccountPromotionCoordinator(                service: container.makeService()),            updateReady: false)         let submenu = try #require(descriptor.sections            .flatMap(\.entries)            .compactMap { entry -> (String, String?, [MenuDescriptor.SubmenuItem])? in                guard case let .submenu(title, systemImageName, items) = entry else { return nil }                return (title, systemImageName, items)            }            .first(where: { $0.0 == "System Account" }))         #expect(submenu.1 == MenuDescriptor.MenuActionSystemImage.systemAccount.rawValue)        #expect(submenu.2.map(\.title) == ["live@example.com", "managed@example.com"])        #expect(submenu.2.count == 2)        #expect(submenu.2[0].isChecked)        #expect(submenu.2[0].isEnabled == false)        #expect(submenu.2[0].action == nil)        #expect(submenu.2[1].isChecked == false)        #expect(submenu.2[1].isEnabled)        #expect(submenu.2[1].action == .requestCodexSystemPromotion(managedAccountID))    }     @Test    func `codex menu descriptor hides single live system account submenu`() throws {        let container = try CodexAccountPromotionTestContainer(            suiteName: "CodexSystemPromotionUITests-menu-single-live")        defer { container.tearDown() }         container.settings._test_liveSystemCodexAccount = ObservedSystemCodexAccount(            email: "live@example.com",            codexHomePath: container.liveHomeURL.path,            observedAt: Date())         let descriptor = MenuDescriptor.build(            provider: .codex,            store: container.usageStore,            settings: container.settings,            account: UsageFetcher().loadAccountInfo(),            managedCodexAccountCoordinator: ManagedCodexAccountCoordinator(),            codexAccountPromotionCoordinator: CodexAccountPromotionCoordinator(                service: container.makeService()),            updateReady: false)         let hasSystemAccountSubmenu = descriptor.sections            .flatMap(\.entries)            .contains { entry in                guard case let .submenu(title, _, _) = entry else { return false }                return title == "System Account"            }         #expect(!hasSystemAccountSubmenu)    }}