This commit is contained in:
DmitriyFadin
2026-09-30 15:05:05 +03:00
commit ca18fc196d
122 changed files with 8794 additions and 0 deletions
@@ -0,0 +1,59 @@
using TrainingPlanner.Application;
namespace TrainingPlanner.Tests;
public class ExerciseImportTests
{
private readonly ExerciseImportOptions options = new() { MaxRows = 1000, MaxClipboardCharacters = 100000 };
[Fact]
public void ClipboardPreservesEmptyCellsAndExcelQuotedValues()
{
var rows = new ClipboardTableParser(options).Parse("\"Жим \"\"узкий\"\"\nсидя\"\thttps://example.com/video\r\nТяга\t\r\n\t\r\n");
Assert.Equal(2, rows.Count);
Assert.Equal("Жим \"узкий\"\nсидя", rows[0][0]);
Assert.Equal("https://example.com/video", rows[0][1]);
Assert.Equal("", rows[1][1]);
}
[Fact]
public void ClipboardHandlesLargePasteAndAllLineEndings()
{
var parser = new ClipboardTableParser(options);
Assert.Equal(500, parser.Parse(string.Join('\n', Enumerable.Repeat("Упражнение\thttps://example.com", 500))).Count);
Assert.Equal(3, parser.Parse("А\rБ\nВ\r\n").Count);
Assert.Empty(parser.Parse("\r\n\t\r\n"));
}
[Fact]
public void ClipboardRejectsUnclosedQuotesAndConfiguredLimits()
{
var parser = new ClipboardTableParser(new ExerciseImportOptions { MaxRows = 1, MaxClipboardCharacters = 20 });
Assert.Throws<InvalidOperationException>(() => parser.Parse("\"Открытая ячейка"));
Assert.Throws<InvalidOperationException>(() => parser.Parse("А\nБ"));
Assert.Throws<InvalidOperationException>(() => parser.Parse(new string('a', 21)));
}
[Fact]
public void ValidationSkipsBlankRowsAndAllowsMissingVideo()
{
var rows = new ExerciseImportValidator(options).Validate([
new(), new() { Name = " Тяга ", VideoUrl = " " },
new() { Name = "Жим", VideoUrl = " https://example.com " }]);
Assert.Equal(2, rows.Count);
Assert.Equal("Тяга", rows[0].Name);
Assert.Equal("", rows[0].VideoUrl);
Assert.Equal("https://example.com", rows[1].VideoUrl);
}
[Fact]
public void ValidationReportsOriginalRowAndRejectsUnsafeLinks()
{
var validator = new ExerciseImportValidator(options);
var error = Assert.Throws<InvalidOperationException>(() => validator.Validate([
new(), new() { Name = "Жим", VideoUrl = "javascript:alert(1)" }]));
Assert.Contains("Строка 2", error.Message);
Assert.Throws<InvalidOperationException>(() => validator.Validate([new() { VideoUrl = "https://example.com" }]));
Assert.Throws<InvalidOperationException>(() => validator.Validate([new()]));
}
}