using Kit.Helpers.SqlHelperAbstract; using Server.WatchBody.Core.Dal.Src.Domain; using Server.WatchBody.Core.Dal.Src.Repository; using Xunit; namespace Server.WatchBody.Core.Tests; // Тесты WorkoutRepository / WorkoutSetRepository / CommandLogRepository // по repository_tests\WorkoutRepository.md и WorkoutSetRepository.md. public class WorkoutRepositoryTests { private static readonly Guid W1 = Guid.Parse("aaaa0000-0000-0000-0000-000000000001"); [Fact] public void Insert_1Основной_5Параметров_NullВерсия() { var expArgs = new ConnectionString().PrepareExecute("src.workout_insert") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_id", W1) .AddParameter("p_program_version_id", DBNull.Value) .AddParameter("p_started_at", new DateTime(2026, 10, 17, 18, 0, 0)) .AddParameter("p_session_kind", "normal") .BuildParams(); var cs = ConnectionStringTest.Scalar(expArgs, W1); var result = new WorkoutRepository(cs).Insert(1, new Workout { Id = W1, StartedAt = new DateTime(2026, 10, 17, 18, 0, 0), SessionKind = "normal", }); Assert.Equal(W1, result); } [Fact] public void Update_1Основной_9Параметров() { var expArgs = new ConnectionString().PrepareExecute("src.workout_update") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_id", W1) .AddParameter("p_ended_at", new DateTime(2026, 10, 17, 19, 10, 0)) .AddParameter("p_status", "finished") .AddParameter("p_session_kind", "normal") .AddParameter("p_avg_hr", 118) .AddParameter("p_facts_json", "{\"schema\":\"workout-facts/1\"}") .AddParameter("p_fit_file_id", "TEST-fit-1") .AddParameter("p_hr_recovery_s", 240) .BuildParams(); var cs = ConnectionStringTest.Scalar(expArgs, 1); var result = new WorkoutRepository(cs).Update(1, new Workout { Id = W1, EndedAt = new DateTime(2026, 10, 17, 19, 10, 0), Status = "finished", SessionKind = "normal", AvgHr = 118, FactsJson = "{\"schema\":\"workout-facts/1\"}", FitFileId = "TEST-fit-1", HrRecoveryS = 240, }); Assert.Equal(1, result); } [Fact] public void Select_1Основной_Sets2ПоПорядку() { var expArgs = new ConnectionString().PrepareExecute("src.workout_select") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_status", DBNull.Value) .AddParameter("p_date_from", DBNull.Value) .AddParameter("p_date_to", DBNull.Value) .BuildParams(); var sets = """[{"id":"bbbb0000-0000-0000-0000-000000000001","workout_id":"aaaa0000-0000-0000-0000-000000000001","athleteId":1,"exercise_id":null,"seq":1,"weight_kg":50.0,"reps":15,"done_at":"2026-10-17T18:05:00","source":"voice","in_plan":true,"rpe":null,"knee_pain":null},{"id":"bbbb0000-0000-0000-0000-000000000002","workout_id":"aaaa0000-0000-0000-0000-000000000001","athleteId":1,"exercise_id":null,"seq":2,"weight_kg":52.5,"reps":15,"done_at":"2026-10-17T18:10:00","source":"voice","in_plan":true,"rpe":null,"knee_pain":null}]"""; var table = TestInfra.Table(TestInfra.WorkoutCols, [W1, 1, DBNull.Value, new DateTime(2026, 10, 17, 18, 0, 0), DBNull.Value, "active", "normal", DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, sets, DBNull.Value]); var cs = new ConnectionStringTest(expArgs, table); var rows = new WorkoutRepository(cs).Select(new WorkoutFilter { AthleteId = 1 }).ToList(); var w = Assert.Single(rows); Assert.Equal(2, w.Sets.Count()); Assert.Equal(1, w.Sets.First().Seq); } [Fact] public void Select_2Граничный_Пустая() { var expArgs = new ConnectionString().PrepareExecute("src.workout_select") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_status", DBNull.Value) .AddParameter("p_date_from", DBNull.Value) .AddParameter("p_date_to", DBNull.Value) .BuildParams(); var cs = new ConnectionStringTest(expArgs, TestInfra.Table(TestInfra.WorkoutCols)); Assert.Empty(new WorkoutRepository(cs).Select(new WorkoutFilter { AthleteId = 1 })); } [Fact] public void Get_1Основной_SetsИCommands() { var expArgs = new ConnectionString().PrepareExecute("src.workout_get") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_id", W1) .BuildParams(); var sets = """[{"id":"bbbb0000-0000-0000-0000-000000000001","workout_id":"aaaa0000-0000-0000-0000-000000000001","athleteId":1,"exercise_id":null,"seq":1,"weight_kg":50.0,"reps":15,"done_at":"2026-10-17T18:05:00","source":"voice","in_plan":true,"rpe":null,"knee_pain":null}]"""; var commands = """[{"id":"cccc0000-0000-0000-0000-000000000001","workout_id":"aaaa0000-0000-0000-0000-000000000001","t_offset_s":65,"recognized_text":"TEST","semantics":{"cmd":"weight"},"accepted":true}]"""; var table = TestInfra.Table(TestInfra.WorkoutCols, [W1, 1, DBNull.Value, new DateTime(2026, 10, 17, 18, 0, 0), DBNull.Value, "active", "normal", DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, sets, commands]); var cs = new ConnectionStringTest(expArgs, table); var w = new WorkoutRepository(cs).Get(1, W1); Assert.NotNull(w); Assert.Single(w.Sets); Assert.Single(w.Commands); Assert.Equal(65, w.Commands.First().TOffsetS); } [Fact] public void Get_2Граничный_Null() { var expArgs = new ConnectionString().PrepareExecute("src.workout_get") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_id", W1) .BuildParams(); var cs = new ConnectionStringTest(expArgs, TestInfra.Table(TestInfra.WorkoutCols)); Assert.Null(new WorkoutRepository(cs).Get(1, W1)); } } public class WorkoutSetRepositoryTests { private static readonly Guid S1 = Guid.Parse("bbbb0000-0000-0000-0000-000000000001"); private static readonly Guid W1 = Guid.Parse("aaaa0000-0000-0000-0000-000000000001"); [Fact] public void Insert_1Основной_12Параметров() { var expArgs = new ConnectionString().PrepareExecute("src.workout_set_insert") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_id", S1) .AddParameter("p_workout_id", W1) .AddParameter("p_exercise_id", DBNull.Value) .AddParameter("p_seq", 1) .AddParameter("p_weight_kg", 50.0m) .AddParameter("p_reps", 15) .AddParameter("p_done_at", new DateTime(2026, 10, 17, 18, 5, 0)) .AddParameter("p_source", "voice") .AddParameter("p_in_plan", true) .AddParameter("p_rpe", DBNull.Value) .AddParameter("p_knee_pain", DBNull.Value) .BuildParams(); var cs = ConnectionStringTest.Scalar(expArgs, S1); var result = new WorkoutSetRepository(cs).Insert(new WorkoutSet { Id = S1, WorkoutId = W1, AthleteId = 1, ExerciseId = null, Seq = 1, WeightKg = 50.0m, Reps = 15, DoneAt = new DateTime(2026, 10, 17, 18, 5, 0), Source = "voice", InPlan = true, Rpe = null, KneePain = null, }); Assert.Equal(S1, result); } [Fact] public void Get_1Основной_Сущность() { var expArgs = new ConnectionString().PrepareExecute("src.workout_set_get") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_id", S1) .BuildParams(); var table = TestInfra.Table(TestInfra.SetCols, [S1, W1, 1, DBNull.Value, 1, 50.0m, 15, new DateTime(2026, 10, 17, 18, 5, 0), "voice", true, DBNull.Value, DBNull.Value]); var cs = new ConnectionStringTest(expArgs, table); var s = new WorkoutSetRepository(cs).Get(1, S1); Assert.NotNull(s); Assert.Null(s.Rpe); Assert.Equal(50.0m, s.WeightKg); } [Fact] public void Get_2Граничный_Null() { var expArgs = new ConnectionString().PrepareExecute("src.workout_set_get") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_id", S1) .BuildParams(); var cs = new ConnectionStringTest(expArgs, TestInfra.Table(TestInfra.SetCols)); Assert.Null(new WorkoutSetRepository(cs).Get(1, S1)); } } public class CommandLogRepositoryTests { private static readonly Guid C1 = Guid.Parse("cccc0000-0000-0000-0000-000000000001"); private static readonly Guid W1 = Guid.Parse("aaaa0000-0000-0000-0000-000000000001"); [Fact] public void Insert_1Основной_7Параметров() { var expArgs = new ConnectionString().PrepareExecute("src.command_log_insert") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_id", C1) .AddParameter("p_workout_id", W1) .AddParameter("p_t_offset_s", 65) .AddParameter("p_recognized_text", "TEST-вес пятьдесят") .AddParameter("p_semantics", "{\"cmd\":\"weight\",\"weight\":50}") .AddParameter("p_accepted", true) .BuildParams(); var cs = ConnectionStringTest.Scalar(expArgs, C1); var result = new CommandLogRepository(cs).Insert(1, new CommandLog { Id = C1, WorkoutId = W1, TOffsetS = 65, RecognizedText = "TEST-вес пятьдесят", Semantics = "{\"cmd\":\"weight\",\"weight\":50}", Accepted = true, }); Assert.Equal(C1, result); } [Fact] public void Select_1Основной_1Сущность() { var expArgs = new ConnectionString().PrepareExecute("src.command_log_select") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_workout_id", W1) .BuildParams(); var table = TestInfra.Table(TestInfra.CommandCols, [C1, W1, 65, "TEST-вес пятьдесят", "{\"cmd\":\"weight\"}", true]); var cs = new ConnectionStringTest(expArgs, table); var rows = new CommandLogRepository(cs).Select(1, W1).ToList(); var c = Assert.Single(rows); Assert.True(c.Accepted); } [Fact] public void Select_2Граничный_Пустая() { var expArgs = new ConnectionString().PrepareExecute("src.command_log_select") .AsStoredProcedure() .AddParameter("p_athlete_id", 1) .AddParameter("p_workout_id", W1) .BuildParams(); var cs = new ConnectionStringTest(expArgs, TestInfra.Table(TestInfra.CommandCols)); Assert.Empty(new CommandLogRepository(cs).Select(1, W1)); } }