@@ -26,6 +26,16 @@ public class OpenApiTagTests
2626 }
2727 } ;
2828
29+ public static readonly OpenApiTag TagWithV32Properties = new ( )
30+ {
31+ Name = "store" ,
32+ Description = "Store operations" ,
33+ Summary = "Operations related to the pet store" ,
34+ Parent = new OpenApiTagReference ( "pet" ) ,
35+ Kind = "operational" ,
36+ ExternalDocs = OpenApiExternalDocsTests . AdvanceExDocs
37+ } ;
38+
2939 public static IOpenApiTag ReferencedTag = new OpenApiTagReference ( "pet" ) ;
3040
3141 [ Theory ]
@@ -310,5 +320,269 @@ public async Task SerializeReferencedTagAsV2YamlWorks()
310320 expected = expected . MakeLineBreaksEnvironmentNeutral ( ) ;
311321 Assert . Equal ( expected , actual ) ;
312322 }
323+
324+ // Tests for V3.2 properties in V3.1 serialization (using extension format)
325+ [ Theory ]
326+ [ InlineData ( true ) ]
327+ [ InlineData ( false ) ]
328+ public async Task SerializeTagWithV32PropertiesAsV31JsonWorksAsync ( bool produceTerseOutput )
329+ {
330+ // Arrange
331+ var outputStringWriter = new StringWriter ( CultureInfo . InvariantCulture ) ;
332+ var writer = new OpenApiJsonWriter ( outputStringWriter , new ( ) { Terse = produceTerseOutput } ) ;
333+
334+ // Act
335+ TagWithV32Properties . SerializeAsV31 ( writer ) ;
336+ await writer . FlushAsync ( ) ;
337+
338+ // Assert
339+ await Verifier . Verify ( outputStringWriter ) . UseParameters ( produceTerseOutput ) ;
340+ }
341+
342+ [ Fact ]
343+ public async Task SerializeTagWithV32PropertiesAsV31YamlWorks ( )
344+ {
345+ // Arrange
346+ var outputStringWriter = new StringWriter ( CultureInfo . InvariantCulture ) ;
347+ var writer = new OpenApiYamlWriter ( outputStringWriter ) ;
348+ var expected = @"name: store
349+ description: Store operations
350+ externalDocs:
351+ description: Find more info here
352+ url: https://example.com
353+ x-oas-summary: Operations related to the pet store
354+ x-oas-parent: pet
355+ x-oas-kind: operational" ;
356+
357+ // Act
358+ TagWithV32Properties . SerializeAsV31 ( writer ) ;
359+ await writer . FlushAsync ( ) ;
360+ var actual = outputStringWriter . GetStringBuilder ( ) . ToString ( ) ;
361+
362+ // Assert
363+ actual = actual . MakeLineBreaksEnvironmentNeutral ( ) ;
364+ expected = expected . MakeLineBreaksEnvironmentNeutral ( ) ;
365+ Assert . Equal ( expected , actual ) ;
366+ }
367+
368+ // Tests for V3.2 properties in V3.2 serialization (using native format)
369+ [ Theory ]
370+ [ InlineData ( true ) ]
371+ [ InlineData ( false ) ]
372+ public async Task SerializeTagWithV32PropertiesAsV32JsonWorksAsync ( bool produceTerseOutput )
373+ {
374+ // Arrange
375+ var outputStringWriter = new StringWriter ( CultureInfo . InvariantCulture ) ;
376+ var writer = new OpenApiJsonWriter ( outputStringWriter , new ( ) { Terse = produceTerseOutput } ) ;
377+
378+ // Act
379+ TagWithV32Properties . SerializeAsV32 ( writer ) ;
380+ await writer . FlushAsync ( ) ;
381+
382+ // Assert
383+ await Verifier . Verify ( outputStringWriter ) . UseParameters ( produceTerseOutput ) ;
384+ }
385+
386+ [ Fact ]
387+ public async Task SerializeTagWithV32PropertiesAsV32YamlWorks ( )
388+ {
389+ // Arrange
390+ var outputStringWriter = new StringWriter ( CultureInfo . InvariantCulture ) ;
391+ var writer = new OpenApiYamlWriter ( outputStringWriter ) ;
392+ var expected = @"name: store
393+ description: Store operations
394+ externalDocs:
395+ description: Find more info here
396+ url: https://example.com
397+ summary: Operations related to the pet store
398+ parent: pet
399+ kind: operational" ;
400+
401+ // Act
402+ TagWithV32Properties . SerializeAsV32 ( writer ) ;
403+ await writer . FlushAsync ( ) ;
404+ var actual = outputStringWriter . GetStringBuilder ( ) . ToString ( ) ;
405+
406+ // Assert
407+ actual = actual . MakeLineBreaksEnvironmentNeutral ( ) ;
408+ expected = expected . MakeLineBreaksEnvironmentNeutral ( ) ;
409+ Assert . Equal ( expected , actual ) ;
410+ }
411+
412+ // Test for V3.0 serialization with V3.2 properties (should use extension format)
413+ [ Fact ]
414+ public async Task SerializeTagWithV32PropertiesAsV3YamlWorks ( )
415+ {
416+ // Arrange
417+ var outputStringWriter = new StringWriter ( CultureInfo . InvariantCulture ) ;
418+ var writer = new OpenApiYamlWriter ( outputStringWriter ) ;
419+ var expected = @"name: store
420+ description: Store operations
421+ externalDocs:
422+ description: Find more info here
423+ url: https://example.com
424+ x-oas-summary: Operations related to the pet store
425+ x-oas-parent: pet
426+ x-oas-kind: operational" ;
427+
428+ // Act
429+ TagWithV32Properties . SerializeAsV3 ( writer ) ;
430+ await writer . FlushAsync ( ) ;
431+ var actual = outputStringWriter . GetStringBuilder ( ) . ToString ( ) ;
432+
433+ // Assert
434+ actual = actual . MakeLineBreaksEnvironmentNeutral ( ) ;
435+ expected = expected . MakeLineBreaksEnvironmentNeutral ( ) ;
436+ Assert . Equal ( expected , actual ) ;
437+ }
438+
439+ // Tests for individual V3.2 properties
440+ [ Fact ]
441+ public void TagWithSummaryPropertyWorks ( )
442+ {
443+ // Arrange & Act
444+ var tag = new OpenApiTag
445+ {
446+ Name = "test" ,
447+ Summary = "Test summary"
448+ } ;
449+
450+ // Assert
451+ Assert . Equal ( "test" , tag . Name ) ;
452+ Assert . Equal ( "Test summary" , tag . Summary ) ;
453+ }
454+
455+ [ Fact ]
456+ public void TagWithParentPropertyWorks ( )
457+ {
458+ // Arrange & Act
459+ var parentTag = new OpenApiTagReference ( "parent-tag" ) ;
460+ var tag = new OpenApiTag
461+ {
462+ Name = "child" ,
463+ Parent = parentTag
464+ } ;
465+
466+ // Assert
467+ Assert . Equal ( "child" , tag . Name ) ;
468+ Assert . NotNull ( tag . Parent ) ;
469+ Assert . Equal ( parentTag , tag . Parent ) ;
470+ }
471+
472+ [ Fact ]
473+ public void TagWithKindPropertyWorks ( )
474+ {
475+ // Arrange & Act
476+ var tag = new OpenApiTag
477+ {
478+ Name = "test" ,
479+ Kind = "category"
480+ } ;
481+
482+ // Assert
483+ Assert . Equal ( "test" , tag . Name ) ;
484+ Assert . Equal ( "category" , tag . Kind ) ;
485+ }
486+
487+ [ Fact ]
488+ public void TagWithAllV32PropertiesWorks ( )
489+ {
490+ // Arrange & Act
491+ var parentTag = new OpenApiTagReference ( "parent-tag" ) ;
492+ var tag = new OpenApiTag
493+ {
494+ Name = "test" ,
495+ Description = "Test description" ,
496+ Summary = "Test summary" ,
497+ Parent = parentTag ,
498+ Kind = "category"
499+ } ;
500+
501+ // Assert
502+ Assert . Equal ( "test" , tag . Name ) ;
503+ Assert . Equal ( "Test description" , tag . Description ) ;
504+ Assert . Equal ( "Test summary" , tag . Summary ) ;
505+ Assert . Equal ( parentTag , tag . Parent ) ;
506+ Assert . Equal ( "category" , tag . Kind ) ;
507+ }
508+
509+ [ Fact ]
510+ public void CreateShallowCopyIncludesV32Properties ( )
511+ {
512+ // Arrange
513+ var originalParent = new OpenApiTagReference ( "original-parent" ) ;
514+ var original = new OpenApiTag
515+ {
516+ Name = "original" ,
517+ Description = "Original description" ,
518+ Summary = "Original summary" ,
519+ Parent = originalParent ,
520+ Kind = "original-kind"
521+ } ;
522+
523+ // Act
524+ var copy = original . CreateShallowCopy ( ) ;
525+
526+ // Assert
527+ Assert . Equal ( original . Name , copy . Name ) ;
528+ Assert . Equal ( original . Description , copy . Description ) ;
529+ Assert . Equal ( original . Summary , copy . Summary ) ;
530+ Assert . Equal ( original . Parent , copy . Parent ) ;
531+ Assert . Equal ( original . Kind , copy . Kind ) ;
532+ }
533+
534+ [ Fact ]
535+ public void TagWithNullV32PropertiesWorks ( )
536+ {
537+ // Arrange & Act
538+ var tag = new OpenApiTag
539+ {
540+ Name = "test" ,
541+ Summary = null ,
542+ Parent = null ,
543+ Kind = null
544+ } ;
545+
546+ // Assert
547+ Assert . Equal ( "test" , tag . Name ) ;
548+ Assert . Null ( tag . Summary ) ;
549+ Assert . Null ( tag . Parent ) ;
550+ Assert . Null ( tag . Kind ) ;
551+ }
552+
553+ [ Theory ]
554+ [ InlineData ( "summary" ) ]
555+ [ InlineData ( "Summary" ) ]
556+ [ InlineData ( "SUMMARY" ) ]
557+ public void TagSummaryPropertyIsCasePreserving ( string summaryValue )
558+ {
559+ // Arrange & Act
560+ var tag = new OpenApiTag
561+ {
562+ Name = "test" ,
563+ Summary = summaryValue
564+ } ;
565+
566+ // Assert
567+ Assert . Equal ( summaryValue , tag . Summary ) ;
568+ }
569+
570+ [ Theory ]
571+ [ InlineData ( "category" ) ]
572+ [ InlineData ( "operational" ) ]
573+ [ InlineData ( "system" ) ]
574+ [ InlineData ( "custom-kind" ) ]
575+ public void TagKindPropertyAcceptsVariousValues ( string kindValue )
576+ {
577+ // Arrange & Act
578+ var tag = new OpenApiTag
579+ {
580+ Name = "test" ,
581+ Kind = kindValue
582+ } ;
583+
584+ // Assert
585+ Assert . Equal ( kindValue , tag . Kind ) ;
586+ }
313587 }
314588}
0 commit comments