From 999331452100a3988c2da5f33ee94da8e6676b6e Mon Sep 17 00:00:00 2001 From: Marine Le Mezo Date: Fri, 23 Aug 2024 17:23:20 +0200 Subject: [PATCH 1/3] [api] fix contextual team while duplicating scenario #1303 --- .../io/openbas/service/ScenarioService.java | 44 +++++- .../service/ScenarioToExerciseService.java | 47 +------ .../java/io/openbas/service/TeamService.java | 21 +++ .../io/openbas/utils/CopyObjectListUtils.java | 36 +++++ .../openbas/service/ScenarioServiceTest.java | 127 ++++++++++++++++++ .../database/repository/TeamRepository.java | 8 +- 6 files changed, 232 insertions(+), 51 deletions(-) create mode 100644 openbas-api/src/main/java/io/openbas/service/TeamService.java create mode 100644 openbas-api/src/main/java/io/openbas/utils/CopyObjectListUtils.java create mode 100644 openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java diff --git a/openbas-api/src/main/java/io/openbas/service/ScenarioService.java b/openbas-api/src/main/java/io/openbas/service/ScenarioService.java index fdada855dc..fad125e89e 100644 --- a/openbas-api/src/main/java/io/openbas/service/ScenarioService.java +++ b/openbas-api/src/main/java/io/openbas/service/ScenarioService.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import io.openbas.config.OpenBASConfig; -import io.openbas.database.criteria.GenericCriteria; import io.openbas.database.model.*; import io.openbas.database.raw.RawPaginationScenario; import io.openbas.database.raw.RawScenario; @@ -86,16 +85,18 @@ public class ScenarioService { private EntityManager entityManager; private final ScenarioRepository scenarioRepository; - private final GrantService grantService; - private final VariableService variableService; - private final ChallengeService challengeService; - private final DocumentRepository documentRepository; private final TeamRepository teamRepository; private final UserRepository userRepository; + private final DocumentRepository documentRepository; private final ScenarioTeamUserRepository scenarioTeamUserRepository; + private final ArticleRepository articleRepository; + + private final GrantService grantService; + private final VariableService variableService; + private final ChallengeService challengeService; + private final TeamService teamService; private final FileService fileService; private final InjectDuplicateService injectDuplicateService; - private final ArticleRepository articleRepository; @Transactional public Scenario createScenario(@NotNull final Scenario scenario) { @@ -485,6 +486,7 @@ public Scenario getDuplicateScenario(@NotBlank String scenarioId) { Scenario scenario = copyScenario(scenarioOrigin); Scenario scenarioDuplicate = scenarioRepository.save(scenario); getListOfDuplicatedInjects(scenarioDuplicate, scenarioOrigin); + getListOfScenarioTeams(scenarioDuplicate, scenarioOrigin); getListOfArticles(scenarioDuplicate, scenarioOrigin); getListOfVariables(scenarioDuplicate, scenarioOrigin); return scenarioRepository.save(scenario); @@ -492,6 +494,35 @@ public Scenario getDuplicateScenario(@NotBlank String scenarioId) { throw new ElementNotFoundException(); } + private void getListOfScenarioTeams(@NotNull Scenario scenario, @NotNull Scenario scenarioOrigin) { + Map contextualTeams = new HashMap<>(); + List scenarioTeams = new ArrayList<>(); + scenarioOrigin.getTeams().forEach(scenarioTeam -> { + if (scenarioTeam.getContextual()) { + Team team = teamService.copyContextualTeam(scenarioTeam); + Team teamSaved = this.teamRepository.save(team); + scenarioTeams.add(teamSaved); + contextualTeams.put(scenarioTeam.getId(), teamSaved); + } else { + scenarioTeams.add(scenarioTeam); + } + }); + scenario.setTeams(new ArrayList<>(scenarioTeams)); + + List scenarioInjects = scenario.getInjects(); + scenarioInjects.forEach(scenarioInject -> { + List teams = new ArrayList<>(); + scenarioInject.getTeams().forEach(team -> { + if (team.getContextual()) { + teams.add(contextualTeams.get(team.getId())); + } else { + teams.add(team); + } + }); + scenarioInject.setTeams(teams); + }); + } + private Scenario copyScenario(Scenario scenario) { Scenario scenarioDuplicate = new Scenario(); scenarioDuplicate.setName(duplicateString(scenario.getName())); @@ -507,7 +538,6 @@ private Scenario copyScenario(Scenario scenario) { scenarioDuplicate.setInjects(new HashSet<>(scenario.getInjects())); scenarioDuplicate.setExternalReference(scenario.getExternalReference()); scenarioDuplicate.setTeamUsers(new ArrayList<>(scenario.getTeamUsers())); - scenarioDuplicate.setTeams(new ArrayList<>(scenario.getTeams())); scenarioDuplicate.setReplyTos(new ArrayList<>(scenario.getReplyTos())); scenarioDuplicate.setLessonsCategories(new ArrayList<>(scenario.getLessonsCategories())); scenarioDuplicate.setObjectives(new ArrayList<>(scenario.getObjectives())); diff --git a/openbas-api/src/main/java/io/openbas/service/ScenarioToExerciseService.java b/openbas-api/src/main/java/io/openbas/service/ScenarioToExerciseService.java index a80ae31076..31b45982c2 100644 --- a/openbas-api/src/main/java/io/openbas/service/ScenarioToExerciseService.java +++ b/openbas-api/src/main/java/io/openbas/service/ScenarioToExerciseService.java @@ -6,6 +6,7 @@ import io.openbas.database.repository.*; import io.openbas.injectors.channel.ChannelContract; import io.openbas.injectors.channel.model.ChannelContent; +import io.openbas.utils.CopyObjectListUtils; import jakarta.annotation.Nullable; import jakarta.annotation.Resource; import jakarta.validation.constraints.NotBlank; @@ -37,6 +38,7 @@ public class ScenarioToExerciseService { private final LessonsQuestionRepository lessonsQuestionRepository; private final InjectRepository injectRepository; private final InjectDocumentRepository injectDocumentRepository; + private final TeamService teamService; private final VariableService variableService; @Transactional(rollbackFor = Exception.class) @@ -58,7 +60,7 @@ public Exercise toExercise( exercise.setStart(start); // Tags - exercise.setTags(copy(scenario.getTags(), Tag.class)); + exercise.setTags(CopyObjectListUtils.copy(scenario.getTags(), Tag.class)); Exercise exerciseSaved = this.exerciseRepository.save(exercise); @@ -78,17 +80,10 @@ public Exercise toExercise( Map contextualTeams = new HashMap<>(); scenario.getTeams().forEach(scenarioTeam -> { if (scenarioTeam.getContextual()) { - Team team = new Team(); - team.setName(scenarioTeam.getName()); - team.setDescription(scenarioTeam.getDescription()); - team.setTags(copy(scenarioTeam.getTags(), Tag.class)); - team.setOrganization(scenarioTeam.getOrganization()); - - team.setUsers(copy(scenarioTeam.getUsers(), User.class)); + Team team = teamService.copyContextualTeam(scenarioTeam); team.setExercises(new ArrayList<>() {{ add(exerciseSaved); }}); - team.setContextual(scenarioTeam.getContextual()); Team teamSaved = this.teamRepository.save(team); contextualTeams.put(scenarioTeam.getId(), teamSaved); } else { @@ -198,7 +193,7 @@ public Exercise toExercise( exerciseInject.setDependsDuration(scenarioInject.getDependsDuration()); exerciseInject.setUser(scenarioInject.getUser()); exerciseInject.setStatus(scenarioInject.getStatus().orElse(null)); - exerciseInject.setTags(copy(scenarioInject.getTags(), Tag.class)); + exerciseInject.setTags(CopyObjectListUtils.copy(scenarioInject.getTags(), Tag.class)); exerciseInject.setContent(scenarioInject.getContent()); // Content @@ -223,8 +218,8 @@ public Exercise toExercise( exerciseInject.setTeams(teams); // Assets & Asset Groups - exerciseInject.setAssets(copy(scenarioInject.getAssets(), Asset.class)); - exerciseInject.setAssetGroups(copy(scenarioInject.getAssetGroups(), AssetGroup.class)); + exerciseInject.setAssets(CopyObjectListUtils.copy(scenarioInject.getAssets(), Asset.class)); + exerciseInject.setAssetGroups(CopyObjectListUtils.copy(scenarioInject.getAssetGroups(), AssetGroup.class)); Inject injectSaved = this.injectRepository.save(exerciseInject); // Documents @@ -257,35 +252,7 @@ public Exercise toExercise( return exerciseSaved; } - private List copy(@NotNull final List origins, Class clazz) { - List destinations = new ArrayList<>(); - origins.forEach(origin -> { - try { - T destination = clazz.getDeclaredConstructor().newInstance(); - BeanUtils.copyProperties(destination, origin); - destinations.add(destination); - } catch (IllegalAccessException | InvocationTargetException | InstantiationException | - NoSuchMethodException e) { - throw new RuntimeException(e); - } - }); - return destinations; - } - private Set copy(@NotNull final Set origins, Class clazz) { - Set destinations = new HashSet<>(); - origins.forEach(origin -> { - try { - T destination = clazz.getDeclaredConstructor().newInstance(); - BeanUtils.copyProperties(destination, origin); - destinations.add(destination); - } catch (IllegalAccessException | InvocationTargetException | InstantiationException | - NoSuchMethodException e) { - throw new RuntimeException(e); - } - }); - return destinations; - } private List addExerciseToDocuments( @NotNull final List origDocuments, diff --git a/openbas-api/src/main/java/io/openbas/service/TeamService.java b/openbas-api/src/main/java/io/openbas/service/TeamService.java new file mode 100644 index 0000000000..171f02c412 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/service/TeamService.java @@ -0,0 +1,21 @@ +package io.openbas.service; + +import io.openbas.database.model.*; +import io.openbas.utils.CopyObjectListUtils; +import org.springframework.stereotype.Service; + +@Service +public class TeamService { + + public Team copyContextualTeam(Team teamToCopy) { + Team newTeam = new Team(); + newTeam.setName(teamToCopy.getName()); + newTeam.setDescription(teamToCopy.getDescription()); + newTeam.setTags(CopyObjectListUtils.copy(teamToCopy.getTags(), Tag.class)); + newTeam.setOrganization(teamToCopy.getOrganization()); + newTeam.setUsers(CopyObjectListUtils.copy(teamToCopy.getUsers(), User.class)); + newTeam.setContextual(teamToCopy.getContextual()); + return newTeam; + } + +} \ No newline at end of file diff --git a/openbas-api/src/main/java/io/openbas/utils/CopyObjectListUtils.java b/openbas-api/src/main/java/io/openbas/utils/CopyObjectListUtils.java new file mode 100644 index 0000000000..b27ff3a8d4 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/utils/CopyObjectListUtils.java @@ -0,0 +1,36 @@ +package io.openbas.utils; + +import io.openbas.database.model.Base; +import jakarta.validation.constraints.NotNull; +import org.apache.commons.beanutils.BeanUtils; + +import java.lang.reflect.InvocationTargetException; +import java.util.*; + +public class CopyObjectListUtils { + + public static List copy(@NotNull final List origins, Class clazz) { + List destinations = new ArrayList<>(); + return copyCollection(origins, clazz, destinations); + } + + public static Set copy(@NotNull final Set origins, Class clazz) { + Set destinations = new HashSet<>(); + return copyCollection(origins, clazz, destinations); + } + + public static > C copyCollection(@NotNull final C origins, Class clazz, C destinations) { + origins.forEach(origin -> { + try { + T destination = clazz.getDeclaredConstructor().newInstance(); + BeanUtils.copyProperties(destination, origin); + destinations.add(destination); + } catch (IllegalAccessException | InvocationTargetException | InstantiationException | + NoSuchMethodException e) { + throw new RuntimeException(e); + } + }); + return destinations; + } + +} diff --git a/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java b/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java new file mode 100644 index 0000000000..08965bd8d5 --- /dev/null +++ b/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java @@ -0,0 +1,127 @@ +package io.openbas.service; + +import io.openbas.database.model.*; +import io.openbas.database.repository.*; +import io.openbas.rest.inject.service.InjectDuplicateService; +import jakarta.transaction.Transactional; +import jakarta.validation.constraints.NotBlank; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +@SpringBootTest +public class ScenarioServiceTest { + + @Autowired + ScenarioRepository scenarioRepository; + @Autowired + private TeamRepository teamRepository; + @Autowired + private UserRepository userRepository; + @Autowired + private DocumentRepository documentRepository; + @Autowired + private ScenarioTeamUserRepository scenarioTeamUserRepository; + @Autowired + private ArticleRepository articleRepository; + + @Autowired + InjectRepository injectRepository; + + @Mock + GrantService grantService; + @Mock + VariableService variableService; + @Mock + ChallengeService challengeService; + @Autowired + private TeamService teamService; + @Mock + FileService fileService; + @Autowired + private InjectDuplicateService injectDuplicateService; + + + @InjectMocks + private ScenarioService scenarioService; + + @BeforeEach + void setUp() { + scenarioService = new ScenarioService(scenarioRepository, teamRepository, userRepository, documentRepository, + scenarioTeamUserRepository, articleRepository, grantService, variableService, challengeService, + teamService, fileService, injectDuplicateService + ); + } + + @DisplayName("Should create new contextual teams during scenario duplication") + @Test + @Transactional(rollbackOn = Exception.class) + void createNewContextualTeamsDuringScenarioDuplication(){ + // -- PREPARE -- + List scenarioTeams = new ArrayList<>();; + Team contextualTeam = createTeam("fakeTeamName1", true); + scenarioTeams.add(contextualTeam); + Team noContextualTeam = createTeam("fakeTeamName2",false); + scenarioTeams.add(noContextualTeam); + + Scenario scenario = createScenario(scenarioTeams); + + // -- EXECUTE -- + Scenario scenarioDuplicated = scenarioService.getDuplicateScenario(scenario.getId()); + + // -- ASSERT -- + assertNotEquals(scenario.getId(), scenarioDuplicated.getId()); + assertEquals(scenario.getFrom(), scenarioDuplicated.getFrom()); + assertEquals(2, scenarioDuplicated.getTeams().size()); + scenarioDuplicated.getTeams().forEach(team -> { + if (team.getContextual()){ + assertNotEquals(contextualTeam.getId(), team.getId()); + assertEquals(contextualTeam.getName(), team.getName()); + } else { + assertEquals(noContextualTeam.getId(), team.getId()); + } + }); + assertEquals(1, scenarioDuplicated.getInjects().size()); + assertEquals(2, scenario.getInjects().get(0).getTeams().size()); + scenarioDuplicated.getInjects().get(0).getTeams().forEach(injectTeam -> { + if (injectTeam.getContextual()){ + assertNotEquals(contextualTeam.getId(), injectTeam.getId()); + assertEquals( + scenarioDuplicated.getTeams().stream().filter(team -> team.getContextual().equals(true)).findFirst().orElse(new Team()).getId(), + injectTeam.getId() + ); + } else { + assertEquals(noContextualTeam.getId(), injectTeam.getId()); + } + }); + } + + private Team createTeam(@NotBlank String name, Boolean isContextualTeam){ + Team team = new Team(); + team.setName(name); + team.setContextual(isContextualTeam); + return this.teamRepository.save(team); + } + + private Scenario createScenario(List scenarioTeams){ + Scenario scenario = new Scenario(); + scenario.setName("Scenario name"); + scenario.setFrom("test@mail.fr"); + scenario.setTeams(scenarioTeams); + Inject inject = new Inject(); + inject.setTeams(scenarioTeams); + Set injects = new HashSet<>(); + injects.add(this.injectRepository.save(inject)); + scenario.setInjects(injects); + return this.scenarioRepository.save(scenario); + } +} diff --git a/openbas-model/src/main/java/io/openbas/database/repository/TeamRepository.java b/openbas-model/src/main/java/io/openbas/database/repository/TeamRepository.java index e34f8c26e1..9d36904aae 100644 --- a/openbas-model/src/main/java/io/openbas/database/repository/TeamRepository.java +++ b/openbas-model/src/main/java/io/openbas/database/repository/TeamRepository.java @@ -51,7 +51,7 @@ public interface TeamRepository extends CrudRepository, @Query(value="SELECT teams.team_id, teams.team_name, teams.team_description, teams.team_created_at, teams.team_updated_at, teams.team_organization, " + " team_contextual, " + - " coalesce(array_agg(DISTINCT teams_tags.team_id) FILTER ( WHERE teams_tags.team_id IS NOT NULL ), '{}') as team_tags, " + + " coalesce(array_agg(DISTINCT teams_tags.tag_id) FILTER ( WHERE teams_tags.tag_id IS NOT NULL ), '{}') as team_tags, " + " coalesce(array_agg(DISTINCT users_teams.user_id) FILTER ( WHERE users_teams.user_id IS NOT NULL ), '{}') as team_users, " + " coalesce(array_agg(DISTINCT exercises_teams.exercise_id) FILTER ( WHERE exercises_teams.exercise_id IS NOT NULL ), '{}') as team_exercises, " + " coalesce(array_agg(DISTINCT scenarios_teams.scenario_id) FILTER ( WHERE scenarios_teams.scenario_id IS NOT NULL ), '{}') as team_scenarios, " + @@ -73,7 +73,7 @@ public interface TeamRepository extends CrudRepository, @Query(value="SELECT teams.team_id, teams.team_name, teams.team_description, teams.team_created_at, teams.team_updated_at, teams.team_organization, " + " team_contextual, " + - " coalesce(array_agg(DISTINCT teams_tags.team_id) FILTER ( WHERE teams_tags.team_id IS NOT NULL ), '{}') as team_tags, " + + " coalesce(array_agg(DISTINCT teams_tags.tag_id) FILTER ( WHERE teams_tags.tag_id IS NOT NULL ), '{}') as team_tags, " + " coalesce(array_agg(DISTINCT users_teams.user_id) FILTER ( WHERE users_teams.user_id IS NOT NULL ), '{}') as team_users, " + " coalesce(array_agg(DISTINCT exercises_teams.exercise_id) FILTER ( WHERE exercises_teams.exercise_id IS NOT NULL ), '{}') as team_exercises, " + " coalesce(array_agg(DISTINCT scenarios_teams.scenario_id) FILTER ( WHERE scenarios_teams.scenario_id IS NOT NULL ), '{}') as team_scenarios, " + @@ -100,7 +100,7 @@ public interface TeamRepository extends CrudRepository, @Query(value="SELECT teams.team_id, teams.team_name, teams.team_description, teams.team_created_at, teams.team_updated_at, teams.team_organization, " + " team_contextual, " + - " coalesce(array_agg(DISTINCT teams_tags.team_id) FILTER ( WHERE teams_tags.team_id IS NOT NULL ), '{}') as team_tags, " + + " coalesce(array_agg(DISTINCT teams_tags.tag_id) FILTER ( WHERE teams_tags.tag_id IS NOT NULL ), '{}') as team_tags, " + " coalesce(array_agg(DISTINCT users_teams.user_id) FILTER ( WHERE users_teams.user_id IS NOT NULL ), '{}') as team_users, " + " coalesce(array_agg(DISTINCT exercises_teams.exercise_id) FILTER ( WHERE exercises_teams.exercise_id IS NOT NULL ), '{}') as team_exercises, " + " coalesce(array_agg(DISTINCT scenarios_teams.scenario_id) FILTER ( WHERE scenarios_teams.scenario_id IS NOT NULL ), '{}') as team_scenarios, " + @@ -122,7 +122,7 @@ public interface TeamRepository extends CrudRepository, @Query(value="SELECT teams.team_id, teams.team_name, teams.team_description, teams.team_created_at, teams.team_updated_at, teams.team_organization, " + " team_contextual, " + - " coalesce(array_agg(DISTINCT teams_tags.team_id) FILTER ( WHERE teams_tags.team_id IS NOT NULL ), '{}') as team_tags, " + + " coalesce(array_agg(DISTINCT teams_tags.tag_id) FILTER ( WHERE teams_tags.tag_id IS NOT NULL ), '{}') as team_tags, " + " coalesce(array_agg(DISTINCT users_teams.user_id) FILTER ( WHERE users_teams.user_id IS NOT NULL ), '{}') as team_users, " + " coalesce(array_agg(DISTINCT exercises_teams.exercise_id) FILTER ( WHERE exercises_teams.exercise_id IS NOT NULL ), '{}') as team_exercises, " + " coalesce(array_agg(DISTINCT scenarios_teams.scenario_id) FILTER ( WHERE scenarios_teams.scenario_id IS NOT NULL ), '{}') as team_scenarios, " + From 02823e2cc93ee6d9c2436ca7b22404f1908425b1 Mon Sep 17 00:00:00 2001 From: Marine Le Mezo Date: Mon, 26 Aug 2024 11:36:15 +0200 Subject: [PATCH 2/3] [backend] use TeamFixture and ScenarioFixture (#1303) --- .../openbas/service/ScenarioServiceTest.java | 33 +++++-------------- .../utils/fixtures/ScenarioFixture.java | 17 ++++++++++ .../openbas/utils/fixtures/TeamFixture.java | 11 +++++-- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java b/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java index 08965bd8d5..824653b4bd 100644 --- a/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java @@ -4,7 +4,6 @@ import io.openbas.database.repository.*; import io.openbas.rest.inject.service.InjectDuplicateService; import jakarta.transaction.Transactional; -import jakarta.validation.constraints.NotBlank; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -12,6 +11,8 @@ import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import static io.openbas.utils.fixtures.TeamFixture.getTeam; +import static io.openbas.utils.fixtures.ScenarioFixture.getScenario; import java.util.*; @@ -68,12 +69,16 @@ void setUp() { void createNewContextualTeamsDuringScenarioDuplication(){ // -- PREPARE -- List scenarioTeams = new ArrayList<>();; - Team contextualTeam = createTeam("fakeTeamName1", true); + Team contextualTeam = this.teamRepository.save(getTeam(null, "fakeTeamName1", true)); scenarioTeams.add(contextualTeam); - Team noContextualTeam = createTeam("fakeTeamName2",false); + Team noContextualTeam = this.teamRepository.save(getTeam(null, "fakeTeamName2",false)); scenarioTeams.add(noContextualTeam); - Scenario scenario = createScenario(scenarioTeams); + Inject inject = new Inject(); + inject.setTeams(scenarioTeams); + Set scenarioInjects = new HashSet<>(); + scenarioInjects.add(this.injectRepository.save(inject)); + Scenario scenario = this.scenarioRepository.save(getScenario(scenarioTeams, scenarioInjects)); // -- EXECUTE -- Scenario scenarioDuplicated = scenarioService.getDuplicateScenario(scenario.getId()); @@ -104,24 +109,4 @@ void createNewContextualTeamsDuringScenarioDuplication(){ } }); } - - private Team createTeam(@NotBlank String name, Boolean isContextualTeam){ - Team team = new Team(); - team.setName(name); - team.setContextual(isContextualTeam); - return this.teamRepository.save(team); - } - - private Scenario createScenario(List scenarioTeams){ - Scenario scenario = new Scenario(); - scenario.setName("Scenario name"); - scenario.setFrom("test@mail.fr"); - scenario.setTeams(scenarioTeams); - Inject inject = new Inject(); - inject.setTeams(scenarioTeams); - Set injects = new HashSet<>(); - injects.add(this.injectRepository.save(inject)); - scenario.setInjects(injects); - return this.scenarioRepository.save(scenario); - } } diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/ScenarioFixture.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/ScenarioFixture.java index 0c52cdbf7e..c868020624 100644 --- a/openbas-api/src/test/java/io/openbas/utils/fixtures/ScenarioFixture.java +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/ScenarioFixture.java @@ -1,14 +1,31 @@ package io.openbas.utils.fixtures; +import io.openbas.database.model.Inject; import io.openbas.database.model.Scenario; +import io.openbas.database.model.Team; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; public class ScenarioFixture { public static Scenario getScenario() { + return getScenario(null, null); + } + + public static Scenario getScenario(List scenarioTeams, Set scenarioInjects) { Scenario scenario = new Scenario(); scenario.setName("Crisis simulation"); scenario.setDescription("A crisis simulation for my enterprise"); scenario.setSubtitle("A crisis simulation"); + scenario.setFrom("simulation@mail.fr"); + if(scenarioTeams != null){ + scenario.setTeams(scenarioTeams); + } + if(scenarioInjects != null){ + scenario.setInjects(scenarioInjects); + } return scenario; } diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/TeamFixture.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/TeamFixture.java index 03f4ea0d7c..4256560351 100644 --- a/openbas-api/src/test/java/io/openbas/utils/fixtures/TeamFixture.java +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/TeamFixture.java @@ -10,9 +10,16 @@ public class TeamFixture { public static final String TEAM_NAME = "My team"; public static Team getTeam(final User user) { + return getTeam(user, TEAM_NAME, false); // Call the other method with default value + } + + public static Team getTeam(final User user, String name, Boolean isContextualTeam ) { Team team = new Team(); - team.setName(TEAM_NAME); - team.setUsers(new ArrayList<>(){{add(user);}}); + team.setName(name); + team.setContextual(isContextualTeam); + if (user != null) { + team.setUsers(new ArrayList<>(){{add(user);}}); + } return team; } From dbb9e17b735053f4a71aaf465616d5bbc17cc38f Mon Sep 17 00:00:00 2001 From: Marine Le Mezo Date: Mon, 26 Aug 2024 17:19:41 +0200 Subject: [PATCH 3/3] [backend] correct simulation #1303 --- .../rest/exercise/ExerciseService.java | 35 +++++++- .../openbas/service/ExerciseServiceTest.java | 81 +++++++++++++++++++ .../utils/fixtures/ExerciseFixture.java | 24 ++++++ 3 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 openbas-api/src/test/java/io/openbas/service/ExerciseServiceTest.java create mode 100644 openbas-api/src/test/java/io/openbas/utils/fixtures/ExerciseFixture.java diff --git a/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseService.java b/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseService.java index b892ecc376..af696c5745 100644 --- a/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseService.java +++ b/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseService.java @@ -3,14 +3,15 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import io.openbas.config.OpenBASConfig; -import io.openbas.database.criteria.GenericCriteria; import io.openbas.database.model.*; import io.openbas.database.repository.ArticleRepository; import io.openbas.database.repository.ExerciseRepository; +import io.openbas.database.repository.TeamRepository; import io.openbas.rest.exercise.form.ExerciseSimple; import io.openbas.rest.inject.service.InjectDuplicateService; import io.openbas.service.GrantService; import io.openbas.service.InjectService; +import io.openbas.service.TeamService; import io.openbas.service.VariableService; import jakarta.annotation.Resource; import jakarta.persistence.EntityManager; @@ -56,10 +57,12 @@ public class ExerciseService { private final GrantService grantService; private final InjectService injectService; private final InjectDuplicateService injectDuplicateService; + private final TeamService teamService; private final VariableService variableService; private final ArticleRepository articleRepository; private final ExerciseRepository exerciseRepository; + private final TeamRepository teamRepository; // region properties @Value("${openbas.mail.imap.enabled}") @@ -211,6 +214,7 @@ public Exercise getDuplicateExercise(@NotBlank String exerciseId) { Exercise exercise = copyExercice(exerciseOrigin); Exercise exerciseDuplicate = exerciseRepository.save(exercise); getListOfDuplicatedInjects(exerciseDuplicate, exerciseOrigin); + getListOfExerciseTeams(exerciseDuplicate, exerciseOrigin); getListOfArticles(exerciseDuplicate, exerciseOrigin); getListOfVariables(exerciseDuplicate, exerciseOrigin); return exerciseRepository.save(exercise); @@ -232,7 +236,6 @@ private Exercise copyExercice(Exercise exerciseOrigin) { exerciseDuplicate.setLogoLight(exerciseOrigin.getLogoLight()); exerciseDuplicate.setGrants(new ArrayList<>(exerciseOrigin.getGrants())); exerciseDuplicate.setTags(new HashSet<>(exerciseOrigin.getTags())); - exerciseDuplicate.setTeams(new ArrayList<>(exerciseOrigin.getTeams())); exerciseDuplicate.setTeamUsers(new ArrayList<>(exerciseOrigin.getTeamUsers())); exerciseDuplicate.setReplyTos(new ArrayList<>(exerciseOrigin.getReplyTos())); exerciseDuplicate.setDocuments(new ArrayList<>(exerciseOrigin.getDocuments())); @@ -240,6 +243,34 @@ private Exercise copyExercice(Exercise exerciseOrigin) { return exerciseDuplicate; } + private void getListOfExerciseTeams(@NotNull Exercise exercise,@NotNull Exercise exerciseOrigin){ + Map contextualTeams = new HashMap<>(); + List exerciseTeams = new ArrayList<>(); + exerciseOrigin.getTeams().forEach(scenarioTeam -> { + if (scenarioTeam.getContextual()) { + Team team = teamService.copyContextualTeam(scenarioTeam); + Team teamSaved = this.teamRepository.save(team); + exerciseTeams.add(teamSaved); + contextualTeams.put(scenarioTeam.getId(), teamSaved); + } else { + exerciseTeams.add(scenarioTeam); + } + }); + exercise.setTeams(new ArrayList<>(exerciseTeams)); + + exercise.getInjects().forEach(inject -> { + List teams = new ArrayList<>(); + inject.getTeams().forEach(team -> { + if (team.getContextual()) { + teams.add(contextualTeams.get(team.getId())); + } else { + teams.add(team); + } + }); + inject.setTeams(teams); + }); + } + private void getListOfDuplicatedInjects(Exercise exercise, Exercise exerciseOrigin) { List injectListForExercise = exerciseOrigin.getInjects() .stream().map(inject -> injectDuplicateService.createInjectForExercise(exercise.getId(), inject.getId(), false)) diff --git a/openbas-api/src/test/java/io/openbas/service/ExerciseServiceTest.java b/openbas-api/src/test/java/io/openbas/service/ExerciseServiceTest.java new file mode 100644 index 0000000000..35466b8959 --- /dev/null +++ b/openbas-api/src/test/java/io/openbas/service/ExerciseServiceTest.java @@ -0,0 +1,81 @@ +package io.openbas.service; + +import io.openbas.database.model.*; +import io.openbas.database.repository.ArticleRepository; +import io.openbas.database.repository.ExerciseRepository; +import io.openbas.database.repository.TeamRepository; +import io.openbas.rest.exercise.ExerciseService; +import io.openbas.rest.inject.service.InjectDuplicateService; +import jakarta.transaction.Transactional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.ArrayList; +import java.util.List; + +import static io.openbas.utils.fixtures.TeamFixture.getTeam; +import static io.openbas.utils.fixtures.ExerciseFixture.getExercise; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +@SpringBootTest +public class ExerciseServiceTest { + @Mock + GrantService grantService; + @Mock + InjectService injectService; + @Mock + InjectDuplicateService injectDuplicateService; + @Autowired + private TeamService teamService; + @Mock + VariableService variableService; + + @Autowired + private ArticleRepository articleRepository; + @Autowired + private ExerciseRepository exerciseRepository; + @Autowired + private TeamRepository teamRepository; + + @InjectMocks + private ExerciseService exerciseService; + @BeforeEach + void setUp() { + exerciseService = new ExerciseService(grantService, injectService, injectDuplicateService, + teamService,variableService, articleRepository,exerciseRepository,teamRepository); + } + + @DisplayName("Should create new contextual teams while exercise duplication") + @Test + @Transactional(rollbackOn = Exception.class) + void createNewContextualTeamsWhileExerciseDuplication(){ + // -- PREPARE -- + List exerciseTeams = new ArrayList<>();; + Team contextualTeam = this.teamRepository.save(getTeam(null, "fakeTeamName1", true)); + exerciseTeams.add(contextualTeam); + Team noContextualTeam = this.teamRepository.save(getTeam(null, "fakeTeamName2",false)); + exerciseTeams.add(noContextualTeam); + Exercise exercise = this.exerciseRepository.save(getExercise(exerciseTeams)); + + // -- EXECUTE -- + Exercise exerciseDuplicated = exerciseService.getDuplicateExercise(exercise.getId()); + + // -- ASSERT -- + assertNotEquals(exercise.getId(), exerciseDuplicated.getId()); + assertEquals(2, exerciseDuplicated.getTeams().size()); + exerciseDuplicated.getTeams().forEach(team -> { + if (team.getContextual()){ + assertNotEquals(contextualTeam.getId(), team.getId()); + assertEquals(contextualTeam.getName(), team.getName()); + } else { + assertEquals(noContextualTeam.getId(), team.getId()); + } + }); + } +} diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/ExerciseFixture.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/ExerciseFixture.java new file mode 100644 index 0000000000..fe7667c0ac --- /dev/null +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/ExerciseFixture.java @@ -0,0 +1,24 @@ +package io.openbas.utils.fixtures; + +import io.openbas.database.model.Exercise; +import io.openbas.database.model.Team; + +import java.util.List; + +public class ExerciseFixture { + + public static final String EXERCISE_NAME = "Exercise test"; + + public static Exercise getExercise() { + return getExercise(null); + } + + public static Exercise getExercise(List exerciseTeams) { + Exercise exercise = new Exercise(); + exercise.setName(EXERCISE_NAME); + if(exerciseTeams != null){ + exercise.setTeams(exerciseTeams); + } + return exercise; + } +}