public async Task GetQuestionAsync_Exists_ReturnQuestion()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion
				(
					"Class1", 
					"Category1", 
					new MethodQuestion() { Name = "Question1" }
				).Build();

			var questionId = database.Context.Questions.First().Id;

			database.Reload();

			var loaderFactory = GetMockQuestionLoaderFactory();
			var questionService = CreateQuestionService
			(
				database.Context, 
				questionLoaderFactory: loaderFactory.Object
			);

			var question = await questionService.GetQuestionAsync
			(
				"Class1",
				questionId
			);

			loaderFactory.Verify(LoadQuestionExpression);
			Assert.Equal("Class1", question.QuestionCategory.Classroom.Name);
			Assert.Equal("Category1", question.QuestionCategory.Name);
			Assert.Equal("Question1", question.Name);
		}
		public async Task GetSectionAsync_Exists_ReturnSection()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.Build();

			database.Reload();

			var sectionService = new SectionService(database.Context);
			var section = await sectionService.GetSectionAsync("Class1", "Section1");

			Assert.Equal("Class1", section.Classroom.Name);
			Assert.Equal("Section1", section.Name);
		}
		public async Task GetClassroomAsync_Exists_ReturnsClassroom()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddClassroom("Class2")
				.Build();

			var classroomId = database.Context.Classrooms.First().Id;

			database.Reload();

			var classroomService = new ClassroomService(database.Context);
			var classroom = await classroomService.GetClassroomAsync("Class1");

			Assert.Equal("Class1", classroom.Name);
		}
		public async Task GetSectionMembershipsAsync_ReturnStudents()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.AddSection("Class1", "Section2")
				.AddStudent("User1", "Last", "First", "Class1", "Section1")
				.AddStudent("User2", "Last", "First", "Class1", "Section1")
				.AddStudent("User3", "Last", "First", "Class1", "Section2")
				.Build();

			database.Reload();

			var sectionService = new SectionService(database.Context);
			var students = await sectionService.GetSectionStudentsAsync("Class1", "Section1");

			Assert.Equal(2, students.Count);
			Assert.Equal("User1", students[0].ClassroomMembership.User.UserName);
			Assert.Equal("User2", students[1].ClassroomMembership.User.UserName);
		}
		public async Task GetQuestionCategoryAsync_Exists_ReturnCategory()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddQuestionCategory("Class1", "Category1")
				.Build();

			var questionCategoryId = database.Context.QuestionCategories.First().Id;

			database.Reload();

			var questionCategoryService = new QuestionCategoryService(database.Context);
			var category = await questionCategoryService.GetQuestionCategoryAsync
			(
				"Class1", 
				questionCategoryId
			);

			Assert.Equal("Class1", category.Classroom.Name);
			Assert.Equal("Category1", category.Name);
		}
		public async Task GetQuestionToSolveAsync_GeneratedQuestionStalePastSubmission_ReturnsRegeneratedQuestionAndSubmission()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.AddStudent("User1", "Last", "First", "Class1", "Section1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1", "Category1",
					new GeneratedQuestionTemplate() { Name = "Question1", DateModified = new DateTime(2016, 1, 2) })
				.AddQuestionSubmission("Class1", "Category1", "Question1", "User1", "PastSubmission1", score: 0.0, 
					dateSubmitted: new DateTime(2016, 1, 1), cachedQuestionData: "OldSerializedQuestion", seed: 12345)
				.Build();

			var questionId = database.Context.Questions.First().Id;
			var userId = database.Context.Users.First().Id;

			database.Reload();

			var loaderFactory = GetMockQuestionLoaderFactory();
			var questionGenerator = GetMockQuestionGenerator(questionId);
			var timeProvider = GetMockTimeProvider(new DateTime(2016, 1, 3));

			var serializer = new Mock<IJsonSerializer>();
			serializer
				.Setup(s => s.Deserialize<QuestionSubmission>("PastSubmission1"))
				.Returns(new CodeQuestionSubmission() { Contents = "PastSubmissionContents" });
			serializer
				.Setup(js => js.Deserialize<Question>("SerializedQuestion"))
				.Returns(new MethodQuestion());

			var questionService = CreateQuestionService
			(
				database.Context,
				questionLoaderFactory: loaderFactory.Object,
				questionGenerator: questionGenerator.Object,
				jsonSerializer: serializer.Object,
				timeProvider: timeProvider.Object
			);

			var questionToSolve = await questionService.GetQuestionToSolveAsync
			(
				"Class1",
				userId,
				questionId
			);

			Assert.Equal("Class1", questionToSolve.Question.QuestionCategory.Classroom.Name);
			Assert.Equal("Category1", questionToSolve.Question.QuestionCategory.Name);
			Assert.Equal("Question1", questionToSolve.Question.Name);
			Assert.True(questionToSolve.Question is MethodQuestion);

			Assert.Equal
			(
				"PastSubmissionContents",
				((CodeQuestionSubmission)questionToSolve.LastSubmission).Contents
			);

			database.Reload();
			var userQuestionData = database.Context.UserQuestionData.First();

			Assert.Equal("SerializedQuestion", userQuestionData.CachedQuestionData);
			Assert.Equal(new DateTime(2016, 1, 3), userQuestionData.CachedQuestionDataTime);
		}
		public async Task CreateQuestionAsync_NoNameCollision_QuestionCreated()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddQuestionCategory("Class1", "Category1")
				.Build();

			var questionCategoryId = database.Context.QuestionCategories.First().Id;
			var modelErrors = new Mock<IModelErrorCollection>();
			var updaterFactory = GetMockQuestionUpdaterFactory();

			var questionService = CreateQuestionService
			(
				database.Context, 
				questionUpdaterFactory: updaterFactory.Object
			);

			var result = await questionService.CreateQuestionAsync
			(
				"Class1",
				new MethodQuestion()
				{
					Name = "Question1",
					QuestionCategoryId = questionCategoryId
				}, 
				modelErrors.Object
			);

			database.Reload();

			var question = database.Context.Questions
				.Include(q => q.QuestionCategory.Classroom)
				.Single();

			Assert.True(result);
			Assert.Equal("Class1", question.QuestionCategory.Classroom.Name);
			Assert.Equal("Category1", question.QuestionCategory.Name);
			Assert.Equal("Question1", question.Name);
			updaterFactory.Verify(UpdateQuestionExpression);
		}
		public async Task CreateQuestionAsync_NameCollision_QuestionNotCreated()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question1" })
				.Build();

			var questionCategoryId = database.Context.QuestionCategories.First().Id;
			var modelErrors = new MockErrorCollection();
			var updaterFactory = GetMockQuestionUpdaterFactory();

			var questionService = CreateQuestionService
			(
				database.Context,
				questionUpdaterFactory: updaterFactory.Object
			);

			var result = await questionService.CreateQuestionAsync
			(
				"Class1",
				new MethodQuestion()
				{
					Name = "Question1",
					QuestionCategoryId = questionCategoryId
				},
				modelErrors
			);

			database.Reload();

			var numQuestions = database.Context.Questions.Count();

			Assert.False(result);
			Assert.True(modelErrors.HasErrors);
			Assert.True(modelErrors.VerifyErrors("Name"));
			Assert.Equal(1, numQuestions);
		}
		public async Task UpdateQuestionCategoryAsync_CategoryUpdated()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddQuestionCategory("Class1", "Category1", privateCategory: true)
				.Build();
			
			var questionCategory = database.Context.QuestionCategories
				.Include(qc => qc.Classroom)
				.First();

			// Update the category
			database.Context.Entry(questionCategory).State = EntityState.Detached;
			questionCategory.IsPrivate = false;

			// Apply the update
			var questionCategoryService = new QuestionCategoryService(database.Context);
			await questionCategoryService.UpdateQuestionCategoryAsync
			(
				"Class1",
				questionCategory
			);

			database.Reload();

			questionCategory = database.Context.QuestionCategories
				.Include(qc => qc.Classroom)
				.Single();

			Assert.Equal("Class1", questionCategory.Classroom.Name);
			Assert.Equal("Category1", questionCategory.Name);
			Assert.Equal(false, questionCategory.IsPrivate);
		}
		public async Task UpdateClassroomAsync_ClassroomUpdated()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.Build();

			var classroom = database.Context.Classrooms.Single();

			// Update the classroom
			database.Context.Entry(classroom).State = EntityState.Detached;
			classroom.DisplayName = "New Display Name";

			// Apply the update
			var classroomService = new ClassroomService(database.Context);
			await classroomService.UpdateClassroomAsync(classroom);

			database.Reload();

			classroom = database.Context.Classrooms.Single();

			Assert.Equal("Class1", classroom.Name);
			Assert.Equal("New Display Name", classroom.DisplayName);
		}
		public async Task UpdateQuestionCategoryAsync_NameCollision_QuestionNotUpdated()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question1" })
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question2" })
				.Build();

			var modelErrors = new Mock<IModelErrorCollection>();
			var updaterFactory = GetMockQuestionUpdaterFactory();
			var question = database.Context.Questions
				.Single(q => q.Name == "Question2");

			var questionService = CreateQuestionService
			(
				database.Context,
				questionUpdaterFactory: updaterFactory.Object
			);

			// Update the category
			database.Context.Entry(question).State = EntityState.Detached;
			question.Name = "Question1";

			// Apply the update
			await questionService.UpdateQuestionAsync
			(
				"Class1",
				question,
				modelErrors.Object
			);

			database.Reload();

			var questionCounts = database.Context.Questions
				.GroupBy(q => q.Name)
				.ToDictionary(g => g.Key, g => g.Count());
			
			Assert.Equal(2, questionCounts.Count);
			Assert.Equal(1, questionCounts["Question1"]);
			Assert.Equal(1, questionCounts["Question2"]);
		}
		public async Task CreateSectionAsync_SectionCreated()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.Build();

			var sectionService = new SectionService(database.Context);
			await sectionService.CreateSectionAsync
			(
				"Class1",
				new Section()
				{
					Name = "Section1"
				}
			);

			database.Reload();

			var section = database.Context.Sections
				.Include(qc => qc.Classroom)
				.Single();

			Assert.Equal("Class1", section.Classroom.Name);
			Assert.Equal("Section1", section.Name);
		}
		public async Task GetClassroomAdminsAsync_ReturnsAdmins()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddClassroom("Class2")
				.AddAdmin("User1", "Last", "First", "Class1", superUser: false)
				.AddAdmin("User2", "Last", "First", "Class1", superUser: false)
				.AddAdmin("User3", "Last", "First", "Class2", superUser: false)
				.Build();

			var users = database.Context.Users
				.OrderBy(u => u.UserName)
				.ToList();

			database.Reload();

			var classroomService = new ClassroomService(database.Context);
			var admins = await classroomService.GetClassroomAdminsAsync("Class1");
			admins = admins.OrderBy(a => a.UserId).ToList();

			Assert.Equal(2, admins.Count);
			Assert.Equal(users[0].Id, admins[0].UserId);
			Assert.Equal(users[1].Id, admins[1].UserId);
		}
		public async Task GetQuestionToSolveAsync_GeneratedQuestionNoPastSubmission_ReturnsQuestion()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.AddStudent("User1", "Last", "First", "Class1", "Section1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1", "Category1", new GeneratedQuestionTemplate() { Name = "Question1" })
				.Build();

			var questionId = database.Context.Questions.First().Id;
			var userId = database.Context.Users.First().Id;

			database.Reload();

			var loaderFactory = GetMockQuestionLoaderFactory();
			var randomNumberProvider = GetMockRandomNumberProvider(randomNumber: 12345);
			var questionGenerator = GetMockQuestionGenerator(questionId);

			var jsonSerializer = new Mock<IJsonSerializer>();
			jsonSerializer
				.Setup(js => js.Deserialize<Question>("SerializedQuestion"))
				.Returns(new MethodQuestion());

			var timeProvider = new Mock<ITimeProvider>();
			timeProvider
				.Setup(tp => tp.UtcNow)
				.Returns(new DateTime(2016, 1, 1));

			var questionService = CreateQuestionService
			(
				database.Context,
				questionLoaderFactory: loaderFactory.Object,
				questionGenerator: questionGenerator.Object,
				jsonSerializer: jsonSerializer.Object,
				randomNumberProvider: randomNumberProvider.Object,
				timeProvider: timeProvider.Object
			);

			var questionToSolve = await questionService.GetQuestionToSolveAsync
			(
				"Class1",
				userId,
				questionId
			);

			Assert.Equal("Class1", questionToSolve.Question.QuestionCategory.Classroom.Name);
			Assert.Equal("Category1", questionToSolve.Question.QuestionCategory.Name);
			Assert.Equal("Question1", questionToSolve.Question.Name);
			Assert.Null(questionToSolve.LastSubmission);
			Assert.True(questionToSolve.Question is MethodQuestion);

			database.Reload();
			var userQuestionData = database.Context.UserQuestionData.First();

			Assert.Equal("SerializedQuestion", userQuestionData.CachedQuestionData);
			Assert.Equal(new DateTime(2016, 1, 1), userQuestionData.CachedQuestionDataTime);
		}
		public async Task GetQuestionToSolveAsync_NormalQuestionPastSubmission_ReturnsQuestionAndSubmission()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.AddStudent("User1", "Last", "First", "Class1", "Section1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question1" })
				.AddQuestionSubmission("Class1", "Category1", "Question1", "User1", "PastSubmission1")
				.Build();

			var questionId = database.Context.Questions.First().Id;
			var userId = database.Context.Users.First().Id;

			database.Reload();

			var loaderFactory = GetMockQuestionLoaderFactory();

			var serializer = new Mock<IJsonSerializer>();
			serializer
				.Setup(s => s.Deserialize<QuestionSubmission>("PastSubmission1"))
				.Returns(new CodeQuestionSubmission() { Contents = "PastSubmissionContents" });

			var questionService = CreateQuestionService
			(
				database.Context,
				questionLoaderFactory: loaderFactory.Object,
				jsonSerializer: serializer.Object
			);

			var questionToSolve = await questionService.GetQuestionToSolveAsync
			(
				"Class1",
				userId,
				questionId
			);

			Assert.Equal("Class1", questionToSolve.Question.QuestionCategory.Classroom.Name);
			Assert.Equal("Category1", questionToSolve.Question.QuestionCategory.Name);
			Assert.Equal("Question1", questionToSolve.Question.Name);

			Assert.Equal
			(
				"PastSubmissionContents", 
				((CodeQuestionSubmission)questionToSolve.LastSubmission).Contents
			);
		}
		public async Task GetQuestionToSolveAsync_NormalQuestionNoPastSubmission_ReturnsQuestion()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.AddStudent("User1", "Last", "First", "Class1", "Section1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question1" })
				.Build();

			var questionId = database.Context.Questions.First().Id;
			var userId = database.Context.Users.First().Id;

			database.Reload();

			var loaderFactory = GetMockQuestionLoaderFactory();
			var questionService = CreateQuestionService
			(
				database.Context,
				questionLoaderFactory: loaderFactory.Object
			);

			var questionToSolve = await questionService.GetQuestionToSolveAsync
			(
				"Class1",
				userId,
				questionId
			);

			Assert.Equal("Class1", questionToSolve.Question.QuestionCategory.Classroom.Name);
			Assert.Equal("Category1", questionToSolve.Question.QuestionCategory.Name);
			Assert.Equal("Question1", questionToSolve.Question.Name);
			Assert.Null(questionToSolve.LastSubmission);
		}
		public async Task DeleteQuestionAsync_QuestionDeleted()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question1" })
				.Build();
			
			var questionId = database.Context.Questions.First().Id;

			database.Reload();

			var loaderFactory = GetMockQuestionLoaderFactory();
			var questionService = CreateQuestionService
			(
				database.Context,
				questionLoaderFactory: loaderFactory.Object
			);

			await questionService.DeleteQuestionAsync
			(
				"Class1",
				questionId
			);

			database.Reload();

			Assert.Equal(0, database.Context.Questions.Count());
		}
		public async Task UpdateQuestionCategoryAsync_NoNameCollision_QuestionUpdated()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1",  "Category1", 
					new MethodQuestion { Name = "Question1", AllowPartialCredit = false })
				.Build();
			
			var question = database.Context.Questions.First();
			var modelErrors = new Mock<IModelErrorCollection>();
			var updaterFactory = GetMockQuestionUpdaterFactory();

			var questionService = CreateQuestionService
			(
				database.Context,
				questionUpdaterFactory: updaterFactory.Object
			);

			// Update the category
			database.Context.Entry(question).State = EntityState.Detached;
			question.AllowPartialCredit = true;

			// Apply the update
			await questionService.UpdateQuestionAsync
			(
				"Class1",
				question,
				modelErrors.Object
			);

			database.Reload();

			question = database.Context.Questions
				.Include(qc => qc.QuestionCategory.Classroom)
				.Single();

			Assert.Equal("Class1", question.QuestionCategory.Classroom.Name);
			Assert.Equal("Category1", question.QuestionCategory.Name);
			Assert.Equal("Question1", question.Name);
			Assert.Equal(true, question.AllowPartialCredit);
			updaterFactory.Verify(UpdateQuestionExpression);
		}
		public async Task GetClassroomsWithAccessAsync_SuperUser_ReturnsClassrooms()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddClassroom("Class2")
				.AddAdmin("User1", "Last", "First", "Class2", superUser: true)
				.Build();

			var userId = database.Context.Users.First().Id;
			var expectedClassrooms = database.Context.Classrooms
				.OrderBy(c => c.Id)
				.ToList();

			database.Reload();

			var classroomService = new ClassroomService(database.Context);
			var classrooms = await classroomService.GetClassroomsWithAccessAsync(userId);
			classrooms = classrooms.OrderBy(c => c.ClassroomId).ToList();

			Assert.Equal(2, classrooms.Count);
			Assert.Equal(userId, classrooms[0].UserId);
			Assert.Equal(expectedClassrooms[0].Id, classrooms[0].ClassroomId);
			Assert.Equal(userId, classrooms[1].UserId);
			Assert.Equal(expectedClassrooms[1].Id, classrooms[1].ClassroomId);
		}
		public async Task GetQuestionToSolveAsync_UnsolvedPrerequisites_ReturnsQuestionAndPrerequisites()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.AddStudent("User1", "Last", "First", "Class1", "Section1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question1" })
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question2" })
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question3" })
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question4" })
				.AddPrerequisiteQuestion("Class1", "Category1", "Question1", "Category1", "Question4")
				.AddPrerequisiteQuestion("Class1", "Category1", "Question2", "Category1", "Question4")
				.AddPrerequisiteQuestion("Class1", "Category1", "Question3", "Category1", "Question4")
				.AddQuestionSubmission("Class1", "Category1", "Question1", "User1", "Contents", score: 1.0)
				.AddQuestionSubmission("Class1", "Category1", "Question2", "User1", "Contents", score: 0.0)
				.Build();

			var questionId = database.Context.Questions
				.Single(q => q.Name == "Question4")
				.Id;

			var userId = database.Context.Users.First().Id;

			database.Reload();

			var loaderFactory = GetMockQuestionLoaderFactory();
			var questionService = CreateQuestionService
			(
				database.Context,
				questionLoaderFactory: loaderFactory.Object
			);

			var questionToSolve = await questionService.GetQuestionToSolveAsync
			(
				"Class1",
				userId,
				questionId
			);
			
			Assert.Equal("Question4", questionToSolve.Question.Name);
			Assert.Equal(2, questionToSolve.UnsolvedPrerequisites.Count);
			Assert.Equal("Question2", questionToSolve.UnsolvedPrerequisites[0].Name);
			Assert.Equal("Question3", questionToSolve.UnsolvedPrerequisites[1].Name);
		}
		public async Task CreateClassroomAsync_ClassroomCreated()
		{
			var database = new TestDatabaseBuilder().Build();

			var classroomService = new ClassroomService(database.Context);
			await classroomService.CreateClassroomAsync
			(
				new Classroom()
				{
					Name = "Class1"
				}
			);

			database.Reload();

			var classroom = database.Context.Classrooms.Single();

			Assert.Equal("Class1", classroom.Name);
		}
		public async Task GenerateFromExistingQuestionAsync_ReturnsMatchingGeneratorTemplate()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question1" })
				.Build();

			var originalQuestion = database.Context.Questions.First();

			database.Reload();

			var loaderFactory = GetMockQuestionLoaderFactory();
			var questionGenerator = GetMockQuestionGenerator(originalQuestion.Id);
			var questionService = CreateQuestionService
			(
				database.Context,
				questionLoaderFactory: loaderFactory.Object,
				questionGenerator: questionGenerator.Object
			);

			var generatedQuestion = (GeneratedQuestionTemplate)
				await questionService.GenerateFromExistingQuestionAsync
			(
				"Class1",
				originalQuestion.Id
			);
			
			loaderFactory.Verify(LoadQuestionExpression);
			Assert.Equal("Question1 (generated)", generatedQuestion.Name);
			Assert.Equal("Generated Question", generatedQuestion.Description);
			Assert.Equal(originalQuestion.QuestionCategoryId, generatedQuestion.QuestionCategoryId);
			Assert.Equal(1, generatedQuestion.ImportedClasses.Count);
			Assert.Equal("java.util.*", generatedQuestion.ImportedClasses[0].ClassName);

			var expectedContents =
				  "public class QuestionGenerator\n"
				+ "{\n" 
				+  "	public static Question generateQuestion(int seed)\n"
				+  "	{\n"
				+  "		QuestionConstructorInvocation\n"
				+  "	}\n"
				+ "}\n";

			Assert.Equal(expectedContents, generatedQuestion.GeneratorContents);
		}
		public async Task DeleteClassroomAsync_ClassroomDeleted()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.Build();

			var classroomId = database.Context.Classrooms.First().Id;

			database.Reload();

			var classroomService = new ClassroomService(database.Context);
			await classroomService.DeleteClassroomAsync("Class1");

			database.Reload();

			Assert.Equal(0, database.Context.Classrooms.Count());
		}
		public async Task GradeSubmissionAsync_NormalQuestion_StoresAndReturnsResult()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.AddStudent("User1", "Last", "First", "Class1", "Section1")
				.AddQuestionCategory("Class1", "Category1")
				.AddQuestion("Class1", "Category1", new MethodQuestion() { Name = "Question1" })
				.Build();

			var questionId = database.Context.Questions.First().Id;
			var userId = database.Context.Users.First().Id;

			database.Reload();

			var loaderFactory = GetMockQuestionLoaderFactory();
			var graderFactory = GetMockQuestionGraderFactory();
			var timeProvider = GetMockTimeProvider(new DateTime(2016, 1, 1));
			var questionSubmission = new CodeQuestionSubmission()
			{
				Contents = "SubmissionContents"
			};

			var serializer = new Mock<IJsonSerializer>();
			serializer
				.Setup(s => s.Serialize<QuestionSubmission>(questionSubmission))
				.Returns("SerializedSubmissionContents");

			var questionService = CreateQuestionService
			(
				database.Context,
				questionLoaderFactory: loaderFactory.Object,
				questionGraderFactory: graderFactory.Object,
				jsonSerializer: serializer.Object,
				timeProvider: timeProvider.Object
			);

			var result = await questionService.GradeSubmissionAsync
			(
				"Class1",
				userId,
				questionId,
				questionSubmission
			);

			Assert.Equal(1.0, result.Score);

			database.Reload();

			var submission = database.Context
				.UserQuestionSubmissions
				.Where(uqs => uqs.UserQuestionData.UserId == userId)
				.Include(uqs => uqs.UserQuestionData)
				.Single(uqs => uqs.UserQuestionData.QuestionId == questionId);

			Assert.Equal(1.0, submission.Score);

			Assert.Equal
			(
				"SerializedSubmissionContents", 
				submission.UserQuestionData.LastQuestionSubmission
			);

			Assert.Equal
			(
				new DateTime(2016, 1, 1),
				submission.DateSubmitted
			);
		}
		public async Task GetClassroomsWithAccessAsync_Student_ReturnsClassrooms()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.AddClassroom("Class2")
				.AddSection("Class2", "Section2")
				.AddStudent("User1", "Last", "First", "Class2", "Section2")
				.Build();

			var userId = database.Context.Users.First().Id;
			var classroomId = database.Context.Classrooms
				.Single(c => c.Name == "Class2")
				.Id;

			database.Reload();

			var classroomService = new ClassroomService(database.Context);
			var classrooms = await classroomService.GetClassroomsWithAccessAsync(userId);

			Assert.Equal(1, classrooms.Count);
			Assert.Equal(userId, classrooms[0].UserId);
			Assert.Equal(classroomId, classrooms[0].ClassroomId);
		}
		public async Task UpdateSectionAsync_SectionUpdated()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.Build();

			var section = database.Context.Sections
				.Include(qc => qc.Classroom)
				.First();

			// Update the section
			database.Context.Entry(section).State = EntityState.Detached;
			section.DisplayName = "New Display Name";

			// Apply the update
			var sectionService = new SectionService(database.Context);
			await sectionService.UpdateSectionAsync("Class1", section);

			database.Reload();

			section = database.Context.Sections
				.Include(qc => qc.Classroom)
				.Single();

			Assert.Equal("Class1", section.Classroom.Name);
			Assert.Equal("Section1", section.Name);
			Assert.Equal("New Display Name", section.DisplayName);
		}
		public async Task DeleteQuestionCategoryAsync_CategoryDeleted()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddQuestionCategory("Class1", "Category1")
				.Build();
			
			var questionCategoryId = database.Context.QuestionCategories.First().Id;

			database.Reload();

			var questionCategoryService = new QuestionCategoryService(database.Context);
			await questionCategoryService.DeleteQuestionCategoryAsync
			(
				"Class1",
				questionCategoryId
			);

			database.Reload();
			
			Assert.Equal(0, database.Context.QuestionCategories.Count());
		}
		public async Task DeleteSectionAsync_SectionDeleted()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Section1")
				.Build();
			
			database.Reload();

			var sectionService = new SectionService(database.Context);
			await sectionService.DeleteSectionAsync("Class1", "Section1");

			database.Reload();

			Assert.Equal(0, database.Context.Sections.Count());
		}
		public async Task CreateQuestionCategoryAsync_CategoryCreated()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.Build();
			
			var questionCategoryService = new QuestionCategoryService(database.Context);
			await questionCategoryService.CreateQuestionCategoryAsync
			(
				"Class1",
				new QuestionCategory()
				{
					Name = "Category1"
				}
			);

			database.Reload();

			var questionCategory = database.Context.QuestionCategories
				.Include(qc => qc.Classroom)
				.Single();

			Assert.Equal("Class1", questionCategory.Classroom.Name);
			Assert.Equal("Category1", questionCategory.Name);
		}
		public async Task CreateCheckpointAsync_CheckpointCreated()
		{
			var database = new TestDatabaseBuilder()
				.AddClassroom("Class1")
				.AddSection("Class1", "Period1")
				.AddSection("Class1", "Period2")
				.AddProject("Class1", "Project1")
				.AddProjectTestClass("Class1", "Project1", "TestClass1")
				.AddProjectTestClass("Class1", "Project1", "TestClass2")
				.Build();

			var testClasses = database.Context.TestClasses.ToList();
			var sections = database.Context.Sections.ToList();
			database.Reload();

			var modelErrors = new MockErrorCollection();
			var checkpointService = GetCheckpointService(database.Context);

			var result = await checkpointService.CreateCheckpointAsync
			(
				"Class1",
				"Project1",
				new Checkpoint()
				{
					Name = "Checkpoint1",
					DisplayName = "Checkpoint1 DisplayName",
					TestClasses = Collections.CreateList
					(
						new CheckpointTestClass() { TestClassId = testClasses[0].Id },
						new CheckpointTestClass() { TestClassId = testClasses[1].Id }
					),
					SectionDates = Collections.CreateList
					(
						new CheckpointDates()
						{
							SectionId = sections[0].Id,
							DueDate = Period1DueDate
						},
						new CheckpointDates()
						{
							SectionId = sections[1].Id,
							DueDate = Period2DueDate
						}
					)
				},
				modelErrors
			);

			database.Reload();

			var checkpoint = database.Context.Checkpoints
				.Include(c => c.Project)
				.Include(c => c.Project.Classroom)
				.Include(c => c.TestClasses)
				.Include(c => c.SectionDates)
				.Single();

			Assert.True(result);
			Assert.False(modelErrors.HasErrors);

			Assert.Equal("Class1", checkpoint.Project.Classroom.Name);
			Assert.Equal("Project1", checkpoint.Project.Name);
			Assert.Equal("Checkpoint1", checkpoint.Name);

			Assert.Equal(2, checkpoint.TestClasses.Count);
			Assert.Equal(testClasses[0].Id, checkpoint.TestClasses[0].TestClassId);
			Assert.Equal(testClasses[1].Id, checkpoint.TestClasses[1].TestClassId);

			Assert.Equal(2, checkpoint.SectionDates.Count);
			Assert.Equal(sections[0].Id, checkpoint.SectionDates[0].SectionId);
			Assert.Equal(Period1DueDate, checkpoint.SectionDates[0].DueDate);
			Assert.Equal(sections[1].Id, checkpoint.SectionDates[1].SectionId);
			Assert.Equal(Period2DueDate, checkpoint.SectionDates[1].DueDate);
		}