@@ -196,6 +196,70 @@ public void GenerateDocument_AddsSecuritySchemes_WhenAuthorizedHubExistsAndSchem
196196 Assert . AreEqual ( SecuritySchemeType . Http , doc . Components . SecuritySchemes [ "Bearer" ] . Type ) ;
197197 }
198198
199+ /// <summary>
200+ /// Verifies that apiKey security schemes added via SecuritySchemes are emitted
201+ /// in the document's components when an authorized hub exists.
202+ /// </summary>
203+ [ TestMethod ]
204+ public void GenerateDocument_AddsApiKeySecurityScheme_WhenConfiguredViaSecuritySchemes ( )
205+ {
206+ var ( discoverer , generator ) = CreateServices ( o =>
207+ {
208+ o . SecuritySchemes [ "Impersonation" ] = new OpenApiSecurityScheme
209+ {
210+ Type = SecuritySchemeType . ApiKey ,
211+ In = ParameterLocation . Header ,
212+ Name = "X-Session-Id" ,
213+ Description = "Session ID for impersonation." ,
214+ } ;
215+ } ) ;
216+
217+ var hubs = discoverer . DiscoverHubs ( ) ;
218+ var doc = generator . GenerateDocument ( hubs ) ;
219+
220+ Assert . IsNotNull ( doc . Components . SecuritySchemes ) ;
221+ Assert . IsTrue ( doc . Components . SecuritySchemes . ContainsKey ( "Impersonation" ) ) ;
222+
223+ var scheme = doc . Components . SecuritySchemes [ "Impersonation" ] ;
224+ Assert . AreEqual ( SecuritySchemeType . ApiKey , scheme . Type ) ;
225+ Assert . AreEqual ( ParameterLocation . Header , scheme . In ) ;
226+ Assert . AreEqual ( "X-Session-Id" , scheme . Name ) ;
227+ Assert . AreEqual ( "Session ID for impersonation." , scheme . Description ) ;
228+ }
229+
230+ /// <summary>
231+ /// Verifies that both apiKey and HTTP Bearer security schemes can coexist
232+ /// in the document when configured via SecuritySchemes.
233+ /// </summary>
234+ [ TestMethod ]
235+ public void GenerateDocument_AddsMixedSecuritySchemes_WhenBothApiKeyAndBearerConfigured ( )
236+ {
237+ var ( discoverer , generator ) = CreateServices ( o =>
238+ {
239+ o . SecuritySchemes [ "Bearer" ] = new OpenApiSecurityScheme
240+ {
241+ Type = SecuritySchemeType . Http ,
242+ Scheme = "bearer" ,
243+ BearerFormat = "JWT" ,
244+ } ;
245+ o . SecuritySchemes [ "Impersonation" ] = new OpenApiSecurityScheme
246+ {
247+ Type = SecuritySchemeType . ApiKey ,
248+ In = ParameterLocation . Header ,
249+ Name = "X-Session-Id" ,
250+ Description = "Session ID for impersonation." ,
251+ } ;
252+ } ) ;
253+
254+ var hubs = discoverer . DiscoverHubs ( ) ;
255+ var doc = generator . GenerateDocument ( hubs ) ;
256+
257+ Assert . IsNotNull ( doc . Components . SecuritySchemes ) ;
258+ Assert . AreEqual ( 2 , doc . Components . SecuritySchemes . Count ) ;
259+ Assert . IsTrue ( doc . Components . SecuritySchemes . ContainsKey ( "Bearer" ) ) ;
260+ Assert . IsTrue ( doc . Components . SecuritySchemes . ContainsKey ( "Impersonation" ) ) ;
261+ }
262+
199263 /// <summary>
200264 /// Verifies no security schemes are added when authorized hubs exist but no schemes are configured.
201265 /// </summary>
@@ -300,6 +364,42 @@ public void GenerateDocument_SetsSecurityOnAuthorizedMethods()
300364 Assert . IsTrue ( getUser . Security . Count > 0 ) ;
301365 }
302366
367+ /// <summary>
368+ /// Verifies security requirements reference all configured schemes including apiKey.
369+ /// </summary>
370+ [ TestMethod ]
371+ public void GenerateDocument_SecurityRequirementsIncludeApiKeyScheme ( )
372+ {
373+ var ( discoverer , generator ) = CreateServices ( o =>
374+ {
375+ o . SecuritySchemes [ "Bearer" ] = new OpenApiSecurityScheme
376+ {
377+ Type = SecuritySchemeType . Http ,
378+ Scheme = "bearer" ,
379+ } ;
380+ o . SecuritySchemes [ "Impersonation" ] = new OpenApiSecurityScheme
381+ {
382+ Type = SecuritySchemeType . ApiKey ,
383+ In = ParameterLocation . Header ,
384+ Name = "X-Session-Id" ,
385+ } ;
386+ } ) ;
387+
388+ var hubs = discoverer . DiscoverHubs ( ) ;
389+ var doc = generator . GenerateDocument ( hubs ) ;
390+
391+ var getUser = doc . Paths [ "/hubs/Attribute/GetUserDetails" ]
392+ . Operations [ Microsoft . OpenApi . Models . OperationType . Post ] ;
393+
394+ Assert . IsNotNull ( getUser . Security ) ;
395+ Assert . AreEqual ( 1 , getUser . Security . Count , "Should have one security requirement." ) ;
396+
397+ var requirement = getUser . Security [ 0 ] ;
398+ var schemeIds = requirement . Keys . Select ( k => k . Reference . Id ) . ToList ( ) ;
399+ CollectionAssert . Contains ( schemeIds , "Bearer" , "Should reference Bearer scheme." ) ;
400+ CollectionAssert . Contains ( schemeIds , "Impersonation" , "Should reference Impersonation scheme." ) ;
401+ }
402+
303403 /// <summary>
304404 /// Verifies data annotations are applied to schemas.
305405 /// </summary>
0 commit comments