fix: FilePreview fileType case + Tailwind v4 gradient transparent bug
- FilePreview.vue: add normalizedFileType computed to handle backend returning uppercase HTML/MD/PPTX (fixes preview/download buttons) - FilePreview.vue: bg-gradient-to-r from-orange-500 -> bg-orange-500 (Tailwind v4 gradient + CSS variable = transparent) - ReportCard.vue: bg-gradient-to-r -> bg-orange-600 for selected state - Add .opencode/, node_modules/, dist/ to .gitignore - Initial git setup for publish project
This commit is contained in:
@@ -0,0 +1,276 @@
|
||||
package com.reportdist.service;
|
||||
|
||||
import com.reportdist.dto.ProjectRequest;
|
||||
import com.reportdist.dto.ProjectResponse;
|
||||
import com.reportdist.entity.Project;
|
||||
import com.reportdist.repository.ProjectRepository;
|
||||
import com.reportdist.repository.ReportRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ProjectServiceTest {
|
||||
|
||||
@Mock
|
||||
private ProjectRepository projectRepository;
|
||||
|
||||
@Mock
|
||||
private ReportRepository reportRepository;
|
||||
|
||||
private ProjectService projectService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
projectService = new ProjectService(projectRepository, reportRepository);
|
||||
}
|
||||
|
||||
// ==================== createProject Tests ====================
|
||||
|
||||
@Test
|
||||
void createProject_shouldCreateAndReturnProject() {
|
||||
// Given
|
||||
ProjectRequest request = new ProjectRequest("Test Project", "Test Description");
|
||||
Project savedProject = new Project(1L, "Test Project", "Test Description", LocalDateTime.now());
|
||||
|
||||
when(projectRepository.save(any(Project.class))).thenReturn(savedProject);
|
||||
|
||||
// When
|
||||
ProjectResponse response = projectService.createProject(request);
|
||||
|
||||
// Then
|
||||
assertNotNull(response);
|
||||
assertEquals(1L, response.getId());
|
||||
assertEquals("Test Project", response.getName());
|
||||
assertEquals("Test Description", response.getDescription());
|
||||
verify(projectRepository, times(1)).save(any(Project.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createProject_shouldHandleDuplicateName() {
|
||||
// Given - Note: The service doesn't explicitly handle duplicates,
|
||||
// but we test the normal flow still works
|
||||
ProjectRequest request = new ProjectRequest("Duplicate Project", "Description");
|
||||
Project savedProject = new Project(2L, "Duplicate Project", "Description", LocalDateTime.now());
|
||||
|
||||
when(projectRepository.save(any(Project.class))).thenReturn(savedProject);
|
||||
|
||||
// When
|
||||
ProjectResponse response = projectService.createProject(request);
|
||||
|
||||
// Then
|
||||
assertNotNull(response);
|
||||
assertEquals("Duplicate Project", response.getName());
|
||||
verify(projectRepository, times(1)).save(any(Project.class));
|
||||
}
|
||||
|
||||
// ==================== getAllProjects Tests ====================
|
||||
|
||||
@Test
|
||||
void getAllProjects_shouldReturnEmptyList() {
|
||||
// Given
|
||||
when(projectRepository.findAll()).thenReturn(Collections.emptyList());
|
||||
|
||||
// When
|
||||
List<ProjectResponse> result = projectService.getAllProjects();
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllProjects_shouldReturnSingleProject() {
|
||||
// Given
|
||||
Project project = new Project(1L, "Single Project", "Description", LocalDateTime.now());
|
||||
when(projectRepository.findAll()).thenReturn(Collections.singletonList(project));
|
||||
|
||||
// When
|
||||
List<ProjectResponse> result = projectService.getAllProjects();
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals("Single Project", result.get(0).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllProjects_shouldReturnMultipleProjects() {
|
||||
// Given
|
||||
Project project1 = new Project(1L, "Project One", "Description 1", LocalDateTime.now());
|
||||
Project project2 = new Project(2L, "Project Two", "Description 2", LocalDateTime.now());
|
||||
Project project3 = new Project(3L, "Project Three", "Description 3", LocalDateTime.now());
|
||||
when(projectRepository.findAll()).thenReturn(Arrays.asList(project1, project2, project3));
|
||||
|
||||
// When
|
||||
List<ProjectResponse> result = projectService.getAllProjects();
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(3, result.size());
|
||||
assertEquals("Project One", result.get(0).getName());
|
||||
assertEquals("Project Two", result.get(1).getName());
|
||||
assertEquals("Project Three", result.get(2).getName());
|
||||
}
|
||||
|
||||
// ==================== updateProject Tests ====================
|
||||
|
||||
@Test
|
||||
void updateProject_shouldUpdateAndReturnProject() {
|
||||
// Given
|
||||
Long projectId = 1L;
|
||||
ProjectRequest request = new ProjectRequest("Updated Name", "Updated Description");
|
||||
Project existingProject = new Project(1L, "Original Name", "Original Description", LocalDateTime.now());
|
||||
Project updatedProject = new Project(1L, "Updated Name", "Updated Description", existingProject.getCreatedAt());
|
||||
|
||||
when(projectRepository.findById(projectId)).thenReturn(java.util.Optional.of(existingProject));
|
||||
when(projectRepository.save(any(Project.class))).thenReturn(updatedProject);
|
||||
|
||||
// When
|
||||
ProjectResponse response = projectService.updateProject(projectId, request);
|
||||
|
||||
// Then
|
||||
assertNotNull(response);
|
||||
assertEquals("Updated Name", response.getName());
|
||||
assertEquals("Updated Description", response.getDescription());
|
||||
verify(projectRepository, times(1)).findById(projectId);
|
||||
verify(projectRepository, times(1)).save(any(Project.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateProject_shouldThrowExceptionWhenNotFound() {
|
||||
// Given
|
||||
Long projectId = 999L;
|
||||
ProjectRequest request = new ProjectRequest("Updated Name", "Updated Description");
|
||||
|
||||
when(projectRepository.findById(projectId)).thenReturn(java.util.Optional.empty());
|
||||
|
||||
// When & Then
|
||||
RuntimeException exception = assertThrows(RuntimeException.class, () -> {
|
||||
projectService.updateProject(projectId, request);
|
||||
});
|
||||
|
||||
assertTrue(exception.getMessage().contains("Project not found"));
|
||||
verify(projectRepository, times(1)).findById(projectId);
|
||||
verify(projectRepository, never()).save(any(Project.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllProjects_shouldIncludeReportCount() {
|
||||
// Given
|
||||
Project project1 = new Project(1L, "Project One", "Description 1", LocalDateTime.now());
|
||||
Project project2 = new Project(2L, "Project Two", "Description 2", LocalDateTime.now());
|
||||
when(projectRepository.findAll()).thenReturn(Arrays.asList(project1, project2));
|
||||
when(reportRepository.countByProjectId(1L)).thenReturn(5L);
|
||||
when(reportRepository.countByProjectId(2L)).thenReturn(3L);
|
||||
|
||||
// When
|
||||
List<ProjectResponse> result = projectService.getAllProjects();
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(2, result.size());
|
||||
assertEquals(5L, result.get(0).getReportCount());
|
||||
assertEquals(3L, result.get(1).getReportCount());
|
||||
verify(reportRepository, times(1)).countByProjectId(1L);
|
||||
verify(reportRepository, times(1)).countByProjectId(2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getProjectById_shouldIncludeReportCount() {
|
||||
// Given
|
||||
Long projectId = 1L;
|
||||
Project project = new Project(1L, "Test Project", "Description", LocalDateTime.now());
|
||||
when(projectRepository.findById(projectId)).thenReturn(java.util.Optional.of(project));
|
||||
when(reportRepository.countByProjectId(projectId)).thenReturn(10L);
|
||||
|
||||
// When
|
||||
ProjectResponse response = projectService.getProjectById(projectId);
|
||||
|
||||
// Then
|
||||
assertNotNull(response);
|
||||
assertEquals(10L, response.getReportCount());
|
||||
verify(reportRepository, times(1)).countByProjectId(projectId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllProjects_withNoReports_shouldHaveZeroReportCount() {
|
||||
// Given
|
||||
Project project = new Project(1L, "Empty Project", "No reports", LocalDateTime.now());
|
||||
when(projectRepository.findAll()).thenReturn(Collections.singletonList(project));
|
||||
when(reportRepository.countByProjectId(1L)).thenReturn(0L);
|
||||
|
||||
// When
|
||||
List<ProjectResponse> result = projectService.getAllProjects();
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(0L, result.get(0).getReportCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateProject_withMultipartCoverImage_shouldReturnUpdatedProjectWithReportCount() {
|
||||
// Given
|
||||
Long projectId = 1L;
|
||||
Project existingProject = new Project(1L, "Original Name", "Description", LocalDateTime.now());
|
||||
Project updatedProject = new Project(1L, "Updated Name", "Description", existingProject.getCreatedAt());
|
||||
updatedProject.setCoverImage("/uploads/covers/1/test.png");
|
||||
|
||||
when(projectRepository.findById(projectId)).thenReturn(java.util.Optional.of(existingProject));
|
||||
when(projectRepository.save(any(Project.class))).thenReturn(updatedProject);
|
||||
when(reportRepository.countByProjectId(projectId)).thenReturn(5L);
|
||||
|
||||
// When
|
||||
ProjectResponse response = projectService.updateProject(projectId, "Updated Name", null, null);
|
||||
|
||||
// Then
|
||||
assertNotNull(response);
|
||||
assertEquals(5L, response.getReportCount());
|
||||
verify(reportRepository, times(1)).countByProjectId(projectId);
|
||||
}
|
||||
|
||||
// ==================== deleteProject Tests ====================
|
||||
|
||||
@Test
|
||||
void deleteProject_shouldDeleteSuccessfully() {
|
||||
// Given
|
||||
Long projectId = 1L;
|
||||
when(projectRepository.existsById(projectId)).thenReturn(true);
|
||||
doNothing().when(projectRepository).deleteById(projectId);
|
||||
|
||||
// When
|
||||
projectService.deleteProject(projectId);
|
||||
|
||||
// Then
|
||||
verify(projectRepository, times(1)).existsById(projectId);
|
||||
verify(projectRepository, times(1)).deleteById(projectId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteProject_shouldThrowExceptionWhenNotFound() {
|
||||
// Given
|
||||
Long projectId = 999L;
|
||||
when(projectRepository.existsById(projectId)).thenReturn(false);
|
||||
|
||||
// When & Then
|
||||
RuntimeException exception = assertThrows(RuntimeException.class, () -> {
|
||||
projectService.deleteProject(projectId);
|
||||
});
|
||||
|
||||
assertTrue(exception.getMessage().contains("Project not found"));
|
||||
verify(projectRepository, times(1)).existsById(projectId);
|
||||
verify(projectRepository, never()).deleteById(any());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user