Merge RB-25 — add the UPLOAD_TRANSPORT injection token

TE-003: UploadShellService documented UploadTransport as the swap seam, then
bound the concrete, unexported KeepaliveTransport class directly, so a spec
could not fake it. UPLOAD_TRANSPORT copies the SESSION_PORT shape; the
default factory returns the same instance, so runtime behaviour is
unchanged. upload-shell.service.ts goes from 0% to 88.57% line coverage
across 16 new specs for upload(), cancel(), delete() and pollReturning().

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

# Conflicts:
#	docs/project/refactor-backlog-setup/refactor-backlog/99-backlog.md
#	libs/shared/docs/behaviour-spec.mdx
This commit is contained in:
eho
2026-08-28 08:33:36 +02:00
5 changed files with 401 additions and 4 deletions
+26 -1
View File
@@ -20,7 +20,7 @@ tested where._
Every bullet below is a real test name from the suite — an `it()` title (frontend) or a test
method name (backend), read as a sentence. Nothing here is hand-written prose: this page
**is** the suite, reshaped for a business reader. 474 frontend behaviours across
**is** the suite, reshaped for a business reader. 487 frontend behaviours across
9 contexts; 261 backend behaviours across 42 test
classes.
@@ -675,6 +675,31 @@ classes.
- map only touches Success
- map2 precedence: Failure &gt; Loading &gt; Success
#### UploadShellService.cancel
- calls the transport cancel function for an in-flight upload and forgets it
- is a no-op for a localId with nothing in flight
#### UploadShellService.delete
- dispatches UploadDeleting, then UploadDeleteComplete on success
- dispatches UploadDeleteFailed with the server detail on failure
- falls back to an empty reason when the server sends no detail
#### UploadShellService.pollReturning
- does nothing when there are no uploads to poll
- dispatches BackgroundUploadsReturned for uploads the server reports complete
- does not dispatch when nothing has arrived yet
#### UploadShellService.upload
- dispatches UploadQueued with the transport backgroundSync flag, then sends via the transport
- translates a progress callback into UploadProgress
- translates a resolved transport into UploadComplete
- translates a rejected transport into UploadFailed with the reason
- does not dispatch UploadFailed on a user-initiated abort
#### authGuard
- allows an authenticated user