@@ -1737,14 +1737,14 @@ it.layer(NodeServices.layer)("server router seam", (it) => {
17371737 ) ;
17381738
17391739 it . effect (
1740- "forwards browser OTLP traces to product analytics with Jira proof only for trusted origin" ,
1740+ "forwards browser product analytics spans with Jira proof only for trusted origin" ,
17411741 ( ) =>
17421742 Effect . gen ( function * ( ) {
17431743 const productRequests : Array < {
17441744 readonly body : string ;
17451745 readonly jiraToken : string | null ;
17461746 } > = [ ] ;
1747- const payload = yield * makeBrowserOtlpPayload ( "product.client.test " ) ;
1747+ const payload = yield * makeBrowserOtlpPayload ( "marcode.ui.composer.submit " ) ;
17481748 const collector = yield * Effect . acquireRelease (
17491749 Effect . promise ( async ( ) => {
17501750 const NodeHttp = await import ( "node:http" ) ;
@@ -1813,11 +1813,68 @@ it.layer(NodeServices.layer)("server router seam", (it) => {
18131813 assert . equal ( productRequests . length , 1 ) ;
18141814 assert . equal ( productRequests [ 0 ] ?. jiraToken , "jira-proof-token" ) ;
18151815 const forwarded = JSON . parse ( productRequests [ 0 ] ! . body ) as typeof payload ;
1816+ const forwardedSpan = forwarded . resourceSpans [ 0 ] ?. scopeSpans [ 0 ] ?. spans [ 0 ] ?. name ?? "" ;
1817+ assert . equal ( forwardedSpan , "marcode.ui.composer.submit" ) ;
18161818 const attributes = forwarded . resourceSpans [ 0 ] ?. resource ?. attributes ?? [ ] ;
18171819 assertTrue ( attributes . some ( ( attribute ) => attribute . key === "analytics.user.is_genesis" ) ) ;
18181820 } ) . pipe ( Effect . provide ( NodeHttpServer . layerTest ) ) ,
18191821 ) ;
18201822
1823+ it . effect ( "does not forward generic browser observability traces to product analytics" , ( ) =>
1824+ Effect . gen ( function * ( ) {
1825+ let productRequestCount = 0 ;
1826+ const payload = yield * makeBrowserOtlpPayload ( "RpcClient.git.listBranches" ) ;
1827+ const collector = yield * Effect . acquireRelease (
1828+ Effect . promise ( async ( ) => {
1829+ const NodeHttp = await import ( "node:http" ) ;
1830+ return await new Promise < {
1831+ readonly close : ( ) => Promise < void > ;
1832+ readonly url : string ;
1833+ } > ( ( resolve , reject ) => {
1834+ const server = NodeHttp . createServer ( ( _request , response ) => {
1835+ productRequestCount ++ ;
1836+ response . statusCode = 204 ;
1837+ response . end ( ) ;
1838+ } ) ;
1839+ server . on ( "error" , reject ) ;
1840+ server . listen ( 0 , "127.0.0.1" , ( ) => {
1841+ const address = server . address ( ) ;
1842+ if ( ! address || typeof address === "string" ) {
1843+ reject ( new Error ( "Expected TCP collector address" ) ) ;
1844+ return ;
1845+ }
1846+ resolve ( {
1847+ url : `http://127.0.0.1:${ address . port } /api/otel/traces` ,
1848+ close : ( ) =>
1849+ new Promise < void > ( ( resolveClose , rejectClose ) => {
1850+ server . close ( ( error ) => ( error ? rejectClose ( error ) : resolveClose ( ) ) ) ;
1851+ } ) ,
1852+ } ) ;
1853+ } ) ;
1854+ } ) ;
1855+ } ) ,
1856+ ( { close } ) => Effect . promise ( close ) ,
1857+ ) ;
1858+
1859+ yield * buildAppUnderTest ( {
1860+ config : {
1861+ productAnalyticsTracesUrl : collector . url ,
1862+ } ,
1863+ } ) ;
1864+
1865+ const response = yield * HttpClient . post ( "/api/observability/v1/traces" , {
1866+ headers : {
1867+ cookie : yield * getAuthenticatedSessionCookieHeader ( ) ,
1868+ "content-type" : "application/json" ,
1869+ } ,
1870+ body : HttpBody . text ( JSON . stringify ( payload ) , "application/json" ) ,
1871+ } ) ;
1872+
1873+ assert . equal ( response . status , 204 ) ;
1874+ assert . equal ( productRequestCount , 0 ) ;
1875+ } ) . pipe ( Effect . provide ( NodeHttpServer . layerTest ) ) ,
1876+ ) ;
1877+
18211878 it . effect (
18221879 "stores browser OTLP trace exports locally when no upstream collector is configured" ,
18231880 ( ) =>
0 commit comments