/// <summary> /// performs the specified function using the given package and difs the result /// </summary> /// <param name="action">the function to perform on the work package</param> /// <param name="package">the work package to perform the action on</param> /// <param name="doCompare">true to do a comparison after the action, false otherwise</param> /// <param name="compareIds">true to compare ids as well, false otherwise</param> private static WorkPackageDTO ActionAndComparePackage(Func<WorkPackageDTO, IHttpActionResult> action, WorkPackageDTO package, bool doCompare, bool compareIds = false) { WorkPackageDTO originalPackage = null; if (doCompare) { // clone the object as the controller doesn't guarantee the object won't be modified originalPackage = Helper.CloneObject(package); } var result = action(package); // get the value from the response var createdPackage = Helper.GetValueFromActionResult<WorkPackageDTO>(result); if (doCompare) { createdPackage.TestEquals(originalPackage); if (compareIds) { AssertRand.AreEqual(createdPackage.Id, originalPackage.Id, "Updated Package Id != Original Package Id"); } } return createdPackage; }
/// <summary> /// Calls the create method on the controller and difs the result /// </summary> /// <param name="package">The package to create</param> /// <param name="doCompare">true to do the comparison afterward, false otherwise</param> public static WorkPackageDTO CreateAndComparePackage(WorkPackageDTO package, bool doCompare) { return Globals.ActionAndComparePackage(Globals.Controller.CreatePackage, package, doCompare); }
public static void ChildTasks(WorkPackageDTO wp, MutateType type) { var indices = Helper.GenerateShuffledIndexList(wp.Tasks); indices.Sort((a, b) => b - a); // to make removal easier, sort it in reverse order switch (type) { case MutateType.Add: for (var i = 0; i < indices.Count; i++) { wp.Tasks.Add(Generate.Task()); } break; case MutateType.Remove: foreach (var i in indices) { wp.Tasks.RemoveAt(i); } break; case MutateType.Modify: foreach (var i in indices) { Mutate.Task(wp.Tasks.ElementAt(i)); } break; default: throw new ArgumentOutOfRangeException("type", type, null); } }
public static void EmptyPackage(WorkPackageDTO wp) { wp.Name = Helper.RandomString(); }
public static WorkPackageDTO ChildPackages(WorkPackageDTO package) { var count = Helper.NextInt(2, 20); for (var i = 0; i < count; i++) { package.ChildPackages.Add(Generate.WithChildTasks()); } return package; }
/// <summary> /// Runs the provided package by a set of rules /// </summary> /// <returns>null on success, or an IHttpActionResult on a failure</returns> private IHttpActionResult ValidatePackage(WorkPackageDTO package) { // get the list of child packages var allPackages = new ListSet<WorkPackageDTO>(package.AllChildren) { package // include the root package to make coding life easier }; // load any existing packages from the context var childPackagesFromDb = this._workPackageRepository.GetAll(allPackages.Select(wp => wp.Id).Where(i => i > 0)).ToDictionary(wp => wp.Id); // first pass - replace non modifyable packages with their current data from the db var newPackageCount = -1; var newTaskCount = -1; for (var i = 0; i < allPackages.Count; i++) { var pkg = allPackages[i]; if (childPackagesFromDb.ContainsKey(pkg.Id)) { // we're dealing with an existing package var fromDb = childPackagesFromDb[pkg.Id]; if (fromDb.IsReadOnlyFor(this._currentUser)) { // ignore any changes to packages the user has no right to change allPackages[i] = Mapper.Map<WorkPackageDTO>(fromDb); continue; } else { // note that we don't update the values here - it gets done by the repository } } else { // we're dealing with a new package pkg.Id = newPackageCount--; pkg.CreatedBy = this._currentUserDto; } // make sure each of the tasks have a unique Id foreach (var task in pkg.Tasks.Where(t => t.Id < 0)) { task.Id = newTaskCount--; } } // second pass - update the packages with correct references // note that whilst we don't update the read only package's content (tasks, name, etc) - we do have to make sure it has the correct package references // so that EF doesn't try and add two of the same package var childDict = allPackages.ToDictionary(wp => wp.Id); var processedPackages = new HashSet<WorkPackageDTO>(); foreach (var pkg in allPackages) { if (!Utilities.IsNullOrEmpty(pkg.ChildPackages) && // save a little time in processing packages with no children !processedPackages.Contains(pkg)) // don't reprocess packages { pkg.ChildPackages = new ListSet<WorkPackageDTO>(pkg.ChildPackages.Select(child => childDict[child.Id])); } processedPackages.Add(pkg); } // third pass - check for cycles // we do this last because we may remove a cycle when we clean up readonly packages var packageWithCycle = package.DetectCycles(); if (packageWithCycle != null) { return this.BadRequest(string.Format(Resources.Error_CreatePackage_Cycles, packageWithCycle.Id)); } return null; }