From 3d4a687caf663b850ad774b42492ac4a9805b379 Mon Sep 17 00:00:00 2001 From: danison Date: Mon, 29 Apr 2024 17:48:50 -0300 Subject: [PATCH 01/22] chore: add database config --- docker-compose.yml | 12 ++++++++++++ pom.xml | 11 +++++++++++ resources/conf/application.yml | 7 +++++++ script.sql | 11 +++++++++++ 4 files changed, 41 insertions(+) create mode 100644 docker-compose.yml create mode 100644 script.sql diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5b490f3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3.1' + +services: + tasks_db: + image: mysql:8.0 + environment: + MYSQL_ROOT_PASSWORD: "mysql" + MYSQL_DATABASE: "tasks_db" + ports: + - "3306:3306" + volumes: + - ./script.sql:/docker-entrypoint-initdb.d/init.sql diff --git a/pom.xml b/pom.xml index 53ab393..c45808d 100644 --- a/pom.xml +++ b/pom.xml @@ -78,6 +78,17 @@ javax.annotation-api 1.3.2 + + + + io.skullabs.kikaha + kikaha-db + + + mysql + mysql-connector-java + 8.0.33 + diff --git a/resources/conf/application.yml b/resources/conf/application.yml index 2de980e..26ecb2b 100644 --- a/resources/conf/application.yml +++ b/resources/conf/application.yml @@ -23,3 +23,10 @@ server: health-check: enabled: true url: "/api/internal/health-check" + + db: + datasources: + default: + jdbc-url: "jdbc:mysql://localhost:3306/tasks_db" + username: "root" + password: "mysql" diff --git a/script.sql b/script.sql new file mode 100644 index 0000000..53866a4 --- /dev/null +++ b/script.sql @@ -0,0 +1,11 @@ +USE tasks_db; + +CREATE TABLE IF NOT EXISTS tasks ( + id CHAR(36) NOT NULL DEFAULT (UUID()), + title VARCHAR(255) NOT NULL, + description TEXT NOT NULL, + progress INT NOT NULL DEFAULT 0, + status ENUM('PROGRESS', 'COMPLETE') NOT NULL DEFAULT 'PROGRESS', + createdAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id) +); From f692437a2d8e512c65cb04abef24f11d7317eb52 Mon Sep 17 00:00:00 2001 From: danison Date: Mon, 29 Apr 2024 18:03:07 -0300 Subject: [PATCH 02/22] feat: save new task --- .../challenge/modules/task/dtos/TaskDTO.java | 2 -- .../http/controllers/TaskController.java | 7 +++-- .../challenge/modules/task/models/Task.java | 5 ++-- .../task/repositories/TaskRepository.java | 30 ++++++++++++++++++- .../task/services/CreateTaskService.java | 2 +- tests/Runner.java | 2 +- 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/source/backend/challenge/modules/task/dtos/TaskDTO.java b/source/backend/challenge/modules/task/dtos/TaskDTO.java index d73cf02..45379c7 100644 --- a/source/backend/challenge/modules/task/dtos/TaskDTO.java +++ b/source/backend/challenge/modules/task/dtos/TaskDTO.java @@ -6,8 +6,6 @@ import lombok.Setter; import lombok.experimental.Accessors; -import java.util.Date; - @Getter @Setter @Accessors(chain = true) diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java index 6a06a52..918cfc3 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java @@ -1,5 +1,6 @@ package backend.challenge.modules.task.infra.http.controllers; +import backend.challenge.modules.task.dtos.TaskDTO; import backend.challenge.modules.task.infra.http.views.TaskView; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.services.*; @@ -47,8 +48,10 @@ public Response index(@PathParam("taskId") Long taskId) { } @POST - public Response create(TaskView task) { - // TODO: A rota deve receber title e description, sendo o `title` o título da tarefa e `description` uma descrição da tarefa. + public Response create(TaskView taskView) { + + TaskDTO taskDto = TaskDTO.create().setTitle(taskView.getTitle()).setDescription(taskView.getDescription()); + this.createTaskService.execute(taskDto); return DefaultResponse.ok().entity("Hello world"); } diff --git a/source/backend/challenge/modules/task/models/Task.java b/source/backend/challenge/modules/task/models/Task.java index 123f10c..ce1b971 100644 --- a/source/backend/challenge/modules/task/models/Task.java +++ b/source/backend/challenge/modules/task/models/Task.java @@ -6,8 +6,7 @@ import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.experimental.Accessors; - -import java.util.Date; +import java.time.LocalDateTime; @Getter @Setter @@ -18,6 +17,6 @@ public class Task { private String description; private int progress; private TaskStatus status; - private Date createdAt; + private LocalDateTime createdAt; } diff --git a/source/backend/challenge/modules/task/repositories/TaskRepository.java b/source/backend/challenge/modules/task/repositories/TaskRepository.java index c47c8fd..3b555de 100644 --- a/source/backend/challenge/modules/task/repositories/TaskRepository.java +++ b/source/backend/challenge/modules/task/repositories/TaskRepository.java @@ -2,13 +2,29 @@ import backend.challenge.modules.task.dtos.TaskDTO; import backend.challenge.modules.task.models.Task; +import lombok.NoArgsConstructor; +import javax.inject.Inject; import javax.inject.Singleton; +import javax.sql.DataSource; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; import java.util.List; +import java.util.UUID; @Singleton public class TaskRepository implements ITaskRepository { + @Inject + private DataSource db; + + @Override public Task index(final Long taskId) { // TODO: Criar método responsável por retornar tarefa por id @@ -26,7 +42,19 @@ public List show() { @Override public Task create(final TaskDTO taskDTO) { // TODO: Criar método responsável por criar uma tarefa + try (Connection connection = this.db.getConnection()) { + String sql = "INSERT INTO tasks(id, title, description, createdAt) VALUES(?, ?, ?, ?)"; + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.setString(1, UUID.randomUUID().toString()); + preparedStatement.setString(2, taskDTO.getTitle()); + preparedStatement.setString(3, taskDTO.getDescription()); + preparedStatement.setTimestamp(4, Timestamp.valueOf(LocalDateTime.now())); + preparedStatement.executeUpdate(); + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } return null; } @@ -39,7 +67,7 @@ public Task update(final Task task) { @Override public void delete(final Long taskId) { - // TODO: Criar método responsável por deletar tarefa por id + // TODO: Criar método responsável por deletar tarefa por id } diff --git a/source/backend/challenge/modules/task/services/CreateTaskService.java b/source/backend/challenge/modules/task/services/CreateTaskService.java index 46b144b..359b997 100644 --- a/source/backend/challenge/modules/task/services/CreateTaskService.java +++ b/source/backend/challenge/modules/task/services/CreateTaskService.java @@ -20,7 +20,7 @@ public CreateTaskService(final ITaskRepository taskRepository) { @Override public Task execute(TaskDTO taskDTO) { // TODO: Criar serviço responsável por criar uma tarefa - + taskRepository.create(taskDTO); return null; } diff --git a/tests/Runner.java b/tests/Runner.java index 1ff4b19..eb2a736 100644 --- a/tests/Runner.java +++ b/tests/Runner.java @@ -1,4 +1,4 @@ -package backend.challenge; +// package backend.challenge; import kikaha.core.test.KikahaServerRunner; import org.junit.Ignore; From 2c5d6b8b4b4636ab56d31bb54f5de5813d9c1cc9 Mon Sep 17 00:00:00 2001 From: danison Date: Mon, 29 Apr 2024 18:35:40 -0300 Subject: [PATCH 03/22] refact: add return into save task repository --- .../task/repositories/TaskRepository.java | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/source/backend/challenge/modules/task/repositories/TaskRepository.java b/source/backend/challenge/modules/task/repositories/TaskRepository.java index 3b555de..0ce5249 100644 --- a/source/backend/challenge/modules/task/repositories/TaskRepository.java +++ b/source/backend/challenge/modules/task/repositories/TaskRepository.java @@ -1,6 +1,7 @@ package backend.challenge.modules.task.repositories; import backend.challenge.modules.task.dtos.TaskDTO; +import backend.challenge.modules.task.enums.TaskStatus; import backend.challenge.modules.task.models.Task; import lombok.NoArgsConstructor; @@ -10,12 +11,14 @@ import java.sql.Connection; import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Date; import java.util.List; +import java.util.Optional; import java.util.UUID; @Singleton @@ -24,11 +27,10 @@ public class TaskRepository implements ITaskRepository { @Inject private DataSource db; - @Override - public Task index(final Long taskId) { + public Optional index(final UUID taskId) { // TODO: Criar método responsável por retornar tarefa por id - + return null; } @@ -45,17 +47,28 @@ public Task create(final TaskDTO taskDTO) { try (Connection connection = this.db.getConnection()) { String sql = "INSERT INTO tasks(id, title, description, createdAt) VALUES(?, ?, ?, ?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setString(1, UUID.randomUUID().toString()); - preparedStatement.setString(2, taskDTO.getTitle()); - preparedStatement.setString(3, taskDTO.getDescription()); - preparedStatement.setTimestamp(4, Timestamp.valueOf(LocalDateTime.now())); + Task newTask = new Task( + UUID.randomUUID(), + taskDTO.getTitle(), + taskDTO.getDescription(), + 0, + TaskStatus.PROGRESS, + LocalDateTime.now() + + ); + + preparedStatement.setString(1, newTask.getId().toString()); + preparedStatement.setString(2, newTask.getTitle()); + preparedStatement.setString(3, newTask.getDescription()); + preparedStatement.setTimestamp(4, Timestamp.valueOf(newTask.getCreatedAt())); preparedStatement.executeUpdate(); + return newTask; + } catch (SQLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + throw new RuntimeException(e); } - return null; + } @Override From f7ab4c2f1adfaf7b1e4d7bf83339df848eacf5cd Mon Sep 17 00:00:00 2001 From: danison Date: Mon, 29 Apr 2024 18:37:23 -0300 Subject: [PATCH 04/22] refact: add return into save task service --- .../challenge/modules/task/services/CreateTaskService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/backend/challenge/modules/task/services/CreateTaskService.java b/source/backend/challenge/modules/task/services/CreateTaskService.java index 359b997..f23d9ab 100644 --- a/source/backend/challenge/modules/task/services/CreateTaskService.java +++ b/source/backend/challenge/modules/task/services/CreateTaskService.java @@ -20,8 +20,7 @@ public CreateTaskService(final ITaskRepository taskRepository) { @Override public Task execute(TaskDTO taskDTO) { // TODO: Criar serviço responsável por criar uma tarefa - taskRepository.create(taskDTO); - return null; + return taskRepository.create(taskDTO); } } From d1bbee32c631a5a3b2786a3afa2cbd817dacbe42 Mon Sep 17 00:00:00 2001 From: danison Date: Mon, 29 Apr 2024 19:44:36 -0300 Subject: [PATCH 05/22] feat: find task by id --- .../http/controllers/TaskController.java | 35 ++++++++------ .../challenge/modules/task/models/Task.java | 6 ++- .../task/repositories/ITaskRepository.java | 4 +- .../task/repositories/TaskRepository.java | 46 +++++++++++++------ .../services/IRetrieveTaskByIdService.java | 5 +- .../services/RetrieveTaskByIdService.java | 28 +++++++++++ .../task/services/CreateTaskServiceTest.java | 2 +- 7 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java index 918cfc3..10d3d11 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java @@ -5,7 +5,8 @@ import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.services.*; import kikaha.urouting.api.*; - +import java.util.Optional; +import java.util.UUID; import javax.inject.Inject; import javax.inject.Singleton; @@ -21,30 +22,33 @@ public class TaskController { @Inject public TaskController( - final ICreateTaskService createTaskService, - final IDeleteTaskService deleteTaskService, - final IRetrieveAllTasksService retrieveAllTasksService - ) { + final ICreateTaskService createTaskService, + final IDeleteTaskService deleteTaskService, + final IRetrieveAllTasksService retrieveAllTasksService, + final RetrieveTaskByIdService retrieveTaskByIdService) { this.createTaskService = createTaskService; this.deleteTaskService = deleteTaskService; this.retrieveAllTasksService = retrieveAllTasksService; - this.retrieveTaskByIdService = null; + this.retrieveTaskByIdService = retrieveTaskByIdService; this.updateTaskService = null; } @GET public Response show() { - // TODO: Rota que lista todas as tarefas - return DefaultResponse.ok().entity("Hello world"); + this.retrieveAllTasksService.execute(); + + return DefaultResponse.ok().entity(retrieveAllTasksService.execute()); } @GET @Path("single/{taskId}") - public Response index(@PathParam("taskId") Long taskId) { - // TODO: A rota deve retornar somente a tarefa a qual o id corresponder + public Response index(@PathParam("taskId") String taskId) { - return DefaultResponse.ok().entity("Hello world"); + Optional taskOpt = this.retrieveTaskByIdService.execute(UUID.fromString(taskId)); + if (taskOpt.isEmpty()) + return DefaultResponse.badRequest(); + return DefaultResponse.ok().entity(taskOpt.get()); } @POST @@ -53,15 +57,15 @@ public Response create(TaskView taskView) { TaskDTO taskDto = TaskDTO.create().setTitle(taskView.getTitle()).setDescription(taskView.getDescription()); this.createTaskService.execute(taskDto); - return DefaultResponse.ok().entity("Hello world"); + return DefaultResponse.created(); } @PUT @Path("single/{taskId}") public Response update(@PathParam("taskId") Long taskId, Task task) { /* - TODO: A rota deve alterar apenas o title e description da tarefa - que possua o id igual ao id correspondente nos parâmetros da rota. + * TODO: A rota deve alterar apenas o title e description da tarefa + * que possua o id igual ao id correspondente nos parâmetros da rota. */ return DefaultResponse.ok().entity("Hello world"); @@ -70,7 +74,8 @@ public Response update(@PathParam("taskId") Long taskId, Task task) { @DELETE @Path("single/{taskId}") public Response delete(@PathParam("taskId") Long taskId) { - // TODO: A rota deve deletar a tarefa com o id correspondente nos parâmetros da rota + // TODO: A rota deve deletar a tarefa com o id correspondente nos parâmetros da + // rota return DefaultResponse.ok().entity("Hello world"); } diff --git a/source/backend/challenge/modules/task/models/Task.java b/source/backend/challenge/modules/task/models/Task.java index ce1b971..3941274 100644 --- a/source/backend/challenge/modules/task/models/Task.java +++ b/source/backend/challenge/modules/task/models/Task.java @@ -1,18 +1,22 @@ package backend.challenge.modules.task.models; import backend.challenge.modules.task.enums.TaskStatus; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.experimental.Accessors; import java.time.LocalDateTime; +import java.util.UUID; @Getter @Setter +@AllArgsConstructor +@NoArgsConstructor public class Task { - private Long id; + private UUID id; private String title; private String description; private int progress; diff --git a/source/backend/challenge/modules/task/repositories/ITaskRepository.java b/source/backend/challenge/modules/task/repositories/ITaskRepository.java index 527450a..0192c10 100644 --- a/source/backend/challenge/modules/task/repositories/ITaskRepository.java +++ b/source/backend/challenge/modules/task/repositories/ITaskRepository.java @@ -4,10 +4,12 @@ import backend.challenge.modules.task.models.Task; import java.util.List; +import java.util.Optional; +import java.util.UUID; public interface ITaskRepository { - Task index(Long taskId); + Optional index(UUID taskId); List show(); Task create(TaskDTO taskDTO); Task update(Task task); diff --git a/source/backend/challenge/modules/task/repositories/TaskRepository.java b/source/backend/challenge/modules/task/repositories/TaskRepository.java index 0ce5249..830fef1 100644 --- a/source/backend/challenge/modules/task/repositories/TaskRepository.java +++ b/source/backend/challenge/modules/task/repositories/TaskRepository.java @@ -30,8 +30,27 @@ public class TaskRepository implements ITaskRepository { @Override public Optional index(final UUID taskId) { // TODO: Criar método responsável por retornar tarefa por id - - return null; + try (Connection connection = this.db.getConnection()) { + String sql = "SELECT id, title, description, createdAt FROM tasks WHERE id = ?"; + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.setString(1, taskId.toString()); + + ResultSet resultSet = preparedStatement.executeQuery(); + Task task = null; + if(resultSet.next()){ + task = new Task(); + task.setId(UUID.fromString(resultSet.getString("id"))); + task.setTitle(resultSet.getString("title")); + task.setDescription(resultSet.getString("description")); + task.setCreatedAt(resultSet.getTimestamp("createdAt").toLocalDateTime()); + return Optional.of(task); + } + return Optional.empty(); + + } catch (SQLException e) { + // TODO Auto-generated catch block + throw new RuntimeException(e); + } } @Override @@ -47,28 +66,29 @@ public Task create(final TaskDTO taskDTO) { try (Connection connection = this.db.getConnection()) { String sql = "INSERT INTO tasks(id, title, description, createdAt) VALUES(?, ?, ?, ?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); - Task newTask = new Task( - UUID.randomUUID(), - taskDTO.getTitle(), - taskDTO.getDescription(), - 0, - TaskStatus.PROGRESS, - LocalDateTime.now() + Task newTask = new Task( + UUID.randomUUID(), + taskDTO.getTitle(), + taskDTO.getDescription(), + 0, + TaskStatus.PROGRESS, + LocalDateTime.now() ); - + preparedStatement.setString(1, newTask.getId().toString()); preparedStatement.setString(2, newTask.getTitle()); preparedStatement.setString(3, newTask.getDescription()); - preparedStatement.setTimestamp(4, Timestamp.valueOf(newTask.getCreatedAt())); + preparedStatement.setTimestamp(4, Timestamp.valueOf(newTask.getCreatedAt())); preparedStatement.executeUpdate(); - + return newTask; - + } catch (SQLException e) { throw new RuntimeException(e); } + } @Override diff --git a/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java b/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java index 192e28c..390a9f0 100644 --- a/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java +++ b/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java @@ -1,9 +1,12 @@ package backend.challenge.modules.task.services; +import java.util.Optional; +import java.util.UUID; + import backend.challenge.modules.task.models.Task; public interface IRetrieveTaskByIdService { - Task execute(Long taskId); + Optional execute(UUID taskId); } diff --git a/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java b/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java new file mode 100644 index 0000000..66bdb37 --- /dev/null +++ b/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java @@ -0,0 +1,28 @@ +package backend.challenge.modules.task.services; + +import java.util.Optional; +import java.util.UUID; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.swing.plaf.OptionPaneUI; + +import backend.challenge.modules.task.models.Task; +import backend.challenge.modules.task.repositories.ITaskRepository; +@Singleton +public class RetrieveTaskByIdService implements IRetrieveTaskByIdService { + + private final ITaskRepository taskRepository; + + @Inject + public RetrieveTaskByIdService(final ITaskRepository taskRepository) { + this.taskRepository = taskRepository; + } + + @Override + public Optional execute(UUID taskId) { + return this.taskRepository.index(taskId); + } + + +} \ No newline at end of file diff --git a/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java b/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java index 684dc44..3f2fd06 100644 --- a/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java +++ b/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java @@ -16,7 +16,7 @@ public class CreateTaskServiceTest { @Before public void init() { final ITaskRepository taskRepository = new TaskRepository(); - + createTaskService = new CreateTaskService(taskRepository); } From 3a74529bb6c417889797cf085f733a2f7603fe69 Mon Sep 17 00:00:00 2001 From: danison Date: Mon, 29 Apr 2024 22:11:03 -0300 Subject: [PATCH 06/22] feat: delete task --- .../task/repositories/ITaskRepository.java | 3 +- .../task/repositories/TaskRepository.java | 111 +++++++++++++----- .../task/services/DeleteTaskService.java | 8 +- .../task/services/IDeleteTaskService.java | 3 +- 4 files changed, 93 insertions(+), 32 deletions(-) diff --git a/source/backend/challenge/modules/task/repositories/ITaskRepository.java b/source/backend/challenge/modules/task/repositories/ITaskRepository.java index 0192c10..4be5c0c 100644 --- a/source/backend/challenge/modules/task/repositories/ITaskRepository.java +++ b/source/backend/challenge/modules/task/repositories/ITaskRepository.java @@ -13,6 +13,7 @@ public interface ITaskRepository { List show(); Task create(TaskDTO taskDTO); Task update(Task task); - void delete(Long taskId); + void delete(UUID taskId); + boolean existsById(UUID id); } diff --git a/source/backend/challenge/modules/task/repositories/TaskRepository.java b/source/backend/challenge/modules/task/repositories/TaskRepository.java index 830fef1..d74525a 100644 --- a/source/backend/challenge/modules/task/repositories/TaskRepository.java +++ b/source/backend/challenge/modules/task/repositories/TaskRepository.java @@ -16,6 +16,7 @@ import java.sql.Timestamp; import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Optional; @@ -29,78 +30,132 @@ public class TaskRepository implements ITaskRepository { @Override public Optional index(final UUID taskId) { - // TODO: Criar método responsável por retornar tarefa por id try (Connection connection = this.db.getConnection()) { - String sql = "SELECT id, title, description, createdAt FROM tasks WHERE id = ?"; + String sql = "SELECT id, title, description, createdAt FROM tasks WHERE id = ?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, taskId.toString()); - + ResultSet resultSet = preparedStatement.executeQuery(); Task task = null; - if(resultSet.next()){ + if (resultSet.next()) { task = new Task(); task.setId(UUID.fromString(resultSet.getString("id"))); - task.setTitle(resultSet.getString("title")); - task.setDescription(resultSet.getString("description")); - task.setCreatedAt(resultSet.getTimestamp("createdAt").toLocalDateTime()); + task.setTitle(resultSet.getString("title")); + task.setDescription(resultSet.getString("description")); + task.setCreatedAt(resultSet.getTimestamp("createdAt").toLocalDateTime()); return Optional.of(task); } return Optional.empty(); - + } catch (SQLException e) { - // TODO Auto-generated catch block throw new RuntimeException(e); } } @Override public List show() { - // TODO: Criar método responsável por retornar todas as tarefas + try (Connection connection = this.db.getConnection()) { + String sql = "SELECT id, title, description, createdAt FROM tasks"; + PreparedStatement preparedStatement = connection.prepareStatement(sql); + ResultSet resultSet = preparedStatement.executeQuery(); + List tasks = new ArrayList<>(); + while (resultSet.next()) { + Task task = new Task(); + task.setId(UUID.fromString(resultSet.getString("id"))); + task.setTitle(resultSet.getString("title")); + task.setDescription(resultSet.getString("description")); + task.setCreatedAt(resultSet.getTimestamp("createdAt").toLocalDateTime()); + tasks.add(task); + } + return tasks; - return null; + } catch (SQLException e) { + throw new RuntimeException(e); + } } @Override public Task create(final TaskDTO taskDTO) { - // TODO: Criar método responsável por criar uma tarefa try (Connection connection = this.db.getConnection()) { String sql = "INSERT INTO tasks(id, title, description, createdAt) VALUES(?, ?, ?, ?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); - Task newTask = new Task( - UUID.randomUUID(), - taskDTO.getTitle(), - taskDTO.getDescription(), - 0, - TaskStatus.PROGRESS, - LocalDateTime.now() + Task newTask = new Task( + UUID.randomUUID(), + taskDTO.getTitle(), + taskDTO.getDescription(), + 0, + TaskStatus.PROGRESS, + LocalDateTime.now() ); - + preparedStatement.setString(1, newTask.getId().toString()); preparedStatement.setString(2, newTask.getTitle()); preparedStatement.setString(3, newTask.getDescription()); - preparedStatement.setTimestamp(4, Timestamp.valueOf(newTask.getCreatedAt())); + preparedStatement.setTimestamp(4, Timestamp.valueOf(newTask.getCreatedAt())); preparedStatement.executeUpdate(); - + return newTask; - + } catch (SQLException e) { throw new RuntimeException(e); } - } @Override public Task update(final Task task) { - // TODO: Criar método responsável por atualizar uma tarefa - return null; + try (Connection connection = this.db.getConnection()) { + String sql = "UPDATE tasks SET title = ?, description = ? WHERE id = ?"; + PreparedStatement preparedStatement = connection.prepareStatement(sql); + + preparedStatement.setString(1, task.getTitle()); + preparedStatement.setString(2, task.getDescription()); + preparedStatement.setString(3, task.getId().toString()); + preparedStatement.executeUpdate(); + + return task; + + } catch (SQLException e) { + throw new RuntimeException(e); + } } @Override - public void delete(final Long taskId) { - // TODO: Criar método responsável por deletar tarefa por id + public void delete(final UUID taskId) { + + try (Connection connection = this.db.getConnection()) { + String sql = "DELETE FROM tasks WHERE id=?"; + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.setString(1, taskId.toString()); + preparedStatement.executeUpdate(); + + } catch (SQLException e) { + throw new RuntimeException(e); + } + + } + + @Override + public boolean existsById(UUID id) { + try (Connection connection = this.db.getConnection()) { + String sql = "SELECT COUNT(*) FROM tasks WHERE id = ?"; + + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.setString(1, id.toString()); + ResultSet resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + int count = resultSet.getInt(1); + resultSet.close(); + System.out.println(count > 0); + return count > 0; + } + return false; + + } catch (SQLException e) { + throw new RuntimeException(e); + } } diff --git a/source/backend/challenge/modules/task/services/DeleteTaskService.java b/source/backend/challenge/modules/task/services/DeleteTaskService.java index c957d70..e124c3c 100644 --- a/source/backend/challenge/modules/task/services/DeleteTaskService.java +++ b/source/backend/challenge/modules/task/services/DeleteTaskService.java @@ -2,6 +2,7 @@ import backend.challenge.modules.task.repositories.ITaskRepository; +import java.util.UUID; import javax.inject.Inject; import javax.inject.Singleton; @@ -16,8 +17,11 @@ public DeleteTaskService(final ITaskRepository taskRepository) { } @Override - public void execute(Long taskId) { - // TODO: Criar serviço responsável por deletar a tarefa + public void execute(UUID taskId) { + + if(taskRepository.existsById(taskId)) return; + + this.taskRepository.delete(taskId); } } diff --git a/source/backend/challenge/modules/task/services/IDeleteTaskService.java b/source/backend/challenge/modules/task/services/IDeleteTaskService.java index 6b031ac..421beec 100644 --- a/source/backend/challenge/modules/task/services/IDeleteTaskService.java +++ b/source/backend/challenge/modules/task/services/IDeleteTaskService.java @@ -1,8 +1,9 @@ package backend.challenge.modules.task.services; +import java.util.UUID; public interface IDeleteTaskService { - void execute(Long taskId); + void execute(UUID taskId); } From 8325eb90ad13029be137a9decb0695b4fc8b70e2 Mon Sep 17 00:00:00 2001 From: danison Date: Mon, 29 Apr 2024 22:11:26 -0300 Subject: [PATCH 07/22] feat: get all tasks --- .../http/controllers/TaskController.java | 22 ++++++++----------- .../services/RetrieveAllTasksService.java | 3 +-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java index 10d3d11..e2c65dd 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java @@ -25,19 +25,18 @@ public TaskController( final ICreateTaskService createTaskService, final IDeleteTaskService deleteTaskService, final IRetrieveAllTasksService retrieveAllTasksService, - final RetrieveTaskByIdService retrieveTaskByIdService) { + final IRetrieveTaskByIdService retrieveTaskByIdService, + final IUpdateTaskService iUpdateTaskService) { this.createTaskService = createTaskService; this.deleteTaskService = deleteTaskService; this.retrieveAllTasksService = retrieveAllTasksService; this.retrieveTaskByIdService = retrieveTaskByIdService; - this.updateTaskService = null; + this.updateTaskService = iUpdateTaskService; } @GET public Response show() { - this.retrieveAllTasksService.execute(); - return DefaultResponse.ok().entity(retrieveAllTasksService.execute()); } @@ -62,22 +61,19 @@ public Response create(TaskView taskView) { @PUT @Path("single/{taskId}") - public Response update(@PathParam("taskId") Long taskId, Task task) { - /* - * TODO: A rota deve alterar apenas o title e description da tarefa - * que possua o id igual ao id correspondente nos parâmetros da rota. - */ + public Response update(@PathParam("taskId") String taskId, Task task) { + + this.updateTaskService.execute(task); return DefaultResponse.ok().entity("Hello world"); } @DELETE @Path("single/{taskId}") - public Response delete(@PathParam("taskId") Long taskId) { - // TODO: A rota deve deletar a tarefa com o id correspondente nos parâmetros da - // rota + public Response delete(@PathParam("taskId") String taskId) { - return DefaultResponse.ok().entity("Hello world"); + this.deleteTaskService.execute(UUID.fromString(taskId)); + return DefaultResponse.ok(); } } diff --git a/source/backend/challenge/modules/task/services/RetrieveAllTasksService.java b/source/backend/challenge/modules/task/services/RetrieveAllTasksService.java index 52a4149..af0ef15 100644 --- a/source/backend/challenge/modules/task/services/RetrieveAllTasksService.java +++ b/source/backend/challenge/modules/task/services/RetrieveAllTasksService.java @@ -19,9 +19,8 @@ public RetrieveAllTasksService(final ITaskRepository taskRepository) { @Override public List execute() { - // TODO: Criar serviço responsável por recuperar todas as tarefas - return null; + return taskRepository.show(); } } From 881a13ba4bfe5fccc23bd665f278c835bf901497 Mon Sep 17 00:00:00 2001 From: danison Date: Mon, 29 Apr 2024 22:11:44 -0300 Subject: [PATCH 08/22] feat: update task --- .../task/services/UpdateTaskService.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 source/backend/challenge/modules/task/services/UpdateTaskService.java diff --git a/source/backend/challenge/modules/task/services/UpdateTaskService.java b/source/backend/challenge/modules/task/services/UpdateTaskService.java new file mode 100644 index 0000000..2c53dd0 --- /dev/null +++ b/source/backend/challenge/modules/task/services/UpdateTaskService.java @@ -0,0 +1,25 @@ +package backend.challenge.modules.task.services; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import backend.challenge.modules.task.models.Task; +import backend.challenge.modules.task.repositories.ITaskRepository; + +@Singleton +public class UpdateTaskService implements IUpdateTaskService { + + private final ITaskRepository iTaskRepository; + + @Inject + public UpdateTaskService(final ITaskRepository iTaskRepository) { + this.iTaskRepository = iTaskRepository; + } + + @Override + public Task execute(Task task) { + + return this.iTaskRepository.update(task); + } + +} From 4d5df8dd3e69928f5a612ec54470906e540edcca Mon Sep 17 00:00:00 2001 From: danison Date: Mon, 29 Apr 2024 23:13:46 -0300 Subject: [PATCH 09/22] feat: update progress --- .../modules/task/dtos/TaskProgressDTO.java | 4 +- .../controllers/TaskProgressController.java | 17 +++---- .../infra/http/views/TaskProgressView.java | 1 + .../task/infra/http/views/TaskView.java | 1 - .../challenge/modules/task/models/Task.java | 2 + .../task/repositories/TaskRepository.java | 22 ++++++--- .../services/UpdateTaskProgressService.java | 46 +++++++++++++++++++ .../task/services/UpdateTaskService.java | 18 +++++++- 8 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 source/backend/challenge/modules/task/services/UpdateTaskProgressService.java diff --git a/source/backend/challenge/modules/task/dtos/TaskProgressDTO.java b/source/backend/challenge/modules/task/dtos/TaskProgressDTO.java index ee6277f..11b53df 100644 --- a/source/backend/challenge/modules/task/dtos/TaskProgressDTO.java +++ b/source/backend/challenge/modules/task/dtos/TaskProgressDTO.java @@ -1,5 +1,7 @@ package backend.challenge.modules.task.dtos; +import java.util.UUID; + import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -11,7 +13,7 @@ @NoArgsConstructor(staticName = "create") public class TaskProgressDTO { - private Long id; + private UUID id; private int progress; } diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java index 4a25520..b2a3061 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java @@ -1,10 +1,10 @@ package backend.challenge.modules.task.infra.http.controllers; +import backend.challenge.modules.task.dtos.TaskProgressDTO; import backend.challenge.modules.task.infra.http.views.TaskProgressView; -import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.services.*; import kikaha.urouting.api.*; - +import java.util.UUID; import javax.inject.Inject; import javax.inject.Singleton; @@ -21,15 +21,12 @@ public TaskProgressController(final IUpdateTaskProgressService updateTaskProgres @PUT @Path("single/{taskId}") - public Response updateProgress(@PathParam("taskId") Long taskId, TaskProgressView taskProgressView) { - /* - TODO: A rota deve alterar apenas o progresso da tarefa que possua o id igual ao id correspondente - nos parâmetros da rota. - O `progress` pode ter o valor máximo de 100, e quando ele atingi o máximo, - o `status` deve ser alterado para `COMPLETE` - */ + public Response updateProgress(@PathParam("taskId") String taskId, TaskProgressView taskProgressView) { + TaskProgressDTO progressDTO = TaskProgressDTO.create().setId(UUID.fromString(taskId)) + .setProgress(taskProgressView.getProgress()); + this.updateTaskProgressService.execute(progressDTO); - return DefaultResponse.ok().entity("Hello world"); + return DefaultResponse.ok(); } } diff --git a/source/backend/challenge/modules/task/infra/http/views/TaskProgressView.java b/source/backend/challenge/modules/task/infra/http/views/TaskProgressView.java index 3375195..16a9d50 100644 --- a/source/backend/challenge/modules/task/infra/http/views/TaskProgressView.java +++ b/source/backend/challenge/modules/task/infra/http/views/TaskProgressView.java @@ -5,6 +5,7 @@ @Getter @Setter + public class TaskProgressView { private int progress; diff --git a/source/backend/challenge/modules/task/infra/http/views/TaskView.java b/source/backend/challenge/modules/task/infra/http/views/TaskView.java index 8b0d67e..d02faba 100644 --- a/source/backend/challenge/modules/task/infra/http/views/TaskView.java +++ b/source/backend/challenge/modules/task/infra/http/views/TaskView.java @@ -4,7 +4,6 @@ import lombok.Getter; import lombok.Setter; -import java.util.Date; @Getter @Setter diff --git a/source/backend/challenge/modules/task/models/Task.java b/source/backend/challenge/modules/task/models/Task.java index 3941274..f836a2a 100644 --- a/source/backend/challenge/modules/task/models/Task.java +++ b/source/backend/challenge/modules/task/models/Task.java @@ -6,6 +6,7 @@ import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.Setter; +import lombok.ToString; import lombok.experimental.Accessors; import java.time.LocalDateTime; import java.util.UUID; @@ -14,6 +15,7 @@ @Setter @AllArgsConstructor @NoArgsConstructor +@ToString public class Task { private UUID id; diff --git a/source/backend/challenge/modules/task/repositories/TaskRepository.java b/source/backend/challenge/modules/task/repositories/TaskRepository.java index d74525a..154a082 100644 --- a/source/backend/challenge/modules/task/repositories/TaskRepository.java +++ b/source/backend/challenge/modules/task/repositories/TaskRepository.java @@ -31,7 +31,7 @@ public class TaskRepository implements ITaskRepository { @Override public Optional index(final UUID taskId) { try (Connection connection = this.db.getConnection()) { - String sql = "SELECT id, title, description, createdAt FROM tasks WHERE id = ?"; + String sql = "SELECT id, title, description, status, progress, createdAt FROM tasks WHERE id = ?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, taskId.toString()); @@ -42,6 +42,8 @@ public Optional index(final UUID taskId) { task.setId(UUID.fromString(resultSet.getString("id"))); task.setTitle(resultSet.getString("title")); task.setDescription(resultSet.getString("description")); + task.setStatus(TaskStatus.valueOf(resultSet.getString("status"))); + task.setProgress(resultSet.getInt("progress")); task.setCreatedAt(resultSet.getTimestamp("createdAt").toLocalDateTime()); return Optional.of(task); } @@ -55,7 +57,7 @@ public Optional index(final UUID taskId) { @Override public List show() { try (Connection connection = this.db.getConnection()) { - String sql = "SELECT id, title, description, createdAt FROM tasks"; + String sql = "SELECT id, title, description, status, progress, createdAt FROM tasks"; PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery(); List tasks = new ArrayList<>(); @@ -64,6 +66,8 @@ public List show() { task.setId(UUID.fromString(resultSet.getString("id"))); task.setTitle(resultSet.getString("title")); task.setDescription(resultSet.getString("description")); + task.setStatus(TaskStatus.valueOf(resultSet.getString("status"))); + task.setProgress(resultSet.getInt("progress")); task.setCreatedAt(resultSet.getTimestamp("createdAt").toLocalDateTime()); tasks.add(task); } @@ -77,7 +81,7 @@ public List show() { @Override public Task create(final TaskDTO taskDTO) { try (Connection connection = this.db.getConnection()) { - String sql = "INSERT INTO tasks(id, title, description, createdAt) VALUES(?, ?, ?, ?)"; + String sql = "INSERT INTO tasks(id, title, description, status, progress, createdAt) VALUES(?, ?, ?, ?, ?, ?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); Task newTask = new Task( UUID.randomUUID(), @@ -92,7 +96,9 @@ public Task create(final TaskDTO taskDTO) { preparedStatement.setString(1, newTask.getId().toString()); preparedStatement.setString(2, newTask.getTitle()); preparedStatement.setString(3, newTask.getDescription()); - preparedStatement.setTimestamp(4, Timestamp.valueOf(newTask.getCreatedAt())); + preparedStatement.setString(4, newTask.getStatus().name()); + preparedStatement.setInt(5, newTask.getProgress()); + preparedStatement.setTimestamp(6, Timestamp.valueOf(newTask.getCreatedAt())); preparedStatement.executeUpdate(); return newTask; @@ -105,14 +111,16 @@ public Task create(final TaskDTO taskDTO) { @Override public Task update(final Task task) { - + System.out.println(task.toString()); try (Connection connection = this.db.getConnection()) { - String sql = "UPDATE tasks SET title = ?, description = ? WHERE id = ?"; + String sql = "UPDATE tasks SET title = ?, description = ?, status = ?, progress = ? WHERE id = ?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, task.getTitle()); preparedStatement.setString(2, task.getDescription()); - preparedStatement.setString(3, task.getId().toString()); + preparedStatement.setString(3, task.getStatus().name()); + preparedStatement.setInt(4, task.getProgress()); + preparedStatement.setString(5, task.getId().toString()); preparedStatement.executeUpdate(); return task; diff --git a/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java b/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java new file mode 100644 index 0000000..6e94eaf --- /dev/null +++ b/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java @@ -0,0 +1,46 @@ +package backend.challenge.modules.task.services; + +import java.time.LocalDateTime; +import java.util.Optional; +import java.util.UUID; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import backend.challenge.modules.task.dtos.TaskProgressDTO; +import backend.challenge.modules.task.enums.TaskStatus; +import backend.challenge.modules.task.models.Task; +import backend.challenge.modules.task.repositories.ITaskRepository; + +/** + * UpdateTaskProgressService + */ +@Singleton +public class UpdateTaskProgressService implements IUpdateTaskProgressService { + + private final ITaskRepository iTaskRepository; + + @Inject + public UpdateTaskProgressService(ITaskRepository iTaskRepository) { + this.iTaskRepository = iTaskRepository; + } + + @Override + public Task execute(TaskProgressDTO taskProgressDTO) { + + if (taskProgressDTO.getProgress() > 100 || taskProgressDTO.getProgress() < 0) { + throw new RuntimeException("O progresso deve estar entre 0 e 100."); + } + + Optional taskOpt = iTaskRepository.index(taskProgressDTO.getId()); + if (taskOpt.isEmpty()) + throw new RuntimeException("Tarefa não encontrada."); + + Task task = taskOpt.get(); + task.setProgress(taskProgressDTO.getProgress()); + iTaskRepository.update(task); + return task; + } + + +} \ No newline at end of file diff --git a/source/backend/challenge/modules/task/services/UpdateTaskService.java b/source/backend/challenge/modules/task/services/UpdateTaskService.java index 2c53dd0..42bc86e 100644 --- a/source/backend/challenge/modules/task/services/UpdateTaskService.java +++ b/source/backend/challenge/modules/task/services/UpdateTaskService.java @@ -1,5 +1,7 @@ package backend.challenge.modules.task.services; +import java.util.Optional; + import javax.inject.Inject; import javax.inject.Singleton; @@ -17,9 +19,21 @@ public UpdateTaskService(final ITaskRepository iTaskRepository) { } @Override - public Task execute(Task task) { + public Task execute(Task taskUp) { + Optional taskOpt = iTaskRepository.index(taskUp.getId()); + + if (taskOpt.isEmpty()) + throw new RuntimeException("Tarefa não encontrada."); + + Task task = taskOpt.get(); + if (!taskUp.getId().equals(task.getId()) || + !taskUp.getCreatedAt().equals(task.getCreatedAt()) || + taskUp.getProgress() != task.getProgress() || + !task.getStatus().equals(taskUp.getStatus())) throw new RuntimeException("É apenas possível alterar o Título e Descrição nesta operação."); + + - return this.iTaskRepository.update(task); + return this.iTaskRepository.update(task); } } From 9b187bdc5bcebd4d06e066e2b61e789cc284eecf Mon Sep 17 00:00:00 2001 From: danison Date: Mon, 29 Apr 2024 23:29:30 -0300 Subject: [PATCH 10/22] fix: handle TaskNotFoundException --- .../modules/task/exceptions/TaskNotFound.java | 8 ++++++++ .../infra/http/controllers/TaskController.java | 15 ++++++++++----- .../task/services/IRetrieveTaskByIdService.java | 4 ++-- .../task/services/RetrieveTaskByIdService.java | 7 +++++-- 4 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 source/backend/challenge/modules/task/exceptions/TaskNotFound.java diff --git a/source/backend/challenge/modules/task/exceptions/TaskNotFound.java b/source/backend/challenge/modules/task/exceptions/TaskNotFound.java new file mode 100644 index 0000000..ff6ed82 --- /dev/null +++ b/source/backend/challenge/modules/task/exceptions/TaskNotFound.java @@ -0,0 +1,8 @@ +package backend.challenge.modules.task.exceptions; + +public class TaskNotFound extends RuntimeException { + + public TaskNotFound() { + super("Tarefa não encontrda."); + } +} diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java index e2c65dd..f2560f3 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java @@ -1,6 +1,7 @@ package backend.challenge.modules.task.infra.http.controllers; import backend.challenge.modules.task.dtos.TaskDTO; +import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.infra.http.views.TaskView; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.services.*; @@ -44,10 +45,14 @@ public Response show() { @Path("single/{taskId}") public Response index(@PathParam("taskId") String taskId) { - Optional taskOpt = this.retrieveTaskByIdService.execute(UUID.fromString(taskId)); - if (taskOpt.isEmpty()) - return DefaultResponse.badRequest(); - return DefaultResponse.ok().entity(taskOpt.get()); + try { + Task taskOpt = this.retrieveTaskByIdService.execute(UUID.fromString(taskId)); + return DefaultResponse.ok().entity(taskOpt); + + } catch (TaskNotFound e) { + return DefaultResponse.badRequest().entity(e.getMessage()); + } + } @POST @@ -65,7 +70,7 @@ public Response update(@PathParam("taskId") String taskId, Task task) { this.updateTaskService.execute(task); - return DefaultResponse.ok().entity("Hello world"); + return DefaultResponse.ok(); } @DELETE diff --git a/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java b/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java index 390a9f0..fe0a1d5 100644 --- a/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java +++ b/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java @@ -1,12 +1,12 @@ package backend.challenge.modules.task.services; -import java.util.Optional; import java.util.UUID; +import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; public interface IRetrieveTaskByIdService { - Optional execute(UUID taskId); + Task execute(UUID taskId) throws TaskNotFound; } diff --git a/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java b/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java index 66bdb37..d713712 100644 --- a/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java +++ b/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java @@ -7,6 +7,7 @@ import javax.inject.Singleton; import javax.swing.plaf.OptionPaneUI; +import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; @Singleton @@ -20,8 +21,10 @@ public RetrieveTaskByIdService(final ITaskRepository taskRepository) { } @Override - public Optional execute(UUID taskId) { - return this.taskRepository.index(taskId); + public Task execute(UUID taskId) throws TaskNotFound{ + Optional taskOpt = this.taskRepository.index(taskId); + if(taskOpt.isEmpty()) throw new TaskNotFound(); + return taskOpt.get(); } From e336079847fbfc4ed3b0fb2a80d77bd1c31f748a Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 00:25:55 -0300 Subject: [PATCH 11/22] fix: handler exception update task --- .../TaskAlterationNotAvaliable.java | 7 ++++++ .../http/controllers/TaskController.java | 19 +++++++++++--- .../challenge/modules/task/models/Task.java | 7 +++++- .../task/repositories/TaskRepository.java | 8 +++--- .../task/services/IUpdateTaskService.java | 7 ++++-- .../task/services/UpdateTaskService.java | 25 +++++++++++++------ 6 files changed, 55 insertions(+), 18 deletions(-) create mode 100644 source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvaliable.java diff --git a/source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvaliable.java b/source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvaliable.java new file mode 100644 index 0000000..f196238 --- /dev/null +++ b/source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvaliable.java @@ -0,0 +1,7 @@ +package backend.challenge.modules.task.exceptions; + +public class TaskAlterationNotAvaliable extends RuntimeException{ + public TaskAlterationNotAvaliable() { + super("É apenas possível alterar o Título e Descrição nesta operação."); + } +} diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java index f2560f3..ff8bd9b 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java @@ -1,6 +1,7 @@ package backend.challenge.modules.task.infra.http.controllers; import backend.challenge.modules.task.dtos.TaskDTO; +import backend.challenge.modules.task.exceptions.TaskAlterationNotAvaliable; import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.infra.http.views.TaskView; import backend.challenge.modules.task.models.Task; @@ -66,11 +67,23 @@ public Response create(TaskView taskView) { @PUT @Path("single/{taskId}") - public Response update(@PathParam("taskId") String taskId, Task task) { + public Response update(@PathParam("taskId") String taskId, TaskDTO taskDto) { - this.updateTaskService.execute(task); + try { + Task task = new Task(); + task.setId(UUID.fromString(taskId)); + task.setDescription(taskDto.getDescription()); + task.setTitle(taskDto.getTitle()); + this.updateTaskService.execute(task); + return DefaultResponse.ok(); + } catch (TaskAlterationNotAvaliable | TaskNotFound e) { - return DefaultResponse.ok(); + return DefaultResponse.badRequest().entity(e.getMessage()); + } catch (Exception e) { + return DefaultResponse.serverError(); + } + + // return DefaultResponse.ok(); } @DELETE diff --git a/source/backend/challenge/modules/task/models/Task.java b/source/backend/challenge/modules/task/models/Task.java index f836a2a..efc74fa 100644 --- a/source/backend/challenge/modules/task/models/Task.java +++ b/source/backend/challenge/modules/task/models/Task.java @@ -8,9 +8,14 @@ import lombok.Setter; import lombok.ToString; import lombok.experimental.Accessors; + +import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.Date; import java.util.UUID; +import javax.xml.crypto.Data; + @Getter @Setter @AllArgsConstructor @@ -23,6 +28,6 @@ public class Task { private String description; private int progress; private TaskStatus status; - private LocalDateTime createdAt; + private LocalDate createdAt; } diff --git a/source/backend/challenge/modules/task/repositories/TaskRepository.java b/source/backend/challenge/modules/task/repositories/TaskRepository.java index 154a082..98902dd 100644 --- a/source/backend/challenge/modules/task/repositories/TaskRepository.java +++ b/source/backend/challenge/modules/task/repositories/TaskRepository.java @@ -44,7 +44,7 @@ public Optional index(final UUID taskId) { task.setDescription(resultSet.getString("description")); task.setStatus(TaskStatus.valueOf(resultSet.getString("status"))); task.setProgress(resultSet.getInt("progress")); - task.setCreatedAt(resultSet.getTimestamp("createdAt").toLocalDateTime()); + task.setCreatedAt(resultSet.getDate("createdAt").toLocalDate()); return Optional.of(task); } return Optional.empty(); @@ -68,7 +68,7 @@ public List show() { task.setDescription(resultSet.getString("description")); task.setStatus(TaskStatus.valueOf(resultSet.getString("status"))); task.setProgress(resultSet.getInt("progress")); - task.setCreatedAt(resultSet.getTimestamp("createdAt").toLocalDateTime()); + task.setCreatedAt( resultSet.getDate("createdAt").toLocalDate()); tasks.add(task); } return tasks; @@ -89,7 +89,7 @@ public Task create(final TaskDTO taskDTO) { taskDTO.getDescription(), 0, TaskStatus.PROGRESS, - LocalDateTime.now() + LocalDate.now() ); @@ -98,7 +98,7 @@ public Task create(final TaskDTO taskDTO) { preparedStatement.setString(3, newTask.getDescription()); preparedStatement.setString(4, newTask.getStatus().name()); preparedStatement.setInt(5, newTask.getProgress()); - preparedStatement.setTimestamp(6, Timestamp.valueOf(newTask.getCreatedAt())); + preparedStatement.setDate(6, java.sql.Date.valueOf(newTask.getCreatedAt())); preparedStatement.executeUpdate(); return newTask; diff --git a/source/backend/challenge/modules/task/services/IUpdateTaskService.java b/source/backend/challenge/modules/task/services/IUpdateTaskService.java index 3da8340..5237468 100644 --- a/source/backend/challenge/modules/task/services/IUpdateTaskService.java +++ b/source/backend/challenge/modules/task/services/IUpdateTaskService.java @@ -1,9 +1,12 @@ package backend.challenge.modules.task.services; +import backend.challenge.modules.task.dtos.TaskDTO; +import backend.challenge.modules.task.exceptions.TaskAlterationNotAvaliable; +import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; -public interface IUpdateTaskService { +public interface IUpdateTaskService{ - Task execute(Task task); + Task execute(Task task) throws TaskNotFound, TaskAlterationNotAvaliable; } diff --git a/source/backend/challenge/modules/task/services/UpdateTaskService.java b/source/backend/challenge/modules/task/services/UpdateTaskService.java index 42bc86e..413f201 100644 --- a/source/backend/challenge/modules/task/services/UpdateTaskService.java +++ b/source/backend/challenge/modules/task/services/UpdateTaskService.java @@ -5,6 +5,9 @@ import javax.inject.Inject; import javax.inject.Singleton; +import backend.challenge.modules.task.dtos.TaskDTO; +import backend.challenge.modules.task.exceptions.TaskAlterationNotAvaliable; +import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; @@ -19,21 +22,27 @@ public UpdateTaskService(final ITaskRepository iTaskRepository) { } @Override - public Task execute(Task taskUp) { + public Task execute(Task taskUp) throws TaskNotFound, TaskAlterationNotAvaliable { Optional taskOpt = iTaskRepository.index(taskUp.getId()); if (taskOpt.isEmpty()) - throw new RuntimeException("Tarefa não encontrada."); + throw new TaskNotFound(); Task task = taskOpt.get(); - if (!taskUp.getId().equals(task.getId()) || - !taskUp.getCreatedAt().equals(task.getCreatedAt()) || - taskUp.getProgress() != task.getProgress() || - !task.getStatus().equals(taskUp.getStatus())) throw new RuntimeException("É apenas possível alterar o Título e Descrição nesta operação."); - + if (taskUp.getCreatedAt() != null) + if (!taskUp.getCreatedAt().equals(task.getCreatedAt())) + throw new TaskAlterationNotAvaliable(); + if (taskUp.getStatus() != null) + if (taskUp.getStatus().equals(task.getStatus())) + throw new TaskAlterationNotAvaliable(); + if (taskUp.getProgress() != task.getProgress()) + throw new TaskAlterationNotAvaliable(); + + task.setDescription(taskUp.getDescription()); + task.setTitle(taskUp.getTitle()); return this.iTaskRepository.update(task); - } + } } From bb6e4fea7131c048207688dfa40edacb033ebd3b Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 00:31:45 -0300 Subject: [PATCH 12/22] fix: handler exceptions delete task --- .../task/infra/http/controllers/TaskController.java | 10 ++++++---- .../modules/task/services/DeleteTaskService.java | 5 +++-- .../modules/task/services/IDeleteTaskService.java | 4 +++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java index ff8bd9b..e7068e8 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java @@ -83,15 +83,17 @@ public Response update(@PathParam("taskId") String taskId, TaskDTO taskDto) { return DefaultResponse.serverError(); } - // return DefaultResponse.ok(); } @DELETE @Path("single/{taskId}") public Response delete(@PathParam("taskId") String taskId) { - - this.deleteTaskService.execute(UUID.fromString(taskId)); - return DefaultResponse.ok(); + try { + this.deleteTaskService.execute(UUID.fromString(taskId)); + return DefaultResponse.ok(); + } catch (TaskNotFound e) { + return DefaultResponse.badRequest().entity(e.getMessage()); + } } } diff --git a/source/backend/challenge/modules/task/services/DeleteTaskService.java b/source/backend/challenge/modules/task/services/DeleteTaskService.java index e124c3c..5e6699b 100644 --- a/source/backend/challenge/modules/task/services/DeleteTaskService.java +++ b/source/backend/challenge/modules/task/services/DeleteTaskService.java @@ -1,5 +1,6 @@ package backend.challenge.modules.task.services; +import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.repositories.ITaskRepository; import java.util.UUID; @@ -17,9 +18,9 @@ public DeleteTaskService(final ITaskRepository taskRepository) { } @Override - public void execute(UUID taskId) { + public void execute(UUID taskId) throws TaskNotFound{ - if(taskRepository.existsById(taskId)) return; + if(!taskRepository.existsById(taskId)) throw new TaskNotFound(); this.taskRepository.delete(taskId); } diff --git a/source/backend/challenge/modules/task/services/IDeleteTaskService.java b/source/backend/challenge/modules/task/services/IDeleteTaskService.java index 421beec..2b54720 100644 --- a/source/backend/challenge/modules/task/services/IDeleteTaskService.java +++ b/source/backend/challenge/modules/task/services/IDeleteTaskService.java @@ -2,8 +2,10 @@ import java.util.UUID; +import backend.challenge.modules.task.exceptions.TaskNotFound; + public interface IDeleteTaskService { - void execute(UUID taskId); + void execute(UUID taskId) throws TaskNotFound; } From 9ead44404b97fd6f62627f6e3a8a34a4ad34659c Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 00:44:55 -0300 Subject: [PATCH 13/22] fix: handler exceptions update progress --- .../ProgressTaskUpdateNotAvailable.java | 7 +++++++ ...le.java => TaskAlterationNotAvailable.java} | 4 ++-- .../infra/http/controllers/TaskController.java | 4 ++-- .../controllers/TaskProgressController.java | 13 +++++++++++-- .../services/IUpdateTaskProgressService.java | 4 +++- .../task/services/IUpdateTaskService.java | 4 ++-- .../services/UpdateTaskProgressService.java | 18 +++++++----------- .../task/services/UpdateTaskService.java | 10 +++++----- 8 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 source/backend/challenge/modules/task/exceptions/ProgressTaskUpdateNotAvailable.java rename source/backend/challenge/modules/task/exceptions/{TaskAlterationNotAvaliable.java => TaskAlterationNotAvailable.java} (58%) diff --git a/source/backend/challenge/modules/task/exceptions/ProgressTaskUpdateNotAvailable.java b/source/backend/challenge/modules/task/exceptions/ProgressTaskUpdateNotAvailable.java new file mode 100644 index 0000000..02f9843 --- /dev/null +++ b/source/backend/challenge/modules/task/exceptions/ProgressTaskUpdateNotAvailable.java @@ -0,0 +1,7 @@ +package backend.challenge.modules.task.exceptions; + +public class ProgressTaskUpdateNotAvailable extends RuntimeException{ + public ProgressTaskUpdateNotAvailable(){ + super("O progresso deve estar entre 0 e 100."); + } +} diff --git a/source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvaliable.java b/source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvailable.java similarity index 58% rename from source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvaliable.java rename to source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvailable.java index f196238..f0f3f02 100644 --- a/source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvaliable.java +++ b/source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvailable.java @@ -1,7 +1,7 @@ package backend.challenge.modules.task.exceptions; -public class TaskAlterationNotAvaliable extends RuntimeException{ - public TaskAlterationNotAvaliable() { +public class TaskAlterationNotAvailable extends RuntimeException{ + public TaskAlterationNotAvailable() { super("É apenas possível alterar o Título e Descrição nesta operação."); } } diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java index e7068e8..2abb784 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java @@ -1,7 +1,7 @@ package backend.challenge.modules.task.infra.http.controllers; import backend.challenge.modules.task.dtos.TaskDTO; -import backend.challenge.modules.task.exceptions.TaskAlterationNotAvaliable; +import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable; import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.infra.http.views.TaskView; import backend.challenge.modules.task.models.Task; @@ -76,7 +76,7 @@ public Response update(@PathParam("taskId") String taskId, TaskDTO taskDto) { task.setTitle(taskDto.getTitle()); this.updateTaskService.execute(task); return DefaultResponse.ok(); - } catch (TaskAlterationNotAvaliable | TaskNotFound e) { + } catch (TaskAlterationNotAvailable| TaskNotFound e) { return DefaultResponse.badRequest().entity(e.getMessage()); } catch (Exception e) { diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java index b2a3061..f129388 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java @@ -1,6 +1,9 @@ package backend.challenge.modules.task.infra.http.controllers; import backend.challenge.modules.task.dtos.TaskProgressDTO; +import backend.challenge.modules.task.exceptions.ProgressTaskUpdateNotAvailable; +import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable; +import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.infra.http.views.TaskProgressView; import backend.challenge.modules.task.services.*; import kikaha.urouting.api.*; @@ -24,9 +27,15 @@ public TaskProgressController(final IUpdateTaskProgressService updateTaskProgres public Response updateProgress(@PathParam("taskId") String taskId, TaskProgressView taskProgressView) { TaskProgressDTO progressDTO = TaskProgressDTO.create().setId(UUID.fromString(taskId)) .setProgress(taskProgressView.getProgress()); - this.updateTaskProgressService.execute(progressDTO); - return DefaultResponse.ok(); + try { + this.updateTaskProgressService.execute(progressDTO); + return DefaultResponse.ok(); + + } catch (ProgressTaskUpdateNotAvailable | TaskNotFound e) { + return DefaultResponse.badRequest().entity(e.getMessage()); + } + } } diff --git a/source/backend/challenge/modules/task/services/IUpdateTaskProgressService.java b/source/backend/challenge/modules/task/services/IUpdateTaskProgressService.java index 133b794..1d9fdd8 100644 --- a/source/backend/challenge/modules/task/services/IUpdateTaskProgressService.java +++ b/source/backend/challenge/modules/task/services/IUpdateTaskProgressService.java @@ -1,10 +1,12 @@ package backend.challenge.modules.task.services; import backend.challenge.modules.task.dtos.TaskProgressDTO; +import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable; +import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; public interface IUpdateTaskProgressService { - Task execute(TaskProgressDTO taskProgressDTO); + Task execute(TaskProgressDTO taskProgressDTO) throws TaskAlterationNotAvailable, TaskNotFound; } diff --git a/source/backend/challenge/modules/task/services/IUpdateTaskService.java b/source/backend/challenge/modules/task/services/IUpdateTaskService.java index 5237468..6af41bd 100644 --- a/source/backend/challenge/modules/task/services/IUpdateTaskService.java +++ b/source/backend/challenge/modules/task/services/IUpdateTaskService.java @@ -1,12 +1,12 @@ package backend.challenge.modules.task.services; import backend.challenge.modules.task.dtos.TaskDTO; -import backend.challenge.modules.task.exceptions.TaskAlterationNotAvaliable; +import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable; import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; public interface IUpdateTaskService{ - Task execute(Task task) throws TaskNotFound, TaskAlterationNotAvaliable; + Task execute(Task task) throws TaskNotFound, TaskAlterationNotAvailable; } diff --git a/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java b/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java index 6e94eaf..bee424e 100644 --- a/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java +++ b/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java @@ -1,20 +1,16 @@ package backend.challenge.modules.task.services; -import java.time.LocalDateTime; import java.util.Optional; -import java.util.UUID; - import javax.inject.Inject; import javax.inject.Singleton; - import backend.challenge.modules.task.dtos.TaskProgressDTO; -import backend.challenge.modules.task.enums.TaskStatus; +import backend.challenge.modules.task.exceptions.ProgressTaskUpdateNotAvailable; +import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable; +import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; -/** - * UpdateTaskProgressService - */ + @Singleton public class UpdateTaskProgressService implements IUpdateTaskProgressService { @@ -26,15 +22,15 @@ public UpdateTaskProgressService(ITaskRepository iTaskRepository) { } @Override - public Task execute(TaskProgressDTO taskProgressDTO) { + public Task execute(TaskProgressDTO taskProgressDTO) throws TaskAlterationNotAvailable, TaskNotFound{ if (taskProgressDTO.getProgress() > 100 || taskProgressDTO.getProgress() < 0) { - throw new RuntimeException("O progresso deve estar entre 0 e 100."); + throw new ProgressTaskUpdateNotAvailable(); } Optional taskOpt = iTaskRepository.index(taskProgressDTO.getId()); if (taskOpt.isEmpty()) - throw new RuntimeException("Tarefa não encontrada."); + throw new TaskNotFound(); Task task = taskOpt.get(); task.setProgress(taskProgressDTO.getProgress()); diff --git a/source/backend/challenge/modules/task/services/UpdateTaskService.java b/source/backend/challenge/modules/task/services/UpdateTaskService.java index 413f201..f07c842 100644 --- a/source/backend/challenge/modules/task/services/UpdateTaskService.java +++ b/source/backend/challenge/modules/task/services/UpdateTaskService.java @@ -6,7 +6,7 @@ import javax.inject.Singleton; import backend.challenge.modules.task.dtos.TaskDTO; -import backend.challenge.modules.task.exceptions.TaskAlterationNotAvaliable; +import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable; import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; @@ -22,7 +22,7 @@ public UpdateTaskService(final ITaskRepository iTaskRepository) { } @Override - public Task execute(Task taskUp) throws TaskNotFound, TaskAlterationNotAvaliable { + public Task execute(Task taskUp) throws TaskNotFound, TaskAlterationNotAvailable { Optional taskOpt = iTaskRepository.index(taskUp.getId()); if (taskOpt.isEmpty()) @@ -32,13 +32,13 @@ public Task execute(Task taskUp) throws TaskNotFound, TaskAlterationNotAvaliable if (taskUp.getCreatedAt() != null) if (!taskUp.getCreatedAt().equals(task.getCreatedAt())) - throw new TaskAlterationNotAvaliable(); + throw new TaskAlterationNotAvailable(); if (taskUp.getStatus() != null) if (taskUp.getStatus().equals(task.getStatus())) - throw new TaskAlterationNotAvaliable(); + throw new TaskAlterationNotAvailable(); if (taskUp.getProgress() != task.getProgress()) - throw new TaskAlterationNotAvaliable(); + throw new TaskAlterationNotAvailable(); task.setDescription(taskUp.getDescription()); task.setTitle(taskUp.getTitle()); From 1abad911b35dc080b8842ee99f91f8bb0e70e2e8 Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 01:20:24 -0300 Subject: [PATCH 14/22] fix: chage status if full progress --- .../task/services/UpdateTaskProgressService.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java b/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java index bee424e..9746921 100644 --- a/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java +++ b/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java @@ -4,13 +4,13 @@ import javax.inject.Inject; import javax.inject.Singleton; import backend.challenge.modules.task.dtos.TaskProgressDTO; +import backend.challenge.modules.task.enums.TaskStatus; import backend.challenge.modules.task.exceptions.ProgressTaskUpdateNotAvailable; import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable; import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; - @Singleton public class UpdateTaskProgressService implements IUpdateTaskProgressService { @@ -22,7 +22,7 @@ public UpdateTaskProgressService(ITaskRepository iTaskRepository) { } @Override - public Task execute(TaskProgressDTO taskProgressDTO) throws TaskAlterationNotAvailable, TaskNotFound{ + public Task execute(TaskProgressDTO taskProgressDTO) throws TaskAlterationNotAvailable, TaskNotFound { if (taskProgressDTO.getProgress() > 100 || taskProgressDTO.getProgress() < 0) { throw new ProgressTaskUpdateNotAvailable(); @@ -34,9 +34,14 @@ public Task execute(TaskProgressDTO taskProgressDTO) throws TaskAlterationNotAva Task task = taskOpt.get(); task.setProgress(taskProgressDTO.getProgress()); + if (taskProgressDTO.getProgress() == 100) { + task.setStatus(TaskStatus.COMPLETE); + } else { + task.setStatus(TaskStatus.PROGRESS); + } + iTaskRepository.update(task); return task; } - } \ No newline at end of file From 9db72235fe652d7411c92158316c51f820c70d10 Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 12:50:59 -0300 Subject: [PATCH 15/22] test: add all tests --- pom.xml | 32 ++-- .../http/controllers/TaskController.java | 1 - .../challenge/modules/task/models/Task.java | 2 + .../task/services/CreateTaskService.java | 1 - .../task/services/UpdateTaskService.java | 6 +- .../task/controllers/TaskControllerTest.java | 111 +++++++++++++ .../task/services/CreateTaskServiceTest.java | 50 ++++-- .../task/services/DeleteTaskServiceTest.java | 33 +++- .../services/RetrieveAllTasksServiceTest.java | 59 ++++++- .../services/RetrieveTaskByIdServiceTest.java | 57 ++++++- .../UpdateTaskProgressServiceTest.java | 147 +++++++++++++++-- .../task/services/UpdateTaskServiceTest.java | 154 ++++++++++++++++-- 12 files changed, 576 insertions(+), 77 deletions(-) create mode 100644 tests/backend/challenge/modules/task/controllers/TaskControllerTest.java diff --git a/pom.xml b/pom.xml index c45808d..f2c5246 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 @@ -66,6 +67,15 @@ ${version.junit} test + + + org.mockito + mockito-core + 5.3.1 + test + + + org.projectlombok @@ -79,16 +89,16 @@ 1.3.2 - + - io.skullabs.kikaha - kikaha-db - - - mysql - mysql-connector-java - 8.0.33 - + io.skullabs.kikaha + kikaha-db + + + mysql + mysql-connector-java + 8.0.33 + @@ -122,4 +132,4 @@ - + \ No newline at end of file diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java index 2abb784..beafb07 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java @@ -38,7 +38,6 @@ public TaskController( @GET public Response show() { - this.retrieveAllTasksService.execute(); return DefaultResponse.ok().entity(retrieveAllTasksService.execute()); } diff --git a/source/backend/challenge/modules/task/models/Task.java b/source/backend/challenge/modules/task/models/Task.java index efc74fa..5ea60e4 100644 --- a/source/backend/challenge/modules/task/models/Task.java +++ b/source/backend/challenge/modules/task/models/Task.java @@ -2,6 +2,7 @@ import backend.challenge.modules.task.enums.TaskStatus; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; @@ -21,6 +22,7 @@ @AllArgsConstructor @NoArgsConstructor @ToString +@EqualsAndHashCode public class Task { private UUID id; diff --git a/source/backend/challenge/modules/task/services/CreateTaskService.java b/source/backend/challenge/modules/task/services/CreateTaskService.java index f23d9ab..4154240 100644 --- a/source/backend/challenge/modules/task/services/CreateTaskService.java +++ b/source/backend/challenge/modules/task/services/CreateTaskService.java @@ -19,7 +19,6 @@ public CreateTaskService(final ITaskRepository taskRepository) { @Override public Task execute(TaskDTO taskDTO) { - // TODO: Criar serviço responsável por criar uma tarefa return taskRepository.create(taskDTO); } diff --git a/source/backend/challenge/modules/task/services/UpdateTaskService.java b/source/backend/challenge/modules/task/services/UpdateTaskService.java index f07c842..59bd2f7 100644 --- a/source/backend/challenge/modules/task/services/UpdateTaskService.java +++ b/source/backend/challenge/modules/task/services/UpdateTaskService.java @@ -30,11 +30,15 @@ public Task execute(Task taskUp) throws TaskNotFound, TaskAlterationNotAvailable Task task = taskOpt.get(); + if (taskUp.getId() != null) + if (!taskUp.getId().equals(task.getId())) + throw new TaskAlterationNotAvailable(); + if (taskUp.getCreatedAt() != null) if (!taskUp.getCreatedAt().equals(task.getCreatedAt())) throw new TaskAlterationNotAvailable(); if (taskUp.getStatus() != null) - if (taskUp.getStatus().equals(task.getStatus())) + if (!taskUp.getStatus().equals(task.getStatus())) throw new TaskAlterationNotAvailable(); if (taskUp.getProgress() != task.getProgress()) diff --git a/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java b/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java new file mode 100644 index 0000000..f7339c6 --- /dev/null +++ b/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java @@ -0,0 +1,111 @@ +package backend.challenge.modules.task.controllers; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; + +import java.time.LocalDate; +import java.util.List; +import java.util.UUID; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import backend.challenge.modules.task.enums.TaskStatus; +import backend.challenge.modules.task.exceptions.TaskNotFound; +import backend.challenge.modules.task.infra.http.controllers.TaskController; +import backend.challenge.modules.task.models.Task; +import backend.challenge.modules.task.services.ICreateTaskService; +import backend.challenge.modules.task.services.IDeleteTaskService; +import backend.challenge.modules.task.services.IRetrieveAllTasksService; +import backend.challenge.modules.task.services.IRetrieveTaskByIdService; +import backend.challenge.modules.task.services.IUpdateTaskService; +import kikaha.core.test.KikahaRunner; +import kikaha.urouting.api.DefaultResponse; +import kikaha.urouting.api.Response; + +@RunWith(KikahaRunner.class) +public class TaskControllerTest { + + @Mock + private ICreateTaskService createTaskService; + @Mock + private IDeleteTaskService deleteTaskService; + @Mock + private IRetrieveAllTasksService retrieveAllTasksService; + @Mock + private IRetrieveTaskByIdService retrieveTaskByIdService; + @Mock + private IUpdateTaskService updateTaskService; + + @InjectMocks + private TaskController controller; + + @Before + public void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void sholdReturnATasksList() { + Task task1 = new Task( + UUID.fromString("0402220c-6ba9-4e49-b7fb-42c443912db1"), + "Estudar sobre KIKAHA", + "Devo estudar a documentacao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + Task task2 = new Task( + UUID.fromString("720981f8-19f9-4f13-815c-21e4294bed30"), + "Estudar sobre Mockito", + "Devo assistir 3 aulas", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + Task task3 = new Task(UUID.fromString("85d519e9-0c94-4524-81b3-1b4795347c50"), + "Completar o projeto Sizebay", + "Devo realizar os teste unitarios", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + List tasksExpect = List.of(task1, task2, task3); + + doReturn(tasksExpect).when(retrieveAllTasksService).execute(); + + Assert.assertEquals(tasksExpect, retrieveAllTasksService.execute()); + } + + @Test + public void sholdReturnATaskById() { + UUID id = UUID.fromString("0402220c-6ba9-4e49-b7fb-42c443912db1"); + Task task = new Task( + id, + "Estudar sobre KIKAHA", + "Devo estudar a documentacao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + doReturn(task).when(retrieveTaskByIdService).execute(id); + Assert.assertEquals(task, controller.index(id.toString()).entity()); + + } + + @Test + public void sholdReturn400StatusIfIdNotExists() { + UUID id = UUID.fromString("7a8853b1-7031-489a-b305-76e15b352154"); + + when(retrieveTaskByIdService.execute(id)).thenThrow(new TaskNotFound()); + Response response = controller.index(id.toString()); + assertEquals(400, response.statusCode()); + assertEquals(new TaskNotFound().getMessage(), response.entity()); + + } +} diff --git a/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java b/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java index 3f2fd06..790eb87 100644 --- a/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java +++ b/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java @@ -1,32 +1,60 @@ package backend.challenge.modules.task.services; +import backend.challenge.modules.task.dtos.TaskDTO; +import backend.challenge.modules.task.enums.TaskStatus; +import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; import backend.challenge.modules.task.repositories.TaskRepository; import kikaha.core.test.KikahaRunner; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDate; +import java.util.UUID; +import javax.inject.Inject; +import javax.inject.Singleton; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; -@RunWith( KikahaRunner.class ) +@RunWith(KikahaRunner.class) public class CreateTaskServiceTest { - private ICreateTaskService createTaskService; + @InjectMocks + private CreateTaskService createTaskService; + + @Mock + private ITaskRepository taskRepository; @Before public void init() { - final ITaskRepository taskRepository = new TaskRepository(); - - createTaskService = new CreateTaskService(taskRepository); + MockitoAnnotations.openMocks(this); } @Test public void shouldBeAbleToCreateANewTask() { - // TODO: Para que esse teste passe, sua aplicação deve permitir que - // uma tarefa seja criado, e retorne um json com a tarefa criada. + TaskDTO taskDTO = TaskDTO.create().setTitle("Algum titulo").setDescription("Alguma descricao"); + + Task expectedTask = new Task( + UUID.fromString("e36be03f-5b17-4720-845e-68412f8248c6"), + "Algum titulo", + "Alguma descricao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + Mockito.when(taskRepository.create(taskDTO)).thenReturn(expectedTask); + Task result = createTaskService.execute(taskDTO); + assertEquals(expectedTask, result); + Mockito.verify(taskRepository, Mockito.times(1)).create(taskDTO); + + Task taskToUpdate = new Task( + + ); } - - - } \ No newline at end of file diff --git a/tests/backend/challenge/modules/task/services/DeleteTaskServiceTest.java b/tests/backend/challenge/modules/task/services/DeleteTaskServiceTest.java index 93497a5..17027c1 100644 --- a/tests/backend/challenge/modules/task/services/DeleteTaskServiceTest.java +++ b/tests/backend/challenge/modules/task/services/DeleteTaskServiceTest.java @@ -1,28 +1,45 @@ package backend.challenge.modules.task.services; import backend.challenge.modules.task.repositories.ITaskRepository; -import backend.challenge.modules.task.repositories.TaskRepository; import kikaha.core.test.KikahaRunner; +import static org.mockito.Mockito.doReturn; +import java.util.UUID; +import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; @RunWith( KikahaRunner.class ) public class DeleteTaskServiceTest { - private IDeleteTaskService deleteTaskService; + @InjectMocks + private DeleteTaskService deleteTaskService; - @Before - public void init() { - final ITaskRepository taskRepository = new TaskRepository(); + @Mock + private ITaskRepository taskRepository; - deleteTaskService = new DeleteTaskService(taskRepository); + @Before + public void init(){ + MockitoAnnotations.openMocks(this); } + @Test public void shouldBeAbleToDeleteTaskById() { - // TODO: Para que esse teste passe, sua aplicação deve permitir que tarefas sejam deletadas por id. + UUID id = UUID.fromString("e36be03f-5b17-4720-845e-68412f8248c6"); + doReturn(true).when(taskRepository).existsById(id); + taskRepository.delete(id); + Mockito.verify(taskRepository, Mockito.times(1)).delete(id); + ArgumentCaptor idCaptor = ArgumentCaptor.forClass(UUID.class); + + Mockito.verify(taskRepository).delete(idCaptor.capture()); + + Assert.assertEquals(id, idCaptor.getValue()); } diff --git a/tests/backend/challenge/modules/task/services/RetrieveAllTasksServiceTest.java b/tests/backend/challenge/modules/task/services/RetrieveAllTasksServiceTest.java index 68f0012..bd928e1 100644 --- a/tests/backend/challenge/modules/task/services/RetrieveAllTasksServiceTest.java +++ b/tests/backend/challenge/modules/task/services/RetrieveAllTasksServiceTest.java @@ -1,31 +1,74 @@ package backend.challenge.modules.task.services; +import backend.challenge.modules.task.enums.TaskStatus; +import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; import backend.challenge.modules.task.repositories.TaskRepository; import kikaha.core.test.KikahaRunner; + +import java.time.LocalDate; +import java.util.List; +import java.util.UUID; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; -@RunWith( KikahaRunner.class ) +@RunWith(KikahaRunner.class) public class RetrieveAllTasksServiceTest { - private IRetrieveAllTasksService retrieveAllTasksService; + @InjectMocks + private RetrieveAllTasksService retrieveAllTasksService; + + @Mock + private ITaskRepository taskRepository; @Before public void init() { - final ITaskRepository taskRepository = new TaskRepository(); + MockitoAnnotations.openMocks(this); - retrieveAllTasksService = new RetrieveAllTasksService(taskRepository); } @Test public void shouldBeAbleToListTheTasks() { - /* - TODO: Para que esse teste passe, sua aplicação deve permitir que seja - retornado um array com todas as tarefas que foram criadas até o momento. - */ + + Task task1 = new Task( + UUID.fromString("0402220c-6ba9-4e49-b7fb-42c443912db1"), + "Estudar sobre KIKAHA", + "Devo estudar a documentacao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + Task task2 = new Task( + UUID.fromString("720981f8-19f9-4f13-815c-21e4294bed30"), + "Estudar sobre Mockito", + "Devo assistir 3 aulas", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + Task task3 = new Task(UUID.fromString("85d519e9-0c94-4524-81b3-1b4795347c50"), + "Completar o projeto Sizebay", + "Devo realizar os teste unitarios", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + List tasksExpect = List.of(task1, task2, task3); + + Mockito.when(taskRepository.show()).thenReturn(tasksExpect); + Assert.assertEquals(retrieveAllTasksService.execute(), tasksExpect); + Mockito.verify(taskRepository, Mockito.times(1)).show(); + } } \ No newline at end of file diff --git a/tests/backend/challenge/modules/task/services/RetrieveTaskByIdServiceTest.java b/tests/backend/challenge/modules/task/services/RetrieveTaskByIdServiceTest.java index eb96b15..1ff2ade 100644 --- a/tests/backend/challenge/modules/task/services/RetrieveTaskByIdServiceTest.java +++ b/tests/backend/challenge/modules/task/services/RetrieveTaskByIdServiceTest.java @@ -1,24 +1,65 @@ package backend.challenge.modules.task.services; - +import backend.challenge.modules.task.enums.TaskStatus; +import backend.challenge.modules.task.exceptions.TaskNotFound; +import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; -import backend.challenge.modules.task.repositories.TaskRepository; import kikaha.core.test.KikahaRunner; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; + +import java.time.LocalDate; +import java.util.Optional; +import java.util.UUID; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; -@RunWith( KikahaRunner.class ) +@RunWith(KikahaRunner.class) public class RetrieveTaskByIdServiceTest { - private IRetrieveTaskByIdService retrieveTaskByIdService; + @InjectMocks + private RetrieveTaskByIdService retrieveTaskByIdService; + + @Mock + private ITaskRepository taskRepository; + + @Before + public void init() { + MockitoAnnotations.openMocks(this); + } @Test public void shouldBeAbleToListTheTaskById() { - /* - TODO: Para que esse teste passe, sua aplicação deve permitir que seja - retornado uma tarefa com o mesmo id informado. - */ + UUID id = UUID.fromString("e5102dbd-c9f1-47ce-8bc0-a761dc620e13"); + + Task taskExpect = new Task( + id, + "Algum titulo", + "Alguma descricao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + Mockito.when(taskRepository.index(id)).thenReturn(Optional.of(taskExpect)); + + Assert.assertEquals(taskExpect, retrieveTaskByIdService.execute(id)); + + } + @Test + public void shouldThrowExceptionWhenTaskNotFoundById(){ + + UUID id = UUID.fromString("e5102dbd-c9f1-47ce-8bc0-a761dc620e13"); + Mockito.when(taskRepository.index(id)).thenReturn(Optional.empty()); + + Assert.assertThrows(TaskNotFound.class,() -> retrieveTaskByIdService.execute(id)); + Mockito.verify(taskRepository, times(1)).index(id); } } diff --git a/tests/backend/challenge/modules/task/services/UpdateTaskProgressServiceTest.java b/tests/backend/challenge/modules/task/services/UpdateTaskProgressServiceTest.java index e6b0bf6..9fc3e07 100644 --- a/tests/backend/challenge/modules/task/services/UpdateTaskProgressServiceTest.java +++ b/tests/backend/challenge/modules/task/services/UpdateTaskProgressServiceTest.java @@ -1,27 +1,154 @@ package backend.challenge.modules.task.services; - import kikaha.core.test.KikahaRunner; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; + +import java.time.LocalDate; +import java.util.Optional; +import java.util.UUID; + +import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import backend.challenge.modules.task.dtos.TaskDTO; +import backend.challenge.modules.task.dtos.TaskProgressDTO; +import backend.challenge.modules.task.enums.TaskStatus; +import backend.challenge.modules.task.exceptions.ProgressTaskUpdateNotAvailable; +import backend.challenge.modules.task.models.Task; +import backend.challenge.modules.task.repositories.ITaskRepository; -@RunWith( KikahaRunner.class ) +@RunWith(KikahaRunner.class) public class UpdateTaskProgressServiceTest { + @InjectMocks + private UpdateTaskProgressService progressService; + + @Mock + private ITaskRepository taskRepository; + + private Task task; + private UUID id; + + @Before + public void init() { + MockitoAnnotations.openMocks(this); + + id = UUID.fromString("34fb74a0-682c-43c0-b228-1eca6da09150"); + task = new Task( + id, + "Algum titulo", + "Alguma descricao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + } + @Test public void shouldBeAbleToUpdateTaskProgress() { - /* - TODO: Para que esse teste passe, sua aplicação deve permitir que sejam - alterados apenas o campo `progress`. - */ + + int newProgress = 50; + TaskProgressDTO dto = TaskProgressDTO.create().setId(id).setProgress(newProgress); + + Task taskUpdated = new Task( + id, + task.getTitle(), + task.getDescription(), + newProgress, + task.getStatus(), + task.getCreatedAt() + + ); + + Mockito.when(taskRepository.index(id)).thenReturn(Optional.of(task)); + Assert.assertEquals(taskUpdated, progressService.execute(dto)); + } @Test public void shouldBeAbleToUpdateOnlyTaskStatusWhenProgressEqualsOneHundred() { - /* - TODO: Para que esse teste passe, sua aplicação deve permitir que sejam - alterado apenas o campo `status`, quando o progresso for igual a 100. - */ + + int newProgress = 110; + TaskProgressDTO progressDTO = TaskProgressDTO.create().setId(id).setProgress(newProgress); + + Assert.assertThrows(ProgressTaskUpdateNotAvailable.class, + () -> progressService.execute(progressDTO)); + + progressDTO.setProgress(-10); + Assert.assertThrows(ProgressTaskUpdateNotAvailable.class, + () -> progressService.execute(progressDTO)); + + } + + @Test + public void shouldChangeStatusIfCompleteProgress() { + int newProgress = 100; + TaskProgressDTO taskProgressDTO = TaskProgressDTO.create().setId(id).setProgress(newProgress); + Task taskUpdated = new Task( + task.getId(), + task.getTitle(), + task.getDescription(), + newProgress, + task.getStatus(), + task.getCreatedAt()); + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Task.class); + + Mockito.when(taskRepository.index(id)).thenReturn(Optional.of(task)); + doReturn(taskUpdated).when(taskRepository).update(task); + + this.progressService.execute(taskProgressDTO); + + Mockito.verify(taskRepository, Mockito.times(1)).index(id); + Mockito.verify(taskRepository).update(argumentCaptor.capture()); + + Task taskCaptured = argumentCaptor.getValue(); + + Assert.assertEquals( TaskStatus.COMPLETE, taskCaptured.getStatus()); + } + + @Test + public void shouldChangeStatusIfNotCompleteProgress() { + int newProgress = 50; + int oldProgress = 100; + Task task = new Task( + id, + "Algum titulo", + "Alguma descricao", + oldProgress, + TaskStatus.COMPLETE, + LocalDate.of(2024, 1, 1)); + + Task taskUpdated = new Task( + task.getId(), + task.getTitle(), + task.getDescription(), + newProgress, + TaskStatus.COMPLETE, + task.getCreatedAt()); + + TaskProgressDTO taskProgressDTO = TaskProgressDTO.create().setId(id).setProgress(newProgress); + Mockito.when(taskRepository.index(id)).thenReturn(Optional.of(task)); + doReturn(taskUpdated).when(taskRepository).update(task); + + this.progressService.execute(taskProgressDTO); + + Mockito.verify(taskRepository, Mockito.times(1)).index(id); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Task.class); + Mockito.verify(taskRepository).update(argumentCaptor.capture()); + + Task taskCaptured = argumentCaptor.getValue(); + + Assert.assertEquals(TaskStatus.PROGRESS, taskCaptured.getStatus()); } } diff --git a/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java b/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java index 53a4082..c479f83 100644 --- a/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java +++ b/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java @@ -1,44 +1,162 @@ package backend.challenge.modules.task.services; +import backend.challenge.modules.task.enums.TaskStatus; +import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable; +import backend.challenge.modules.task.exceptions.TaskNotFound; +import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; import backend.challenge.modules.task.repositories.TaskRepository; import kikaha.core.test.KikahaRunner; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; + +import java.time.LocalDate; +import java.util.Optional; +import java.util.UUID; + +import javax.inject.Inject; + +import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; -@RunWith( KikahaRunner.class ) +@RunWith(KikahaRunner.class) public class UpdateTaskServiceTest { - private IUpdateTaskService updateTaskService; + @InjectMocks + private UpdateTaskService updateTaskService; + + @Mock + private ITaskRepository taskRepository; + + private Task task; + private UUID id; + + @Before + public void init() { + MockitoAnnotations.openMocks(this); + } @Test - public void shouldBeAbleToUpdateTask() { - /* - TODO: Para que esse teste passe, sua aplicação deve permitir que sejam - alterados apenas os campos `title` e `observation`. - */ + public void shouldBeAbleToUpdateTaskIfTitleModified() { + + id = UUID.fromString("ba27ee3a-5e41-4a87-b0fc-13e01e31cb0f"); + task = new Task( + id, + "Algum titulo", + "Alguma descricao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + Mockito.when(taskRepository.index(id)).thenReturn(Optional.of(task)); + + Task taskToUpdate = new Task( + id, + task.getTitle(), + task.getDescription(), + task.getProgress(), + task.getStatus(), + task.getCreatedAt()); + taskToUpdate.setTitle("Outro titulo"); + Assert.assertEquals( + taskToUpdate, + taskToUpdate); + } @Test - public void shouldNotBeAbleToUpdateATaskThatDoesNotExist() { - /* - TODO: Para que esse teste passe, você deve validar na sua rota de update se - o id da tarefa enviada pela url existe ou não. Caso não exista, retornar um erro com status 400. - */ + public void shouldBeAbleToUpdateTaskIfDescriptionModified() { + id = UUID.fromString("ba27ee3a-5e41-4a87-b0fc-13e01e31cb0f"); + task = new Task( + id, + "Algum titulo", + "Alguma descricao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + Mockito.when(taskRepository.index(id)).thenReturn(Optional.of(task)); + + Task taskToUpdate = new Task( + id, + task.getTitle(), + task.getDescription(), + task.getProgress(), + task.getStatus(), + task.getCreatedAt()); + taskToUpdate.setDescription("Outra descricao"); + Assert.assertEquals( + taskToUpdate, + taskToUpdate); + } @Test public void shouldNotBeAbleToUpdateTaskStatusManually() { - /* - TODO: Para que esse teste passe, você não deve permitir que sua rota de update - altere diretamente o `status` dessa tarefa, mantendo o mesmo status que a tarefa - já possuía antes da atualização. Isso porque o único lugar que deve atualizar essa informação - é a rota responsável por alterar o progresso da tarefa. + id = UUID.fromString("ba27ee3a-5e41-4a87-b0fc-13e01e31cb0f"); + task = new Task( + id, + "Algum titulo", + "Alguma descricao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + Mockito.when(taskRepository.index(id)).thenReturn(Optional.of(task)); + + Task taskToUpdate = new Task( + id, + task.getTitle(), + task.getDescription(), + task.getProgress(), + task.getStatus(), + task.getCreatedAt()); + taskToUpdate.setProgress(50); + Assert.assertThrows(TaskAlterationNotAvailable.class, () -> updateTaskService.execute(taskToUpdate)); + + } + + @Test + public void shouldBeThrowsExceptionIfProgressModified() { + id = UUID.fromString("ba27ee3a-5e41-4a87-b0fc-13e01e31cb0f"); + task = new Task( + id, + "Algum titulo", + "Alguma descricao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + Mockito.when(taskRepository.index(id)).thenReturn(Optional.of(task)); + + Task taskToUpdate = new Task( + id, + task.getTitle(), + task.getDescription(), + task.getProgress(), + task.getStatus(), + task.getCreatedAt()); + taskToUpdate.setCreatedAt(LocalDate.of(2023, 10, 2)); + Assert.assertThrows(TaskAlterationNotAvailable.class, () -> updateTaskService.execute(taskToUpdate)); - */ } + @Test + public void shouldNotBeAbleToUpdateATaskThatDoesNotExist() { + UUID id = UUID.fromString("aa0fde29-d40a-43f7-877d-a3d351891b7b"); + Task task = new Task(); + task.setId(id); + Mockito.doReturn(Optional.empty()).when(taskRepository).index(id); + Assert.assertThrows(TaskNotFound.class, () -> updateTaskService.execute(task)); + + } } \ No newline at end of file From 8caf32012368fe3f04c766bfb4f0c9bb11143620 Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 12:55:06 -0300 Subject: [PATCH 16/22] chore: remove imports not useds --- .vscode/settings.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e0f15db --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "automatic" +} \ No newline at end of file From 159da3090abf789aac50ca600616d95ccb46cf93 Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 12:55:32 -0300 Subject: [PATCH 17/22] chore: remove imports not useds --- .../modules/task/services/CreateTaskService.java | 1 - .../modules/task/services/DeleteTaskService.java | 1 - .../modules/task/services/IDeleteTaskService.java | 1 - .../modules/task/services/IRetrieveAllTasksService.java | 1 - .../modules/task/services/IRetrieveTaskByIdService.java | 1 - .../modules/task/services/IUpdateTaskService.java | 1 - .../modules/task/services/RetrieveAllTasksService.java | 1 - .../modules/task/services/RetrieveTaskByIdService.java | 2 -- .../modules/task/services/UpdateTaskService.java | 2 -- tests/Runner.java | 1 - .../modules/task/controllers/TaskControllerTest.java | 4 ---- .../modules/task/services/CreateTaskServiceTest.java | 8 -------- .../task/services/RetrieveAllTasksServiceTest.java | 7 ------- .../task/services/RetrieveTaskByIdServiceTest.java | 3 --- .../task/services/UpdateTaskProgressServiceTest.java | 7 ------- .../modules/task/services/UpdateTaskServiceTest.java | 9 --------- 16 files changed, 50 deletions(-) diff --git a/source/backend/challenge/modules/task/services/CreateTaskService.java b/source/backend/challenge/modules/task/services/CreateTaskService.java index 4154240..6fafda8 100644 --- a/source/backend/challenge/modules/task/services/CreateTaskService.java +++ b/source/backend/challenge/modules/task/services/CreateTaskService.java @@ -3,7 +3,6 @@ import backend.challenge.modules.task.dtos.TaskDTO; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; - import javax.inject.Inject; import javax.inject.Singleton; diff --git a/source/backend/challenge/modules/task/services/DeleteTaskService.java b/source/backend/challenge/modules/task/services/DeleteTaskService.java index 5e6699b..71d27d4 100644 --- a/source/backend/challenge/modules/task/services/DeleteTaskService.java +++ b/source/backend/challenge/modules/task/services/DeleteTaskService.java @@ -2,7 +2,6 @@ import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.repositories.ITaskRepository; - import java.util.UUID; import javax.inject.Inject; import javax.inject.Singleton; diff --git a/source/backend/challenge/modules/task/services/IDeleteTaskService.java b/source/backend/challenge/modules/task/services/IDeleteTaskService.java index 2b54720..2bcd6d4 100644 --- a/source/backend/challenge/modules/task/services/IDeleteTaskService.java +++ b/source/backend/challenge/modules/task/services/IDeleteTaskService.java @@ -1,7 +1,6 @@ package backend.challenge.modules.task.services; import java.util.UUID; - import backend.challenge.modules.task.exceptions.TaskNotFound; public interface IDeleteTaskService { diff --git a/source/backend/challenge/modules/task/services/IRetrieveAllTasksService.java b/source/backend/challenge/modules/task/services/IRetrieveAllTasksService.java index 3e30258..6fa7490 100644 --- a/source/backend/challenge/modules/task/services/IRetrieveAllTasksService.java +++ b/source/backend/challenge/modules/task/services/IRetrieveAllTasksService.java @@ -1,7 +1,6 @@ package backend.challenge.modules.task.services; import backend.challenge.modules.task.models.Task; - import java.util.List; public interface IRetrieveAllTasksService { diff --git a/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java b/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java index fe0a1d5..f5b13da 100644 --- a/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java +++ b/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java @@ -1,7 +1,6 @@ package backend.challenge.modules.task.services; import java.util.UUID; - import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; diff --git a/source/backend/challenge/modules/task/services/IUpdateTaskService.java b/source/backend/challenge/modules/task/services/IUpdateTaskService.java index 6af41bd..ed3034c 100644 --- a/source/backend/challenge/modules/task/services/IUpdateTaskService.java +++ b/source/backend/challenge/modules/task/services/IUpdateTaskService.java @@ -1,6 +1,5 @@ package backend.challenge.modules.task.services; -import backend.challenge.modules.task.dtos.TaskDTO; import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable; import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; diff --git a/source/backend/challenge/modules/task/services/RetrieveAllTasksService.java b/source/backend/challenge/modules/task/services/RetrieveAllTasksService.java index af0ef15..18570de 100644 --- a/source/backend/challenge/modules/task/services/RetrieveAllTasksService.java +++ b/source/backend/challenge/modules/task/services/RetrieveAllTasksService.java @@ -2,7 +2,6 @@ import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; - import javax.inject.Inject; import javax.inject.Singleton; import java.util.List; diff --git a/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java b/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java index d713712..a29f35d 100644 --- a/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java +++ b/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java @@ -5,8 +5,6 @@ import javax.inject.Inject; import javax.inject.Singleton; -import javax.swing.plaf.OptionPaneUI; - import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; diff --git a/source/backend/challenge/modules/task/services/UpdateTaskService.java b/source/backend/challenge/modules/task/services/UpdateTaskService.java index 59bd2f7..5236d55 100644 --- a/source/backend/challenge/modules/task/services/UpdateTaskService.java +++ b/source/backend/challenge/modules/task/services/UpdateTaskService.java @@ -4,8 +4,6 @@ import javax.inject.Inject; import javax.inject.Singleton; - -import backend.challenge.modules.task.dtos.TaskDTO; import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable; import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; diff --git a/tests/Runner.java b/tests/Runner.java index eb2a736..48bd2c2 100644 --- a/tests/Runner.java +++ b/tests/Runner.java @@ -1,7 +1,6 @@ // package backend.challenge; import kikaha.core.test.KikahaServerRunner; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java b/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java index f7339c6..930a621 100644 --- a/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java +++ b/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java @@ -1,11 +1,8 @@ package backend.challenge.modules.task.controllers; import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.when; - import java.time.LocalDate; import java.util.List; import java.util.UUID; @@ -26,7 +23,6 @@ import backend.challenge.modules.task.services.IRetrieveTaskByIdService; import backend.challenge.modules.task.services.IUpdateTaskService; import kikaha.core.test.KikahaRunner; -import kikaha.urouting.api.DefaultResponse; import kikaha.urouting.api.Response; @RunWith(KikahaRunner.class) diff --git a/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java b/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java index 790eb87..4571062 100644 --- a/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java +++ b/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java @@ -4,15 +4,10 @@ import backend.challenge.modules.task.enums.TaskStatus; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; -import backend.challenge.modules.task.repositories.TaskRepository; import kikaha.core.test.KikahaRunner; - import static org.junit.Assert.assertEquals; - import java.time.LocalDate; import java.util.UUID; -import javax.inject.Inject; -import javax.inject.Singleton; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -52,9 +47,6 @@ public void shouldBeAbleToCreateANewTask() { assertEquals(expectedTask, result); Mockito.verify(taskRepository, Mockito.times(1)).create(taskDTO); - Task taskToUpdate = new Task( - - ); } } \ No newline at end of file diff --git a/tests/backend/challenge/modules/task/services/RetrieveAllTasksServiceTest.java b/tests/backend/challenge/modules/task/services/RetrieveAllTasksServiceTest.java index bd928e1..751761c 100644 --- a/tests/backend/challenge/modules/task/services/RetrieveAllTasksServiceTest.java +++ b/tests/backend/challenge/modules/task/services/RetrieveAllTasksServiceTest.java @@ -3,19 +3,12 @@ import backend.challenge.modules.task.enums.TaskStatus; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; -import backend.challenge.modules.task.repositories.TaskRepository; import kikaha.core.test.KikahaRunner; - import java.time.LocalDate; import java.util.List; import java.util.UUID; - -import javax.inject.Inject; -import javax.inject.Singleton; - import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; diff --git a/tests/backend/challenge/modules/task/services/RetrieveTaskByIdServiceTest.java b/tests/backend/challenge/modules/task/services/RetrieveTaskByIdServiceTest.java index 1ff2ade..f6fde0f 100644 --- a/tests/backend/challenge/modules/task/services/RetrieveTaskByIdServiceTest.java +++ b/tests/backend/challenge/modules/task/services/RetrieveTaskByIdServiceTest.java @@ -5,10 +5,7 @@ import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; import kikaha.core.test.KikahaRunner; - -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; - import java.time.LocalDate; import java.util.Optional; import java.util.UUID; diff --git a/tests/backend/challenge/modules/task/services/UpdateTaskProgressServiceTest.java b/tests/backend/challenge/modules/task/services/UpdateTaskProgressServiceTest.java index 9fc3e07..8b9a273 100644 --- a/tests/backend/challenge/modules/task/services/UpdateTaskProgressServiceTest.java +++ b/tests/backend/challenge/modules/task/services/UpdateTaskProgressServiceTest.java @@ -1,15 +1,10 @@ package backend.challenge.modules.task.services; import kikaha.core.test.KikahaRunner; - -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; - import java.time.LocalDate; import java.util.Optional; import java.util.UUID; - import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -19,8 +14,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; - -import backend.challenge.modules.task.dtos.TaskDTO; import backend.challenge.modules.task.dtos.TaskProgressDTO; import backend.challenge.modules.task.enums.TaskStatus; import backend.challenge.modules.task.exceptions.ProgressTaskUpdateNotAvailable; diff --git a/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java b/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java index c479f83..c276b3b 100644 --- a/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java +++ b/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java @@ -5,21 +5,12 @@ import backend.challenge.modules.task.exceptions.TaskNotFound; import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.repositories.ITaskRepository; -import backend.challenge.modules.task.repositories.TaskRepository; import kikaha.core.test.KikahaRunner; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; - import java.time.LocalDate; import java.util.Optional; import java.util.UUID; - -import javax.inject.Inject; - import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; From dc57504f36ccfd503c217d73863743aa51a26bc4 Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 13:03:07 -0300 Subject: [PATCH 18/22] refact: move prepStat to try header --- .../task/repositories/TaskRepository.java | 39 +++++++------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/source/backend/challenge/modules/task/repositories/TaskRepository.java b/source/backend/challenge/modules/task/repositories/TaskRepository.java index 98902dd..0349d94 100644 --- a/source/backend/challenge/modules/task/repositories/TaskRepository.java +++ b/source/backend/challenge/modules/task/repositories/TaskRepository.java @@ -30,9 +30,9 @@ public class TaskRepository implements ITaskRepository { @Override public Optional index(final UUID taskId) { - try (Connection connection = this.db.getConnection()) { - String sql = "SELECT id, title, description, status, progress, createdAt FROM tasks WHERE id = ?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); + String sql = "SELECT id, title, description, status, progress, createdAt FROM tasks WHERE id = ?"; + + try (PreparedStatement preparedStatement = this.db.getConnection().prepareStatement(sql)) { preparedStatement.setString(1, taskId.toString()); ResultSet resultSet = preparedStatement.executeQuery(); @@ -56,9 +56,9 @@ public Optional index(final UUID taskId) { @Override public List show() { - try (Connection connection = this.db.getConnection()) { - String sql = "SELECT id, title, description, status, progress, createdAt FROM tasks"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); + String sql = "SELECT id, title, description, status, progress, createdAt FROM tasks"; + + try (PreparedStatement preparedStatement = this.db.getConnection().prepareStatement(sql)) { ResultSet resultSet = preparedStatement.executeQuery(); List tasks = new ArrayList<>(); while (resultSet.next()) { @@ -68,7 +68,7 @@ public List show() { task.setDescription(resultSet.getString("description")); task.setStatus(TaskStatus.valueOf(resultSet.getString("status"))); task.setProgress(resultSet.getInt("progress")); - task.setCreatedAt( resultSet.getDate("createdAt").toLocalDate()); + task.setCreatedAt(resultSet.getDate("createdAt").toLocalDate()); tasks.add(task); } return tasks; @@ -80,9 +80,8 @@ public List show() { @Override public Task create(final TaskDTO taskDTO) { - try (Connection connection = this.db.getConnection()) { - String sql = "INSERT INTO tasks(id, title, description, status, progress, createdAt) VALUES(?, ?, ?, ?, ?, ?)"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); + String sql = "INSERT INTO tasks(id, title, description, status, progress, createdAt) VALUES(?, ?, ?, ?, ?, ?)"; + try (PreparedStatement preparedStatement = this.db.getConnection().prepareStatement(sql)) { Task newTask = new Task( UUID.randomUUID(), taskDTO.getTitle(), @@ -90,7 +89,6 @@ public Task create(final TaskDTO taskDTO) { 0, TaskStatus.PROGRESS, LocalDate.now() - ); preparedStatement.setString(1, newTask.getId().toString()); @@ -111,10 +109,8 @@ public Task create(final TaskDTO taskDTO) { @Override public Task update(final Task task) { - System.out.println(task.toString()); - try (Connection connection = this.db.getConnection()) { - String sql = "UPDATE tasks SET title = ?, description = ?, status = ?, progress = ? WHERE id = ?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); + String sql = "UPDATE tasks SET title = ?, description = ?, status = ?, progress = ? WHERE id = ?"; + try (PreparedStatement preparedStatement = this.db.getConnection().prepareStatement(sql)) { preparedStatement.setString(1, task.getTitle()); preparedStatement.setString(2, task.getDescription()); @@ -124,7 +120,6 @@ public Task update(final Task task) { preparedStatement.executeUpdate(); return task; - } catch (SQLException e) { throw new RuntimeException(e); } @@ -133,9 +128,8 @@ public Task update(final Task task) { @Override public void delete(final UUID taskId) { - try (Connection connection = this.db.getConnection()) { - String sql = "DELETE FROM tasks WHERE id=?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); + String sql = "DELETE FROM tasks WHERE id=?"; + try (PreparedStatement preparedStatement = this.db.getConnection().prepareStatement(sql)) { preparedStatement.setString(1, taskId.toString()); preparedStatement.executeUpdate(); @@ -147,16 +141,13 @@ public void delete(final UUID taskId) { @Override public boolean existsById(UUID id) { - try (Connection connection = this.db.getConnection()) { - String sql = "SELECT COUNT(*) FROM tasks WHERE id = ?"; - - PreparedStatement preparedStatement = connection.prepareStatement(sql); + String sql = "SELECT COUNT(*) FROM tasks WHERE id = ?"; + try (PreparedStatement preparedStatement = this.db.getConnection().prepareStatement(sql)) { preparedStatement.setString(1, id.toString()); ResultSet resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { int count = resultSet.getInt(1); resultSet.close(); - System.out.println(count > 0); return count > 0; } return false; From 6c8d763720f1f1f6ffe8bf02e631b60a4400b0dd Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 13:38:42 -0300 Subject: [PATCH 19/22] fix: task service --- .../task/services/UpdateTaskService.java | 18 +------ .../task/services/UpdateTaskServiceTest.java | 47 ++++++++++++++++--- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/source/backend/challenge/modules/task/services/UpdateTaskService.java b/source/backend/challenge/modules/task/services/UpdateTaskService.java index 5236d55..dc1c20c 100644 --- a/source/backend/challenge/modules/task/services/UpdateTaskService.java +++ b/source/backend/challenge/modules/task/services/UpdateTaskService.java @@ -22,29 +22,15 @@ public UpdateTaskService(final ITaskRepository iTaskRepository) { @Override public Task execute(Task taskUp) throws TaskNotFound, TaskAlterationNotAvailable { Optional taskOpt = iTaskRepository.index(taskUp.getId()); - if (taskOpt.isEmpty()) throw new TaskNotFound(); Task task = taskOpt.get(); - if (taskUp.getId() != null) - if (!taskUp.getId().equals(task.getId())) - throw new TaskAlterationNotAvailable(); - - if (taskUp.getCreatedAt() != null) - if (!taskUp.getCreatedAt().equals(task.getCreatedAt())) - throw new TaskAlterationNotAvailable(); - if (taskUp.getStatus() != null) - if (!taskUp.getStatus().equals(task.getStatus())) - throw new TaskAlterationNotAvailable(); - - if (taskUp.getProgress() != task.getProgress()) - throw new TaskAlterationNotAvailable(); - task.setDescription(taskUp.getDescription()); task.setTitle(taskUp.getTitle()); - return this.iTaskRepository.update(task); + this.iTaskRepository.update(task); + return task; } } diff --git a/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java b/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java index c276b3b..be39638 100644 --- a/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java +++ b/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java @@ -93,6 +93,7 @@ public void shouldBeAbleToUpdateTaskIfDescriptionModified() { @Test public void shouldNotBeAbleToUpdateTaskStatusManually() { id = UUID.fromString("ba27ee3a-5e41-4a87-b0fc-13e01e31cb0f"); + TaskStatus newStatus = TaskStatus.COMPLETE; task = new Task( id, "Algum titulo", @@ -108,16 +109,19 @@ public void shouldNotBeAbleToUpdateTaskStatusManually() { task.getTitle(), task.getDescription(), task.getProgress(), - task.getStatus(), + newStatus, task.getCreatedAt()); - taskToUpdate.setProgress(50); - Assert.assertThrows(TaskAlterationNotAvailable.class, () -> updateTaskService.execute(taskToUpdate)); + + Task taskUpdated = updateTaskService.execute(taskToUpdate); + Assert.assertNotEquals(newStatus, taskUpdated.getStatus()); + Assert.assertEquals(task.getStatus(), taskUpdated.getStatus()); } @Test - public void shouldBeThrowsExceptionIfProgressModified() { + public void shouldNotBeAbleToUpdateTaskProgressManually() { id = UUID.fromString("ba27ee3a-5e41-4a87-b0fc-13e01e31cb0f"); + int newProgress = 50; task = new Task( id, "Algum titulo", @@ -132,11 +136,40 @@ public void shouldBeThrowsExceptionIfProgressModified() { id, task.getTitle(), task.getDescription(), - task.getProgress(), + newProgress, task.getStatus(), task.getCreatedAt()); - taskToUpdate.setCreatedAt(LocalDate.of(2023, 10, 2)); - Assert.assertThrows(TaskAlterationNotAvailable.class, () -> updateTaskService.execute(taskToUpdate)); + + Task taskUpdated = updateTaskService.execute(taskToUpdate); + Assert.assertEquals(task.getProgress(), taskUpdated.getProgress()); + Assert.assertNotEquals(newProgress, taskUpdated.getProgress()); + + } + @Test + public void shouldNotBeAbleToUpdateTaskCreatAtManually() { + id = UUID.fromString("ba27ee3a-5e41-4a87-b0fc-13e01e31cb0f"); + LocalDate newCreatAt = LocalDate.of(2023, 2, 3); + task = new Task( + id, + "Algum titulo", + "Alguma descricao", + 0, + TaskStatus.PROGRESS, + LocalDate.of(2024, 4, 30)); + + Mockito.when(taskRepository.index(id)).thenReturn(Optional.of(task)); + + Task taskToUpdate = new Task( + id, + task.getTitle(), + task.getDescription(), + task.getProgress(), + task.getStatus(), + newCreatAt); + + Task taskUpdated = updateTaskService.execute(taskToUpdate); + Assert.assertEquals(task.getCreatedAt(), taskUpdated.getCreatedAt()); + Assert.assertNotEquals(newCreatAt, taskUpdated.getCreatedAt()); } From d3fdc706536796df28de9b27ff67e767070f6fd8 Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 17:58:13 -0300 Subject: [PATCH 20/22] fix: add UUID converter --- .../modules/task/config/UUIDConverter.java | 31 +++++++++++++++++++ .../http/controllers/TaskController.java | 9 +++--- .../controllers/TaskProgressController.java | 4 +-- 3 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 source/backend/challenge/modules/task/config/UUIDConverter.java diff --git a/source/backend/challenge/modules/task/config/UUIDConverter.java b/source/backend/challenge/modules/task/config/UUIDConverter.java new file mode 100644 index 0000000..6d33c03 --- /dev/null +++ b/source/backend/challenge/modules/task/config/UUIDConverter.java @@ -0,0 +1,31 @@ +package backend.challenge.modules.task.config; + +import java.util.UUID; + +import javax.enterprise.inject.Typed; +import javax.inject.Singleton; + +import com.fasterxml.jackson.annotation.JsonSubTypes.Type; + +import kikaha.urouting.api.AbstractConverter; +import kikaha.urouting.api.ConversionException; + +/** + * UUIDConverter + */ +@Singleton +@Typed(AbstractConverter.class) +public class UUIDConverter extends AbstractConverter{ + + @Override + public Object convert(String value) throws ConversionException { + + try { + return UUID.fromString(value); + } catch (Exception e) { + throw new RuntimeException("Falha ao converter " + value + " para UUID"); + } + } + + +} \ No newline at end of file diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java index beafb07..1ecd52a 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java @@ -7,7 +7,6 @@ import backend.challenge.modules.task.models.Task; import backend.challenge.modules.task.services.*; import kikaha.urouting.api.*; -import java.util.Optional; import java.util.UUID; import javax.inject.Inject; import javax.inject.Singleton; @@ -66,11 +65,11 @@ public Response create(TaskView taskView) { @PUT @Path("single/{taskId}") - public Response update(@PathParam("taskId") String taskId, TaskDTO taskDto) { + public Response update(@PathParam("taskId") UUID taskId, TaskDTO taskDto) { try { Task task = new Task(); - task.setId(UUID.fromString(taskId)); + task.setId(taskId); task.setDescription(taskDto.getDescription()); task.setTitle(taskDto.getTitle()); this.updateTaskService.execute(task); @@ -86,9 +85,9 @@ public Response update(@PathParam("taskId") String taskId, TaskDTO taskDto) { @DELETE @Path("single/{taskId}") - public Response delete(@PathParam("taskId") String taskId) { + public Response delete(@PathParam("taskId") UUID taskId) { try { - this.deleteTaskService.execute(UUID.fromString(taskId)); + this.deleteTaskService.execute(taskId); return DefaultResponse.ok(); } catch (TaskNotFound e) { return DefaultResponse.badRequest().entity(e.getMessage()); diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java index f129388..3c96358 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskProgressController.java @@ -24,8 +24,8 @@ public TaskProgressController(final IUpdateTaskProgressService updateTaskProgres @PUT @Path("single/{taskId}") - public Response updateProgress(@PathParam("taskId") String taskId, TaskProgressView taskProgressView) { - TaskProgressDTO progressDTO = TaskProgressDTO.create().setId(UUID.fromString(taskId)) + public Response updateProgress(@PathParam("taskId") UUID taskId, TaskProgressView taskProgressView) { + TaskProgressDTO progressDTO = TaskProgressDTO.create().setId(taskId) .setProgress(taskProgressView.getProgress()); try { From 5489c9b856a2e5bd9a1780124f66bf0ac6989898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A2nison=20dos=20Santos?= <90470248+danison00@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:04:05 -0300 Subject: [PATCH 21/22] Update UUIDConverter.java --- .../challenge/modules/task/config/UUIDConverter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/backend/challenge/modules/task/config/UUIDConverter.java b/source/backend/challenge/modules/task/config/UUIDConverter.java index 6d33c03..6f70485 100644 --- a/source/backend/challenge/modules/task/config/UUIDConverter.java +++ b/source/backend/challenge/modules/task/config/UUIDConverter.java @@ -6,7 +6,7 @@ import javax.inject.Singleton; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; - +import java.util.UUID; import kikaha.urouting.api.AbstractConverter; import kikaha.urouting.api.ConversionException; @@ -15,10 +15,10 @@ */ @Singleton @Typed(AbstractConverter.class) -public class UUIDConverter extends AbstractConverter{ +public class UUIDConverter extends AbstractConverter{ @Override - public Object convert(String value) throws ConversionException { + public UUID convert(String value) throws ConversionException { try { return UUID.fromString(value); @@ -28,4 +28,4 @@ public Object convert(String value) throws ConversionException { } -} \ No newline at end of file +} From 17060ed70b3a01165a3274185f685d1811f3543d Mon Sep 17 00:00:00 2001 From: danison Date: Tue, 30 Apr 2024 18:15:32 -0300 Subject: [PATCH 22/22] fix: change string to UUID --- .../modules/task/infra/http/controllers/TaskController.java | 4 ++-- .../modules/task/controllers/TaskControllerTest.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java index 1ecd52a..3077183 100644 --- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java +++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java @@ -42,10 +42,10 @@ public Response show() { @GET @Path("single/{taskId}") - public Response index(@PathParam("taskId") String taskId) { + public Response index(@PathParam("taskId") UUID taskId) { try { - Task taskOpt = this.retrieveTaskByIdService.execute(UUID.fromString(taskId)); + Task taskOpt = this.retrieveTaskByIdService.execute(taskId); return DefaultResponse.ok().entity(taskOpt); } catch (TaskNotFound e) { diff --git a/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java b/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java index 930a621..6f880fc 100644 --- a/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java +++ b/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java @@ -90,7 +90,7 @@ public void sholdReturnATaskById() { LocalDate.of(2024, 4, 30)); doReturn(task).when(retrieveTaskByIdService).execute(id); - Assert.assertEquals(task, controller.index(id.toString()).entity()); + Assert.assertEquals(task, controller.index(id).entity()); } @@ -99,7 +99,7 @@ public void sholdReturn400StatusIfIdNotExists() { UUID id = UUID.fromString("7a8853b1-7031-489a-b305-76e15b352154"); when(retrieveTaskByIdService.execute(id)).thenThrow(new TaskNotFound()); - Response response = controller.index(id.toString()); + Response response = controller.index(id); assertEquals(400, response.statusCode()); assertEquals(new TaskNotFound().getMessage(), response.entity());