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
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..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
@@ -78,6 +88,17 @@
javax.annotation-api
1.3.2
+
+
+
+ io.skullabs.kikaha
+ kikaha-db
+
+
+ mysql
+ mysql-connector-java
+ 8.0.33
+
@@ -111,4 +132,4 @@
-
+
\ No newline at end of file
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)
+);
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..6f70485
--- /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 java.util.UUID;
+import kikaha.urouting.api.AbstractConverter;
+import kikaha.urouting.api.ConversionException;
+
+/**
+ * UUIDConverter
+ */
+@Singleton
+@Typed(AbstractConverter.class)
+public class UUIDConverter extends AbstractConverter{
+
+ @Override
+ public UUID convert(String value) throws ConversionException {
+
+ try {
+ return UUID.fromString(value);
+ } catch (Exception e) {
+ throw new RuntimeException("Falha ao converter " + value + " para UUID");
+ }
+ }
+
+
+}
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/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/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/TaskAlterationNotAvailable.java b/source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvailable.java
new file mode 100644
index 0000000..f0f3f02
--- /dev/null
+++ b/source/backend/challenge/modules/task/exceptions/TaskAlterationNotAvailable.java
@@ -0,0 +1,7 @@
+package backend.challenge.modules.task.exceptions;
+
+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/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 6a06a52..3077183 100644
--- a/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java
+++ b/source/backend/challenge/modules/task/infra/http/controllers/TaskController.java
@@ -1,10 +1,13 @@
package backend.challenge.modules.task.infra.http.controllers;
+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.infra.http.views.TaskView;
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;
@@ -20,56 +23,75 @@ 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 IRetrieveTaskByIdService retrieveTaskByIdService,
+ final IUpdateTaskService iUpdateTaskService) {
this.createTaskService = createTaskService;
this.deleteTaskService = deleteTaskService;
this.retrieveAllTasksService = retrieveAllTasksService;
- this.retrieveTaskByIdService = null;
- this.updateTaskService = null;
+ this.retrieveTaskByIdService = retrieveTaskByIdService;
+ this.updateTaskService = iUpdateTaskService;
}
@GET
public Response show() {
- // TODO: Rota que lista todas as tarefas
-
- return DefaultResponse.ok().entity("Hello world");
+ 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") UUID taskId) {
+
+ try {
+ Task taskOpt = this.retrieveTaskByIdService.execute(taskId);
+ return DefaultResponse.ok().entity(taskOpt);
+
+ } catch (TaskNotFound e) {
+ return DefaultResponse.badRequest().entity(e.getMessage());
+ }
- return DefaultResponse.ok().entity("Hello world");
}
@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");
+ 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.
- */
+ public Response update(@PathParam("taskId") UUID taskId, TaskDTO taskDto) {
+
+ try {
+ Task task = new Task();
+ task.setId(taskId);
+ task.setDescription(taskDto.getDescription());
+ task.setTitle(taskDto.getTitle());
+ this.updateTaskService.execute(task);
+ return DefaultResponse.ok();
+ } catch (TaskAlterationNotAvailable| TaskNotFound e) {
+
+ return DefaultResponse.badRequest().entity(e.getMessage());
+ } catch (Exception e) {
+ return DefaultResponse.serverError();
+ }
- 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
-
- return DefaultResponse.ok().entity("Hello world");
+ public Response delete(@PathParam("taskId") UUID taskId) {
+ try {
+ 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 4a25520..3c96358 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,13 @@
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.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 +24,18 @@ 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`
- */
-
- return DefaultResponse.ok().entity("Hello world");
+ public Response updateProgress(@PathParam("taskId") UUID taskId, TaskProgressView taskProgressView) {
+ TaskProgressDTO progressDTO = TaskProgressDTO.create().setId(taskId)
+ .setProgress(taskProgressView.getProgress());
+
+ 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/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 123f10c..5ea60e4 100644
--- a/source/backend/challenge/modules/task/models/Task.java
+++ b/source/backend/challenge/modules/task/models/Task.java
@@ -1,23 +1,35 @@
package backend.challenge.modules.task.models;
import backend.challenge.modules.task.enums.TaskStatus;
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
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
+@NoArgsConstructor
+@ToString
+@EqualsAndHashCode
public class Task {
- private Long id;
+ private UUID id;
private String title;
private String description;
private int progress;
private TaskStatus status;
- private Date createdAt;
+ private LocalDate createdAt;
}
diff --git a/source/backend/challenge/modules/task/repositories/ITaskRepository.java b/source/backend/challenge/modules/task/repositories/ITaskRepository.java
index 527450a..4be5c0c 100644
--- a/source/backend/challenge/modules/task/repositories/ITaskRepository.java
+++ b/source/backend/challenge/modules/task/repositories/ITaskRepository.java
@@ -4,13 +4,16 @@
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);
- 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 c47c8fd..0349d94 100644
--- a/source/backend/challenge/modules/task/repositories/TaskRepository.java
+++ b/source/backend/challenge/modules/task/repositories/TaskRepository.java
@@ -1,45 +1,160 @@
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;
+import javax.inject.Inject;
import javax.inject.Singleton;
+import javax.sql.DataSource;
+
+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.ArrayList;
+import java.util.Date;
import java.util.List;
+import java.util.Optional;
+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
+ public Optional index(final UUID taskId) {
+ 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();
+ 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.setStatus(TaskStatus.valueOf(resultSet.getString("status")));
+ task.setProgress(resultSet.getInt("progress"));
+ task.setCreatedAt(resultSet.getDate("createdAt").toLocalDate());
+ return Optional.of(task);
+ }
+ return Optional.empty();
- return null;
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
}
@Override
public List show() {
- // TODO: Criar método responsável por retornar todas as tarefas
+ String sql = "SELECT id, title, description, status, progress, createdAt FROM tasks";
- return null;
+ try (PreparedStatement preparedStatement = this.db.getConnection().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.setStatus(TaskStatus.valueOf(resultSet.getString("status")));
+ task.setProgress(resultSet.getInt("progress"));
+ task.setCreatedAt(resultSet.getDate("createdAt").toLocalDate());
+ tasks.add(task);
+ }
+ return tasks;
+
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
}
@Override
public Task create(final TaskDTO taskDTO) {
- // TODO: Criar método responsável por criar uma tarefa
+ 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(),
+ taskDTO.getDescription(),
+ 0,
+ TaskStatus.PROGRESS,
+ LocalDate.now()
+ );
+
+ preparedStatement.setString(1, newTask.getId().toString());
+ preparedStatement.setString(2, newTask.getTitle());
+ preparedStatement.setString(3, newTask.getDescription());
+ preparedStatement.setString(4, newTask.getStatus().name());
+ preparedStatement.setInt(5, newTask.getProgress());
+ preparedStatement.setDate(6, java.sql.Date.valueOf(newTask.getCreatedAt()));
+ preparedStatement.executeUpdate();
+
+ return newTask;
+
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
- return null;
}
@Override
public Task update(final Task task) {
- // TODO: Criar método responsável por atualizar uma tarefa
+ 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());
+ preparedStatement.setString(3, task.getStatus().name());
+ preparedStatement.setInt(4, task.getProgress());
+ preparedStatement.setString(5, task.getId().toString());
+ preparedStatement.executeUpdate();
+
+ return task;
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void delete(final UUID taskId) {
+
+ String sql = "DELETE FROM tasks WHERE id=?";
+ try (PreparedStatement preparedStatement = this.db.getConnection().prepareStatement(sql)) {
+ preparedStatement.setString(1, taskId.toString());
+ preparedStatement.executeUpdate();
+
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
- return null;
}
@Override
- public void delete(final Long taskId) {
- // TODO: Criar método responsável por deletar tarefa por id
+ public boolean existsById(UUID id) {
+ 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();
+ return count > 0;
+ }
+ return false;
+
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
}
diff --git a/source/backend/challenge/modules/task/services/CreateTaskService.java b/source/backend/challenge/modules/task/services/CreateTaskService.java
index 46b144b..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;
@@ -19,9 +18,7 @@ public CreateTaskService(final ITaskRepository taskRepository) {
@Override
public Task execute(TaskDTO taskDTO) {
- // TODO: Criar serviço responsável por criar uma tarefa
-
- return null;
+ return taskRepository.create(taskDTO);
}
}
diff --git a/source/backend/challenge/modules/task/services/DeleteTaskService.java b/source/backend/challenge/modules/task/services/DeleteTaskService.java
index c957d70..71d27d4 100644
--- a/source/backend/challenge/modules/task/services/DeleteTaskService.java
+++ b/source/backend/challenge/modules/task/services/DeleteTaskService.java
@@ -1,7 +1,8 @@
package backend.challenge.modules.task.services;
+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;
@@ -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) throws TaskNotFound{
+
+ 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 6b031ac..2bcd6d4 100644
--- a/source/backend/challenge/modules/task/services/IDeleteTaskService.java
+++ b/source/backend/challenge/modules/task/services/IDeleteTaskService.java
@@ -1,8 +1,10 @@
package backend.challenge.modules.task.services;
+import java.util.UUID;
+import backend.challenge.modules.task.exceptions.TaskNotFound;
public interface IDeleteTaskService {
- void execute(Long taskId);
+ void execute(UUID taskId) throws TaskNotFound;
}
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 192e28c..f5b13da 100644
--- a/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java
+++ b/source/backend/challenge/modules/task/services/IRetrieveTaskByIdService.java
@@ -1,9 +1,11 @@
package backend.challenge.modules.task.services;
+import java.util.UUID;
+import backend.challenge.modules.task.exceptions.TaskNotFound;
import backend.challenge.modules.task.models.Task;
public interface IRetrieveTaskByIdService {
- Task execute(Long taskId);
+ Task execute(UUID taskId) throws TaskNotFound;
}
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 3da8340..ed3034c 100644
--- a/source/backend/challenge/modules/task/services/IUpdateTaskService.java
+++ b/source/backend/challenge/modules/task/services/IUpdateTaskService.java
@@ -1,9 +1,11 @@
package backend.challenge.modules.task.services;
+import backend.challenge.modules.task.exceptions.TaskAlterationNotAvailable;
+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, TaskAlterationNotAvailable;
}
diff --git a/source/backend/challenge/modules/task/services/RetrieveAllTasksService.java b/source/backend/challenge/modules/task/services/RetrieveAllTasksService.java
index 52a4149..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;
@@ -19,9 +18,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();
}
}
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..a29f35d
--- /dev/null
+++ b/source/backend/challenge/modules/task/services/RetrieveTaskByIdService.java
@@ -0,0 +1,29 @@
+package backend.challenge.modules.task.services;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import backend.challenge.modules.task.exceptions.TaskNotFound;
+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 Task execute(UUID taskId) throws TaskNotFound{
+ Optional taskOpt = this.taskRepository.index(taskId);
+ if(taskOpt.isEmpty()) throw new TaskNotFound();
+ return taskOpt.get();
+ }
+
+
+}
\ No newline at end of file
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..9746921
--- /dev/null
+++ b/source/backend/challenge/modules/task/services/UpdateTaskProgressService.java
@@ -0,0 +1,47 @@
+package backend.challenge.modules.task.services;
+
+import java.util.Optional;
+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 {
+
+ private final ITaskRepository iTaskRepository;
+
+ @Inject
+ public UpdateTaskProgressService(ITaskRepository iTaskRepository) {
+ this.iTaskRepository = iTaskRepository;
+ }
+
+ @Override
+ public Task execute(TaskProgressDTO taskProgressDTO) throws TaskAlterationNotAvailable, TaskNotFound {
+
+ if (taskProgressDTO.getProgress() > 100 || taskProgressDTO.getProgress() < 0) {
+ throw new ProgressTaskUpdateNotAvailable();
+ }
+
+ Optional taskOpt = iTaskRepository.index(taskProgressDTO.getId());
+ if (taskOpt.isEmpty())
+ throw new TaskNotFound();
+
+ 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
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..dc1c20c
--- /dev/null
+++ b/source/backend/challenge/modules/task/services/UpdateTaskService.java
@@ -0,0 +1,36 @@
+package backend.challenge.modules.task.services;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+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 UpdateTaskService implements IUpdateTaskService {
+
+ private final ITaskRepository iTaskRepository;
+
+ @Inject
+ public UpdateTaskService(final ITaskRepository iTaskRepository) {
+ this.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();
+
+ task.setDescription(taskUp.getDescription());
+ task.setTitle(taskUp.getTitle());
+ this.iTaskRepository.update(task);
+ return task;
+
+ }
+}
diff --git a/tests/Runner.java b/tests/Runner.java
index 1ff4b19..48bd2c2 100644
--- a/tests/Runner.java
+++ b/tests/Runner.java
@@ -1,7 +1,6 @@
-package backend.challenge;
+// 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
new file mode 100644
index 0000000..6f880fc
--- /dev/null
+++ b/tests/backend/challenge/modules/task/controllers/TaskControllerTest.java
@@ -0,0 +1,107 @@
+package backend.challenge.modules.task.controllers;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+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.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).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);
+ 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 684dc44..4571062 100644
--- a/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java
+++ b/tests/backend/challenge/modules/task/services/CreateTaskServiceTest.java
@@ -1,32 +1,52 @@
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 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);
+ }
}
\ 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..751761c 100644
--- a/tests/backend/challenge/modules/task/services/RetrieveAllTasksServiceTest.java
+++ b/tests/backend/challenge/modules/task/services/RetrieveAllTasksServiceTest.java
@@ -1,31 +1,67 @@
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 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..f6fde0f 100644
--- a/tests/backend/challenge/modules/task/services/RetrieveTaskByIdServiceTest.java
+++ b/tests/backend/challenge/modules/task/services/RetrieveTaskByIdServiceTest.java
@@ -1,24 +1,62 @@
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.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..8b9a273 100644
--- a/tests/backend/challenge/modules/task/services/UpdateTaskProgressServiceTest.java
+++ b/tests/backend/challenge/modules/task/services/UpdateTaskProgressServiceTest.java
@@ -1,27 +1,147 @@
package backend.challenge.modules.task.services;
-
import kikaha.core.test.KikahaRunner;
+import static org.mockito.Mockito.doReturn;
+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.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..be39638 100644
--- a/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java
+++ b/tests/backend/challenge/modules/task/services/UpdateTaskServiceTest.java
@@ -1,44 +1,186 @@
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 java.time.LocalDate;
+import java.util.Optional;
+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.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");
+ TaskStatus newStatus = TaskStatus.COMPLETE;
+ 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(),
+ newStatus,
+ task.getCreatedAt());
+
+ Task taskUpdated = updateTaskService.execute(taskToUpdate);
+ Assert.assertNotEquals(newStatus, taskUpdated.getStatus());
+ Assert.assertEquals(task.getStatus(), taskUpdated.getStatus());
+
+ }
+
+ @Test
+ public void shouldNotBeAbleToUpdateTaskProgressManually() {
+ id = UUID.fromString("ba27ee3a-5e41-4a87-b0fc-13e01e31cb0f");
+ int newProgress = 50;
+ 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(),
+ newProgress,
+ task.getStatus(),
+ task.getCreatedAt());
+
+ 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());
- */
}
+ @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