Files
yushen 20ab324237 MUL-2976: resolve composer file chip downloadUrl before Linking.openURL
Last relative-URL hole flagged in re-review of PR #3747. `api.uploadFile`
returns a non-CloudFront `download_url` like `/api/attachments/{id}/download`
which the composer's completed non-image chip handed straight to RN's
`Linking.openURL` — iOS rejects relative URLs ("Cannot open URL"), so the
tap was silently dropped.

- apps/mobile/components/issue/composer-attachment-row.tsx: wrap
  `item.downloadUrl` with `resolveAttachmentUrl` before `Linking.openURL`,
  matching what comment-attachment-list.tsx and markdown-image.tsx already
  do. Falls through to a no-op when the helper returns null.

- apps/mobile/lib/attachment-url.test.ts (new): pure-function tests for
  `resolveAttachmentUrlWithBase` — relative→absolute, trailing slash trim,
  absolute (CloudFront / http) pass-through, null/undefined/empty,
  empty-base keep-as-is. New "composer file chip — completed non-image
  attachment" describe block pins the specific path the reviewer flagged
  (relative downloadUrl → absolute, absolute downloadUrl unchanged,
  undefined downloadUrl → null no-op).

- apps/mobile/vitest.config.ts (new): minimal Node-environment vitest
  scoped to `lib/**/*.test.ts`. Mobile only runs pure-function tests
  here — RN component rendering is intentionally not part of this lane.

- apps/mobile/package.json: add `test` script and `vitest` from the
  workspace catalog.

- .github/workflows/mobile-verify.yml: extend the turbo invocation to
  `typecheck lint test` so the new suite runs on every mobile PR; update
  the doc comment to reflect that mobile now has a (narrow) vitest suite.

Verified locally: pnpm -C apps/mobile run test (11 cases pass),
typecheck + lint clean, pnpm exec turbo typecheck lint test
--filter=@multica/mobile (4 successful tasks, mirrors CI command),
pnpm -C packages/views run typecheck still clean.

Co-authored-by: multica-agent <github@multica.ai>
2026-06-04 14:10:51 +08:00
..
2026-06-04 13:36:34 +08:00