Skip to content

test(lists): cover the mid-backfill owner change guarding stale-key republish #8052

Closed

Description

@NotThatKindOfDrLiz

Follow-up to #7728, which is closed because its code fix is already on main. The fix has no regression test, so it can be removed without anything going red.

What is unprotected

mobile/lib/services/curated_list_service.dart:1608-1653 re-reads the owner inside the per-list serialized operation and bails if it changed mid-backfill:

final currentOwner = _relayGateway.currentAuthenticatedPubkey();   // 1633
if (currentOwner == null || currentOwner != owner) return;          // 1634

Without that guard, _backfillUnpublishedLists republishes a stranded list under the previous account's owner key after a sign-out or account switch. Relays accept it, because the signature is genuinely valid — it was signed by that key. The prior account's lists then surface under the new one.

Why existing coverage does not catch it

mobile/test/services/curated_list_service_crud_test.dart has two nearby tests, neither of which exercises this:

  • does not backfill a subscribed list owned by someone else — ownership is wrong from the start, so the loop never had a valid owner to go stale.
  • skips a sealed event if the user signs out during sync — covers _processListEvent, not the backfill loop.

The specific uncovered case is an owner that is valid when the loop starts and different by the time an iteration publishes.

Test to add

In curated_list_service_crud_test.dart:

  1. Sign in, create two or more lists with nostrEventId == null so both are stranded.
  2. Enter _backfillUnpublishedLists, and between iterations make _relayGateway.currentAuthenticatedPubkey() return a different pubkey (and separately, null).
  3. Assert no publish happens for the remaining lists under the original owner key.
  4. Assert the already-published first list is unaffected.

Deleting either line 1633 or 1634 must turn the test red — mutation-check it, per the lesson recorded on #7936 / #7988 that an assertion can pass without proving the guard does the work.

Cost

Test-only. curated_list_service.dart is a baselined god-file (ceiling 1848, currently 1831), but test files do not count against that ceiling, so this carries no line budget.

Metadata

Metadata

Labels

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions