142 lines
4.3 KiB
C#
142 lines
4.3 KiB
C#
// <copyright file="LicenseEvidenceBuilderTests.cs" company="StellaOps">
|
|
// Copyright (c) StellaOps. Licensed under the AGPL-3.0-or-later.
|
|
// </copyright>
|
|
|
|
using System.Collections.Immutable;
|
|
using FluentAssertions;
|
|
using StellaOps.Scanner.Core.Contracts;
|
|
using StellaOps.Scanner.Emit.Evidence;
|
|
using Xunit;
|
|
|
|
namespace StellaOps.Scanner.Emit.Tests.Evidence;
|
|
|
|
/// <summary>
|
|
/// Unit tests for <see cref="LicenseEvidenceBuilder"/>.
|
|
/// Sprint: SPRINT_20260107_005_001 Task EV-011
|
|
/// </summary>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class LicenseEvidenceBuilderTests
|
|
{
|
|
private readonly LicenseEvidenceBuilder _sut = new();
|
|
|
|
[Fact]
|
|
public void Build_WithLicenseEvidence_ReturnsLicenseChoices()
|
|
{
|
|
// Arrange
|
|
var evidence = ImmutableArray.Create(
|
|
new ComponentEvidence { Kind = "license", Value = "MIT", Source = "/app/LICENSE" });
|
|
var component = CreateComponent(evidence);
|
|
|
|
// Act
|
|
var result = _sut.Build(component);
|
|
|
|
// Assert
|
|
result.Should().HaveCount(1);
|
|
result[0].License.Should().NotBeNull();
|
|
result[0].License!.License.Should().NotBeNull();
|
|
result[0].License!.License!.Id.Should().Be("MIT");
|
|
}
|
|
|
|
[Fact]
|
|
public void Build_WithMultipleLicenses_ReturnsAllLicenses()
|
|
{
|
|
// Arrange
|
|
var evidence = ImmutableArray.Create(
|
|
new ComponentEvidence { Kind = "license", Value = "MIT", Source = "/app/LICENSE" },
|
|
new ComponentEvidence { Kind = "license", Value = "Apache-2.0", Source = "/app/LICENSE.apache" },
|
|
new ComponentEvidence { Kind = "license", Value = "GPL-3.0", Source = "/app/COPYING" });
|
|
var component = CreateComponent(evidence);
|
|
|
|
// Act
|
|
var result = _sut.Build(component);
|
|
|
|
// Assert
|
|
result.Should().HaveCount(3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Build_WithNonLicenseEvidence_FiltersOutNonLicenses()
|
|
{
|
|
// Arrange
|
|
var evidence = ImmutableArray.Create(
|
|
new ComponentEvidence { Kind = "license", Value = "MIT", Source = "/app/LICENSE" },
|
|
new ComponentEvidence { Kind = "file", Value = "readme.md", Source = "/app/README.md" });
|
|
var component = CreateComponent(evidence);
|
|
|
|
// Act
|
|
var result = _sut.Build(component);
|
|
|
|
// Assert
|
|
result.Should().HaveCount(1);
|
|
result[0].License!.License!.Id.Should().Be("MIT");
|
|
}
|
|
|
|
[Fact]
|
|
public void Build_WithNoEvidence_ReturnsEmptyArray()
|
|
{
|
|
// Arrange
|
|
var component = CreateComponent(ImmutableArray<ComponentEvidence>.Empty);
|
|
|
|
// Act
|
|
var result = _sut.Build(component);
|
|
|
|
// Assert
|
|
result.Should().BeEmpty();
|
|
}
|
|
|
|
[Fact]
|
|
public void Build_NullComponent_ThrowsArgumentNullException()
|
|
{
|
|
// Act & Assert
|
|
var act = () => _sut.Build(null!);
|
|
act.Should().Throw<ArgumentNullException>();
|
|
}
|
|
|
|
[Fact]
|
|
public void Build_WithExpression_ParsesAsExpression()
|
|
{
|
|
// Arrange
|
|
var evidence = ImmutableArray.Create(
|
|
new ComponentEvidence { Kind = "license", Value = "MIT OR Apache-2.0", Source = "/app/LICENSE" });
|
|
var component = CreateComponent(evidence);
|
|
|
|
// Act
|
|
var result = _sut.Build(component);
|
|
|
|
// Assert
|
|
result.Should().HaveCount(1);
|
|
// SPDX expressions are parsed as expression rather than ID
|
|
result[0].License.Expression.Should().NotBeNullOrWhiteSpace();
|
|
}
|
|
|
|
[Fact]
|
|
public void Build_DeduplicatesSameLicense()
|
|
{
|
|
// Arrange
|
|
var evidence = ImmutableArray.Create(
|
|
new ComponentEvidence { Kind = "license", Value = "MIT", Source = "/app/LICENSE" },
|
|
new ComponentEvidence { Kind = "license", Value = "MIT", Source = "/app/package.json" }); // Same license
|
|
var component = CreateComponent(evidence);
|
|
|
|
// Act
|
|
var result = _sut.Build(component);
|
|
|
|
// Assert
|
|
result.Should().HaveCount(1);
|
|
}
|
|
|
|
private static AggregatedComponent CreateComponent(ImmutableArray<ComponentEvidence> evidence)
|
|
{
|
|
var identity = ComponentIdentity.Create(
|
|
key: "pkg:npm/lodash@4.17.21",
|
|
name: "lodash",
|
|
purl: "pkg:npm/lodash@4.17.21");
|
|
|
|
return new AggregatedComponent
|
|
{
|
|
Identity = identity,
|
|
Evidence = evidence,
|
|
};
|
|
}
|
|
}
|