This commit is contained in:
63
modules/core/deployment/pom.xml
Normal file
63
modules/core/deployment/pom.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>fr.cnd.compositor</groupId>
|
||||
<artifactId>core-parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>core-deployment</artifactId>
|
||||
<name>Core - Deployment</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-arc-deployment</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-rest-jackson-deployment</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>fr.cnd.compositor</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit-internal</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-extension-processor</artifactId>
|
||||
<version>${quarkus.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,14 @@
|
||||
package fr.cnd.compositor.core.deployment;
|
||||
|
||||
import io.quarkus.deployment.annotations.BuildStep;
|
||||
import io.quarkus.deployment.builditem.FeatureBuildItem;
|
||||
|
||||
class CoreProcessor {
|
||||
|
||||
private static final String FEATURE = "core";
|
||||
|
||||
@BuildStep
|
||||
FeatureBuildItem feature() {
|
||||
return new FeatureBuildItem(FEATURE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package fr.cnd.compositor.blocks.blocks;
|
||||
|
||||
import fr.cnd.compositor.models.BlockRenderDefinition;
|
||||
import fr.cnd.compositor.blocks.specs.BlockTemplate;
|
||||
import io.smallrye.common.annotation.Identifier;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
/**
|
||||
* Implémentation de test pour {@link BlockTemplate}.
|
||||
*/
|
||||
@Identifier("test-block")
|
||||
@ApplicationScoped
|
||||
public class TestBlockTemplate implements BlockTemplate {
|
||||
|
||||
@Override
|
||||
public Uni<String> render(BlockRenderDefinition definition) {
|
||||
return Uni.createFrom().item("<div>Test Block</div>");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package fr.cnd.compositor.blocks.pebble;
|
||||
|
||||
import fr.cnd.compositor.models.BlockRenderDefinition;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.inject.Inject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@QuarkusTest
|
||||
class AbstractPebbleBlockTemplateTest {
|
||||
|
||||
@Inject
|
||||
PebbleBlockEngine engine;
|
||||
|
||||
@Test
|
||||
void shouldRenderStaticTemplate() {
|
||||
AbstractPebbleBlockTemplate template = createTemplate("<div>Hello</div>");
|
||||
|
||||
String result = template.render(BlockRenderDefinition.builder().build()).await().indefinitely();
|
||||
|
||||
assertEquals("<div>Hello</div>", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRenderTemplateWithContext() {
|
||||
AbstractPebbleBlockTemplate template = createTemplate("<div>Hello {{ name }}</div>");
|
||||
Map<String, Object> context = Map.of("name", "World");
|
||||
|
||||
String result = template.render(BlockRenderDefinition.builder()
|
||||
.inputs(context)
|
||||
.build()).await().indefinitely();
|
||||
|
||||
assertEquals("<div>Hello World</div>", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRenderTemplateWithEmptyContext() {
|
||||
AbstractPebbleBlockTemplate template = createTemplate("<span>Static content</span>");
|
||||
final Map<String, Object> context = new HashMap<>();
|
||||
|
||||
String result = template.render(BlockRenderDefinition.builder()
|
||||
.inputs(context)
|
||||
.build()).await().indefinitely();
|
||||
|
||||
assertEquals("<span>Static content</span>", result);
|
||||
}
|
||||
|
||||
private AbstractPebbleBlockTemplate createTemplate(String templateContent) {
|
||||
AbstractPebbleBlockTemplate template = new AbstractPebbleBlockTemplate() {
|
||||
@Override
|
||||
public Uni<String> getTemplate() {
|
||||
return Uni.createFrom().item(templateContent);
|
||||
}
|
||||
};
|
||||
template.setEngine(engine);
|
||||
return template;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package fr.cnd.compositor.blocks.pebble;
|
||||
|
||||
import fr.cnd.compositor.blocks.specs.BlockEngine;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import jakarta.inject.Inject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Tests unitaires pour {@link PebbleBlockEngine}.
|
||||
* <p>
|
||||
* Cette classe vérifie le comportement du moteur de rendu Pebble
|
||||
* qui implémente l'interface {@link BlockEngine}.
|
||||
*/
|
||||
@QuarkusTest
|
||||
class PebbleBlockEngineTest {
|
||||
|
||||
@Inject
|
||||
PebbleBlockEngine pebbleBlockEngine;
|
||||
|
||||
@Test
|
||||
void shouldRenderSimpleTemplate() {
|
||||
String content = "Hello World";
|
||||
|
||||
String result = pebbleBlockEngine.render(content, Collections.emptyMap())
|
||||
.await().indefinitely();
|
||||
|
||||
assertEquals("Hello World", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRenderTemplateWithVariable() {
|
||||
String content = "Hello {{ name }}!";
|
||||
Map<String, Object> context = Map.of("name", "Guillaume");
|
||||
|
||||
String result = pebbleBlockEngine.render(content, context)
|
||||
.await().indefinitely();
|
||||
|
||||
assertEquals("Hello Guillaume!", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRenderTemplateWithMultipleVariables() {
|
||||
String content = "{{ greeting }} {{ name }}, you have {{ count }} messages.";
|
||||
Map<String, Object> context = Map.of(
|
||||
"greeting", "Bonjour",
|
||||
"name", "Alice",
|
||||
"count", 5
|
||||
);
|
||||
|
||||
String result = pebbleBlockEngine.render(content, context)
|
||||
.await().indefinitely();
|
||||
|
||||
assertEquals("Bonjour Alice, you have 5 messages.", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRenderTemplateWithConditional() {
|
||||
String content = "{% if active %}Active{% else %}Inactive{% endif %}";
|
||||
|
||||
String resultActive = pebbleBlockEngine.render(content, Map.of("active", true))
|
||||
.await().indefinitely();
|
||||
String resultInactive = pebbleBlockEngine.render(content, Map.of("active", false))
|
||||
.await().indefinitely();
|
||||
|
||||
assertEquals("Active", resultActive);
|
||||
assertEquals("Inactive", resultInactive);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRenderTemplateWithLoop() {
|
||||
String content = "{% for item in items %}{{ item }}{% if not loop.last %}, {% endif %}{% endfor %}";
|
||||
Map<String, Object> context = Map.of("items", java.util.List.of("A", "B", "C"));
|
||||
|
||||
String result = pebbleBlockEngine.render(content, context)
|
||||
.await().indefinitely();
|
||||
|
||||
assertEquals("A, B, C", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleEmptyContext() {
|
||||
String content = "Static content only";
|
||||
|
||||
String result = pebbleBlockEngine.render(content, Collections.emptyMap())
|
||||
.await().indefinitely();
|
||||
|
||||
assertEquals("Static content only", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleMissingVariableGracefully() {
|
||||
String content = "Hello {{ name }}!";
|
||||
|
||||
String result = pebbleBlockEngine.render(content, Collections.emptyMap())
|
||||
.await().indefinitely();
|
||||
|
||||
assertEquals("Hello !", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowExceptionForInvalidTemplate() {
|
||||
String content = "{% invalid syntax %}";
|
||||
|
||||
RuntimeException exception = assertThrows(RuntimeException.class, () ->
|
||||
pebbleBlockEngine.render(content, Collections.emptyMap())
|
||||
.await().indefinitely()
|
||||
);
|
||||
|
||||
assertTrue(exception.getMessage().contains("Failed to render template content"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package fr.cnd.compositor.blocks.resolvers;
|
||||
|
||||
import fr.cnd.compositor.models.BlockRenderDefinition;
|
||||
import fr.cnd.compositor.blocks.specs.BlockTemplate;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import jakarta.inject.Inject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Tests unitaires pour {@link CDIBlockTemplateResolver}.
|
||||
* <p>
|
||||
* Cette classe vérifie le comportement du resolver qui recherche
|
||||
* les instances de {@link BlockTemplate} par leur annotation {@code @Identifier}.
|
||||
*/
|
||||
@QuarkusTest
|
||||
class CDIBlockTemplateResolverTest {
|
||||
|
||||
@Inject
|
||||
CDIBlockTemplateResolver resolver;
|
||||
|
||||
/**
|
||||
* Vérifie que le resolver retourne null lorsque le template n'existe pas.
|
||||
*/
|
||||
@Test
|
||||
void shouldReturnNullWhenTemplateNotFound() {
|
||||
BlockTemplate result = resolver.resolveTemplate("unknown-template").await().indefinitely();
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie que le resolver trouve et retourne le template correspondant à l'identifiant.
|
||||
*/
|
||||
@Test
|
||||
void shouldResolveTemplateTemplateByIdentifier() {
|
||||
BlockTemplate result = resolver.resolveTemplate("test-block").await().indefinitely();
|
||||
|
||||
assertNotNull(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie que le template résolu peut effectuer un rendu.
|
||||
*/
|
||||
@Test
|
||||
void shouldResolveTemplateWorkingTemplate() {
|
||||
BlockTemplate result = resolver.resolveTemplate("test-block").await().indefinitely();
|
||||
|
||||
assertNotNull(result);
|
||||
String rendered = result.render(BlockRenderDefinition.builder().build()).await().indefinitely();
|
||||
assertEquals("<div>Test Block</div>", rendered);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package fr.cnd.compositor.blocks.services;
|
||||
|
||||
import fr.cnd.compositor.models.BlockRenderDefinition;
|
||||
import fr.cnd.compositor.blocks.specs.BlockTemplate;
|
||||
import fr.cnd.compositor.blocks.specs.BlockTemplateResolver;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import jakarta.inject.Inject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Tests unitaires pour {@link BlockService}.
|
||||
* <p>
|
||||
* Cette classe vérifie le comportement du service de résolution des templates
|
||||
* qui parcourt les différents {@link BlockTemplateResolver}
|
||||
* pour trouver le premier template correspondant.
|
||||
*/
|
||||
@QuarkusTest
|
||||
class BlockServiceTest {
|
||||
|
||||
@Inject
|
||||
BlockService blockService;
|
||||
|
||||
/**
|
||||
* Vérifie que le service retourne null lorsque aucun resolver ne trouve le template.
|
||||
*/
|
||||
@Test
|
||||
void shouldReturnNullWhenNoResolverFindsTemplate() {
|
||||
BlockTemplate result = blockService.resolveTemplate("unknown-template").await().indefinitely();
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie que le service trouve un template existant via les resolvers.
|
||||
*/
|
||||
@Test
|
||||
void shouldResolveTemplateExistingTemplate() {
|
||||
BlockTemplate result = blockService.resolveTemplate("test-block").await().indefinitely();
|
||||
|
||||
assertNotNull(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie que le template résolu peut effectuer un rendu correct.
|
||||
*/
|
||||
@Test
|
||||
void shouldResolveTemplateWorkingTemplate() {
|
||||
BlockTemplate result = blockService.resolveTemplate("test-block").await().indefinitely();
|
||||
|
||||
assertNotNull(result);
|
||||
String rendered = result.render(BlockRenderDefinition.builder().build()).await().indefinitely();
|
||||
assertEquals("<div>Test Block</div>", rendered);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user