diff --git a/src/test/java/com/lab/labtimesheet/feature/reporting/controller/RoleDashboardWebIntegrationTest.java b/src/test/java/com/lab/labtimesheet/feature/reporting/controller/RoleDashboardWebIntegrationTest.java new file mode 100644 index 0000000..9e9878e --- /dev/null +++ b/src/test/java/com/lab/labtimesheet/feature/reporting/controller/RoleDashboardWebIntegrationTest.java @@ -0,0 +1,188 @@ +package com.lab.labtimesheet.feature.reporting.controller; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.lab.labtimesheet.config.TestcontainersConfiguration; +import com.lab.labtimesheet.feature.account.model.GlobalRole; +import com.lab.labtimesheet.feature.account.model.dto.CreateAccountCommand; +import com.lab.labtimesheet.feature.account.service.AccountService; +import com.lab.labtimesheet.feature.account.service.BootstrapService; +import com.lab.labtimesheet.feature.integration.model.SecurityMode; +import com.lab.labtimesheet.feature.integration.model.dto.SmtpConnection; +import com.lab.labtimesheet.feature.integration.model.dto.SmtpDraft; +import com.lab.labtimesheet.feature.integration.service.SmtpConfigurationService; +import com.lab.labtimesheet.feature.integration.service.SmtpProbe; +import com.lab.labtimesheet.feature.project.model.dto.ProjectCreateCommand; +import com.lab.labtimesheet.feature.project.service.ProjectQueryService; +import com.lab.labtimesheet.feature.project.service.ProjectService; +import com.lab.labtimesheet.feature.task.model.TaskStatus; +import com.lab.labtimesheet.feature.task.model.dto.CreateTaskCommand; +import com.lab.labtimesheet.feature.task.service.TaskService; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +@Import({TestcontainersConfiguration.class, RoleDashboardWebIntegrationTest.MailProbeConfiguration.class}) +@SpringBootTest +@AutoConfigureMockMvc +@ActiveProfiles("test") +@Transactional +class RoleDashboardWebIntegrationTest { + + @Autowired + private MockMvc mvc; + + @Autowired + private BootstrapService bootstrap; + + @Autowired + private AccountService accounts; + + @Autowired + private SmtpConfigurationService smtp; + + @Autowired + private RecordingSmtpProbe mail; + + @Autowired + private ProjectService projects; + + @Autowired + private ProjectQueryService projectQueries; + + @Autowired + private TaskService tasks; + + @Test + void mentorAndInternDashboardsRenderRealScopedProjectTaskAndAttendanceData() throws Exception { + long adminId = initializeAdminAndSmtp(); + long mentorId = createActiveAccount( + adminId, + new CreateAccountCommand( + "mentor@example.test", "Minh Mentor", GlobalRole.MENTOR, null, null, null)); + long internId = createActiveAccount( + adminId, + new CreateAccountCommand( + "intern@example.test", + "Mai Intern", + GlobalRole.INTERN, + "INT-001", + LocalDate.of(2026, 8, 1), + LocalDate.of(2026, 12, 31))); + accounts.activateInternship(internId, adminId); + + long projectId = projects.create( + mentorId, + new ProjectCreateCommand( + "Intern Portal", + "Portal refresh", + LocalDate.of(2026, 8, 1), + LocalDate.of(2026, 9, 30), + internId)); + projects.activate(mentorId, projectId); + long membershipId = projectQueries.taskContext(internId, projectId).currentLeaderMembershipId(); + var task = tasks.create( + "intern@example.test", + new CreateTaskCommand( + projectId, + membershipId, + "Resolve accessibility review", + null, + LocalDate.of(2026, 8, 20))); + tasks.changeStatus("intern@example.test", projectId, task.id(), TaskStatus.BLOCKED); + + mvc.perform(get("/dashboard").with(user("mentor@example.test").roles("MENTOR"))) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("Good morning, Minh Mentor"))) + .andExpect(content().string(containsString( + "Active owned Projects