test(extension-chrome): extract background-core for unit coverage#17
Merged
Conversation
Pulls the maybeReconcile + pollRemoteOnce algorithm out of background.ts into src/lib/background-core.ts as runMaybeReconcile + runPollRemoteOnce. Both take dependencies (now, lastReconciledAt, runReconcile, storage hooks, etc.) as parameters so they're unit-testable without driving chrome.* or Date.now(). background.ts becomes a thin wiring layer that resolves the dependencies (chrome.storage.local, GitHubClient construction, IdMap.load, etc.) and passes them through. The existing live behavior is preserved: same keys, same constants, same error-classification rules. TDD: - RED: wrote 11 tests against src/lib/background-core.js (didn't exist), watched them fail to resolve the import. - GREEN: created background-core.ts implementing the functions. All 11 new tests pass; existing 72 unaffected (83 total). Typecheck clean. Coverage now includes: - 1-hour reconcile throttle (early-return when within window) - RECONCILED_AT stamp + lastError clear on success - lastError persistence with kind='auth' on GitHubAuthError - lastError persistence with kind='unknown' on other GitHubError - No RECONCILED_AT stamp on failure (so retry runs next cold start) - read() vs readIfChanged() routing by etag presence - Early-return on 304 (null result from readIfChanged) — no apply, no etag write - applyRemote + etag write + lastError clear on success - Silent swallow of GitHubNotFoundError in poll (no lastError) - auth-vs-unknown classification in poll lastError Closes #4
This was referenced May 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Pulls the
maybeReconcile+pollRemoteOncealgorithm out ofbackground.tsinto a newsrc/lib/background-core.tswith dependency-injectednow,lastReconciledAt, storage hooks, and arunReconcilecallback. The new module is fully unit-testable;background.tsbecomes a thin wiring layer that resolves the deps and passes them through. Live behavior is preserved — same storage keys, same constants, same error-classification rules.TDD log
test/background-core.test.tsagainst a module that didn't exist. Watched them fail at import resolution — the right failure mode for "this module hasn't been created yet."src/lib/background-core.tsexportingrunMaybeReconcile+runPollRemoteOnce. All 11 new tests pass. Existing 72 still pass (83 total). Refactoredbackground.tsto call the new functions; e2e and unit suites remained green throughout.Partial<GitHubClient>typing in the test was too strict for the generic methods. Switched toanyto match the existingfakeClient(over: any)pattern used in other test files.Coverage added
now - lastReconciledAt < interval)RECONCILED_ATstamp +lastErrorclear on successlastErrorpersistence withkind: "auth"onGitHubAuthErrorlastErrorpersistence withkind: "unknown"on other errorsRECONCILED_ATstamp on failure (so retry runs next cold start)read()vsreadIfChanged()routing by etag presenceapplyRemote+ etag write +lastErrorclear on successGitHubNotFoundErrorin poll (nolastError)lastErrorTest plan
pnpm test83/83 (11 new for this PR)pnpm typecheckcleanpnpm buildcleanCloses #4