diff --git a/test/DemaConsulting.SpdxTool.Tests/DiagramTests.cs b/test/DemaConsulting.SpdxTool.Tests/DiagramTests.cs new file mode 100644 index 0000000..be13533 --- /dev/null +++ b/test/DemaConsulting.SpdxTool.Tests/DiagramTests.cs @@ -0,0 +1,309 @@ +// Copyright (c) 2024 DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +namespace DemaConsulting.SpdxTool.Tests; + +/// +/// Tests for the 'diagram' command +/// +[TestClass] +public class DiagramTests +{ + /// + /// Test the 'diagram' command with missing arguments + /// + [TestMethod] + public void DiagramCommand_MissingArguments() + { + // Act: Run the command + var exitCode = Runner.Run( + out var output, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "diagram"); + + // Assert: Verify error reported + Assert.AreEqual(1, exitCode); + Assert.Contains("'diagram' command invalid arguments", output); + } + + /// + /// Test the 'diagram' command with insufficient arguments + /// + [TestMethod] + public void DiagramCommand_InsufficientArguments() + { + // Act: Run the command + var exitCode = Runner.Run( + out var output, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "diagram", + "test.spdx.json"); + + // Assert: Verify error reported + Assert.AreEqual(1, exitCode); + Assert.Contains("'diagram' command invalid arguments", output); + } + + /// + /// Test the 'diagram' command with missing SPDX file + /// + [TestMethod] + public void DiagramCommand_MissingSpdxFile() + { + // Act: Run the command + var exitCode = Runner.Run( + out var output, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "diagram", + "missing.spdx.json", + "output.mermaid.txt"); + + // Assert: Verify error reported + Assert.AreEqual(1, exitCode); + Assert.Contains("File not found: missing.spdx.json", output); + } + + /// + /// Test the 'diagram' command with invalid option + /// + [TestMethod] + public void DiagramCommand_InvalidOption() + { + const string spdxContents = + """ + { + "files": [], + "packages": [], + "relationships": [], + "spdxVersion": "SPDX-2.2", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "Test Document", + "documentNamespace": "https://sbom.spdx.org", + "creationInfo": { + "created": "2021-10-01T00:00:00Z", + "creators": [ "Person: Malcolm Nixon" ] + } + } + """; + + try + { + // Arrange: Write the SPDX file + File.WriteAllText("test.spdx.json", spdxContents); + + // Act: Run the command + var exitCode = Runner.Run( + out var output, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "diagram", + "test.spdx.json", + "output.mermaid.txt", + "invalid-option"); + + // Assert: Verify error reported + Assert.AreEqual(1, exitCode); + Assert.Contains("'diagram' command invalid option invalid-option", output); + } + finally + { + File.Delete("test.spdx.json"); + } + } + + /// + /// Test the 'diagram' command to generate a diagram + /// + [TestMethod] + public void DiagramCommand_GenerateDiagram() + { + const string spdxContents = + """ + { + "files": [], + "packages": [ + { + "SPDXID": "SPDXRef-Application", + "name": "Test Application", + "versionInfo": "1.2.3", + "downloadLocation": "https://github.com/demaconsulting/SpdxTool", + "licenseConcluded": "MIT" + }, + { + "SPDXID": "SPDXRef-Library", + "name": "Test Library", + "versionInfo": "2.3.4", + "downloadLocation": "https://github.com/demaconsulting/SpdxTool", + "licenseConcluded": "MIT" + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Application", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Application", + "relatedSpdxElement": "SPDXRef-Library", + "relationshipType": "DEPENDS_ON" + } + ], + "spdxVersion": "SPDX-2.2", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "Test Document", + "documentNamespace": "https://sbom.spdx.org", + "creationInfo": { + "created": "2021-10-01T00:00:00Z", + "creators": [ "Person: Malcolm Nixon" ] + } + } + """; + + try + { + // Arrange: Write the SPDX file + File.WriteAllText("test.spdx.json", spdxContents); + + // Act: Run the command + var exitCode = Runner.Run( + out _, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "diagram", + "test.spdx.json", + "test.mermaid.txt"); + + // Assert: Verify success reported + Assert.AreEqual(0, exitCode); + + // Assert: Verify the mermaid file was created + Assert.IsTrue(File.Exists("test.mermaid.txt")); + var mermaid = File.ReadAllText("test.mermaid.txt"); + Assert.Contains("erDiagram", mermaid); + Assert.Contains("Test Application / 1.2.3", mermaid); + Assert.Contains("Test Library / 2.3.4", mermaid); + Assert.Contains("DEPENDS_ON", mermaid); + } + finally + { + File.Delete("test.spdx.json"); + File.Delete("test.mermaid.txt"); + } + } + + /// + /// Test the 'diagram' command with tools option + /// + [TestMethod] + public void DiagramCommand_WithTools() + { + const string spdxContents = + """ + { + "files": [], + "packages": [ + { + "SPDXID": "SPDXRef-Application", + "name": "Test Application", + "versionInfo": "1.2.3", + "downloadLocation": "https://github.com/demaconsulting/SpdxTool", + "licenseConcluded": "MIT" + }, + { + "SPDXID": "SPDXRef-Tool", + "name": "Build Tool", + "versionInfo": "3.4.5", + "downloadLocation": "https://github.com/demaconsulting/SpdxTool", + "licenseConcluded": "MIT" + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Application", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Tool", + "relatedSpdxElement": "SPDXRef-Application", + "relationshipType": "BUILD_TOOL_OF" + } + ], + "spdxVersion": "SPDX-2.2", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "Test Document", + "documentNamespace": "https://sbom.spdx.org", + "creationInfo": { + "created": "2021-10-01T00:00:00Z", + "creators": [ "Person: Malcolm Nixon" ] + } + } + """; + + try + { + // Arrange: Write the SPDX file + File.WriteAllText("test.spdx.json", spdxContents); + + // Act: Run the command without tools option + var exitCode = Runner.Run( + out _, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "diagram", + "test.spdx.json", + "test-no-tools.mermaid.txt"); + + // Assert: Verify success and tools not included + Assert.AreEqual(0, exitCode); + var mermaidNoTools = File.ReadAllText("test-no-tools.mermaid.txt"); + Assert.DoesNotContain("Build Tool", mermaidNoTools); + + // Act: Run the command with tools option + exitCode = Runner.Run( + out _, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "diagram", + "test.spdx.json", + "test-with-tools.mermaid.txt", + "tools"); + + // Assert: Verify success and tools included + Assert.AreEqual(0, exitCode); + var mermaidWithTools = File.ReadAllText("test-with-tools.mermaid.txt"); + Assert.Contains("Build Tool / 3.4.5", mermaidWithTools); + Assert.Contains("BUILD_TOOL_OF", mermaidWithTools); + } + finally + { + File.Delete("test.spdx.json"); + File.Delete("test-no-tools.mermaid.txt"); + File.Delete("test-with-tools.mermaid.txt"); + } + } +} diff --git a/test/DemaConsulting.SpdxTool.Tests/ValidateTests.cs b/test/DemaConsulting.SpdxTool.Tests/ValidateTests.cs new file mode 100644 index 0000000..298fd4e --- /dev/null +++ b/test/DemaConsulting.SpdxTool.Tests/ValidateTests.cs @@ -0,0 +1,313 @@ +// Copyright (c) 2024 DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +namespace DemaConsulting.SpdxTool.Tests; + +/// +/// Tests for the 'validate' command +/// +[TestClass] +public class ValidateTests +{ + /// + /// Test the 'validate' command with missing arguments + /// + [TestMethod] + public void ValidateCommand_MissingArguments() + { + // Act: Run the command + var exitCode = Runner.Run( + out var output, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "validate"); + + // Assert: Verify error reported + Assert.AreEqual(1, exitCode); + Assert.Contains("'validate' command missing arguments", output); + } + + /// + /// Test the 'validate' command with missing SPDX file + /// + [TestMethod] + public void ValidateCommand_MissingSpdxFile() + { + // Act: Run the command + var exitCode = Runner.Run( + out var output, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "validate", + "missing.spdx.json"); + + // Assert: Verify error reported + Assert.AreEqual(1, exitCode); + Assert.Contains("File not found: missing.spdx.json", output); + } + + /// + /// Test the 'validate' command with a valid SPDX document + /// + [TestMethod] + public void ValidateCommand_ValidDocument() + { + const string spdxContents = + """ + { + "files": [], + "packages": [ + { + "SPDXID": "SPDXRef-Package", + "name": "Test Package", + "versionInfo": "1.0.0", + "downloadLocation": "https://github.com/demaconsulting/SpdxTool", + "filesAnalyzed": false, + "licenseConcluded": "MIT" + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package", + "relationshipType": "DESCRIBES" + } + ], + "spdxVersion": "SPDX-2.2", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "Test Document", + "documentNamespace": "https://sbom.spdx.org", + "creationInfo": { + "created": "2021-10-01T00:00:00Z", + "creators": [ "Person: Malcolm Nixon" ] + } + } + """; + + try + { + // Arrange: Write the SPDX file + File.WriteAllText("test.spdx.json", spdxContents); + + // Act: Run the command + var exitCode = Runner.Run( + out _, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "validate", + "test.spdx.json"); + + // Assert: Verify success reported + Assert.AreEqual(0, exitCode); + } + finally + { + File.Delete("test.spdx.json"); + } + } + + /// + /// Test the 'validate' command with valid document without files analyzed + /// + [TestMethod] + public void ValidateCommand_NoFilesAnalyzed() + { + const string spdxContents = + """ + { + "files": [], + "packages": [ + { + "SPDXID": "SPDXRef-Package", + "name": "Test Package", + "versionInfo": "1.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "NOASSERTION" + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package", + "relationshipType": "DESCRIBES" + } + ], + "spdxVersion": "SPDX-2.2", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "Test Document", + "documentNamespace": "https://sbom.spdx.org", + "creationInfo": { + "created": "2021-10-01T00:00:00Z", + "creators": [ "Person: Malcolm Nixon" ] + } + } + """; + + try + { + // Arrange: Write the SPDX file + File.WriteAllText("test.spdx.json", spdxContents); + + // Act: Run the command + var exitCode = Runner.Run( + out _, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "validate", + "test.spdx.json"); + + // Assert: Verify success (validation checks are lenient) + Assert.AreEqual(0, exitCode); + } + finally + { + File.Delete("test.spdx.json"); + } + } + + /// + /// Test the 'validate' command with NTIA option on valid document + /// + [TestMethod] + public void ValidateCommand_NtiaValid() + { + const string spdxContents = + """ + { + "files": [], + "packages": [ + { + "SPDXID": "SPDXRef-Package", + "name": "Test Package", + "versionInfo": "1.0.0", + "supplier": "Organization: Test", + "downloadLocation": "https://github.com/demaconsulting/SpdxTool", + "filesAnalyzed": false, + "licenseConcluded": "MIT" + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package", + "relationshipType": "DESCRIBES" + } + ], + "spdxVersion": "SPDX-2.2", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "Test Document", + "documentNamespace": "https://sbom.spdx.org", + "creationInfo": { + "created": "2021-10-01T00:00:00Z", + "creators": [ "Person: Malcolm Nixon" ] + } + } + """; + + try + { + // Arrange: Write the SPDX file + File.WriteAllText("test.spdx.json", spdxContents); + + // Act: Run the command with NTIA flag + var exitCode = Runner.Run( + out _, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "validate", + "test.spdx.json", + "ntia"); + + // Assert: Verify success reported + Assert.AreEqual(0, exitCode); + } + finally + { + File.Delete("test.spdx.json"); + } + } + + /// + /// Test the 'validate' command with NTIA option on invalid document + /// + [TestMethod] + public void ValidateCommand_NtiaInvalid() + { + const string spdxContents = + """ + { + "files": [], + "packages": [ + { + "SPDXID": "SPDXRef-Package", + "name": "Test Package", + "versionInfo": "1.0.0", + "downloadLocation": "https://github.com/demaconsulting/SpdxTool", + "filesAnalyzed": false, + "licenseConcluded": "MIT" + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package", + "relationshipType": "DESCRIBES" + } + ], + "spdxVersion": "SPDX-2.2", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "Test Document", + "documentNamespace": "https://sbom.spdx.org", + "creationInfo": { + "created": "2021-10-01T00:00:00Z", + "creators": [ "Person: Malcolm Nixon" ] + } + } + """; + + try + { + // Arrange: Write the SPDX file + File.WriteAllText("test.spdx.json", spdxContents); + + // Act: Run the command with NTIA flag + var exitCode = Runner.Run( + out var output, + "dotnet", + "DemaConsulting.SpdxTool.dll", + "validate", + "test.spdx.json", + "ntia"); + + // Assert: Verify error reported (missing supplier for NTIA) + Assert.AreEqual(1, exitCode); + Assert.Contains("Issues in test.spdx.json", output); + } + finally + { + File.Delete("test.spdx.json"); + } + } +}