Commit Graph

3 Commits

Author SHA1 Message Date
0cbe338b58 Add failing tests for the download retry policy
Tests only; the retry module they import does not exist yet, so the
branch is red at this commit.

New test/retry/retry.test.ts documents the classifier and the backoff:
which errors are worth another attempt, which are not, and how the delay
before each retry is derived. It asserts on the arguments handed to an
injected sleep function rather than on elapsed time, so the suite never
waits and the numbers are exact.

test/api/client.test.ts gains the request-count contract for each of the
six call sites, the deadline behaviour, the ApiError typing that the
presigned PUT and the null-body paths need in order to be classified at
all, and the replay rule for the two non-idempotent methods.

test/download/download.test.ts gains the case that motivates the whole
design: a socket reset after the response headers arrived, which happens
below ApiClient and can only be caught by retrying the request, the
stream consumption and the decryption together. It also pins that a
retried download stages exactly one temp file, and that the two retry
layers do not compose into a multiplied request budget. The existing
truncation tests now assert on the error type rather than its wording,
since that type is what the classifier reads.

test/thumbnails/thumbnails.test.ts separates a genuine 404 from an
exhausted retry, so a failing server can no longer make
fix-missing-thumbnails re-upload thumbnails that already exist.
2026-08-09 05:11:07 +00:00
25d3c612cf Replace sharp with jpeg-js + exif-reader; add bun compile binary
sharp was the only native dependency preventing a single-file binary.
Replaced with:
  - jpeg-js (pure JS) for JPEG decode/resize/encode in thumbnail gen
  - exif-reader (pure JS) for EXIF tag parsing
  - Raw JPEG APP1 marker extraction for EXIF segment discovery
  - Raw XMP packet extraction from file bytes

make build-bin produces a ~59MB self-contained Mach-O binary via
bun build --compile (bun installed via nix-shell). Zero runtime
dependencies. Tested: login, whoami, collections, files all work
from the compiled binary.

bin/quak.ts: init() called once at program start before commander
parses, so libsodium is ready for all commands including those that
restore sessions from disk.

118 tests pass.
2026-06-10 10:44:26 -07:00
6cb679d62f Add tests for thumbnail-helpers branch (20 new tests)
test/crypto/encrypt-blob.test.ts (8 tests):
  Round-trip with decryptBlob, zero-length payload, ciphertext
  overhead check, header size check, different keys produce different
  output, same key produces different output each call (random nonce),
  wrong-key rejection, tamper detection.

test/api/upload.test.ts (4 tests):
  putJSON sends PUT with auth headers and JSON body. putFile sends
  PUT to the exact presigned URL with Content-Type octet-stream and
  does NOT send X-Auth-Token or X-Client-Package (S3 would reject
  them). getUploadURL POSTs with contentLength and contentMD5.
  updateThumbnail PUTs to /files/thumbnail with correct body shape.

test/thumbnails/thumbnails.test.ts (8 tests):
  listMissingThumbnails identifies empty (0 byte) and 404 thumbnails
  while ignoring working ones; deduplicates across collections.
  fixMissingThumbnails verifies the full pipeline: download original,
  generate JPEG via sharp, encrypt with encryptBlob, upload via
  presigned URL, register via PUT /files/thumbnail. The test
  decrypts the uploaded ciphertext and verifies it starts with JPEG
  magic bytes (FF D8 FF). Also tests: nonexistent file ID reports
  failure without crashing; mixed success/failure across multiple
  files; Client.getApiClient() works when logged in, throws after
  logout.
2026-06-09 12:29:24 -04:00