11import type { Mock } from 'vitest' ;
22import { afterEach , describe , expect , it , vi } from 'vitest' ;
33
4+ // eslint-disable-next-line import/first
5+ import { getActiveTraceId , injectSpanTraceHeaders } from './traceparent' ;
6+
47vi . mock ( '@lobechat/observability-otel/api' , ( ) => {
58 const inject = vi . fn ( ) ;
69 const setSpan = vi . fn ( ( _ctx , span ) => span ) ;
10+ const getActiveSpan = vi . fn ( ) ;
711
812 return {
913 context : {
1014 active : vi . fn ( ( ) => ( { } ) ) ,
1115 } ,
1216 propagation : { inject } ,
13- trace : { setSpan } ,
17+ trace : { getActiveSpan , setSpan } ,
1418 } ;
1519} ) ;
1620
17- // eslint-disable-next-line import/first
18- import { injectSpanTraceHeaders } from './traceparent' ;
19-
2021const mockSpan = ( traceId : string , spanId : string ) =>
2122 ( {
2223 spanContext : ( ) => ( {
@@ -39,7 +40,9 @@ describe('injectSpanTraceHeaders', () => {
3940
4041 it ( 'uses propagator output when available' , async ( ) => {
4142 const { propagation } = await api ;
42- ( propagation . inject as unknown as Mock < typeof propagation . inject < Record < string , string > > > ) . mockImplementation ( ( _ctx , carrier ) => {
43+ (
44+ propagation . inject as unknown as Mock < typeof propagation . inject < Record < string , string > > >
45+ ) . mockImplementation ( ( _ctx , carrier ) => {
4346 carrier . traceparent = 'from-propagator' ;
4447 carrier . tracestate = 'state' ;
4548 } ) ;
@@ -56,14 +59,50 @@ describe('injectSpanTraceHeaders', () => {
5659
5760 it ( 'falls back to manual traceparent formatting when propagator gives none' , async ( ) => {
5861 const { propagation } = await api ;
59- ( propagation . inject as unknown as Mock < typeof propagation . inject < Record < string , string > > > ) . mockImplementation ( ( ) => undefined ) ;
62+ (
63+ propagation . inject as unknown as Mock < typeof propagation . inject < Record < string , string > > >
64+ ) . mockImplementation ( ( ) => undefined ) ;
6065
6166 const headers = headersWith ( ) ;
6267 const span = mockSpan ( '1' . repeat ( 32 ) , '2' . repeat ( 16 ) ) ;
6368
6469 const tp = injectSpanTraceHeaders ( headers , span ) ;
6570
6671 expect ( tp ) . toBe ( '00-11111111111111111111111111111111-2222222222222222-01' ) ;
67- expect ( headers . get ( 'traceparent' ) ) . toBe ( '00-11111111111111111111111111111111-2222222222222222-01' ) ;
72+ expect ( headers . get ( 'traceparent' ) ) . toBe (
73+ '00-11111111111111111111111111111111-2222222222222222-01' ,
74+ ) ;
75+ } ) ;
76+ } ) ;
77+
78+ describe ( 'getActiveTraceId' , ( ) => {
79+ const api = vi . importMock < typeof import ( '@lobechat/observability-otel/api' ) > (
80+ '@lobechat/observability-otel/api' ,
81+ ) ;
82+
83+ afterEach ( ( ) => {
84+ vi . resetAllMocks ( ) ;
85+ } ) ;
86+
87+ it ( 'returns traceId from active span' , async ( ) => {
88+ const { trace } = await api ;
89+ const expectedTraceId = 'a' . repeat ( 32 ) ;
90+ ( trace . getActiveSpan as Mock ) . mockReturnValue ( mockSpan ( expectedTraceId , 'b' . repeat ( 16 ) ) ) ;
91+
92+ expect ( getActiveTraceId ( ) ) . toBe ( expectedTraceId ) ;
93+ } ) ;
94+
95+ it ( 'returns undefined when no active span' , async ( ) => {
96+ const { trace } = await api ;
97+ ( trace . getActiveSpan as Mock ) . mockReturnValue ( undefined ) ;
98+
99+ expect ( getActiveTraceId ( ) ) . toBeUndefined ( ) ;
100+ } ) ;
101+
102+ it ( 'returns undefined when traceId is all zeros' , async ( ) => {
103+ const { trace } = await api ;
104+ ( trace . getActiveSpan as Mock ) . mockReturnValue ( mockSpan ( '0' . repeat ( 32 ) , 'b' . repeat ( 16 ) ) ) ;
105+
106+ expect ( getActiveTraceId ( ) ) . toBeUndefined ( ) ;
68107 } ) ;
69108} ) ;
0 commit comments