Update low-risk Common packages
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
using NUnit.Framework;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using SacsCore = Sarand.Net.Standard.Base.Core.Sacs;
|
||||
|
||||
namespace Sacs.UnitTests.Net.Standard.Base.Helpers
|
||||
{
|
||||
[TestFixture]
|
||||
public class SacsContentTypeHelper_Tester
|
||||
{
|
||||
// --- Filename Content Types ---
|
||||
|
||||
[TestCase("report.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")]
|
||||
[TestCase("archive.7z", "application/x-7z-compressed")]
|
||||
[TestCase("README", "application/octet-stream")]
|
||||
[TestCase("data.unknown", "application/octet-stream")]
|
||||
public void GetContentTypeFromFilename_ReturnsExpectedContentType(string fileName, string expected)
|
||||
{
|
||||
Assert.That(fileName.GetContentTypeFromFilename(), Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
// --- Form File Content Types ---
|
||||
|
||||
[TestCase("application/pdf", "image.png", "application/pdf")]
|
||||
[TestCase("application/octet-stream", "image.png", "image/png")]
|
||||
[TestCase("", "document.pdf", "application/pdf")]
|
||||
[TestCase("", "", "application/octet-stream")]
|
||||
public void GetContentTypeFromFormFile_UsesSpecificTypeOrFilenameFallback(string contentType, string fileName, string expected)
|
||||
{
|
||||
Assert.That(SacsContentTypeHelper.GetContentTypeFromFormFile(contentType, fileName), Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
// --- MIME Mappings ---
|
||||
|
||||
[Test]
|
||||
public void GetContentTypeFromMimeType_MapsKnownAndUnknownValues()
|
||||
{
|
||||
Assert.That(SacsContentTypeHelper.GetContentTypeFromMimeType(SacsCore.MimeType.Pdf), Is.EqualTo("application/pdf"));
|
||||
Assert.That(SacsContentTypeHelper.GetContentTypeFromMimeType(SacsCore.MimeType.Unknown), Is.EqualTo(SacsContentTypeHelper.ContentTypeDefault));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetMimeTypeFromContentType_MapsKnownAndUnknownValues()
|
||||
{
|
||||
Assert.That("image/jpeg".GetMimeTypeFromContentType(), Is.EqualTo(SacsCore.MimeType.Jpeg));
|
||||
Assert.That("".GetMimeTypeFromContentType(), Is.EqualTo(SacsCore.MimeType.Unknown));
|
||||
}
|
||||
|
||||
// --- The End ---
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using NUnit.Framework;
|
||||
using Sarand.Net.Standard.Base.Net;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ZstdNet;
|
||||
|
||||
namespace Sacs.UnitTests.Net.Standard.Base.Net
|
||||
{
|
||||
[TestFixture]
|
||||
public class SacsHttpClient_Tester
|
||||
{
|
||||
// --- Zstandard Responses ---
|
||||
|
||||
[Test]
|
||||
public async Task DoRequest_DecompressesZstandardResponse()
|
||||
{
|
||||
const string responseText = "Zstandard response content: £12.34";
|
||||
byte[] compressedData;
|
||||
using (Compressor compressor = new Compressor())
|
||||
compressedData = compressor.Wrap(Encoding.UTF8.GetBytes(responseText));
|
||||
|
||||
TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
|
||||
listener.Start();
|
||||
try
|
||||
{
|
||||
int port = ((IPEndPoint)listener.LocalEndpoint).Port;
|
||||
Task serverTask = SendResponse(listener, compressedData);
|
||||
SacsHttpRequestData requestData = new SacsHttpRequestData(null)
|
||||
{
|
||||
Url = $"http://127.0.0.1:{port}/zstd"
|
||||
};
|
||||
|
||||
SacsHttpResponseData response = await SacsHttpClient.DoRequest(requestData);
|
||||
await serverTask;
|
||||
|
||||
Assert.That(response.Success, Is.True);
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
Assert.That(response.Exception, Is.Null);
|
||||
Assert.That(response.Data, Is.EqualTo(responseText));
|
||||
Assert.That(response.ContentHeaders["Content-Encoding"], Does.Contain("zstd"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
listener.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
// --- Test Support ---
|
||||
|
||||
private static async Task SendResponse(TcpListener listener, byte[] compressedData)
|
||||
{
|
||||
using (TcpClient client = await listener.AcceptTcpClientAsync())
|
||||
using (NetworkStream stream = client.GetStream())
|
||||
{
|
||||
await ReadRequestHeaders(stream);
|
||||
byte[] headers = Encoding.ASCII.GetBytes(
|
||||
"HTTP/1.1 200 OK\r\n" +
|
||||
"Content-Encoding: zstd\r\n" +
|
||||
"Content-Type: text/plain; charset=utf-8\r\n" +
|
||||
$"Content-Length: {compressedData.Length}\r\n" +
|
||||
"Connection: close\r\n\r\n");
|
||||
|
||||
await stream.WriteAsync(headers);
|
||||
await stream.WriteAsync(compressedData);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ReadRequestHeaders(Stream stream)
|
||||
{
|
||||
byte[] buffer = new byte[1];
|
||||
int matchedBytes = 0;
|
||||
byte[] terminator = "\r\n\r\n"u8.ToArray();
|
||||
|
||||
while (matchedBytes < terminator.Length && await stream.ReadAsync(buffer) > 0)
|
||||
{
|
||||
matchedBytes = buffer[0] == terminator[matchedBytes]
|
||||
? matchedBytes + 1
|
||||
: buffer[0] == terminator[0] ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// --- The End ---
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
@@ -186,7 +186,7 @@ namespace Sarand.Net.Standard.Base.Helpers
|
||||
private static readonly List<String> genericContentTypes = new List<string>() { "application/octet-stream", "application/oleobject" };
|
||||
/// <summary>
|
||||
/// Given a file path, determine the MIME type.
|
||||
/// <para>Ref. NuGet package Microsoft.AspNetCore.StaticFiles</para>
|
||||
/// <para>Ref. the Microsoft.AspNetCore.App shared framework.</para>
|
||||
/// </summary>
|
||||
public static String GetContentTypeFromFilename(this String fileName)
|
||||
{
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CsvHelper" Version="19.0.0" />
|
||||
<PackageReference Include="MailKit" Version="4.17.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.0" />
|
||||
<PackageReference Include="MailKit" Version="4.18.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
|
||||
<PackageReference Include="ZstdNet" Version="1.4.5" />
|
||||
<PackageReference Include="ZstdNet" Version="1.5.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
|
||||
<PackageReference Include="DocumentFormat.OpenXml" Version="3.5.1" />
|
||||
<PackageReference Include="NPOI" Version="2.7.6" />
|
||||
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.12" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -7,11 +7,11 @@ table td {
|
||||
}
|
||||
</style>
|
||||
|
||||
Last updated: 2026-09-14
|
||||
Last updated: 2026-09-15
|
||||
|
||||
| Component | Scope | Status | Date reviewed | Next steps | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| `SaCommonVS.sln` | .NET 10 migration build and tests | Migration complete; passing with warnings | 2026-09-14 | Continue the staged package review, beginning with framework-aligned BusinessMgr packages. | All supported projects target .NET 10 only. The low-risk package patches and removal of the redundant Registry reference pass the complete validation. The solution builds with zero errors and all 126 tests pass; BusinessMgr builds with 11 Control and 13 Portal tests passing. Xamarin remains isolated and unchanged. |
|
||||
| `SaCommonVS.sln` | .NET 10 migration build and tests | Migration complete; passing with warnings | 2026-09-15 | Continue the staged package review with the remaining framework-aligned and separately tested major updates. | All supported projects target .NET 10 only. MailKit 4.18.0, DocumentFormat.OpenXml 3.5.1, ZstdNet 1.5.7, and replacement of the obsolete ASP.NET Core 2.3 packages with the .NET 10 shared framework pass the complete validation. The solution builds with zero errors and all 137 tests pass; BusinessMgr builds with 11 Control and 13 Portal tests passing. Xamarin remains isolated and unchanged. |
|
||||
| `SacsStandardBase/Base/Utils/ImageUtils.cs` | ImageSharp wrapper | Covered for package upgrades | 2026-09-14 | Extend the suite when adding formats or changing resize policy. | Five in-memory tests cover PNG and JPEG metadata, invalid and truncated input, SVG recognition, format-preserving encoding, proportional landscape and portrait resizing, no-upscale behavior, and invalid constraints. |
|
||||
| `SacsStandardBase` JSON utilities and `SysId` converter | Newtonsoft.Json integration | Covered for package upgrades | 2026-09-14 | Retain the suite for future Newtonsoft.Json updates. | Six tests cover objects, arrays, nulls, serializer settings, valid and invalid parsing paths, dynamic access, `SysId` conversion, independent deep copies, nested collections, and constructor-value replacement. |
|
||||
| `SacsStandardDbas` provider and parameter creation | Microsoft.Data.SqlClient and registry integration | Initial package-upgrade coverage complete | 2026-09-14 | Expand into configured database integration tests before the planned SqlClient major upgrade. | Four database-free tests cover SQL versus forced ODBC connection selection, connection strings, values and nulls, explicit integer and binary types, SQL `DateTime2`, ODBC `DateTime`, precision normalization, and sentinel dates. The redundant Registry 5.0.0 package was removed; .NET 10 supplies the APIs and `NU1510` is gone. |
|
||||
@@ -19,7 +19,10 @@ Last updated: 2026-09-14
|
||||
| `SacsMobileXamarin` | Migration disposition | Isolated; retained for reference | 2026-09-10 | Keep outside the supported build unless a separately scoped resurrection or migration is approved. | Source is unchanged and available through `SaCommonVS.LegacyXamarin.sln`; see `docs/legacy-xamarin.md`. |
|
||||
| [`SacsMobileMaui`](../SacsMobileMaui/docs/component-reviews.md) | Project | .NET 10 migration complete; tracked in project docs | 2026-09-11 | Validate Apple targets on a Mac and continue API cleanup in the project tracker. | The shared project and both active mobile consumers target .NET 10. Windows runtime smoke tests pass, and Windows and Android Debug builds complete with zero errors. |
|
||||
| `SacsStandardBase/Base/Procs/SaProcess_Base.cs` | Class | In progress | 2026-09-09 | Complete the Process Base actions recorded in `topics.md`; review derived processes separately for cooperative polling. | Lifecycle state ownership and cancellation lock ordering were changed. Five focused tests pass. Remaining concerns include mixed sync/async execution, durable cancellation outcome, cancellation exception handling, disposal, and status synchronization. |
|
||||
| `SacsStandardBase/Base/Email/SaEmailConsole.cs` | Class | Dependency upgrade complete; security action still required | 2026-09-12 | Separately restore SMTP certificate validation and require the configured TLS mode. | MailKit and MimeKit 4.17.0 pass the Common and downstream validation suites without vulnerability warnings. Message construction is covered for addressing, bodies, attachments, content IDs, default filenames, and tags. The current SMTP client still accepts every server certificate. |
|
||||
| `SacsStandardBase/Base/Email/SaEmailConsole.cs` | Class | Dependency upgrade complete; security action still required | 2026-09-15 | Separately restore SMTP certificate validation and require the configured TLS mode. | MailKit 4.18.0 and its resolved MimeKit dependency pass the Common and downstream validation suites without vulnerability warnings. Message construction is covered for addressing, bodies, attachments, content IDs, default filenames, and tags. The current SMTP client still accepts every server certificate. |
|
||||
| `SacsStandardBase/Base/Helpers/SacsContentTypeHelper.cs` | Class | Framework dependency modernised | 2026-09-15 | Retain the content-type tests for future framework updates. | Removed direct references to the obsolete ASP.NET Core 2.3 `Http` and `StaticFiles` packages and now consumes their APIs from the .NET 10 `Microsoft.AspNetCore.App` shared framework. Ten regression cases cover filename lookup, generic form-file fallback, defaults, and bidirectional MIME mappings. |
|
||||
| `SacsStandardBase/Base/Net/SacsHttpClient.cs` | Class | Zstandard dependency upgraded and covered | 2026-09-15 | Retain the loopback response test for future HTTP and ZstdNet updates. | ZstdNet 1.5.7 replaces 1.4.5. An in-process HTTP test exercises the real response path with native Zstandard compression and verifies successful UTF-8 decompression without external network access. |
|
||||
| `SacsStandardProc/Proc/Excel/SaMsSpreadsheet_OpenXml.cs` | Class | Dependency upgrade complete; implementation remains incomplete | 2026-09-15 | Scope functional completion and dedicated wrapper tests separately if this implementation is to be revived. | DocumentFormat.OpenXml 3.5.1 builds and passes the existing spreadsheet and downstream validation. The Open XML implementation contains numerous pre-existing unsupported or placeholder operations, so this update does not present it as production-complete. |
|
||||
| `SacsStandardProc/Proc/Excel/SaMsSpreadsheet_POI.cs` | Class | Dependency upgrade complete | 2026-09-12 | Retain the focused spreadsheet suite for future NPOI updates; do not adopt NPOI 2.8.0 without an explicit licensing decision. | NPOI 2.7.6 is paired with an explicit `System.Security.Cryptography.Xml` 10.0.12 reference and NuGet reports no vulnerable packages for `SacsStandardProc`. Nullable date and indexed-colour API changes were adapted. Ten focused tests and all 111 Common tests pass; BusinessMgr builds and its 21 tests pass. |
|
||||
| `SacsStandardBase/Base/Helpers/SacsEncryptionHelper.cs` and `SacsStandardBase/Base/Data/SacsAesIvCrypter.cs` | Classes | Reviewed; action required | 2026-09-08 | Design a versioned authenticated-encryption format with legacy migration and tamper tests. | Current CBC encryption is unauthenticated; password-based key derivation uses a fixed salt and low iteration count. |
|
||||
| `eng/validate.ps1` | Repository validation | Complete; passing | 2026-09-12 | Use as the standard validation entry point and extend it when repository-wide checks change. | Builds serially, runs 10 focused and 111 full tests, audits the NPOI-owning project, verifies changed-file line endings and diffs, then invokes BusinessMgr validation. |
|
||||
| `eng/validate.ps1` | Repository validation | Complete; passing | 2026-09-15 | Use as the standard validation entry point and extend it when repository-wide checks change. | Builds serially, runs the 10-test focused NPOI suite and all 137 Common tests, audits the NPOI-owning project, verifies changed-file line endings and diffs, then invokes BusinessMgr validation. |
|
||||
|
||||
+3
-1
@@ -7,7 +7,7 @@ table td {
|
||||
}
|
||||
</style>
|
||||
|
||||
Last updated: 2026-09-14
|
||||
Last updated: 2026-09-15
|
||||
|
||||
## Prioritised Topics to Be Actioned
|
||||
|
||||
@@ -44,6 +44,8 @@ Last updated: 2026-09-14
|
||||
|
||||
| Topic | Date noted | Date started | Date completed | Outcome |
|
||||
|---|---|---|---|---|
|
||||
| Update ZstdNet and cover HTTP decompression | 2026-09-15 | 2026-09-15 | 2026-09-15 | Updated ZstdNet from 1.4.5 to 1.5.7. Added an in-process loopback HTTP test that creates a Zstandard-compressed UTF-8 response and verifies status, headers, native decompression, and decoded content through `SacsHttpClient`. The focused test, all 137 Common tests, and downstream BusinessMgr validation pass. |
|
||||
| Apply the next low-risk Common package updates | 2026-09-15 | 2026-09-15 | 2026-09-15 | Updated MailKit from 4.17.0 to 4.18.0 and DocumentFormat.OpenXml from 3.3.0 to 3.5.1. Replaced the obsolete ASP.NET Core 2.3 `Http` and `StaticFiles` package references with the .NET 10 `Microsoft.AspNetCore.App` shared-framework reference. Added ten content-type regression cases; email, spreadsheet, all 136 Common tests, and downstream BusinessMgr validation pass. |
|
||||
| Migrate Common tests from MSTest to NUnit | 2026-09-14 | 2026-09-14 | 2026-09-15 | Replaced MSTest with NUnit 4.6.1, NUnit3TestAdapter 6.3.0, and NUnit.Analyzers 4.15.0. Converted all 27 fixtures and 126 tests to NUnit's constraint-style `Assert.That` model, removed unused MSTest `TestContext` template scaffolding, and brought every migrated fixture into line with the repository's section-comment convention. Full Common and downstream BusinessMgr validation, including coverage collection, passes. |
|
||||
| Modernise Common test tooling and coverage collection | 2026-09-14 | 2026-09-14 | 2026-09-14 | Updated Microsoft.NET.Test.Sdk from 16.5.0 to 18.10.0, MSTest adapter and framework from 2.1.0 to 4.4.0, and coverlet collector from 1.2.0 to 10.0.1 with private-assets metadata. Replaced legacy exception assertions, corrected the `TestContext` property, and fixed 39 reversed expected/actual assertions identified by the MSTest 4 analyzers. All 126 Common tests, 11 BusinessMgr Control tests, and 13 BusinessMgr Portal tests pass. The validation scripts offer `-CollectCoverage`, which verifies non-empty Cobertura reports across Common and both BusinessMgr suites. |
|
||||
| Remove redundant Microsoft.Win32.Registry package | 2026-09-10 | 2026-09-14 | 2026-09-14 | Removed the direct 5.0.0 package reference from `SacsStandardDbas`; .NET 10 supplies the required registry APIs. Common and BusinessMgr restore, build, and all 126 Common, 11 Control, and 13 Portal tests pass. The `NU1510` warning no longer appears. |
|
||||
|
||||
Reference in New Issue
Block a user