文件名清理改为固定的 Windows 非法字符集,Linux CI 现在也会将 : 替换为 -。
清除了 DOCX 测试的空引用警告,以及 3 处 xUnit Assert.Single 分析器警告。
This commit is contained in:
1 parent
6e2eaad0fa
commit
8a72c1582c
4 files changed
+27
-14
No files matched your search
@@ -5,6 +5,11 @@ namespace Jiaowu.Api.Infrastructure.Files;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class DownloadFileName
|
public static class DownloadFileName
|
||||||
{
|
{
|
||||||
|
// Do not use Path.GetInvalidFileNameChars(): its result is platform-specific,
|
||||||
|
// while downloaded names must remain usable on Windows regardless of where
|
||||||
|
// the API is built or hosted.
|
||||||
|
private static readonly char[] WindowsInvalidFileNameChars = ['<', '>', ':', '"', '/', '\\', '|', '?', '*'];
|
||||||
|
|
||||||
public static string Export(string title, string extension, params string?[] parts) =>
|
public static string Export(string title, string extension, params string?[] parts) =>
|
||||||
Build(title, extension, includeTimestamp: true, parts);
|
Build(title, extension, includeTimestamp: true, parts);
|
||||||
|
|
||||||
@@ -33,9 +38,8 @@ public static class DownloadFileName
|
|||||||
private static string Clean(string? value)
|
private static string Clean(string? value)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(value)) return string.Empty;
|
if (string.IsNullOrWhiteSpace(value)) return string.Empty;
|
||||||
var invalid = Path.GetInvalidFileNameChars();
|
|
||||||
var cleaned = new string(value.Trim().Select(character =>
|
var cleaned = new string(value.Trim().Select(character =>
|
||||||
invalid.Contains(character) ? '-' : character).ToArray());
|
WindowsInvalidFileNameChars.Contains(character) || char.IsControl(character) ? '-' : character).ToArray());
|
||||||
return cleaned.Trim('.', ' ');
|
return cleaned.Trim('.', ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,12 +110,14 @@ public sealed class CourseSelectionsControllerTests
|
|||||||
.OrderBy(x => x.UserId)
|
.OrderBy(x => x.UserId)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
Assert.Equal(2, resultNotifications.Count);
|
Assert.Equal(2, resultNotifications.Count);
|
||||||
var selectedNotification = Assert.Single(resultNotifications
|
var selectedNotification = Assert.Single(
|
||||||
.Where(x => x.UserId == data.EnrolledUserId));
|
resultNotifications,
|
||||||
|
x => x.UserId == data.EnrolledUserId);
|
||||||
Assert.Contains("最终选中 1 门", selectedNotification.Content);
|
Assert.Contains("最终选中 1 门", selectedNotification.Content);
|
||||||
Assert.Contains("《程序设计基础》", selectedNotification.Content);
|
Assert.Contains("《程序设计基础》", selectedNotification.Content);
|
||||||
var waitlistNotification = Assert.Single(resultNotifications
|
var waitlistNotification = Assert.Single(
|
||||||
.Where(x => x.UserId == data.FirstWaiterUserId));
|
resultNotifications,
|
||||||
|
x => x.UserId == data.FirstWaiterUserId);
|
||||||
Assert.Contains("本轮未选中课程", waitlistNotification.Content);
|
Assert.Contains("本轮未选中课程", waitlistNotification.Content);
|
||||||
Assert.Contains("候补未成功 1 门", waitlistNotification.Content);
|
Assert.Contains("候补未成功 1 门", waitlistNotification.Content);
|
||||||
Assert.Equal(NotificationCategory.CourseSelection, waitlistNotification.Category);
|
Assert.Equal(NotificationCategory.CourseSelection, waitlistNotification.Category);
|
||||||
|
|||||||
@@ -43,16 +43,19 @@ public sealed class GradeAnalysisWordReportGeneratorTests
|
|||||||
Assert.True(bytes.Length > 10_000);
|
Assert.True(bytes.Length > 10_000);
|
||||||
using var stream = new MemoryStream(bytes);
|
using var stream = new MemoryStream(bytes);
|
||||||
using var document = WordprocessingDocument.Open(stream, false);
|
using var document = WordprocessingDocument.Open(stream, false);
|
||||||
var text = document.MainDocumentPart!.Document.InnerText;
|
var mainDocumentPart = document.MainDocumentPart
|
||||||
|
?? throw new InvalidOperationException("Generated document has no main document part.");
|
||||||
|
var text = mainDocumentPart.Document?.InnerText
|
||||||
|
?? throw new InvalidOperationException("Generated document has no document body.");
|
||||||
Assert.Contains("成绩分析报告", text);
|
Assert.Contains("成绩分析报告", text);
|
||||||
Assert.Contains("同课程教学班对比", text);
|
Assert.Contains("同课程教学班对比", text);
|
||||||
Assert.Contains("各范围基准", text);
|
Assert.Contains("各范围基准", text);
|
||||||
Assert.Contains("历年成绩趋势", text);
|
Assert.Contains("历年成绩趋势", text);
|
||||||
Assert.Contains("行政班组成", text);
|
Assert.Contains("行政班组成", text);
|
||||||
Assert.Contains("计科一班", text);
|
Assert.Contains("计科一班", text);
|
||||||
Assert.Equal(3, document.MainDocumentPart.ImageParts.Count());
|
Assert.Equal(3, mainDocumentPart.ImageParts.Count());
|
||||||
Assert.Equal(2, document.MainDocumentPart.HeaderParts.Count());
|
Assert.Equal(2, mainDocumentPart.HeaderParts.Count());
|
||||||
Assert.Equal(2, document.MainDocumentPart.FooterParts.Count());
|
Assert.Equal(2, mainDocumentPart.FooterParts.Count());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -76,10 +79,13 @@ public sealed class GradeAnalysisWordReportGeneratorTests
|
|||||||
Assert.True(bytes.Length > 8_000);
|
Assert.True(bytes.Length > 8_000);
|
||||||
using var stream = new MemoryStream(bytes);
|
using var stream = new MemoryStream(bytes);
|
||||||
using var document = WordprocessingDocument.Open(stream, false);
|
using var document = WordprocessingDocument.Open(stream, false);
|
||||||
var text = document.MainDocumentPart!.Document.InnerText;
|
var mainDocumentPart = document.MainDocumentPart
|
||||||
|
?? throw new InvalidOperationException("Generated document has no main document part.");
|
||||||
|
var text = mainDocumentPart.Document?.InnerText
|
||||||
|
?? throw new InvalidOperationException("Generated document has no document body.");
|
||||||
Assert.Contains("科目总体成绩分析报告", text);
|
Assert.Contains("科目总体成绩分析报告", text);
|
||||||
Assert.Contains("学生来源学院对比", text);
|
Assert.Contains("学生来源学院对比", text);
|
||||||
Assert.Contains("教学班横向比较", text);
|
Assert.Contains("教学班横向比较", text);
|
||||||
Assert.Single(document.MainDocumentPart.ImageParts);
|
Assert.Single(mainDocumentPart.ImageParts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loaded 3 of 4 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user