Mise à jour des tests unitaires et passage en v0.9.2-beta en conséquence.
Some checks failed
Build & Push Images / build (brain) (push) Has been cancelled
Build & Push Images / build (core) (push) Has been cancelled
Build & Push Images / build (web) (push) Has been cancelled
Build & Push Images / build-switcher (push) Has been cancelled

This commit is contained in:
2026-06-03 15:56:26 +02:00
parent 504c4b7b6c
commit 091de0daf7
8 changed files with 31 additions and 25 deletions

View File

@@ -46,7 +46,7 @@ from app.infrastructure.onemin_adapter import OneMinAiLLMProvider
app = FastAPI( app = FastAPI(
title="LoreMind Brain", title="LoreMind Brain",
description="Backend IA pour la génération de contenu narratif.", description="Backend IA pour la génération de contenu narratif.",
version="0.9.1-beta", version="0.9.2-beta",
) )

View File

@@ -14,7 +14,7 @@
<groupId>com.loremind</groupId> <groupId>com.loremind</groupId>
<artifactId>loremind-core</artifactId> <artifactId>loremind-core</artifactId>
<version>0.9.1-beta</version> <version>0.9.2-beta</version>
<name>LoreMind Core</name> <name>LoreMind Core</name>
<description>Backend Core - Architecture Hexagonale</description> <description>Backend Core - Architecture Hexagonale</description>

View File

@@ -1,15 +1,16 @@
package com.loremind.application.campaigncontext; package com.loremind.application.campaigncontext;
import com.loremind.application.playcontext.PlaythroughService;
import com.loremind.domain.campaigncontext.Arc; import com.loremind.domain.campaigncontext.Arc;
import com.loremind.domain.campaigncontext.Campaign; import com.loremind.domain.campaigncontext.Campaign;
import com.loremind.domain.campaigncontext.Chapter; import com.loremind.domain.campaigncontext.Chapter;
import com.loremind.domain.campaigncontext.Character;
import com.loremind.domain.campaigncontext.Scene; import com.loremind.domain.campaigncontext.Scene;
import com.loremind.domain.campaigncontext.ports.ArcRepository; import com.loremind.domain.campaigncontext.ports.ArcRepository;
import com.loremind.domain.campaigncontext.ports.CampaignRepository; import com.loremind.domain.campaigncontext.ports.CampaignRepository;
import com.loremind.domain.campaigncontext.ports.ChapterRepository; import com.loremind.domain.campaigncontext.ports.ChapterRepository;
import com.loremind.domain.campaigncontext.ports.CharacterRepository;
import com.loremind.domain.campaigncontext.ports.SceneRepository; import com.loremind.domain.campaigncontext.ports.SceneRepository;
import com.loremind.domain.playcontext.Playthrough;
import com.loremind.domain.playcontext.ports.PlaythroughRepository;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@@ -42,7 +43,9 @@ public class CampaignServiceTest {
@Mock @Mock
private SceneRepository sceneRepository; private SceneRepository sceneRepository;
@Mock @Mock
private CharacterRepository characterRepository; private PlaythroughRepository playthroughRepository;
@Mock
private PlaythroughService playthroughService;
@InjectMocks @InjectMocks
private CampaignService campaignService; private CampaignService campaignService;
@@ -222,7 +225,7 @@ public class CampaignServiceTest {
verify(arcRepository, never()).deleteById(anyString()); verify(arcRepository, never()).deleteById(anyString());
verify(chapterRepository, never()).deleteById(anyString()); verify(chapterRepository, never()).deleteById(anyString());
verify(sceneRepository, never()).deleteById(anyString()); verify(sceneRepository, never()).deleteById(anyString());
verify(characterRepository, never()).deleteById(anyString()); verify(playthroughService, never()).delete(anyString());
} }
@Test @Test
@@ -249,13 +252,15 @@ public class CampaignServiceTest {
} }
@Test @Test
void testDeleteCampaign_CascadesCharacters() { void testDeleteCampaign_CascadesPlaythroughs() {
Character pc = Character.builder().id("char-1").campaignId("campaign-1").name("Alric").build(); // Depuis Playthrough : les PJ/sessions ne sont plus rattachés à la campagne ;
when(characterRepository.findByCampaignId("campaign-1")).thenReturn(List.of(pc)); // la suppression cascade sur les Parties, qui cascadent elles-mêmes.
Playthrough play = Playthrough.builder().id("play-1").campaignId("campaign-1").name("Partie principale").build();
when(playthroughRepository.findByCampaignId("campaign-1")).thenReturn(List.of(play));
campaignService.deleteCampaign("campaign-1"); campaignService.deleteCampaign("campaign-1");
verify(characterRepository).deleteById("char-1"); verify(playthroughService).delete("play-1");
verify(campaignRepository).deleteById("campaign-1"); verify(campaignRepository).deleteById("campaign-1");
} }
@@ -267,20 +272,20 @@ public class CampaignServiceTest {
Scene s1 = Scene.builder().id("s-1").chapterId("chap-1").name("S1").build(); Scene s1 = Scene.builder().id("s-1").chapterId("chap-1").name("S1").build();
Scene s2 = Scene.builder().id("s-2").chapterId("chap-2").name("S2").build(); Scene s2 = Scene.builder().id("s-2").chapterId("chap-2").name("S2").build();
Scene s3 = Scene.builder().id("s-3").chapterId("chap-2").name("S3").build(); Scene s3 = Scene.builder().id("s-3").chapterId("chap-2").name("S3").build();
Character pc = Character.builder().id("char-1").campaignId("campaign-1").name("Alric").build(); Playthrough play = Playthrough.builder().id("play-1").campaignId("campaign-1").name("Partie principale").build();
when(arcRepository.findByCampaignId("campaign-1")).thenReturn(List.of(arc)); when(arcRepository.findByCampaignId("campaign-1")).thenReturn(List.of(arc));
when(chapterRepository.findByArcId("arc-1")).thenReturn(List.of(c1, c2)); when(chapterRepository.findByArcId("arc-1")).thenReturn(List.of(c1, c2));
when(sceneRepository.findByChapterId("chap-1")).thenReturn(List.of(s1)); when(sceneRepository.findByChapterId("chap-1")).thenReturn(List.of(s1));
when(sceneRepository.findByChapterId("chap-2")).thenReturn(List.of(s2, s3)); when(sceneRepository.findByChapterId("chap-2")).thenReturn(List.of(s2, s3));
when(characterRepository.findByCampaignId("campaign-1")).thenReturn(List.of(pc)); when(playthroughRepository.findByCampaignId("campaign-1")).thenReturn(List.of(play));
CampaignService.DeletionImpact impact = campaignService.getDeletionImpact("campaign-1"); CampaignService.DeletionImpact impact = campaignService.getDeletionImpact("campaign-1");
assertEquals(1, impact.arcs()); assertEquals(1, impact.arcs());
assertEquals(2, impact.chapters()); assertEquals(2, impact.chapters());
assertEquals(3, impact.scenes()); assertEquals(3, impact.scenes());
assertEquals(1, impact.characters()); assertEquals(1, impact.playthroughs());
} }
@Test @Test

View File

@@ -151,11 +151,11 @@ public class CampaignStructuralContextBuilderTest {
@Test @Test
void testBuild_ProjectsCharactersAndNpcsWithSnippets() { void testBuild_ProjectsCharactersAndNpcsWithSnippets() {
Character pj1 = Character.builder().id("c-1").campaignId("camp-1").order(1) Character pj1 = Character.builder().id("c-1").playthroughId("play-1").order(1)
.name("Aragorn") .name("Aragorn")
.values(new java.util.HashMap<>(java.util.Map.of("Histoire", "# Aragorn\n\nRôdeur du Nord, héritier d'Isildur."))) .values(new java.util.HashMap<>(java.util.Map.of("Histoire", "# Aragorn\n\nRôdeur du Nord, héritier d'Isildur.")))
.build(); .build();
Character pj2 = Character.builder().id("c-2").campaignId("camp-1").order(2) Character pj2 = Character.builder().id("c-2").playthroughId("play-1").order(2)
.name("Legolas") .name("Legolas")
.values(null) // pas de snippet → string vide .values(null) // pas de snippet → string vide
.build(); .build();
@@ -170,10 +170,10 @@ public class CampaignStructuralContextBuilderTest {
when(campaignRepository.findById("camp-1")).thenReturn(Optional.of(campaign)); when(campaignRepository.findById("camp-1")).thenReturn(Optional.of(campaign));
when(arcRepository.findByCampaignId("camp-1")).thenReturn(List.of()); when(arcRepository.findByCampaignId("camp-1")).thenReturn(List.of());
when(characterRepository.findByCampaignId("camp-1")).thenReturn(List.of(pj2, pj1)); when(characterRepository.findByPlaythroughId("play-1")).thenReturn(List.of(pj2, pj1));
when(npcRepository.findByCampaignId("camp-1")).thenReturn(List.of(npc1, npc2)); when(npcRepository.findByCampaignId("camp-1")).thenReturn(List.of(npc1, npc2));
CampaignStructuralContext ctx = builder.build("camp-1"); CampaignStructuralContext ctx = builder.build("camp-1", "play-1");
// PJ triés par order croissant // PJ triés par order croissant
assertEquals(2, ctx.characters().size()); assertEquals(2, ctx.characters().size());

View File

@@ -25,7 +25,8 @@ class CampaignStructuralContextTest {
"L'auberge", "L'auberge",
"Rencontre tendue avec le tavernier", "Rencontre tendue avec le tavernier",
2, 2,
List.of(branch)); List.of(branch),
List.of());
ChapterSummary chapter = new ChapterSummary( ChapterSummary chapter = new ChapterSummary(
"L'arrivee", "L'arrivee",
@@ -77,7 +78,7 @@ class CampaignStructuralContextTest {
void illustrationCount_defaultsToZero_onAllSummaryTypes() { void illustrationCount_defaultsToZero_onAllSummaryTypes() {
ArcSummary arc = new ArcSummary("X", null, 0, List.of()); ArcSummary arc = new ArcSummary("X", null, 0, List.of());
ChapterSummary chapter = new ChapterSummary("X", null, 0, List.of()); ChapterSummary chapter = new ChapterSummary("X", null, 0, List.of());
SceneSummary scene = new SceneSummary("X", null, 0, List.of()); SceneSummary scene = new SceneSummary("X", null, 0, List.of(), List.of());
assertEquals(0, arc.illustrationCount()); assertEquals(0, arc.illustrationCount());
assertEquals(0, chapter.illustrationCount()); assertEquals(0, chapter.illustrationCount());

View File

@@ -163,7 +163,7 @@ class BrainChatPayloadBuilderTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
void build_campaignContext_serializesFullNarrativeTree() { void build_campaignContext_serializesFullNarrativeTree() {
BranchHint branch = new BranchHint("fuite", "La poursuite", "HP < 50%"); BranchHint branch = new BranchHint("fuite", "La poursuite", "HP < 50%");
SceneSummary scene = new SceneSummary("L'auberge", "Rencontre tendue", 3, List.of(branch)); SceneSummary scene = new SceneSummary("L'auberge", "Rencontre tendue", 3, List.of(branch), List.of());
ChapterSummary chapter = new ChapterSummary("L'arrivee", "...", 0, List.of(scene)); ChapterSummary chapter = new ChapterSummary("L'arrivee", "...", 0, List.of(scene));
ArcSummary arc = new ArcSummary("Acte I", "Mise en place", 1, List.of(chapter)); ArcSummary arc = new ArcSummary("Acte I", "Mise en place", 1, List.of(chapter));
CampaignStructuralContext camp = new CampaignStructuralContext( CampaignStructuralContext camp = new CampaignStructuralContext(
@@ -213,7 +213,7 @@ class BrainChatPayloadBuilderTest {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
void build_sceneSummary_omitsBranches_whenEmpty() { void build_sceneSummary_omitsBranches_whenEmpty() {
SceneSummary scene = new SceneSummary("S", "", 0, List.of()); SceneSummary scene = new SceneSummary("S", "", 0, List.of(), List.of());
ChapterSummary chapter = new ChapterSummary("Ch", "", 0, List.of(scene)); ChapterSummary chapter = new ChapterSummary("Ch", "", 0, List.of(scene));
ArcSummary arc = new ArcSummary("A", "", 0, List.of(chapter)); ArcSummary arc = new ArcSummary("A", "", 0, List.of(chapter));
CampaignStructuralContext camp = new CampaignStructuralContext( CampaignStructuralContext camp = new CampaignStructuralContext(
@@ -232,7 +232,7 @@ class BrainChatPayloadBuilderTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
void build_branchHint_omitsCondition_whenBlank() { void build_branchHint_omitsCondition_whenBlank() {
BranchHint branch = new BranchHint("X", "Y", " "); BranchHint branch = new BranchHint("X", "Y", " ");
SceneSummary scene = new SceneSummary("S", "", 0, List.of(branch)); SceneSummary scene = new SceneSummary("S", "", 0, List.of(branch), List.of());
ChapterSummary chapter = new ChapterSummary("Ch", "", 0, List.of(scene)); ChapterSummary chapter = new ChapterSummary("Ch", "", 0, List.of(scene));
ArcSummary arc = new ArcSummary("A", "", 0, List.of(chapter)); ArcSummary arc = new ArcSummary("A", "", 0, List.of(chapter));
CampaignStructuralContext camp = new CampaignStructuralContext( CampaignStructuralContext camp = new CampaignStructuralContext(

4
web/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "loremind-web", "name": "loremind-web",
"version": "0.9.1-beta", "version": "0.9.2-beta",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "loremind-web", "name": "loremind-web",
"version": "0.9.1-beta", "version": "0.9.2-beta",
"dependencies": { "dependencies": {
"@angular/animations": "^17.0.0", "@angular/animations": "^17.0.0",
"@angular/common": "^17.0.0", "@angular/common": "^17.0.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "loremind-web", "name": "loremind-web",
"version": "0.9.1-beta", "version": "0.9.2-beta",
"description": "LoreMind Frontend - Angular", "description": "LoreMind Frontend - Angular",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",