Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stepSubmitAnswer mutation with mock repository #63

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions TeacherWorkout.Api/GraphQL/TeacherWorkoutMutation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ namespace TeacherWorkout.Api.GraphQL
{
public class TeacherWorkoutMutation : ObjectGraphType<object>
{
public TeacherWorkoutMutation(CompleteStep completeStep,
CreateTheme createTheme)
public TeacherWorkoutMutation(
CompleteStep completeStep,
CreateTheme createTheme,
SubmitAnswer submitAnswer)
{
Name = "Mutation";

Expand All @@ -38,6 +40,17 @@ public TeacherWorkoutMutation(CompleteStep completeStep,
return completeStep.Execute(input);
});

Field<StepSubmitAnswerPayloadType>(
"stepSubmitAnswer",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<StepSubmitAnswerInputType>> { Name = "input" }
),
resolve: context =>
{
var input = context.GetArgument<StepSubmitAnswerInput>("input");
return submitAnswer.Execute(input);
});

Field<ThemeCreatePayloadType>(
"themeCreate",
arguments: new QueryArguments(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using GraphQL.Types;
using TeacherWorkout.Domain.Models.Inputs;

namespace TeacherWorkout.Api.GraphQL.Types.Inputs
{
public class StepSubmitAnswerInputType : InputObjectGraphType<StepSubmitAnswerInput>
{
public StepSubmitAnswerInputType()
{
Name = "StepSubmitAnswerInput";

Field(x => x.StepId, type: typeof(NonNullGraphType<IdGraphType>));
Field(x => x.AnswerIds, type: typeof(ListGraphType<IdGraphType>));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using GraphQL.Types;
using TeacherWorkout.Domain.Models.Payloads;

namespace TeacherWorkout.Api.GraphQL.Types.Payloads
{
public class StepSubmitAnswerPayloadType : ObjectGraphType<StepSubmitAnswerPayload>
{
public StepSubmitAnswerPayloadType()
{
Name = "StepSubmitAnswerPayload";

Field(x => x.Step, type: typeof(StepUnionType)).Description("The completed step.");
Field(x => x.LessonStatus).Description("The status of the lesson.");
}

}
}
16 changes: 14 additions & 2 deletions TeacherWorkout.Api/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public Startup(IConfiguration configuration)
public void ConfigureServices(IServiceCollection services)
{
EnsureReferencedAssembliesAreLoaded();

services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
Expand All @@ -43,6 +43,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddScoped<TeacherWorkoutMutation>();
services.AddScoped<ISchema, TeacherWorkoutSchema>();
AddOperations(services);
AddValidators(services);
AddRepositories(services, "TeacherWorkout.MockData");
AddRepositories(services, "TeacherWorkout.Data");

Expand Down Expand Up @@ -92,6 +93,17 @@ private static void AddOperations(IServiceCollection services)
.ForEach(t => services.AddScoped(t));
}

private static void AddValidators(IServiceCollection services)
{
var validatorType = typeof(IValidator);
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass)
.Where(t => t.GetInterfaces().Contains(validatorType))
.ToList()
.ForEach(t => services.AddScoped(t));
}

private static void AddRepositories(IServiceCollection services, string sourceNamespace)
{
AppDomain.CurrentDomain.GetAssemblies()
Expand All @@ -106,7 +118,7 @@ private static void AddRepositories(IServiceCollection services, string sourceNa
services.AddScoped(repositoryInterface, t);
});
}

private static void EnsureReferencedAssembliesAreLoaded()
{
// We need to reference something in the assembly to make it load
Expand Down
12 changes: 12 additions & 0 deletions TeacherWorkout.Domain/Common/IValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace TeacherWorkout.Domain.Common
{
public interface IValidator
{

}

public interface IValidator<T> : IValidator
{
public bool IsValid(T input);
}
}
9 changes: 9 additions & 0 deletions TeacherWorkout.Domain/Lessons/IAnswerRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using TeacherWorkout.Domain.Models;

namespace TeacherWorkout.Domain.Lessons
{
public interface IAnswerRepository
{
public Answer Find(string id);
}
}
4 changes: 3 additions & 1 deletion TeacherWorkout.Domain/Lessons/IStepRepository.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Collections.Generic;
using TeacherWorkout.Domain.Models;
using TeacherWorkout.Domain.Models.Payloads;

namespace TeacherWorkout.Domain.Lessons
{
Expand All @@ -8,5 +8,7 @@ public interface IStepRepository
ILessonStep Find(string id);

ILessonStep CompleteStep(string id);

ILessonStep SubmitAnswer(string id, IEnumerable<string> answerIds);
}
}
39 changes: 39 additions & 0 deletions TeacherWorkout.Domain/Lessons/StepSubmitAnswerInputValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using TeacherWorkout.Domain.Common;
using TeacherWorkout.Domain.Models.Inputs;

namespace TeacherWorkout.Domain.Lessons
{
public class StepSubmitAnswerInputValidator : IValidator<StepSubmitAnswerInput>
{
private readonly IStepRepository _stepRepository;
private readonly IAnswerRepository _answerRepository;

public StepSubmitAnswerInputValidator(IStepRepository stepRepository, IAnswerRepository answerRepository)
{
_stepRepository = stepRepository;
_answerRepository = answerRepository;
}

public bool IsValid(StepSubmitAnswerInput input)
{
var step = _stepRepository.Find(input.StepId);

if (step == null)
{
return false;
}

foreach (var answerId in input.AnswerIds)
{
var answer = _answerRepository.Find(answerId);

if (answer == null)
{
return false;
}
}

return true;
}
}
}
49 changes: 49 additions & 0 deletions TeacherWorkout.Domain/Lessons/SubmitAnswer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
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 SubmitAnswer : IOperation<StepSubmitAnswerInput, StepSubmitAnswerPayload>
{
private readonly IStepRepository _stepRepository;
private readonly ILessonStatusRepository _lessonStatusRepository;
private readonly StepSubmitAnswerInputValidator _validator;

public SubmitAnswer(IStepRepository stepRepository, ILessonStatusRepository lessonStatusRepository, StepSubmitAnswerInputValidator validator)
{
_stepRepository = stepRepository;
_lessonStatusRepository = lessonStatusRepository;
_validator = validator;
}

public StepSubmitAnswerPayload Execute(StepSubmitAnswerInput input)
{
if (!_validator.IsValid(input))
{
throw new ArgumentException("Input is not valid");
}

var step = _stepRepository.SubmitAnswer(input.StepId, input.AnswerIds);
var lessonId = (step.GetType().GetProperty("Lesson").GetValue(step) as Lesson).Id;

var lessonStatus = _lessonStatusRepository
.List(
new LessonStatusFilter()
{
LessonIds = new List<string>() { lessonId }
})
.FirstOrDefault();

return new StepSubmitAnswerPayload()
{
Step = step,
LessonStatus = lessonStatus
};
}
}
}
12 changes: 12 additions & 0 deletions TeacherWorkout.Domain/Models/Inputs/StepSubmitAnswerInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Collections.Generic;

namespace TeacherWorkout.Domain.Models.Inputs
{
public class StepSubmitAnswerInput
{
public string StepId { get; set; }

public IEnumerable<string> AnswerIds { get; set; }

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace TeacherWorkout.Domain.Models.Payloads
{
public class StepSubmitAnswerPayload
{
public ILessonStep Step { get; set; }

public LessonStatus LessonStatus { get; set; }
}
}
43 changes: 43 additions & 0 deletions TeacherWorkout.MockData/Repositories/AnswerRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using TeacherWorkout.Domain.Lessons;
using TeacherWorkout.Domain.Models;

namespace TeacherWorkout.MockData.Repositories
{
public class AnswerRepository : IAnswerRepository
{
public Answer Find(string id)
{
switch (id)
{
case "1":
{
return new Answer
{
Id = "1",
Title = "42"
};
}

case "2":
{
return new Answer
{
Id = "2",
Title = "13"
};
}
case "3":
{
return new Answer
{
Id = "3",
Title = "There is NONE"
};
}
default:
throw new ArgumentException("Does not exist");
}
}
}
}
Loading