From c6ce528ba1aa9f822543e927a86383fd267bd450 Mon Sep 17 00:00:00 2001 From: Alex Mickelson Date: Mon, 4 Dec 2023 12:27:06 -0700 Subject: [PATCH] testing markdown storage and retrieval --- Management.Test/Management.Test.csproj | 1 + Management.Test/Markdown/FileStorageTests.cs | 261 ++++++++++++++++++ .../ViewModels/MonthDetailTests.cs | 6 +- Management.Web/Pages/AssignmentFormPage.razor | 1 - Management.Web/Pages/Course.razor | 1 - Management.Web/Pages/Index.razor | 1 - Management.Web/Pages/QuizFormPage.razor | 1 - .../AssignmentMarkdownEditor.razor | 9 - .../AssignmentTemplateManagement.razor | 125 --------- .../Assignment/Templates/TemplateEditor.razor | 96 ------- .../Assignment/AssignmentSubmissionType.cs | 28 ++ .../{ => Assignment}/AssignmentTemplate.cs | 0 .../Local/{ => Assignment}/LocalAssignment.cs | 35 --- .../{ => Assignment}/LocalAssignmentGroup.cs | 0 .../Models/Local/Assignment/RubricItem.cs | 9 + Management/Models/Local/LocalCourse.cs | 2 - .../Models/Local/{ => Quiz}/LocalQuiz.cs | 0 .../Local/{ => Quiz}/LocalQuizQuestion.cs | 0 .../{ => Quiz}/LocalQuizQuestionAnswer.cs | 0 .../Services/Files/FileConfiguration.cs | 17 ++ .../{ => Files}/FileStorageManager.cs | 84 ++---- .../Files/LoadCourseFromFileException.cs | 3 + .../Services/Files/LoadMarkdownCourse.cs | 127 +++++++++ 23 files changed, 467 insertions(+), 340 deletions(-) create mode 100644 Management.Test/Markdown/FileStorageTests.cs delete mode 100644 Management.Web/Shared/Module/Assignment/Templates/AssignmentTemplateManagement.razor delete mode 100644 Management.Web/Shared/Module/Assignment/Templates/TemplateEditor.razor create mode 100644 Management/Models/Local/Assignment/AssignmentSubmissionType.cs rename Management/Models/Local/{ => Assignment}/AssignmentTemplate.cs (100%) rename Management/Models/Local/{ => Assignment}/LocalAssignment.cs (83%) rename Management/Models/Local/{ => Assignment}/LocalAssignmentGroup.cs (100%) create mode 100644 Management/Models/Local/Assignment/RubricItem.cs rename Management/Models/Local/{ => Quiz}/LocalQuiz.cs (100%) rename Management/Models/Local/{ => Quiz}/LocalQuizQuestion.cs (100%) rename Management/Models/Local/{ => Quiz}/LocalQuizQuestionAnswer.cs (100%) create mode 100644 Management/Services/Files/FileConfiguration.cs rename Management/Services/{ => Files}/FileStorageManager.cs (66%) create mode 100644 Management/Services/Files/LoadCourseFromFileException.cs create mode 100644 Management/Services/Files/LoadMarkdownCourse.cs diff --git a/Management.Test/Management.Test.csproj b/Management.Test/Management.Test.csproj index 1c65369..abf1b49 100644 --- a/Management.Test/Management.Test.csproj +++ b/Management.Test/Management.Test.csproj @@ -12,6 +12,7 @@ + diff --git a/Management.Test/Markdown/FileStorageTests.cs b/Management.Test/Markdown/FileStorageTests.cs new file mode 100644 index 0000000..a6a8bc2 --- /dev/null +++ b/Management.Test/Markdown/FileStorageTests.cs @@ -0,0 +1,261 @@ +using LocalModels; +using Management.Services; +using Microsoft.Extensions.Logging.Abstractions; +using NSubstitute; +using NUnit.Framework.Internal; + +public class FileStorageTests +{ + private FileStorageManager fileManager { get; set; } + + + private string setupTempDirectory() + { + var tempDirectory = Path.GetTempPath(); + var storageDirectory = tempDirectory + "fileStorageTests"; + Console.WriteLine(storageDirectory); + if (!Directory.Exists(storageDirectory)) + Directory.CreateDirectory(storageDirectory); + else + { + var di = new DirectoryInfo(storageDirectory); + + foreach (FileInfo file in di.GetFiles()) + { + file.Delete(); + } + foreach (DirectoryInfo dir in di.GetDirectories()) + { + dir.Delete(true); + } + } + + return storageDirectory; + } + + [SetUp] + public void SetUp() + { + var storageDirectory = setupTempDirectory(); + + var fileManagerLogger = new MyLogger(NullLogger.Instance); + var markdownLoaderLogger = new MyLogger(NullLogger.Instance); + + Environment.SetEnvironmentVariable("storageDirectory", storageDirectory); + var markdownLoader = new CourseMarkdownLoader(markdownLoaderLogger); + fileManager = new FileStorageManager(fileManagerLogger, markdownLoader); + } + + [Test] + public async Task EmptyCourse_CanBeSavedAndLoaded() + { + LocalCourse testCourse = new LocalCourse + { + Settings = new() + { + Name = "test empty course", + }, + Modules = [] + }; + + await fileManager.SaveCourseAsync(testCourse); + + var loadedCourses = await fileManager.LoadSavedMarkdownCourses(); + var loadedCourse = loadedCourses.First(c => c.Settings.Name == testCourse.Settings.Name); + + loadedCourse.Should().BeEquivalentTo(testCourse); + } + + [Test] + public async Task CourseSettings_CanBeSavedAndLoaded() + { + LocalCourse testCourse = new() + { + Settings = new() + { + AssignmentGroups = [], + Name = "Test Course with settings", + DaysOfWeek = [DayOfWeek.Monday, DayOfWeek.Wednesday], + StartDate = new DateTime(), + EndDate = new DateTime(), + DefaultDueTime = new() { Hour = 1, Minute = 59 }, + }, + Modules = [] + }; + + await fileManager.SaveCourseAsync(testCourse); + + var loadedCourses = await fileManager.LoadSavedMarkdownCourses(); + var loadedCourse = loadedCourses.First(c => c.Settings.Name == testCourse.Settings.Name); + + loadedCourse.Settings.Should().BeEquivalentTo(testCourse.Settings); + } + + + [Test] + public async Task EmptyCourseModules_CanBeSavedAndLoaded() + { + LocalCourse testCourse = new() + { + Settings = new() + { + Name = "Test Course with modules", + }, + Modules = [ + new() { + Name="test module 1", + Assignments= [], + Quizzes=[] + } + ] + }; + + await fileManager.SaveCourseAsync(testCourse); + + var loadedCourses = await fileManager.LoadSavedMarkdownCourses(); + var loadedCourse = loadedCourses.First(c => c.Settings.Name == testCourse.Settings.Name); + + loadedCourse.Modules.Should().BeEquivalentTo(testCourse.Modules); + } + + [Test] + public async Task CourseModules_WithAssignments_CanBeSavedAndLoaded() + { + LocalCourse testCourse = new() + { + Settings = new() + { + Name = "Test Course with modules and assignments", + }, + Modules = [ + new() { + Name="test module 1 with assignments", + Assignments=[ + new () { + Name="test assignment", + Description ="here is the description", + DueAt = new DateTime(), + LockAt = new DateTime(), + SubmissionTypes = [AssignmentSubmissionType.ONLINE_UPLOAD], + LocalAssignmentGroupName = "Final Project", + Rubric = [ + new() {Points = 4, Label="do task 1"}, + new() {Points = 2, Label="do task 2"}, + ] + } + ], + Quizzes=[] + } + ] + }; + + await fileManager.SaveCourseAsync(testCourse); + + var loadedCourses = await fileManager.LoadSavedMarkdownCourses(); + var loadedCourse = loadedCourses.First(c => c.Settings.Name == testCourse.Settings.Name); + + loadedCourse.Modules.First().Assignments.Should().BeEquivalentTo(testCourse.Modules.First().Assignments); + } + + + [Test] + public async Task CourseModules_WithQuizzes_CanBeSavedAndLoaded() + { + LocalCourse testCourse = new() + { + Settings = new() { Name = "Test Course with modules and quiz" }, + Modules = [ + new() { + Name="test module 1 with quiz", + Assignments=[], + Quizzes=[ + new() { + Name = "Test Quiz", + Description = "quiz description", + LockAt = new DateTime(2022, 10, 3, 12, 5, 0), + DueAt = new DateTime(2022, 10, 3, 12, 5, 0), + ShuffleAnswers = true, + OneQuestionAtATime = true, + LocalAssignmentGroupName = "Assignments", + Questions=[ + new () { + Text = "test essay", + QuestionType = QuestionType.ESSAY, + Points = 1 + } + ] + } + ] + } + ] + }; + + await fileManager.SaveCourseAsync(testCourse); + + var loadedCourses = await fileManager.LoadSavedMarkdownCourses(); + var loadedCourse = loadedCourses.First(c => c.Settings.Name == testCourse.Settings.Name); + + loadedCourse.Modules.First().Quizzes.Should().BeEquivalentTo(testCourse.Modules.First().Quizzes); + } + + + [Test] + public async Task MarkdownStorage_FullyPopulated_DoesNotLoseData() + { + LocalCourse testCourse = new (){ + Settings = new () { + AssignmentGroups = [], + Name = "Test Course with lots of data", + DaysOfWeek = [DayOfWeek.Monday, DayOfWeek.Wednesday], + StartDate = new DateTime(), + EndDate = new DateTime(), + DefaultDueTime = new() { Hour = 1, Minute = 59 }, + }, + Modules = [ + new() { + Name= "new test module", + Assignments = [ + new() { + Name="test assignment", + Description ="here is the description", + DueAt = new DateTime(), + LockAt = new DateTime(), + SubmissionTypes = [AssignmentSubmissionType.ONLINE_UPLOAD], + LocalAssignmentGroupName = "Final Project", + Rubric = [ + new() { Points = 4, Label="do task 1" }, + new() { Points = 2, Label="do task 2" }, + ] + } + ], + Quizzes = [ + new() { + Name = "Test Quiz", + Description = "quiz description", + LockAt = new DateTime(), + DueAt = new DateTime(), + ShuffleAnswers = true, + OneQuestionAtATime = false, + LocalAssignmentGroupName = "someId", + AllowedAttempts = -1, + Questions = [ + new() { + Text = "test short answer", + QuestionType = QuestionType.SHORT_ANSWER, + Points = 1 + } + ] + } + ] + } + ] + }; + + await fileManager.SaveCourseAsync(testCourse); + + var loadedCourses = await fileManager.LoadSavedMarkdownCourses(); + var loadedCourse = loadedCourses.First(c => c.Settings.Name == testCourse.Settings.Name); + + loadedCourse.Should().BeEquivalentTo(testCourse); + } +} \ No newline at end of file diff --git a/Management.Test/ViewModels/MonthDetailTests.cs b/Management.Test/ViewModels/MonthDetailTests.cs index e79e878..9865fa2 100644 --- a/Management.Test/ViewModels/MonthDetailTests.cs +++ b/Management.Test/ViewModels/MonthDetailTests.cs @@ -5,9 +5,11 @@ public class MonthDetailTests [Test] public void TestCanGetMonthName() { - var detail = new MonthDetail(); var calendarMonth = new CalendarMonth(2022, 2); - detail.Month = calendarMonth; + var detail = new MonthDetail() + { + Month = calendarMonth + }; detail.MonthName.Should().Be("February"); } diff --git a/Management.Web/Pages/AssignmentFormPage.razor b/Management.Web/Pages/AssignmentFormPage.razor index 96c9ff5..677a781 100644 --- a/Management.Web/Pages/AssignmentFormPage.razor +++ b/Management.Web/Pages/AssignmentFormPage.razor @@ -3,7 +3,6 @@ @using CanvasModel.EnrollmentTerms @using Management.Web.Shared.Components.AssignmentForm @using Management.Web.Shared.Course -@using Management.Web.Shared.Module.Assignment.Templates @using Management.Web.Shared.Semester @using CanvasModel.Courses @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage diff --git a/Management.Web/Pages/Course.razor b/Management.Web/Pages/Course.razor index b0fd274..3275b55 100644 --- a/Management.Web/Pages/Course.razor +++ b/Management.Web/Pages/Course.razor @@ -1,7 +1,6 @@ @page "/course/{CourseName}" @using CanvasModel.EnrollmentTerms @using Management.Web.Shared.Course -@using Management.Web.Shared.Module.Assignment.Templates @using Management.Web.Shared.Semester @using CanvasModel.Courses @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage diff --git a/Management.Web/Pages/Index.razor b/Management.Web/Pages/Index.razor index b8c5cda..628df27 100644 --- a/Management.Web/Pages/Index.razor +++ b/Management.Web/Pages/Index.razor @@ -1,7 +1,6 @@ @page "/" @using CanvasModel.EnrollmentTerms @using Management.Web.Shared.Course -@using Management.Web.Shared.Module.Assignment.Templates @using Management.Web.Shared.Semester @using CanvasModel.Courses @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage diff --git a/Management.Web/Pages/QuizFormPage.razor b/Management.Web/Pages/QuizFormPage.razor index 832a37b..41fc042 100644 --- a/Management.Web/Pages/QuizFormPage.razor +++ b/Management.Web/Pages/QuizFormPage.razor @@ -4,7 +4,6 @@ @using CanvasModel.Quizzes @using Management.Web.Shared.Components.AssignmentForm @using Management.Web.Shared.Course -@using Management.Web.Shared.Module.Assignment.Templates @using Management.Web.Shared.Semester @using CanvasModel.Courses @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage diff --git a/Management.Web/Shared/Components/AssignmentForm/AssignmentMarkdownEditor.razor b/Management.Web/Shared/Components/AssignmentForm/AssignmentMarkdownEditor.razor index 8c4adbb..8817a2a 100644 --- a/Management.Web/Shared/Components/AssignmentForm/AssignmentMarkdownEditor.razor +++ b/Management.Web/Shared/Components/AssignmentForm/AssignmentMarkdownEditor.razor @@ -32,15 +32,6 @@ public string? TemplateId { get; set; } - public Dictionary VariableValues { get; set; } = new Dictionary(); - - private AssignmentTemplate? selectedTemplate => - planner - .LocalCourse? - .Settings - .AssignmentTemplates - .FirstOrDefault(t => t.Id == TemplateId); - private void handleChange(string newRawAssignment) { rawText = newRawAssignment; diff --git a/Management.Web/Shared/Module/Assignment/Templates/AssignmentTemplateManagement.razor b/Management.Web/Shared/Module/Assignment/Templates/AssignmentTemplateManagement.razor deleted file mode 100644 index eff634f..0000000 --- a/Management.Web/Shared/Module/Assignment/Templates/AssignmentTemplateManagement.razor +++ /dev/null @@ -1,125 +0,0 @@ -@using Management.Web.Shared.Components - - -@inject CoursePlanner planner - -@code -{ - private Modal modal { get; set; } = default!; - private string newTemplateName { get; set; } = ""; - protected override void OnInitialized() - { - planner.StateHasChanged += reload; - } - private void reload() - { - this.InvokeAsync(this.StateHasChanged); - } - public void Dispose() - { - planner.StateHasChanged -= reload; - } - - private string? _selectedTemplateId; - private string? selectedTemplateId - { - get { return _selectedTemplateId; } - set { _selectedTemplateId = value; } - } - - private AssignmentTemplate? selectedTemplate => - planner - .LocalCourse? - .Settings - .AssignmentTemplates - .FirstOrDefault(t => t.Id == selectedTemplateId); - - private void newTemplate() - { - if (planner.LocalCourse != null) - { - var newOne = new AssignmentTemplate() - { - Id=Guid.NewGuid().ToString(), - Name=newTemplateName - }; - planner.LocalCourse = planner.LocalCourse with - { - Settings = planner.LocalCourse.Settings with - { - AssignmentTemplates = planner.LocalCourse.Settings.AssignmentTemplates.Append(newOne) - } - }; - newTemplateName = ""; - } - } - -} - - -@if(planner.LocalCourse != null) -{ - - - <h1>Assignment Templates</h1> - - -
-
-
- - -
-
-
-
- - - -
-
-
- @if(selectedTemplate != null) - { - - } - -
- -
-
- -} diff --git a/Management.Web/Shared/Module/Assignment/Templates/TemplateEditor.razor b/Management.Web/Shared/Module/Assignment/Templates/TemplateEditor.razor deleted file mode 100644 index d646a25..0000000 --- a/Management.Web/Shared/Module/Assignment/Templates/TemplateEditor.razor +++ /dev/null @@ -1,96 +0,0 @@ -@using Markdig - -@inject CoursePlanner planner - -@code -{ - [Parameter, EditorRequired] - public AssignmentTemplate Template { get; set; } = default!; - - protected override void OnInitialized() - { - base.OnInitialized(); - } - public string Preview => Markdown.ToHtml(Template.Markdown); - - private void SetName(string newName) - { - if(planner.LocalCourse != null) - { - var newTemplates = planner.LocalCourse.Settings.AssignmentTemplates.Select(t => - t.Id == Template.Id - ? t with { Name=newName } - : t - ); - planner.LocalCourse = planner.LocalCourse with - { - Settings = planner.LocalCourse.Settings with - { - AssignmentTemplates=newTemplates - } - }; - } - } - private void SetMarkdown(string newMarkdown) - { - if(planner.LocalCourse != null) - { - var newTemplates = planner.LocalCourse.Settings.AssignmentTemplates.Select(t => - t.Id == Template.Id - ? t with { Markdown=newMarkdown } - : t - ); - planner.LocalCourse = planner.LocalCourse with - { - Settings = planner.LocalCourse.Settings with - { - AssignmentTemplates=newTemplates - } - }; - } - } -} - -
-
- -
-
- -
-
-