public void TestAddStepToGoal()
        {
            // Generate db entry to test.
            var rnd   = new Random();
            var count = rnd.Next(1, 13);

            foreach (var i in Range(0, count))
            {
                _ = _userEditRepo.Create(RandomUserEdit()).Result;
            }
            var origUserEdit = _userEditRepo.Create(RandomUserEdit()).Result;

            // Generate correct result for comparison.
            var          modUserEdit  = origUserEdit.Clone();
            const string stringStep   = "This is another step added.";
            const int    modGoalIndex = 0;

            modUserEdit.Edits[modGoalIndex].StepData.Add(stringStep);

            // Create and put wrapper object.
            var stepWrapperObj = new UserEditStepWrapper(modGoalIndex, stringStep);

            _ = _userEditController.UpdateUserEditStep(_projId, origUserEdit.Id, stepWrapperObj);

            // Step count should have increased by 1.
            Assert.That(_userEditRepo.GetAllUserEdits(_projId).Result, Has.Count.EqualTo(count + 1));

            var userEdit = _userEditRepo.GetUserEdit(_projId, origUserEdit.Id).Result;

            if (userEdit is null)
            {
                Assert.Fail();
                return;
            }
            Assert.Contains(stringStep, userEdit.Edits[modGoalIndex].StepData);

            // Now update a step within the goal.
            const string modStringStep = "This is a replacement step.";
            const int    modStepIndex  = 1;

            modUserEdit.Edits[modGoalIndex].StepData[modStepIndex] = modStringStep;

            // Create and put wrapper object.
            stepWrapperObj = new UserEditStepWrapper(modGoalIndex, modStringStep, modStepIndex);
            _ = _userEditController.UpdateUserEditStep(_projId, origUserEdit.Id, stepWrapperObj);

            // Step count should not have further increased.
            Assert.That(_userEditRepo.GetAllUserEdits(_projId).Result, Has.Count.EqualTo(count + 1));

            userEdit = _userEditRepo.GetUserEdit(_projId, origUserEdit.Id).Result;
            if (userEdit is null)
            {
                Assert.Fail();
                return;
            }
            Assert.Contains(modStringStep, userEdit.Edits[modGoalIndex].StepData);
        }
        public async Task <IActionResult> UpdateUserEditStep(string projectId, string userEditId,
                                                             [FromBody, BindRequired] UserEditStepWrapper stepEdit)
        {
            if (!await _permissionService.HasProjectPermission(HttpContext, Permission.WordEntry))
            {
                return(Forbid());
            }

            // Check to see if user is changing the correct user edit
            if (await _permissionService.IsViolationEdit(HttpContext, userEditId, projectId))
            {
                return(BadRequest("You cannot edit another user's UserEdit."));
            }

            // Ensure project exists.
            var proj = await _projRepo.GetProject(projectId);

            if (proj is null)
            {
                return(NotFound(projectId));
            }

            // Ensure userEdit exists.
            var document = await _userEditRepo.GetUserEdit(projectId, userEditId);

            if (document is null)
            {
                return(NotFound(projectId));
            }

            // Ensure indices exist.
            if (stepEdit.GoalIndex < 0 || stepEdit.GoalIndex >= document.Edits.Count)
            {
                return(BadRequest("Goal index out of range."));
            }
            var maxStepIndex = document.Edits[stepEdit.GoalIndex].StepData.Count;
            var stepIndex    = stepEdit.StepIndex ?? maxStepIndex;

            if (stepIndex < 0 || stepIndex > maxStepIndex)
            {
                return(BadRequest("Step index out of range."));
            }

            // Add new step to or update step in goal.
            if (stepIndex == maxStepIndex)
            {
                await _userEditService.AddStepToGoal(
                    projectId, userEditId, stepEdit.GoalIndex, stepEdit.StepString);
            }
            else
            {
                await _userEditService.UpdateStepInGoal(
                    projectId, userEditId, stepEdit.GoalIndex, stepEdit.StepString, stepIndex);
            }

            return(Ok(stepIndex));
        }