Sfoglia il codice sorgente

test: BUG-5 回归——api-test 语言协商用例,dashboard-test 断言转绿

- api-test:raw() 支持自定义请求头;06_auth.php 加两条 Accept-Language 用例
  (探针用错验证码换 invite,不占登录限流额度)
- dashboard-test:注册第 3 步收紧为必须显示中文;BUG-5 断言移到「回归」组保留;
  README 通过数 11/2,测试日志勾掉 BUG-5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
visuddhinanda 1 settimana fa
parent
commit
1e6c4932cf

+ 27 - 0
api-test/cases/06_auth.php

@@ -233,3 +233,30 @@ test('GET /v3/me(带 token)→ 200,不回显 token', function () {
         fail('me.data 不应回显 token(v2 auth/current 会)');
     }
 });
+
+/* ---- 语言协商(v3 按 Accept-Language 本地化 detail / errors,title 保持英文)---- */
+// 探针用「错验证码换 invite」:不写库、不发信,走 sign-up 限流(同 IP 每分钟 20 次),
+// 不占登录的「账号 + IP」额度;返回的是 messages.php 里的文案。
+
+/** 用指定 Accept-Language 发一次错验证码请求 */
+function auth_wrong_code_in(string $acceptLanguage): array
+{
+    return raw('POST', '/v3/invites', null, [
+        'email' => auth_unregistered_email(),
+        'code' => '000000',
+    ], null, ['Accept-Language' => $acceptLanguage]);
+}
+
+test('Accept-Language: zh-Hans → 中文错误文案 + Content-Language', function () {
+    $res = auth_wrong_code_in('zh-Hans');
+    assert_field_error('code', $res, 'invites 错验证码(zh-Hans)');
+    assert_eq('验证码不正确或已过期。', $res['body']['errors']['code'][0] ?? null, 'errors.code');
+    assert_eq('zh-Hans', $res['headers']['Content-Language'][0] ?? null, 'Content-Language');
+});
+
+test('Accept-Language: zh-TW → 繁体;不支持的语言 → en', function () {
+    $hant = auth_wrong_code_in('zh-TW');
+    assert_eq('驗證碼不正確或已過期。', $hant['body']['errors']['code'][0] ?? null, 'zh-TW 的 errors.code');
+    $fr = auth_wrong_code_in('fr-FR');
+    assert_eq('en', $fr['headers']['Content-Language'][0] ?? null, 'fr-FR 的 Content-Language');
+});

+ 2 - 2
api-test/src/bootstrap.php

@@ -97,10 +97,10 @@ function request(callable $fn): array
  * 原始 HTTP 请求:绕过生成客户端的必填参数校验,用于「缺参/非法组合」这类负向用例。
  * $path 以 / 开头(如 /v3/reactions),base URL 已含 /api 前缀。
  */
-function raw(string $method, string $path, ?array $query = null, ?array $json = null, ?string $token = null): array
+function raw(string $method, string $path, ?array $query = null, ?array $json = null, ?string $token = null, array $headers = []): array
 {
     $http = new Client(['timeout' => config()['timeout'], 'http_errors' => false]);
-    $opts = ['headers' => []];
+    $opts = ['headers' => $headers];
     if ($query !== null) {
         $opts['query'] = $query;
     }

+ 3 - 4
dashboard-test/README.md

@@ -116,11 +116,10 @@ dashboard-test/
 - BUG-1 Webhooks 页签不应跳到已废弃的 `/studio/...`
 - BUG-4 不存在的频道不应出现 `Unexpected Application Error`
 
-`src/tests/users.spec.ts` 有一条:
+所以 `npm test` 现在是 **11 通过 / 2 失败**(channel 4/2、users 7/0),两个失败即上述待修项。
 
-- BUG-5 中文界面下 v3 接口的错误文案应为中文(目前 api 组没有语言协商,总是英文)
-
-所以 `npm test` 现在是 **10 通过 / 3 失败**(channel 4/2、users 6/1),三个失败即上述待修项。
+修复后的缺陷断言保留作回归保护:`src/tests/users.spec.ts` 的「回归」组里有
+BUG-5(中文界面下 v3 错误文案应为中文,2026-10-08 修复)。
 
 ### 限流
 

+ 3 - 1
dashboard-test/documents/testlog/users_20261008_072502.md

@@ -65,7 +65,9 @@
 
 ## 二、待修复
 
-- [ ] **BUG-5 v3 接口的错误文案没有本地化,中文界面里显示英文**
+- [x] **BUG-5 v3 接口的错误文案没有本地化,中文界面里显示英文**(同日修复:后端 v3 路由组挂
+  `V3\NegotiateLocale` 按 Accept-Language 选语言,`client.ts` 按界面语言带上这个头;
+  复跑 `npm run test:users` 7/7 通过,断言移到「回归」组保留)
 
   ```text
   Expected: "验证码不正确或已过期。"

+ 8 - 10
dashboard-test/src/tests/users.spec.ts

@@ -109,11 +109,9 @@ test.describe('自助注册 /anonymous/sign-up', () => {
       // 没有真的发过码,服务端 Cache 里查不到 → 必然 422 errors.code,不写库
       await page.getByPlaceholder('请输入邮件里的 6 位验证码').fill('000000');
       await page.getByRole('button', { name: '下一步' }).click();
-      // 文案语言不在这里断言:v3 的错误文案目前总是英文,见下面 BUG-5
+      // 中文界面 → 后端按 Accept-Language 返回中文(BUG-5 已修复)
       await expect(
-        page.locator('.ant-form-item-explain-error', {
-          hasText: /验证码不正确或已过期|verification code is incorrect/,
-        })
+        page.locator('.ant-form-item-explain-error', { hasText: '验证码不正确或已过期' })
       ).toBeVisible();
       await shot(page, '03-signup-wrong-code');
       log.dump('3. 错误验证码(预期 HTTP 422)');
@@ -413,14 +411,14 @@ test.describe('登录 /anonymous/sign-in', () => {
   });
 });
 
-test.describe('已知缺陷', () => {
+test.describe('回归', () => {
   /**
-   * BUG-5 v3 接口的错误文案没有本地化:中文界面里显示英文。
+   * BUG-5(2026-10-08 发现并修复)v3 接口的错误文案没有本地化:中文界面里显示英文。
    *
-   * 后端 `SetLocale` 中间件只挂在 web 组,api 组没有语言协商,`__()` 永远取 en
-   * (v3-resource skill 第 11 条已记录)。前端 `src/api/client.ts` 也没有把界面语言
-   * 告诉后端。修复需要两边一起:v3 路由组挂语言协商 + client 中间件带上界面语言。
-   * 修复前保持红灯。
+   * 原因:api 组没有语言协商,`__()` 永远取 en;前端也没把界面语言告诉后端。
+   * 修复:后端 v3 路由组挂 `V3\NegotiateLocale`(只读 Accept-Language),
+   * dashboard-v6 `src/api/client.ts` 按界面语言设置 Accept-Language。
+   * 这条断言保留作回归保护。
    */
   test('BUG-5 中文界面下,v3 的字段错误应为中文', async ({ page }) => {
     await page.goto('anonymous/sign-up', { waitUntil: 'networkidle' });