diff --git a/README.md b/README.md index 745d97a..86abe0d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # REST API using Spring Boot - ## task 1 + ## task 2 diff --git a/pom.xml b/pom.xml index 4270842..8575695 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,11 @@ spring-boot-starter-test test + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + diff --git a/src/main/java/task/repository/TaskRepository.java b/src/main/java/task/repository/TaskRepository.java index 086dc26..26c18ac 100644 --- a/src/main/java/task/repository/TaskRepository.java +++ b/src/main/java/task/repository/TaskRepository.java @@ -11,6 +11,7 @@ public interface TaskRepository { public List findByUserIdAndIsDeleteFalse(Long userId); public List findByUserIdAndIsCompleteFalseAndIsDeleteFalse(Long userId) ; public Task save(Task task) ; + public Optional findByIdAndIsDeleteFalse(Long taskId); public void markAsDeleted(Long taskId); } diff --git a/src/main/java/task/repository/impl/TaskRepositoryImpl.java b/src/main/java/task/repository/impl/TaskRepositoryImpl.java index 406e53a..2a08f1c 100644 --- a/src/main/java/task/repository/impl/TaskRepositoryImpl.java +++ b/src/main/java/task/repository/impl/TaskRepositoryImpl.java @@ -47,6 +47,11 @@ public Task save(Task task) { return task; } @Override + public Optional findByIdAndIsDeleteFalse(Long taskId) { + Task task = tasks.get(taskId); + return (task != null && !task.getIsDelete()) ? Optional.of(task) : Optional.empty(); + } + @Override public void markAsDeleted(Long taskId) { Optional.ofNullable(tasks.get(taskId)) .ifPresent(task -> task.setIsDelete(true)); diff --git a/src/test/java/task/controller/NotificationControllerTest.java b/src/test/java/task/controller/NotificationControllerTest.java new file mode 100644 index 0000000..a004079 --- /dev/null +++ b/src/test/java/task/controller/NotificationControllerTest.java @@ -0,0 +1,96 @@ +package task.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import task.model.Notification; +import task.service.NotificationService; + +import java.util.List; + +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +class NotificationControllerTest { + + private MockMvc mockMvc; + private ObjectMapper objectMapper; + + @Mock + private NotificationService notificationService; + + @InjectMocks + private NotificationController notificationController; + + private Notification notification; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + mockMvc = MockMvcBuilders.standaloneSetup(notificationController).build(); + objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + + notification = Notification.builder() + .notificationId(1L) + .text("New task available") + .userId(1L) + .taskId(2L) + .isRead(false) + .build(); + } + + @Test + void getAllNotifications_WhenExist_ReturnsOkAndList() throws Exception { + when(notificationService.getAllNotifications()).thenReturn(List.of(notification)); + + mockMvc.perform(get("/api/notifications")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].text").value("New task available")); + + verify(notificationService).getAllNotifications(); + } + + @Test + void getUserNotifications_ValidUserId_ReturnsOkAndList() throws Exception { + when(notificationService.getUserNotifications(1L)).thenReturn(List.of(notification)); + + mockMvc.perform(get("/api/notifications/user/1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].userId").value(1)); + + verify(notificationService).getUserNotifications(1L); + } + + @Test + void getUserNotificationsUnread_UnreadExist_ReturnsOkAndUnreadList() throws Exception { + when(notificationService.getUserNotificationsUnread(1L)).thenReturn(List.of(notification)); + + mockMvc.perform(get("/api/notifications/user/1/unread")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].isRead").value(false)); + + verify(notificationService).getUserNotificationsUnread(1L); + } + + @Test + void createNotification_ValidData_ReturnsCreated() throws Exception { + when(notificationService.createNotification(any(Notification.class))).thenReturn(notification); + + mockMvc.perform(post("/api/notifications") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(notification))) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.text").value("New task available")); + + verify(notificationService).createNotification(any(Notification.class)); + } +} diff --git a/src/test/java/task/controller/TaskControllerTest.java b/src/test/java/task/controller/TaskControllerTest.java new file mode 100644 index 0000000..75e27f8 --- /dev/null +++ b/src/test/java/task/controller/TaskControllerTest.java @@ -0,0 +1,96 @@ +package task.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import task.model.Task; +import task.service.TaskService; + +import java.time.LocalDateTime; +import java.util.List; + +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +class TaskControllerTest { + + private MockMvc mockMvc; + private ObjectMapper objectMapper; + + @Mock + private TaskService taskService; + + @InjectMocks + private TaskController taskController; + + private Task task; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + mockMvc = MockMvcBuilders.standaloneSetup(taskController).build(); + objectMapper = new ObjectMapper(); + + objectMapper.registerModule(new JavaTimeModule()); + + task = Task.builder() + .taskId(1L) + .taskText("Sample Task") + .userId(1L) + .createDate(LocalDateTime.now()) + .build(); + } + + @Test + void getAllTasks_WhenTasksExist_ReturnsOkAndList() throws Exception { + when(taskService.getAllTasks()).thenReturn(List.of(task)); + + mockMvc.perform(get("/api/tasks")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].taskText").value("Sample Task")); + + verify(taskService).getAllTasks(); + } + + @Test + void getUserTasks_ValidUserId_ReturnsOk() throws Exception { + when(taskService.getUserTasks(1L)).thenReturn(List.of(task)); + + mockMvc.perform(get("/api/tasks/user/1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].userId").value(1)); + + verify(taskService).getUserTasks(1L); + } + + @Test + void createTask_ValidTask_ReturnsCreated() throws Exception { + when(taskService.createTask(any(Task.class))).thenReturn(task); + + mockMvc.perform(post("/api/tasks") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(task))) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.taskText").value("Sample Task")); + + verify(taskService).createTask(any(Task.class)); + } + + @Test + void deleteTask_ValidId_ReturnsNoContent() throws Exception { + doNothing().when(taskService).deleteTask(1L); + + mockMvc.perform(delete("/api/tasks/1")) + .andExpect(status().isNoContent()); + + verify(taskService).deleteTask(1L); + } +} diff --git a/src/test/java/task/controller/UserControllerTest.java b/src/test/java/task/controller/UserControllerTest.java new file mode 100644 index 0000000..3421299 --- /dev/null +++ b/src/test/java/task/controller/UserControllerTest.java @@ -0,0 +1,93 @@ +package task.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.InjectMocks; +import org.mockito.MockitoAnnotations; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import task.model.User; +import task.service.UserService; + +import java.util.List; +import java.util.Optional; + +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +class UserControllerTest { + + private MockMvc mockMvc; + + @Mock + private UserService userService; + + @InjectMocks + private UserController userController; + + private ObjectMapper objectMapper; + private User user; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + mockMvc = MockMvcBuilders.standaloneSetup(userController).build(); + objectMapper = new ObjectMapper(); + + user = User.builder() + .userId(1L) + .login("testLogin") + .userName("testUser") + .email("test@mail.com") + .build(); + } + + @Test + void getAllUsers_WhenUsersExist_ReturnsOkAndUserList() throws Exception { + when(userService.getAllUsers()).thenReturn(List.of(user)); + + mockMvc.perform(get("/api/users")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].userName").value("testUser")); + + verify(userService).getAllUsers(); + } + + @Test + void register_ValidUser_ReturnsCreated() throws Exception { + when(userService.register(any(User.class))).thenReturn(user); + + mockMvc.perform(post("/api/users") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(user))) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.login").value("testLogin")); + + verify(userService).register(any(User.class)); + } + + @Test + void getUserById_ExistingId_ReturnsOkAndUser() throws Exception { + when(userService.getUserById(1L)).thenReturn(Optional.of(user)); + + mockMvc.perform(get("/api/users/1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.userName").value("testUser")); + + verify(userService).getUserById(1L); + } + + @Test + void getUserById_NonExistingId_ReturnsNotFound() throws Exception { + when(userService.getUserById(99L)).thenReturn(Optional.empty()); + + mockMvc.perform(get("/api/users/99")) + .andExpect(status().isNotFound()); + + verify(userService).getUserById(99L); + } +} diff --git a/src/test/java/task/repository/impl/NotificationRepositoryImplTest.java b/src/test/java/task/repository/impl/NotificationRepositoryImplTest.java new file mode 100644 index 0000000..9aedc68 --- /dev/null +++ b/src/test/java/task/repository/impl/NotificationRepositoryImplTest.java @@ -0,0 +1,137 @@ +package task.repository.impl; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import task.model.Notification; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class NotificationRepositoryImplTest { + + private NotificationRepositoryImpl repository; + private Notification notification; + + @BeforeEach + void setUp() { + repository = new NotificationRepositoryImpl(); + + notification = Notification.builder() + .text("Reminder about task") + .taskId(1L) + .userId(10L) + .isRead(false) + .build(); + } + + @Test + void save_NewNotification_AssignsIdAndStoresNotification() { + // Act + Notification saved = repository.save(notification); + + // Assert + assertNotNull(saved.getNotificationId(), "Id должен быть присвоен"); + assertEquals(1, repository.findAll().size(), "Ожидаем 1 уведомление в репозитории"); + } + + @Test + void findByUserId_UserHasNotifications_ReturnsCorrectList() { + // Arrange + repository.save(notification); + repository.save(Notification.builder() + .text("Another one") + .taskId(2L) + .userId(20L) + .isRead(false) + .build()); + + // Act + List list = repository.findByUserId(10L); + + // Assert + assertEquals(1, list.size(), "Ожидаем 1 уведомление для userId=10"); + assertEquals("Reminder about task", list.get(0).getText()); + } + + @Test + void findByUserId_UserHasNoNotifications_ReturnsEmptyList() { + // Arrange + repository.save(notification); + + // Act + List list = repository.findByUserId(999L); + + // Assert + assertTrue(list.isEmpty(), "Список должен быть пуст для неизвестного пользователя"); + } + + @Test + void findByUserIdAndIsReadFalse_HasUnread_ReturnsOnlyUnread() { + // Arrange + repository.save(notification); // unread + repository.save(Notification.builder() + .text("Read message") + .taskId(2L) + .userId(10L) + .isRead(true) + .build()); + + // Act + List unread = repository.findByUserIdAndIsReadFalse(10L); + + // Assert + assertEquals(1, unread.size(), "Ожидаем только одно непрочитанное уведомление"); + assertFalse(unread.get(0).getIsRead(), "Уведомление должно быть непрочитанным"); + } + + @Test + void findByUserIdAndIsReadFalse_NoUnread_ReturnsEmptyList() { + // Arrange + repository.save(Notification.builder() + .text("Read message") + .taskId(3L) + .userId(15L) + .isRead(true) + .build()); + + // Act + List unread = repository.findByUserIdAndIsReadFalse(15L); + + // Assert + assertTrue(unread.isEmpty(), "Ожидаем пустой список при отсутствии непрочитанных"); + } + + @Test + void save_ExistingNotificationId_UpdatesStoredNotification() { + // Arrange + Notification saved = repository.save(notification); + saved.setText("Updated text"); + + // Act + repository.save(saved); + + // Assert + List all = repository.findAll(); + assertEquals(1, all.size()); + assertEquals("Updated text", all.get(0).getText(), "Текст должен быть обновлён"); + } + + @Test + void findAll_MultipleNotifications_ReturnsAll() { + // Arrange + repository.save(notification); + repository.save(Notification.builder() + .text("Second note") + .taskId(2L) + .userId(10L) + .isRead(false) + .build()); + + // Act + List all = repository.findAll(); + + // Assert + assertEquals(2, all.size(), "Ожидаем 2 уведомления"); + } +} diff --git a/src/test/java/task/repository/impl/TaskRepositoryImplTest.java b/src/test/java/task/repository/impl/TaskRepositoryImplTest.java new file mode 100644 index 0000000..33ead9d --- /dev/null +++ b/src/test/java/task/repository/impl/TaskRepositoryImplTest.java @@ -0,0 +1,95 @@ +package task.repository.impl; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import task.model.Task; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +class TaskRepositoryImplTest { + + private TaskRepositoryImpl repository; + private Task task; + private static final LocalDateTime DATE_NOW = LocalDateTime.now(); + + @BeforeEach + void setUp() { + repository = new TaskRepositoryImpl(); + + task = Task.builder() + .taskText("Test task 1") + .userId(1L) + .actionDate(DATE_NOW.plusDays(2)) + .build(); + } + + @Test + void save_NewTask_AssignsIdAndStoresTask() { + Task saved = repository.save(task); + + assertNotNull(saved.getTaskId(), "Id должен быть назначен"); + assertEquals(1, repository.findAllIsDeleteFalse().size(), "В репозитории должен быть 1 элемент"); + } + + @Test + void findByUserIdAndIsDeleteFalse_ExistingTasks_ReturnsCorrectTasks() { + repository.save(task); + repository.save(Task.builder() + .taskText("Test task 2") + .userId(2L) + .actionDate(DATE_NOW.plusDays(3)) + .build() + ); + + List tasks = repository.findByUserIdAndIsDeleteFalse(1L); + + assertEquals(1, tasks.size()); + assertEquals("Test task 1", tasks.get(0).getTaskText()); + } + + @Test + void findByUserIdAndIsDeleteFalse_NoTasksForUser_ReturnsEmptyList() { + // не сохраняем задачи для userId=99 + List tasks = repository.findByUserIdAndIsDeleteFalse(99L); + assertTrue(tasks.isEmpty(), "Ожидаем пустой список если задач нет для заданного пользователя"); + } + + @Test + void findByUserIdAndIsCompleteFalseAndIsDeleteFalse_OnlyIncomplete_ReturnsPending() { + Task completedTask = Task.builder() + .taskText("Completed task") + .userId(1L) + .actionDate(DATE_NOW.plusDays(3)) + .isComplete(true) // помечена как выполненная + .build(); + + repository.save(task); // incomplete + repository.save(completedTask); // complete + + List pending = repository.findByUserIdAndIsCompleteFalseAndIsDeleteFalse(1L); + + assertEquals(1, pending.size()); + assertEquals("Test task 1", pending.get(0).getTaskText()); + } + + @Test + void markAsDeleted_TaskExists_SetsIsDeleteTrue() { + Task saved = repository.save(task); + repository.markAsDeleted(saved.getTaskId()); + + // findById должен вернуть empty, т.к. task помечен как удаленный + assertTrue(repository.findByIdAndIsDeleteFalse(saved.getTaskId()).isEmpty()); + } + + @Test + void markAsDeleted_NonExistingTask_NoExceptionAndStateUnchanged() { + // не должно кидать исключения при пометке несуществующего id + repository.markAsDeleted(999L); + // репозиторий по-прежнему пуст + assertTrue(repository.findAllIsDeleteFalse().isEmpty()); + } +} diff --git a/src/test/java/task/repository/impl/UserRepositoryImplTest.java b/src/test/java/task/repository/impl/UserRepositoryImplTest.java new file mode 100644 index 0000000..baf909a --- /dev/null +++ b/src/test/java/task/repository/impl/UserRepositoryImplTest.java @@ -0,0 +1,118 @@ +package task.repository.impl; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import task.model.User; + +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +class UserRepositoryImplTest { + + private UserRepositoryImpl repository; + private User user; + + @BeforeEach + void setUp() { + repository = new UserRepositoryImpl(); + + user = User.builder() + .login("login1") + .password("pass123") + .email("user1@mail.com") + .userName("user1Name") + .build(); + } + + @Test + void save_NewUser_AssignsIdAndStoresUser() { + // Act + User saved = repository.save(user); + + // Assert + assertNotNull(saved.getUserId(), "Id должен быть назначен"); + assertEquals(1, repository.findAll().size(), "В репозитории должен быть 1 пользователь"); + } + + @Test + void findByUserName_UserExists_ReturnsUser() { + // Arrange + repository.save(user); + + // Act + Optional result = repository.findByUserName("user1Name"); + + // Assert + assertTrue(result.isPresent(), "Пользователь должен быть найден"); + assertEquals("login1", result.get().getLogin()); + } + + @Test + void findByUserName_UserNotExists_ReturnsEmpty() { + // Arrange + repository.save(user); + + // Act + Optional result = repository.findByUserName("unknown"); + + // Assert + assertTrue(result.isEmpty(), "Ожидаем пустой Optional"); + } + + @Test + void findById_ExistingId_ReturnsUser() { + // Arrange + User saved = repository.save(user); + + // Act + Optional found = repository.findById(saved.getUserId()); + + // Assert + assertTrue(found.isPresent(), "Пользователь должен быть найден"); + assertEquals(saved.getUserName(), found.get().getUserName()); + } + + @Test + void findById_NonExistingId_ReturnsEmpty() { + // Act + Optional found = repository.findById(999L); + + // Assert + assertTrue(found.isEmpty(), "Ожидаем Optional.empty для несуществующего id"); + } + + @Test + void findAll_WhenMultipleUsersExist_ReturnsAllUsers() { + // Arrange + repository.save(user); + repository.save(User.builder() + .login("login2") + .password("pass456") + .email("user2@mail.com") + .userName("user2Name") + .build()); + + // Act + List all = repository.findAll(); + + // Assert + assertEquals(2, all.size(), "Ожидаем 2 пользователя"); + } + + @Test + void save_UserWithExistingId_OverwritesExistingUser() { + // Arrange + User saved = repository.save(user); + saved.setEmail("updated@mail.com"); + + // Act + repository.save(saved); + + // Assert + Optional found = repository.findById(saved.getUserId()); + assertTrue(found.isPresent()); + assertEquals("updated@mail.com", found.get().getEmail(), "Email должен быть обновлён"); + } +} diff --git a/src/test/java/task/service/impl/NotificationServiceImplTest.java b/src/test/java/task/service/impl/NotificationServiceImplTest.java new file mode 100644 index 0000000..6ad9108 --- /dev/null +++ b/src/test/java/task/service/impl/NotificationServiceImplTest.java @@ -0,0 +1,91 @@ +package task.service.impl; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import task.model.Notification; +import task.repository.NotificationRepository; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class NotificationServiceImplTest { + + @Mock + private NotificationRepository notificationRepository; + + @InjectMocks + private NotificationServiceImpl notificationService; + + private Notification notification; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + + notification = Notification.builder() + .notificationId(1L) + .text("Task reminder") + .taskId(1L) + .userId(10L) + .isRead(false) + .build(); + } + + @Test + void getAllNotifications_WhenExist_ReturnsList() { + when(notificationRepository.findAll()).thenReturn(List.of(notification)); + + List result = notificationService.getAllNotifications(); + + assertEquals(1, result.size()); + assertEquals("Task reminder", result.get(0).getText()); + verify(notificationRepository).findAll(); + } + + @Test + void getUserNotifications_ValidUserId_ReturnsNotifications() { + when(notificationRepository.findByUserId(10L)).thenReturn(List.of(notification)); + + List result = notificationService.getUserNotifications(10L); + + assertEquals(1, result.size()); + verify(notificationRepository).findByUserId(10L); + } + + @Test + void getUserNotifications_NoNotifications_ReturnsEmptyList() { + when(notificationRepository.findByUserId(99L)).thenReturn(List.of()); + + List result = notificationService.getUserNotifications(99L); + + assertTrue(result.isEmpty()); + verify(notificationRepository).findByUserId(99L); + } + + @Test + void getUserNotificationsUnread_HasUnread_ReturnsOnlyUnread() { + when(notificationRepository.findByUserIdAndIsReadFalse(10L)).thenReturn(List.of(notification)); + + List unread = notificationService.getUserNotificationsUnread(10L); + + assertEquals(1, unread.size()); + assertFalse(unread.get(0).getIsRead()); + verify(notificationRepository).findByUserIdAndIsReadFalse(10L); + } + + @Test + void createNotification_ValidNotification_SavesAndReturns() { + when(notificationRepository.save(notification)).thenReturn(notification); + + Notification created = notificationService.createNotification(notification); + + assertNotNull(created); + assertEquals("Task reminder", created.getText()); + verify(notificationRepository).save(notification); + } +} diff --git a/src/test/java/task/service/impl/TaskServiceImplTest.java b/src/test/java/task/service/impl/TaskServiceImplTest.java new file mode 100644 index 0000000..26cfaf0 --- /dev/null +++ b/src/test/java/task/service/impl/TaskServiceImplTest.java @@ -0,0 +1,88 @@ +package task.service.impl; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import task.model.Task; +import task.repository.TaskRepository; + +import java.time.LocalDateTime; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class TaskServiceImplTest { + + @Mock + private TaskRepository taskRepository; + + @InjectMocks + private TaskServiceImpl taskService; + + private Task task; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + + task = Task.builder() + .taskId(1L) + .taskText("Test task") + .userId(1L) + .createDate(LocalDateTime.now()) + .build(); + } + + @Test + void getAllTasks_WhenTasksExist_ReturnsTaskList() { + when(taskRepository.findAllIsDeleteFalse()).thenReturn(List.of(task)); + + List result = taskService.getAllTasks(); + + assertEquals(1, result.size()); + assertEquals("Test task", result.get(0).getTaskText()); + verify(taskRepository).findAllIsDeleteFalse(); + } + + @Test + void getUserTasks_ValidUserId_ReturnsTasks() { + when(taskRepository.findByUserIdAndIsDeleteFalse(1L)).thenReturn(List.of(task)); + + List result = taskService.getUserTasks(1L); + + assertEquals(1, result.size()); + verify(taskRepository).findByUserIdAndIsDeleteFalse(1L); + } + + @Test + void getUserTasksPending_OnlyIncompleteTasks_ReturnsPending() { + when(taskRepository.findByUserIdAndIsCompleteFalseAndIsDeleteFalse(1L)).thenReturn(List.of(task)); + + List result = taskService.getUserTasksPending(1L); + + assertEquals(1, result.size()); + assertFalse(result.get(0).getIsComplete()); + verify(taskRepository).findByUserIdAndIsCompleteFalseAndIsDeleteFalse(1L); + } + + @Test + void createTask_ValidTask_SavesTask() { + when(taskRepository.save(task)).thenReturn(task); + + Task created = taskService.createTask(task); + + assertNotNull(created); + assertEquals("Test task", created.getTaskText()); + verify(taskRepository).save(task); + } + + @Test + void deleteTask_ValidId_CallsRepositoryMarkAsDeleted() { + taskService.deleteTask(1L); + + verify(taskRepository).markAsDeleted(1L); + } +} diff --git a/src/test/java/task/service/impl/UserServiceImplTest.java b/src/test/java/task/service/impl/UserServiceImplTest.java new file mode 100644 index 0000000..c72fccf --- /dev/null +++ b/src/test/java/task/service/impl/UserServiceImplTest.java @@ -0,0 +1,102 @@ +package task.service.impl; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import task.model.User; +import task.repository.UserRepository; + +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class UserServiceImplTest { + + @Mock + private UserRepository userRepository; + + @InjectMocks + private UserServiceImpl userService; + + private User user; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + + user = User.builder() + .userId(1L) + .login("userLogin") + .password("12345") + .userName("userName") + .email("user@mail.com") + .build(); + } + + @Test + void getAllUsers_WhenUsersExist_ReturnsUserList() { + when(userRepository.findAll()).thenReturn(List.of(user)); + + List result = userService.getAllUsers(); + + assertEquals(1, result.size()); + assertEquals("userName", result.get(0).getUserName()); + verify(userRepository).findAll(); + } + + @Test + void register_ValidUser_SavesUser() { + when(userRepository.save(any(User.class))).thenReturn(user); + + User saved = userService.register(user); + + assertNotNull(saved); + assertEquals("userLogin", saved.getLogin()); + verify(userRepository).save(user); + } + + @Test + void login_ValidCredentials_ReturnsUser() { + when(userRepository.findByUserName("userName")).thenReturn(Optional.of(user)); + + Optional result = userService.login("userName", "12345"); + + assertTrue(result.isPresent()); + assertEquals("userLogin", result.get().getLogin()); + verify(userRepository).findByUserName("userName"); + } + + @Test + void login_InvalidPassword_ReturnsEmpty() { + when(userRepository.findByUserName("userName")).thenReturn(Optional.of(user)); + + Optional result = userService.login("userName", "wrongPass"); + + assertTrue(result.isEmpty()); + verify(userRepository).findByUserName("userName"); + } + + @Test + void getUserById_ExistingId_ReturnsUser() { + when(userRepository.findById(1L)).thenReturn(Optional.of(user)); + + Optional result = userService.getUserById(1L); + + assertTrue(result.isPresent()); + assertEquals("userLogin", result.get().getLogin()); + verify(userRepository).findById(1L); + } + + @Test + void getUserById_NonExistingId_ReturnsEmpty() { + when(userRepository.findById(99L)).thenReturn(Optional.empty()); + + Optional result = userService.getUserById(99L); + + assertTrue(result.isEmpty()); + } +} diff --git a/target/classes/task/repository/TaskRepository.class b/target/classes/task/repository/TaskRepository.class index 3bd4526..fdb9c7f 100644 Binary files a/target/classes/task/repository/TaskRepository.class and b/target/classes/task/repository/TaskRepository.class differ diff --git a/target/classes/task/repository/impl/TaskRepositoryImpl.class b/target/classes/task/repository/impl/TaskRepositoryImpl.class index 15cf135..397df04 100644 Binary files a/target/classes/task/repository/impl/TaskRepositoryImpl.class and b/target/classes/task/repository/impl/TaskRepositoryImpl.class differ diff --git a/target/test-classes/task/controller/NotificationControllerTest.class b/target/test-classes/task/controller/NotificationControllerTest.class new file mode 100644 index 0000000..26ef8d0 Binary files /dev/null and b/target/test-classes/task/controller/NotificationControllerTest.class differ diff --git a/target/test-classes/task/controller/TaskControllerTest.class b/target/test-classes/task/controller/TaskControllerTest.class new file mode 100644 index 0000000..76a1569 Binary files /dev/null and b/target/test-classes/task/controller/TaskControllerTest.class differ diff --git a/target/test-classes/task/controller/UserControllerTest.class b/target/test-classes/task/controller/UserControllerTest.class new file mode 100644 index 0000000..20a2a36 Binary files /dev/null and b/target/test-classes/task/controller/UserControllerTest.class differ diff --git a/target/test-classes/task/repository/impl/NotificationRepositoryImplTest.class b/target/test-classes/task/repository/impl/NotificationRepositoryImplTest.class new file mode 100644 index 0000000..3da8c44 Binary files /dev/null and b/target/test-classes/task/repository/impl/NotificationRepositoryImplTest.class differ diff --git a/target/test-classes/task/repository/impl/TaskRepositoryImplTest.class b/target/test-classes/task/repository/impl/TaskRepositoryImplTest.class new file mode 100644 index 0000000..6a34a06 Binary files /dev/null and b/target/test-classes/task/repository/impl/TaskRepositoryImplTest.class differ diff --git a/target/test-classes/task/repository/impl/UserRepositoryImplTest.class b/target/test-classes/task/repository/impl/UserRepositoryImplTest.class new file mode 100644 index 0000000..395f821 Binary files /dev/null and b/target/test-classes/task/repository/impl/UserRepositoryImplTest.class differ diff --git a/target/test-classes/task/service/impl/NotificationServiceImplTest.class b/target/test-classes/task/service/impl/NotificationServiceImplTest.class new file mode 100644 index 0000000..00e1345 Binary files /dev/null and b/target/test-classes/task/service/impl/NotificationServiceImplTest.class differ diff --git a/target/test-classes/task/service/impl/TaskServiceImplTest.class b/target/test-classes/task/service/impl/TaskServiceImplTest.class new file mode 100644 index 0000000..8cbb5b3 Binary files /dev/null and b/target/test-classes/task/service/impl/TaskServiceImplTest.class differ diff --git a/target/test-classes/task/service/impl/UserServiceImplTest.class b/target/test-classes/task/service/impl/UserServiceImplTest.class new file mode 100644 index 0000000..693fff7 Binary files /dev/null and b/target/test-classes/task/service/impl/UserServiceImplTest.class differ