public async Task PatchAsync_UpdateLearningModuleWithNonAdminUser_ReturnsUnauthorizedResult()
        {
            // ARRANGE
            var learningModuleModel = new ResourceModuleViewPatchModel
            {
                LearningModule = new LearningModuleViewModel
                {
                    Title       = "Test title",
                    Description = "Test description",
                    ImageUrl    = "https://test.jpg",
                },
            };
            var module = FakeData.GetLearningModule();

            module.CreatedBy = Guid.NewGuid();
            this.memberValidationService.Setup(validationService => validationService.ValidateMemberAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())).ReturnsAsync(false);
            this.unitOfWork.Setup(uow => uow.LearningModuleRepository.GetAsync(It.IsAny <Guid>())).ReturnsAsync(module);

            // ACT
            var result = (ObjectResult)await this.learningModuleController.PatchAsync(Guid.NewGuid(), learningModuleModel);

            // ASSERT
            Assert.AreEqual(result.StatusCode, StatusCodes.Status401Unauthorized);
        }
        public async Task <IActionResult> PatchAsync(Guid id, ResourceModuleViewPatchModel moduleResourceDetails)
        {
            try
            {
                this.logger.LogError("Learning module - HTTP Patch call initiated.");
                this.RecordEvent("Learning module - HTTP Patch call initiated", RequestType.Initiated);

                if (moduleResourceDetails == null)
                {
                    this.logger.LogError($"Learning module details is null for userId: {this.UserObjectId}");
                    this.RecordEvent("Learning module - HTTP Patch call failed.", RequestType.Failed);

                    return(this.BadRequest("Learning module details cannot be null."));
                }

                if (id == null || id == Guid.Empty)
                {
                    this.logger.LogError($"Learning module - HTTP Patch module Id is either null or empty guid for userId: {this.UserObjectId}");
                    this.RecordEvent("Learning module - HTTP patch call failed.", RequestType.Failed);
                    return(this.BadRequest("Learning module Id cannot be null or empty."));
                }

                var existingLearningModuleDetails = await this.unitOfWork.LearningModuleRepository.GetAsync(id);

                if (existingLearningModuleDetails == null)
                {
                    this.logger.LogError(StatusCodes.Status404NotFound, $"Learning module detail that user is trying to update does not exist for learning module id: {id} and userId: {this.UserObjectId}");
                    this.RecordEvent("Learning module - HTTP patch call failed.", RequestType.Failed);
                    return(this.NotFound("Learning module not found."));
                }

                if (existingLearningModuleDetails.CreatedBy != this.UserObjectId)
                {
                    var isAdmin = await this.memberValidationService.ValidateMemberAsync(this.UserObjectId.ToString(), this.securityGroupOptions.Value.AdminGroupId, this.Request.Headers["Authorization"].ToString());

                    if (!isAdmin)
                    {
                        this.logger.LogError(StatusCodes.Status401Unauthorized, $"The current user who is trying to update learning module detail have not created learning module or not a part of administrator group for learning module id: {id} ");
                        this.RecordEvent("Resource - HTTP Patch call failed, user is not creator of learning module or not part of an administrator group.", RequestType.Failed);
                        return(this.Unauthorized("Current user does not have permission to update given learning module"));
                    }
                }

                // Delete existing resource tag from storage.
                this.unitOfWork.LearningModuleTagRepository.DeleteLearningModuleTag(existingLearningModuleDetails.LearningModuleTag);

                // Delete resource module mapping from storage.
                var existingResourceModuleMappings = await this.unitOfWork.ResourceModuleRepository.FindAsync(module => module.LearningModuleId == existingLearningModuleDetails.Id);

                if (existingResourceModuleMappings.Any() && moduleResourceDetails.Resources.Count() < existingResourceModuleMappings.Count())
                {
                    var resourceModuleMappingsToRetain = moduleResourceDetails.Resources;
                    foreach (var resourceModuleMapping in existingResourceModuleMappings)
                    {
                        var resourceMapping = resourceModuleMappingsToRetain.FirstOrDefault(k => k.Id == resourceModuleMapping.ResourceId);
                        if (resourceMapping == null)
                        {
                            this.unitOfWork.ResourceModuleRepository.Delete(resourceModuleMapping);
                        }
                    }
                }

                // Update learning module details to storage.
                var resourceTag = moduleResourceDetails.LearningModule.LearningModuleTag;
                moduleResourceDetails.LearningModule.LearningModuleTag = null;
                moduleResourceDetails.LearningModule.CreatedOn         = existingLearningModuleDetails.CreatedOn;
                moduleResourceDetails.LearningModule.CreatedBy         = existingLearningModuleDetails.CreatedBy;

                var learningModuleEntityModel = this.learningModuleMapper.PatchAndMapToDTO(moduleResourceDetails.LearningModule, this.UserObjectId);
                this.unitOfWork.LearningModuleRepository.Update(learningModuleEntityModel);

                // Add selected learning module Tags to database.
                List <LearningModuleTag> learningModuleTags = resourceTag.Select(x => new LearningModuleTag {
                    LearningModuleId = learningModuleEntityModel.Id, TagId = x.TagId
                }).ToList();

                this.unitOfWork.LearningModuleTagRepository.AddLearningModuleTag(learningModuleTags);

                await this.unitOfWork.SaveChangesAsync();

                this.RecordEvent("Learning module - HTTP patch call succeeded.", RequestType.Succeeded);
                this.logger.LogInformation("Learning module - HTTP patch call succeeded");

                // Get userId and user display name.
                IEnumerable <string> userAADObjectIds = new string[] { learningModuleEntityModel.CreatedBy.ToString() };
                var idToNameMap = await this.usersService.GetUserDisplayNamesAsync(this.UserObjectId.ToString(), this.Request.Headers["Authorization"].ToString(), userAADObjectIds);

                var learningModuleVotes = await this.GetLearningModuleVotesAsync(learningModuleEntityModel.Id);

                var moduledata = await this.unitOfWork.LearningModuleRepository.GetAsync(id);

                var resourceCount = await this.GetLearningModuleResourcesAsync(learningModuleEntityModel.Id);

                var learningModule = this.learningModuleMapper.PatchAndMapToViewModel(
                    moduledata,
                    this.UserObjectId,
                    learningModuleVotes,
                    resourceCount,
                    idToNameMap);

                return(this.Ok(learningModule));
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, $"Error while updating learning module with Id: {id}");
                this.RecordEvent("Learning module - HTTP patch call failed.", RequestType.Failed);
                throw;
            }
        }