diff --git a/TeacherWorkout.Api/GraphQL/TeacherWorkoutMutation.cs b/TeacherWorkout.Api/GraphQL/TeacherWorkoutMutation.cs index 2246a37..ad78c34 100644 --- a/TeacherWorkout.Api/GraphQL/TeacherWorkoutMutation.cs +++ b/TeacherWorkout.Api/GraphQL/TeacherWorkoutMutation.cs @@ -3,26 +3,38 @@ using TeacherWorkout.Api.GraphQL.Resolvers; using TeacherWorkout.Api.GraphQL.Types.Inputs; using TeacherWorkout.Api.GraphQL.Types.Payloads; +using TeacherWorkout.Domain.Lessons; using TeacherWorkout.Domain.Models.Inputs; namespace TeacherWorkout.Api.GraphQL { public class TeacherWorkoutMutation : ObjectGraphType { - public TeacherWorkoutMutation() + public TeacherWorkoutMutation(CompleteStep completeStep) { Name = "Mutation"; Field>( "lessonSave", arguments: new QueryArguments( - new QueryArgument> {Name = "input"} + new QueryArgument> { Name = "input" } ), resolve: context => { var lessonSave = context.GetArgument("input"); return LessonSaveResolver.Resolve(lessonSave); }); + + Field( + "stepComplete", + arguments: new QueryArguments( + new QueryArgument> { Name = "input" } + ), + resolve: context => + { + var stepComplete = context.GetArgument("input"); + return completeStep.Execute(stepComplete); + }); } } } \ No newline at end of file diff --git a/TeacherWorkout.Api/GraphQL/Types/Inputs/StepCompleteInputType.cs b/TeacherWorkout.Api/GraphQL/Types/Inputs/StepCompleteInputType.cs new file mode 100644 index 0000000..d543f42 --- /dev/null +++ b/TeacherWorkout.Api/GraphQL/Types/Inputs/StepCompleteInputType.cs @@ -0,0 +1,15 @@ +using GraphQL.Types; +using TeacherWorkout.Domain.Models.Inputs; + +namespace TeacherWorkout.Api.GraphQL.Types.Inputs +{ + public class StepCompleteInputType : InputObjectGraphType + { + public StepCompleteInputType() + { + Name = "StepCompleteInput"; + + Field(x => x.StepId, type: typeof(NonNullGraphType)); + } + } +} diff --git a/TeacherWorkout.Api/GraphQL/Types/Payloads/StepCompletePayloadType.cs b/TeacherWorkout.Api/GraphQL/Types/Payloads/StepCompletePayloadType.cs new file mode 100644 index 0000000..25dde65 --- /dev/null +++ b/TeacherWorkout.Api/GraphQL/Types/Payloads/StepCompletePayloadType.cs @@ -0,0 +1,16 @@ +using GraphQL.Types; +using TeacherWorkout.Domain.Models.Payloads; + +namespace TeacherWorkout.Api.GraphQL.Types.Payloads +{ + public class StepCompletePayloadType : ObjectGraphType + { + public StepCompletePayloadType() + { + Name = "StepCompletePayload"; + + Field(x => x.Step, type: typeof(StepUnionType)).Description("The completed step."); + Field(x => x.LessonStatus).Description("The status of the lesson."); + } + } +} diff --git a/TeacherWorkout.Domain/Lessons/CompleteStep.cs b/TeacherWorkout.Domain/Lessons/CompleteStep.cs new file mode 100644 index 0000000..04d192a --- /dev/null +++ b/TeacherWorkout.Domain/Lessons/CompleteStep.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Linq; +using TeacherWorkout.Domain.Common; +using TeacherWorkout.Domain.Models; +using TeacherWorkout.Domain.Models.Inputs; +using TeacherWorkout.Domain.Models.Payloads; + +namespace TeacherWorkout.Domain.Lessons +{ + public class CompleteStep : IOperation + { + private readonly IStepRepository _stepRepository; + private readonly ILessonStatusRepository _lessonStatusRepository; + + public CompleteStep(IStepRepository stepRepository, ILessonStatusRepository lessonStatusRepository) + { + _stepRepository = stepRepository; + _lessonStatusRepository = lessonStatusRepository; + } + + public StepCompletePayload Execute(StepCompleteInput input) + { + var step = _stepRepository.CompleteStep(input.StepId); + var lessonId = (step.GetType().GetProperty("Lesson").GetValue(step) as Lesson).Id; + + var lessonStatus = _lessonStatusRepository + .List( + new LessonStatusFilter() + { + LessonIds = new List() { lessonId } + }) + .FirstOrDefault(); + + return new StepCompletePayload() + { + Step = step, + LessonStatus = lessonStatus + }; + } + } +} diff --git a/TeacherWorkout.Domain/Lessons/IStepRepository.cs b/TeacherWorkout.Domain/Lessons/IStepRepository.cs index 6b3d4fc..e1a6f7d 100644 --- a/TeacherWorkout.Domain/Lessons/IStepRepository.cs +++ b/TeacherWorkout.Domain/Lessons/IStepRepository.cs @@ -1,9 +1,12 @@ using TeacherWorkout.Domain.Models; +using TeacherWorkout.Domain.Models.Payloads; namespace TeacherWorkout.Domain.Lessons { public interface IStepRepository { ILessonStep Find(string id); + + ILessonStep CompleteStep(string id); } } \ No newline at end of file diff --git a/TeacherWorkout.Domain/Models/ExerciseStep.cs b/TeacherWorkout.Domain/Models/ExerciseStep.cs index 130c612..a8e46b5 100644 --- a/TeacherWorkout.Domain/Models/ExerciseStep.cs +++ b/TeacherWorkout.Domain/Models/ExerciseStep.cs @@ -7,7 +7,9 @@ public class ExerciseStep : ILessonStep public string Id { get; set; } public string Question { get; set; } - + public IEnumerable Answers { get; set; } + + public Lesson Lesson { get; set; } } } \ No newline at end of file diff --git a/TeacherWorkout.Domain/Models/ExerciseSummaryStep.cs b/TeacherWorkout.Domain/Models/ExerciseSummaryStep.cs index c271f84..fd75a2b 100644 --- a/TeacherWorkout.Domain/Models/ExerciseSummaryStep.cs +++ b/TeacherWorkout.Domain/Models/ExerciseSummaryStep.cs @@ -7,5 +7,7 @@ public class ExerciseSummaryStep : ILessonStep public string Id { get; set; } public IEnumerable Results { get; set; } + + public Lesson Lesson { get; set; } } } \ No newline at end of file diff --git a/TeacherWorkout.Domain/Models/Inputs/StepCompleteInput.cs b/TeacherWorkout.Domain/Models/Inputs/StepCompleteInput.cs new file mode 100644 index 0000000..5177789 --- /dev/null +++ b/TeacherWorkout.Domain/Models/Inputs/StepCompleteInput.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TeacherWorkout.Domain.Models.Inputs +{ + public class StepCompleteInput + { + public string StepId { get; set; } + } +} diff --git a/TeacherWorkout.Domain/Models/LessonSummaryStep.cs b/TeacherWorkout.Domain/Models/LessonSummaryStep.cs index 7492165..8a3f6d3 100644 --- a/TeacherWorkout.Domain/Models/LessonSummaryStep.cs +++ b/TeacherWorkout.Domain/Models/LessonSummaryStep.cs @@ -5,5 +5,7 @@ public class LessonSummaryStep : ILessonStep public string Id { get; set; } public int ExperiencePoints { get; set; } + + public Lesson Lesson { get; set; } } } \ No newline at end of file diff --git a/TeacherWorkout.Domain/Models/Payloads/StepCompletePayload.cs b/TeacherWorkout.Domain/Models/Payloads/StepCompletePayload.cs new file mode 100644 index 0000000..477ecfe --- /dev/null +++ b/TeacherWorkout.Domain/Models/Payloads/StepCompletePayload.cs @@ -0,0 +1,9 @@ +namespace TeacherWorkout.Domain.Models.Payloads +{ + public class StepCompletePayload + { + public ILessonStep Step { get; set; } + + public LessonStatus LessonStatus { get; set; } + } +} diff --git a/TeacherWorkout.Domain/Models/SlideStep.cs b/TeacherWorkout.Domain/Models/SlideStep.cs index 2f8e78a..abd741d 100644 --- a/TeacherWorkout.Domain/Models/SlideStep.cs +++ b/TeacherWorkout.Domain/Models/SlideStep.cs @@ -5,11 +5,13 @@ public class SlideStep : ILessonStep public string Id { get; set; } public string Title { get; set; } - + public string Description { get; set; } - + public Image Image { get; set; } public ILessonStep PreviousStep { get; set; } + + public Lesson Lesson { get; set; } } } \ No newline at end of file diff --git a/TeacherWorkout.MockData/Repositories/StepRepository.cs b/TeacherWorkout.MockData/Repositories/StepRepository.cs index 98d3d2d..45bffc8 100644 --- a/TeacherWorkout.MockData/Repositories/StepRepository.cs +++ b/TeacherWorkout.MockData/Repositories/StepRepository.cs @@ -7,6 +7,161 @@ namespace TeacherWorkout.MockData.Repositories { public class StepRepository : IStepRepository { + public ILessonStep CompleteStep(string id) + { + switch (id) + { + case "1": + return new SlideStep + { + Id = "1", + Title = "My title 1", + Description = + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum;", + Image = new Image + { + Description = "Cat Photo", + Url = + "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Felis_catus-cat_on_snow.jpg/640px-Felis_catus-cat_on_snow.jpg" + }, + PreviousStep = null, + Lesson = new Lesson() + { + Id = "1" + } + }; + case "2": + return new SlideStep + { + Id = "2", + Title = "My title 2", + Description = + "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).", + Image = new Image + { + Description = "Cat Photo", + Url = + "https://imagesvc.meredithcorp.io/v3/mm/image?url=https%3A%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F12%2F2015%2F06%2Fcrazy-cat.jpg&q=85" + }, + PreviousStep = new SlideStep + { + Id = "1", + Description = + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum;", + Image = new Image + { + Description = "Cat Photo", + Url = + "https://www.google.com/url?sa=i&url=https%3A%2F%2Ficatcare.org%2F&psig=AOvVaw0nBkNYvmgGLHcuursLSpxE&ust=1624782643255000&source=images&cd=vfe&ved=0CAoQjRxqFwoTCJCJqI3ytPECFQAAAAAdAAAAABAJ" + }, + PreviousStep = null + }, + Lesson = new Lesson() + { + Id = "1" + } + }; + case "3": + return new ExerciseStep + { + Id = "3", + Question = "What is the meaning of life, universe and everything?", + Answers = new[] + { + new Answer + { + Id = "1", + Title = "42" + }, + new Answer + { + Id = "2", + Title = "13" + }, + new Answer + { + Id = "3", + Title = "There is NONE" + }, + }, + Lesson = new Lesson() + { + Id = "1" + } + }; + case "4": + return new ExerciseSummaryStep + { + Id = "4", + Results = new List + { + new() + { + Status = AnswerStatus.Correct, + Answer = new Answer + { + Id = "1", + Title = "42" + } + }, + new() + { + Status = AnswerStatus.None, + Answer = new Answer + { + Id = "2", + Title = "13" + } + }, + new() + { + Status = AnswerStatus.Incorrect, + Answer = new Answer + { + Id = "3", + Title = "There is NONE" + } + } + }, + Lesson = new Lesson() + { + Id = "1" + } + }; + case "5": + return new SlideStep + { + Id = "5", + Title = "This is my title", + Description = + "There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.", + Image = new Image + { + Description = "Cat Photo", + Url = + "https://www.google.com/url?sa=i&url=https%3A%2F%2Ficatcare.org%2F&psig=AOvVaw0nBkNYvmgGLHcuursLSpxE&ust=1624782643255000&source=images&cd=vfe&ved=0CAoQjRxqFwoTCJCJqI3ytPECFQAAAAAdAAAAABAJ" + }, + Lesson = new Lesson() + { + Id = "1" + } + }; + case "6": + return new LessonSummaryStep + { + Id = "6", + ExperiencePoints = 100, + Lesson = new Lesson() + { + Id = "1" + } + }; + default: + throw new ArgumentException("Does not exist"); + } + + } + public ILessonStep Find(string id) { switch (id)