11import { notStrictEqual , ok , strictEqual , throws } from "node:assert/strict" ;
22import { test } from "node:test" ;
3- import { createFederationDebugger } from "@fedify/debugger" ;
3+ import { createFederationDebugger , resetAutoSetup } from "@fedify/debugger" ;
44import type {
55 FederationDebuggerAuth ,
66 SerializedLogRecord ,
@@ -453,6 +453,7 @@ test("trace detail page shows empty message when no activities", async () => {
453453test ( "simplified overload returns Federation without exporter" , ( ) => {
454454 // Save original global tracer provider to restore later
455455 const originalProvider = trace . getTracerProvider ( ) ;
456+ resetAutoSetup ( ) ;
456457 try {
457458 const { federation } = createMockFederation ( ) ;
458459 const dbg = createFederationDebugger ( federation ) ;
@@ -463,12 +464,14 @@ test("simplified overload returns Federation without exporter", () => {
463464 } finally {
464465 // Restore original provider
465466 trace . setGlobalTracerProvider ( originalProvider ) ;
467+ resetAutoSetup ( ) ;
466468 }
467469} ) ;
468470
469471test ( "simplified overload registers a global TracerProvider" , ( ) => {
470472 // Disable any existing global provider first
471473 trace . disable ( ) ;
474+ resetAutoSetup ( ) ;
472475 try {
473476 const { federation } = createMockFederation ( ) ;
474477 // Before: the global provider should return a noop tracer
@@ -488,11 +491,13 @@ test("simplified overload registers a global TracerProvider", () => {
488491 span . end ( ) ;
489492 } finally {
490493 trace . disable ( ) ;
494+ resetAutoSetup ( ) ;
491495 }
492496} ) ;
493497
494498test ( "simplified overload serves debug dashboard" , async ( ) => {
495499 const originalProvider = trace . getTracerProvider ( ) ;
500+ resetAutoSetup ( ) ;
496501 try {
497502 const { federation } = createMockFederation ( ) ;
498503 const dbg = createFederationDebugger ( federation ) ;
@@ -505,11 +510,13 @@ test("simplified overload serves debug dashboard", async () => {
505510 ok ( html . includes ( "Fedify Debug Dashboard" ) ) ;
506511 } finally {
507512 trace . setGlobalTracerProvider ( originalProvider ) ;
513+ resetAutoSetup ( ) ;
508514 }
509515} ) ;
510516
511517test ( "simplified overload with custom path" , async ( ) => {
512518 const originalProvider = trace . getTracerProvider ( ) ;
519+ resetAutoSetup ( ) ;
513520 try {
514521 const { federation } = createMockFederation ( ) ;
515522 const dbg = createFederationDebugger ( federation , { path : "/_dbg" } ) ;
@@ -520,11 +527,13 @@ test("simplified overload with custom path", async () => {
520527 ok ( ct . includes ( "text/html" ) , `Expected text/html, got ${ ct } ` ) ;
521528 } finally {
522529 trace . setGlobalTracerProvider ( originalProvider ) ;
530+ resetAutoSetup ( ) ;
523531 }
524532} ) ;
525533
526534test ( "simplified overload delegates non-debug requests" , async ( ) => {
527535 const originalProvider = trace . getTracerProvider ( ) ;
536+ resetAutoSetup ( ) ;
528537 try {
529538 const { federation, calls } = createMockFederation ( ) ;
530539 const dbg = createFederationDebugger ( federation ) ;
@@ -535,11 +544,13 @@ test("simplified overload delegates non-debug requests", async () => {
535544 strictEqual ( await response . text ( ) , "Federation response" ) ;
536545 } finally {
537546 trace . setGlobalTracerProvider ( originalProvider ) ;
547+ resetAutoSetup ( ) ;
538548 }
539549} ) ;
540550
541551test ( "simplified overload JSON API returns traces" , async ( ) => {
542552 const originalProvider = trace . getTracerProvider ( ) ;
553+ resetAutoSetup ( ) ;
543554 try {
544555 const { federation } = createMockFederation ( ) ;
545556 const dbg = createFederationDebugger ( federation ) ;
@@ -555,6 +566,7 @@ test("simplified overload JSON API returns traces", async () => {
555566 strictEqual ( body . length , 0 ) ;
556567 } finally {
557568 trace . setGlobalTracerProvider ( originalProvider ) ;
569+ resetAutoSetup ( ) ;
558570 }
559571} ) ;
560572
@@ -947,6 +959,46 @@ test("auth password: forged session cookie is rejected", async () => {
947959 ok ( html . includes ( "Login Required" ) ) ;
948960} ) ;
949961
962+ // ---------- Idempotency tests ----------
963+
964+ test ( "simplified overload is idempotent: repeated calls share exporter" , async ( ) => {
965+ trace . disable ( ) ;
966+ resetAutoSetup ( ) ;
967+ try {
968+ const { federation : fed1 } = createMockFederation ( ) ;
969+ const { federation : fed2 } = createMockFederation ( ) ;
970+ // First call: sets up global OTel + exporter
971+ const dbg1 = createFederationDebugger ( fed1 ) ;
972+ // Second call: should reuse the same exporter, so both dashboards
973+ // see the same trace data
974+ const dbg2 = createFederationDebugger ( fed2 ) ;
975+ // Both should still be functional
976+ notStrictEqual ( dbg1 , null ) ;
977+ notStrictEqual ( dbg2 , null ) ;
978+ strictEqual ( typeof dbg1 . fetch , "function" ) ;
979+ strictEqual ( typeof dbg2 . fetch , "function" ) ;
980+ // Both should serve the same trace data (shared exporter)
981+ const r1 = await dbg1 . fetch (
982+ new Request ( "https://example.com/__debug__/api/traces" ) ,
983+ { contextData : undefined } ,
984+ ) ;
985+ const r2 = await dbg2 . fetch (
986+ new Request ( "https://example.com/__debug__/api/traces" ) ,
987+ { contextData : undefined } ,
988+ ) ;
989+ const t1 = await r1 . json ( ) ;
990+ const t2 = await r2 . json ( ) ;
991+ strictEqual (
992+ JSON . stringify ( t1 ) ,
993+ JSON . stringify ( t2 ) ,
994+ "Both debugger instances should share the same exporter" ,
995+ ) ;
996+ } finally {
997+ trace . disable ( ) ;
998+ resetAutoSetup ( ) ;
999+ }
1000+ } ) ;
1001+
9501002// ---------- Sink property tests ----------
9511003
9521004test ( "createFederationDebugger exposes a sink property" , ( ) => {
@@ -960,13 +1012,15 @@ test("createFederationDebugger exposes a sink property", () => {
9601012
9611013test ( "simplified overload exposes a sink property" , ( ) => {
9621014 const originalProvider = trace . getTracerProvider ( ) ;
1015+ resetAutoSetup ( ) ;
9631016 try {
9641017 const { federation } = createMockFederation ( ) ;
9651018 const dbg = createFederationDebugger ( federation ) ;
9661019 notStrictEqual ( dbg . sink , null ) ;
9671020 strictEqual ( typeof dbg . sink , "function" ) ;
9681021 } finally {
9691022 trace . setGlobalTracerProvider ( originalProvider ) ;
1023+ resetAutoSetup ( ) ;
9701024 }
9711025} ) ;
9721026
0 commit comments