public async Task GetTodo_Existing_OkWithDto()
        {
            // Arrange
            var service = new MockTodoService
            {
                MGetTodoByIdAsync = (todoId, userId) => MockTodoDto.Get(0)
            };
            var controller = new TodoController(service);

            MockClaims.AddUserIdClaim(controller, MockApplicationUsers.Get(5).Id);
            const int tId = 10101;

            // Act
            var result = await controller.GetTodo(tId) as OkObjectResult;

            var dto = result?.Value as TodoDto;

            // Assert
            Assert.NotNull(result);
            Assert.Equal(200, result.StatusCode);
            Assert.NotNull(dto);
            Assert.Equal(MockTodoDto.Get(0).Id, dto.Id);
            Assert.Equal(MockTodoDto.Get(0).Due, dto.Due);
            Assert.Equal(MockTodoDto.Get(0).Description, dto.Description);
        }
        public async Task GetAllTodos_ListOfTodos_Ok()
        {
            // Arrange
            var service = new MockTodoService
            {
                MGetAllTodosOrderedByDueAsync = (year, month, day, userId) => new[]
                {
                    MockTodoDto.Get(0),
                    MockTodoDto.Get(1)
                }
            };
            var controller = new TodoController(service);

            MockClaims.AddUserIdClaim(controller, MockApplicationUsers.Get(5).Id);

            // Act
            var result = await controller.GetAllTodos() as OkObjectResult;

            var list = result?.Value as TodoDto[];

            // Assert
            Assert.NotNull(result);
            Assert.Equal(200, result.StatusCode);
            Assert.NotNull(list);
            Assert.Equal(2, list.Count());
            Assert.Equal(MockTodoDto.Get(0).Id, list[0].Id);
            Assert.Equal(MockTodoDto.Get(0).Due, list[0].Due);
            Assert.Equal(MockTodoDto.Get(0).Description, list[0].Description);
            Assert.Equal(MockTodoDto.Get(1).Id, list[1].Id);
            Assert.Equal(MockTodoDto.Get(1).Due, list[1].Due);
            Assert.Equal(MockTodoDto.Get(1).Description, list[1].Description);
        }
        public async Task EditTodo_NullModel_BadRequest()
        {
            // Arrange
            var service    = new MockTodoService();
            var controller = new TodoController(service);

            // Act
            var result = await controller.EditTodo(null) as BadRequestResult;

            // Assert
            Assert.NotNull(result);
            Assert.Equal(400, result.StatusCode);
        }
        public async Task EditTodo_ValidUserAndTodo_Ok()
        {
            // Arrange
            var service = new MockTodoService
            {
                MEditTodoAsync = (model, userId) => { }
            };
            var controller = new TodoController(service);

            MockClaims.AddUserIdClaim(controller, MockApplicationUsers.Get(0).Id);

            // Act
            var result = await controller.EditTodo(MockEditTodoViewModel.Get(0)) as OkResult;

            // Assert
            Assert.NotNull(result);
            Assert.Equal(200, result.StatusCode);
        }
        public async Task RemoveTodo_ValidTodo_NoContent()
        {
            // Arrange
            var tId     = 15;
            var service = new MockTodoService
            {
                MRemoveTodoByIdAsync = (todoId, userId) => { }
            };
            var controller = new TodoController(service);

            MockClaims.AddUserIdClaim(controller, MockApplicationUsers.Get(0).Id);

            // Act
            var result = await controller.RemoveTodo(tId) as NoContentResult;

            // Assert
            Assert.NotNull(result);
            Assert.Equal(204, result.StatusCode);
        }
        public async Task EditTodo_InvalidModel_BadRequest()
        {
            // Arrange
            const string field        = "required";
            const string errorMessage = "something is required";
            var          service      = new MockTodoService();
            var          controller   = new TodoController(service);

            controller.ModelState.AddModelError(field, errorMessage);
            var model = MockEditTodoViewModel.Get(0);

            // Act
            var result = await controller.EditTodo(model) as BadRequestObjectResult;

            var error = result?.Value as SerializableError;

            // Assert
            Assert.NotNull(error);
            Assert.Equal(400, result.StatusCode);
            Assert.Single(error.Keys);
            Assert.True(error.ContainsKey(field));
            Assert.Equal(new[] { errorMessage }, error.GetValueOrDefault(field));
        }
        public async Task CreateTodo_ValidUserAndTodo_CreatedAtRoute()
        {
            // Arrange
            var id      = 15;
            var service = new MockTodoService
            {
                MCreateTodoAsync = (model, userId) => id
            };
            var controller = new TodoController(service);

            MockClaims.AddUserIdClaim(controller, MockApplicationUsers.Get(0).Id);

            // Act
            var result = await controller.CreateTodo(MockCreateTodoViewModel.Get(0)) as CreatedAtRouteResult;

            // Assert
            Assert.NotNull(result);
            Assert.Equal(201, result.StatusCode);
            Assert.Equal(MethodNames.GetSingleTodoMethodName, result.RouteName);
            Assert.Single(result.RouteValues.Keys);
            Assert.True(result.RouteValues.ContainsKey("todoId"));
            Assert.Equal(id, result.RouteValues.GetValueOrDefault("todoId"));
        }