diff --git a/backend/.idea/workspace.xml b/backend/.idea/workspace.xml
index c18727c..3e12b67 100644
--- a/backend/.idea/workspace.xml
+++ b/backend/.idea/workspace.xml
@@ -4,8 +4,10 @@
-
+
+
+
@@ -84,7 +86,69 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -100,70 +164,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -173,11 +173,11 @@
+
-
-
-
-
+
+
+
@@ -449,15 +449,21 @@
1699646291964
-
+
+
+ 1699693472182
+
+
+
+ 1699693472182
+
+
-
-
@@ -481,7 +487,9 @@
-
+
+
+
diff --git a/backend/src/main/java/core/api/models/timemanager/tasks/TaskFieldInfo.java b/backend/src/main/java/core/api/models/timemanager/tasks/TaskFieldInfo.java
index 9d2eb31..d4f2cf9 100644
--- a/backend/src/main/java/core/api/models/timemanager/tasks/TaskFieldInfo.java
+++ b/backend/src/main/java/core/api/models/timemanager/tasks/TaskFieldInfo.java
@@ -14,6 +14,16 @@ public class TaskFieldInfo {
private LocalDate startDate;
private LocalDate deadline;
+ public TaskFieldInfo() {
+ }
+
+ public TaskFieldInfo(String taskName, int eta, LocalDate startDate, LocalDate deadline) {
+ this.taskName = taskName;
+ this.eta = eta;
+ this.startDate = startDate;
+ this.deadline = deadline;
+ }
+
public String getTaskName() {
return taskName;
}
diff --git a/backend/src/main/java/core/entities/timemanager/Task.java b/backend/src/main/java/core/entities/timemanager/Task.java
index 9154f0f..440f59b 100644
--- a/backend/src/main/java/core/entities/timemanager/Task.java
+++ b/backend/src/main/java/core/entities/timemanager/Task.java
@@ -12,7 +12,7 @@ import java.util.Set;
public class Task {
@Id
- @GeneratedValue(strategy = GenerationType.AUTO)
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
private long taskID;
@ManyToOne
@@ -113,19 +113,6 @@ public class Task {
this.workTime += workTime;
}
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- Task task = (Task) o;
- return taskID == task.taskID;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(taskID);
- }
-
public void setTaskID(long taskID) {
this.taskID = taskID;
}
@@ -150,4 +137,31 @@ public class Task {
public void increaseActiveTime(int minutesSpent) {
this.workTime += minutesSpent;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Task task = (Task) o;
+ return taskID == task.taskID && eta == task.eta && finished == task.finished && workTime == task.workTime && Objects.equals(taskgroup, task.taskgroup) && Objects.equals(taskName, task.taskName) && Objects.equals(startDate, task.startDate) && Objects.equals(deadline, task.deadline);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(taskID, taskgroup, taskName, startDate, deadline, eta, finished, workTime);
+ }
+
+ @Override
+ public String toString() {
+ return "Task{" +
+ "taskID=" + taskID +
+ ", taskgroup=" + taskgroup +
+ ", taskName='" + taskName + '\'' +
+ ", startDate=" + startDate +
+ ", deadline=" + deadline +
+ ", eta=" + eta +
+ ", finished=" + finished +
+ ", workTime=" + workTime +
+ '}';
+ }
}
diff --git a/backend/src/main/java/core/entities/timemanager/Taskgroup.java b/backend/src/main/java/core/entities/timemanager/Taskgroup.java
index a832632..6fc92e1 100644
--- a/backend/src/main/java/core/entities/timemanager/Taskgroup.java
+++ b/backend/src/main/java/core/entities/timemanager/Taskgroup.java
@@ -29,6 +29,7 @@ public class Taskgroup {
@JoinColumn(name = "parent_id")
private Taskgroup parent;
+
@OneToMany(mappedBy = "taskgroup", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set tasks;
diff --git a/backend/src/main/java/core/services/ServiceExitCode.java b/backend/src/main/java/core/services/ServiceExitCode.java
index 4282071..93cbddd 100644
--- a/backend/src/main/java/core/services/ServiceExitCode.java
+++ b/backend/src/main/java/core/services/ServiceExitCode.java
@@ -5,5 +5,6 @@ public enum ServiceExitCode {
OK,
ENTITY_ALREADY_EXIST,
MISSING_ENTITY,
- INVALID_OPERATION;
+ INVALID_OPERATION,
+ INVALID_PARAMETER;
}
diff --git a/backend/src/main/java/core/services/TaskService.java b/backend/src/main/java/core/services/TaskService.java
index 843d3e1..278a69f 100644
--- a/backend/src/main/java/core/services/TaskService.java
+++ b/backend/src/main/java/core/services/TaskService.java
@@ -11,6 +11,9 @@ import core.repositories.timemanager.TaskgroupRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.transaction.Transactional;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
@@ -20,12 +23,17 @@ public class TaskService {
private final TaskRepository taskRepository;
private final TaskScheduleService taskScheduleService;
+ private final TaskgroupRepository taskgroupRepository;
+ @PersistenceContext
+ private EntityManager entityManager;
public TaskService(@Autowired TaskRepository taskRepository,
- @Autowired TaskScheduleService taskScheduleService) {
+ @Autowired TaskScheduleService taskScheduleService,
+ TaskgroupRepository taskgroupRepository) {
this.taskRepository = taskRepository;
this.taskScheduleService = taskScheduleService;
+ this.taskgroupRepository = taskgroupRepository;
}
public ServiceResult createTask(Taskgroup taskgroup, TaskFieldInfo taskFieldInfo) {
@@ -33,6 +41,11 @@ public class TaskService {
return new ServiceResult<>(ServiceExitCode.ENTITY_ALREADY_EXIST);
}
+ //Check for invalid date (deadline before start
+ if(taskFieldInfo.getStartDate() != null && taskFieldInfo.getDeadline() != null &&
+ taskFieldInfo.getDeadline().isBefore(taskFieldInfo.getStartDate())) {
+ return new ServiceResult<>(ServiceExitCode.INVALID_PARAMETER);
+ }
Task task = new Task(taskgroup, taskFieldInfo.getTaskName(), taskFieldInfo.getStartDate(), taskFieldInfo.getDeadline(), taskFieldInfo.getEta());
taskgroup.getTasks().add(task);
@@ -57,11 +70,19 @@ public class TaskService {
}
public ServiceResult editTask(Task task, TaskFieldInfo taskFieldInfo) {
- if(!task.getTaskName().equals(taskFieldInfo.getTaskName()) && !existTaskByName(task.getTaskgroup().getTasks(), taskFieldInfo.getTaskName())) {
- task.setTaskName(taskFieldInfo.getTaskName());
+ if(!task.getTaskName().equals(taskFieldInfo.getTaskName())) {
+ //taskname will be updated
+ if(existTaskByName(task.getTaskgroup().getTasks(), taskFieldInfo.getTaskName())) {
+ return new ServiceResult<>(ServiceExitCode.ENTITY_ALREADY_EXIST);
+ } else {
+ task.setTaskName(taskFieldInfo.getTaskName());
+ }
+ }
- } else if(!task.getTaskName().equals(taskFieldInfo.getTaskName()) && existTaskByName(task.getTaskgroup().getTasks(), taskFieldInfo.getTaskName())) {
- return new ServiceResult<>(ServiceExitCode.ENTITY_ALREADY_EXIST);
+ //Check for invalid date (deadline before start
+ if(taskFieldInfo.getStartDate() != null && taskFieldInfo.getDeadline() != null &&
+ taskFieldInfo.getDeadline().isBefore(taskFieldInfo.getStartDate())) {
+ return new ServiceResult<>(ServiceExitCode.INVALID_PARAMETER);
}
task.setEta(taskFieldInfo.getEta());
task.setStartDate(taskFieldInfo.getStartDate());
@@ -70,9 +91,13 @@ public class TaskService {
return new ServiceResult<>(task);
}
+ @Transactional
public void deleteTask(Task task) {
taskScheduleService.deleteScheduleByTask(task);
taskRepository.deleteByTaskID(task.getTaskID());
+
+ entityManager.flush();
+ entityManager.detach(task);
}
public void clearTasks(Taskgroup taskgroup) {
diff --git a/backend/src/test/java/core/tasks/TaskRepositoryTest.java b/backend/src/test/java/core/tasks/TaskRepositoryTest.java
index 5df74d5..99ea0ce 100644
--- a/backend/src/test/java/core/tasks/TaskRepositoryTest.java
+++ b/backend/src/test/java/core/tasks/TaskRepositoryTest.java
@@ -49,7 +49,7 @@ public class TaskRepositoryTest {
List tasks_user1_false = taskRepository.findAllByUser(testUser1.getUsername(), false);
List tasks_user1_true = taskRepository.findAllByUser(testUser1.getUsername(), true);
assertEquals(7, tasks_user1_true.size());
- assertEquals(7, tasks_user1_false.size());
+ assertEquals(8, tasks_user1_false.size());
assertTrue(tasks_user1_false.contains(testEntityManager.find(Task.class, 1L)));
assertTrue(tasks_user1_false.contains(testEntityManager.find(Task.class, 3L)));
@@ -149,7 +149,7 @@ public class TaskRepositoryTest {
List active = taskRepository.findAllActive(testuser1.getUsername(), referenceDate);
//1,3,5,11,12
- assertEquals(5, active.size());
+ assertEquals(6, active.size());
assertTrue(active.contains(testEntityManager.find(Task.class, 1L)));
assertTrue(active.contains(testEntityManager.find(Task.class, 3L)));
assertTrue(active.contains(testEntityManager.find(Task.class, 5L)));
diff --git a/backend/src/test/java/core/tasks/TaskServiceTest.java b/backend/src/test/java/core/tasks/TaskServiceTest.java
new file mode 100644
index 0000000..1cd88a9
--- /dev/null
+++ b/backend/src/test/java/core/tasks/TaskServiceTest.java
@@ -0,0 +1,191 @@
+package core.tasks;
+
+import core.api.models.timemanager.tasks.TaskFieldInfo;
+import core.entities.timemanager.Task;
+import core.entities.timemanager.Taskgroup;
+import core.repositories.timemanager.TaskRepository;
+import core.repositories.timemanager.TaskgroupRepository;
+import core.services.*;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.Rollback;
+import org.springframework.test.context.jdbc.Sql;
+import org.springframework.test.context.jdbc.SqlGroup;
+
+import javax.persistence.EntityManager;
+import javax.transaction.Transactional;
+
+import java.time.LocalDate;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+@SpringBootTest
+@Transactional
+public class TaskServiceTest {
+
+
+ @Autowired
+ private TaskService taskService;
+ @Autowired
+ private EntityManager entityManager;
+
+ private static final String username = "Testuser1";
+ private static final String username2 = "Testuser2";
+ @Autowired
+ private TaskRepository taskRepository;
+ @Autowired
+ private TaskgroupRepository taskgroupRepository;
+
+ @Test
+ @SqlGroup({
+ @Sql("classpath:taskgroupRepositoryTestEntries.sql"),
+ @Sql("classpath:taskRepositoryEntries.sql")
+ })
+ void createTask() {
+ //Situation 1: Task with that name already exists in a taskgroup
+ TaskFieldInfo taskFieldInfo_1 = new TaskFieldInfo(entityManager.find(Task.class, 1L).getTaskName(), 0, null, null);
+ ServiceResult situation_1 = taskService.createTask(entityManager.find(Taskgroup.class, 2L), taskFieldInfo_1);
+ assertEquals(ServiceExitCode.ENTITY_ALREADY_EXIST, situation_1.getExitCode());
+
+ //Situation 2: Task with that name exists in another taskgroup
+ TaskFieldInfo taskFieldInfo_2 = new TaskFieldInfo(entityManager.find(Task.class, 1L).getTaskName(), 0, null, null);
+ ServiceResult result_2 = taskService.createTask(entityManager.find(Taskgroup.class, 1L), taskFieldInfo_2);
+ assertEquals(ServiceExitCode.OK, result_2.getExitCode());
+ assertThat(entityManager.find(Task.class, result_2.getResult().getTaskID())).isNotNull();
+
+ //Situation 3: Normal, everything fine
+ TaskFieldInfo taskFieldInfo_3 = new TaskFieldInfo("Situation 3", 0, null, null);
+ ServiceResult result_3 = taskService.createTask(entityManager.find(Taskgroup.class, 1L), taskFieldInfo_3);
+ assertEquals(ServiceExitCode.OK, result_3.getExitCode());
+ assertThat(entityManager.find(Task.class, result_3.getResult().getTaskID())).isNotNull();
+
+ //Robustness - Test for invalid dates
+ //Situation 4: Deadline, no start
+ TaskFieldInfo taskFieldInfo_4 = new TaskFieldInfo("Situation 4", 0, null, LocalDate.now());
+ ServiceResult result_4 = taskService.createTask(entityManager.find(Taskgroup.class, 1L), taskFieldInfo_4);
+ assertEquals(ServiceExitCode.OK, result_4.getExitCode());
+ assertThat(entityManager.find(Task.class, result_4.getResult().getTaskID())).isNotNull();
+
+ //Situation 5: Start but no deadline
+ TaskFieldInfo taskFieldInfo_5 = new TaskFieldInfo("Situation 5", 0, LocalDate.now(),null);
+ ServiceResult result_5 = taskService.createTask(entityManager.find(Taskgroup.class, 1L), taskFieldInfo_5);
+ assertEquals(ServiceExitCode.OK, result_5.getExitCode());
+ assertThat(entityManager.find(Task.class, result_5.getResult().getTaskID())).isNotNull();
+
+ //Situation 6: Deadline before start (invalid)
+ TaskFieldInfo taskFieldInfo_6 = new TaskFieldInfo("Situation 6", 0, LocalDate.now(),LocalDate.of(2010, 3, 20));
+ ServiceResult result_6= taskService.createTask(entityManager.find(Taskgroup.class, 1L), taskFieldInfo_6);
+ assertEquals(ServiceExitCode.INVALID_PARAMETER, result_6.getExitCode());
+ }
+
+ @Test
+ @SqlGroup({
+ @Sql("classpath:taskgroupRepositoryTestEntries.sql"),
+ @Sql("classpath:taskRepositoryEntries.sql")
+ })
+ void getTaskPermissions() {
+ //Situation 1: correct task and username
+ PermissionResult permissionResult_1 = taskService.getTaskPermissions(1L, username);
+ assertEquals(ServiceExitCode.OK, permissionResult_1.getExitCode());
+ assertTrue(permissionResult_1.isHasPermissions());
+ assertEquals(entityManager.find(Task.class, 1L), permissionResult_1.getResult());
+
+ //Situation 2: invalid taskgroup
+ PermissionResult permissionResult_2 = taskService.getTaskPermissions(200L, username);
+ assertEquals(ServiceExitCode.MISSING_ENTITY, permissionResult_2.getExitCode());
+ assertFalse(permissionResult_2.isHasPermissions());
+ assertThat(permissionResult_2.getResult()).isNull();
+
+ //Situation 3: invalid user
+ PermissionResult permissionResult_3 = taskService.getTaskPermissions(1L, username2);
+ assertEquals(ServiceExitCode.OK, permissionResult_3.getExitCode());
+ assertFalse(permissionResult_2.isHasPermissions());
+ assertEquals(entityManager.find(Task.class, 1L), permissionResult_3.getResult());
+ }
+
+ @Test
+ @SqlGroup({
+ @Sql("classpath:taskgroupRepositoryTestEntries.sql"),
+ @Sql("classpath:taskRepositoryEntries.sql")
+ })
+ void editTask() {
+ //Situation 1: Nothing is updated
+ Task task_1 = entityManager.find(Task.class, 1L);
+ TaskFieldInfo taskFieldInfo_1 = new TaskFieldInfo(entityManager.find(Task.class, 1L).getTaskName(), 0, null, null);
+ ServiceResult result_1 = taskService.editTask(entityManager.find(Task.class, 1L), taskFieldInfo_1);
+ assertEquals(ServiceExitCode.OK, result_1.getExitCode());
+ assertEquals(task_1, result_1.getResult());
+
+ //Situation 2: Name is updated to name that already exists within the taskgroup
+ Task task_2 = entityManager.find(Task.class, 1L);
+ TaskFieldInfo taskFieldInfo_2 = new TaskFieldInfo(entityManager.find(Task.class, 2L).getTaskName(), 0, null, null);
+ ServiceResult result_2 = taskService.editTask(entityManager.find(Task.class, 1L), taskFieldInfo_2);
+ task_2.setTaskName(entityManager.find(Task.class, 2L).getTaskName());
+ assertEquals(ServiceExitCode.ENTITY_ALREADY_EXIST, result_2.getExitCode());
+ assertNotEquals(task_2, result_2.getResult());
+
+ //Situation 3: Name is updated to nonexistend Name
+ Task task_3 = entityManager.find(Task.class, 1L);
+ TaskFieldInfo taskFieldInfo_3 = new TaskFieldInfo("Situation 3", 0, null, null);
+ ServiceResult result_3 = taskService.editTask(entityManager.find(Task.class, 1L), taskFieldInfo_3);
+ task_3.setTaskName("Situation 3");
+ assertEquals(ServiceExitCode.OK, result_3.getExitCode());
+ assertEquals(task_3, result_3.getResult());
+
+ //Situation 4: eta is updated
+ Task task_4 = entityManager.find(Task.class, 1L);
+ TaskFieldInfo taskFieldInfo_4 = new TaskFieldInfo(task_4.getTaskName(), 90, null, null);
+ ServiceResult result_4 = taskService.editTask(entityManager.find(Task.class, 1L), taskFieldInfo_4);
+ task_4.setEta(90);
+ assertEquals(ServiceExitCode.OK, result_4.getExitCode());
+ assertEquals(task_4, result_4.getResult());
+
+ //Situation 5: deadline and start is updated in a valid way
+ Task task_5 = entityManager.find(Task.class, 1L);
+ TaskFieldInfo taskFieldInfo_5 = new TaskFieldInfo(task_5.getTaskName(), task_5.getEta(), LocalDate.of(2023, 4, 9), LocalDate.of(2023,5,9));
+ ServiceResult result_5 = taskService.editTask(entityManager.find(Task.class, 1L), taskFieldInfo_5);
+ task_5.setStartDate(LocalDate.of(2023,4,9));
+ task_5.setDeadline(LocalDate.of(2023,5,9));
+ assertEquals(ServiceExitCode.OK, result_5.getExitCode());
+ assertEquals(task_5, result_5.getResult());
+
+ //Situation 6: Deadline and start are updated in a not valid way
+ Task task_6 = entityManager.find(Task.class, 1L);
+ TaskFieldInfo taskFieldInfo_6 = new TaskFieldInfo(task_5.getTaskName(), task_5.getEta(), LocalDate.of(2023, 5, 9), LocalDate.of(2023,4,9));
+ ServiceResult result_6 = taskService.editTask(entityManager.find(Task.class, 1L), taskFieldInfo_6);
+ task_6.setStartDate(LocalDate.of(2023,5,9));
+ task_6.setDeadline(LocalDate.of(2023,4,9));
+ assertEquals(ServiceExitCode.INVALID_PARAMETER, result_6.getExitCode());
+ assertNotEquals(task_6, result_6.getResult());
+
+ //Situation 10 Startdate = null;
+ Task task_10 = entityManager.find(Task.class, 5L);
+ TaskFieldInfo taskFieldInfo_10 = new TaskFieldInfo(task_10.getTaskName(), task_10.getEta(),null, task_10.getDeadline());
+ ServiceResult result_10 = taskService.editTask(entityManager.find(Task.class, 5L), taskFieldInfo_10);
+ task_10.setStartDate(null);
+ assertEquals(ServiceExitCode.OK, result_10.getExitCode());
+ assertEquals(task_10, result_10.getResult());
+
+ //Situation 11 Deadline = null
+ Task task_11 = entityManager.find(Task.class, 5L);
+ TaskFieldInfo taskFieldInfo_11 = new TaskFieldInfo(task_11.getTaskName(), task_11.getEta(),task_11.getStartDate(), null);
+ ServiceResult result_11 = taskService.editTask(entityManager.find(Task.class, 5L), taskFieldInfo_11);
+ task_11.setDeadline(null);
+ assertEquals(ServiceExitCode.OK, result_11.getExitCode());
+ assertEquals(task_11, result_11.getResult());
+ }
+
+ @Test
+ @SqlGroup({
+ @Sql("classpath:taskgroupRepositoryTestEntries.sql"),
+ @Sql("classpath:taskRepositoryEntries.sql")
+ })
+ void deleteTask() {
+ for(long i=1; i<=15; i++) {
+ taskRepository.deleteByTaskID(entityManager.find(Task.class, i).getTaskID());
+ assertThat(entityManager.find(Task.class, i)).isNull();
+ }
+ }
+}
diff --git a/backend/src/test/resources/application.properties b/backend/src/test/resources/application.properties
index 512dbe3..0ad612c 100644
--- a/backend/src/test/resources/application.properties
+++ b/backend/src/test/resources/application.properties
@@ -9,4 +9,5 @@ spring.liquibase.enabled=false
demo.webapp.jwtSecret=demoWebappSecretKey
demo.webapp.jwtExpirationMS=86400000
spring.sql.init.mode=always
-spring.jpa.hibernate.ddl-auto=create-drop
\ No newline at end of file
+spring.jpa.hibernate.ddl-auto=create-drop
+spring.jpa.show-sql=true
\ No newline at end of file
diff --git a/backend/src/test/resources/taskRepositoryEntries.sql b/backend/src/test/resources/taskRepositoryEntries.sql
index 697318c..f326ec1 100644
--- a/backend/src/test/resources/taskRepositoryEntries.sql
+++ b/backend/src/test/resources/taskRepositoryEntries.sql
@@ -16,3 +16,4 @@ INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, f
INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, finished, work_time) VALUES (13, NULL, 0, '2022-03-20', 'Task 6', 2, true, 0);
INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, finished, work_time) VALUES (14, '2044-03-20', 0, '2022-03-20', 'Task 6', 2, true, 0);
+INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, finished, work_time) VALUES (15, NULL, 0, NULL, 'Task 15', 2, false, 0);