public async Task <IActionResult> AddUserTaskAsync([FromBody] UserTaskResource userTaskResource) { // How does this validate against the UserTask model? if (!ModelState.IsValid) { return(BadRequest(ModelState)); } // Verify email address has valid structure string normalizedAddress; if (!EmailExtension.TryNormalizeEmail(userTaskResource.OwnerEmail, out normalizedAddress)) { return(BadRequest("Not a valid email address!")); } // Get users email address from token and verify that task owner email is the same var tokenOwnerEmail = User.FindFirst("Email").Value; if (!tokenOwnerEmail.Equals(normalizedAddress)) { return(Forbid()); } //Make sure that the task resource specifies a valid team if (userTaskResource.TeamId != null) { var team = await unitOfWork.UserTeamRepository.GetUserTeamAsync((int)userTaskResource.TeamId); if (team == null || team.IsDeleted) { return(NotFound("No such team")); } } // Map object from UserTaskResource into UserTask userTaskResource.OwnerEmail = normalizedAddress; var userTask = _mapper.Map <UserTask>(userTaskResource); // Save userTask to database await unitOfWork.UserTaskRepository.AddAsync(userTask); // Save changes so that the userTask.Id is loaded properly Task.WaitAll(unitOfWork.CompleteAsync()); await unitOfWork.TodoRepository.AddTodoAsync(userTask.Id); // Saves changes to database (Errors if `await` is used on this method) Task.WaitAll(unitOfWork.CompleteAsync()); // Retrieve userTask from database userTask = await unitOfWork.UserTaskRepository .GetTaskAsync(userTask.Id); // Return mapped resource return(Ok(mapToTaskResource(userTask))); }
public void TaskControllerAddTaskTest() { // In-memory database only exists while the connection is open var connection = new SqliteConnection("DataSource=:memory:"); connection.Open(); try { IUnitOfWork unitOfWork; TasksController controller; var options = new DbContextOptionsBuilder <SynchroLeanDbContext>() .UseSqlite(connection) .Options; // Create database schema var context = new SynchroLeanDbContext(options); context.Database.EnsureCreated(); // Bind the context to the UnitOfWork object unitOfWork = new UnitOfWork(context); // Create an instance of TasksController controller = new TasksController(unitOfWork, mapper); /// Create a newUserTask to send to HTTPPost method (without dates) var newUserTask = new UserTaskResource { Name = "SQLite unit test add", Description = "Add a task using SQLite database", Weekdays = 40, IsCompleted = false, IsDeleted = false }; // Add newUserTask to UserTasks table in Db asynchronously var taskResult = controller.AddUserTaskAsync(newUserTask); var actionResult = taskResult.Result; var okObjectResult = actionResult as OkObjectResult; var userTask = okObjectResult.Value as UserTaskResource; // Validate data equals UserTaskResource passed in // Not sure why userTask.Name needs to be trimmed but userTask.Description doesn't Assert.True(newUserTask.Name == userTask.Name.Trim()); Assert.True(newUserTask.Description == userTask.Description); Assert.True(newUserTask.Weekdays.Equals(userTask.Weekdays)); Assert.True(newUserTask.IsCompleted.Equals(userTask.IsCompleted)); Assert.True(newUserTask.IsDeleted.Equals(userTask.IsDeleted)); } finally { connection.Close(); } }
/// <summary> /// Map a task to a resource /// </summary> /// <param name="task">The task to be mapped</param> /// <returns>A UserTaskResource representing it</returns> protected UserTaskResource mapToTaskResource(UserTask task) { return(UserTaskResource.CreateWithMapper(_mapper, task)); }
public async Task <IActionResult> EditUserTaskAsync(int taskId, [FromBody] UserTaskResource userTaskResource) { // How does this validate against the UserTask model? if (!ModelState.IsValid) { return(BadRequest()); } // Verify email address has valid structure string normalizedAddress; if (!EmailExtension.TryNormalizeEmail(userTaskResource.OwnerEmail, out normalizedAddress)) { return(BadRequest("Not a valid email address!")); } // Get users email address from token var tokenOwnerEmail = User.FindFirst("Email").Value; if (!tokenOwnerEmail.Equals(normalizedAddress)) { return(Forbid()); } // Fetch an account from the DB asynchronously var account = await unitOfWork.UserAccountRepository .GetUserAccountAsync(tokenOwnerEmail); // Return not found exception if account doesn't exist if (account == null) { return(NotFound("Couldn't find account matching that ownerId.")); } // Retrieves task from UserTasks table var task = await unitOfWork.UserTaskRepository .GetTaskAsync(taskId); // Nothing was retrieved, no id match if (task == null || task.IsDeleted) { return(NotFound("Task couldn't be found.")); } // Validates task belongs to correct user if (task.OwnerEmail != account.Email) { return(BadRequest("Task does not belong to this account.")); } //Make sure that the task resource specifies a valid team if (userTaskResource.TeamId != null) { var team = await unitOfWork.UserTeamRepository.GetUserTeamAsync((int)userTaskResource.TeamId); if (team == null || (team.IsDeleted && (task.TeamId == null || userTaskResource.TeamId != task.TeamId))) { return(NotFound("No such team")); } } //Check if a todo for that task exists var todo = task.Todo; var todoExists = todo != null; //Complete the task if needed if (todoExists) { if (userTaskResource.IsCompleted && !todo.IsCompleted) { await unitOfWork.TodoRepository.CompleteTodoAsync(todo.TaskId); } else if (!userTaskResource.IsCompleted && todo.IsCompleted) { await unitOfWork.TodoRepository.UndoCompleteTodoAsync(todo.TaskId); } } //Delete the task if needed //Remove the todo if needed if (userTaskResource.IsDeleted) { await unitOfWork.TodoRepository.RemoveTodosAsync(taskId); } // Map resource to model task.Name = userTaskResource.Name; task.Description = userTaskResource.Description; task.Weekdays = userTaskResource.Weekdays; task.Frequency = userTaskResource.Frequency; //Don't change the email associated with the task task.TeamId = userTaskResource.TeamId; if (userTaskResource.IsDeleted) { task.Delete(); } //Refresh the todo list await unitOfWork.TodoRepository.RefreshTodo(taskId); // Save updated userTask to database await unitOfWork.CompleteAsync(); // Return mapped resource return(Ok(mapToTaskResource(task))); }
public async void GetUserMetricsTestAsync() { // In-memory database only exists while the connection is open var connection = new SqliteConnection("DataSource=:memory:"); connection.Open(); try { IUnitOfWork unitOfWork; TasksController taskController; AccountsController accountController; DateTime startDate; var options = new DbContextOptionsBuilder <SynchroLeanDbContext>() .UseSqlite(connection) .Options; // Create the schema in the database using (var context = new SynchroLeanDbContext(options)) { context.Database.EnsureCreated(); } // Create a newUserTask to send to HTTPPost method (without dates) var newUserTask1 = new UserTaskResource { Name = "User metrics", Description = "Modify metrics endpoints to accept DateTimes", Weekdays = 40, CreationDate = DateTime.Now, IsCompleted = false, IsDeleted = false, OwnerEmail = "*****@*****.**" }; // Create a newUserTask to send to HTTPPost method (without dates) var newUserTask2 = new UserTaskResource { Name = "User metrics", Description = "complete this to have 50% completion rate", Weekdays = 0, CreationDate = DateTime.Now, IsCompleted = false, IsDeleted = false, OwnerEmail = "*****@*****.**" }; var account = new UserAccountResource { FirstName = "Cole", LastName = "Phares", Email = "*****@*****.**", IsDeleted = false }; // Run the test against one instance of the context using (var context = new SynchroLeanDbContext(options)) { // Bind the context to the UnitOfWork object unitOfWork = new UnitOfWork(context); // Create an instance of TasksController taskController = new TasksController(unitOfWork, mapper); // Create an instance of AccountsController accountController = new AccountsController(unitOfWork, mapper); var newAccount = new CreateUserAccountResource { Email = account.Email, FirstName = account.FirstName, LastName = account.LastName, Password = "******", IsDeleted = false }; await accountController.AddUserAccountAsync(newAccount); // Add newUserTask to UserTasks table in Db asynchronously await taskController.AddUserTaskAsync(newUserTask1); await taskController.AddUserTaskAsync(newUserTask2); startDate = DateTime.Now; await taskController.EditUserTaskAsync(2, new UserTaskResource { Name = "User metrics", Description = "complete this to have 50% completion rate", Weekdays = 0, IsCompleted = true, IsDeleted = false, } ); } // Use a separate instance of the context to verify correct data was saved to database using (var context = new SynchroLeanDbContext(options)) { // Bind the Db context to the UnitOfWork object unitOfWork = new UnitOfWork(context); // Create new instance of task controller taskController = new TasksController(unitOfWork, mapper); DateTime endDate = DateTime.Now; // Retrieve the task from the Db asynchronously var completionRateResult = taskController.GetUserCompletionRate("*****@*****.**", startDate, endDate); var actionResult = completionRateResult.Result; var okObjectResult = actionResult as OkObjectResult; var completionRate = okObjectResult.Value as double?; Assert.True(completionRate.Equals(.5)); } } finally { connection.Close(); } }
public async void TaskControllerGetTaskTestAsync() { // In-memory database only exists while the connection is open var connection = new SqliteConnection("DataSource=:memory:"); connection.Open(); try { IUnitOfWork unitOfWork; TasksController controller; var options = new DbContextOptionsBuilder <SynchroLeanDbContext>() .UseSqlite(connection) .Options; // Create the schema in the database using (var context = new SynchroLeanDbContext(options)) { context.Database.EnsureCreated(); } /// Create a newUserTask to send to HTTPPost method (without dates) var newUserTask = new UserTaskResource { Name = "SQLite unit test add", Description = "Add a task using SQLite database", Weekdays = 40, IsCompleted = false, IsDeleted = false }; // Run the test against one instance of the context using (var context = new SynchroLeanDbContext(options)) { // Bind the context to the UnitOfWork object unitOfWork = new UnitOfWork(context); // Create an instance of TasksController controller = new TasksController(unitOfWork, mapper); // Add newUserTask to UserTasks table in Db asynchronously await controller.AddUserTaskAsync(newUserTask); } // Use a separate instance of the context to verify correct data was saved to database using (var context = new SynchroLeanDbContext(options)) { // Bind the Db context to the UnitOfWork object unitOfWork = new UnitOfWork(context); // Create new instance of task controller controller = new TasksController(unitOfWork, mapper); // Retrieve the task from the Db asynchronously var taskResult = controller.GetTaskAsync("*****@*****.**", newUserTask.Id); var actionResult = taskResult.Result; var okObjectResult = actionResult as OkObjectResult; var userTaskList = okObjectResult.Value as List <UserTaskResource>; // Assert that UserTasks table in Db contains 1 entry Assert.True(userTaskList.Count().Equals(1)); // Retreive the first element from the list UserTaskResource userTask = userTaskList[0]; // Validate data equals UserTaskResource passed in // Not sure why userTask.Name needs to be trimmed but userTask.Description doesn't Assert.True(newUserTask.Name == userTask.Name.Trim()); Assert.True(newUserTask.Description == userTask.Description); Assert.True(newUserTask.Weekdays.Equals(userTask.Weekdays)); Assert.True(newUserTask.IsCompleted.Equals(userTask.IsCompleted)); Assert.True(newUserTask.IsDeleted.Equals(userTask.IsDeleted)); } } finally { connection.Close(); } }