diff --git a/test/integration/proxy.test.ts b/test/integration/proxy.test.ts index f254d57..4ee2dca 100644 --- a/test/integration/proxy.test.ts +++ b/test/integration/proxy.test.ts @@ -13,7 +13,9 @@ vi.hoisted(() => { }); let downstream: ReturnType; -let captured: { auth?: string; fake?: string; path?: string; method?: string; body?: string } = {}; +let captured: { + auth?: string; fake?: string; path?: string; method?: string; body?: string; trace?: string; +} = {}; /** 主机保全见证:只有真打到"配置的下游"这台服务的请求才会记进来(C1 回归用) */ const hits: string[] = []; @@ -41,6 +43,7 @@ describe('gateway proxy', () => { path: c.req.path, method: c.req.method, body: await c.req.text(), + trace: c.req.header('traceparent') ?? '', }; return c.json({ from: 'downstream' }); }); @@ -114,6 +117,25 @@ describe('gateway proxy', () => { } }); + // 网关是外部请求的第一跳:缺 traceparent 补发一条,已有的绝不覆盖。 + // 两条断言互为反向:去掉注入那行 → 第一条红;把 `!` 去掉(无条件 set)→ 第二条红。 + it('traceparent:缺则补发合法形状,已有则原样透传不覆盖', async () => { + captured = {}; + const injected = await buildApp().request('/api/task/task/t-1/view', { + headers: { authorization: `Bearer ${token}` }, + }); + expect(injected.status).toBe(200); + expect(captured.trace).toMatch(/^00-[0-9a-f]{32}-[0-9a-f]{16}-01$/); + + captured = {}; + const mine = '00-0123456789abcdef0123456789abcdef-89abcdef01234567-01'; + const passed = await buildApp().request('/api/task/task/t-1/view', { + headers: { authorization: `Bearer ${token}`, traceparent: mine }, + }); + expect(passed.status).toBe(200); + expect(captured.trace).toBe(mine); // 覆盖=把上游已开好的链从中间截断 + }); + it('下游 gzip 响应:解码后的 body 不得再带 content-encoding(D9)', async () => { const res = await buildApp().request('/api/task/gzip', { headers: { authorization: `Bearer ${token}` },