diff --git a/maven-spring/.gitignore b/maven-spring/.gitignore index 549e00a..9ad541b 100644 --- a/maven-spring/.gitignore +++ b/maven-spring/.gitignore @@ -3,6 +3,7 @@ target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ !**/src/test/**/target/ +**/.DS_Store ### STS ### .apt_generated diff --git a/maven-spring/pom.xml b/maven-spring/pom.xml index 7c9c33a..2def633 100644 --- a/maven-spring/pom.xml +++ b/maven-spring/pom.xml @@ -11,7 +11,7 @@ com.poliveira javaverse - 0.0.1 + 0.1.0 javaverse JavaVerse macro project for mutiverse of Java @@ -35,13 +35,13 @@ org.springframework.boot spring-boot-starter-web - 3.3.4 + 3.4.4 org.springframework.boot spring-boot-starter-data-jpa - 3.3.4 + 3.4.4 @@ -53,7 +53,19 @@ org.postgresql postgresql - 42.7.4 + 42.7.5 + + + + org.flywaydb + flyway-core + 11.7.2 + + + + org.flywaydb + flyway-database-postgresql + 11.7.2 diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/controller/.DS_Store b/maven-spring/src/main/java/com/poliveira/javaverse/controller/.DS_Store deleted file mode 100644 index c77904a..0000000 Binary files a/maven-spring/src/main/java/com/poliveira/javaverse/controller/.DS_Store and /dev/null differ diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/controller/HelloWorld.java b/maven-spring/src/main/java/com/poliveira/javaverse/controllers/HelloWorld.java similarity index 88% rename from maven-spring/src/main/java/com/poliveira/javaverse/controller/HelloWorld.java rename to maven-spring/src/main/java/com/poliveira/javaverse/controllers/HelloWorld.java index 5210546..2c1851f 100644 --- a/maven-spring/src/main/java/com/poliveira/javaverse/controller/HelloWorld.java +++ b/maven-spring/src/main/java/com/poliveira/javaverse/controllers/HelloWorld.java @@ -1,4 +1,4 @@ -package com.poliveira.javaverse.controller; +package com.poliveira.javaverse.controllers; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/controller/TaskController.java b/maven-spring/src/main/java/com/poliveira/javaverse/controllers/TaskController.java similarity index 78% rename from maven-spring/src/main/java/com/poliveira/javaverse/controller/TaskController.java rename to maven-spring/src/main/java/com/poliveira/javaverse/controllers/TaskController.java index b6b0834..d72f1a5 100644 --- a/maven-spring/src/main/java/com/poliveira/javaverse/controller/TaskController.java +++ b/maven-spring/src/main/java/com/poliveira/javaverse/controllers/TaskController.java @@ -1,12 +1,13 @@ -package com.poliveira.javaverse.controller; +package com.poliveira.javaverse.controllers; import static org.springframework.http.HttpStatus.CREATED; -import com.poliveira.javaverse.model.SimpleTaskVO; -import com.poliveira.javaverse.model.SuccessVO; -import com.poliveira.javaverse.model.TaskVO; -import com.poliveira.javaverse.service.TaskService; +import com.poliveira.javaverse.models.SimpleTaskVO; +import com.poliveira.javaverse.models.SuccessVO; +import com.poliveira.javaverse.models.TaskVO; +import com.poliveira.javaverse.services.TaskService; import java.util.List; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -32,17 +33,17 @@ public TaskVO createTask(@RequestBody SimpleTaskVO taskVO) { } @GetMapping("/{id}") - public TaskVO readTask(@PathVariable Long id) { + public TaskVO readTask(@PathVariable UUID id) { return taskService.getTaskById(id); } @PatchMapping("/{id}") - public TaskVO updateTask(@PathVariable Long id, @RequestBody SimpleTaskVO taskVO) { + public TaskVO updateTask(@PathVariable UUID id, @RequestBody SimpleTaskVO taskVO) { return taskService.updateTask(id, taskVO); } @DeleteMapping("/{id}") - public SuccessVO deleteTask(@PathVariable Long id) { + public SuccessVO deleteTask(@PathVariable UUID id) { return SuccessVO.builder() .success(taskService.deleteTask(id)) .message("Task deleted successfully") diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/entities/StatusEntity.java b/maven-spring/src/main/java/com/poliveira/javaverse/entities/StatusEntity.java new file mode 100644 index 0000000..fbf56cc --- /dev/null +++ b/maven-spring/src/main/java/com/poliveira/javaverse/entities/StatusEntity.java @@ -0,0 +1,30 @@ +package com.poliveira.javaverse.entities; + +import jakarta.persistence.*; +import java.time.LocalDateTime; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "status", schema = "public") +public class StatusEntity { + @Id + @Column(columnDefinition = "UUID") + private UUID id; + + @Column(nullable = false) + private String name; + + @Column( + name = "created_at", + nullable = false, + columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") + private LocalDateTime createdAt; +} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/entities/TaskEntity.java b/maven-spring/src/main/java/com/poliveira/javaverse/entities/TaskEntity.java new file mode 100644 index 0000000..a56adfc --- /dev/null +++ b/maven-spring/src/main/java/com/poliveira/javaverse/entities/TaskEntity.java @@ -0,0 +1,35 @@ +package com.poliveira.javaverse.entities; + +import jakarta.persistence.*; +import java.time.LocalDateTime; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "tasks") +public class TaskEntity { + + @Id @GeneratedValue private UUID id; + + @Column(nullable = false) + private String name; + + private String description; + + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @Column(name = "updated_at") + private LocalDateTime updatedAt; + + @ManyToOne + @JoinColumn(name = "status_id") + private StatusEntity status; +} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/model/SimpleTaskVO.java b/maven-spring/src/main/java/com/poliveira/javaverse/model/SimpleTaskVO.java deleted file mode 100644 index e2c4f2f..0000000 --- a/maven-spring/src/main/java/com/poliveira/javaverse/model/SimpleTaskVO.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.poliveira.javaverse.model; - -import static jakarta.persistence.GenerationType.IDENTITY; - -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Entity -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class SimpleTaskVO { - - @Id - @GeneratedValue(strategy = IDENTITY) - private long id; - - private String title; - private String description; -} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/model/Status.java b/maven-spring/src/main/java/com/poliveira/javaverse/model/Status.java deleted file mode 100644 index 0b2268e..0000000 --- a/maven-spring/src/main/java/com/poliveira/javaverse/model/Status.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.poliveira.javaverse.model; - -import static lombok.AccessLevel.PRIVATE; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor(access = PRIVATE) -public enum Status { - TODO("To Do"), - IN_PROGRESS("In Progress"), - DONE("Done"); - - private final String status; -} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/model/TaskVO.java b/maven-spring/src/main/java/com/poliveira/javaverse/model/TaskVO.java deleted file mode 100644 index aecbf77..0000000 --- a/maven-spring/src/main/java/com/poliveira/javaverse/model/TaskVO.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.poliveira.javaverse.model; - -import static jakarta.persistence.GenerationType.IDENTITY; - -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Entity -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class TaskVO { - - @Id - @GeneratedValue(strategy = IDENTITY) - private long id; - - private String title; - private String description; - private Status status; - private long createdAt; - private long updatedAt; -} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/models/SimpleTaskVO.java b/maven-spring/src/main/java/com/poliveira/javaverse/models/SimpleTaskVO.java new file mode 100644 index 0000000..8a4504b --- /dev/null +++ b/maven-spring/src/main/java/com/poliveira/javaverse/models/SimpleTaskVO.java @@ -0,0 +1,16 @@ +package com.poliveira.javaverse.models; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SimpleTaskVO { + + private String name; + private String description; +} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/models/Status.java b/maven-spring/src/main/java/com/poliveira/javaverse/models/Status.java new file mode 100644 index 0000000..4fabeb2 --- /dev/null +++ b/maven-spring/src/main/java/com/poliveira/javaverse/models/Status.java @@ -0,0 +1,26 @@ +package com.poliveira.javaverse.models; + +import static lombok.AccessLevel.PRIVATE; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor(access = PRIVATE) +public enum Status { + OPEN("Open"), + IN_PROGRESS("In Progress"), + BLOCKED("Blocked"), + DONE("Done"); + + private final String status; + + public static Status from(String status) { + for (Status s : Status.values()) { + if (s.getStatus().equalsIgnoreCase(status)) { + return s; + } + } + throw new IllegalArgumentException("Invalid status: " + status); + } +} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/model/SuccessVO.java b/maven-spring/src/main/java/com/poliveira/javaverse/models/SuccessVO.java similarity index 86% rename from maven-spring/src/main/java/com/poliveira/javaverse/model/SuccessVO.java rename to maven-spring/src/main/java/com/poliveira/javaverse/models/SuccessVO.java index 3caca11..6feb394 100644 --- a/maven-spring/src/main/java/com/poliveira/javaverse/model/SuccessVO.java +++ b/maven-spring/src/main/java/com/poliveira/javaverse/models/SuccessVO.java @@ -1,4 +1,4 @@ -package com.poliveira.javaverse.model; +package com.poliveira.javaverse.models; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/models/TaskVO.java b/maven-spring/src/main/java/com/poliveira/javaverse/models/TaskVO.java new file mode 100644 index 0000000..34de51a --- /dev/null +++ b/maven-spring/src/main/java/com/poliveira/javaverse/models/TaskVO.java @@ -0,0 +1,21 @@ +package com.poliveira.javaverse.models; + +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class TaskVO { + + private UUID id; + private String name; + private String description; + private Status status; + private long createdAt; + private long updatedAt; +} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/processors/MappingService.java b/maven-spring/src/main/java/com/poliveira/javaverse/processors/MappingService.java new file mode 100644 index 0000000..a42bbc0 --- /dev/null +++ b/maven-spring/src/main/java/com/poliveira/javaverse/processors/MappingService.java @@ -0,0 +1,46 @@ +package com.poliveira.javaverse.processors; + +import com.poliveira.javaverse.entities.StatusEntity; +import com.poliveira.javaverse.entities.TaskEntity; +import com.poliveira.javaverse.models.Status; +import com.poliveira.javaverse.models.TaskVO; +import com.poliveira.javaverse.utils.TimeUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MappingService { + + private final TimeUtils timeUtils; + + public Status toVO(StatusEntity statusEntity) { + return Status.from(statusEntity.getName()); + } + + public StatusEntity toEntity(Status status) { + return StatusEntity.builder().name(status.name()).build(); + } + + public TaskEntity toEntity(TaskVO taskVO) { + return TaskEntity.builder() + .id(taskVO.getId()) + .name(taskVO.getName()) + .description(taskVO.getDescription()) + .createdAt(timeUtils.toLocalDateTime(taskVO.getCreatedAt())) + .updatedAt(timeUtils.toLocalDateTime(taskVO.getUpdatedAt())) + .status(toEntity(taskVO.getStatus())) + .build(); + } + + public TaskVO toVO(TaskEntity taskEntity) { + return TaskVO.builder() + .id(taskEntity.getId()) + .name(taskEntity.getName()) + .description(taskEntity.getDescription()) + .status(toVO(taskEntity.getStatus())) + .createdAt(timeUtils.toEpochMilli(taskEntity.getCreatedAt())) + .updatedAt(timeUtils.toEpochMilli(taskEntity.getUpdatedAt())) + .build(); + } +} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/repositories/TaskRepository.java b/maven-spring/src/main/java/com/poliveira/javaverse/repositories/TaskRepository.java new file mode 100644 index 0000000..61dcf3d --- /dev/null +++ b/maven-spring/src/main/java/com/poliveira/javaverse/repositories/TaskRepository.java @@ -0,0 +1,9 @@ +package com.poliveira.javaverse.repositories; + +import com.poliveira.javaverse.entities.TaskEntity; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface TaskRepository extends JpaRepository {} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/repository/TaskRepository.java b/maven-spring/src/main/java/com/poliveira/javaverse/repository/TaskRepository.java deleted file mode 100644 index 51fcfd4..0000000 --- a/maven-spring/src/main/java/com/poliveira/javaverse/repository/TaskRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.poliveira.javaverse.repository; - -import com.poliveira.javaverse.model.TaskVO; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface TaskRepository extends JpaRepository { - - // Custom query methods can be defined here if needed - // For example, to find tasks by status: - // List findByStatus(Status status); - -} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/service/TaskService.java b/maven-spring/src/main/java/com/poliveira/javaverse/service/TaskService.java deleted file mode 100644 index c07f9fa..0000000 --- a/maven-spring/src/main/java/com/poliveira/javaverse/service/TaskService.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.poliveira.javaverse.service; - -import static com.poliveira.javaverse.model.Status.TODO; -import static java.lang.System.currentTimeMillis; -import static java.util.Objects.nonNull; - -import com.poliveira.javaverse.model.SimpleTaskVO; -import com.poliveira.javaverse.model.TaskVO; -import com.poliveira.javaverse.repository.TaskRepository; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class TaskService { - - private final TaskRepository taskRepository; - - public List getAllTasks() { - return taskRepository.findAll(); - } - - public TaskVO getTaskById(Long id) { - return taskRepository.findById(id).orElse(null); - } - - public TaskVO createTask(SimpleTaskVO simpleTaskVO) { - TaskVO task = - TaskVO.builder() - .title(simpleTaskVO.getTitle()) - .description(simpleTaskVO.getDescription()) - .status(TODO) - .createdAt(currentTimeMillis()) - .updatedAt(currentTimeMillis()) - .build(); - return taskRepository.save(task); - } - - public TaskVO updateTask(Long id, SimpleTaskVO task) { - TaskVO existingTask = taskRepository.findById(id).orElse(null); - if (nonNull(existingTask)) { - existingTask.setTitle(task.getTitle()); - existingTask.setDescription(task.getDescription()); - existingTask.setUpdatedAt(currentTimeMillis()); - return taskRepository.save(existingTask); - } - return null; - } - - public boolean deleteTask(Long id) { - try { - taskRepository.deleteById(id); - return true; - } catch (Exception e) { - return false; - } - } -} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/services/TaskService.java b/maven-spring/src/main/java/com/poliveira/javaverse/services/TaskService.java new file mode 100644 index 0000000..acb08d6 --- /dev/null +++ b/maven-spring/src/main/java/com/poliveira/javaverse/services/TaskService.java @@ -0,0 +1,62 @@ +package com.poliveira.javaverse.services; + +import static com.poliveira.javaverse.models.Status.OPEN; +import static java.lang.System.currentTimeMillis; + +import com.poliveira.javaverse.entities.TaskEntity; +import com.poliveira.javaverse.models.SimpleTaskVO; +import com.poliveira.javaverse.models.TaskVO; +import com.poliveira.javaverse.processors.MappingService; +import com.poliveira.javaverse.repositories.TaskRepository; +import java.util.List; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class TaskService { + + private final TaskRepository taskRepository; + private final MappingService mappingService; + + public List getAllTasks() { + return taskRepository.findAll().stream().map(mappingService::toVO).toList(); + } + + public TaskVO getTaskById(UUID id) { + TaskEntity taskEntity = taskRepository.findById(id).orElseThrow(); + return mappingService.toVO(taskEntity); + } + + public TaskVO createTask(SimpleTaskVO simpleTaskVO) { + TaskVO task = + TaskVO.builder() + .name(simpleTaskVO.getName()) + .description(simpleTaskVO.getDescription()) + .status(OPEN) + .createdAt(currentTimeMillis()) + .updatedAt(currentTimeMillis()) + .build(); + TaskEntity taskEntity = mappingService.toEntity(task); + return mappingService.toVO(taskRepository.save(taskEntity)); + } + + public TaskVO updateTask(UUID id, SimpleTaskVO task) { + TaskEntity existingTask = taskRepository.findById(id).orElseThrow(); + TaskVO taskVo = mappingService.toVO(existingTask); + taskVo.setName(task.getName()); + taskVo.setDescription(task.getDescription()); + taskVo.setUpdatedAt(currentTimeMillis()); + return mappingService.toVO(taskRepository.save(mappingService.toEntity(taskVo))); + } + + public boolean deleteTask(UUID id) { + try { + taskRepository.deleteById(id); + return true; + } catch (Exception e) { + return false; + } + } +} diff --git a/maven-spring/src/main/java/com/poliveira/javaverse/utils/TimeUtils.java b/maven-spring/src/main/java/com/poliveira/javaverse/utils/TimeUtils.java new file mode 100644 index 0000000..a61f4e9 --- /dev/null +++ b/maven-spring/src/main/java/com/poliveira/javaverse/utils/TimeUtils.java @@ -0,0 +1,23 @@ +package com.poliveira.javaverse.utils; + +import static java.lang.System.currentTimeMillis; +import static java.time.ZoneOffset.UTC; + +import java.time.LocalDateTime; +import java.util.Objects; +import org.springframework.stereotype.Service; + +@Service +public class TimeUtils { + public LocalDateTime toLocalDateTime(long epochSecond) { + return LocalDateTime.ofEpochSecond(epochSecond / 1000, 0, UTC); + } + + public long toEpochMilli(LocalDateTime localDateTime) { + if (Objects.isNull(localDateTime)) { + return currentTimeMillis(); + } + + return localDateTime.toEpochSecond(UTC) * 1000; + } +} diff --git a/maven-spring/src/main/resources/application-dev.yml b/maven-spring/src/main/resources/application-dev.yml index 56d6bb7..2cc43ae 100644 --- a/maven-spring/src/main/resources/application-dev.yml +++ b/maven-spring/src/main/resources/application-dev.yml @@ -1,16 +1,3 @@ spring: - application: - name: javaverse - datasource: - url: jdbc:postgresql://localhost:5432/tasks - username: myuser - password: mypassword - driver-class-name: "org.postgresql.Driver" - - jpa: - hibernate: - ddl-auto: update - -server: - port: 5190 + url: jdbc:postgresql://localhost:5432/tasks \ No newline at end of file diff --git a/maven-spring/src/main/resources/application.yml b/maven-spring/src/main/resources/application.yml index 9a73bc5..38a8999 100644 --- a/maven-spring/src/main/resources/application.yml +++ b/maven-spring/src/main/resources/application.yml @@ -12,5 +12,9 @@ spring: hibernate: ddl-auto: update + flyway: + enabled: true + baseline-on-migrate: true + server: port: 5190 diff --git a/maven-spring/src/main/resources/db/migration/V1__create_tasks.sql b/maven-spring/src/main/resources/db/migration/V1__create_tasks.sql new file mode 100644 index 0000000..83119e0 --- /dev/null +++ b/maven-spring/src/main/resources/db/migration/V1__create_tasks.sql @@ -0,0 +1,7 @@ +CREATE TABLE tasks +( + id UUID PRIMARY KEY NOT NULL, + name VARCHAR(255) NOT NULL, + description TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); \ No newline at end of file diff --git a/maven-spring/src/main/resources/db/migration/V2__add_status.sql b/maven-spring/src/main/resources/db/migration/V2__add_status.sql new file mode 100644 index 0000000..4cd44fa --- /dev/null +++ b/maven-spring/src/main/resources/db/migration/V2__add_status.sql @@ -0,0 +1,10 @@ +CREATE TABLE status +( + id UUID PRIMARY KEY NOT NULL, + name VARCHAR(255) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +ALTER TABLE tasks +ADD COLUMN status_id UUID, +ADD CONSTRAINT fk_status FOREIGN KEY (status_id) REFERENCES status(id); \ No newline at end of file diff --git a/maven-spring/src/main/resources/db/migration/V3__insert_data.sql b/maven-spring/src/main/resources/db/migration/V3__insert_data.sql new file mode 100644 index 0000000..c21f478 --- /dev/null +++ b/maven-spring/src/main/resources/db/migration/V3__insert_data.sql @@ -0,0 +1,10 @@ +INSERT INTO status (id, name) +VALUES + ('D6127F26-55B6-408D-A010-322FBEC9B1B1', 'Open'), + ('C78BDBC7-E2D6-4C39-AF32-FDDAC2DC9004', 'In Progress'), + ('31BD3B30-FFCC-44C5-B24B-F169E28FC138', 'Blocked'), + ('9CD7D8F8-980B-4344-9A6C-44DA84A72974', 'Done'); + +-- create new task with status in progress +INSERT INTO tasks (id, name, description, created_at, status_id) +VALUES ('525B5626-D373-4023-A026-FBA5642EAEF0', 'Create CLI', 'This todo list as CLI', now(), 'C78BDBC7-E2D6-4C39-AF32-FDDAC2DC9004'); \ No newline at end of file diff --git a/maven-spring/src/test/java/com/poliveira/javaverse/TasksRepositoryTest.java b/maven-spring/src/test/java/com/poliveira/javaverse/TasksRepositoryTest.java index 9958d5c..742818c 100644 --- a/maven-spring/src/test/java/com/poliveira/javaverse/TasksRepositoryTest.java +++ b/maven-spring/src/test/java/com/poliveira/javaverse/TasksRepositoryTest.java @@ -1,16 +1,18 @@ package com.poliveira.javaverse; -import static com.poliveira.javaverse.model.Status.TODO; import static java.lang.System.currentTimeMillis; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import com.poliveira.javaverse.model.TaskVO; -import com.poliveira.javaverse.repository.TaskRepository; +import com.poliveira.javaverse.entities.StatusEntity; +import com.poliveira.javaverse.entities.TaskEntity; +import com.poliveira.javaverse.repositories.TaskRepository; +import com.poliveira.javaverse.utils.TimeUtils; import java.util.List; +import java.util.Optional; +import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -22,108 +24,123 @@ public class TasksRepositoryTest { @Mock private TaskRepository taskRepository; + private TimeUtils timeUtils = new TimeUtils(); + private StatusEntity open = + StatusEntity.builder() + .id(UUID.fromString("D6127F26-55B6-408D-A010-322FBEC9B1B1")) + .name("Open") + .build(); + @BeforeEach public void setUp() {} @Test public void testCreateTask() { - TaskVO mockTaskVO = - TaskVO.builder() - .id(1L) - .title("New Task") + UUID taskId = UUID.randomUUID(); + TaskEntity mockTaskEntity = + TaskEntity.builder() + .id(taskId) + .name("New Task") .description("This is a new task") - .status(TODO) - .createdAt(currentTimeMillis()) - .updatedAt(currentTimeMillis()) + .status(open) + .status(open) + .status(open) + .createdAt(timeUtils.toLocalDateTime(currentTimeMillis())) + .updatedAt(timeUtils.toLocalDateTime(currentTimeMillis())) .build(); - when(taskRepository.save(any(TaskVO.class))).thenReturn(mockTaskVO); + when(taskRepository.save(any(TaskEntity.class))).thenReturn(mockTaskEntity); - TaskVO taskVO = taskRepository.save(mockTaskVO); - assertTrue(taskVO.getId() > 0); - assertEquals(mockTaskVO.getTitle(), taskVO.getTitle()); - assertEquals(mockTaskVO.getDescription(), taskVO.getDescription()); - assertEquals(TODO, taskVO.getStatus()); + TaskEntity taskEntity = taskRepository.save(mockTaskEntity); + assertEquals(taskEntity.getId(), taskId); + assertEquals(mockTaskEntity.getName(), taskEntity.getName()); + assertEquals(mockTaskEntity.getDescription(), taskEntity.getDescription()); + assertEquals(open.getId(), taskEntity.getStatus().getId()); + assertEquals(open.getName(), taskEntity.getStatus().getName()); } @Test public void testFindAllTasks() { - TaskVO task1 = - TaskVO.builder() - .id(1L) - .title("Task 1") + UUID taskId1 = UUID.randomUUID(); + TaskEntity task1 = + TaskEntity.builder() + .id(taskId1) + .name("Task 1") .description("Description 1") - .status(TODO) - .createdAt(currentTimeMillis()) - .updatedAt(currentTimeMillis()) + .createdAt(timeUtils.toLocalDateTime(currentTimeMillis())) + .updatedAt(timeUtils.toLocalDateTime(currentTimeMillis())) .build(); - TaskVO task2 = - TaskVO.builder() - .id(2L) - .title("Task 2") + UUID taskId2 = UUID.randomUUID(); + TaskEntity task2 = + TaskEntity.builder() + .id(taskId2) + .name("Task 2") .description("Description 2") - .status(TODO) - .createdAt(currentTimeMillis()) - .updatedAt(currentTimeMillis()) + .createdAt(timeUtils.toLocalDateTime(currentTimeMillis())) + .updatedAt(timeUtils.toLocalDateTime(currentTimeMillis())) .build(); when(taskRepository.findAll()).thenReturn(List.of(task1, task2)); - List tasks = taskRepository.findAll(); + List tasks = taskRepository.findAll(); assertEquals(2, tasks.size()); - assertEquals(task1.getTitle(), tasks.get(0).getTitle()); - assertEquals(task2.getTitle(), tasks.get(1).getTitle()); + assertEquals(task1.getName(), tasks.get(0).getName()); + assertEquals(task2.getName(), tasks.get(1).getName()); } @Test public void testFindById() { - TaskVO task1 = - TaskVO.builder() - .id(1L) - .title("Task 1") + UUID taskId = UUID.randomUUID(); + TaskEntity task1 = + TaskEntity.builder() + .id(taskId) + .name("Task 1") .description("Description 1") - .status(TODO) - .createdAt(currentTimeMillis()) - .updatedAt(currentTimeMillis()) + .status(open) + .createdAt(timeUtils.toLocalDateTime(currentTimeMillis())) + .updatedAt(timeUtils.toLocalDateTime(currentTimeMillis())) .build(); - when(taskRepository.findById(1L)).thenReturn(java.util.Optional.of(task1)); + when(taskRepository.findById(taskId)).thenReturn(Optional.of(task1)); - TaskVO foundTask = taskRepository.findById(1L).orElse(null); + TaskEntity foundTask = taskRepository.findById(taskId).orElse(null); assertNotNull(foundTask); - assertEquals(task1.getTitle(), foundTask.getTitle()); + assertEquals(task1.getName(), foundTask.getName()); assertEquals(task1.getDescription(), foundTask.getDescription()); } @Test public void testUpdateTask() { - TaskVO mockTaskVO = - TaskVO.builder() - .id(1L) - .title("New Task") + UUID taskId = UUID.randomUUID(); + TaskEntity mockTaskEntity = + TaskEntity.builder() + .id(taskId) + .name("New Task") .description("This is an new task") - .status(TODO) - .createdAt(currentTimeMillis()) - .updatedAt(currentTimeMillis()) + .status(open) + .createdAt(timeUtils.toLocalDateTime(currentTimeMillis())) + .updatedAt(timeUtils.toLocalDateTime(currentTimeMillis())) .build(); - when(taskRepository.save(any(TaskVO.class))).thenReturn(mockTaskVO); + when(taskRepository.save(any(TaskEntity.class))).thenReturn(mockTaskEntity); - TaskVO taskVO1 = taskRepository.save(mockTaskVO); - assertTrue(taskVO1.getId() > 0); - assertEquals(mockTaskVO.getTitle(), taskVO1.getTitle()); - assertEquals(mockTaskVO.getDescription(), taskVO1.getDescription()); - assertEquals(TODO, taskVO1.getStatus()); + TaskEntity taskEntity1 = taskRepository.save(mockTaskEntity); + assertEquals(taskEntity1.getId(), taskId); + assertEquals(mockTaskEntity.getName(), taskEntity1.getName()); + assertEquals(mockTaskEntity.getDescription(), taskEntity1.getDescription()); + assertEquals(open.getId(), taskEntity1.getStatus().getId()); + assertEquals(open.getName(), taskEntity1.getStatus().getName()); // update the task - mockTaskVO.setTitle("Updated Task"); - when(taskRepository.save(any(TaskVO.class))).thenReturn(mockTaskVO); - - TaskVO taskVO2 = taskRepository.save(mockTaskVO); - assertTrue(taskVO2.getId() > 0); - assertEquals(mockTaskVO.getTitle(), taskVO2.getTitle()); - assertEquals(mockTaskVO.getDescription(), taskVO2.getDescription()); - assertEquals(TODO, taskVO2.getStatus()); + mockTaskEntity.setName("Updated Task"); + when(taskRepository.save(any(TaskEntity.class))).thenReturn(mockTaskEntity); + + TaskEntity taskEntity2 = taskRepository.save(mockTaskEntity); + assertEquals(taskEntity2.getId(), taskId); + assertEquals(mockTaskEntity.getName(), taskEntity2.getName()); + assertEquals(mockTaskEntity.getDescription(), taskEntity2.getDescription()); + assertEquals(open.getId(), taskEntity2.getStatus().getId()); + assertEquals(open.getName(), taskEntity2.getStatus().getName()); } } diff --git a/maven-spring/src/test/java/com/poliveira/javaverse/TasksServiceTest.java b/maven-spring/src/test/java/com/poliveira/javaverse/TasksServiceTest.java index e48bd27..d94c417 100644 --- a/maven-spring/src/test/java/com/poliveira/javaverse/TasksServiceTest.java +++ b/maven-spring/src/test/java/com/poliveira/javaverse/TasksServiceTest.java @@ -1,18 +1,22 @@ package com.poliveira.javaverse; -import static com.poliveira.javaverse.model.Status.TODO; +import static com.poliveira.javaverse.models.Status.OPEN; import static java.lang.System.currentTimeMillis; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import com.poliveira.javaverse.model.SimpleTaskVO; -import com.poliveira.javaverse.model.TaskVO; -import com.poliveira.javaverse.repository.TaskRepository; -import com.poliveira.javaverse.service.TaskService; +import com.poliveira.javaverse.entities.StatusEntity; +import com.poliveira.javaverse.entities.TaskEntity; +import com.poliveira.javaverse.models.SimpleTaskVO; +import com.poliveira.javaverse.models.TaskVO; +import com.poliveira.javaverse.processors.MappingService; +import com.poliveira.javaverse.repositories.TaskRepository; +import com.poliveira.javaverse.services.TaskService; +import com.poliveira.javaverse.utils.TimeUtils; import java.util.List; import java.util.Optional; +import java.util.UUID; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -22,79 +26,122 @@ @ExtendWith(MockitoExtension.class) public class TasksServiceTest { + private final StatusEntity open = + StatusEntity.builder() + .id(UUID.fromString("D6127F26-55B6-408D-A010-322FBEC9B1B1")) + .name("Open") + .build(); + + @Mock private TimeUtils timeUtils; + @Mock private MappingService mappingService; @Mock private TaskRepository taskRepository; @InjectMocks private TaskService taskService; @Test public void testCreateTask() { SimpleTaskVO task = - SimpleTaskVO.builder().title("New Task").description("This is a new task").build(); + SimpleTaskVO.builder().name("New Task").description("This is a new task").build(); + UUID taskId = UUID.randomUUID(); + long now = currentTimeMillis(); + TaskEntity mockTaskEntity = + TaskEntity.builder() + .id(taskId) + .name("New Task") + .description("This is a new task") + .status(open) + .createdAt(timeUtils.toLocalDateTime(now)) + .updatedAt(timeUtils.toLocalDateTime(now)) + .build(); TaskVO mockTaskVO = TaskVO.builder() - .id(1L) - .title(task.getTitle()) - .description(task.getDescription()) - .status(TODO) - .createdAt(currentTimeMillis()) - .updatedAt(currentTimeMillis()) + .id(taskId) + .name("New Task") + .description("This is a new task") + .status(OPEN) + .createdAt(now) + .updatedAt(now) .build(); - when(taskRepository.save(any(TaskVO.class))).thenReturn(mockTaskVO); + when(mappingService.toVO(any(TaskEntity.class))).thenReturn(mockTaskVO); + when(mappingService.toEntity(any(TaskVO.class))).thenReturn(mockTaskEntity); + when(taskRepository.save(any(TaskEntity.class))).thenReturn(mockTaskEntity); TaskVO taskVO = taskService.createTask(task); - assertTrue(taskVO.getId() > 0); - assertEquals(task.getTitle(), taskVO.getTitle()); - assertEquals(task.getDescription(), taskVO.getDescription()); - assertEquals(TODO, taskVO.getStatus()); + assertEquals(taskVO.getId(), taskId); + assertEquals("New Task", taskVO.getName()); + assertEquals("This is a new task", taskVO.getDescription()); + assertEquals(OPEN, taskVO.getStatus()); } @Test public void testFindAll() { - TaskVO task = + TaskVO mockTaskVO = TaskVO.builder() - .id(1L) - .title("Test Task") + .id(UUID.randomUUID()) + .name("Test Task") .description("This is a test task") - .status(TODO) + .status(OPEN) .createdAt(currentTimeMillis()) .updatedAt(currentTimeMillis()) .build(); + TaskEntity task = + TaskEntity.builder() + .id(UUID.randomUUID()) + .name("Test Task") + .description("This is a test task") + .status(open) + .createdAt(timeUtils.toLocalDateTime(currentTimeMillis())) + .updatedAt(timeUtils.toLocalDateTime(currentTimeMillis())) + .build(); + when(mappingService.toVO(any(TaskEntity.class))).thenReturn(mockTaskVO); when(taskRepository.findAll()).thenReturn(List.of(task)); List tasks = taskService.getAllTasks(); assertEquals(1, tasks.size()); - assertEquals(task.getTitle(), tasks.getFirst().getTitle()); + assertEquals(task.getName(), tasks.getFirst().getName()); } @Test public void testUpdateTask() { - TaskVO mockExistingTask = + UUID taskId = UUID.randomUUID(); + TaskEntity mockExistingTask = + TaskEntity.builder() + .id(taskId) + .name("Old Task") + .description("This is an old task") + .status(open) + .createdAt(timeUtils.toLocalDateTime(currentTimeMillis())) + .updatedAt(timeUtils.toLocalDateTime(currentTimeMillis())) + .build(); + TaskVO mockExistingTaskVO = TaskVO.builder() - .id(1L) - .title("Old Task") + .id(taskId) + .name("Old Task") .description("This is an old task") - .status(TODO) + .status(OPEN) .createdAt(currentTimeMillis()) .updatedAt(currentTimeMillis()) .build(); - TaskVO mockUpdatedTask = - TaskVO.builder() - .id(1L) - .title("Updated Task") + TaskEntity mockUpdatedTask = + TaskEntity.builder() + .id(taskId) + .name("Updated Task") .description("This is an updated task") - .status(TODO) - .createdAt(currentTimeMillis()) - .updatedAt(currentTimeMillis()) + .status(open) + .createdAt(timeUtils.toLocalDateTime(currentTimeMillis())) + .updatedAt(timeUtils.toLocalDateTime(currentTimeMillis())) .build(); - when(taskRepository.findById(1L)).thenReturn(Optional.of(mockExistingTask)); - when(taskRepository.save(any(TaskVO.class))).thenReturn(mockUpdatedTask); + when(taskRepository.findById(taskId)).thenReturn(Optional.of(mockExistingTask)); + when(mappingService.toVO(any(TaskEntity.class))).thenReturn(mockExistingTaskVO); + when(mappingService.toEntity(any(TaskVO.class))).thenReturn(mockUpdatedTask); + when(taskRepository.save(any(TaskEntity.class))).thenReturn(mockUpdatedTask); SimpleTaskVO task = - SimpleTaskVO.builder().title("Updated Task").description("This is an updated task").build(); - TaskVO updatedTask = taskService.updateTask(1L, task); - assertEquals(task.getTitle(), updatedTask.getTitle()); + SimpleTaskVO.builder().name("Updated Task").description("This is an updated task").build(); + TaskVO updatedTask = taskService.updateTask(taskId, task); + assertEquals(task.getName(), updatedTask.getName()); assertEquals(task.getDescription(), updatedTask.getDescription()); } }