Improve REST path binding for enum path variables and valueOf

Treat enum @PathVariable parameters as internal triggers, expand multiple path placeholders via cartesian bindings, derive event cases from proven Enum.valueOf chains, and add enterprise HTML regression coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-14 06:52:27 +02:00
parent 24fe8dfe00
commit 5d432e8893
5 changed files with 295 additions and 8 deletions

View File

@@ -0,0 +1,64 @@
package click.kamil.springstatemachineexporter.html;
import click.kamil.springstatemachineexporter.exporter.JsonExporter;
import click.kamil.springstatemachineexporter.html.exporter.HtmlExporter;
import click.kamil.springstatemachineexporter.service.ExportService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Enterprise dedicated REST endpoints must produce HTML explorer link keys end-to-end;
* generic {@code {event}} dispatchers remain unresolved external.
*/
class EnterpriseDedicatedEndpointHtmlTest {
private static final String PAY_ENDPOINT = "POST /api/machine/order/pay";
private static final String GENERIC_ENDPOINT = "POST /api/machine/{machineType}/transition/{event}";
@Test
void htmlShouldExposeLinkKeysForDedicatedPayEndpoint(@TempDir Path tempDir) throws Exception {
Path enterprise = findProjectRoot().resolve("state_machines/state_machine_enterprise");
ExportService exportService = new ExportService(List.of(new HtmlExporter(), new JsonExporter()));
exportService.runExporter(enterprise, tempDir, List.of("html"), true, List.of(), null, null,
click.kamil.springstatemachineexporter.exporter.EnumFormat.fn,
click.kamil.springstatemachineexporter.exporter.EnumFormat.fn);
Path htmlFile = findOrderMachineHtml(tempDir);
String html = Files.readString(htmlFile);
assertThat(html).contains(PAY_ENDPOINT);
assertThat(html).contains("\"linkResolution\" : \"RESOLVED\"");
assertThat(html).contains("#link_");
assertThat(html).contains("\"linkKey\"");
assertThat(html).contains(GENERIC_ENDPOINT);
assertThat(html).contains("linkResolution === 'UNRESOLVED_EXTERNAL'");
}
private static Path findOrderMachineHtml(Path outputDir) throws Exception {
Path machineDir;
try (var stream = Files.list(outputDir)) {
machineDir = stream
.filter(Files::isDirectory)
.filter(path -> path.getFileName().toString().endsWith("OrderStateMachineConfiguration"))
.findFirst()
.orElseThrow(() -> new IllegalStateException("Order machine output not found"));
}
Path htmlFile = machineDir.resolve(machineDir.getFileName() + ".html");
assertThat(htmlFile).exists();
return htmlFile;
}
private static Path findProjectRoot() {
Path current = Path.of(".").toAbsolutePath();
while (current != null && !Files.exists(current.resolve("settings.gradle"))) {
current = current.getParent();
}
return current;
}
}