/// <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
                    );
        }
Example #10
0
        /// <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;
        }
Example #11
0
		/// <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();
		}
Example #16
0
        /// <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."
				);
			}
		}
Example #18
0
		/// <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();
		}
Example #19
0
		/// <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;
		}
Example #20
0
		/// <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;
        }