using TrainingPlanner.Application; using TrainingPlanner.Domain; namespace TrainingPlanner.Tests; public class PlanEditingTests { private readonly PlannerOptions options = new() { DefaultWeekCount = 4, DefaultSetsCount = 3, DefaultRestMinutes = 1.5m, DefaultRepetitions = "10" }; [Fact] public void MonthlyCopyPreservesPrescriptionAndCanBeEditedIndependently() { var plan = CreatePlan(); var workout = plan.Weeks[0].Workouts[0]; workout.Duration = "1 ч 15 мин"; var exercise = workout.Blocks[0].Exercises[0]; exercise.Id = 17; exercise.Weight = "Подобрать"; exercise.Repetitions = "По 10 (1 RIR)"; exercise.WarmupSets = "1 — гриф; 2 — 40 кг"; exercise.Notes = "Без рывков"; exercise.IntensityPercent = 80; exercise.RequiresVideo = true; exercise.VideoUrl = "https://disk.yandex.ru/i/example"; var copy = new PlanCopier().Copy(plan, "Октябрь"); var copiedWorkout = copy.Weeks[0].Workouts[0]; var copied = copiedWorkout.Blocks[0].Exercises[0]; Assert.Equal(0, copied.Id); Assert.Equal(workout.Duration, copiedWorkout.Duration); Assert.Equal(exercise.WarmupSets, copied.WarmupSets); Assert.Equal(exercise.Notes, copied.Notes); Assert.Equal(exercise.Weight, copied.Weight); Assert.Equal(exercise.Repetitions, copied.Repetitions); Assert.Equal(exercise.IntensityPercent, copied.IntensityPercent); Assert.Equal(exercise.VideoUrl, copied.VideoUrl); Assert.True(copied.RequiresVideo); copied.Weight = "60"; copiedWorkout.Blocks[0].SetsCount = 4; Assert.Equal("Подобрать", exercise.Weight); Assert.Equal(3, workout.Blocks[0].SetsCount); } [Fact] public void RestIncludesLastApproachAndDoesNotMultiplyByRepetitions() { var workout = CreatePlan().Weeks[0].Workouts[0]; workout.Blocks[0].RestMinutes = 2; workout.Blocks[0].Exercises[0].Repetitions = "По 10 (1 RIR)"; Assert.Equal(6m, WorkoutTotals.RestMinutes(workout)); workout.Blocks.Add(new WorkoutBlock { SetsCount = 2, RestMinutes = 1.5m }); Assert.Equal(9m, WorkoutTotals.RestMinutes(workout)); Assert.Equal(0m, WorkoutTotals.RestMinutes(new Workout())); } [Fact] public void ValidationAllowsTextWeightAndRejectsSupersets() { var plan = CreatePlan(); var block = plan.Weeks[0].Workouts[0].Blocks[0]; block.Exercises[0].Weight = "Подобрать / собственный вес"; new PlanValidator().Validate(plan); block.Exercises.Add(new WorkoutExercise { Name = "Второе", Repetitions = "10" }); Assert.Throws(() => new PlanValidator().Validate(plan)); } [Theory] [InlineData(0, 1.5, 80)] [InlineData(3, -1, 80)] [InlineData(3, 2, 101)] [InlineData(3, 2, -1)] public void ValidationRejectsInvalidPrescription(int sets, double rest, int intensity) { var plan = CreatePlan(); var block = plan.Weeks[0].Workouts[0].Blocks[0]; block.SetsCount = sets; block.RestMinutes = (decimal)rest; block.Exercises[0].IntensityPercent = intensity; Assert.Throws(() => new PlanValidator().Validate(plan)); } [Fact] public void MovePreservesPrescriptionAndValidationRenumbersBlocks() { var plan = CreatePlan(); var workout = plan.Weeks[0].Workouts[0]; var original = workout.Blocks[0]; original.Exercises[0].WarmupSets = "Гриф"; workout.Blocks.Add(new PlanFactory(options).CreateBlock(new LibraryExercise { Name = "Тяга" })); new BlockEditor().Move(workout, 0, 1); new PlanValidator().Validate(plan); Assert.Same(original, workout.Blocks[1]); Assert.Equal(1, original.Position); Assert.Equal("Гриф", original.Exercises[0].WarmupSets); Assert.Throws(() => PlanValidator.ValidateVideoUrl("javascript:alert(1)")); } private TrainingPlan CreatePlan() { var factory = new PlanFactory(options); var plan = factory.Create(1, "Сентябрь"); plan.Weeks[0].Workouts.Add(new Workout { Name = "Ноги", Blocks = [factory.CreateBlock(new LibraryExercise { Name = "Приседания" })] }); return plan; } }