@@ -147,8 +147,17 @@ func TestOutputDiagnostics_PrettyFormat_WithUpstreamErrors(t *testing.T) {
147147
148148func TestOutputDiagnostics_PrettyFormat_WithOAuthRequired (t * testing.T ) {
149149 diag := map [string ]interface {}{
150- "total_issues" : 2 ,
151- "oauth_required" : []interface {}{"sentry-server" , "github-server" },
150+ "total_issues" : 2 ,
151+ "oauth_required" : []interface {}{
152+ map [string ]interface {}{
153+ "server_name" : "sentry-server" ,
154+ "message" : "Authentication required" ,
155+ },
156+ map [string ]interface {}{
157+ "server_name" : "github-server" ,
158+ "message" : "" ,
159+ },
160+ },
152161 }
153162
154163 // Capture stdout
@@ -191,9 +200,8 @@ func TestOutputDiagnostics_PrettyFormat_WithMissingSecrets(t *testing.T) {
191200 "total_issues" : 1 ,
192201 "missing_secrets" : []interface {}{
193202 map [string ]interface {}{
194- "name" : "API_KEY" ,
195- "server" : "weather-api" ,
196- "reference" : "${WEATHER_API_KEY}" ,
203+ "secret_name" : "API_KEY" ,
204+ "used_by" : []interface {}{"weather-api" },
197205 },
198206 },
199207 }
@@ -226,9 +234,6 @@ func TestOutputDiagnostics_PrettyFormat_WithMissingSecrets(t *testing.T) {
226234 if ! strings .Contains (output , "weather-api" ) {
227235 t .Error ("Missing server name" )
228236 }
229- if ! strings .Contains (output , "${WEATHER_API_KEY}" ) {
230- t .Error ("Missing secret reference" )
231- }
232237}
233238
234239func TestOutputDiagnostics_PrettyFormat_WithRuntimeWarnings (t * testing.T ) {
@@ -606,8 +611,8 @@ func TestOutputDiagnostics_SecretWithoutOptionalFields(t *testing.T) {
606611 "total_issues" : 1 ,
607612 "missing_secrets" : []interface {}{
608613 map [string ]interface {}{
609- "name " : "API_KEY" ,
610- // server and reference are optional
614+ "secret_name " : "API_KEY" ,
615+ // used_by is optional
611616 },
612617 },
613618 }
@@ -635,3 +640,49 @@ func TestOutputDiagnostics_SecretWithoutOptionalFields(t *testing.T) {
635640 t .Error ("Should display secret name even without optional fields" )
636641 }
637642}
643+
644+ // TestOutputDiagnostics_MissingSecretsRealJSON tests that the doctor command
645+ // correctly parses the actual JSON field names produced by the backend.
646+ // The MissingSecretInfo struct uses json:"secret_name" and json:"used_by",
647+ // NOT "name", "server", "reference".
648+ func TestOutputDiagnostics_MissingSecretsRealJSON (t * testing.T ) {
649+ // This is the ACTUAL JSON structure produced by the backend
650+ // (see internal/contracts/types.go MissingSecretInfo struct)
651+ diag := map [string ]interface {}{
652+ "total_issues" : 1 ,
653+ "missing_secrets" : []interface {}{
654+ map [string ]interface {}{
655+ "secret_name" : "GITHUB_TOKEN" , // NOT "name"
656+ "used_by" : []interface {}{"github-mcp" }, // NOT "server" (and it's an array)
657+ },
658+ },
659+ }
660+
661+ // Capture stdout
662+ oldStdout := os .Stdout
663+ r , w , _ := os .Pipe ()
664+ os .Stdout = w
665+ defer func () { os .Stdout = oldStdout }()
666+
667+ doctorOutput = "pretty"
668+ err := outputDiagnostics (diag , nil )
669+
670+ w .Close ()
671+ var buf bytes.Buffer
672+ buf .ReadFrom (r )
673+ output := buf .String ()
674+
675+ if err != nil {
676+ t .Errorf ("outputDiagnostics() returned error: %v" , err )
677+ }
678+
679+ // Verify the secret name is displayed
680+ if ! strings .Contains (output , "GITHUB_TOKEN" ) {
681+ t .Errorf ("Should display secret name 'GITHUB_TOKEN' from secret_name field.\n Got output:\n %s" , output )
682+ }
683+
684+ // Verify the server name is displayed
685+ if ! strings .Contains (output , "github-mcp" ) {
686+ t .Errorf ("Should display server 'github-mcp' from used_by field.\n Got output:\n %s" , output )
687+ }
688+ }
0 commit comments