Mise en ligne de la version 0.2.0
All checks were successful
Build & Push Images / build (brain) (push) Successful in 46s
Build & Push Images / build (core) (push) Successful in 1m21s
Build & Push Images / build (web) (push) Successful in 1m25s

This commit is contained in:
2026-04-21 14:25:17 +02:00
parent ebee8e106b
commit ba8a503b3e
300 changed files with 35329 additions and 1 deletions

View File

@@ -0,0 +1,198 @@
package com.loremind.application.campaigncontext;
import com.loremind.domain.campaigncontext.Arc;
import com.loremind.domain.campaigncontext.ports.ArcRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
/**
* Test unitaire pour ArcService.
* Utilise des mocks pour les ports de sortie (ArcRepository).
* Teste la logique d'orchestration de la couche Application.
*/
@ExtendWith(MockitoExtension.class)
public class ArcServiceTest {
@Mock
private ArcRepository arcRepository;
@InjectMocks
private ArcService arcService;
private Arc testArc;
@BeforeEach
void setUp() {
testArc = Arc.builder()
.id("arc-1")
.name("Test Arc")
.description("Test Description")
.campaignId("campaign-1")
.order(1)
.build();
}
@Test
void testCreateArc() {
// Arrange
when(arcRepository.save(any(Arc.class))).thenReturn(testArc);
// Act
Arc result = arcService.createArc("New Arc", "Description", "campaign-1", 1);
// Assert
assertNotNull(result);
verify(arcRepository, times(1)).save(any(Arc.class));
}
@Test
void testGetArcById_Found() {
// Arrange
when(arcRepository.findById("arc-1")).thenReturn(Optional.of(testArc));
// Act
Optional<Arc> result = arcService.getArcById("arc-1");
// Assert
assertTrue(result.isPresent());
assertEquals("Test Arc", result.get().getName());
verify(arcRepository, times(1)).findById("arc-1");
}
@Test
void testGetArcById_NotFound() {
// Arrange
when(arcRepository.findById("invalid-id")).thenReturn(Optional.empty());
// Act
Optional<Arc> result = arcService.getArcById("invalid-id");
// Assert
assertFalse(result.isPresent());
verify(arcRepository, times(1)).findById("invalid-id");
}
@Test
void testGetAllArcs() {
// Arrange
Arc arc2 = Arc.builder()
.id("arc-2")
.name("Arc 2")
.build();
when(arcRepository.findAll()).thenReturn(List.of(testArc, arc2));
// Act
List<Arc> result = arcService.getAllArcs();
// Assert
assertEquals(2, result.size());
verify(arcRepository, times(1)).findAll();
}
@Test
void testGetArcsByCampaignId() {
// Arrange
when(arcRepository.findByCampaignId("campaign-1")).thenReturn(List.of(testArc));
// Act
List<Arc> result = arcService.getArcsByCampaignId("campaign-1");
// Assert
assertEquals(1, result.size());
verify(arcRepository, times(1)).findByCampaignId("campaign-1");
}
@Test
void testUpdateArc_Success() {
// Arrange
Arc updatedArc = Arc.builder()
.name("Updated Arc")
.description("Updated Description")
.order(2)
.themes("Theme1, Theme2")
.stakes("High stakes")
.gmNotes("GM notes")
.rewards("Rewards")
.resolution("Resolution")
.relatedPageIds(List.of("page-1"))
.illustrationImageIds(List.of("image-1"))
.build();
when(arcRepository.findById("arc-1")).thenReturn(Optional.of(testArc));
when(arcRepository.save(any(Arc.class))).thenReturn(testArc);
// Act
Arc result = arcService.updateArc("arc-1", updatedArc);
// Assert
assertNotNull(result);
verify(arcRepository, times(1)).findById("arc-1");
verify(arcRepository, times(1)).save(any(Arc.class));
}
@Test
void testUpdateArc_NotFound() {
// Arrange
Arc updatedArc = Arc.builder()
.name("Updated Arc")
.build();
when(arcRepository.findById("invalid-id")).thenReturn(Optional.empty());
// Act & Assert
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> arcService.updateArc("invalid-id", updatedArc)
);
assertEquals("Arc non trouvé avec l'ID: invalid-id", exception.getMessage());
verify(arcRepository, times(1)).findById("invalid-id");
verify(arcRepository, never()).save(any());
}
@Test
void testDeleteArc() {
// Arrange
doNothing().when(arcRepository).deleteById("arc-1");
// Act
arcService.deleteArc("arc-1");
// Assert
verify(arcRepository, times(1)).deleteById("arc-1");
}
@Test
void testArcExists_True() {
// Arrange
when(arcRepository.existsById("arc-1")).thenReturn(true);
// Act
boolean result = arcService.arcExists("arc-1");
// Assert
assertTrue(result);
verify(arcRepository, times(1)).existsById("arc-1");
}
@Test
void testArcExists_False() {
// Arrange
when(arcRepository.existsById("invalid-id")).thenReturn(false);
// Act
boolean result = arcService.arcExists("invalid-id");
// Assert
assertFalse(result);
verify(arcRepository, times(1)).existsById("invalid-id");
}
}

View File

@@ -0,0 +1,271 @@
package com.loremind.application.campaigncontext;
import com.loremind.domain.campaigncontext.Campaign;
import com.loremind.domain.campaigncontext.ports.CampaignRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;
/**
* Test unitaire pour CampaignService.
* Utilise des mocks pour les ports de sortie (CampaignRepository).
* Teste la logique d'orchestration de la couche Application.
*/
@ExtendWith(MockitoExtension.class)
public class CampaignServiceTest {
@Mock
private CampaignRepository campaignRepository;
@InjectMocks
private CampaignService campaignService;
private Campaign testCampaign;
@BeforeEach
void setUp() {
testCampaign = Campaign.builder()
.id("campaign-1")
.name("Test Campaign")
.description("Test Description")
.loreId("lore-1")
.arcsCount(0)
.build();
}
@Test
void testCreateCampaign_WithLoreId() {
// Arrange
CampaignService.CampaignData data = new CampaignService.CampaignData(
"New Campaign",
"Description",
"lore-123"
);
when(campaignRepository.save(any(Campaign.class))).thenReturn(testCampaign);
// Act
Campaign result = campaignService.createCampaign(data);
// Assert
assertNotNull(result);
verify(campaignRepository, times(1)).save(any(Campaign.class));
assertEquals("lore-123", result.getLoreId());
}
@Test
void testCreateCampaign_WithNullLoreId() {
// Arrange
CampaignService.CampaignData data = new CampaignService.CampaignData(
"New Campaign",
"Description",
null
);
when(campaignRepository.save(any(Campaign.class))).thenReturn(testCampaign);
// Act
Campaign result = campaignService.createCampaign(data);
// Assert
assertNotNull(result);
verify(campaignRepository, times(1)).save(any(Campaign.class));
assertNull(result.getLoreId());
}
@Test
void testCreateCampaign_WithBlankLoreId() {
// Arrange
CampaignService.CampaignData data = new CampaignService.CampaignData(
"New Campaign",
"Description",
" "
);
when(campaignRepository.save(any(Campaign.class))).thenReturn(testCampaign);
// Act
Campaign result = campaignService.createCampaign(data);
// Assert
assertNotNull(result);
verify(campaignRepository, times(1)).save(any(Campaign.class));
assertNull(result.getLoreId());
}
@Test
void testGetCampaignById_Found() {
// Arrange
when(campaignRepository.findById("campaign-1")).thenReturn(Optional.of(testCampaign));
// Act
Optional<Campaign> result = campaignService.getCampaignById("campaign-1");
// Assert
assertTrue(result.isPresent());
assertEquals("Test Campaign", result.get().getName());
verify(campaignRepository, times(1)).findById("campaign-1");
}
@Test
void testGetCampaignById_NotFound() {
// Arrange
when(campaignRepository.findById("invalid-id")).thenReturn(Optional.empty());
// Act
Optional<Campaign> result = campaignService.getCampaignById("invalid-id");
// Assert
assertFalse(result.isPresent());
verify(campaignRepository, times(1)).findById("invalid-id");
}
@Test
void testGetAllCampaigns() {
// Arrange
Campaign campaign2 = Campaign.builder()
.id("campaign-2")
.name("Campaign 2")
.build();
when(campaignRepository.findAll()).thenReturn(List.of(testCampaign, campaign2));
// Act
List<Campaign> result = campaignService.getAllCampaigns();
// Assert
assertEquals(2, result.size());
verify(campaignRepository, times(1)).findAll();
}
@Test
void testUpdateCampaign_Success() {
// Arrange
CampaignService.CampaignData data = new CampaignService.CampaignData(
"Updated Campaign",
"Updated Description",
"lore-456"
);
when(campaignRepository.findById("campaign-1")).thenReturn(Optional.of(testCampaign));
when(campaignRepository.save(any(Campaign.class))).thenReturn(testCampaign);
// Act
Campaign result = campaignService.updateCampaign("campaign-1", data);
// Assert
assertNotNull(result);
verify(campaignRepository, times(1)).findById("campaign-1");
verify(campaignRepository, times(1)).save(any(Campaign.class));
}
@Test
void testUpdateCampaign_NotFound() {
// Arrange
CampaignService.CampaignData data = new CampaignService.CampaignData(
"Updated Campaign",
"Updated Description",
"lore-456"
);
when(campaignRepository.findById("invalid-id")).thenReturn(Optional.empty());
// Act & Assert
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> campaignService.updateCampaign("invalid-id", data)
);
assertEquals("Campaign non trouvé avec l'ID: invalid-id", exception.getMessage());
verify(campaignRepository, times(1)).findById("invalid-id");
verify(campaignRepository, never()).save(any());
}
@Test
void testDeleteCampaign() {
// Arrange
doNothing().when(campaignRepository).deleteById("campaign-1");
// Act
campaignService.deleteCampaign("campaign-1");
// Assert
verify(campaignRepository, times(1)).deleteById("campaign-1");
}
@Test
void testCampaignExists_True() {
// Arrange
when(campaignRepository.existsById("campaign-1")).thenReturn(true);
// Act
boolean result = campaignService.campaignExists("campaign-1");
// Assert
assertTrue(result);
verify(campaignRepository, times(1)).existsById("campaign-1");
}
@Test
void testCampaignExists_False() {
// Arrange
when(campaignRepository.existsById("invalid-id")).thenReturn(false);
// Act
boolean result = campaignService.campaignExists("invalid-id");
// Assert
assertFalse(result);
verify(campaignRepository, times(1)).existsById("invalid-id");
}
@Test
void testSearchCampaigns_WithValidQuery() {
// Arrange
when(campaignRepository.searchByName("Test")).thenReturn(List.of(testCampaign));
// Act
List<Campaign> result = campaignService.searchCampaigns("Test");
// Assert
assertEquals(1, result.size());
verify(campaignRepository, times(1)).searchByName("Test");
}
@Test
void testSearchCampaigns_WithNullQuery() {
// Act
List<Campaign> result = campaignService.searchCampaigns(null);
// Assert
assertTrue(result.isEmpty());
verify(campaignRepository, never()).searchByName(anyString());
}
@Test
void testSearchCampaigns_WithBlankQuery() {
// Act
List<Campaign> result = campaignService.searchCampaigns(" ");
// Assert
assertTrue(result.isEmpty());
verify(campaignRepository, never()).searchByName(anyString());
}
@Test
void testSearchCampaigns_WithTrim() {
// Arrange
when(campaignRepository.searchByName("Test")).thenReturn(List.of(testCampaign));
// Act
List<Campaign> result = campaignService.searchCampaigns(" Test ");
// Assert
assertEquals(1, result.size());
verify(campaignRepository, times(1)).searchByName("Test");
}
}

View File

@@ -0,0 +1,196 @@
package com.loremind.application.campaigncontext;
import com.loremind.domain.campaigncontext.Chapter;
import com.loremind.domain.campaigncontext.ports.ChapterRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
/**
* Test unitaire pour ChapterService.
* Utilise des mocks pour les ports de sortie (ChapterRepository).
* Teste la logique d'orchestration de la couche Application.
*/
@ExtendWith(MockitoExtension.class)
public class ChapterServiceTest {
@Mock
private ChapterRepository chapterRepository;
@InjectMocks
private ChapterService chapterService;
private Chapter testChapter;
@BeforeEach
void setUp() {
testChapter = Chapter.builder()
.id("chapter-1")
.name("Test Chapter")
.description("Test Description")
.arcId("arc-1")
.order(1)
.build();
}
@Test
void testCreateChapter() {
// Arrange
when(chapterRepository.save(any(Chapter.class))).thenReturn(testChapter);
// Act
Chapter result = chapterService.createChapter("New Chapter", "Description", "arc-1", 1);
// Assert
assertNotNull(result);
verify(chapterRepository, times(1)).save(any(Chapter.class));
}
@Test
void testGetChapterById_Found() {
// Arrange
when(chapterRepository.findById("chapter-1")).thenReturn(Optional.of(testChapter));
// Act
Optional<Chapter> result = chapterService.getChapterById("chapter-1");
// Assert
assertTrue(result.isPresent());
assertEquals("Test Chapter", result.get().getName());
verify(chapterRepository, times(1)).findById("chapter-1");
}
@Test
void testGetChapterById_NotFound() {
// Arrange
when(chapterRepository.findById("invalid-id")).thenReturn(Optional.empty());
// Act
Optional<Chapter> result = chapterService.getChapterById("invalid-id");
// Assert
assertFalse(result.isPresent());
verify(chapterRepository, times(1)).findById("invalid-id");
}
@Test
void testGetAllChapters() {
// Arrange
Chapter chapter2 = Chapter.builder()
.id("chapter-2")
.name("Chapter 2")
.build();
when(chapterRepository.findAll()).thenReturn(List.of(testChapter, chapter2));
// Act
List<Chapter> result = chapterService.getAllChapters();
// Assert
assertEquals(2, result.size());
verify(chapterRepository, times(1)).findAll();
}
@Test
void testGetChaptersByArcId() {
// Arrange
when(chapterRepository.findByArcId("arc-1")).thenReturn(List.of(testChapter));
// Act
List<Chapter> result = chapterService.getChaptersByArcId("arc-1");
// Assert
assertEquals(1, result.size());
verify(chapterRepository, times(1)).findByArcId("arc-1");
}
@Test
void testUpdateChapter_Success() {
// Arrange
Chapter updatedChapter = Chapter.builder()
.name("Updated Chapter")
.description("Updated Description")
.order(2)
.gmNotes("GM notes")
.playerObjectives("Objectives")
.narrativeStakes("Stakes")
.relatedPageIds(List.of("page-1"))
.illustrationImageIds(List.of("image-1"))
.build();
when(chapterRepository.findById("chapter-1")).thenReturn(Optional.of(testChapter));
when(chapterRepository.save(any(Chapter.class))).thenReturn(testChapter);
// Act
Chapter result = chapterService.updateChapter("chapter-1", updatedChapter);
// Assert
assertNotNull(result);
verify(chapterRepository, times(1)).findById("chapter-1");
verify(chapterRepository, times(1)).save(any(Chapter.class));
}
@Test
void testUpdateChapter_NotFound() {
// Arrange
Chapter updatedChapter = Chapter.builder()
.name("Updated Chapter")
.build();
when(chapterRepository.findById("invalid-id")).thenReturn(Optional.empty());
// Act & Assert
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> chapterService.updateChapter("invalid-id", updatedChapter)
);
assertEquals("Chapter non trouvé avec l'ID: invalid-id", exception.getMessage());
verify(chapterRepository, times(1)).findById("invalid-id");
verify(chapterRepository, never()).save(any());
}
@Test
void testDeleteChapter() {
// Arrange
doNothing().when(chapterRepository).deleteById("chapter-1");
// Act
chapterService.deleteChapter("chapter-1");
// Assert
verify(chapterRepository, times(1)).deleteById("chapter-1");
}
@Test
void testChapterExists_True() {
// Arrange
when(chapterRepository.existsById("chapter-1")).thenReturn(true);
// Act
boolean result = chapterService.chapterExists("chapter-1");
// Assert
assertTrue(result);
verify(chapterRepository, times(1)).existsById("chapter-1");
}
@Test
void testChapterExists_False() {
// Arrange
when(chapterRepository.existsById("invalid-id")).thenReturn(false);
// Act
boolean result = chapterService.chapterExists("invalid-id");
// Assert
assertFalse(result);
verify(chapterRepository, times(1)).existsById("invalid-id");
}
}

View File

@@ -0,0 +1,358 @@
package com.loremind.application.campaigncontext;
import com.loremind.domain.campaigncontext.Scene;
import com.loremind.domain.campaigncontext.SceneBranch;
import com.loremind.domain.campaigncontext.ports.SceneRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
/**
* Test unitaire pour SceneService.
* Utilise des mocks pour les ports de sortie (SceneRepository).
* Teste la logique d'orchestration de la couche Application.
*/
@ExtendWith(MockitoExtension.class)
public class SceneServiceTest {
@Mock
private SceneRepository sceneRepository;
@InjectMocks
private SceneService sceneService;
private Scene testScene;
private Scene scene2;
private Scene scene3;
@BeforeEach
void setUp() {
testScene = Scene.builder()
.id("scene-1")
.name("Test Scene")
.description("Test Description")
.chapterId("chapter-1")
.order(1)
.build();
scene2 = Scene.builder()
.id("scene-2")
.name("Scene 2")
.chapterId("chapter-1")
.order(2)
.build();
scene3 = Scene.builder()
.id("scene-3")
.name("Scene 3")
.chapterId("chapter-1")
.order(3)
.build();
}
@Test
void testCreateScene() {
// Arrange
when(sceneRepository.save(any(Scene.class))).thenReturn(testScene);
// Act
Scene result = sceneService.createScene("New Scene", "Description", "chapter-1", 1);
// Assert
assertNotNull(result);
verify(sceneRepository, times(1)).save(any(Scene.class));
}
@Test
void testGetSceneById_Found() {
// Arrange
when(sceneRepository.findById("scene-1")).thenReturn(Optional.of(testScene));
// Act
Optional<Scene> result = sceneService.getSceneById("scene-1");
// Assert
assertTrue(result.isPresent());
assertEquals("Test Scene", result.get().getName());
verify(sceneRepository, times(1)).findById("scene-1");
}
@Test
void testGetSceneById_NotFound() {
// Arrange
when(sceneRepository.findById("invalid-id")).thenReturn(Optional.empty());
// Act
Optional<Scene> result = sceneService.getSceneById("invalid-id");
// Assert
assertFalse(result.isPresent());
verify(sceneRepository, times(1)).findById("invalid-id");
}
@Test
void testGetAllScenes() {
// Arrange
when(sceneRepository.findAll()).thenReturn(List.of(testScene, scene2));
// Act
List<Scene> result = sceneService.getAllScenes();
// Assert
assertEquals(2, result.size());
verify(sceneRepository, times(1)).findAll();
}
@Test
void testGetScenesByChapterId() {
// Arrange
when(sceneRepository.findByChapterId("chapter-1")).thenReturn(List.of(testScene, scene2));
// Act
List<Scene> result = sceneService.getScenesByChapterId("chapter-1");
// Assert
assertEquals(2, result.size());
verify(sceneRepository, times(1)).findByChapterId("chapter-1");
}
@Test
void testUpdateScene_Success() {
// Arrange
Scene updatedScene = Scene.builder()
.name("Updated Scene")
.description("Updated Description")
.order(2)
.location("Tavern")
.timing("Evening")
.atmosphere("Cozy")
.playerNarration("Narration")
.gmSecretNotes("Secret")
.choicesConsequences("Choices")
.combatDifficulty("Medium")
.enemies("Goblins")
.relatedPageIds(List.of("page-1"))
.illustrationImageIds(List.of("image-1"))
.branches(List.of())
.build();
when(sceneRepository.findById("scene-1")).thenReturn(Optional.of(testScene));
when(sceneRepository.save(any(Scene.class))).thenReturn(testScene);
// Act
Scene result = sceneService.updateScene("scene-1", updatedScene);
// Assert
assertNotNull(result);
verify(sceneRepository, times(1)).findById("scene-1");
verify(sceneRepository, times(1)).save(any(Scene.class));
}
@Test
void testUpdateScene_NotFound() {
// Arrange
Scene updatedScene = Scene.builder()
.name("Updated Scene")
.build();
when(sceneRepository.findById("invalid-id")).thenReturn(Optional.empty());
// Act & Assert
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> sceneService.updateScene("invalid-id", updatedScene)
);
assertEquals("Scene non trouvée avec l'ID: invalid-id", exception.getMessage());
verify(sceneRepository, times(1)).findById("invalid-id");
verify(sceneRepository, never()).save(any());
}
@Test
void testUpdateScene_WithValidBranches() {
// Arrange
SceneBranch branch = SceneBranch.builder()
.targetSceneId("scene-2")
.label("Go to scene 2")
.build();
Scene updatedScene = Scene.builder()
.name("Updated Scene")
.branches(List.of(branch))
.chapterId("chapter-1")
.build();
when(sceneRepository.findById("scene-1")).thenReturn(Optional.of(testScene));
when(sceneRepository.findByChapterId("chapter-1")).thenReturn(List.of(testScene, scene2, scene3));
when(sceneRepository.save(any(Scene.class))).thenReturn(testScene);
// Act
Scene result = sceneService.updateScene("scene-1", updatedScene);
// Assert
assertNotNull(result);
verify(sceneRepository, times(1)).findById("scene-1");
verify(sceneRepository, times(1)).save(any(Scene.class));
}
@Test
void testUpdateScene_WithBranchToSelf() {
// Arrange
SceneBranch branch = SceneBranch.builder()
.targetSceneId("scene-1")
.label("Self-reference")
.build();
Scene updatedScene = Scene.builder()
.name("Updated Scene")
.branches(List.of(branch))
.chapterId("chapter-1")
.build();
when(sceneRepository.findById("scene-1")).thenReturn(Optional.of(testScene));
when(sceneRepository.findByChapterId("chapter-1")).thenReturn(List.of(testScene, scene2));
// Act & Assert
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> sceneService.updateScene("scene-1", updatedScene)
);
assertEquals("Une scène ne peut pas se brancher sur elle-même", exception.getMessage());
verify(sceneRepository, times(1)).findById("scene-1");
verify(sceneRepository, never()).save(any());
}
@Test
void testUpdateScene_WithBranchToDifferentChapter() {
// Arrange
SceneBranch branch = SceneBranch.builder()
.targetSceneId("scene-other-chapter")
.label("Go to other chapter")
.build();
Scene updatedScene = Scene.builder()
.name("Updated Scene")
.branches(List.of(branch))
.chapterId("chapter-1")
.build();
when(sceneRepository.findById("scene-1")).thenReturn(Optional.of(testScene));
when(sceneRepository.findByChapterId("chapter-1")).thenReturn(List.of(testScene, scene2));
// Act & Assert
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> sceneService.updateScene("scene-1", updatedScene)
);
assertTrue(exception.getMessage().contains("n'appartient pas au même chapitre"));
verify(sceneRepository, times(1)).findById("scene-1");
verify(sceneRepository, never()).save(any());
}
@Test
void testUpdateScene_WithBranchNullTarget() {
// Arrange
SceneBranch branch = SceneBranch.builder()
.targetSceneId(null)
.label("Null target")
.build();
Scene updatedScene = Scene.builder()
.name("Updated Scene")
.branches(List.of(branch))
.chapterId("chapter-1")
.build();
when(sceneRepository.findById("scene-1")).thenReturn(Optional.of(testScene));
// Act & Assert
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> sceneService.updateScene("scene-1", updatedScene)
);
assertEquals("Une branche doit avoir une scène de destination", exception.getMessage());
verify(sceneRepository, times(1)).findById("scene-1");
verify(sceneRepository, never()).save(any());
}
@Test
void testUpdateScene_WithBranchBlankTarget() {
// Arrange
SceneBranch branch = SceneBranch.builder()
.targetSceneId(" ")
.label("Blank target")
.build();
Scene updatedScene = Scene.builder()
.name("Updated Scene")
.branches(List.of(branch))
.chapterId("chapter-1")
.build();
when(sceneRepository.findById("scene-1")).thenReturn(Optional.of(testScene));
// Act & Assert
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> sceneService.updateScene("scene-1", updatedScene)
);
assertEquals("Une branche doit avoir une scène de destination", exception.getMessage());
verify(sceneRepository, times(1)).findById("scene-1");
verify(sceneRepository, never()).save(any());
}
@Test
void testUpdateScene_WithEmptyBranches() {
// Arrange
Scene updatedScene = Scene.builder()
.name("Updated Scene")
.branches(List.of())
.chapterId("chapter-1")
.build();
when(sceneRepository.findById("scene-1")).thenReturn(Optional.of(testScene));
when(sceneRepository.save(any(Scene.class))).thenReturn(testScene);
// Act
Scene result = sceneService.updateScene("scene-1", updatedScene);
// Assert
assertNotNull(result);
verify(sceneRepository, times(1)).findById("scene-1");
verify(sceneRepository, times(1)).save(any(Scene.class));
}
@Test
void testDeleteScene() {
// Arrange
doNothing().when(sceneRepository).deleteById("scene-1");
// Act
sceneService.deleteScene("scene-1");
// Assert
verify(sceneRepository, times(1)).deleteById("scene-1");
}
@Test
void testSceneExists_True() {
// Arrange
when(sceneRepository.existsById("scene-1")).thenReturn(true);
// Act
boolean result = sceneService.sceneExists("scene-1");
// Assert
assertTrue(result);
verify(sceneRepository, times(1)).existsById("scene-1");
}
@Test
void testSceneExists_False() {
// Arrange
when(sceneRepository.existsById("invalid-id")).thenReturn(false);
// Act
boolean result = sceneService.sceneExists("invalid-id");
// Assert
assertFalse(result);
verify(sceneRepository, times(1)).existsById("invalid-id");
}
}

View File

@@ -0,0 +1,103 @@
package com.loremind.infrastructure.persistence.postgres;
import com.loremind.domain.lorecontext.Lore;
import com.loremind.domain.lorecontext.ports.LoreRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
/**
* Test pour vérifier que PostgresLoreRepository fonctionne correctement.
* Utilise PostgreSQL (loremind_test) pour les tests d'intégration.
*/
@SpringBootTest
public class PostgresLoreRepositoryTest {
@Autowired
private LoreRepository loreRepository;
@Test
public void testSaveAndFindLore() {
// Créer un Lore
Lore lore = Lore.builder()
.name("Lore Test")
.description("Description test")
.nodeCount(0)
.pageCount(0)
.createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now())
.build();
// Sauvegarder
Lore savedLore = loreRepository.save(lore);
assertNotNull(savedLore.getId());
// Récupérer
Optional<Lore> foundLore = loreRepository.findById(savedLore.getId());
assertTrue(foundLore.isPresent());
assertEquals("Lore Test", foundLore.get().getName());
// Nettoyer
loreRepository.deleteById(savedLore.getId());
}
@Test
public void testFindAllLores() {
// Créer deux Lores
Lore lore1 = Lore.builder()
.name("Lore 1")
.description("Description 1")
.nodeCount(0)
.pageCount(0)
.createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now())
.build();
Lore lore2 = Lore.builder()
.name("Lore 2")
.description("Description 2")
.nodeCount(0)
.pageCount(0)
.createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now())
.build();
Lore saved1 = loreRepository.save(lore1);
Lore saved2 = loreRepository.save(lore2);
// Récupérer tous
List<Lore> allLores = loreRepository.findAll();
assertTrue(allLores.size() >= 2);
// Nettoyer
loreRepository.deleteById(saved1.getId());
loreRepository.deleteById(saved2.getId());
}
@Test
public void testDeleteLore() {
// Créer un Lore
Lore lore = Lore.builder()
.name("Lore to delete")
.description("Description")
.nodeCount(0)
.pageCount(0)
.createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now())
.build();
Lore savedLore = loreRepository.save(lore);
// Supprimer
loreRepository.deleteById(savedLore.getId());
// Vérifier qu'il n'existe plus
assertFalse(loreRepository.existsById(savedLore.getId()));
}
}

View File

@@ -0,0 +1,10 @@
# Configuration de test avec PostgreSQL
spring.datasource.url=${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/loremind_test}
spring.datasource.username=${SPRING_DATASOURCE_USERNAME:}
spring.datasource.password=${SPRING_DATASOURCE_PASSWORD:}
spring.datasource.driver-class-name=org.postgresql.Driver
# Configuration JPA pour les tests
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true