Some checks failed
Build Test Deploy / build-test (push) Has been cancelled
Build Test Deploy / authority-container (push) Has been cancelled
Build Test Deploy / docs (push) Has been cancelled
Build Test Deploy / deploy (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
93 lines
3.1 KiB
C#
93 lines
3.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using FluentAssertions;
|
|
using StellaOps.Concelier.Connector.Cccs.Internal;
|
|
using StellaOps.Concelier.Connector.Common.Html;
|
|
using Xunit;
|
|
using Xunit.Abstractions;
|
|
|
|
namespace StellaOps.Concelier.Connector.Cccs.Tests.Internal;
|
|
|
|
public sealed class CccsHtmlParserTests
|
|
{
|
|
private readonly ITestOutputHelper _output;
|
|
private static readonly HtmlContentSanitizer Sanitizer = new();
|
|
private static readonly CccsHtmlParser Parser = new(Sanitizer);
|
|
|
|
public CccsHtmlParserTests(ITestOutputHelper output)
|
|
{
|
|
_output = output ?? throw new ArgumentNullException(nameof(output));
|
|
}
|
|
|
|
public static IEnumerable<object[]> ParserCases()
|
|
{
|
|
yield return new object[]
|
|
{
|
|
"cccs-raw-advisory.json",
|
|
"TEST-001",
|
|
"en",
|
|
new[] { "Vendor Widget 1.0", "Vendor Widget 2.0" },
|
|
new[]
|
|
{
|
|
"https://example.com/details",
|
|
"https://www.cyber.gc.ca/en/contact-cyber-centre?lang=en"
|
|
},
|
|
new[] { "CVE-2020-1234", "CVE-2021-9999" }
|
|
};
|
|
|
|
yield return new object[]
|
|
{
|
|
"cccs-raw-advisory-fr.json",
|
|
"TEST-002-FR",
|
|
"fr",
|
|
new[] { "Produit Exemple 3.1", "Produit Exemple 3.2", "Variante 3.2.1" },
|
|
new[]
|
|
{
|
|
"https://exemple.ca/details",
|
|
"https://www.cyber.gc.ca/fr/contact-centre-cyber"
|
|
},
|
|
new[] { "CVE-2024-1111" }
|
|
};
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(ParserCases))]
|
|
public void Parse_ExtractsExpectedFields(
|
|
string fixtureName,
|
|
string expectedSerial,
|
|
string expectedLanguage,
|
|
string[] expectedProducts,
|
|
string[] expectedReferenceUrls,
|
|
string[] expectedCves)
|
|
{
|
|
var raw = LoadFixture<CccsRawAdvisoryDocument>(fixtureName);
|
|
|
|
var dto = Parser.Parse(raw);
|
|
|
|
_output.WriteLine("Products: {0}", string.Join("|", dto.Products));
|
|
_output.WriteLine("References: {0}", string.Join("|", dto.References.Select(r => $"{r.Url} ({r.Label})")));
|
|
_output.WriteLine("CVEs: {0}", string.Join("|", dto.CveIds));
|
|
|
|
dto.SerialNumber.Should().Be(expectedSerial);
|
|
dto.Language.Should().Be(expectedLanguage);
|
|
dto.Products.Should().BeEquivalentTo(expectedProducts);
|
|
foreach (var url in expectedReferenceUrls)
|
|
{
|
|
dto.References.Should().Contain(reference => reference.Url == url);
|
|
}
|
|
|
|
dto.CveIds.Should().BeEquivalentTo(expectedCves);
|
|
dto.ContentHtml.Should().Contain("<ul>").And.Contain("<li>");
|
|
dto.ContentHtml.Should().Contain("<h2", because: "heading structure must survive sanitisation for UI rendering");
|
|
}
|
|
|
|
internal static T LoadFixture<T>(string fileName)
|
|
{
|
|
var path = Path.Combine(AppContext.BaseDirectory, "Fixtures", fileName);
|
|
var json = File.ReadAllText(path);
|
|
return JsonSerializer.Deserialize<T>(json, new JsonSerializerOptions(JsonSerializerDefaults.Web))!;
|
|
}
|
|
}
|