Repository: spdx/tools-python

Issue:
Check for duplicated SPDX ids
This should be part of the validation. There can only be a single element per SPDX id.

Discussion:

Patch:
diff --git a/src/spdx/validation/document_validator.py b/src/spdx/validation/document_validator.py
index a3fa007..fe6422a 100644
--- a/src/spdx/validation/document_validator.py
+++ b/src/spdx/validation/document_validator.py
@@ -21,6 +21,7 @@ from spdx.validation.file_validator import validate_files
 from spdx.validation.package_validator import validate_packages
 from spdx.validation.relationship_validator import validate_relationships
 from spdx.validation.snippet_validator import validate_snippets
+from spdx.validation.spdx_id_validators import get_list_of_all_spdx_ids
 from spdx.validation.validation_message import ValidationMessage, ValidationContext, SpdxElementType
 
 
@@ -74,4 +75,16 @@ def validate_full_spdx_document(document: Document, spdx_version: str = None) ->
                 ValidationContext(spdx_id=document_id,
                                   element_type=SpdxElementType.DOCUMENT)))
 
+    all_spdx_ids: List[str] = get_list_of_all_spdx_ids(document)
+    auxiliary_set = set()
+    duplicated_spdx_ids = set(
+        spdx_id for spdx_id in all_spdx_ids if spdx_id in auxiliary_set or auxiliary_set.add(spdx_id))
+
+    if duplicated_spdx_ids:
+        validation_messages.append(
+            ValidationMessage(
+                f"every spdx_id must be unique within the document, but found the following duplicates: {sorted(duplicated_spdx_ids)}",
+                context)
+        )
+
     return validation_messages


Test patch:
diff --git a/tests/spdx/validation/test_document_validator.py b/tests/spdx/validation/test_document_validator.py
index c3b8055..944f307 100644
--- a/tests/spdx/validation/test_document_validator.py
+++ b/tests/spdx/validation/test_document_validator.py
@@ -16,7 +16,7 @@ import pytest
 from spdx.model.document import Document, CreationInfo
 from spdx.validation.document_validator import validate_full_spdx_document
 from spdx.validation.validation_message import ValidationMessage, ValidationContext, SpdxElementType
-from tests.spdx.fixtures import document_fixture, creation_info_fixture
+from tests.spdx.fixtures import document_fixture, creation_info_fixture, file_fixture, package_fixture, snippet_fixture
 
 
 def test_valid_document():
@@ -56,3 +56,18 @@ def test_spdx_version_handling(creation_info: CreationInfo, version_input: str,
     assert validation_messages == expected
 
     # TODO: https://github.com/spdx/tools-python/issues/375
+
+
+def test_duplicated_spdx_ids():
+    document = document_fixture(
+        files=[file_fixture(spdx_id="SPDXRef-File"), file_fixture(spdx_id="SPDXRef-2"), file_fixture(spdx_id="SPDXRef-3")],
+        packages=[package_fixture(spdx_id="SPDXRef-2"), package_fixture(spdx_id="SPDXRef-DOCUMENT")],
+        snippets=[snippet_fixture(spdx_id="SPDXRef-2"), snippet_fixture(spdx_id="SPDXRef-3")])
+
+    context = ValidationContext(spdx_id=document.creation_info.spdx_id, element_type=SpdxElementType.DOCUMENT)
+
+    validation_messages: List[ValidationMessage] = validate_full_spdx_document(document)
+
+    assert validation_messages == [ValidationMessage(
+        "every spdx_id must be unique within the document, but found the following duplicates: ['SPDXRef-2', 'SPDXRef-3', 'SPDXRef-DOCUMENT']",
+        context)]