public void Throws_UserNotAuthorizedForEntityException_When_User_Not_Part_Of_Same_Organization_As_Milestone() { // Setup var org1 = new Organization(); var org2 = new Organization(); var user = new User { IsOrganizationAdmin = true, Organization = org1 }; var ms = new MilestoneConfig { Organization = org2, IsStartingMilestone = true }; _context.MilestoneConfigs.Add(ms); _context.Users.Add(user); _context.SaveChanges(); IProcess <MilestoneIdParams, MilestoneDisplayViewModel> process = new MilestoneQueryProcesses(_context); // Act try { process.Execute(new MilestoneIdParams { MilestoneId = ms.Id, RequestingUserId = user.Id }); Assert.Fail("No exception was thrown"); } // Verify catch (UserNotAuthorizedForEntityException ex) { Assert.AreEqual(typeof(MilestoneConfig), ex.EntityType, "Exception's entity type was incorrect"); Assert.AreEqual(user.Id, ex.UserId, "Exception's user id value was incorrect"); Assert.AreEqual(ms.Id, ex.IdValue, "Exception's id value was incorrect"); } }
public void Uncompleted_Jobsearch_Milestone_Doesnt_Progress_To_Next_Milestone() { // Setup MilestoneConfig ms2 = new MilestoneConfig(); MilestoneConfig ms1 = new MilestoneConfig { JobSearchMetrics = new JobSearchMetrics { NumCompaniesCreated = 2 }, NextMilestone = ms2 }; JobSearch search = new JobSearch { Metrics = new JobSearchMetrics { NumCompaniesCreated = 1 }, CurrentMilestone = ms1 }; _unitOfWork.JobSearches.Add(search); _unitOfWork.Commit(); Mock <JobSearchByIdQuery> jobSearchQuery = new Mock <JobSearchByIdQuery>(_unitOfWork); jobSearchQuery.Setup(x => x.WithJobSearchId(It.IsAny <int>())).Returns(jobSearchQuery.Object); jobSearchQuery.Setup(x => x.Execute()).Returns(search); _serviceFactory.Setup(x => x.GetService <JobSearchByIdQuery>()).Returns(jobSearchQuery.Object); // Act new StartNextJobSearchMilestoneCommand(_serviceFactory.Object) .Execute(new StartNextJobSearchMilestoneCommandParams { JobSearchId = search.Id }); // Verify JobSearch result = _unitOfWork.JobSearches.Fetch().Single(); Assert.AreEqual(ms1, result.CurrentMilestone, "Job search's CurrentMilestone was incorrect"); }
public void Jobsearch_With_Current_Milestone_Does_Not_Get_Organization_Starting_Milestone_Propogated() { // Setup var org = new Organization(); var search = new JobSearch { User = new User { Organization = org } }; var ms1 = new MilestoneConfig { IsStartingMilestone = true }; var ms2 = new MilestoneConfig { IsStartingMilestone = true }; org.MilestoneConfigurations.Add(ms1); search.CurrentMilestone = ms2; _context.JobSearches.Add(search); _context.SaveChanges(); IProcess <JobSearchMilestonePropogationParams, JobSearchMilestoneChangedResultViewModel> process = new JobSearchMilestonePropogationProcesses(_context); // Verify var result = process.Execute(new JobSearchMilestonePropogationParams { JobSearchId = search.Id }); // Act Assert.IsFalse(result.JobSearchMilestoneChanged, "Process did not return the correct status"); Assert.AreEqual(ms2, search.CurrentMilestone, "Job search's current milestone is incorrect"); }
public void Jobsearch_That_Finished_Milestones_Already_Does_Not_Get_Organization_Starting_Milestone_Propogated() { // Setup var org = new Organization(); var search = new JobSearch { User = new User { Organization = org }, MilestonesCompleted = true }; var ms = new MilestoneConfig { IsStartingMilestone = true }; org.MilestoneConfigurations.Add(ms); _context.JobSearches.Add(search); _context.SaveChanges(); IProcess <JobSearchMilestonePropogationParams, JobSearchMilestoneChangedResultViewModel> process = new JobSearchMilestonePropogationProcesses(_context); // Verify var result = process.Execute(new JobSearchMilestonePropogationParams { JobSearchId = search.Id }); // Act Assert.IsFalse(result.JobSearchMilestoneChanged, "Process did not return the correct milestone changed status"); Assert.IsNull(search.CurrentMilestone, "Job search's current milestone was not null"); }
public void Returns_Organizations_Starting_Milestone_If_OrganizationId_Is_Given() { // Setup var org = new Organization(); var config1 = new MilestoneConfig { IsStartingMilestone = true }; var config2 = new MilestoneConfig { IsStartingMilestone = true, Organization = org }; var config3 = new MilestoneConfig { IsStartingMilestone = true }; _context.MilestoneConfigs.Add(config1); _context.MilestoneConfigs.Add(config2); _context.MilestoneConfigs.Add(config3); _context.SaveChanges(); // Act MilestoneConfig result = new StartingMilestoneQuery(_context).Execute(new StartingMilestoneQueryParams { OrganizationId = org.Id }); // Verify Assert.AreEqual(config2, result, "The returned milestone was incorrect"); }
public void JobSearch_With_No_Current_Or_Finished_Milestones_Gets_Organizations_Starting_Milestone() { // Setup var org = new Organization(); var search = new JobSearch { User = new User { Organization = org } }; var ms = new MilestoneConfig { IsStartingMilestone = true }; org.MilestoneConfigurations.Add(ms); _context.JobSearches.Add(search); _context.SaveChanges(); IProcess <JobSearchMilestonePropogationParams, JobSearchMilestoneChangedResultViewModel> process = new JobSearchMilestonePropogationProcesses(_context); // Verify var result = process.Execute(new JobSearchMilestonePropogationParams { JobSearchId = search.Id }); // Act Assert.IsTrue(result.JobSearchMilestoneChanged, "Process did not return status that current milestone changed"); Assert.AreEqual(ms, search.CurrentMilestone, "Job search's current milestone is incorrect"); }
public void Throws_EntityNotFoundException_If_User_Doesnt_Exist() { // Setup var ms = new MilestoneConfig(); _context.MilestoneConfigs.Add(ms); _context.SaveChanges(); IProcess <MilestoneIdParams, MilestoneDisplayViewModel> process = new MilestoneQueryProcesses(_context); int id = 5; // Act try { process.Execute(new MilestoneIdParams { MilestoneId = ms.Id, RequestingUserId = id }); Assert.Fail("No exception was thrown"); } // Verify catch (MJLEntityNotFoundException ex) { Assert.AreEqual(typeof(User), ex.EntityType, "Exception's entity type was incorrect"); Assert.AreEqual(id.ToString(), ex.IdValue, "Exception's id value was incorrect"); } }
public void Does_Not_Return_Starting_Milestone_For_Organization_If_None_Requested() { // Setup var org = new Organization(); var config1 = new MilestoneConfig { IsStartingMilestone = true, Organization = org }; var config2 = new MilestoneConfig { IsStartingMilestone = true }; var config3 = new MilestoneConfig { IsStartingMilestone = true, Organization = org }; _context.MilestoneConfigs.Add(config1); _context.MilestoneConfigs.Add(config2); _context.MilestoneConfigs.Add(config3); _context.SaveChanges(); // Act MilestoneConfig result = new StartingMilestoneQuery(_context).Execute(new StartingMilestoneQueryParams()); // Verify Assert.AreEqual(config2, result, "The returned milestone was incorrect"); }
public void Jobsearch_Marked_As_Milestones_Completed_When_Last_Milestone_Is_Completed() { // Setup var ms = new MilestoneConfig { JobSearchMetrics = new JobSearchMetrics() }; var search = new JobSearch { Metrics = new JobSearchMetrics(), CurrentMilestone = ms }; _context.MilestoneConfigs.Add(ms); _context.JobSearches.Add(search); _context.SaveChanges(); Mock <JobSearchByIdQuery> jobSearchQuery = new Mock <JobSearchByIdQuery>(_unitOfWork); jobSearchQuery.Setup(x => x.WithJobSearchId(It.IsAny <int>())).Returns(jobSearchQuery.Object); jobSearchQuery.Setup(x => x.Execute()).Returns(search); _serviceFactory.Setup(x => x.GetService <JobSearchByIdQuery>()).Returns(jobSearchQuery.Object); // Act new StartNextJobSearchMilestoneCommand(_serviceFactory.Object) .Execute(new StartNextJobSearchMilestoneCommandParams { JobSearchId = search.Id }); // Verify Assert.IsTrue(search.MilestonesCompleted, "Job search is not marked as completing all milestones"); }
public void Throws_NotAuthorizedException_When_User_Not_Org_Admin() { // Setup var org = new Organization(); var user = new User { Organization = org, IsOrganizationAdmin = false }; var m1 = new MilestoneConfig(); org.MilestoneConfigurations.Add(m1); _context.Users.Add(user); _context.Organizations.Add(org); _context.SaveChanges(); IProcess <ByOrganizationIdParams, MilestoneDisplayListViewModel> process = new MilestoneQueryProcesses(_context); // Act try { var result = process.Execute(new ByOrganizationIdParams { RequestingUserId = user.Id, OrganizationId = org.Id }); Assert.Fail("No exception was thrown"); } // Verify catch (UserNotAuthorizedForEntityException ex) { Assert.AreEqual(org.Id, ex.IdValue, "Exception's id value was incorrect"); Assert.AreEqual(typeof(Organization), ex.EntityType, "Exception's entity type was incorrect"); Assert.AreEqual(user.Id, ex.UserId, "Exception's user id value was incorrect"); } }
public void Can_Retrieve_Milestone_Data() { // Setup var user = new User { IsOrganizationAdmin = true }; var org = new Organization(); org.Members.Add(user); var ms3 = new MilestoneConfig { Organization = org }; var ms2 = new MilestoneConfig { Organization = org, Title = "title", Instructions = "instructions", NextMilestone = ms3, JobSearchMetrics = new JobSearchMetrics { NumApplyTasksCompleted = 1, NumApplyTasksCreated = 2, NumCompaniesCreated = 3, NumContactsCreated = 4, NumInPersonInterviewTasksCreated = 5, NumPhoneInterviewTasksCreated = 6 } }; var ms1 = new MilestoneConfig { Organization = org, NextMilestone = ms2, IsStartingMilestone = true, Title = "previous title" }; _context.MilestoneConfigs.Add(ms1); _context.SaveChanges(); IProcess <MilestoneIdParams, MilestoneDisplayViewModel> process = new MilestoneQueryProcesses(_context); // Act var result = process.Execute(new MilestoneIdParams { MilestoneId = ms2.Id, RequestingUserId = user.Id }); // Setup Assert.IsNotNull(result, "Process returned a null result"); Assert.AreEqual(ms2.Id, result.Id, "Id value was incorrect"); Assert.AreEqual(ms2.Title, result.Title, "Title was incorrect"); Assert.AreEqual(ms2.Instructions, result.Instructions, "Instructions value was incorrect"); Assert.AreEqual(ms2.CompletionDisplay, result.CompletionDisplay, "Completion display was incorrect"); Assert.AreEqual(ms2.JobSearchMetrics, result.JobSearchMetrics, "Job Search metrics were incorrect"); Assert.AreEqual(ms1.Id, result.PreviousMilestoneId, "Previous milestone id was incorrect"); Assert.AreEqual(ms1.Title, result.PreviousMilestoneName, "Previous milestone title was icorrect"); }
public void Can_Edit_Milestone() { // Setup var org = new Organization(); var user = new User { Organization = org, IsOrganizationAdmin = true }; var ms = new MilestoneConfig(); org.MilestoneConfigurations.Add(ms); _context.Users.Add(user); _context.SaveChanges(); var param = new SaveMilestoneParams { RequestingUserId = user.Id, Id = ms.Id, Title = "Title", Instructions = "Instructions", CompletionDisplay = "Completion", JobSearchMetrics = new DomainModel.Entities.Metrics.JobSearchMetrics { NumApplyTasksCompleted = 1, NumApplyTasksCreated = 2, NumCompaniesCreated = 3, NumContactsCreated = 4, NumInPersonInterviewTasksCreated = 5, NumPhoneInterviewTasksCreated = 6 } }; IProcess <SaveMilestoneParams, MilestoneIdViewModel> process = new MilestoneNonQueryProcesses(_context); // Act var result = process.Execute(param); // Verify var milestone = _context.MilestoneConfigs.SingleOrDefault(); Assert.IsNotNull(milestone, "No milestone was created"); Assert.IsNotNull(result, "Process returned a null result"); Assert.AreEqual(milestone.Id, result.Id, "Result's id value and the milestone's id value did not match"); Assert.AreEqual(ms, milestone, "Milestone in the database was incorrect"); Assert.AreEqual(org, milestone.Organization, "Milestone's organization was incorrect"); Assert.AreEqual(param.Title, milestone.Title, "Milestone's title was incorrect"); Assert.AreEqual(param.Instructions, milestone.Instructions, "Milestone's instructions were incorrect"); Assert.AreEqual(param.CompletionDisplay, milestone.CompletionDisplay, "Milestone's completion text was incorrect"); Assert.AreEqual(param.JobSearchMetrics.NumApplyTasksCompleted, milestone.JobSearchMetrics.NumApplyTasksCompleted, "Milestones num apply tasks completed was incorrect"); Assert.AreEqual(param.JobSearchMetrics.NumApplyTasksCreated, milestone.JobSearchMetrics.NumApplyTasksCreated, "Milestones num apply tasks created was incorrect"); Assert.AreEqual(param.JobSearchMetrics.NumCompaniesCreated, milestone.JobSearchMetrics.NumCompaniesCreated, "Milestones num companies was incorrect"); Assert.AreEqual(param.JobSearchMetrics.NumContactsCreated, milestone.JobSearchMetrics.NumContactsCreated, "Milestones num contacts was incorrect"); Assert.AreEqual(param.JobSearchMetrics.NumInPersonInterviewTasksCreated, milestone.JobSearchMetrics.NumInPersonInterviewTasksCreated, "Milestones num InPersonInterview Tasks completed was incorrect"); Assert.AreEqual(param.JobSearchMetrics.NumPhoneInterviewTasksCreated, milestone.JobSearchMetrics.NumPhoneInterviewTasksCreated, "Milestones Num InPersonInterview Tasks created was incorrect"); }
public void Specifying_Previous_Milestone_Moves_Milestone_In_Between_Other_Milestones_In_Organization() { // Setup var org = new Organization(); var user = new User { Organization = org, IsOrganizationAdmin = true }; var ms4 = new MilestoneConfig { IsStartingMilestone = true, Organization = new Organization() }; var ms3 = new MilestoneConfig(); var ms2 = new MilestoneConfig { NextMilestone = ms3 }; var ms1 = new MilestoneConfig { NextMilestone = ms2, IsStartingMilestone = true }; org.MilestoneConfigurations.Add(ms1); org.MilestoneConfigurations.Add(ms2); org.MilestoneConfigurations.Add(ms3); _context.Users.Add(user); _context.MilestoneConfigs.Add(ms3); _context.SaveChanges(); var param = new SaveMilestoneParams { RequestingUserId = user.Id, Id = ms3.Id, PreviousMilestoneId = ms1.Id }; IProcess <SaveMilestoneParams, MilestoneIdViewModel> process = new MilestoneNonQueryProcesses(_context); // Act var result = process.Execute(param); // Verify Assert.IsFalse(ms3.IsStartingMilestone, "Milestone 3 was incorrectly set as the starting milestone"); Assert.AreEqual(ms2, ms3.NextMilestone, "Milestone 3's next milestone was incorrect"); Assert.IsTrue(ms1.IsStartingMilestone, "The previous starting milestone is no longer set as the starting milestone"); Assert.AreEqual(ms3, ms1.NextMilestone, "Ms1's next milestone was incorrect"); Assert.IsTrue(ms4.IsStartingMilestone, "Other organization's milestone was incorrectly set as non-starting"); }
public void New_JobSearch_Queries_For_Organizations_Starting_MilestoneConfig_When_User_In_Organization() { // Setup InitializeTestEntities(); MilestoneConfig config = new MilestoneConfig(); _unitOfWork.MilestoneConfigs.Add(config); _unitOfWork.Commit(); _startingMilestoneQuery.Setup(x => x.Execute(It.Is <StartingMilestoneQueryParams>(y => y.OrganizationId == _org.Id))).Returns(config); // Act new CreateJobSearchForUserCommand(_serviceFactory.Object).ForUserId(_user.Id).Execute(); // Verify JobSearch result = _unitOfWork.JobSearches.Fetch().Single(); Assert.AreEqual(config, result.CurrentMilestone, "Job Search's current milestone was incorrect"); }
public void Specifying_Previous_Milestone_Of_Zero_Makes_It_The_Only_Starting_Milestone_For_Organization_When_Creating_Milestone() { // Setup var org = new Organization(); var user = new User { Organization = org, IsOrganizationAdmin = true }; var ms3 = new MilestoneConfig { IsStartingMilestone = true, Organization = new Organization() }; var ms2 = new MilestoneConfig(); var ms1 = new MilestoneConfig { NextMilestone = ms2, IsStartingMilestone = true }; org.MilestoneConfigurations.Add(ms1); org.MilestoneConfigurations.Add(ms2); _context.Users.Add(user); _context.MilestoneConfigs.Add(ms3); _context.SaveChanges(); var param = new SaveMilestoneParams { RequestingUserId = user.Id, OrganizationId = org.Id, PreviousMilestoneId = 0 }; IProcess <SaveMilestoneParams, MilestoneIdViewModel> process = new MilestoneNonQueryProcesses(_context); // Act var result = process.Execute(param); // Verify var newMs = _context.MilestoneConfigs.Where(x => x.Id != ms1.Id && x.Id != ms2.Id && x.Id != ms3.Id).Single(); Assert.IsTrue(newMs.IsStartingMilestone, "New milestone was not set at the starting milestone"); Assert.AreEqual(ms1, newMs.NextMilestone, "New milestone's next milestone was incorrect"); Assert.IsFalse(ms1.IsStartingMilestone, "The previous starting milestone is still set as the starting milestone"); Assert.AreEqual(ms2, ms1.NextMilestone, "Ms1's next milestone was incorrect"); Assert.IsTrue(ms3.IsStartingMilestone, "Other organization's milestone was incorrectly set as non-starting"); }
public void Can_Calculate_NumContactsCreatedProgress() { // Setup MilestoneConfig milestone = new MilestoneConfig { JobSearchMetrics = new JobSearchMetrics { NumContactsCreated = 5 } }; JobSearch jobSearch = new JobSearch { Metrics = new JobSearchMetrics { NumContactsCreated = 2 }, CurrentMilestone = milestone }; // Execute JobSearchMilestoneProgress result = new JobSearchMilestoneProgress(jobSearch); // Verify Assert.AreEqual(((decimal)2 / (decimal)5), result.NumContactsCreatedProgress, "NumContactsCreatedProgress's value was incorrect"); }
public void Progess_Is_One_When_Milestone_NumInPersonInterviewTasksCreated_Is_Zero() { // Setup MilestoneConfig milestone = new MilestoneConfig { JobSearchMetrics = new JobSearchMetrics { NumInPersonInterviewTasksCreated = 0 } }; JobSearch jobSearch = new JobSearch { Metrics = new JobSearchMetrics { NumInPersonInterviewTasksCreated = 2 }, CurrentMilestone = milestone }; // Execute JobSearchMilestoneProgress result = new JobSearchMilestoneProgress(jobSearch); // Verify Assert.AreEqual(1, result.NumInPersonInterviewTasksCreatedProgress, "NumInPersonInterviewTasksCreatedProgress's value was incorrect"); }
public void Progress_Is_One_When_JobSearch_NumCompaniesCreated_Is_Greater_Than_Milestone() { // Setup MilestoneConfig milestone = new MilestoneConfig { JobSearchMetrics = new JobSearchMetrics { NumCompaniesCreated = 3 } }; JobSearch jobSearch = new JobSearch { Metrics = new JobSearchMetrics { NumCompaniesCreated = 4 }, CurrentMilestone = milestone }; // Execute JobSearchMilestoneProgress result = new JobSearchMilestoneProgress(jobSearch); // Verify Assert.AreEqual(1, result.NumCompaniesCreatedProgress, "NumCompaniesCreatedProgress's value was incorrect"); }
public void Can_Retrieve_Milestones_For_Organization() { // Setup var org1 = new Organization(); var org2 = new Organization(); var user = new User { Organization = org1, IsOrganizationAdmin = true }; var m1 = new MilestoneConfig(); var m2 = new MilestoneConfig(); var m3 = new MilestoneConfig { IsStartingMilestone = true, NextMilestone = m1 }; org1.MilestoneConfigurations.Add(m1); org2.MilestoneConfigurations.Add(m2); org1.MilestoneConfigurations.Add(m3); _context.Organizations.Add(org1); _context.Organizations.Add(org2); _context.Users.Add(user); _context.SaveChanges(); IProcess <ByOrganizationIdParams, MilestoneDisplayListViewModel> process = new MilestoneQueryProcesses(_context); // Act var result = process.Execute(new ByOrganizationIdParams { RequestingUserId = user.Id, OrganizationId = org1.Id }); // Verify Assert.IsNotNull(result, "Process returned a null result"); Assert.IsNotNull(result.Milestones, "Process returned a null list of milestones"); Assert.AreEqual(2, result.Milestones.Count, "Process returned a incorrect number of milestones"); Assert.IsTrue(result.Milestones.Any(x => x.Id == m1.Id), "Results did not have the first milestone"); Assert.IsTrue(result.Milestones.Any(x => x.Id == m3.Id), "Results did not have the third milestone"); }
public void Can_Retrieve_First_Seen_Starting_Milestone() { // Setup MilestoneConfig config1 = new MilestoneConfig { IsStartingMilestone = false }; MilestoneConfig config2 = new MilestoneConfig { IsStartingMilestone = true }; MilestoneConfig config3 = new MilestoneConfig { IsStartingMilestone = false }; _unitOfWork.MilestoneConfigs.Add(config1); _unitOfWork.MilestoneConfigs.Add(config2); _unitOfWork.MilestoneConfigs.Add(config3); _unitOfWork.Commit(); // Act MilestoneConfig result = new StartingMilestoneQuery(_context).Execute(new StartingMilestoneQueryParams()); // Verify Assert.AreEqual(config2, result, "The returned milestone configuration was incorrect"); }
public void Milestone_List_Is_Ordered_In_Milestone_Order() { // Setup var org1 = new Organization(); var user = new User { Organization = org1, IsOrganizationAdmin = true }; var m1 = new MilestoneConfig(); var m2 = new MilestoneConfig(); var m3 = new MilestoneConfig(); org1.MilestoneConfigurations.Add(m1); org1.MilestoneConfigurations.Add(m2); org1.MilestoneConfigurations.Add(m3); m2.IsStartingMilestone = true; m2.NextMilestone = m1; m1.NextMilestone = m3; _context.Organizations.Add(org1); _context.Users.Add(user); _context.SaveChanges(); IProcess <ByOrganizationIdParams, MilestoneDisplayListViewModel> process = new MilestoneQueryProcesses(_context); // Act var result = process.Execute(new ByOrganizationIdParams { RequestingUserId = user.Id, OrganizationId = org1.Id }); // Verify Assert.AreEqual(3, result.Milestones.Count, "Milestone count was incorrect"); Assert.AreEqual(m2.Id, result.Milestones[0].Id, "First milestone was incorrect"); Assert.AreEqual(m1.Id, result.Milestones[1].Id, "Second milestone was incorrect"); Assert.AreEqual(m3.Id, result.Milestones[2].Id, "Third milestone was incorrect"); }
public void Throws_UserNotAuthorizedForEntityException_When_Editing_Milestone_And_User_Not_Admin_For_Organization() { // Setup var org = new Organization(); var user = new User { Organization = org, IsOrganizationAdmin = false }; var ms = new MilestoneConfig(); org.MilestoneConfigurations.Add(ms); _context.Users.Add(user); _context.SaveChanges(); var param = new SaveMilestoneParams { RequestingUserId = user.Id, Id = ms.Id }; IProcess <SaveMilestoneParams, MilestoneIdViewModel> process = new MilestoneNonQueryProcesses(_context); // Act try { var result = process.Execute(param); Assert.Fail("No exception was thrown"); } // Verify catch (UserNotAuthorizedForEntityException ex) { Assert.AreEqual(typeof(Organization), ex.EntityType, "Exception's type was incorrect"); Assert.AreEqual(user.Id, ex.UserId, "Exception's user id value was incorrect"); Assert.AreEqual(org.Id, ex.IdValue, "Exception's entity id value was incorrect"); } }
public MilestoneIdViewModel Execute(SaveMilestoneParams procParams) { MilestoneConfig milestone; // Determine if we are creating a new milestone or editing an existing one if (procParams.Id == 0) { var org = _context.Organizations.Where(x => x.Id == procParams.OrganizationId).FirstOrDefault(); if (!org.Members.Any(x => x.Id == procParams.RequestingUserId && x.IsOrganizationAdmin)) { throw new UserNotAuthorizedForEntityException(typeof(Organization), procParams.OrganizationId, procParams.RequestingUserId); } milestone = Mapper.Map <SaveMilestoneParams, MilestoneConfig>(procParams); milestone.Organization = org; _context.MilestoneConfigs.Add(milestone); } else { milestone = _context.MilestoneConfigs .Where(x => x.Id == procParams.Id) .Include(x => x.Organization) .SingleOrDefault(); // Make sure the user is authorized to edit the milestone if (milestone.Organization != null) { if (!milestone.Organization.Members.Any(x => x.Id == procParams.RequestingUserId && x.IsOrganizationAdmin)) { throw new UserNotAuthorizedForEntityException(typeof(Organization), milestone.Organization.Id, procParams.RequestingUserId); } } milestone = Mapper.Map <SaveMilestoneParams, MilestoneConfig>(procParams, milestone); } // Place the milestone in it's specified spot var startingMilestone = milestone.Organization.MilestoneConfigurations.Where(x => x.IsStartingMilestone).FirstOrDefault(); if (startingMilestone == null) { // There should be no milestones since none is starting milestone.IsStartingMilestone = true; } else { // First loop through all the milestones and unlink the current milestone MilestoneConfig currentMilestone = startingMilestone; while (currentMilestone != null) { if (currentMilestone.NextMilestone == milestone) { currentMilestone.NextMilestone = milestone.NextMilestone; break; } currentMilestone = currentMilestone.NextMilestone; } // If the previous milestone id is zero, set it as the starting milestone if (procParams.PreviousMilestoneId == 0) { milestone.IsStartingMilestone = true; milestone.NextMilestone = startingMilestone; startingMilestone.IsStartingMilestone = false; } else { // Do a second loop to add the milestone back into it's correct position currentMilestone = startingMilestone; while (currentMilestone != null) { if (currentMilestone.Id == procParams.PreviousMilestoneId) { milestone.NextMilestone = currentMilestone.NextMilestone; currentMilestone.NextMilestone = milestone; break; } currentMilestone = currentMilestone.NextMilestone; } } } _context.SaveChanges(); return(new MilestoneIdViewModel { Id = milestone.Id }); }