address platform review findings and document APIs

This commit is contained in:
sechmachine
2026-08-15 02:43:01 +07:00
parent 17fa25bb09
commit 8ff6ee3d87
44 changed files with 573 additions and 1 deletions
@@ -11,13 +11,19 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.sql.DataSource;
import com.lab.labtimesheet.LabtimesheetApplication;
import com.lab.labtimesheet.config.TestcontainersConfiguration;
import com.lab.labtimesheet.feature.account.model.AccountStatus;
import com.lab.labtimesheet.feature.account.model.GlobalRole;
import com.lab.labtimesheet.feature.account.repository.AppUserRepository;
import com.lab.labtimesheet.feature.account.repository.SystemStateRepository;
import com.zaxxer.hikari.HikariDataSource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.context.annotation.Import;
@@ -47,6 +53,9 @@ class BootstrapIntegrationTest {
@Autowired
private SystemStateRepository systemStates;
@Autowired
private DataSource dataSource;
@Test
void onlyBootstrapAndHealthAreAvailableBeforeInitialization() throws Exception {
mockMvc.perform(get("/bootstrap")).andExpect(status().isOk());
@@ -87,6 +96,29 @@ class BootstrapIntegrationTest {
assertThat(systemStates.findById((short) 1).orElseThrow().isInitialized()).isTrue();
}
@Test
void bootstrapRemainsClosedInAnIndependentApplicationContext() {
bootstrapService.bootstrap("admin@example.com", "First Admin", "correct horse battery staple");
HikariDataSource currentDataSource = (HikariDataSource) dataSource;
try (var restarted = new SpringApplicationBuilder(LabtimesheetApplication.class)
.profiles("test")
.web(WebApplicationType.SERVLET)
.properties(
"server.port=0",
"spring.main.register-shutdown-hook=false",
"spring.datasource.url=" + currentDataSource.getJdbcUrl(),
"spring.datasource.username=" + currentDataSource.getUsername(),
"spring.datasource.password=" + currentDataSource.getPassword())
.run()) {
BootstrapService restartedBootstrap = restarted.getBean(BootstrapService.class);
assertThat(restartedBootstrap.isInitialized()).isTrue();
assertThat(restartedBootstrap.bootstrap(
"another@example.com", "Another", "correct horse battery staple"))
.isEqualTo(BootstrapService.BootstrapOutcome.ALREADY_INITIALIZED);
}
}
@Test
void exposesIdentityAndDateAwareInternEligibilityWithoutPersistenceTypes() {
bootstrapService.bootstrap("admin@example.com", "First Admin", "correct horse battery staple");
@@ -141,6 +141,36 @@ class SmtpOnboardingWebIntegrationTest {
.andExpect(status().isForbidden());
}
@Test
void failedSmtpTestRendersActionableFeedbackWithoutActivatingTheDraft() throws Exception {
mockMvc.perform(post("/admin/smtp/draft")
.with(user("admin@example.com").roles("ADMIN"))
.with(csrf())
.param("host", "mailpit")
.param("port", "1025")
.param("securityMode", "NONE")
.param("fromAddress", "notifications@example.com")
.param("fromName", "Lab Timesheet"))
.andExpect(status().is3xxRedirection());
String html = mockMvc.perform(get("/admin/smtp")
.with(user("admin@example.com").roles("ADMIN")))
.andReturn().getResponse().getContentAsString();
String draftId = html.replaceAll("(?s).*name=\"draftId\" value=\"([0-9]+)\".*", "$1");
probe.failureMessage = "Connection refused by the configured SMTP server";
mockMvc.perform(post("/admin/smtp/test")
.with(user("admin@example.com").roles("ADMIN"))
.with(csrf())
.param("draftId", draftId))
.andExpect(status().isOk())
.andExpect(view().name("smtp/form"))
.andExpect(content().string(org.hamcrest.Matchers.containsString(
"Connection refused by the configured SMTP server")))
.andExpect(content().string(org.hamcrest.Matchers.not(
org.hamcrest.Matchers.containsString("Activate SMTP"))));
}
@TestConfiguration(proxyBeanMethods = false)
static class ProbeConfiguration {
@Bean
@@ -152,9 +182,13 @@ class SmtpOnboardingWebIntegrationTest {
static final class RecordingProbe implements SmtpProbe {
private final List<String> recipients = new ArrayList<>();
private String failureMessage;
@Override
public void send(SmtpConnection connection, String recipient, String subject, String body) {
if (failureMessage != null) {
throw new IllegalStateException(failureMessage);
}
recipients.add(recipient);
}
}