Skip to content

fix(attachments): normalize attachment list handling and add test cases - #334

Merged
hexqi merged 3 commits into
opentiny:developfrom
SonyLeo:fix/attachments-normalize
Apr 29, 2026
Merged

fix(attachments): normalize attachment list handling and add test cases#334
hexqi merged 3 commits into
opentiny:developfrom
SonyLeo:fix/attachments-normalize

Conversation

@SonyLeo

@SonyLeo SonyLeo commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator

问题

normalizeAttachments 在处理输入数据时存在两个缺陷:

  1. 缺少兜底分支items.map() 回调只处理了 isUrlSizeItem(有 url + size)和 isRawFileItem(有 rawFile)两种情况,不符合任一条件的 item 返回 undefined,被 as Attachment[] 强转掩盖。
  2. isUrlSizeItem 判定过严:要求 typeof item.size === 'number',导致只传 url 不传 size 的远程附件(这是合理的使用方式)无法被识别,落入无人处理的分支变成 undefined

此外,watchif (newItems && newItems.length > 0) 的守卫导致父组件清空 itemsfileList 不会同步清空。

改动

commit 1 5f5c01bd — 核心修复(5 个文件)

useFileType.ts

  • map 改为 reduce,只有匹配到的 item 才 push 进结果,不匹配的跳过而非返回 undefined
  • isRawFileItem 判定优先于 isUrlItem(有 rawFile 的即使同时带 url 也走本地文件路径)
  • isUrlItem 去掉 size 的强制要求,只要有 url 即可
  • transformUrlItem 中:用 getUrlDisplayName(url) 替代简单的 url.split('/').pop(),支持从 query 参数提取文件名;item.fileType ?? inferredFileType 尊重用户显式传入的 fileType
  • transformRawFileItem 中:item.fileType ?? detectFileType(rawFile) 同样尊重用户传入值;item.size ?? rawFile.size?? 替代 ||

index.type.ts + docs/src/components/attachments.md

  • UrlAttachment.sizenumber 改为 number?,类型与逻辑对齐

index.vue

  • watch 中去掉 newItems.length > 0 守卫,改为 normalizeAttachments(newItems || []),父组件清空时同步清空

utils.ts(新增):

  • getStringDetectionCandidates:为 URL 字符串生成多个候选值(原始值、query 参数中的 filename、pathname、最后一段路径),供 detectFileType 逐一匹配
  • getUrlDisplayName:从 URL 中提取人类可读的文件名,优先级为 query 参数 > 最后一段路径 > 完整路径
  • 支持绝对 URL、协议相对 URL、带 hash/query 的路径等多种格式

commit 2 f39c9c6f — E2E 测试(4 个文件)

  • 新增 packages/test/src/attachments/index.vue 测试页面,覆盖 7 种数据输入场景
  • 新增 packages/test/src/attachments/index.spec.ts,8 个 Playwright 测试用例
  • 注册到测试应用路由

测试覆盖

用例 验证点
仅传 url 无 size 的远程附件 issue 核心场景,修复前为 undefined
显式 fileType 保留 item.fileType ?? inferred 不覆盖用户值
name 优先于无后缀 URL 推断类型 name 有后缀时优先用 name 推断
query filename 参数提取 ?filename=report.pdf 正确提取
带 query + hash 的资源 URL image.png?token=1#viewer 正确解析
rawFile 全量字段优先按 rawFile 识别 rawFile 路径优先于 url 路径
rawFile + 预览 url 保留本地文件信息 有 rawFile 时 name 取自 rawFile
父级清空 items 同步清空列表 watch 守卫修复验证

Summary by CodeRabbit

  • Bug Fixes

    • Fixed issue where clearing attachment items failed to properly update the displayed list.
  • New Features

    • Made file size an optional property for URL-based attachments, allowing leaner attachment configurations.
    • Enhanced automatic detection of file types from both uploaded files and URLs with intelligent fallback inference.
    • Improved extraction of display names from URL query parameters and file path segments.

@coderabbitai

coderabbitai Bot commented Apr 28, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@SonyLeo has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 44 minutes and 14 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d5d48607-7cf6-47b3-ac9d-129a3bf824f5

📥 Commits

Reviewing files that changed from the base of the PR and between f39c9c6 and 78843bd.

📒 Files selected for processing (2)
  • packages/components/src/attachments/utils.ts
  • packages/test/src/attachments/index.spec.ts

Walkthrough

Updates make UrlAttachment.size optional, add URL/name parsing utilities, refine file-type detection and URL normalization, and change the items watcher to always recompute the file list. New test pages and Playwright specs validate multiple attachment scenarios. Documentation reflects the optional size change.

Changes

Cohort / File(s) Summary
Documentation
docs/src/components/attachments.md
Updates type example: UrlAttachment.size from required to optional.
Attachments Types
packages/components/src/attachments/index.type.ts
Makes size optional on UrlAttachment interface.
Attachments Core Logic
packages/components/src/attachments/composables/useFileType.ts, packages/components/src/attachments/utils.ts, packages/components/src/attachments/index.vue
Enhances file/URL type detection with string candidates and display-name derivation; adds URL parsing/name utilities; watcher now always normalizes items (clears on empty/undefined).
Test Harness App
packages/test/src/App.vue, packages/test/src/home/index.vue
Adds Attachments route, import, and menu entry for manual/testing navigation.
Attachments Test Pages
packages/test/src/attachments/index.vue, packages/test/src/attachments/index.spec.ts
Introduces test page and Playwright specs covering URL-only, explicit fileType, name precedence, query/hash parsing, rawFile priority, preview handling, and clearing state.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

I twitch my ears at links that gleam,
Names from paths—what a tasty theme! 🥕
Sizes optional, neat and small,
Types inferred—I sniff them all.
Click to clear, the list goes light—
Hop, hop, tests pass in moonlit night. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately describes the main changes: normalizing attachment list handling (making size optional, updating watcher logic) and adding comprehensive test cases for the attachments component.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 44 minutes and 14 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@SonyLeo SonyLeo changed the title fix(Attachments): optimize attachment component rendering logic and add test cases fix(attachments): optimize attachment component rendering logic and add test cases Apr 28, 2026
@github-actions

github-actions Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

✅ Preview build completed successfully!

Click the image above to preview.
Preview will be automatically removed when this PR is closed.

@github-actions

github-actions Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

@SonyLeo SonyLeo linked an issue Apr 29, 2026 that may be closed by this pull request
@SonyLeo
SonyLeo force-pushed the fix/attachments-normalize branch from f235e9c to f39c9c6 Compare April 29, 2026 01:41
@SonyLeo
SonyLeo marked this pull request as ready for review April 29, 2026 03:22

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/test/src/attachments/index.spec.ts (1)

69-75: Add an explicit undefined-items clearing test

Lines 69-75 validate clearing to empty, but this PR also touches behavior when items becomes undefined. Adding that case would lock down the watcher change and prevent regressions.

Suggested additional test
test('父级将 items 置为 undefined 后应同步清空附件列表', async ({ page }) => {
  const section = page.locator('[data-testid="url-only-section"]')

  await expect(section.locator('.tr-file-card')).toHaveCount(1)
  await page.getByTestId('url-only-set-undefined').click() // add control in test page if missing
  await expect(section.locator('.tr-file-card')).toHaveCount(0)
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/test/src/attachments/index.spec.ts` around lines 69 - 75, Add a new
Playwright test that mirrors the existing empty-clear case but sets the parent
`items` to undefined and asserts attachments are cleared: create a test named
like '父级将 items 置为 undefined 后应同步清空附件列表' that queries the same section locator
'[data-testid="url-only-section"]', asserts the initial `.tr-file-card` count is
1, clicks a control with test id 'url-only-set-undefined' (add that control to
the test page if it doesn't exist), then asserts `.tr-file-card` count is 0 to
lock down watcher behavior when `items` becomes undefined.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/components/src/attachments/utils.ts`:
- Line 1: The FILE_NAME_QUERY_KEYS array currently includes the generic key
'name' which causes functions like getStringDetectionCandidates() and
getUrlDisplayName() to treat query params such as ?name=alice as filenames;
remove 'name' from FILE_NAME_QUERY_KEYS so it only contains 'filename' and
'fileName' (i.e., update the const FILE_NAME_QUERY_KEYS to exclude 'name') and
run/update any tests relying on the broader behavior; references to
FILE_NAME_QUERY_KEYS in getStringDetectionCandidates() and getUrlDisplayName()
will then correctly prefer path-based filenames or explicit filename keys.

In `@packages/test/src/attachments/index.spec.ts`:
- Around line 4-8: The setup uses a broad h2 locator in test.beforeEach which
can match unrelated headings; tighten the assertion by targeting the specific
heading text or role—replace the
expect(page.locator('h2')).toContainText('Attachments 组件测试') with a more
specific locator (e.g., getByRole('heading' with name "Attachments 组件测试" and
level 2, or a locator scoped under the panel opened by
page.click('text=Attachments 组件')) so the test.beforeEach reliably asserts the
intended heading.

---

Nitpick comments:
In `@packages/test/src/attachments/index.spec.ts`:
- Around line 69-75: Add a new Playwright test that mirrors the existing
empty-clear case but sets the parent `items` to undefined and asserts
attachments are cleared: create a test named like '父级将 items 置为 undefined
后应同步清空附件列表' that queries the same section locator
'[data-testid="url-only-section"]', asserts the initial `.tr-file-card` count is
1, clicks a control with test id 'url-only-set-undefined' (add that control to
the test page if it doesn't exist), then asserts `.tr-file-card` count is 0 to
lock down watcher behavior when `items` becomes undefined.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: edc3ee7c-511d-4330-b65c-b0fbfcd78fac

📥 Commits

Reviewing files that changed from the base of the PR and between 5bc319a and f39c9c6.

📒 Files selected for processing (9)
  • docs/src/components/attachments.md
  • packages/components/src/attachments/composables/useFileType.ts
  • packages/components/src/attachments/index.type.ts
  • packages/components/src/attachments/index.vue
  • packages/components/src/attachments/utils.ts
  • packages/test/src/App.vue
  • packages/test/src/attachments/index.spec.ts
  • packages/test/src/attachments/index.vue
  • packages/test/src/home/index.vue

Comment thread packages/components/src/attachments/utils.ts Outdated
Comment thread packages/test/src/attachments/index.spec.ts
@SonyLeo SonyLeo changed the title fix(attachments): optimize attachment component rendering logic and add test cases fix(attachments): normalize attachment list handling and add test cases Apr 29, 2026
@hexqi
hexqi merged commit ed36cb6 into opentiny:develop Apr 29, 2026
4 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🧹 Preview Cleaned Up

The preview deployment has been removed.

@SonyLeo
SonyLeo deleted the fix/attachments-normalize branch April 30, 2026 01:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 [Bug]: 附件组件的数据格式问题

2 participants