@@ -832,4 +832,103 @@ extension CodexAccountScopedRefreshTests {
832832 #expect( liveSnapshot. primary? . windowMinutes == 300 )
833833 #expect( liveSnapshot. primary? . resetsAt == priorReset)
834834 }
835+
836+ @Test
837+ func `ignores live codex prior snapshot after auth fingerprint changes`() async throws {
838+ let settings = self . makeSettingsStore (
839+ suite: " CodexAccountVisibleHistoryBackfillTests-live-prior-auth-change " )
840+ settings. refreshFrequency = . manual
841+ settings. multiAccountMenuLayout = . stacked
842+
843+ let managedID = try #require( UUID ( uuidString: " DDDDDDDD-EEEE-FFFF-AAAA-222222222222 " ) )
844+ let liveHome = FileManager . default. temporaryDirectory
845+ . appendingPathComponent ( " codex-visible-live-prior-auth- \( UUID ( ) . uuidString) " , isDirectory: true )
846+ let managedHome = FileManager . default. temporaryDirectory
847+ . appendingPathComponent ( " codex-visible-live-prior-auth-managed- \( UUID ( ) . uuidString) " , isDirectory: true )
848+ try FileManager . default. createDirectory ( at: liveHome, withIntermediateDirectories: true )
849+ try FileManager . default. createDirectory ( at: managedHome, withIntermediateDirectories: true )
850+ settings. _test_liveSystemCodexAccount = ObservedSystemCodexAccount (
851+ email: " live-prior-auth@example.com " ,
852+ authFingerprint: " current-live-auth-fingerprint " ,
853+ codexHomePath: liveHome. path,
854+ observedAt: Date ( ) ,
855+ identity: . emailOnly( normalizedEmail: " live-prior-auth@example.com " ) )
856+ let managedAccount = ManagedCodexAccount (
857+ id: managedID,
858+ email: " managed-prior-auth@example.com " ,
859+ providerAccountID: " acct-managed-prior-auth " ,
860+ workspaceLabel: " Managed Team " ,
861+ workspaceAccountID: " acct-managed-prior-auth " ,
862+ managedHomePath: managedHome. path,
863+ createdAt: 1 ,
864+ updatedAt: 2 ,
865+ lastAuthenticatedAt: 2 )
866+ let storeURL = try self . makeManagedAccountStoreURL ( accounts: [ managedAccount] )
867+ defer {
868+ settings. _test_managedCodexAccountStoreURL = nil
869+ settings. _test_liveSystemCodexAccount = nil
870+ try ? FileManager . default. removeItem ( at: storeURL)
871+ try ? FileManager . default. removeItem ( at: liveHome)
872+ try ? FileManager . default. removeItem ( at: managedHome)
873+ }
874+ settings. _test_managedCodexAccountStoreURL = storeURL
875+ settings. codexActiveSource = . managedAccount( id: managedID)
876+
877+ let now = Date ( )
878+ let priorReset = now. addingTimeInterval ( 2 * 60 * 60 )
879+ let liveAccount = try #require( settings. codexVisibleAccountProjection. visibleAccounts. first {
880+ $0. selectionSource == . liveSystem
881+ } )
882+ let priorLiveAccount = CodexVisibleAccount (
883+ id: liveAccount. id,
884+ email: liveAccount. email,
885+ workspaceLabel: liveAccount. workspaceLabel,
886+ workspaceAccountID: liveAccount. workspaceAccountID,
887+ authFingerprint: " stale-live-auth-fingerprint " ,
888+ storedAccountID: liveAccount. storedAccountID,
889+ selectionSource: liveAccount. selectionSource,
890+ isActive: liveAccount. isActive,
891+ isLive: liveAccount. isLive,
892+ canReauthenticate: liveAccount. canReauthenticate,
893+ canRemove: liveAccount. canRemove)
894+ let snapshotStore = RecordingCodexAccountUsageSnapshotStore ( initialSnapshots: [
895+ CodexAccountUsageSnapshot (
896+ account: priorLiveAccount,
897+ snapshot: UsageSnapshot (
898+ primary: RateWindow (
899+ usedPercent: 18 ,
900+ windowMinutes: 300 ,
901+ resetsAt: priorReset,
902+ resetDescription: nil ) ,
903+ secondary: nil ,
904+ updatedAt: now. addingTimeInterval ( - 60 ) ) ,
905+ error: nil ,
906+ sourceLabel: " cached " ) ,
907+ ] )
908+ let store = UsageStore (
909+ fetcher: UsageFetcher ( environment: [ : ] ) ,
910+ browserDetection: BrowserDetection ( cacheTTL: 0 ) ,
911+ settings: settings,
912+ codexAccountUsageSnapshotStore: snapshotStore,
913+ startupBehavior: . testing)
914+ self . installContextualCodexProvider ( on: store) { _ in
915+ UsageSnapshot (
916+ primary: RateWindow (
917+ usedPercent: 9 ,
918+ windowMinutes: 0 ,
919+ resetsAt: nil ,
920+ resetDescription: nil ) ,
921+ secondary: nil ,
922+ updatedAt: now)
923+ }
924+
925+ await store. refreshCodexVisibleAccountsForMenu ( )
926+
927+ let liveSnapshot = try #require( store. codexAccountSnapshots. first {
928+ $0. account. selectionSource == . liveSystem
929+ } ? . snapshot)
930+ #expect( liveSnapshot. primary? . usedPercent == 9 )
931+ #expect( liveSnapshot. primary? . windowMinutes == 0 )
932+ #expect( liveSnapshot. primary? . resetsAt == nil )
933+ }
835934}
0 commit comments