mirror of
https://github.com/yattee/yattee.git
synced 2026-10-23 13:12:53 +00:00
Let activation know the accounts before it repairs the selection
Foreground activation started identity resolution, the deletion repair and the CloudKit fetch as three things racing each other. With a tombstone for the selected account already on disk and a sibling login on the same server whose status had not been read back yet, the repair ran against `checking` — which it will not repair onto — and landed on local. It commits, so the status refresh arriving a moment later changed nothing: the selection no longer named an account for a second repair to act on. The steps now run as one sequence in both platform paths, because each one is what makes the next correct: the identity says whose accounts these are, the status refresh says which of them this device can use, the repair reads those statuses, and the fetch goes last so a deletion it delivers repairs against the same refreshed picture.
This commit is contained in:
@@ -795,6 +795,35 @@ struct DataContextRepairTests {
|
||||
#expect(!manager.pendingContextUpload)
|
||||
}
|
||||
|
||||
@Test("A repair made while a sibling was still being checked never comes back")
|
||||
func repairIsNotReconsideredWhenStatusesSettle() {
|
||||
let instances = InstancesManager()
|
||||
let instance = makeInstance("inv")
|
||||
instances.add(instance)
|
||||
defer { instances.remove(instance) }
|
||||
|
||||
let manager = makeManager(instances: instances)
|
||||
let selected = manager.addAccount(instanceID: instance.id)
|
||||
let sibling = manager.addAccount(instanceID: instance.id)
|
||||
// Nothing is known about the sibling yet, so it cannot be repaired
|
||||
// onto: `checking` is the absence of an answer, not a usable login.
|
||||
manager.setStatus(.checking, for: sibling.id)
|
||||
manager.setContext(.account(selected.id))
|
||||
|
||||
manager.removeAccount(selected.id)
|
||||
#expect(manager.currentContext == .local)
|
||||
|
||||
// Statuses settling afterwards is not a second chance. The selection no
|
||||
// longer names an account, so the tombstone repair has nothing left to
|
||||
// act on and local is where the user stays — which is why foreground
|
||||
// activation refreshes statuses *before* it lets a tombstone move
|
||||
// anything, rather than repairing twice.
|
||||
manager.setStatus(.signedIn, for: sibling.id)
|
||||
|
||||
#expect(!manager.correctContextIfAccountDeleted())
|
||||
#expect(manager.currentContext == .local)
|
||||
}
|
||||
|
||||
@Test("A signed-in account on another server is never the repair")
|
||||
func repairNeverCrossesInstances() {
|
||||
let instances = InstancesManager()
|
||||
|
||||
Reference in New Issue
Block a user