/// <summary> /// Constructor. /// </summary> public ViewFeedbackResult( Section section, Submission submission, IList<Checkpoint> checkpoints) { LastName = submission.Commit.User.LastName; FirstName = submission.Commit.User.FirstName; UserId = submission.Commit.User.Id; RepoName = submission.Commit.GetRepoName(); SubmissionId = submission.Id; PullRequestNumber = submission.PullRequestNumber; PushDate = submission.Commit.PushDate; Feedback = submission.Feedback; Unread = submission.DateFeedbackRead == null; var dueDate = submission.Checkpoint .SectionDates ?.FirstOrDefault(sd => sd.Section == section) ?.DueDate; FutureCheckpoints = dueDate != null && submission.Checkpoint .Project .Checkpoints .Any ( c => c.SectionDates?.Any ( sd => sd.SectionId == section.Id && sd.DueDate > dueDate.Value ) ?? false ); }
/// <summary> /// Constructor. /// </summary> public UserSubmissionResults( User user, Section section, IList<Checkpoint> checkpoints, IList<Submission> submissions) { User = user; SubmissionResults = checkpoints .Where ( c => c.SectionDates?.Any(sd => sd.Section == section) ?? false ) .OrderBy ( c => c.SectionDates.Single(sd => sd.Section == section).DueDate ) .Select ( checkpoint => new UserSubmissionResult ( section, checkpoint, submissions .Where(s => s.Checkpoint == checkpoint) .OrderByDescending(s => s.DateSubmitted) .FirstOrDefault() ) ).ToList(); }
/// <summary> /// Constructor. /// </summary> public PastSubmissionResult(Submission submission, Section section) { CheckpointDisplayName = submission.Checkpoint.DisplayName; CommitDate = submission.Commit.PushDate; DaysLate = submission.GetDaysLate(section); PullRequestNumber = submission.PullRequestNumber; Feedback = submission.Feedback; Build = submission.Commit.Build; }
/// <summary> /// Creates a section. /// </summary> public async Task CreateSectionAsync(string classroomName, Section section) { var classroom = await LoadClassroomAsync(classroomName); section.ClassroomId = classroom.Id; _dbContext.Add(section); await _dbContext.SaveChangesAsync(); }
/// <summary> /// Constructor. /// </summary> public UserSubmissionResult( Section section, Checkpoint checkpoint, Submission submission) { CheckpointName = checkpoint.Name; CheckpointDisplayName = checkpoint.DisplayName; CheckpointDueDate = checkpoint.SectionDates .Single(sd => sd.Section == section) .DueDate; Submission = submission; }
public async Task<IActionResult> Create(Section section) { EnsureNoDuplicateSectionGradebooks(section); if (ModelState.IsValid) { await SectionService.CreateSectionAsync(ClassroomName, section); return RedirectToAction("Index"); } else { return View("CreateEdit", section); } }
/// <summary> /// Updates a section. /// </summary> public async Task UpdateSectionAsync(string classroomName, Section section) { var classroom = await LoadClassroomAsync(classroomName); section.ClassroomId = classroom.Id; var currentSection = await _dbContext.Sections .Where(s => s.Id == section.Id) .SingleOrDefaultAsync(); _dbContext.Entry(currentSection).State = EntityState.Detached; UpdateSection(section); _dbContext.Update(section); await _dbContext.SaveChangesAsync(); }
/// <summary> /// Returns the given user's role for this section. /// </summary> private static SectionRole GetSectionRole(User user, Section section) { if (user?.SuperUser ?? false) { return SectionRole.Admin; } else { var classroomMembership = user?.ClassroomMemberships ?.SingleOrDefault(m => m.Classroom == section.Classroom); if (classroomMembership?.Role == ClassroomRole.Admin) return SectionRole.Admin; return classroomMembership?.SectionMemberships ?.SingleOrDefault(m => m.Section == section) ?.Role ?? SectionRole.None; } }
/// <summary> /// Constructor. /// </summary> public GradeSubmissionResult( User user, Section section, Submission currentSubmission, IList<Submission> pastSubmissions) { LastName = user.LastName; FirstName = user.FirstName; SubmissionId = currentSubmission.Id; CommitDate = currentSubmission.Commit.PushDate; DaysLate = currentSubmission.GetDaysLate(section); PullRequestNumber = currentSubmission.PullRequestNumber; Feedback = currentSubmission.Feedback; FeedbackSent = currentSubmission.FeedbackSent; Build = currentSubmission.Commit.Build; PastSubmissions = pastSubmissions .Select(ps => new PastSubmissionResult(ps, section)) .ToList(); RequiredTestsPassed = currentSubmission.Commit.Build.Status == BuildStatus.Completed && currentSubmission.Commit.Build.TestResults .Select ( tr => new { Required = currentSubmission.Checkpoint .TestClasses .FirstOrDefault ( tc => tc.TestClass.ClassName == tr.ClassName )?.Required ?? false, Passed = tr.Succeeded } ) .All ( tr => !tr.Required || tr.Passed ); }
/// <summary> /// Constructor. /// </summary> public BuildResult( Build build, bool latestBuild, Section section, IList<Checkpoint> checkpoints, IList<Submission> submissions, IList<BuildTestCount> allBuildTestCounts) { Build = build; LatestBuild = latestBuild; Submissions = new UserSubmissionResults ( build.Commit.User, section, checkpoints, submissions ); AllBuildTestCounts = allBuildTestCounts; }
/// <summary> /// Populates the view bag with information needed for registration. /// </summary> private void PopulateRegistrationViewBag(Section section) { ViewBag.ClassroomDisplayName = section.Classroom.DisplayName; ViewBag.SectionDisplayName = section.DisplayName; ViewBag.UserName = _identityProvider.CurrentIdentity.UserName; ViewBag.LastName = _identityProvider.CurrentIdentity.LastName; }
/// <summary> /// Returns a query for all submissions in a given checkpoint. /// </summary> private IQueryable<Submission> GetCheckpointSubmissionsQuery( Checkpoint checkpoint, Section section) { return _dbContext.Submissions .Where ( submission => submission.CheckpointId == checkpoint.Id && submission.Commit.User.ClassroomMemberships.Any ( cm => cm.SectionMemberships.Any ( sm => sm.SectionId == section.Id && sm.Role == SectionRole.Student ) ) ) .Include(submission => submission.Commit.User.ClassroomMemberships) .Include(submission => submission.Commit.Build); }
/// <summary> /// Returns all checkpoints for a given user, grouped by checkpoint. /// </summary> private static List<IGrouping<Checkpoint, Submission>> GroupSubmissions( Section section, List<Submission> submissions, User student) { return submissions .Where(s => s.Commit.UserId == student.Id) .OrderByDescending(s => s.DateSubmitted) .GroupBy(s => s.Checkpoint) .OrderByDescending ( group => group.Key .SectionDates .Single(sd => sd.SectionId == section.Id) .DueDate ).ToList(); }
/// <summary> /// Returns all submissions for the current checkpoint, along with /// submissions for past checkpoints. /// </summary> private async Task<List<Submission>> GetSubmissionsForGrading( Checkpoint checkpoint, Section section, DateTime dueDate) { return await _dbContext.Submissions .Where ( submission => submission.Checkpoint.ProjectId == checkpoint.ProjectId && submission.Checkpoint .SectionDates.First(sd => sd.SectionId == section.Id) .DueDate <= dueDate && submission.Commit.User.ClassroomMemberships.Any ( cm => cm.SectionMemberships.Any ( sm => sm.SectionId == section.Id && sm.Role == SectionRole.Student ) ) ) .Include(submission => submission.Commit.Build.TestResults) .Include(submission => submission.Commit.User.ClassroomMemberships) .Include(submission => submission.Checkpoint.SectionDates) .ToListAsync(); }
/// <summary> /// Returns all students in a given section. /// </summary> private async Task<List<User>> GetStudentsAsync(Section section) { return await _dbContext.Users .Where ( user => user.ClassroomMemberships.Any ( cm => cm.SectionMemberships.Any ( sm => sm.SectionId == section.Id && sm.Role == SectionRole.Student ) ) ) .OrderBy(user => user.LastName) .ThenBy(user => user.FirstName) .ToListAsync(); }
/// <summary> /// Returns the number of days late a given submission is. /// </summary> public int GetDaysLate(Section section) { var dueDate = Checkpoint .SectionDates .Single(sd => sd.Section == section) .DueDate; return (int)Math.Ceiling ( Math.Max ( (Commit.PushDate - dueDate).TotalDays, 0.0 ) ); }
/// <summary> /// Ensures that there are no duplicate section gradebooks. /// </summary> private void EnsureNoDuplicateSectionGradebooks(Section section) { var classroomGradebookIds = section.SectionGradebooks .Select(d => d.ClassroomGradebookId) .ToList(); if (classroomGradebookIds.Distinct().Count() != classroomGradebookIds.Count) { ModelState.AddModelError ( "SectionGradebooks", "You may only have one section gradebook per classroom gradebook." ); } }
/// <summary> /// Returns a list of students in the given section. /// </summary> private async Task<List<ClassroomMembership>> GetStudentsAsync(Section section) { return await _dbContext.ClassroomMemberships .Where ( cm => cm.SectionMemberships.Any ( sm => sm.SectionId == section.Id && sm.Role == SectionRole.Student ) ).Include(cm => cm.User) .ToListAsync(); }
/// <summary> /// Ensures a section membership exists for the given user and role. /// The caller is responsible for saving changes. /// </summary> private async Task<SectionMembership> EnsureSectionMembershipAsync( User user, Section section, SectionRole role) { var classroomMembership = await EnsureClassroomMembershipAsync( user, section.Classroom, ClassroomRole.General); if (classroomMembership.SectionMemberships == null) { classroomMembership.SectionMemberships = new List<SectionMembership>(); } var sectionMembership = classroomMembership.SectionMemberships .SingleOrDefault(m => m.SectionId == section.Id); if (sectionMembership == null) { sectionMembership = new SectionMembership() { ClassroomMembershipId = classroomMembership.Id, ClassroomMembership = classroomMembership, SectionId = section.Id, Section = section, Role = role }; classroomMembership.SectionMemberships.Add(sectionMembership); } else if (role > sectionMembership.Role) { sectionMembership.Role = role; } return sectionMembership; }
/// <summary> /// Updates a classroom. /// </summary> private void UpdateSection(Section section) { _dbContext.RemoveUnwantedObjects ( _dbContext.SectionGradebooks, sectionGradebook => sectionGradebook.Id, sectionGradebook => sectionGradebook.SectionId == section.Id, section.SectionGradebooks ); }
/// <summary> /// Adds a section to the database. /// </summary> public TestDatabaseBuilder AddSection( string classroomName, string sectionName, bool allowRegistrations = true) { var classroom = _buildContext.Classrooms .Single(c => c.Name == classroomName); var section = new Section() { Name = sectionName, DisplayName = $"{sectionName} DisplayName", ClassroomId = classroom.Id, AllowNewRegistrations = allowRegistrations }; _buildContext.Sections.Add(section); _buildContext.SaveChanges(); return this; }