From d1b85d3a43b3984fcb85257e681bc86feeb4d66e Mon Sep 17 00:00:00 2001
From: Jim Schubert <james.schubert@gmail.com>
Date: Sun, 26 Apr 2020 23:01:42 -0400
Subject: [PATCH] [validation] Warn on duplicate tags

The specification requires that tags are unique. This isn't caught by
swagger-parser, so we will issue a warning if duplicate tag names are
found.
---
 .../validations/oas/OpenApiEvaluator.java     | 26 ++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/validations/oas/OpenApiEvaluator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/validations/oas/OpenApiEvaluator.java
index 5cbe4c9eb89..56097b74d0f 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/validations/oas/OpenApiEvaluator.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/validations/oas/OpenApiEvaluator.java
@@ -6,12 +6,11 @@ import io.swagger.v3.oas.models.Paths;
 import io.swagger.v3.oas.models.media.Schema;
 import io.swagger.v3.oas.models.parameters.Parameter;
 import io.swagger.v3.oas.models.security.SecurityScheme;
+import io.swagger.v3.oas.models.tags.Tag;
 import org.openapitools.codegen.utils.ModelUtils;
 import org.openapitools.codegen.validation.*;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * A validator which evaluates an OpenAPI 3.x specification document
@@ -101,6 +100,27 @@ public class OpenApiEvaluator implements Validator<OpenAPI> {
             validationResult.consume(parameterValidations.validate(wrapper));
         });
 
+        List<Tag> tags = specification.getTags();
+        if (tags != null && tags.size() > 1) {
+            Set<String> distinct = new HashSet<>();
+            Set<String> duplicated = new HashSet<>();
+            tags.forEach(tag -> {
+                // add returns false if it already exists…
+                if (!distinct.add(tag.getName())) {
+                    duplicated.add(tag.getName());
+                }
+            });
+            if (duplicated.size() > 0) {
+                // From https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#fixed-fields
+                // A list of tags used by the specification with additional metadata. The order of the tags can be used
+                // to reflect on their order by the parsing tools. Not all tags that are used by the Operation Object
+                // must be declared. The tags that are not declared MAY be organized randomly or based on the tools'
+                // logic. Each tag name in the list MUST be unique.
+                ValidationRule rule = ValidationRule.warn("Duplicate tags", "The specification requires that tag names are unique.", s -> ValidationRule.Fail.empty());
+                validationResult.addResult(Validated.invalid(rule, "Duplicated tag(s): " + String.join(",", duplicated)));
+            }
+        }
+
         return validationResult;
     }
 }
-- 
GitLab