Restructure solution layout by module

This commit is contained in:
master
2025-10-28 15:10:40 +02:00
parent 95daa159c4
commit d870da18ce
4103 changed files with 192899 additions and 187024 deletions

View File

@@ -0,0 +1,73 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.Concelier.Connector.Vndr.Cisco.Internal;
using Xunit;
namespace StellaOps.Concelier.Connector.Vndr.Cisco.Tests;
public sealed class CiscoDtoFactoryTests
{
[Fact]
public async Task CreateAsync_MergesRawAndCsafProducts()
{
const string CsafPayload = @"
{
""product_tree"": {
""full_product_names"": [
{ ""product_id"": ""PID-1"", ""name"": ""Cisco Widget"" }
]
},
""vulnerabilities"": [
{
""product_status"": {
""known_affected"": [""PID-1""]
}
}
]
}";
var csafClient = new StubCsafClient(CsafPayload);
var factory = new CiscoDtoFactory(csafClient, NullLogger<CiscoDtoFactory>.Instance);
var raw = new CiscoRawAdvisory
{
AdvisoryId = "CISCO-SA-TEST",
AdvisoryTitle = "Test Advisory",
Summary = "Summary",
Sir = "High",
FirstPublished = "2025-10-01T00:00:00Z",
LastUpdated = "2025-10-02T00:00:00Z",
PublicationUrl = "https://example.com/advisory",
CsafUrl = "https://sec.cloudapps.cisco.com/csaf/test.json",
Cves = new List<string> { "CVE-2024-0001" },
BugIds = new List<string> { "BUG123" },
ProductNames = new List<string> { "Cisco Widget" },
Version = "1.2.3",
CvssBaseScore = "9.8"
};
var dto = await factory.CreateAsync(raw, CancellationToken.None);
dto.Should().NotBeNull();
dto.Severity.Should().Be("high");
dto.CvssBaseScore.Should().Be(9.8);
dto.Products.Should().HaveCount(1);
var product = dto.Products[0];
product.Name.Should().Be("Cisco Widget");
product.ProductId.Should().Be("PID-1");
product.Statuses.Should().Contain("known_affected");
}
private sealed class StubCsafClient : ICiscoCsafClient
{
private readonly string? _payload;
public StubCsafClient(string? payload) => _payload = payload;
public Task<string?> TryFetchAsync(string? url, CancellationToken cancellationToken)
=> Task.FromResult(_payload);
}
}

View File

@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using FluentAssertions;
using MongoDB.Bson;
using StellaOps.Concelier.Models;
using StellaOps.Concelier.Connector.Common;
using StellaOps.Concelier.Connector.Vndr.Cisco;
using StellaOps.Concelier.Connector.Vndr.Cisco.Internal;
using StellaOps.Concelier.Storage.Mongo.Documents;
using StellaOps.Concelier.Storage.Mongo.Dtos;
using Xunit;
namespace StellaOps.Concelier.Connector.Vndr.Cisco.Tests;
public sealed class CiscoMapperTests
{
[Fact]
public void Map_ProducesCanonicalAdvisory()
{
var published = new DateTimeOffset(2025, 10, 1, 0, 0, 0, TimeSpan.Zero);
var updated = published.AddDays(1);
var dto = new CiscoAdvisoryDto(
AdvisoryId: "CISCO-SA-TEST",
Title: "Test Advisory",
Summary: "Sample summary",
Severity: "High",
Published: published,
Updated: updated,
PublicationUrl: "https://example.com/advisory",
CsafUrl: "https://sec.cloudapps.cisco.com/csaf/test.json",
CvrfUrl: "https://example.com/cvrf.xml",
CvssBaseScore: 9.8,
Cves: new List<string> { "CVE-2024-0001" },
BugIds: new List<string> { "BUG123" },
Products: new List<CiscoAffectedProductDto>
{
new("Cisco Widget", "PID-1", "1.2.3", new [] { AffectedPackageStatusCatalog.KnownAffected })
});
var document = new DocumentRecord(
Id: Guid.NewGuid(),
SourceName: VndrCiscoConnectorPlugin.SourceName,
Uri: "https://api.cisco.com/security/advisories/v2/advisories/CISCO-SA-TEST",
FetchedAt: published,
Sha256: "abc123",
Status: DocumentStatuses.PendingMap,
ContentType: "application/json",
Headers: null,
Metadata: null,
Etag: null,
LastModified: updated,
GridFsId: null);
var dtoRecord = new DtoRecord(Guid.NewGuid(), document.Id, VndrCiscoConnectorPlugin.SourceName, "cisco.dto.test", new BsonDocument(), updated);
var advisory = CiscoMapper.Map(dto, document, dtoRecord);
advisory.AdvisoryKey.Should().Be("CISCO-SA-TEST");
advisory.Title.Should().Be("Test Advisory");
advisory.Severity.Should().Be("high");
advisory.Aliases.Should().Contain(new[] { "CISCO-SA-TEST", "CVE-2024-0001", "BUG123" });
advisory.References.Should().Contain(reference => reference.Url == "https://example.com/advisory");
advisory.References.Should().Contain(reference => reference.Url == "https://sec.cloudapps.cisco.com/csaf/test.json");
advisory.AffectedPackages.Should().HaveCount(1);
var package = advisory.AffectedPackages[0];
package.Type.Should().Be(AffectedPackageTypes.Vendor);
package.Identifier.Should().Be("Cisco Widget");
package.Statuses.Should().ContainSingle(status => status.Status == AffectedPackageStatusCatalog.KnownAffected);
package.VersionRanges.Should().ContainSingle();
var range = package.VersionRanges[0];
range.RangeKind.Should().Be("semver");
range.Provenance.Source.Should().Be(VndrCiscoConnectorPlugin.SourceName);
range.Primitives.Should().NotBeNull();
range.Primitives!.SemVer.Should().NotBeNull();
range.Primitives.SemVer!.ExactValue.Should().Be("1.2.3");
}
}

View File

@@ -0,0 +1,18 @@
<?xml version='1.0' encoding='utf-8'?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Models/StellaOps.Concelier.Models.csproj" />
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Connector.Common/StellaOps.Concelier.Connector.Common.csproj" />
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Connector.Vndr.Cisco/StellaOps.Concelier.Connector.Vndr.Cisco.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
</ItemGroup>
</Project>