From 7bb2f8a73e8caf258cfb8990e17c8acf65af6e08 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Thu, 19 Dec 2024 13:36:19 +0100 Subject: [PATCH 01/16] rebased --- .../io/openbas/migration/V3_54__TagRule.java | 43 + .../io/openbas/rest/exercise/ExerciseApi.java | 16 +- .../form/ExerciseUpdateTagsInput.java | 3 + .../exercise/form/UpdateExerciseInput.java | 16 + .../exercise/service/ExerciseService.java | 42 + .../io/openbas/rest/inject/InjectApi.java | 22 +- .../rest/inject/service/InjectService.java | 8 - .../io/openbas/rest/scenario/ScenarioApi.java | 18 +- .../form/ScenarioUpdateTagsInput.java | 3 + .../scenario/form/UpdateScenarioInput.java | 12 + .../io/openbas/service/ScenarioService.java | 42 + .../io/openbas/service/TagRuleService.java | 44 +- .../rest/exercise/ExerciseApiTest.java | 143 ++- .../service/ExerciseServiceTest.java | 48 +- .../rest/{ => inject}/InjectApiTest.java | 10 +- .../inject/service/InjectServiceTest.java | 114 +++ .../rest/scenario/ScenarioApiTest.java | 145 ++- .../ExerciseServiceIntegrationTest.java | 6 + .../io/openbas/service/InjectServiceTest.java | 830 ------------------ .../openbas/service/ScenarioServiceTest.java | 64 +- .../openbas/service/TagRuleServiceTest.java | 35 + .../openbas/utils/fixtures/AssetFixture.java | 12 + .../utils/fixtures/ExerciseFixture.java | 11 + .../utils/fixtures/ScenarioFixture.java | 8 + .../io/openbas/utils/fixtures/TagFixture.java | 8 + .../utils/fixtures/TagRuleFixture.java | 12 + .../repository/TagRuleRepository.java | 7 + 27 files changed, 844 insertions(+), 878 deletions(-) create mode 100644 openbas-api/src/main/java/io/openbas/migration/V3_54__TagRule.java create mode 100644 openbas-api/src/main/java/io/openbas/rest/exercise/form/UpdateExerciseInput.java create mode 100644 openbas-api/src/main/java/io/openbas/rest/scenario/form/UpdateScenarioInput.java rename openbas-api/src/test/java/io/openbas/{ => rest/exercise}/service/ExerciseServiceTest.java (65%) rename openbas-api/src/test/java/io/openbas/rest/{ => inject}/InjectApiTest.java (99%) create mode 100644 openbas-api/src/test/java/io/openbas/rest/inject/service/InjectServiceTest.java delete mode 100644 openbas-api/src/test/java/io/openbas/service/InjectServiceTest.java create mode 100644 openbas-api/src/test/java/io/openbas/utils/fixtures/AssetFixture.java diff --git a/openbas-api/src/main/java/io/openbas/migration/V3_54__TagRule.java b/openbas-api/src/main/java/io/openbas/migration/V3_54__TagRule.java new file mode 100644 index 0000000000..61e8c19dcd --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/migration/V3_54__TagRule.java @@ -0,0 +1,43 @@ +package io.openbas.migration; + +import java.sql.Connection; +import java.sql.Statement; +import org.flywaydb.core.api.migration.BaseJavaMigration; +import org.flywaydb.core.api.migration.Context; +import org.springframework.stereotype.Component; + +@Component +public class V3_54__TagRule extends BaseJavaMigration { + + @Override + public void migrate(Context context) throws Exception { + Connection connection = context.getConnection(); + Statement select = connection.createStatement(); + // Create relations between contracts and attack_patterns + select.execute( + """ + CREATE TABLE tag_rules ( + tag_rule_id varchar(255) not null, + tag_id varchar(255) not null + constraint tag_id_fk + references tags, + primary key (tag_rule_id) + ); + CREATE INDEX idx_tag_id ON tag_rules (tag_id); + """); + + select.execute( + """ + CREATE TABLE tag_rule_assets ( + tag_rule_id varchar(255) not null + constraint tag_rule_id_fk + references tag_rules, + asset_id varchar(255) not null + constraint asset_id_fk + references assets + on delete cascade, + primary key (tag_rule_id, asset_id) + ); + """); + } +} diff --git a/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseApi.java b/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseApi.java index 99b766a10a..fc0c1a38fc 100644 --- a/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseApi.java @@ -399,12 +399,17 @@ public Exercise duplicateExercise(@PathVariable @NotBlank final String exerciseI @PreAuthorize("isExercisePlanner(#exerciseId)") @Transactional(rollbackOn = Exception.class) public Exercise updateExerciseInformation( - @PathVariable String exerciseId, @Valid @RequestBody ExerciseInput input) { + @PathVariable String exerciseId, @Valid @RequestBody UpdateExerciseInput input) { Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(ElementNotFoundException::new); + Set currentTagList = exercise.getTags(); exercise.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds()))); exercise.setUpdateAttributes(input); - return exerciseRepository.save(exercise); + if (input.isApplyTagRule()) { + return exerciseService.updateExerciceAndApplyRule(exercise, currentTagList); + } else { + return exerciseRepository.save(exercise); + } } @PutMapping(EXERCISE_URI + "/{exerciseId}/start_date") @@ -430,8 +435,13 @@ public Exercise updateExerciseTags( @PathVariable String exerciseId, @Valid @RequestBody ExerciseUpdateTagsInput input) { Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(ElementNotFoundException::new); + Set currentTagList = exercise.getTags(); exercise.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds()))); - return exerciseRepository.save(exercise); + if (input.isApplyTagRule()) { + return exerciseService.updateExerciceAndApplyRule(exercise, currentTagList); + } else { + return exerciseRepository.save(exercise); + } } @PutMapping(EXERCISE_URI + "/{exerciseId}/logos") diff --git a/openbas-api/src/main/java/io/openbas/rest/exercise/form/ExerciseUpdateTagsInput.java b/openbas-api/src/main/java/io/openbas/rest/exercise/form/ExerciseUpdateTagsInput.java index bfc1f7c834..3869fcd545 100644 --- a/openbas-api/src/main/java/io/openbas/rest/exercise/form/ExerciseUpdateTagsInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/exercise/form/ExerciseUpdateTagsInput.java @@ -12,4 +12,7 @@ public class ExerciseUpdateTagsInput { @JsonProperty("exercise_tags") private List tagIds = new ArrayList<>(); + + @JsonProperty("apply_tag_rule") + private boolean applyTagRule = false; } diff --git a/openbas-api/src/main/java/io/openbas/rest/exercise/form/UpdateExerciseInput.java b/openbas-api/src/main/java/io/openbas/rest/exercise/form/UpdateExerciseInput.java new file mode 100644 index 0000000000..5299537052 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/rest/exercise/form/UpdateExerciseInput.java @@ -0,0 +1,16 @@ +package io.openbas.rest.exercise.form; + +import static io.openbas.config.AppConfig.*; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Data +public class UpdateExerciseInput extends ExerciseInput { + @JsonProperty("apply_tag_rule") + private boolean applyTagRule = false; +} diff --git a/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java b/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java index 8788f92a95..90e91e4777 100644 --- a/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java +++ b/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java @@ -24,7 +24,9 @@ import io.openbas.rest.exercise.form.ExercisesGlobalScoresInput; import io.openbas.rest.exercise.response.ExercisesGlobalScoresOutput; import io.openbas.rest.inject.service.InjectDuplicateService; +import io.openbas.rest.inject.service.InjectService; import io.openbas.service.GrantService; +import io.openbas.service.TagRuleService; import io.openbas.service.TeamService; import io.openbas.service.VariableService; import io.openbas.utils.AtomicTestingUtils; @@ -68,6 +70,8 @@ public class ExerciseService { private final InjectDuplicateService injectDuplicateService; private final TeamService teamService; private final VariableService variableService; + private final TagRuleService tagRuleService; + private final InjectService injectService; private final ExerciseMapper exerciseMapper; private final InjectMapper injectMapper; @@ -614,4 +618,42 @@ public Iterable removeTeams( this.lessonsCategoryRepository.removeTeamsForExercise(exerciseId, teamIds); return teamRepository.findAllById(teamIds); } + + /** + * Update the simulation and each of the injects to add/remove default assets + * + * @param exercise + * @param currentTags list of the tags before the update + * @return + */ + @Transactional + public Exercise updateExerciceAndApplyRule( + @NotNull final Exercise exercise, @NotNull final Set currentTags) { + // Get assets from the TagRule of the added tags + List defaultAssetsToAdd = + tagRuleService.getAssetsFromTagIds( + exercise.getTags().stream() + .filter(tag -> !currentTags.contains(tag)) + .map(Tag::getId) + .toList()); + + // Get assets from the TagRule of the removed tags + List defaultAssetsToRemove = + tagRuleService.getAssetsFromTagIds( + currentTags.stream() + .filter(tag -> !exercise.getTags().contains(tag)) + .map(Tag::getId) + .toList()); + + // Add/remove the default assets to/from the injects + exercise + .getInjects() + .forEach( + inject -> + injectService.applyDefaultAssetsToInject( + inject.getId(), defaultAssetsToAdd, defaultAssetsToRemove)); + + exercise.setUpdatedAt(now()); + return exerciseRepository.save(exercise); + } } diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java b/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java index d366d2bd4b..9c4ae85abd 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java @@ -33,6 +33,7 @@ import io.openbas.rest.inject.service.InjectService; import io.openbas.service.InjectSearchService; import io.openbas.service.ScenarioService; +import io.openbas.service.TagRuleService; import io.openbas.telemetry.Tracing; import io.openbas.utils.pagination.SearchPaginationInput; import jakarta.validation.Valid; @@ -40,9 +41,7 @@ import jakarta.validation.constraints.NotNull; import java.time.Duration; import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.StreamSupport; import lombok.RequiredArgsConstructor; @@ -84,6 +83,7 @@ public class InjectApi extends RestBehavior { private final ExecutableInjectService executableInjectService; private final InjectSearchService injectSearchService; private final InjectDuplicateService injectDuplicateService; + private final TagRuleService tagRuleService; // -- INJECTS -- @@ -346,7 +346,13 @@ public Inject createInjectForExercise( .toList()); } inject.setTeams(fromIterable(teamRepository.findAllById(input.getTeams()))); - inject.setAssets(fromIterable(assetService.assets(input.getAssets()))); + + // Get input assets + inject.setAssets( + this.tagRuleService.applyTagRuleToInjectCreation( + exercise.getTags().stream().map(Tag::getId).toList(), + assetService.assets(input.getAssets()))); + inject.setAssetGroups(fromIterable(assetGroupService.assetGroups(input.getAssetGroups()))); inject.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds()))); List injectDocuments = @@ -579,7 +585,13 @@ public Inject createInjectForScenario( .toList()); } inject.setTeams(fromIterable(teamRepository.findAllById(input.getTeams()))); - inject.setAssets(fromIterable(assetService.assets(input.getAssets()))); + + // Get input assets + inject.setAssets( + this.tagRuleService.applyTagRuleToInjectCreation( + scenario.getTags().stream().map(Tag::getId).toList(), + assetService.assets(input.getAssets()))); + inject.setAssetGroups(fromIterable(assetGroupService.assetGroups(input.getAssetGroups()))); inject.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds()))); List injectDocuments = diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java index c8b3921a94..d865049f43 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java @@ -4,7 +4,6 @@ import static java.time.Instant.now; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import io.openbas.database.model.ExecutionStatus; import io.openbas.database.model.Inject; import io.openbas.database.model.InjectDocument; @@ -20,7 +19,6 @@ import jakarta.annotation.Resource; import jakarta.transaction.Transactional; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import java.time.Instant; import java.util.List; import java.util.stream.Stream; @@ -86,12 +84,6 @@ public void cleanInjectsDocExercise(String exerciseId, String documentId) { injectDocumentRepository.deleteAll(updatedInjects); } - public T convertInjectContent(@NotNull final Inject inject, @NotNull final Class converter) - throws Exception { - ObjectNode content = inject.getContent(); - return this.mapper.treeToValue(content, converter); - } - public void cleanInjectsDocScenario(String scenarioId, String documentId) { // Delete document from all scenario injects List scenarioInjects = diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java index c9f068d543..2f28f26612 100644 --- a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java @@ -31,6 +31,7 @@ import jakarta.validation.constraints.NotNull; import java.io.IOException; import java.util.List; +import java.util.Set; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -100,11 +101,16 @@ public Scenario scenario(@PathVariable @NotBlank final String scenarioId) { @PreAuthorize("isScenarioPlanner(#scenarioId)") public Scenario updateScenario( @PathVariable @NotBlank final String scenarioId, - @Valid @RequestBody final ScenarioInput input) { + @Valid @RequestBody final UpdateScenarioInput input) { Scenario scenario = this.scenarioService.scenario(scenarioId); + Set currentTagList = scenario.getTags(); scenario.setUpdateAttributes(input); scenario.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds()))); - return this.scenarioService.updateScenario(scenario); + if (input.isApplyTagRule()) { + return this.scenarioService.updateScenarioAndApplyRule(scenario, currentTagList); + } else { + return this.scenarioService.updateScenario(scenario); + } } @PutMapping(SCENARIO_URI + "/{scenarioId}/information") @@ -131,8 +137,14 @@ public Scenario updateScenarioTags( @PathVariable @NotBlank final String scenarioId, @Valid @RequestBody final ScenarioUpdateTagsInput input) { Scenario scenario = this.scenarioService.scenario(scenarioId); + Set currentTagList = scenario.getTags(); scenario.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds()))); - return scenarioService.updateScenario(scenario); + + if (input.isApplyTagRule()) { + return this.scenarioService.updateScenarioAndApplyRule(scenario, currentTagList); + } else { + return this.scenarioService.updateScenario(scenario); + } } // -- EXPORT -- diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioUpdateTagsInput.java b/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioUpdateTagsInput.java index c1cec13872..ee4bc37c6d 100644 --- a/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioUpdateTagsInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioUpdateTagsInput.java @@ -12,4 +12,7 @@ public class ScenarioUpdateTagsInput { @JsonProperty("scenario_tags") private List tagIds = new ArrayList<>(); + + @JsonProperty("apply_tag_rule") + private boolean applyTagRule = false; } diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/form/UpdateScenarioInput.java b/openbas-api/src/main/java/io/openbas/rest/scenario/form/UpdateScenarioInput.java new file mode 100644 index 0000000000..2ec3728f0f --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/form/UpdateScenarioInput.java @@ -0,0 +1,12 @@ +package io.openbas.rest.scenario.form; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.Getter; + +@Data +@Getter +public class UpdateScenarioInput extends ScenarioInput { + @JsonProperty("apply_tag_rule") + private boolean applyTagRule = false; +} 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 70b4297c45..fd88d36520 100644 --- a/openbas-api/src/main/java/io/openbas/service/ScenarioService.java +++ b/openbas-api/src/main/java/io/openbas/service/ScenarioService.java @@ -33,6 +33,7 @@ import io.openbas.rest.exercise.exports.VariableWithValueMixin; import io.openbas.rest.exercise.form.ExerciseSimple; import io.openbas.rest.inject.service.InjectDuplicateService; +import io.openbas.rest.inject.service.InjectService; import io.openbas.rest.scenario.export.ScenarioExportMixins; import io.openbas.rest.scenario.export.ScenarioFileExport; import io.openbas.rest.scenario.form.ScenarioSimple; @@ -102,6 +103,9 @@ public class ScenarioService { private final TeamService teamService; private final FileService fileService; private final InjectDuplicateService injectDuplicateService; + private final TagRuleService tagRuleService; + private final InjectService injectService; + private final InjectRepository injectRepository; private final LessonsCategoryRepository lessonsCategoryRepository; @@ -294,6 +298,44 @@ public Scenario updateScenario(@NotNull final Scenario scenario) { return this.scenarioRepository.save(scenario); } + /** + * Update the scenario and each of the injects to add/remove default assets + * + * @param scenario + * @param currentTags list of the tags before the update + * @return + */ + @Transactional + public Scenario updateScenarioAndApplyRule( + @NotNull final Scenario scenario, @NotNull Set currentTags) { + // Get assets from the TagRule of the added tags + List defaultAssetsToAdd = + tagRuleService.getAssetsFromTagIds( + scenario.getTags().stream() + .filter(tag -> !currentTags.contains(tag)) + .map(Tag::getId) + .toList()); + + // Get assets from the TagRule of the removed tags + List defaultAssetsToRemove = + tagRuleService.getAssetsFromTagIds( + currentTags.stream() + .filter(tag -> !scenario.getTags().contains(tag)) + .map(Tag::getId) + .toList()); + + // Add/remove the default assets to/from the injects + scenario + .getInjects() + .forEach( + inject -> + injectService.applyDefaultAssetsToInject( + inject.getId(), defaultAssetsToAdd, defaultAssetsToRemove)); + + scenario.setUpdatedAt(now()); + return this.scenarioRepository.save(scenario); + } + public void updateScenarios(@NotNull final List scenarios) { scenarios.forEach(scenario -> scenario.setUpdatedAt(now())); this.scenarioRepository.saveAll(scenarios); diff --git a/openbas-api/src/main/java/io/openbas/service/TagRuleService.java b/openbas-api/src/main/java/io/openbas/service/TagRuleService.java index f02d04fa18..5b1706a4c3 100644 --- a/openbas-api/src/main/java/io/openbas/service/TagRuleService.java +++ b/openbas-api/src/main/java/io/openbas/service/TagRuleService.java @@ -12,21 +12,21 @@ import io.openbas.rest.exception.ElementNotFoundException; import io.openbas.utils.pagination.SearchPaginationInput; import jakarta.validation.constraints.NotBlank; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import jakarta.validation.constraints.NotNull; +import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; import java.util.stream.StreamSupport; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; -@Service @RequiredArgsConstructor +@Service public class TagRuleService { - private final TagRuleRepository tagRuleRepository; - private final TagRepository tagRepository; - private final AssetRepository assetRepository; + private TagRuleRepository tagRuleRepository; + private TagRepository tagRepository; + private AssetRepository assetRepository; public Optional findById(String id) { return tagRuleRepository.findById(id); @@ -83,6 +83,36 @@ protected Tag getTag(@NotBlank final String tagName) { .orElseThrow(() -> new ElementNotFoundException("Tag not found with name: " + tagName)); } + /** + * Return the set of assets to add from a tag id list + * + * @param tagIds + * @return set of assets to add by default + */ + public List getAssetsFromTagIds(@NotNull final List tagIds) { + return this.tagRuleRepository.findByTags(tagIds).stream() + .flatMap(tagRule -> tagRule.getAssets().stream()) + .toList(); + } + + /** + * Apply the rule to add the default assets to the input assets during Injects creation + * + * @param tagIds list of Assets of the Inject before applying the rules + * @param inputAssets list of Assets of the Inject before applying the rules + * @return return the new list of assets + */ + public List applyTagRuleToInjectCreation(List tagIds, List inputAssets) { + + List defaultAssets = this.getAssetsFromTagIds(tagIds); + + // remove duplicate + Set uniqueAssetsIds = new HashSet<>(); + return Stream.concat(inputAssets.stream(), defaultAssets.stream()) + .filter(asset -> uniqueAssetsIds.add(asset.getId())) + .toList(); + } + @VisibleForTesting protected List getAssets(final List assetIds) { return assetIds == null diff --git a/openbas-api/src/test/java/io/openbas/rest/exercise/ExerciseApiTest.java b/openbas-api/src/test/java/io/openbas/rest/exercise/ExerciseApiTest.java index 830f12fcd2..2eb1c5a0db 100644 --- a/openbas-api/src/test/java/io/openbas/rest/exercise/ExerciseApiTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/exercise/ExerciseApiTest.java @@ -3,7 +3,8 @@ import static io.openbas.rest.exercise.ExerciseApi.EXERCISE_URI; import static io.openbas.utils.JsonUtils.asJsonString; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -12,19 +13,23 @@ import com.jayway.jsonpath.JsonPath; import io.openbas.database.model.Exercise; import io.openbas.database.model.ExerciseTeamUser; +import io.openbas.database.model.Tag; import io.openbas.database.model.Team; import io.openbas.database.model.User; -import io.openbas.database.repository.ExerciseRepository; -import io.openbas.database.repository.ExerciseTeamUserRepository; -import io.openbas.database.repository.TeamRepository; -import io.openbas.database.repository.UserRepository; +import io.openbas.database.repository.*; +import io.openbas.rest.exercise.form.ExerciseUpdateTagsInput; import io.openbas.rest.exercise.form.ExercisesGlobalScoresInput; +import io.openbas.rest.exercise.form.UpdateExerciseInput; +import io.openbas.rest.exercise.service.ExerciseService; import io.openbas.utils.fixtures.ExerciseFixture; +import io.openbas.utils.fixtures.TagFixture; import io.openbas.utils.fixtures.TeamFixture; import io.openbas.utils.fixtures.UserFixture; import io.openbas.utils.mockUser.WithMockAdminUser; import java.util.*; import org.junit.jupiter.api.*; +import org.mockito.InjectMocks; +import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -33,7 +38,6 @@ @SpringBootTest @AutoConfigureMockMvc -@TestInstance(PER_CLASS) public class ExerciseApiTest { @Autowired private MockMvc mvc; @@ -45,12 +49,16 @@ public class ExerciseApiTest { @Autowired private ExerciseTeamUserRepository exerciseTeamUserRepository; + @Mock ExerciseRepository exerciseRepositoryMock; + @Mock TagRepository tagRepositoryMock; + @Mock ExerciseService exerciseServiceMock; + @InjectMocks private ExerciseApi exerciseApi; + private static final List EXERCISE_IDS = new ArrayList<>(); private static final List USER_IDS = new ArrayList<>(); private static final List TEAM_IDS = new ArrayList<>(); - @AfterAll - void afterAll() { + void cleanup() { this.exerciseRepository.deleteAllById(EXERCISE_IDS); this.userRepository.deleteAllById(USER_IDS); this.teamRepository.deleteAllById(TEAM_IDS); @@ -95,6 +103,8 @@ void retrievingPlayersByExercise() throws Exception { jsonPath("$[*].user_id") .value( org.hamcrest.Matchers.containsInAnyOrder(userTom.getId(), userBen.getId()))); + + cleanup(); } @Test @@ -130,6 +140,123 @@ void getGlobalScoreForExercises() throws Exception { "[]", JsonPath.read(response, "$.global_scores_by_exercise_ids." + exercise2Saved.getId()) .toString()); + + cleanup(); } } + + @DisplayName("Update with apply rule") + @Test + public void testUpdateExercise_WITH_apply_rule_true() { + Tag tag1 = TagFixture.getTag("Tag1"); + Tag tag2 = TagFixture.getTag("Tag2"); + Tag tag3 = TagFixture.getTag("Tag3"); + + Exercise exercise = ExerciseFixture.createDefaultCrisisExercise(); + exercise.setTags(Set.of(tag2, tag3, tag1)); + exercise.setId("test"); + UpdateExerciseInput input = new UpdateExerciseInput(); + input.setDescription("test"); + input.setApplyTagRule(true); + input.setTagIds(List.of(tag1.getId(), tag2.getId())); + + Exercise expected = ExerciseFixture.createDefaultCrisisExercise(); + expected.setId("test"); + expected.setDescription("test"); + expected.setTags(Set.of(tag1, tag2)); + + doReturn(List.of(tag1, tag2)) + .when(tagRepositoryMock) + .findAllById(List.of(tag1.getId(), tag2.getId())); + doReturn(Optional.of(exercise)).when(exerciseRepositoryMock).findById(exercise.getId()); + + exerciseApi.updateExerciseInformation(exercise.getId(), input); + + verify(exerciseServiceMock).updateExerciceAndApplyRule(expected, Set.of(tag2, tag3, tag1)); + } + + @DisplayName("Update without apply rule") + @Test + public void testUpdateExercise_WITH_apply_rule_false() throws Exception { + Tag tag1 = TagFixture.getTag("Tag1"); + Tag tag2 = TagFixture.getTag("Tag2"); + Tag tag3 = TagFixture.getTag("Tag3"); + + Exercise exercise = ExerciseFixture.createDefaultCrisisExercise(); + exercise.setTags(Set.of(tag2, tag3, tag1)); + exercise.setId("test"); + UpdateExerciseInput input = new UpdateExerciseInput(); + input.setDescription("test"); + input.setTagIds(List.of(tag1.getId(), tag2.getId())); + + Exercise expected = ExerciseFixture.createDefaultCrisisExercise(); + expected.setId("test"); + expected.setDescription("test"); + expected.setTags(Set.of(tag1, tag2)); + + doReturn(List.of(tag1, tag2)) + .when(tagRepositoryMock) + .findAllById(List.of(tag1.getId(), tag2.getId())); + doReturn(Optional.of(exercise)).when(exerciseRepositoryMock).findById(exercise.getId()); + + exerciseApi.updateExerciseInformation(exercise.getId(), input); + + verify(exerciseRepositoryMock).save(expected); + } + + @DisplayName("Update tags without apply rule") + @Test + public void testUpdateExerciseTags_WITH_apply_rule_false() { + Tag tag1 = TagFixture.getTag("Tag1"); + Tag tag2 = TagFixture.getTag("Tag2"); + Tag tag3 = TagFixture.getTag("Tag3"); + + Exercise exercise = ExerciseFixture.createDefaultCrisisExercise(); + exercise.setTags(Set.of(tag2, tag3, tag1)); + exercise.setId("test"); + + ExerciseUpdateTagsInput input = new ExerciseUpdateTagsInput(); + input.setTagIds(List.of(tag1.getId(), tag2.getId())); + + Exercise expected = ExerciseFixture.createDefaultCrisisExercise(); + expected.setTags(Set.of(tag1, tag2)); + expected.setId("test"); + + doReturn(List.of(tag1, tag2)) + .when(tagRepositoryMock) + .findAllById(List.of(tag1.getId(), tag2.getId())); + doReturn(Optional.of(exercise)).when(exerciseRepositoryMock).findById(exercise.getId()); + + exerciseApi.updateExerciseTags(exercise.getId(), input); + + verify(exerciseRepositoryMock).save(expected); + } + + @DisplayName("Update tags with apply rule") + @Test + public void testUpdateExerciseTags_WITH_apply_rule_true() { + Tag tag1 = TagFixture.getTag("Tag1"); + Tag tag2 = TagFixture.getTag("Tag2"); + Tag tag3 = TagFixture.getTag("Tag3"); + + Exercise exercise = ExerciseFixture.createDefaultCrisisExercise(); + exercise.setTags(Set.of(tag2, tag3, tag1)); + exercise.setId("test"); + ExerciseUpdateTagsInput input = new ExerciseUpdateTagsInput(); + input.setTagIds(List.of(tag1.getId(), tag2.getId())); + input.setApplyTagRule(true); + + Exercise expected = ExerciseFixture.createDefaultCrisisExercise(); + expected.setTags(Set.of(tag1, tag2)); + expected.setId("test"); + + doReturn(List.of(tag1, tag2)) + .when(tagRepositoryMock) + .findAllById(List.of(tag1.getId(), tag2.getId())); + doReturn(Optional.of(exercise)).when(exerciseRepositoryMock).findById(exercise.getId()); + + exerciseApi.updateExerciseTags(exercise.getId(), input); + + verify(exerciseServiceMock).updateExerciceAndApplyRule(expected, Set.of(tag2, tag3, tag1)); + } } diff --git a/openbas-api/src/test/java/io/openbas/service/ExerciseServiceTest.java b/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java similarity index 65% rename from openbas-api/src/test/java/io/openbas/service/ExerciseServiceTest.java rename to openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java index 3830cd1869..e301d31947 100644 --- a/openbas-api/src/test/java/io/openbas/service/ExerciseServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java @@ -1,17 +1,24 @@ -package io.openbas.service; +package io.openbas.rest.exercise.service; -import static io.openbas.expectation.ExpectationType.*; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.openbas.database.model.Asset; +import io.openbas.database.model.Exercise; +import io.openbas.database.model.Tag; import io.openbas.database.repository.*; import io.openbas.rest.exercise.form.ExercisesGlobalScoresInput; -import io.openbas.rest.exercise.service.ExerciseService; import io.openbas.rest.inject.service.InjectDuplicateService; +import io.openbas.rest.inject.service.InjectService; +import io.openbas.service.GrantService; +import io.openbas.service.TagRuleService; +import io.openbas.service.TeamService; +import io.openbas.service.VariableService; import io.openbas.utils.ExerciseMapper; import io.openbas.utils.InjectMapper; import io.openbas.utils.ResultUtils; -import io.openbas.utils.fixtures.ExpectationResultsByTypeFixture; +import io.openbas.utils.fixtures.*; import java.util.*; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; @@ -41,6 +48,8 @@ class ExerciseServiceTest { @Mock private ExerciseTeamUserRepository exerciseTeamUserRepository; @Mock private InjectRepository injectRepository; @Mock private LessonsCategoryRepository lessonsCategoryRepository; + @Mock private TagRuleService tagRuleService; + @Mock private InjectService injectService; @InjectMocks private ExerciseService exerciseService; @@ -52,6 +61,8 @@ void setUp() { injectDuplicateService, teamService, variableService, + tagRuleService, + injectService, exerciseMapper, injectMapper, resultUtils, @@ -98,4 +109,33 @@ void getExercisesGlobalScores() { exerciseId1, ExpectationResultsByTypeFixture.exercise1GlobalScores, exerciseId2, ExpectationResultsByTypeFixture.exercise2GlobalScores)); } + + @Test + public void testUpdateExerciseAndApplyRule_WITH_AddedAndRemovedTags() { + Asset asset1 = AssetFixture.createDefaultAsset("asset1"); + Asset asset2 = AssetFixture.createDefaultAsset("asset2"); + Asset asset3 = AssetFixture.createDefaultAsset("asset3"); + io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); + io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); + io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); + Exercise exercise = ExerciseFixture.getExerciseWithInjects(); + exercise.setTags(Set.of(tag1, tag2)); + Set currentTags = Set.of(tag2, tag3); + List assetsToAdd = List.of(asset1, asset2); + List assetsToRemove = List.of(asset3); + + when(tagRuleService.getAssetsFromTagIds(List.of(tag1.getId()))).thenReturn(assetsToAdd); + when(tagRuleService.getAssetsFromTagIds(List.of(tag3.getId()))).thenReturn(assetsToRemove); + when(exerciseRepository.save(exercise)).thenReturn(exercise); + + exerciseService.updateExerciceAndApplyRule(exercise, currentTags); + + exercise + .getInjects() + .forEach( + inject -> + verify(injectService) + .applyDefaultAssetsToInject(inject.getId(), assetsToAdd, assetsToRemove)); + verify(exerciseRepository).save(exercise); + } } diff --git a/openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java b/openbas-api/src/test/java/io/openbas/rest/inject/InjectApiTest.java similarity index 99% rename from openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java rename to openbas-api/src/test/java/io/openbas/rest/inject/InjectApiTest.java index 24d576b84c..c0ab9c6b11 100644 --- a/openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/inject/InjectApiTest.java @@ -1,4 +1,4 @@ -package io.openbas.rest; +package io.openbas.rest.inject; import static io.openbas.config.SessionHelper.currentUser; import static io.openbas.database.model.ExerciseStatus.RUNNING; @@ -44,14 +44,12 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.time.Instant; -import java.util.Base64; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; +import org.mockito.InjectMocks; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; @@ -96,6 +94,8 @@ class InjectApiTest extends IntegrationTest { @Resource private ObjectMapper objectMapper; @MockBean private JavaMailSender javaMailSender; + @InjectMocks private InjectApi injectApiWithMock; + @BeforeAll void beforeAll() { Scenario scenario = new Scenario(); diff --git a/openbas-api/src/test/java/io/openbas/rest/inject/service/InjectServiceTest.java b/openbas-api/src/test/java/io/openbas/rest/inject/service/InjectServiceTest.java new file mode 100644 index 0000000000..6183eb53bd --- /dev/null +++ b/openbas-api/src/test/java/io/openbas/rest/inject/service/InjectServiceTest.java @@ -0,0 +1,114 @@ +package io.openbas.rest.inject.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.*; + +import io.openbas.database.model.Asset; +import io.openbas.database.model.Inject; +import io.openbas.database.repository.InjectRepository; +import io.openbas.rest.exception.ElementNotFoundException; +import io.openbas.utils.fixtures.AssetFixture; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +public class InjectServiceTest { + + private static final String INJECT_ID = "injectid"; + + @Mock private InjectRepository injectRepository; + + @InjectMocks private InjectService injectService; + + @Test + public void testApplyDefaultAssetsToInject_WITH_unexisting_inject() { + doReturn(Optional.empty()).when(injectRepository).findById(INJECT_ID); + assertThrows( + ElementNotFoundException.class, + () -> { + injectService.applyDefaultAssetsToInject(INJECT_ID, List.of(), List.of()); + }); + } + + @Test + public void testApplyDefaultAssetsToInject_WITH_add_and_remove() { + Asset asset1 = AssetFixture.createDefaultAsset("asset1"); + Asset asset2 = AssetFixture.createDefaultAsset("asset2"); + Asset asset3 = AssetFixture.createDefaultAsset("asset3"); + Asset asset4 = AssetFixture.createDefaultAsset("asset4"); + Inject inject = new Inject(); + inject.setId(INJECT_ID); + inject.setAssets(List.of(asset1, asset2, asset3)); + doReturn(Optional.of(inject)).when(injectRepository).findById(INJECT_ID); + + injectService.applyDefaultAssetsToInject(INJECT_ID, List.of(asset4), List.of(asset3)); + + ArgumentCaptor injectCaptor = ArgumentCaptor.forClass(Inject.class); + verify(injectRepository).save(injectCaptor.capture()); + Inject capturedInject = injectCaptor.getValue(); + assertEquals(INJECT_ID, capturedInject.getId()); + assertEquals( + new HashSet<>(List.of(asset1, asset2, asset4)), new HashSet<>(capturedInject.getAssets())); + } + + @Test + public void testApplyDefaultAssetsToInject_WITH_remove_all() { + Asset asset1 = AssetFixture.createDefaultAsset("asset1"); + Asset asset2 = AssetFixture.createDefaultAsset("asset2"); + Asset asset3 = AssetFixture.createDefaultAsset("asset3"); + Inject inject = new Inject(); + inject.setId(INJECT_ID); + inject.setAssets(List.of(asset1, asset2, asset3)); + doReturn(Optional.of(inject)).when(injectRepository).findById(INJECT_ID); + + injectService.applyDefaultAssetsToInject(INJECT_ID, List.of(), List.of(asset1, asset2, asset3)); + + ArgumentCaptor injectCaptor = ArgumentCaptor.forClass(Inject.class); + verify(injectRepository).save(injectCaptor.capture()); + Inject capturedInject = injectCaptor.getValue(); + assertEquals(INJECT_ID, capturedInject.getId()); + assertEquals(List.of(), capturedInject.getAssets()); + } + + @Test + public void testApplyDefaultAssetsToInject_WITH_add_all() { + Asset asset1 = AssetFixture.createDefaultAsset("asset1"); + Asset asset2 = AssetFixture.createDefaultAsset("asset2"); + Asset asset3 = AssetFixture.createDefaultAsset("asset3"); + Inject inject = new Inject(); + inject.setId(INJECT_ID); + inject.setAssets(List.of()); + doReturn(Optional.of(inject)).when(injectRepository).findById(INJECT_ID); + + injectService.applyDefaultAssetsToInject(INJECT_ID, List.of(asset1, asset2, asset3), List.of()); + + ArgumentCaptor injectCaptor = ArgumentCaptor.forClass(Inject.class); + verify(injectRepository).save(injectCaptor.capture()); + Inject capturedInject = injectCaptor.getValue(); + assertEquals(INJECT_ID, capturedInject.getId()); + assertEquals( + new HashSet<>(List.of(asset1, asset2, asset3)), new HashSet<>(capturedInject.getAssets())); + } + + @Test + public void testApplyDefaultAssetsToInject_WITH_no_change() { + Asset asset1 = AssetFixture.createDefaultAsset("asset1"); + Asset asset2 = AssetFixture.createDefaultAsset("asset2"); + Asset asset3 = AssetFixture.createDefaultAsset("asset3"); + Inject inject = new Inject(); + inject.setId(INJECT_ID); + inject.setAssets(List.of(asset1, asset2, asset3)); + doReturn(Optional.of(inject)).when(injectRepository).findById(INJECT_ID); + + injectService.applyDefaultAssetsToInject(INJECT_ID, List.of(asset1), List.of(asset1)); + + verify(injectRepository, never()).save(any()); + } +} diff --git a/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java b/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java index e29bc3ca9b..f0316036da 100644 --- a/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java @@ -4,18 +4,31 @@ import static io.openbas.utils.JsonUtils.asJsonString; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.jayway.jsonpath.JsonPath; +import io.openbas.database.model.Scenario; +import io.openbas.database.model.Tag; import io.openbas.database.repository.ScenarioRepository; +import io.openbas.database.repository.TagRepository; import io.openbas.rest.scenario.form.ScenarioInformationInput; import io.openbas.rest.scenario.form.ScenarioInput; +import io.openbas.rest.scenario.form.ScenarioUpdateTagsInput; +import io.openbas.rest.scenario.form.UpdateScenarioInput; +import io.openbas.service.ScenarioService; +import io.openbas.utils.fixtures.ScenarioFixture; +import io.openbas.utils.fixtures.TagFixture; import io.openbas.utils.mockUser.WithMockObserverUser; import io.openbas.utils.mockUser.WithMockPlannerUser; +import java.util.List; +import java.util.Set; import org.junit.jupiter.api.*; +import org.mockito.InjectMocks; +import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -25,17 +38,19 @@ @SpringBootTest @AutoConfigureMockMvc @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -@TestInstance(PER_CLASS) public class ScenarioApiTest { @Autowired private MockMvc mvc; @Autowired private ScenarioRepository scenarioRepository; + @Mock TagRepository tagRepositoryMock; + @Mock ScenarioService scenarioServiceMock; + @InjectMocks private ScenarioApi scenarioApi; + static String SCENARIO_ID; - @AfterAll - void afterAll() { + void cleanup() { this.scenarioRepository.deleteById(SCENARIO_ID); } @@ -79,6 +94,7 @@ void createScenarioTest() throws Exception { // -- ASSERT -- assertNotNull(response); SCENARIO_ID = JsonPath.read(response, "$.scenario_id"); + cleanup(); } @DisplayName("Retrieve scenarios") @@ -97,6 +113,7 @@ void retrieveScenariosTest() throws Exception { // -- ASSERT -- assertNotNull(response); + cleanup(); } @DisplayName("Retrieve scenario") @@ -115,6 +132,7 @@ void retrieveScenarioTest() throws Exception { // -- ASSERT -- assertNotNull(response); + cleanup(); } @DisplayName("Update scenario") @@ -153,6 +171,7 @@ void updateScenarioTest() throws Exception { // -- ASSERT -- assertNotNull(response); assertEquals(subtitle, JsonPath.read(response, "$.scenario_subtitle")); + cleanup(); } @DisplayName("Update scenario information") @@ -182,6 +201,7 @@ void updateScenarioInformationTest() throws Exception { // -- ASSERT -- assertNotNull(response); assertEquals(header, JsonPath.read(response, "$.scenario_message_header")); + cleanup(); } @DisplayName("Delete scenario") @@ -193,5 +213,122 @@ void deleteScenarioTest() throws Exception { this.mvc .perform(delete(SCENARIO_URI + "/" + SCENARIO_ID)) .andExpect(status().is2xxSuccessful()); + cleanup(); + } + + @DisplayName("Update with apply rule") + @Test + public void testUpdateScenario_WITH_apply_rule_true() { + io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); + io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); + io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); + + Scenario scenario = ScenarioFixture.getScenarioWithInjects(); + scenario.setTags(Set.of(tag2, tag3, tag1)); + scenario.setId("test"); + UpdateScenarioInput input = new UpdateScenarioInput(); + input.setDescription("test"); + input.setApplyTagRule(true); + input.setTagIds(List.of(tag1.getId(), tag2.getId())); + + Scenario expected = ScenarioFixture.getScenarioWithInjects(); + scenario.setId("test"); + expected.setDescription("test"); + expected.setTags(Set.of(tag1, tag2)); + + doReturn(List.of(tag1, tag2)) + .when(tagRepositoryMock) + .findAllById(List.of(tag1.getId(), tag2.getId())); + doReturn(scenario).when(scenarioServiceMock).scenario(scenario.getId()); + + scenarioApi.updateScenario(scenario.getId(), input); + + verify(scenarioServiceMock).updateScenarioAndApplyRule(expected, Set.of(tag2, tag3, tag1)); + } + + @DisplayName("Update without apply rule") + @Test + public void testUpdateScenario_WITH_apply_rule_false() throws Exception { + io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); + io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); + io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); + + Scenario scenario = ScenarioFixture.getScenarioWithInjects(); + scenario.setTags(Set.of(tag2, tag3, tag1)); + scenario.setId("test"); + UpdateScenarioInput input = new UpdateScenarioInput(); + input.setDescription("test"); + input.setApplyTagRule(true); + input.setTagIds(List.of(tag1.getId(), tag2.getId())); + + Scenario expected = ScenarioFixture.getScenarioWithInjects(); + expected.setId("test"); + expected.setDescription("test"); + expected.setTags(Set.of(tag1, tag2)); + + doReturn(List.of(tag1, tag2)) + .when(tagRepositoryMock) + .findAllById(List.of(tag1.getId(), tag2.getId())); + doReturn(scenario).when(scenarioServiceMock).scenario(scenario.getId()); + + scenarioApi.updateScenario(scenario.getId(), input); + + verify(scenarioServiceMock).updateScenario(expected); + } + + @DisplayName("Update tags without apply rule") + @Test + public void testUpdateScenarioTags_WITH_apply_rule_false() { + io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); + io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); + io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); + + Scenario scenario = ScenarioFixture.getScenarioWithInjects(); + scenario.setTags(Set.of(tag2, tag3, tag1)); + scenario.setId("test"); + + ScenarioUpdateTagsInput input = new ScenarioUpdateTagsInput(); + input.setTagIds(List.of(tag1.getId(), tag2.getId())); + + Scenario expected = ScenarioFixture.getScenarioWithInjects(); + expected.setId("test"); + expected.setTags(Set.of(tag1, tag2)); + + doReturn(List.of(tag1, tag2)) + .when(tagRepositoryMock) + .findAllById(List.of(tag1.getId(), tag2.getId())); + doReturn(scenario).when(scenarioServiceMock).scenario(scenario.getId()); + + scenarioApi.updateScenarioTags(scenario.getId(), input); + + verify(scenarioServiceMock).updateScenario(expected); + } + + @DisplayName("Update tags with apply rule") + @Test + public void testUpdateScenarioTags_WITH_apply_rule_true() { + io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); + io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); + Tag tag3 = TagFixture.getTag("Tag3"); + + Scenario scenario = ScenarioFixture.getScenarioWithInjects(); + scenario.setTags(Set.of(tag2, tag3, tag1)); + scenario.setId("test"); + ScenarioUpdateTagsInput input = new ScenarioUpdateTagsInput(); + input.setTagIds(List.of(tag1.getId(), tag2.getId())); + input.setApplyTagRule(true); + + Scenario expected = ScenarioFixture.getScenarioWithInjects(); + expected.setId("test"); + expected.setTags(Set.of(tag1, tag2)); + + doReturn(List.of(tag1, tag2)) + .when(tagRepositoryMock) + .findAllById(List.of(tag1.getId(), tag2.getId())); + doReturn(scenario).when(scenarioServiceMock).scenario(scenario.getId()); + + scenarioApi.updateScenarioTags(scenario.getId(), input); + + verify(scenarioServiceMock).updateScenarioAndApplyRule(expected, Set.of(tag2, tag3, tag1)); } } diff --git a/openbas-api/src/test/java/io/openbas/service/ExerciseServiceIntegrationTest.java b/openbas-api/src/test/java/io/openbas/service/ExerciseServiceIntegrationTest.java index afa6470179..b2c6c3786c 100644 --- a/openbas-api/src/test/java/io/openbas/service/ExerciseServiceIntegrationTest.java +++ b/openbas-api/src/test/java/io/openbas/service/ExerciseServiceIntegrationTest.java @@ -13,6 +13,7 @@ import io.openbas.database.repository.*; import io.openbas.rest.exercise.service.ExerciseService; import io.openbas.rest.inject.service.InjectDuplicateService; +import io.openbas.rest.inject.service.InjectService; import io.openbas.utils.ExerciseMapper; import io.openbas.utils.InjectMapper; import io.openbas.utils.ResultUtils; @@ -35,6 +36,9 @@ class ExerciseServiceIntegrationTest { @Mock VariableService variableService; @Autowired private TeamService teamService; + @Autowired private TagRuleService tagRuleService; + @Autowired private InjectService injectService; + @Autowired private ExerciseMapper exerciseMapper; @Autowired private InjectMapper injectMapper; @Autowired private ResultUtils resultUtils; @@ -65,6 +69,8 @@ void setUp() { injectDuplicateService, teamService, variableService, + tagRuleService, + injectService, exerciseMapper, injectMapper, resultUtils, diff --git a/openbas-api/src/test/java/io/openbas/service/InjectServiceTest.java b/openbas-api/src/test/java/io/openbas/service/InjectServiceTest.java deleted file mode 100644 index 673a2e2336..0000000000 --- a/openbas-api/src/test/java/io/openbas/service/InjectServiceTest.java +++ /dev/null @@ -1,830 +0,0 @@ -package io.openbas.service; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import io.openbas.config.OpenBASOAuth2User; -import io.openbas.config.SessionHelper; -import io.openbas.database.model.*; -import io.openbas.database.repository.*; -import io.openbas.rest.exception.BadRequestException; -import io.openbas.rest.scenario.form.InjectsImportInput; -import io.openbas.rest.scenario.response.ImportMessage; -import io.openbas.rest.scenario.response.ImportPostSummary; -import io.openbas.rest.scenario.response.ImportTestSummary; -import io.openbas.utils.CustomMockMultipartFile; -import jakarta.annotation.Resource; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.LocalDateTime; -import java.time.Month; -import java.time.ZoneOffset; -import java.util.*; -import org.apache.commons.io.FilenameUtils; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.util.ResourceUtils; - -@ExtendWith(MockitoExtension.class) -class InjectServiceTest { - - @Mock InjectRepository injectRepository; - @Mock TeamRepository teamRepository; - @Mock ScenarioTeamUserRepository scenarioTeamUserRepository; - @Mock ExerciseTeamUserRepository exerciseTeamUserRepository; - @Mock UserRepository userRepository; - @Mock private InjectImportService injectImportService; - - private Scenario mockedScenario; - - private Exercise mockedExercise; - - private ImportMapper mockedImportMapper; - - private InjectsImportInput mockedInjectsImportInput; - @Resource protected ObjectMapper mapper; - - @BeforeEach - void setUp() { - injectImportService = - new InjectImportService( - injectRepository, - scenarioTeamUserRepository, - exerciseTeamUserRepository, - teamRepository, - userRepository); - - mockedScenario = new Scenario(); - mockedExercise = new Exercise(); - mapper = new ObjectMapper(); - } - - @DisplayName("Post and store an XLS file") - @Test - void postAnXLSFile() throws Exception { - // -- PREPARE -- - // Getting a test file - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_1.xlsx"); - - InputStream in = new FileInputStream(testFile); - MockMultipartFile xlsFile = - new MockMultipartFile("file", "my-awesome-file.xls", "application/xlsx", in.readAllBytes()); - - ImportPostSummary response = injectImportService.storeXlsFileForImport(xlsFile); - - // -- ASSERT -- - assertNotNull(response); - try { - UUID.fromString(response.getImportId()); - } catch (Exception ex) { - fail(); - } - assertEquals(1, response.getAvailableSheets().size()); - assertEquals("CHECKLIST", response.getAvailableSheets().get(0)); - } - - @DisplayName("Post and store a corrupted XLS file") - @Test - void postACorruptedXLSFile() throws Exception { - // Getting a test file - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_1.xlsx"); - // -- PREPARE -- - InputStream in = new FileInputStream(testFile); - MockMultipartFile xlsFile = - new CustomMockMultipartFile( - "file", "my-awesome-file.xls", "application/xlsx", in.readAllBytes()); - - // -- EXECUTE -- - try { - injectImportService.storeXlsFileForImport(xlsFile); - fail(); - } catch (Exception ex) { - assertTrue(ex instanceof BadRequestException); - } - } - - @DisplayName("Import an XLS file with relative date") - @Test - void testImportXlsRelativeDate() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - User mockedUser = new User(); - String fileID = UUID.randomUUID().toString(); - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_1.xlsx"); - createTempFile(testFile, fileID); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - when(userRepository.findById(any())).thenReturn(Optional.of(mockedUser)); - Team team1 = new Team(); - team1.setName("team1"); - Team team2 = new Team(); - team2.setName("team2"); - when(teamRepository.findAll()).thenReturn(List.of(team1)); - when(teamRepository.save(any())).thenReturn(team2); - - mockedScenario.setId(UUID.randomUUID().toString()); - - sessionHelper.when(SessionHelper::currentUser).thenReturn(new OpenBASOAuth2User(mockedUser)); - ImportTestSummary importTestSummary = - injectImportService.importInjectIntoScenarioFromXLS( - mockedScenario, mockedImportMapper, fileID, "CHECKLIST", 120, false); - - verify(teamRepository, times(1)).save(any()); - assertEquals( - 30 * 24 * 60 * 60, importTestSummary.getInjects().getLast().getDependsDuration()); - - ObjectNode jsonNodeMail = - (ObjectNode) - mapper.readTree( - "{\"message\":\"message1\",\"expectations\":[{\"expectation_description\":\"expectation\",\"expectation_name\":\"expectation done\",\"expectation_score\":100.0,\"expectation_type\":\"MANUAL\",\"expectation_expectation_group\":false}]}"); - assertEquals(jsonNodeMail, importTestSummary.getInjects().getFirst().getContent()); - - ObjectNode jsonNodeSms = - (ObjectNode) - mapper.readTree( - "{\"subject\":\"subject\",\"body\":\"message2\",\"expectations\":[{\"expectation_description\":\"expectation\",\"expectation_name\":\"expectation done\",\"expectation_score\":100.0,\"expectation_type\":\"MANUAL\",\"expectation_expectation_group\":false}]}"); - assertEquals(jsonNodeSms, importTestSummary.getInjects().getLast().getContent()); - } - } - - @DisplayName("Import a non existing XLS file") - @Test - void testImportXlsBadFile() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - String fileID = UUID.randomUUID().toString(); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - try { - injectImportService.importInjectIntoScenarioFromXLS( - mockedScenario, mockedImportMapper, fileID, "CHECKLIST", 120, true); - fail(); - } catch (Exception ex) { - assertTrue(ex instanceof BadRequestException); - } - } - } - - @DisplayName("Import an XLS file and have several matches of importer") - @Test - void testImportXlsSeveralMatches() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - User mockedUser = new User(); - String fileID = UUID.randomUUID().toString(); - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_1.xlsx"); - createTempFile(testFile, fileID); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - when(userRepository.findById(any())).thenReturn(Optional.of(mockedUser)); - Team team1 = new Team(); - team1.setName("team1"); - Team team2 = new Team(); - team2.setName("team2"); - when(teamRepository.findAll()).thenReturn(List.of(team1)); - lenient().when(teamRepository.save(any())).thenReturn(team2); - - sessionHelper.when(SessionHelper::currentUser).thenReturn(new OpenBASOAuth2User(mockedUser)); - - InjectImporter injectImporterMailCopy = new InjectImporter(); - injectImporterMailCopy.setId(UUID.randomUUID().toString()); - injectImporterMailCopy.setImportTypeValue(".*mail"); - injectImporterMailCopy.setRuleAttributes(new ArrayList<>()); - injectImporterMailCopy.setInjectorContract(createMailInjectorContract()); - - injectImporterMailCopy.getRuleAttributes().addAll(createRuleAttributeMail()); - mockedImportMapper.getInjectImporters().add(injectImporterMailCopy); - ImportTestSummary importTestSummary = - injectImportService.importInjectIntoScenarioFromXLS( - mockedScenario, mockedImportMapper, fileID, "CHECKLIST", 120, true); - assertTrue( - importTestSummary.getImportMessage().stream() - .anyMatch( - importMessage -> - importMessage.getMessageLevel().equals(ImportMessage.MessageLevel.WARN) - && importMessage - .getErrorCode() - .equals(ImportMessage.ErrorCode.SEVERAL_MATCHES))); - } - } - - @DisplayName("Import an XLS file with absolute date") - @Test - void testImportXlsAbsoluteDate() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - User mockedUser = new User(); - String fileID = UUID.randomUUID().toString(); - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_2.xlsx"); - createTempFile(testFile, fileID); - - mockedScenario = new Scenario(); - mockedScenario.setId(UUID.randomUUID().toString()); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - mockedImportMapper - .getInjectImporters() - .forEach( - injectImporter -> { - injectImporter.setRuleAttributes( - injectImporter.getRuleAttributes().stream() - .map( - ruleAttribute -> { - if ("trigger_time".equals(ruleAttribute.getName())) { - ruleAttribute.setAdditionalConfig( - Map.of("timePattern", "dd/MM/yyyy HH'h'mm")); - } - return ruleAttribute; - }) - .toList()); - }); - when(userRepository.findById(any())).thenReturn(Optional.of(mockedUser)); - Team team1 = new Team(); - team1.setName("team1"); - team1.setUsers(List.of(new User())); - Team team2 = new Team(); - team2.setName("team2"); - team1.setUsers(List.of(new User())); - when(teamRepository.findAll()).thenReturn(List.of(team1)); - when(teamRepository.save(any())).thenReturn(team2); - - when(injectRepository.saveAll(any())) - .thenReturn(List.of(createNewInject(List.of(team1)), new Inject())); - - sessionHelper.when(SessionHelper::currentUser).thenReturn(new OpenBASOAuth2User(mockedUser)); - ImportTestSummary importTestSummary = - injectImportService.importInjectIntoScenarioFromXLS( - mockedScenario, mockedImportMapper, fileID, "CHECKLIST", 120, true); - - assertTrue( - LocalDateTime.of(2024, Month.JUNE, 26, 0, 0) - .toInstant(ZoneOffset.of("Z")) - .equals(mockedScenario.getRecurrenceStart())); - assertTrue("0 0 7 * * *".equals(mockedScenario.getRecurrence())); - } - } - - @DisplayName("Import an XLS file with absolute date") - @Test - void testImportXlsAbsoluteDateWithExistingScenarioTeamUser() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - User mockedUser = new User(); - String fileID = UUID.randomUUID().toString(); - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_2.xlsx"); - createTempFile(testFile, fileID); - - mockedScenario = new Scenario(); - mockedScenario.setId(UUID.randomUUID().toString()); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - mockedImportMapper - .getInjectImporters() - .forEach( - injectImporter -> { - injectImporter.setRuleAttributes( - injectImporter.getRuleAttributes().stream() - .map( - ruleAttribute -> { - if ("trigger_time".equals(ruleAttribute.getName())) { - ruleAttribute.setAdditionalConfig( - Map.of("timePattern", "dd/MM/yyyy HH'h'mm")); - } - return ruleAttribute; - }) - .toList()); - }); - when(userRepository.findById(any())).thenReturn(Optional.of(mockedUser)); - Team team1 = new Team(); - team1.setName("team1"); - team1.setUsers(List.of(new User())); - Team team2 = new Team(); - team2.setName("team2"); - team1.setUsers(List.of(new User())); - when(scenarioTeamUserRepository.findById(any())) - .thenReturn(Optional.of(new ScenarioTeamUser())); - when(teamRepository.findAll()).thenReturn(List.of(team1)); - when(teamRepository.save(any())).thenReturn(team2); - - when(injectRepository.saveAll(any())) - .thenReturn(List.of(createNewInject(List.of(team1)), new Inject())); - - sessionHelper.when(SessionHelper::currentUser).thenReturn(new OpenBASOAuth2User(mockedUser)); - ImportTestSummary importTestSummary = - injectImportService.importInjectIntoScenarioFromXLS( - mockedScenario, mockedImportMapper, fileID, "CHECKLIST", 120, true); - - assertTrue( - LocalDateTime.of(2024, Month.JUNE, 26, 0, 0) - .toInstant(ZoneOffset.of("Z")) - .equals(mockedScenario.getRecurrenceStart())); - assertTrue("0 0 7 * * *".equals(mockedScenario.getRecurrence())); - } - } - - @DisplayName("Import an XLS file with relative and absolute dates") - @Test - void testImportXlsAbsoluteAndRelativeDates() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - User mockedUser = new User(); - String fileID = UUID.randomUUID().toString(); - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_3.xlsx"); - createTempFile(testFile, fileID); - - mockedScenario = new Scenario(); - mockedScenario.setId(UUID.randomUUID().toString()); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - mockedImportMapper - .getInjectImporters() - .forEach( - injectImporter -> { - injectImporter.setRuleAttributes( - injectImporter.getRuleAttributes().stream() - .map( - ruleAttribute -> { - if ("trigger_time".equals(ruleAttribute.getName())) { - ruleAttribute.setAdditionalConfig( - Map.of("timePattern", "dd/MM/yyyy HH'h'mm")); - } - return ruleAttribute; - }) - .toList()); - }); - when(userRepository.findById(any())).thenReturn(Optional.of(mockedUser)); - Team team1 = new Team(); - team1.setName("team1"); - Team team2 = new Team(); - team2.setName("team2"); - when(teamRepository.findAll()).thenReturn(List.of(team1)); - when(teamRepository.save(any())).thenReturn(team2); - - sessionHelper.when(SessionHelper::currentUser).thenReturn(new OpenBASOAuth2User(mockedUser)); - ImportTestSummary importTestSummary = - injectImportService.importInjectIntoScenarioFromXLS( - mockedScenario, mockedImportMapper, fileID, "CHECKLIST", 120, false); - - List sortedInjects = - importTestSummary.getInjects().stream() - .sorted(Comparator.comparing(Inject::getDependsDuration)) - .toList(); - - assertEquals(24 * 60 * 60, sortedInjects.get(1).getDependsDuration()); - assertEquals(24 * 60 * 60 + 5 * 60, sortedInjects.get(2).getDependsDuration()); - assertEquals(2 * 24 * 60 * 60, sortedInjects.get(3).getDependsDuration()); - } - } - - @DisplayName("Import an XLS file with relative dates and absolute hours") - @Test - void testImportXlsRelativeDatesAndAbsoluteHour() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - User mockedUser = new User(); - String fileID = UUID.randomUUID().toString(); - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_4.xlsx"); - createTempFile(testFile, fileID); - - mockedScenario.setId(UUID.randomUUID().toString()); - mockedScenario.setRecurrenceStart( - LocalDateTime.of(2024, Month.JUNE, 26, 0, 0).toInstant(ZoneOffset.of("Z"))); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - mockedImportMapper - .getInjectImporters() - .forEach( - injectImporter -> { - injectImporter.setRuleAttributes( - injectImporter.getRuleAttributes().stream() - .map( - ruleAttribute -> { - if ("trigger_time".equals(ruleAttribute.getName())) { - ruleAttribute.setAdditionalConfig(Map.of("timePattern", "HH'h'mm")); - } - return ruleAttribute; - }) - .toList()); - }); - when(userRepository.findById(any())).thenReturn(Optional.of(mockedUser)); - Team team1 = new Team(); - team1.setName("team1"); - Team team2 = new Team(); - team2.setName("team2"); - when(teamRepository.findAll()).thenReturn(List.of(team1)); - when(teamRepository.save(any())).thenReturn(team2); - - sessionHelper.when(SessionHelper::currentUser).thenReturn(new OpenBASOAuth2User(mockedUser)); - ImportTestSummary importTestSummary = - injectImportService.importInjectIntoScenarioFromXLS( - mockedScenario, mockedImportMapper, fileID, "CHECKLIST", 120, false); - - List sortedInjects = - importTestSummary.getInjects().stream() - .sorted(Comparator.comparing(Inject::getDependsDuration)) - .toList(); - - assertEquals(24 * 60 * 60, sortedInjects.get(1).getDependsDuration()); - assertEquals(2 * 24 * 60 * 60, sortedInjects.get(2).getDependsDuration()); - assertEquals(4 * 24 * 60 * 60 + 5 * 60, sortedInjects.get(3).getDependsDuration()); - } - } - - @DisplayName( - "Critical message when import an XLS file with relative dates " - + "and absolute hours but no date in scenario") - @Test - void testImportXlsRelativeDatesAndAbsoluteHourCriticalMessage() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - User mockedUser = new User(); - String fileID = UUID.randomUUID().toString(); - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_4.xlsx"); - createTempFile(testFile, fileID); - - mockedScenario = new Scenario(); - mockedScenario.setId(UUID.randomUUID().toString()); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - mockedImportMapper - .getInjectImporters() - .forEach( - injectImporter -> { - injectImporter.setRuleAttributes( - injectImporter.getRuleAttributes().stream() - .map( - ruleAttribute -> { - if ("trigger_time".equals(ruleAttribute.getName())) { - ruleAttribute.setAdditionalConfig(Map.of("timePattern", "HH'h'mm")); - } - return ruleAttribute; - }) - .toList()); - }); - when(userRepository.findById(any())).thenReturn(Optional.of(mockedUser)); - Team team1 = new Team(); - team1.setName("team1"); - Team team2 = new Team(); - team2.setName("team2"); - when(teamRepository.findAll()).thenReturn(List.of(team1)); - when(teamRepository.save(any())).thenReturn(team2); - - sessionHelper.when(SessionHelper::currentUser).thenReturn(new OpenBASOAuth2User(mockedUser)); - ImportTestSummary importTestSummary = - injectImportService.importInjectIntoScenarioFromXLS( - mockedScenario, mockedImportMapper, fileID, "CHECKLIST", 120, true); - - assertTrue( - importTestSummary.getImportMessage().stream() - .anyMatch( - importMessage -> - ImportMessage.MessageLevel.CRITICAL.equals(importMessage.getMessageLevel()) - && ImportMessage.ErrorCode.ABSOLUTE_TIME_WITHOUT_START_DATE.equals( - importMessage.getErrorCode()))); - } - } - - @DisplayName("Import an XLS file with relative dates, hours and minutes") - @Test - void testImportXlsRelativeDatesHoursAndMinutes() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - User mockedUser = new User(); - String fileID = UUID.randomUUID().toString(); - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_5.xlsx"); - createTempFile(testFile, fileID); - mockedInjectsImportInput = new InjectsImportInput(); - mockedInjectsImportInput.setImportMapperId(fileID); - mockedInjectsImportInput.setName("CHECKLIST"); - mockedInjectsImportInput.setTimezoneOffset(120); - - mockedScenario = new Scenario(); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - when(userRepository.findById(any())).thenReturn(Optional.of(mockedUser)); - Team team1 = new Team(); - team1.setName("team1"); - Team team2 = new Team(); - team2.setName("team2"); - when(teamRepository.findAll()).thenReturn(List.of(team1)); - when(teamRepository.save(any())).thenReturn(team2); - - sessionHelper.when(SessionHelper::currentUser).thenReturn(new OpenBASOAuth2User(mockedUser)); - ImportTestSummary importTestSummary = - injectImportService.importInjectIntoScenarioFromXLS( - mockedScenario, mockedImportMapper, fileID, "CHECKLIST", 120, false); - - List sortedInjects = - importTestSummary.getInjects().stream() - .sorted(Comparator.comparing(Inject::getDependsDuration)) - .toList(); - - assertEquals(24 * 60 * 60, sortedInjects.get(1).getDependsDuration()); - assertEquals(((((2 * 24) + 2) * 60) - 5) * 60, sortedInjects.get(2).getDependsDuration()); - assertEquals(4 * 24 * 60 * 60, sortedInjects.get(3).getDependsDuration()); - } - } - - @DisplayName("Import an XLS file with default values") - @Test - void testImportXlsDefaultValue() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - User mockedUser = new User(); - String fileID = UUID.randomUUID().toString(); - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_5.xlsx"); - createTempFile(testFile, fileID); - - mockedScenario = new Scenario(); - mockedScenario.setId(UUID.randomUUID().toString()); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - mockedImportMapper - .getInjectImporters() - .forEach( - injectImporter -> { - injectImporter.setRuleAttributes( - injectImporter.getRuleAttributes().stream() - .map( - ruleAttribute -> { - if ("title".equals(ruleAttribute.getName()) - || "trigger_time".equals(ruleAttribute.getName())) { - ruleAttribute.setColumns("A"); - } - return ruleAttribute; - }) - .toList()); - }); - when(userRepository.findById(any())).thenReturn(Optional.of(mockedUser)); - Team team1 = new Team(); - team1.setName("team1"); - Team team2 = new Team(); - team2.setName("team2"); - when(teamRepository.findAll()).thenReturn(List.of(team1)); - when(teamRepository.save(any())).thenReturn(team2); - - sessionHelper.when(SessionHelper::currentUser).thenReturn(new OpenBASOAuth2User(mockedUser)); - ImportTestSummary importTestSummary = - injectImportService.importInjectIntoScenarioFromXLS( - mockedScenario, mockedImportMapper, fileID, "CHECKLIST", 120, false); - - assertSame("title", importTestSummary.getInjects().getFirst().getTitle()); - } - } - - @DisplayName("Import an XLS file in an exercise") - @Test - void testImportXlsWithExercise() throws IOException { - try (MockedStatic sessionHelper = Mockito.mockStatic(SessionHelper.class)) { - User mockedUser = new User(); - String fileID = UUID.randomUUID().toString(); - File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_2.xlsx"); - createTempFile(testFile, fileID); - - mockedExercise = new Exercise(); - mockedExercise.setId(UUID.randomUUID().toString()); - - mockedImportMapper = createImportMapper(UUID.randomUUID().toString()); - mockedImportMapper - .getInjectImporters() - .forEach( - injectImporter -> { - injectImporter.setRuleAttributes( - injectImporter.getRuleAttributes().stream() - .map( - ruleAttribute -> { - if ("trigger_time".equals(ruleAttribute.getName())) { - ruleAttribute.setAdditionalConfig( - Map.of("timePattern", "dd/MM/yyyy HH'h'mm")); - } - return ruleAttribute; - }) - .toList()); - }); - when(userRepository.findById(any())).thenReturn(Optional.of(mockedUser)); - Team team1 = new Team(); - team1.setName("team1"); - team1.setUsers(List.of(new User())); - Team team2 = new Team(); - team2.setName("team2"); - team1.setUsers(List.of(new User())); - when(teamRepository.findAll()).thenReturn(List.of(team1)); - when(teamRepository.save(any())).thenReturn(team2); - - when(injectRepository.saveAll(any())) - .thenReturn(List.of(createNewInject(List.of(team1)), new Inject())); - - sessionHelper.when(SessionHelper::currentUser).thenReturn(new OpenBASOAuth2User(mockedUser)); - ImportTestSummary importTestSummary = - injectImportService.importInjectIntoExerciseFromXLS( - mockedExercise, mockedImportMapper, fileID, "CHECKLIST", 120, true); - - assertTrue( - LocalDateTime.of(2024, Month.JUNE, 26, 0, 0) - .toInstant(ZoneOffset.of("Z")) - .equals(mockedExercise.getStart().get())); - } - } - - private void createTempFile(File testFile, String fileID) throws IOException { - InputStream in = new FileInputStream(testFile); - MockMultipartFile file = - new MockMultipartFile("file", "my-awesome-file.xls", "application/xlsx", in.readAllBytes()); - - // Writing the file in a temp dir - Path tempDir = Files.createDirectory(Path.of(System.getProperty("java.io.tmpdir"), fileID)); - Path tempFile = - Files.createTempFile( - tempDir, null, "." + FilenameUtils.getExtension(file.getOriginalFilename())); - Files.write(tempFile, file.getBytes()); - - // We're making sure the files are deleted when the test stops - tempDir.toFile().deleteOnExit(); - tempFile.toFile().deleteOnExit(); - } - - private ImportMapper createImportMapper(String id) throws JsonProcessingException { - ImportMapper importMapper = new ImportMapper(); - importMapper.setName("test import mapper"); - importMapper.setId(id); - importMapper.setInjectTypeColumn("B"); - importMapper.setInjectImporters(new ArrayList<>()); - - InjectImporter injectImporterSms = new InjectImporter(); - injectImporterSms.setId(UUID.randomUUID().toString()); - injectImporterSms.setImportTypeValue(".*(sms|SMS).*"); - injectImporterSms.setRuleAttributes(new ArrayList<>()); - injectImporterSms.setInjectorContract(createSmsInjectorContract()); - - injectImporterSms.getRuleAttributes().addAll(createRuleAttributeSms()); - - InjectImporter injectImporterMail = new InjectImporter(); - injectImporterMail.setId(UUID.randomUUID().toString()); - injectImporterMail.setImportTypeValue(".*mail.*"); - injectImporterMail.setRuleAttributes(new ArrayList<>()); - injectImporterMail.setInjectorContract(createMailInjectorContract()); - - injectImporterMail.getRuleAttributes().addAll(createRuleAttributeMail()); - - importMapper.getInjectImporters().add(injectImporterSms); - importMapper.getInjectImporters().add(injectImporterMail); - - return importMapper; - } - - private InjectorContract createSmsInjectorContract() throws JsonProcessingException { - InjectorContract injectorContract = new InjectorContract(); - ObjectNode jsonNode = - (ObjectNode) - mapper.readTree( - "{\"config\":{\"type\":\"openbas_ovh_sms\",\"expose\":true,\"label\":{\"en\":\"SMS (OVH)\"},\"color_dark\":\"#9c27b0\",\"color_light\":\"#9c27b0\"},\"label\":{\"en\":\"Send a SMS\",\"fr\":\"Envoyer un SMS\"},\"manual\":false,\"fields\":[{\"key\":\"teams\",\"label\":\"Teams\",\"mandatory\":true,\"readOnly\":false,\"mandatoryGroups\":null,\"linkedFields\":[],\"linkedValues\":[],\"cardinality\":\"n\",\"defaultValue\":[],\"type\":\"team\"},{\"key\":\"message\",\"label\":\"Message\",\"mandatory\":true,\"readOnly\":false,\"mandatoryGroups\":null,\"linkedFields\":[],\"linkedValues\":[],\"defaultValue\":\"\",\"richText\":false,\"type\":\"textarea\"},{\"key\":\"expectations\",\"label\":\"Expectations\",\"mandatory\":false,\"readOnly\":false,\"mandatoryGroups\":null,\"linkedFields\":[],\"linkedValues\":[],\"cardinality\":\"n\",\"defaultValue\":[],\"predefinedExpectations\":[],\"type\":\"expectation\"}],\"variables\":[{\"key\":\"user\",\"label\":\"User that will receive the injection\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[{\"key\":\"user.id\",\"label\":\"Id of the user in the platform\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"user.email\",\"label\":\"Email of the user\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"user.firstname\",\"label\":\"Firstname of the user\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"user.lastname\",\"label\":\"Lastname of the user\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"user.lang\",\"label\":\"Lang of the user\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]}]},{\"key\":\"exercise\",\"label\":\"Exercise of the current injection\",\"type\":\"Object\",\"cardinality\":\"1\",\"children\":[{\"key\":\"exercise.id\",\"label\":\"Id of the user in the platform\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"exercise.name\",\"label\":\"Name of the exercise\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"exercise.description\",\"label\":\"Description of the exercise\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]}]},{\"key\":\"teams\",\"label\":\"List of team name for the injection\",\"type\":\"String\",\"cardinality\":\"n\",\"children\":[]},{\"key\":\"player_uri\",\"label\":\"Player interface platform link\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"challenges_uri\",\"label\":\"Challenges interface platform link\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"scoreboard_uri\",\"label\":\"Scoreboard interface platform link\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"lessons_uri\",\"label\":\"Lessons learned interface platform link\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]}],\"context\":{},\"contract_id\":\"e9e902bc-b03d-4223-89e1-fca093ac79dd\",\"contract_attack_patterns_external_ids\":[],\"is_atomic_testing\":true,\"needs_executor\":false,\"platforms\":[\"Service\"]}"); - injectorContract.setConvertedContent(jsonNode); - - return injectorContract; - } - - private InjectorContract createMailInjectorContract() throws JsonProcessingException { - InjectorContract injectorContract = new InjectorContract(); - ObjectNode jsonNode = - (ObjectNode) - mapper.readTree( - "{\"config\":{\"type\":\"openbas_email\",\"expose\":true,\"label\":{\"en\":\"Email\",\"fr\":\"Email\"},\"color_dark\":\"#cddc39\",\"color_light\":\"#cddc39\"},\"label\":{\"en\":\"Send individual mails\",\"fr\":\"Envoyer des mails individuels\"},\"manual\":false,\"fields\":[{\"key\":\"teams\",\"label\":\"Teams\",\"mandatory\":true,\"readOnly\":false,\"mandatoryGroups\":null,\"linkedFields\":[],\"linkedValues\":[],\"cardinality\":\"n\",\"defaultValue\":[],\"type\":\"team\"},{\"key\":\"subject\",\"label\":\"Subject\",\"mandatory\":true,\"readOnly\":false,\"mandatoryGroups\":null,\"linkedFields\":[],\"linkedValues\":[],\"defaultValue\":\"\",\"type\":\"text\"},{\"key\":\"body\",\"label\":\"Body\",\"mandatory\":true,\"readOnly\":false,\"mandatoryGroups\":null,\"linkedFields\":[],\"linkedValues\":[],\"defaultValue\":\"\",\"richText\":true,\"type\":\"textarea\"},{\"key\":\"encrypted\",\"label\":\"Encrypted\",\"mandatory\":false,\"readOnly\":false,\"mandatoryGroups\":null,\"linkedFields\":[],\"linkedValues\":[],\"defaultValue\":false,\"type\":\"checkbox\"},{\"key\":\"attachments\",\"label\":\"Attachments\",\"mandatory\":false,\"readOnly\":false,\"mandatoryGroups\":null,\"linkedFields\":[],\"linkedValues\":[],\"cardinality\":\"n\",\"defaultValue\":[],\"type\":\"attachment\"},{\"key\":\"expectations\",\"label\":\"Expectations\",\"mandatory\":false,\"readOnly\":false,\"mandatoryGroups\":null,\"linkedFields\":[],\"linkedValues\":[],\"cardinality\":\"n\",\"defaultValue\":[],\"predefinedExpectations\":[],\"type\":\"expectation\"}],\"variables\":[{\"key\":\"document_uri\",\"label\":\"Http user link to upload the document (only for document expectation)\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"user\",\"label\":\"User that will receive the injection\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[{\"key\":\"user.id\",\"label\":\"Id of the user in the platform\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"user.email\",\"label\":\"Email of the user\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"user.firstname\",\"label\":\"Firstname of the user\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"user.lastname\",\"label\":\"Lastname of the user\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"user.lang\",\"label\":\"Lang of the user\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]}]},{\"key\":\"exercise\",\"label\":\"Exercise of the current injection\",\"type\":\"Object\",\"cardinality\":\"1\",\"children\":[{\"key\":\"exercise.id\",\"label\":\"Id of the user in the platform\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"exercise.name\",\"label\":\"Name of the exercise\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"exercise.description\",\"label\":\"Description of the exercise\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]}]},{\"key\":\"teams\",\"label\":\"List of team name for the injection\",\"type\":\"String\",\"cardinality\":\"n\",\"children\":[]},{\"key\":\"player_uri\",\"label\":\"Player interface platform link\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"challenges_uri\",\"label\":\"Challenges interface platform link\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"scoreboard_uri\",\"label\":\"Scoreboard interface platform link\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]},{\"key\":\"lessons_uri\",\"label\":\"Lessons learned interface platform link\",\"type\":\"String\",\"cardinality\":\"1\",\"children\":[]}],\"context\":{},\"contract_id\":\"138ad8f8-32f8-4a22-8114-aaa12322bd09\",\"contract_attack_patterns_external_ids\":[],\"is_atomic_testing\":true,\"needs_executor\":false,\"platforms\":[\"Service\"]}"); - injectorContract.setConvertedContent(jsonNode); - - return injectorContract; - } - - private List createRuleAttributeSms() { - List results = new ArrayList<>(); - RuleAttribute ruleAttributeTitle = new RuleAttribute(); - ruleAttributeTitle.setName("title"); - ruleAttributeTitle.setColumns("B"); - ruleAttributeTitle.setDefaultValue("title"); - - RuleAttribute ruleAttributeDescription = new RuleAttribute(); - ruleAttributeDescription.setName("description"); - ruleAttributeDescription.setColumns("G"); - ruleAttributeDescription.setDefaultValue("description"); - - RuleAttribute ruleAttributeTriggerTime = new RuleAttribute(); - ruleAttributeTriggerTime.setName("trigger_time"); - ruleAttributeTriggerTime.setColumns("C"); - ruleAttributeTriggerTime.setDefaultValue("trigger_time"); - ruleAttributeTriggerTime.setAdditionalConfig(Map.of("timePattern", "")); - - RuleAttribute ruleAttributeMessage = new RuleAttribute(); - ruleAttributeMessage.setName("message"); - ruleAttributeMessage.setColumns("F"); - ruleAttributeMessage.setDefaultValue("message"); - - RuleAttribute ruleAttributeTeams = new RuleAttribute(); - ruleAttributeTeams.setName("teams"); - ruleAttributeTeams.setColumns("D"); - ruleAttributeTeams.setDefaultValue("teams"); - - RuleAttribute ruleAttributeExpectationScore = new RuleAttribute(); - ruleAttributeExpectationScore.setName("expectation_score"); - ruleAttributeExpectationScore.setColumns("J"); - ruleAttributeExpectationScore.setDefaultValue("500.0"); - - RuleAttribute ruleAttributeExpectationName = new RuleAttribute(); - ruleAttributeExpectationName.setName("expectation_name"); - ruleAttributeExpectationName.setColumns("I"); - ruleAttributeExpectationName.setDefaultValue("name"); - - RuleAttribute ruleAttributeExpectationDescription = new RuleAttribute(); - ruleAttributeExpectationDescription.setName("expectation_description"); - ruleAttributeExpectationDescription.setColumns("H"); - ruleAttributeExpectationDescription.setDefaultValue("description"); - - results.add(ruleAttributeTitle); - results.add(ruleAttributeDescription); - results.add(ruleAttributeTriggerTime); - results.add(ruleAttributeMessage); - results.add(ruleAttributeTeams); - results.add(ruleAttributeExpectationScore); - results.add(ruleAttributeExpectationName); - results.add(ruleAttributeExpectationDescription); - - return results; - } - - private List createRuleAttributeMail() { - List results = new ArrayList<>(); - RuleAttribute ruleAttributeTitle = new RuleAttribute(); - ruleAttributeTitle.setName("title"); - ruleAttributeTitle.setColumns("B"); - ruleAttributeTitle.setDefaultValue("title"); - - RuleAttribute ruleAttributeDescription = new RuleAttribute(); - ruleAttributeDescription.setName("description"); - ruleAttributeDescription.setColumns("G"); - ruleAttributeDescription.setDefaultValue("description"); - - RuleAttribute ruleAttributeTriggerTime = new RuleAttribute(); - ruleAttributeTriggerTime.setName("trigger_time"); - ruleAttributeTriggerTime.setColumns("C"); - ruleAttributeTriggerTime.setDefaultValue("trigger_time"); - ruleAttributeTriggerTime.setAdditionalConfig(Map.of("timePattern", "")); - - RuleAttribute ruleAttributeMessage = new RuleAttribute(); - ruleAttributeMessage.setName("subject"); - ruleAttributeMessage.setColumns("E"); - ruleAttributeMessage.setDefaultValue("subject"); - - RuleAttribute ruleAttributeSubject = new RuleAttribute(); - ruleAttributeSubject.setName("body"); - ruleAttributeSubject.setColumns("F"); - ruleAttributeSubject.setDefaultValue("body"); - - RuleAttribute ruleAttributeTeams = new RuleAttribute(); - ruleAttributeTeams.setName("teams"); - ruleAttributeTeams.setColumns("D"); - ruleAttributeTeams.setDefaultValue("teams"); - - RuleAttribute ruleAttributeExpectationScore = new RuleAttribute(); - ruleAttributeExpectationScore.setName("expectation_score"); - ruleAttributeExpectationScore.setColumns("J"); - ruleAttributeExpectationScore.setDefaultValue("500.0"); - - RuleAttribute ruleAttributeExpectationName = new RuleAttribute(); - ruleAttributeExpectationName.setName("expectation_name"); - ruleAttributeExpectationName.setColumns("I"); - ruleAttributeExpectationName.setDefaultValue("name"); - - RuleAttribute ruleAttributeExpectationDescription = new RuleAttribute(); - ruleAttributeExpectationDescription.setName("expectation_description"); - ruleAttributeExpectationDescription.setColumns("H"); - ruleAttributeExpectationDescription.setDefaultValue("description"); - - results.add(ruleAttributeTitle); - results.add(ruleAttributeDescription); - results.add(ruleAttributeTriggerTime); - results.add(ruleAttributeMessage); - results.add(ruleAttributeSubject); - results.add(ruleAttributeTeams); - results.add(ruleAttributeExpectationScore); - results.add(ruleAttributeExpectationName); - results.add(ruleAttributeExpectationDescription); - - return results; - } - - private Object deepCopy(Object objectToCopy, Class classToCopy) throws JsonProcessingException { - ObjectMapper objectMapper = new ObjectMapper(); - - return objectMapper.readValue(objectMapper.writeValueAsString(objectToCopy), classToCopy); - } - - private Inject createNewInject(List teams) { - Inject inject = new Inject(); - inject.setTeams(teams); - inject.setId(UUID.randomUUID().toString()); - return inject; - } -} 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 ffde237c0e..70e71b64c3 100644 --- a/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java @@ -7,12 +7,18 @@ import static io.openbas.utils.fixtures.UserFixture.getUser; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import io.openbas.database.model.*; +import io.openbas.database.model.Tag; import io.openbas.database.repository.*; import io.openbas.rest.inject.service.InjectDuplicateService; +import io.openbas.rest.inject.service.InjectService; import io.openbas.utils.ExerciseMapper; +import io.openbas.utils.fixtures.AssetFixture; import io.openbas.utils.fixtures.ScenarioFixture; +import io.openbas.utils.fixtures.TagFixture; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -37,6 +43,7 @@ class ScenarioServiceTest { @Autowired InjectRepository injectRepository; + @Mock ScenarioRepository mockScenarioRepository; @Mock GrantService grantService; @Mock VariableService variableService; @Mock ChallengeService challengeService; @@ -46,7 +53,8 @@ class ScenarioServiceTest { @Autowired private ExerciseMapper exerciseMapper; @Autowired private InjectorContractRepository injectorContractRepository; @Autowired private LessonsCategoryRepository lessonsCategoryRepository; - + @Mock private InjectService injectService; + @Mock private TagRuleService tagRuleService; @InjectMocks private ScenarioService scenarioService; private static String USER_ID; @@ -70,6 +78,30 @@ void setUp() { teamService, fileService, injectDuplicateService, + tagRuleService, + injectService, + injectRepository, + lessonsCategoryRepository); + } + + void setUpWithMockRepository() { + scenarioService = + new ScenarioService( + mockScenarioRepository, + teamRepository, + userRepository, + documentRepository, + scenarioTeamUserRepository, + articleRepository, + exerciseMapper, + grantService, + variableService, + challengeService, + teamService, + fileService, + injectDuplicateService, + tagRuleService, + injectService, injectRepository, lessonsCategoryRepository); } @@ -171,4 +203,34 @@ void testRemoveTeams() { Inject injectAssert = this.injectRepository.findById(INJECT_ID).orElseThrow(); assertEquals(0, injectAssert.getTeams().size()); } + + @Test + public void testUpdateScenarioAndApplyRule_WITH_AddedAndRemovedTags() { + setUpWithMockRepository(); + Asset asset1 = AssetFixture.createDefaultAsset("asset1"); + Asset asset2 = AssetFixture.createDefaultAsset("asset2"); + Asset asset3 = AssetFixture.createDefaultAsset("asset3"); + Tag tag1 = TagFixture.getTag("Tag1"); + Tag tag2 = TagFixture.getTag("Tag2"); + Tag tag3 = TagFixture.getTag("Tag3"); + Scenario scenario = ScenarioFixture.getScenarioWithInjects(); + scenario.setTags(Set.of(tag1, tag2)); + Set currentTags = Set.of(tag2, tag3); + List assetsToAdd = List.of(asset1, asset2); + List assetsToRemove = List.of(asset3); + + when(tagRuleService.getAssetsFromTagIds(List.of(tag1.getId()))).thenReturn(assetsToAdd); + when(tagRuleService.getAssetsFromTagIds(List.of(tag3.getId()))).thenReturn(assetsToRemove); + when(mockScenarioRepository.save(scenario)).thenReturn(scenario); + + scenarioService.updateScenarioAndApplyRule(scenario, currentTags); + + scenario + .getInjects() + .forEach( + inject -> + verify(injectService) + .applyDefaultAssetsToInject(inject.getId(), assetsToAdd, assetsToRemove)); + verify(mockScenarioRepository).save(scenario); + } } diff --git a/openbas-api/src/test/java/io/openbas/service/TagRuleServiceTest.java b/openbas-api/src/test/java/io/openbas/service/TagRuleServiceTest.java index 661deac76a..7ea1d98fe8 100644 --- a/openbas-api/src/test/java/io/openbas/service/TagRuleServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/service/TagRuleServiceTest.java @@ -13,6 +13,7 @@ import io.openbas.database.repository.TagRepository; import io.openbas.database.repository.TagRuleRepository; import io.openbas.rest.exception.ElementNotFoundException; +import io.openbas.utils.fixtures.AssetFixture; import io.openbas.utils.fixtures.TagFixture; import io.openbas.utils.fixtures.TagRuleFixture; import java.util.HashSet; @@ -194,4 +195,38 @@ void testUpdateTagRule_WITH_non_existing_tag_rule() { expected.getAssets().stream().map(Asset::getId).toList()); }); } + + @Test + void testGetAssetsFromTagIds() { + List tagIds = List.of("tag1"); + TagRule tagRule = TagRuleFixture.createTagRule(TAG_RULE_ID); + when(tagRuleRepository.findByTags(tagIds)).thenReturn(List.of(tagRule)); + assertEquals( + new HashSet<>(tagRule.getAssets()), + new HashSet<>(tagRuleService.getAssetsFromTagIds(tagIds))); + } + + @Test + void testApplyTagRuleToInjectCreation() throws Exception { + Asset asset1 = AssetFixture.createDefaultAsset("asset1"); + Asset asset2 = AssetFixture.createDefaultAsset("asset2"); + Asset asset3 = AssetFixture.createDefaultAsset("asset3"); + Asset asset4 = AssetFixture.createDefaultAsset("asset4"); + + Tag tag1 = TagFixture.getTag("tag2"); + Tag tag2 = TagFixture.getTag("tag3"); + + List currentAssets = List.of(asset1, asset2); + List defaultAssets = List.of(asset2, asset3, asset4); + TagRule tagRule = TagRuleFixture.createTagRule("tag_rule1", defaultAssets); + + when(tagRuleRepository.findByTags(List.of(tag1.getId(), tag2.getId()))) + .thenReturn(List.of(tagRule)); + + List result = + tagRuleService.applyTagRuleToInjectCreation( + List.of(tag1.getId(), tag2.getId()), currentAssets); + List expected = List.of(asset1, asset2, asset3, asset4); + assertEquals(new HashSet<>(expected), new HashSet<>(result)); + } } diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/AssetFixture.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/AssetFixture.java new file mode 100644 index 0000000000..f7c10c2824 --- /dev/null +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/AssetFixture.java @@ -0,0 +1,12 @@ +package io.openbas.utils.fixtures; + +import io.openbas.database.model.Asset; +import org.jetbrains.annotations.NotNull; + +public class AssetFixture { + public static Asset createDefaultAsset(@NotNull final String id) { + Asset assetGroup = new Asset(); + assetGroup.setId(id); + return assetGroup; + } +} 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 index 265bd545a5..fe2691a5fc 100644 --- a/openbas-api/src/test/java/io/openbas/utils/fixtures/ExerciseFixture.java +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/ExerciseFixture.java @@ -4,6 +4,7 @@ import io.openbas.database.model.Exercise; import io.openbas.database.model.ExerciseStatus; +import io.openbas.database.model.Inject; import io.openbas.database.model.Team; import java.time.Instant; import java.util.List; @@ -25,6 +26,16 @@ public static Exercise getExercise(List exerciseTeams) { return exercise; } + public static Exercise getExerciseWithInjects() { + Exercise exercise = getExercise(null); + Inject inject1 = new Inject(); + inject1.setId("1"); + Inject inject2 = new Inject(); + inject1.setId("2"); + exercise.setInjects(List.of(inject1, inject2)); + return exercise; + } + public static Exercise createDefaultCrisisExercise() { Exercise exercise = new Exercise(); exercise.setName("Crisis exercise"); 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 af95b6d80f..e7fb74565e 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 @@ -49,4 +49,12 @@ public static Scenario createDefaultIncidentResponseScenario() { scenario.setSeverity(critical); return scenario; } + + public static Scenario getScenarioWithInjects() { + Inject inject1 = new Inject(); + inject1.setId("1"); + Inject inject2 = new Inject(); + inject1.setId("2"); + return getScenario(null, Set.of(inject1, inject2)); + } } diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/TagFixture.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/TagFixture.java index 7f70146c18..d362a15fe1 100644 --- a/openbas-api/src/test/java/io/openbas/utils/fixtures/TagFixture.java +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/TagFixture.java @@ -13,4 +13,12 @@ public static Tag getTag() { tag.setColor("#FFFFFF"); return tag; } + + public static Tag getTag(final String id) { + Tag tag = new Tag(); + tag.setId(id); + tag.setName(TAG_NAME); + tag.setColor("#FFFFFF"); + return tag; + } } diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/TagRuleFixture.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/TagRuleFixture.java index e68f6205e2..d22ccdde9c 100644 --- a/openbas-api/src/test/java/io/openbas/utils/fixtures/TagRuleFixture.java +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/TagRuleFixture.java @@ -37,6 +37,18 @@ public static TagRule createTagRule(String tagRuleId) { return rule; } + public static TagRule createTagRule(String tagRuleId, List assets) { + Tag tag = new Tag(); + tag.setName(TAG_NAME); + + TagRule rule = new TagRule(); + rule.setAssets(assets); + rule.setTag(tag); + rule.setId(tagRuleId); + + return rule; + } + public static TagRuleOutput createTagRuleOutput() { return TagRuleOutput.builder() .tagName(TAG_NAME) diff --git a/openbas-model/src/main/java/io/openbas/database/repository/TagRuleRepository.java b/openbas-model/src/main/java/io/openbas/database/repository/TagRuleRepository.java index 79bb86edaa..9189982347 100644 --- a/openbas-model/src/main/java/io/openbas/database/repository/TagRuleRepository.java +++ b/openbas-model/src/main/java/io/openbas/database/repository/TagRuleRepository.java @@ -5,6 +5,10 @@ import org.jetbrains.annotations.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; + +import java.util.List; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository @@ -13,4 +17,7 @@ public interface TagRuleRepository @NotNull Optional findById(@NotNull String id); + + @Query("select tr from TagRule tr where tr.tag.id IN :tagids") + List findByTags(@Param("tagids") List tagIds); } From 7ca53f75e4233dc570ab1b157b00357c652b1b33 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 14:40:48 +0100 Subject: [PATCH 02/16] updated scenario logic --- .../rest/inject/service/InjectService.java | 49 +++++- .../io/openbas/rest/scenario/ScenarioApi.java | 14 +- .../io/openbas/service/ScenarioService.java | 56 +++--- .../rest/scenario/ScenarioApiTest.java | 164 +++++++----------- .../openbas/service/ScenarioServiceTest.java | 35 +++- 5 files changed, 166 insertions(+), 152 deletions(-) diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java index d865049f43..f5707f99d8 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java @@ -4,10 +4,7 @@ import static java.time.Instant.now; import com.fasterxml.jackson.databind.ObjectMapper; -import io.openbas.database.model.ExecutionStatus; -import io.openbas.database.model.Inject; -import io.openbas.database.model.InjectDocument; -import io.openbas.database.model.InjectStatus; +import io.openbas.database.model.*; import io.openbas.database.repository.InjectDocumentRepository; import io.openbas.database.repository.InjectRepository; import io.openbas.database.repository.InjectStatusRepository; @@ -20,7 +17,10 @@ import jakarta.transaction.Transactional; import jakarta.validation.constraints.NotBlank; import java.time.Instant; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; import java.util.stream.Stream; import lombok.RequiredArgsConstructor; import lombok.extern.java.Log; @@ -133,6 +133,47 @@ public void delete(String id) { injectRepository.deleteById(id); } + /** + * Update an inject with default assets + * + * @param injectId + * @param defaultAssetsToAdd + * @param defaultAssetsToRemove + * @return + */ + @Transactional + public Inject applyDefaultAssetsToInject( + final String injectId, + final List defaultAssetsToAdd, + final List defaultAssetsToRemove) { + + // fetch the inject + Inject inject = + this.injectRepository.findById(injectId).orElseThrow(ElementNotFoundException::new); + + // remove/add default assets and remove duplicates + List currentAssets = inject.getAssets(); + // Get the Id of the assets to remove and filter the assets that are in both lists + List assetIdsToRemove = + defaultAssetsToRemove.stream() + .filter(asset -> !defaultAssetsToAdd.contains(asset)) + .map(Asset::getId) + .toList(); + Set uniqueAssetsIds = new HashSet<>(); + List newListOfAssets = + Stream.concat(currentAssets.stream(), defaultAssetsToAdd.stream()) + .filter(asset -> !assetIdsToRemove.contains(asset.getId())) + .filter(asset -> uniqueAssetsIds.add(asset.getId())) + .collect(Collectors.toList()); + + if (new HashSet<>(currentAssets).equals(new HashSet<>(newListOfAssets))) { + return inject; + } else { + inject.setAssets(newListOfAssets); + return this.injectRepository.save(inject); + } + } + private Inject findAndDuplicateInject(String id) { Inject injectOrigin = injectRepository.findById(id).orElseThrow(ElementNotFoundException::new); return InjectUtils.duplicateInject(injectOrigin); diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java index 2f28f26612..27db5fc030 100644 --- a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java @@ -105,12 +105,7 @@ public Scenario updateScenario( Scenario scenario = this.scenarioService.scenario(scenarioId); Set currentTagList = scenario.getTags(); scenario.setUpdateAttributes(input); - scenario.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds()))); - if (input.isApplyTagRule()) { - return this.scenarioService.updateScenarioAndApplyRule(scenario, currentTagList); - } else { - return this.scenarioService.updateScenario(scenario); - } + return this.scenarioService.updateScenario(scenario, currentTagList, input.isApplyTagRule()); } @PutMapping(SCENARIO_URI + "/{scenarioId}/information") @@ -139,12 +134,7 @@ public Scenario updateScenarioTags( Scenario scenario = this.scenarioService.scenario(scenarioId); Set currentTagList = scenario.getTags(); scenario.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds()))); - - if (input.isApplyTagRule()) { - return this.scenarioService.updateScenarioAndApplyRule(scenario, currentTagList); - } else { - return this.scenarioService.updateScenario(scenario); - } + return this.scenarioService.updateScenario(scenario, currentTagList, input.isApplyTagRule()); } // -- EXPORT -- 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 fd88d36520..b0be7c882d 100644 --- a/openbas-api/src/main/java/io/openbas/service/ScenarioService.java +++ b/openbas-api/src/main/java/io/openbas/service/ScenarioService.java @@ -294,8 +294,7 @@ public ExerciseSimple latestExerciseByExternalReference( } public Scenario updateScenario(@NotNull final Scenario scenario) { - scenario.setUpdatedAt(now()); - return this.scenarioRepository.save(scenario); + return this.updateScenario(scenario, null, false); } /** @@ -306,32 +305,33 @@ public Scenario updateScenario(@NotNull final Scenario scenario) { * @return */ @Transactional - public Scenario updateScenarioAndApplyRule( - @NotNull final Scenario scenario, @NotNull Set currentTags) { - // Get assets from the TagRule of the added tags - List defaultAssetsToAdd = - tagRuleService.getAssetsFromTagIds( - scenario.getTags().stream() - .filter(tag -> !currentTags.contains(tag)) - .map(Tag::getId) - .toList()); - - // Get assets from the TagRule of the removed tags - List defaultAssetsToRemove = - tagRuleService.getAssetsFromTagIds( - currentTags.stream() - .filter(tag -> !scenario.getTags().contains(tag)) - .map(Tag::getId) - .toList()); - - // Add/remove the default assets to/from the injects - scenario - .getInjects() - .forEach( - inject -> - injectService.applyDefaultAssetsToInject( - inject.getId(), defaultAssetsToAdd, defaultAssetsToRemove)); - + public Scenario updateScenario( + @NotNull final Scenario scenario, Set currentTags, boolean applyRule) { + if(applyRule) { + // Get assets from the TagRule of the added tags + List defaultAssetsToAdd = + tagRuleService.getAssetsFromTagIds( + scenario.getTags().stream() + .filter(tag -> !currentTags.contains(tag)) + .map(Tag::getId) + .toList()); + + // Get assets from the TagRule of the removed tags + List defaultAssetsToRemove = + tagRuleService.getAssetsFromTagIds( + currentTags.stream() + .filter(tag -> !scenario.getTags().contains(tag)) + .map(Tag::getId) + .toList()); + + // Add/remove the default assets to/from the injects + scenario + .getInjects() + .forEach( + inject -> + injectService.applyDefaultAssetsToInject( + inject.getId(), defaultAssetsToAdd, defaultAssetsToRemove)); + } scenario.setUpdatedAt(now()); return this.scenarioRepository.save(scenario); } diff --git a/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java b/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java index f0316036da..f6182fdbe5 100644 --- a/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java @@ -1,5 +1,6 @@ package io.openbas.rest.scenario; +import static io.openbas.injectors.email.EmailContract.EMAIL_DEFAULT; import static io.openbas.rest.scenario.ScenarioApi.SCENARIO_URI; import static io.openbas.utils.JsonUtils.asJsonString; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -11,19 +12,24 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.jayway.jsonpath.JsonPath; +import io.openbas.database.model.Asset; +import io.openbas.database.model.Inject; import io.openbas.database.model.Scenario; import io.openbas.database.model.Tag; -import io.openbas.database.repository.ScenarioRepository; -import io.openbas.database.repository.TagRepository; +import io.openbas.database.repository.*; import io.openbas.rest.scenario.form.ScenarioInformationInput; import io.openbas.rest.scenario.form.ScenarioInput; import io.openbas.rest.scenario.form.ScenarioUpdateTagsInput; import io.openbas.rest.scenario.form.UpdateScenarioInput; import io.openbas.service.ScenarioService; +import io.openbas.utils.fixtures.InjectFixture; +import io.openbas.utils.fixtures.InjectorContractFixture; import io.openbas.utils.fixtures.ScenarioFixture; import io.openbas.utils.fixtures.TagFixture; import io.openbas.utils.mockUser.WithMockObserverUser; import io.openbas.utils.mockUser.WithMockPlannerUser; + +import java.util.HashSet; import java.util.List; import java.util.Set; import org.junit.jupiter.api.*; @@ -39,16 +45,22 @@ @AutoConfigureMockMvc @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class ScenarioApiTest { + public static final String EMAIL_DEFAULT = "138ad8f8-32f8-4a22-8114-aaa12322bd09"; @Autowired private MockMvc mvc; @Autowired private ScenarioRepository scenarioRepository; + @Autowired private TagRepository tagRepository; + @Autowired private AssetRepository assetRepository; + @Autowired private InjectorContractRepository injectorContractRepository; @Mock TagRepository tagRepositoryMock; @Mock ScenarioService scenarioServiceMock; @InjectMocks private ScenarioApi scenarioApi; static String SCENARIO_ID; + @Autowired + private InjectRepository injectRepository; void cleanup() { this.scenarioRepository.deleteById(SCENARIO_ID); @@ -216,119 +228,63 @@ void deleteScenarioTest() throws Exception { cleanup(); } + @DisplayName("Update with apply rule") @Test - public void testUpdateScenario_WITH_apply_rule_true() { - io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); - io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); - io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); - - Scenario scenario = ScenarioFixture.getScenarioWithInjects(); - scenario.setTags(Set.of(tag2, tag3, tag1)); - scenario.setId("test"); - UpdateScenarioInput input = new UpdateScenarioInput(); - input.setDescription("test"); - input.setApplyTagRule(true); - input.setTagIds(List.of(tag1.getId(), tag2.getId())); - - Scenario expected = ScenarioFixture.getScenarioWithInjects(); - scenario.setId("test"); - expected.setDescription("test"); - expected.setTags(Set.of(tag1, tag2)); - - doReturn(List.of(tag1, tag2)) - .when(tagRepositoryMock) - .findAllById(List.of(tag1.getId(), tag2.getId())); - doReturn(scenario).when(scenarioServiceMock).scenario(scenario.getId()); - - scenarioApi.updateScenario(scenario.getId(), input); - - verify(scenarioServiceMock).updateScenarioAndApplyRule(expected, Set.of(tag2, tag3, tag1)); - } + public void testUpdateScenario_WITH_apply_rule_true() throws Exception { + String tag1 = "tag1"; + String tag2 = "tag2"; + Tag tag3 = createTag("tag3"); + Scenario scenario = createScenario("testScenario", List.of(tag1, tag2)); - @DisplayName("Update without apply rule") - @Test - public void testUpdateScenario_WITH_apply_rule_false() throws Exception { - io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); - io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); - io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); - - Scenario scenario = ScenarioFixture.getScenarioWithInjects(); - scenario.setTags(Set.of(tag2, tag3, tag1)); - scenario.setId("test"); - UpdateScenarioInput input = new UpdateScenarioInput(); - input.setDescription("test"); - input.setApplyTagRule(true); - input.setTagIds(List.of(tag1.getId(), tag2.getId())); - - Scenario expected = ScenarioFixture.getScenarioWithInjects(); - expected.setId("test"); - expected.setDescription("test"); - expected.setTags(Set.of(tag1, tag2)); - - doReturn(List.of(tag1, tag2)) - .when(tagRepositoryMock) - .findAllById(List.of(tag1.getId(), tag2.getId())); - doReturn(scenario).when(scenarioServiceMock).scenario(scenario.getId()); - - scenarioApi.updateScenario(scenario.getId(), input); - - verify(scenarioServiceMock).updateScenario(expected); - } + UpdateScenarioInput updateScenarioInput = new UpdateScenarioInput(); + updateScenarioInput.setApplyTagRule(false); + updateScenarioInput.setTagIds(List.of(tag3.getId())); - @DisplayName("Update tags without apply rule") - @Test - public void testUpdateScenarioTags_WITH_apply_rule_false() { - io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); - io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); - io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); - Scenario scenario = ScenarioFixture.getScenarioWithInjects(); - scenario.setTags(Set.of(tag2, tag3, tag1)); - scenario.setId("test"); + this.mvc + .perform( + put(SCENARIO_URI + "/" + scenario.getId()) + .content(asJsonString(updateScenarioInput)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); + - ScenarioUpdateTagsInput input = new ScenarioUpdateTagsInput(); - input.setTagIds(List.of(tag1.getId(), tag2.getId())); + Scenario updatedScenario = scenarioRepository.findById(scenario.getId()).orElseThrow(); + assertEquals(updatedScenario.getTags().size(), 1); + assertEquals(new HashSet<>(updatedScenario.getInjects().getFirst().getAssets()), + new HashSet<>(scenario.getInjects().getFirst().getAssets())); + } - Scenario expected = ScenarioFixture.getScenarioWithInjects(); - expected.setId("test"); - expected.setTags(Set.of(tag1, tag2)); - doReturn(List.of(tag1, tag2)) - .when(tagRepositoryMock) - .findAllById(List.of(tag1.getId(), tag2.getId())); - doReturn(scenario).when(scenarioServiceMock).scenario(scenario.getId()); + private Scenario createScenario(String scenarioName, List tagNames) { + Scenario scenario = new Scenario(); + tagNames.forEach(tagName -> scenario.getTags().add(createTag(tagName))); + scenarioRepository.save(scenario); + createInject(scenario.getId()); + return scenarioRepository.findById(scenario.getId()).orElseThrow(); + } - scenarioApi.updateScenarioTags(scenario.getId(), input); + private Inject createInject(String scenarioId) { + Inject inject = InjectFixture.getInjectForEmailContract(injectorContractRepository.findById(EMAIL_DEFAULT).orElseThrow()); + inject.setScenario(scenarioRepository.findById(scenarioId).orElseThrow()); + return injectRepository.save(inject); + } - verify(scenarioServiceMock).updateScenario(expected); + private Tag createTag(String tagName) { + Tag tag = new Tag(); + tag.setName(tagName + System.currentTimeMillis()); + tag.setColor("#0000"); + return tagRepository.save(tag); } - @DisplayName("Update tags with apply rule") - @Test - public void testUpdateScenarioTags_WITH_apply_rule_true() { - io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); - io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); - Tag tag3 = TagFixture.getTag("Tag3"); - - Scenario scenario = ScenarioFixture.getScenarioWithInjects(); - scenario.setTags(Set.of(tag2, tag3, tag1)); - scenario.setId("test"); - ScenarioUpdateTagsInput input = new ScenarioUpdateTagsInput(); - input.setTagIds(List.of(tag1.getId(), tag2.getId())); - input.setApplyTagRule(true); - - Scenario expected = ScenarioFixture.getScenarioWithInjects(); - expected.setId("test"); - expected.setTags(Set.of(tag1, tag2)); - - doReturn(List.of(tag1, tag2)) - .when(tagRepositoryMock) - .findAllById(List.of(tag1.getId(), tag2.getId())); - doReturn(scenario).when(scenarioServiceMock).scenario(scenario.getId()); - - scenarioApi.updateScenarioTags(scenario.getId(), input); - - verify(scenarioServiceMock).updateScenarioAndApplyRule(expected, Set.of(tag2, tag3, tag1)); + private Asset createAsset(String assetName) { + Asset asset = new Asset(); + asset.setName(assetName); + return assetRepository.save(asset); } } 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 70e71b64c3..d3181496d8 100644 --- a/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java @@ -7,8 +7,7 @@ import static io.openbas.utils.fixtures.UserFixture.getUser; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; import io.openbas.database.model.*; import io.openbas.database.model.Tag; @@ -205,7 +204,7 @@ void testRemoveTeams() { } @Test - public void testUpdateScenarioAndApplyRule_WITH_AddedAndRemovedTags() { + public void testUpdateScenario_WITH_applyRule_true() { setUpWithMockRepository(); Asset asset1 = AssetFixture.createDefaultAsset("asset1"); Asset asset2 = AssetFixture.createDefaultAsset("asset2"); @@ -223,7 +222,7 @@ public void testUpdateScenarioAndApplyRule_WITH_AddedAndRemovedTags() { when(tagRuleService.getAssetsFromTagIds(List.of(tag3.getId()))).thenReturn(assetsToRemove); when(mockScenarioRepository.save(scenario)).thenReturn(scenario); - scenarioService.updateScenarioAndApplyRule(scenario, currentTags); + scenarioService.updateScenario(scenario, currentTags, true); scenario .getInjects() @@ -233,4 +232,32 @@ public void testUpdateScenarioAndApplyRule_WITH_AddedAndRemovedTags() { .applyDefaultAssetsToInject(inject.getId(), assetsToAdd, assetsToRemove)); verify(mockScenarioRepository).save(scenario); } + + @Test + public void testUpdateScenario_WITH_applyRule_false() { + setUpWithMockRepository(); + Asset asset1 = AssetFixture.createDefaultAsset("asset1"); + Asset asset2 = AssetFixture.createDefaultAsset("asset2"); + Asset asset3 = AssetFixture.createDefaultAsset("asset3"); + Tag tag1 = TagFixture.getTag("Tag1"); + Tag tag2 = TagFixture.getTag("Tag2"); + Tag tag3 = TagFixture.getTag("Tag3"); + Scenario scenario = ScenarioFixture.getScenarioWithInjects(); + scenario.setTags(Set.of(tag1, tag2)); + Set currentTags = Set.of(tag2, tag3); + List assetsToAdd = List.of(asset1, asset2); + List assetsToRemove = List.of(asset3); + + when(tagRuleService.getAssetsFromTagIds(List.of(tag1.getId()))).thenReturn(assetsToAdd); + when(tagRuleService.getAssetsFromTagIds(List.of(tag3.getId()))).thenReturn(assetsToRemove); + when(mockScenarioRepository.save(scenario)).thenReturn(scenario); + + scenarioService.updateScenario(scenario, currentTags, false); + + scenario + .getInjects() + .forEach( + inject -> + verify(injectService, never()).applyDefaultAssetsToInject(any(), any(), any())); + } } From b3f5a7b3798b1aad3354a73239d2b0a32914f6d8 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 14:49:27 +0100 Subject: [PATCH 03/16] updated scenario logic --- ...3_54__TagRule.java => V3_57__TagRule.java} | 2 +- .../rest/inject/service/InjectService.java | 59 +++++++++++-------- .../rest/scenario/ScenarioApiTest.java | 2 +- 3 files changed, 35 insertions(+), 28 deletions(-) rename openbas-api/src/main/java/io/openbas/migration/{V3_54__TagRule.java => V3_57__TagRule.java} (96%) diff --git a/openbas-api/src/main/java/io/openbas/migration/V3_54__TagRule.java b/openbas-api/src/main/java/io/openbas/migration/V3_57__TagRule.java similarity index 96% rename from openbas-api/src/main/java/io/openbas/migration/V3_54__TagRule.java rename to openbas-api/src/main/java/io/openbas/migration/V3_57__TagRule.java index 61e8c19dcd..2655fa7328 100644 --- a/openbas-api/src/main/java/io/openbas/migration/V3_54__TagRule.java +++ b/openbas-api/src/main/java/io/openbas/migration/V3_57__TagRule.java @@ -7,7 +7,7 @@ import org.springframework.stereotype.Component; @Component -public class V3_54__TagRule extends BaseJavaMigration { +public class V3_57__TagRule extends BaseJavaMigration { @Override public void migrate(Context context) throws Exception { diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java index f5707f99d8..e2c92543b1 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java @@ -4,6 +4,7 @@ import static java.time.Instant.now; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import io.openbas.database.model.*; import io.openbas.database.repository.InjectDocumentRepository; import io.openbas.database.repository.InjectRepository; @@ -16,6 +17,7 @@ import jakarta.annotation.Resource; import jakarta.transaction.Transactional; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.time.Instant; import java.util.HashSet; import java.util.List; @@ -41,8 +43,8 @@ public class InjectService { public Inject inject(@NotBlank final String injectId) { return this.injectRepository - .findById(injectId) - .orElseThrow(() -> new ElementNotFoundException("Inject not found")); + .findById(injectId) + .orElseThrow(() -> new ElementNotFoundException("Inject not found")); } @Transactional(rollbackOn = Exception.class) @@ -69,36 +71,42 @@ public void deleteAllByIds(List injectIds) { public void cleanInjectsDocExercise(String exerciseId, String documentId) { // Delete document from all exercise injects List exerciseInjects = - injectRepository.findAllForExerciseAndDoc(exerciseId, documentId); + injectRepository.findAllForExerciseAndDoc(exerciseId, documentId); List updatedInjects = - exerciseInjects.stream() - .flatMap( - inject -> { - @SuppressWarnings("UnnecessaryLocalVariable") - Stream filterDocuments = - inject.getDocuments().stream() - .filter(document -> document.getDocument().getId().equals(documentId)); - return filterDocuments; - }) - .toList(); + exerciseInjects.stream() + .flatMap( + inject -> { + @SuppressWarnings("UnnecessaryLocalVariable") + Stream filterDocuments = + inject.getDocuments().stream() + .filter(document -> document.getDocument().getId().equals(documentId)); + return filterDocuments; + }) + .toList(); injectDocumentRepository.deleteAll(updatedInjects); } + public T convertInjectContent(@NotNull final Inject inject, @NotNull final Class converter) + throws Exception { + ObjectNode content = inject.getContent(); + return this.mapper.treeToValue(content, converter); + } + public void cleanInjectsDocScenario(String scenarioId, String documentId) { // Delete document from all scenario injects List scenarioInjects = - injectRepository.findAllForScenarioAndDoc(scenarioId, documentId); + injectRepository.findAllForScenarioAndDoc(scenarioId, documentId); List updatedInjects = - scenarioInjects.stream() - .flatMap( - inject -> { - @SuppressWarnings("UnnecessaryLocalVariable") - Stream filterDocuments = - inject.getDocuments().stream() - .filter(document -> document.getDocument().getId().equals(documentId)); - return filterDocuments; - }) - .toList(); + scenarioInjects.stream() + .flatMap( + inject -> { + @SuppressWarnings("UnnecessaryLocalVariable") + Stream filterDocuments = + inject.getDocuments().stream() + .filter(document -> document.getDocument().getId().equals(documentId)); + return filterDocuments; + }) + .toList(); injectDocumentRepository.deleteAll(updatedInjects); } @@ -132,7 +140,6 @@ public void delete(String id) { injectDocumentRepository.deleteDocumentsFromInject(id); injectRepository.deleteById(id); } - /** * Update an inject with default assets * @@ -194,4 +201,4 @@ private InjectStatus saveInjectStatusAsQueuing(Inject inject) { this.injectStatusRepository.save(injectStatus); return injectStatus; } -} +} \ No newline at end of file diff --git a/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java b/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java index f6182fdbe5..42f4670fff 100644 --- a/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java @@ -231,7 +231,7 @@ void deleteScenarioTest() throws Exception { @DisplayName("Update with apply rule") @Test - public void testUpdateScenario_WITH_apply_rule_true() throws Exception { + public void testUpdateScenario_WITH_apply_rule_false() throws Exception { String tag1 = "tag1"; String tag2 = "tag2"; Tag tag3 = createTag("tag3"); From 36981b360c73cdfc971da9a624fe0774ba2d2be9 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 16:21:12 +0100 Subject: [PATCH 04/16] removed unit tests --- .../io/openbas/migration/V3_57__TagRule.java | 43 ---- .../rest/exercise/ExerciseApiTest.java | 143 +----------- .../rest/scenario/ScenarioApiTest.java | 219 +++++------------- 3 files changed, 71 insertions(+), 334 deletions(-) delete mode 100644 openbas-api/src/main/java/io/openbas/migration/V3_57__TagRule.java diff --git a/openbas-api/src/main/java/io/openbas/migration/V3_57__TagRule.java b/openbas-api/src/main/java/io/openbas/migration/V3_57__TagRule.java deleted file mode 100644 index 2655fa7328..0000000000 --- a/openbas-api/src/main/java/io/openbas/migration/V3_57__TagRule.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.openbas.migration; - -import java.sql.Connection; -import java.sql.Statement; -import org.flywaydb.core.api.migration.BaseJavaMigration; -import org.flywaydb.core.api.migration.Context; -import org.springframework.stereotype.Component; - -@Component -public class V3_57__TagRule extends BaseJavaMigration { - - @Override - public void migrate(Context context) throws Exception { - Connection connection = context.getConnection(); - Statement select = connection.createStatement(); - // Create relations between contracts and attack_patterns - select.execute( - """ - CREATE TABLE tag_rules ( - tag_rule_id varchar(255) not null, - tag_id varchar(255) not null - constraint tag_id_fk - references tags, - primary key (tag_rule_id) - ); - CREATE INDEX idx_tag_id ON tag_rules (tag_id); - """); - - select.execute( - """ - CREATE TABLE tag_rule_assets ( - tag_rule_id varchar(255) not null - constraint tag_rule_id_fk - references tag_rules, - asset_id varchar(255) not null - constraint asset_id_fk - references assets - on delete cascade, - primary key (tag_rule_id, asset_id) - ); - """); - } -} diff --git a/openbas-api/src/test/java/io/openbas/rest/exercise/ExerciseApiTest.java b/openbas-api/src/test/java/io/openbas/rest/exercise/ExerciseApiTest.java index 2eb1c5a0db..830f12fcd2 100644 --- a/openbas-api/src/test/java/io/openbas/rest/exercise/ExerciseApiTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/exercise/ExerciseApiTest.java @@ -3,8 +3,7 @@ import static io.openbas.rest.exercise.ExerciseApi.EXERCISE_URI; import static io.openbas.utils.JsonUtils.asJsonString; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; +import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -13,23 +12,19 @@ import com.jayway.jsonpath.JsonPath; import io.openbas.database.model.Exercise; import io.openbas.database.model.ExerciseTeamUser; -import io.openbas.database.model.Tag; import io.openbas.database.model.Team; import io.openbas.database.model.User; -import io.openbas.database.repository.*; -import io.openbas.rest.exercise.form.ExerciseUpdateTagsInput; +import io.openbas.database.repository.ExerciseRepository; +import io.openbas.database.repository.ExerciseTeamUserRepository; +import io.openbas.database.repository.TeamRepository; +import io.openbas.database.repository.UserRepository; import io.openbas.rest.exercise.form.ExercisesGlobalScoresInput; -import io.openbas.rest.exercise.form.UpdateExerciseInput; -import io.openbas.rest.exercise.service.ExerciseService; import io.openbas.utils.fixtures.ExerciseFixture; -import io.openbas.utils.fixtures.TagFixture; import io.openbas.utils.fixtures.TeamFixture; import io.openbas.utils.fixtures.UserFixture; import io.openbas.utils.mockUser.WithMockAdminUser; import java.util.*; import org.junit.jupiter.api.*; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -38,6 +33,7 @@ @SpringBootTest @AutoConfigureMockMvc +@TestInstance(PER_CLASS) public class ExerciseApiTest { @Autowired private MockMvc mvc; @@ -49,16 +45,12 @@ public class ExerciseApiTest { @Autowired private ExerciseTeamUserRepository exerciseTeamUserRepository; - @Mock ExerciseRepository exerciseRepositoryMock; - @Mock TagRepository tagRepositoryMock; - @Mock ExerciseService exerciseServiceMock; - @InjectMocks private ExerciseApi exerciseApi; - private static final List EXERCISE_IDS = new ArrayList<>(); private static final List USER_IDS = new ArrayList<>(); private static final List TEAM_IDS = new ArrayList<>(); - void cleanup() { + @AfterAll + void afterAll() { this.exerciseRepository.deleteAllById(EXERCISE_IDS); this.userRepository.deleteAllById(USER_IDS); this.teamRepository.deleteAllById(TEAM_IDS); @@ -103,8 +95,6 @@ void retrievingPlayersByExercise() throws Exception { jsonPath("$[*].user_id") .value( org.hamcrest.Matchers.containsInAnyOrder(userTom.getId(), userBen.getId()))); - - cleanup(); } @Test @@ -140,123 +130,6 @@ void getGlobalScoreForExercises() throws Exception { "[]", JsonPath.read(response, "$.global_scores_by_exercise_ids." + exercise2Saved.getId()) .toString()); - - cleanup(); } } - - @DisplayName("Update with apply rule") - @Test - public void testUpdateExercise_WITH_apply_rule_true() { - Tag tag1 = TagFixture.getTag("Tag1"); - Tag tag2 = TagFixture.getTag("Tag2"); - Tag tag3 = TagFixture.getTag("Tag3"); - - Exercise exercise = ExerciseFixture.createDefaultCrisisExercise(); - exercise.setTags(Set.of(tag2, tag3, tag1)); - exercise.setId("test"); - UpdateExerciseInput input = new UpdateExerciseInput(); - input.setDescription("test"); - input.setApplyTagRule(true); - input.setTagIds(List.of(tag1.getId(), tag2.getId())); - - Exercise expected = ExerciseFixture.createDefaultCrisisExercise(); - expected.setId("test"); - expected.setDescription("test"); - expected.setTags(Set.of(tag1, tag2)); - - doReturn(List.of(tag1, tag2)) - .when(tagRepositoryMock) - .findAllById(List.of(tag1.getId(), tag2.getId())); - doReturn(Optional.of(exercise)).when(exerciseRepositoryMock).findById(exercise.getId()); - - exerciseApi.updateExerciseInformation(exercise.getId(), input); - - verify(exerciseServiceMock).updateExerciceAndApplyRule(expected, Set.of(tag2, tag3, tag1)); - } - - @DisplayName("Update without apply rule") - @Test - public void testUpdateExercise_WITH_apply_rule_false() throws Exception { - Tag tag1 = TagFixture.getTag("Tag1"); - Tag tag2 = TagFixture.getTag("Tag2"); - Tag tag3 = TagFixture.getTag("Tag3"); - - Exercise exercise = ExerciseFixture.createDefaultCrisisExercise(); - exercise.setTags(Set.of(tag2, tag3, tag1)); - exercise.setId("test"); - UpdateExerciseInput input = new UpdateExerciseInput(); - input.setDescription("test"); - input.setTagIds(List.of(tag1.getId(), tag2.getId())); - - Exercise expected = ExerciseFixture.createDefaultCrisisExercise(); - expected.setId("test"); - expected.setDescription("test"); - expected.setTags(Set.of(tag1, tag2)); - - doReturn(List.of(tag1, tag2)) - .when(tagRepositoryMock) - .findAllById(List.of(tag1.getId(), tag2.getId())); - doReturn(Optional.of(exercise)).when(exerciseRepositoryMock).findById(exercise.getId()); - - exerciseApi.updateExerciseInformation(exercise.getId(), input); - - verify(exerciseRepositoryMock).save(expected); - } - - @DisplayName("Update tags without apply rule") - @Test - public void testUpdateExerciseTags_WITH_apply_rule_false() { - Tag tag1 = TagFixture.getTag("Tag1"); - Tag tag2 = TagFixture.getTag("Tag2"); - Tag tag3 = TagFixture.getTag("Tag3"); - - Exercise exercise = ExerciseFixture.createDefaultCrisisExercise(); - exercise.setTags(Set.of(tag2, tag3, tag1)); - exercise.setId("test"); - - ExerciseUpdateTagsInput input = new ExerciseUpdateTagsInput(); - input.setTagIds(List.of(tag1.getId(), tag2.getId())); - - Exercise expected = ExerciseFixture.createDefaultCrisisExercise(); - expected.setTags(Set.of(tag1, tag2)); - expected.setId("test"); - - doReturn(List.of(tag1, tag2)) - .when(tagRepositoryMock) - .findAllById(List.of(tag1.getId(), tag2.getId())); - doReturn(Optional.of(exercise)).when(exerciseRepositoryMock).findById(exercise.getId()); - - exerciseApi.updateExerciseTags(exercise.getId(), input); - - verify(exerciseRepositoryMock).save(expected); - } - - @DisplayName("Update tags with apply rule") - @Test - public void testUpdateExerciseTags_WITH_apply_rule_true() { - Tag tag1 = TagFixture.getTag("Tag1"); - Tag tag2 = TagFixture.getTag("Tag2"); - Tag tag3 = TagFixture.getTag("Tag3"); - - Exercise exercise = ExerciseFixture.createDefaultCrisisExercise(); - exercise.setTags(Set.of(tag2, tag3, tag1)); - exercise.setId("test"); - ExerciseUpdateTagsInput input = new ExerciseUpdateTagsInput(); - input.setTagIds(List.of(tag1.getId(), tag2.getId())); - input.setApplyTagRule(true); - - Exercise expected = ExerciseFixture.createDefaultCrisisExercise(); - expected.setTags(Set.of(tag1, tag2)); - expected.setId("test"); - - doReturn(List.of(tag1, tag2)) - .when(tagRepositoryMock) - .findAllById(List.of(tag1.getId(), tag2.getId())); - doReturn(Optional.of(exercise)).when(exerciseRepositoryMock).findById(exercise.getId()); - - exerciseApi.updateExerciseTags(exercise.getId(), input); - - verify(exerciseServiceMock).updateExerciceAndApplyRule(expected, Set.of(tag2, tag3, tag1)); - } } diff --git a/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java b/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java index 42f4670fff..0384987361 100644 --- a/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java @@ -1,40 +1,21 @@ package io.openbas.rest.scenario; -import static io.openbas.injectors.email.EmailContract.EMAIL_DEFAULT; import static io.openbas.rest.scenario.ScenarioApi.SCENARIO_URI; import static io.openbas.utils.JsonUtils.asJsonString; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; +import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.jayway.jsonpath.JsonPath; -import io.openbas.database.model.Asset; -import io.openbas.database.model.Inject; -import io.openbas.database.model.Scenario; -import io.openbas.database.model.Tag; -import io.openbas.database.repository.*; +import io.openbas.database.repository.ScenarioRepository; import io.openbas.rest.scenario.form.ScenarioInformationInput; import io.openbas.rest.scenario.form.ScenarioInput; -import io.openbas.rest.scenario.form.ScenarioUpdateTagsInput; -import io.openbas.rest.scenario.form.UpdateScenarioInput; -import io.openbas.service.ScenarioService; -import io.openbas.utils.fixtures.InjectFixture; -import io.openbas.utils.fixtures.InjectorContractFixture; -import io.openbas.utils.fixtures.ScenarioFixture; -import io.openbas.utils.fixtures.TagFixture; import io.openbas.utils.mockUser.WithMockObserverUser; import io.openbas.utils.mockUser.WithMockPlannerUser; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; import org.junit.jupiter.api.*; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -44,25 +25,17 @@ @SpringBootTest @AutoConfigureMockMvc @TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@TestInstance(PER_CLASS) public class ScenarioApiTest { - public static final String EMAIL_DEFAULT = "138ad8f8-32f8-4a22-8114-aaa12322bd09"; @Autowired private MockMvc mvc; @Autowired private ScenarioRepository scenarioRepository; - @Autowired private TagRepository tagRepository; - @Autowired private AssetRepository assetRepository; - @Autowired private InjectorContractRepository injectorContractRepository; - - @Mock TagRepository tagRepositoryMock; - @Mock ScenarioService scenarioServiceMock; - @InjectMocks private ScenarioApi scenarioApi; static String SCENARIO_ID; - @Autowired - private InjectRepository injectRepository; - void cleanup() { + @AfterAll + void afterAll() { this.scenarioRepository.deleteById(SCENARIO_ID); } @@ -76,12 +49,12 @@ void createScenarioTest() throws Exception { // -- EXECUTE & ASSERT -- this.mvc - .perform( - post(SCENARIO_URI) - .content(asJsonString(scenarioInput)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is4xxClientError()); + .perform( + post(SCENARIO_URI) + .content(asJsonString(scenarioInput)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()); // -- PREPARE -- String name = "My scenario"; @@ -91,22 +64,21 @@ void createScenarioTest() throws Exception { // -- EXECUTE -- String response = - this.mvc - .perform( - post(SCENARIO_URI) - .content(asJsonString(scenarioInput)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andExpect(jsonPath("$.scenario_name").value(name)) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform( + post(SCENARIO_URI) + .content(asJsonString(scenarioInput)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andExpect(jsonPath("$.scenario_name").value(name)) + .andReturn() + .getResponse() + .getContentAsString(); // -- ASSERT -- assertNotNull(response); SCENARIO_ID = JsonPath.read(response, "$.scenario_id"); - cleanup(); } @DisplayName("Retrieve scenarios") @@ -116,16 +88,15 @@ void createScenarioTest() throws Exception { void retrieveScenariosTest() throws Exception { // -- EXECUTE -- String response = - this.mvc - .perform(get(SCENARIO_URI).accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform(get(SCENARIO_URI).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); // -- ASSERT -- assertNotNull(response); - cleanup(); } @DisplayName("Retrieve scenario") @@ -135,16 +106,15 @@ void retrieveScenariosTest() throws Exception { void retrieveScenarioTest() throws Exception { // -- EXECUTE -- String response = - this.mvc - .perform(get(SCENARIO_URI + "/" + SCENARIO_ID).accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform(get(SCENARIO_URI + "/" + SCENARIO_ID).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); // -- ASSERT -- assertNotNull(response); - cleanup(); } @DisplayName("Update scenario") @@ -154,12 +124,12 @@ void retrieveScenarioTest() throws Exception { void updateScenarioTest() throws Exception { // -- PREPARE -- String response = - this.mvc - .perform(get(SCENARIO_URI + "/" + SCENARIO_ID).accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform(get(SCENARIO_URI + "/" + SCENARIO_ID).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); ScenarioInput scenarioInput = new ScenarioInput(); String subtitle = "A subtitle"; @@ -169,21 +139,20 @@ void updateScenarioTest() throws Exception { // -- EXECUTE -- response = - this.mvc - .perform( - put(SCENARIO_URI + "/" + SCENARIO_ID) - .content(asJsonString(scenarioInput)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform( + put(SCENARIO_URI + "/" + SCENARIO_ID) + .content(asJsonString(scenarioInput)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); // -- ASSERT -- assertNotNull(response); assertEquals(subtitle, JsonPath.read(response, "$.scenario_subtitle")); - cleanup(); } @DisplayName("Update scenario information") @@ -199,21 +168,20 @@ void updateScenarioInformationTest() throws Exception { // -- EXECUTE -- String response = - this.mvc - .perform( - put(SCENARIO_URI + "/" + SCENARIO_ID + "/information") - .content(asJsonString(scenarioInformationInput)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform( + put(SCENARIO_URI + "/" + SCENARIO_ID + "/information") + .content(asJsonString(scenarioInformationInput)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); // -- ASSERT -- assertNotNull(response); assertEquals(header, JsonPath.read(response, "$.scenario_message_header")); - cleanup(); } @DisplayName("Delete scenario") @@ -223,68 +191,7 @@ void updateScenarioInformationTest() throws Exception { void deleteScenarioTest() throws Exception { // -- EXECUTE 1 ASSERT -- this.mvc - .perform(delete(SCENARIO_URI + "/" + SCENARIO_ID)) - .andExpect(status().is2xxSuccessful()); - cleanup(); - } - - - @DisplayName("Update with apply rule") - @Test - public void testUpdateScenario_WITH_apply_rule_false() throws Exception { - String tag1 = "tag1"; - String tag2 = "tag2"; - Tag tag3 = createTag("tag3"); - Scenario scenario = createScenario("testScenario", List.of(tag1, tag2)); - - UpdateScenarioInput updateScenarioInput = new UpdateScenarioInput(); - updateScenarioInput.setApplyTagRule(false); - updateScenarioInput.setTagIds(List.of(tag3.getId())); - - - this.mvc - .perform( - put(SCENARIO_URI + "/" + scenario.getId()) - .content(asJsonString(updateScenarioInput)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); - - - Scenario updatedScenario = scenarioRepository.findById(scenario.getId()).orElseThrow(); - assertEquals(updatedScenario.getTags().size(), 1); - assertEquals(new HashSet<>(updatedScenario.getInjects().getFirst().getAssets()), - new HashSet<>(scenario.getInjects().getFirst().getAssets())); - } - - - private Scenario createScenario(String scenarioName, List tagNames) { - Scenario scenario = new Scenario(); - tagNames.forEach(tagName -> scenario.getTags().add(createTag(tagName))); - scenarioRepository.save(scenario); - createInject(scenario.getId()); - return scenarioRepository.findById(scenario.getId()).orElseThrow(); - } - - private Inject createInject(String scenarioId) { - Inject inject = InjectFixture.getInjectForEmailContract(injectorContractRepository.findById(EMAIL_DEFAULT).orElseThrow()); - inject.setScenario(scenarioRepository.findById(scenarioId).orElseThrow()); - return injectRepository.save(inject); - } - - private Tag createTag(String tagName) { - Tag tag = new Tag(); - tag.setName(tagName + System.currentTimeMillis()); - tag.setColor("#0000"); - return tagRepository.save(tag); - } - - private Asset createAsset(String assetName) { - Asset asset = new Asset(); - asset.setName(assetName); - return assetRepository.save(asset); + .perform(delete(SCENARIO_URI + "/" + SCENARIO_ID)) + .andExpect(status().is2xxSuccessful()); } -} +} \ No newline at end of file From 8e803114d2d44dcd62906a3e8c1b5018a52232b3 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 16:31:53 +0100 Subject: [PATCH 05/16] updated excercise service --- .../io/openbas/rest/exercise/ExerciseApi.java | 12 +---- .../exercise/service/ExerciseService.java | 53 ++++++++++--------- .../io/openbas/rest/scenario/ScenarioApi.java | 4 +- .../exercise/service/ExerciseServiceTest.java | 31 +++++++++-- .../openbas/service/ScenarioServiceTest.java | 6 +-- 5 files changed, 59 insertions(+), 47 deletions(-) diff --git a/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseApi.java b/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseApi.java index fc0c1a38fc..92bb777565 100644 --- a/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseApi.java @@ -405,11 +405,7 @@ public Exercise updateExerciseInformation( Set currentTagList = exercise.getTags(); exercise.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds()))); exercise.setUpdateAttributes(input); - if (input.isApplyTagRule()) { - return exerciseService.updateExerciceAndApplyRule(exercise, currentTagList); - } else { - return exerciseRepository.save(exercise); - } + return exerciseService.updateExercice(exercise, currentTagList, input.isApplyTagRule()); } @PutMapping(EXERCISE_URI + "/{exerciseId}/start_date") @@ -437,11 +433,7 @@ public Exercise updateExerciseTags( exerciseRepository.findById(exerciseId).orElseThrow(ElementNotFoundException::new); Set currentTagList = exercise.getTags(); exercise.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds()))); - if (input.isApplyTagRule()) { - return exerciseService.updateExerciceAndApplyRule(exercise, currentTagList); - } else { - return exerciseRepository.save(exercise); - } + return exerciseService.updateExercice(exercise, currentTagList, input.isApplyTagRule()); } @PutMapping(EXERCISE_URI + "/{exerciseId}/logos") diff --git a/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java b/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java index 90e91e4777..5bcbce7de4 100644 --- a/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java +++ b/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java @@ -627,32 +627,33 @@ public Iterable removeTeams( * @return */ @Transactional - public Exercise updateExerciceAndApplyRule( - @NotNull final Exercise exercise, @NotNull final Set currentTags) { - // Get assets from the TagRule of the added tags - List defaultAssetsToAdd = - tagRuleService.getAssetsFromTagIds( - exercise.getTags().stream() - .filter(tag -> !currentTags.contains(tag)) - .map(Tag::getId) - .toList()); - - // Get assets from the TagRule of the removed tags - List defaultAssetsToRemove = - tagRuleService.getAssetsFromTagIds( - currentTags.stream() - .filter(tag -> !exercise.getTags().contains(tag)) - .map(Tag::getId) - .toList()); - - // Add/remove the default assets to/from the injects - exercise - .getInjects() - .forEach( - inject -> - injectService.applyDefaultAssetsToInject( - inject.getId(), defaultAssetsToAdd, defaultAssetsToRemove)); - + public Exercise updateExercice( + @NotNull final Exercise exercise, @NotNull final Set currentTags, boolean applyRule) { + if(applyRule) { + // Get assets from the TagRule of the added tags + List defaultAssetsToAdd = + tagRuleService.getAssetsFromTagIds( + exercise.getTags().stream() + .filter(tag -> !currentTags.contains(tag)) + .map(Tag::getId) + .toList()); + + // Get assets from the TagRule of the removed tags + List defaultAssetsToRemove = + tagRuleService.getAssetsFromTagIds( + currentTags.stream() + .filter(tag -> !exercise.getTags().contains(tag)) + .map(Tag::getId) + .toList()); + + // Add/remove the default assets to/from the injects + exercise + .getInjects() + .forEach( + inject -> + injectService.applyDefaultAssetsToInject( + inject.getId(), defaultAssetsToAdd, defaultAssetsToRemove)); + } exercise.setUpdatedAt(now()); return exerciseRepository.save(exercise); } diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java index 27db5fc030..f31fd1d2f2 100644 --- a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java @@ -105,7 +105,7 @@ public Scenario updateScenario( Scenario scenario = this.scenarioService.scenario(scenarioId); Set currentTagList = scenario.getTags(); scenario.setUpdateAttributes(input); - return this.scenarioService.updateScenario(scenario, currentTagList, input.isApplyTagRule()); + return this.scenarioService.updateScenario(scenario, currentTagList, true); } @PutMapping(SCENARIO_URI + "/{scenarioId}/information") @@ -134,7 +134,7 @@ public Scenario updateScenarioTags( Scenario scenario = this.scenarioService.scenario(scenarioId); Set currentTagList = scenario.getTags(); scenario.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds()))); - return this.scenarioService.updateScenario(scenario, currentTagList, input.isApplyTagRule()); + return this.scenarioService.updateScenario(scenario, currentTagList, true); } // -- EXPORT -- diff --git a/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java b/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java index e301d31947..e044c6c433 100644 --- a/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java @@ -1,8 +1,7 @@ package io.openbas.rest.exercise.service; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; import io.openbas.database.model.Asset; import io.openbas.database.model.Exercise; @@ -111,7 +110,7 @@ void getExercisesGlobalScores() { } @Test - public void testUpdateExerciseAndApplyRule_WITH_AddedAndRemovedTags() { + public void testUpdateExercise_WITH_apply_rule_true() { Asset asset1 = AssetFixture.createDefaultAsset("asset1"); Asset asset2 = AssetFixture.createDefaultAsset("asset2"); Asset asset3 = AssetFixture.createDefaultAsset("asset3"); @@ -128,7 +127,7 @@ public void testUpdateExerciseAndApplyRule_WITH_AddedAndRemovedTags() { when(tagRuleService.getAssetsFromTagIds(List.of(tag3.getId()))).thenReturn(assetsToRemove); when(exerciseRepository.save(exercise)).thenReturn(exercise); - exerciseService.updateExerciceAndApplyRule(exercise, currentTags); + exerciseService.updateExercice(exercise, currentTags, true); exercise .getInjects() @@ -138,4 +137,28 @@ public void testUpdateExerciseAndApplyRule_WITH_AddedAndRemovedTags() { .applyDefaultAssetsToInject(inject.getId(), assetsToAdd, assetsToRemove)); verify(exerciseRepository).save(exercise); } + + @Test + public void testUpdateExercise_WITH_apply_rule_false() { + Asset asset1 = AssetFixture.createDefaultAsset("asset1"); + Asset asset2 = AssetFixture.createDefaultAsset("asset2"); + Asset asset3 = AssetFixture.createDefaultAsset("asset3"); + io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); + io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); + io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); + Exercise exercise = ExerciseFixture.getExerciseWithInjects(); + exercise.setTags(Set.of(tag1, tag2)); + Set currentTags = Set.of(tag2, tag3); + List assetsToAdd = List.of(asset1, asset2); + List assetsToRemove = List.of(asset3); + + when(tagRuleService.getAssetsFromTagIds(List.of(tag1.getId()))).thenReturn(assetsToAdd); + when(tagRuleService.getAssetsFromTagIds(List.of(tag3.getId()))).thenReturn(assetsToRemove); + when(exerciseRepository.save(exercise)).thenReturn(exercise); + + exerciseService.updateExercice(exercise, currentTags, false); + + verify(injectService, never()) + .applyDefaultAssetsToInject(any(), any(), any()); + } } 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 d3181496d8..db65a95674 100644 --- a/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java @@ -254,10 +254,6 @@ public void testUpdateScenario_WITH_applyRule_false() { scenarioService.updateScenario(scenario, currentTags, false); - scenario - .getInjects() - .forEach( - inject -> - verify(injectService, never()).applyDefaultAssetsToInject(any(), any(), any())); + verify(injectService, never()).applyDefaultAssetsToInject(any(), any(), any()); } } From e44743a3dc9b0c6ed3feada2b933e916205abd55 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 16:39:54 +0100 Subject: [PATCH 06/16] fixed scenarioservice --- .../src/main/java/io/openbas/rest/scenario/ScenarioApi.java | 1 + 1 file changed, 1 insertion(+) diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java index f31fd1d2f2..87b0cbe765 100644 --- a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java @@ -105,6 +105,7 @@ public Scenario updateScenario( Scenario scenario = this.scenarioService.scenario(scenarioId); Set currentTagList = scenario.getTags(); scenario.setUpdateAttributes(input); + scenario.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds()))); return this.scenarioService.updateScenario(scenario, currentTagList, true); } From c92fcd409eb647261354b5e3ab25913a9eec862f Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 17:04:40 +0100 Subject: [PATCH 07/16] correct input --- .../src/main/java/io/openbas/rest/scenario/ScenarioApi.java | 4 ++-- .../src/main/java/io/openbas/service/TagRuleService.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java index 87b0cbe765..364a4810c3 100644 --- a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java @@ -106,7 +106,7 @@ public Scenario updateScenario( Set currentTagList = scenario.getTags(); scenario.setUpdateAttributes(input); scenario.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds()))); - return this.scenarioService.updateScenario(scenario, currentTagList, true); + return this.scenarioService.updateScenario(scenario, currentTagList, input.isApplyTagRule()); } @PutMapping(SCENARIO_URI + "/{scenarioId}/information") @@ -135,7 +135,7 @@ public Scenario updateScenarioTags( Scenario scenario = this.scenarioService.scenario(scenarioId); Set currentTagList = scenario.getTags(); scenario.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds()))); - return this.scenarioService.updateScenario(scenario, currentTagList, true); + return this.scenarioService.updateScenario(scenario, currentTagList, input.isApplyTagRule()); } // -- EXPORT -- diff --git a/openbas-api/src/main/java/io/openbas/service/TagRuleService.java b/openbas-api/src/main/java/io/openbas/service/TagRuleService.java index 5b1706a4c3..eec7b04917 100644 --- a/openbas-api/src/main/java/io/openbas/service/TagRuleService.java +++ b/openbas-api/src/main/java/io/openbas/service/TagRuleService.java @@ -24,9 +24,9 @@ @RequiredArgsConstructor @Service public class TagRuleService { - private TagRuleRepository tagRuleRepository; - private TagRepository tagRepository; - private AssetRepository assetRepository; + private final TagRuleRepository tagRuleRepository; + private final TagRepository tagRepository; + private final AssetRepository assetRepository; public Optional findById(String id) { return tagRuleRepository.findById(id); From 9fe0e1e6a7281183812c58fe034c8204e0e901af Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 17:07:57 +0100 Subject: [PATCH 08/16] fixed comment --- .../src/main/java/io/openbas/rest/inject/InjectApi.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java b/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java index 9c4ae85abd..299d20ff26 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java @@ -347,7 +347,7 @@ public Inject createInjectForExercise( } inject.setTeams(fromIterable(teamRepository.findAllById(input.getTeams()))); - // Get input assets + // add default assets inject.setAssets( this.tagRuleService.applyTagRuleToInjectCreation( exercise.getTags().stream().map(Tag::getId).toList(), @@ -586,7 +586,7 @@ public Inject createInjectForScenario( } inject.setTeams(fromIterable(teamRepository.findAllById(input.getTeams()))); - // Get input assets + // add default assets inject.setAssets( this.tagRuleService.applyTagRuleToInjectCreation( scenario.getTags().stream().map(Tag::getId).toList(), From 44b13177a1a74c8c2589f6d2b36e7f2a9d72e1ce Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 17:12:25 +0100 Subject: [PATCH 09/16] fixed untouched file --- .../rest/scenario/ScenarioApiTest.java | 116 +++++++++--------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java b/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java index 0384987361..e29bc3ca9b 100644 --- a/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/scenario/ScenarioApiTest.java @@ -49,12 +49,12 @@ void createScenarioTest() throws Exception { // -- EXECUTE & ASSERT -- this.mvc - .perform( - post(SCENARIO_URI) - .content(asJsonString(scenarioInput)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is4xxClientError()); + .perform( + post(SCENARIO_URI) + .content(asJsonString(scenarioInput)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()); // -- PREPARE -- String name = "My scenario"; @@ -64,17 +64,17 @@ void createScenarioTest() throws Exception { // -- EXECUTE -- String response = - this.mvc - .perform( - post(SCENARIO_URI) - .content(asJsonString(scenarioInput)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andExpect(jsonPath("$.scenario_name").value(name)) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform( + post(SCENARIO_URI) + .content(asJsonString(scenarioInput)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andExpect(jsonPath("$.scenario_name").value(name)) + .andReturn() + .getResponse() + .getContentAsString(); // -- ASSERT -- assertNotNull(response); @@ -88,12 +88,12 @@ void createScenarioTest() throws Exception { void retrieveScenariosTest() throws Exception { // -- EXECUTE -- String response = - this.mvc - .perform(get(SCENARIO_URI).accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform(get(SCENARIO_URI).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); // -- ASSERT -- assertNotNull(response); @@ -106,12 +106,12 @@ void retrieveScenariosTest() throws Exception { void retrieveScenarioTest() throws Exception { // -- EXECUTE -- String response = - this.mvc - .perform(get(SCENARIO_URI + "/" + SCENARIO_ID).accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform(get(SCENARIO_URI + "/" + SCENARIO_ID).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); // -- ASSERT -- assertNotNull(response); @@ -124,12 +124,12 @@ void retrieveScenarioTest() throws Exception { void updateScenarioTest() throws Exception { // -- PREPARE -- String response = - this.mvc - .perform(get(SCENARIO_URI + "/" + SCENARIO_ID).accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform(get(SCENARIO_URI + "/" + SCENARIO_ID).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); ScenarioInput scenarioInput = new ScenarioInput(); String subtitle = "A subtitle"; @@ -139,16 +139,16 @@ void updateScenarioTest() throws Exception { // -- EXECUTE -- response = - this.mvc - .perform( - put(SCENARIO_URI + "/" + SCENARIO_ID) - .content(asJsonString(scenarioInput)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform( + put(SCENARIO_URI + "/" + SCENARIO_ID) + .content(asJsonString(scenarioInput)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); // -- ASSERT -- assertNotNull(response); @@ -168,16 +168,16 @@ void updateScenarioInformationTest() throws Exception { // -- EXECUTE -- String response = - this.mvc - .perform( - put(SCENARIO_URI + "/" + SCENARIO_ID + "/information") - .content(asJsonString(scenarioInformationInput)) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().is2xxSuccessful()) - .andReturn() - .getResponse() - .getContentAsString(); + this.mvc + .perform( + put(SCENARIO_URI + "/" + SCENARIO_ID + "/information") + .content(asJsonString(scenarioInformationInput)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); // -- ASSERT -- assertNotNull(response); @@ -191,7 +191,7 @@ void updateScenarioInformationTest() throws Exception { void deleteScenarioTest() throws Exception { // -- EXECUTE 1 ASSERT -- this.mvc - .perform(delete(SCENARIO_URI + "/" + SCENARIO_ID)) - .andExpect(status().is2xxSuccessful()); + .perform(delete(SCENARIO_URI + "/" + SCENARIO_ID)) + .andExpect(status().is2xxSuccessful()); } -} \ No newline at end of file +} From 28c4fffdaa955df317bf1b05675393cce2a5e630 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 17:15:08 +0100 Subject: [PATCH 10/16] fixed untouched file --- .../io/openbas/rest/{inject => }/InjectApiTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename openbas-api/src/test/java/io/openbas/rest/{inject => }/InjectApiTest.java (99%) diff --git a/openbas-api/src/test/java/io/openbas/rest/inject/InjectApiTest.java b/openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java similarity index 99% rename from openbas-api/src/test/java/io/openbas/rest/inject/InjectApiTest.java rename to openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java index c0ab9c6b11..24d576b84c 100644 --- a/openbas-api/src/test/java/io/openbas/rest/inject/InjectApiTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java @@ -1,4 +1,4 @@ -package io.openbas.rest.inject; +package io.openbas.rest; import static io.openbas.config.SessionHelper.currentUser; import static io.openbas.database.model.ExerciseStatus.RUNNING; @@ -44,12 +44,14 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.time.Instant; -import java.util.*; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; -import org.mockito.InjectMocks; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; @@ -94,8 +96,6 @@ class InjectApiTest extends IntegrationTest { @Resource private ObjectMapper objectMapper; @MockBean private JavaMailSender javaMailSender; - @InjectMocks private InjectApi injectApiWithMock; - @BeforeAll void beforeAll() { Scenario scenario = new Scenario(); From af4db23a60df6cc9ece17de493e682f33aa2a932 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 17:26:43 +0100 Subject: [PATCH 11/16] fixed unit test --- .../rest/exercise/service/ExerciseServiceTest.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java b/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java index e044c6c433..6b04e99bf7 100644 --- a/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java @@ -140,25 +140,17 @@ public void testUpdateExercise_WITH_apply_rule_true() { @Test public void testUpdateExercise_WITH_apply_rule_false() { - Asset asset1 = AssetFixture.createDefaultAsset("asset1"); - Asset asset2 = AssetFixture.createDefaultAsset("asset2"); - Asset asset3 = AssetFixture.createDefaultAsset("asset3"); io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); Exercise exercise = ExerciseFixture.getExerciseWithInjects(); exercise.setTags(Set.of(tag1, tag2)); Set currentTags = Set.of(tag2, tag3); - List assetsToAdd = List.of(asset1, asset2); - List assetsToRemove = List.of(asset3); - when(tagRuleService.getAssetsFromTagIds(List.of(tag1.getId()))).thenReturn(assetsToAdd); - when(tagRuleService.getAssetsFromTagIds(List.of(tag3.getId()))).thenReturn(assetsToRemove); when(exerciseRepository.save(exercise)).thenReturn(exercise); exerciseService.updateExercice(exercise, currentTags, false); - verify(injectService, never()) - .applyDefaultAssetsToInject(any(), any(), any()); + verify(injectService, never()).applyDefaultAssetsToInject(any(), any(), any()); } } From c2042c1bd71a0d5abfb67ff899b9e1a643f8fed1 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 17:32:34 +0100 Subject: [PATCH 12/16] spotless --- .../io/openbas/database/repository/TagRuleRepository.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openbas-model/src/main/java/io/openbas/database/repository/TagRuleRepository.java b/openbas-model/src/main/java/io/openbas/database/repository/TagRuleRepository.java index 9189982347..11eee77eae 100644 --- a/openbas-model/src/main/java/io/openbas/database/repository/TagRuleRepository.java +++ b/openbas-model/src/main/java/io/openbas/database/repository/TagRuleRepository.java @@ -1,13 +1,12 @@ package io.openbas.database.repository; import io.openbas.database.model.TagRule; +import java.util.List; import java.util.Optional; import org.jetbrains.annotations.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.data.repository.CrudRepository; - -import java.util.List; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; From f6ca59d665d35fee00f8cc0edeab5357a12348a1 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 17:36:09 +0100 Subject: [PATCH 13/16] spotless --- .../rest/inject/service/InjectService.java | 77 ++++++++++--------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java index e2c92543b1..1a85fa1ac3 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java @@ -43,8 +43,8 @@ public class InjectService { public Inject inject(@NotBlank final String injectId) { return this.injectRepository - .findById(injectId) - .orElseThrow(() -> new ElementNotFoundException("Inject not found")); + .findById(injectId) + .orElseThrow(() -> new ElementNotFoundException("Inject not found")); } @Transactional(rollbackOn = Exception.class) @@ -71,23 +71,23 @@ public void deleteAllByIds(List injectIds) { public void cleanInjectsDocExercise(String exerciseId, String documentId) { // Delete document from all exercise injects List exerciseInjects = - injectRepository.findAllForExerciseAndDoc(exerciseId, documentId); + injectRepository.findAllForExerciseAndDoc(exerciseId, documentId); List updatedInjects = - exerciseInjects.stream() - .flatMap( - inject -> { - @SuppressWarnings("UnnecessaryLocalVariable") - Stream filterDocuments = - inject.getDocuments().stream() - .filter(document -> document.getDocument().getId().equals(documentId)); - return filterDocuments; - }) - .toList(); + exerciseInjects.stream() + .flatMap( + inject -> { + @SuppressWarnings("UnnecessaryLocalVariable") + Stream filterDocuments = + inject.getDocuments().stream() + .filter(document -> document.getDocument().getId().equals(documentId)); + return filterDocuments; + }) + .toList(); injectDocumentRepository.deleteAll(updatedInjects); } public T convertInjectContent(@NotNull final Inject inject, @NotNull final Class converter) - throws Exception { + throws Exception { ObjectNode content = inject.getContent(); return this.mapper.treeToValue(content, converter); } @@ -95,18 +95,18 @@ public T convertInjectContent(@NotNull final Inject inject, @NotNull final C public void cleanInjectsDocScenario(String scenarioId, String documentId) { // Delete document from all scenario injects List scenarioInjects = - injectRepository.findAllForScenarioAndDoc(scenarioId, documentId); + injectRepository.findAllForScenarioAndDoc(scenarioId, documentId); List updatedInjects = - scenarioInjects.stream() - .flatMap( - inject -> { - @SuppressWarnings("UnnecessaryLocalVariable") - Stream filterDocuments = - inject.getDocuments().stream() - .filter(document -> document.getDocument().getId().equals(documentId)); - return filterDocuments; - }) - .toList(); + scenarioInjects.stream() + .flatMap( + inject -> { + @SuppressWarnings("UnnecessaryLocalVariable") + Stream filterDocuments = + inject.getDocuments().stream() + .filter(document -> document.getDocument().getId().equals(documentId)); + return filterDocuments; + }) + .toList(); injectDocumentRepository.deleteAll(updatedInjects); } @@ -140,6 +140,7 @@ public void delete(String id) { injectDocumentRepository.deleteDocumentsFromInject(id); injectRepository.deleteById(id); } + /** * Update an inject with default assets * @@ -150,28 +151,28 @@ public void delete(String id) { */ @Transactional public Inject applyDefaultAssetsToInject( - final String injectId, - final List defaultAssetsToAdd, - final List defaultAssetsToRemove) { + final String injectId, + final List defaultAssetsToAdd, + final List defaultAssetsToRemove) { // fetch the inject Inject inject = - this.injectRepository.findById(injectId).orElseThrow(ElementNotFoundException::new); + this.injectRepository.findById(injectId).orElseThrow(ElementNotFoundException::new); // remove/add default assets and remove duplicates List currentAssets = inject.getAssets(); // Get the Id of the assets to remove and filter the assets that are in both lists List assetIdsToRemove = - defaultAssetsToRemove.stream() - .filter(asset -> !defaultAssetsToAdd.contains(asset)) - .map(Asset::getId) - .toList(); + defaultAssetsToRemove.stream() + .filter(asset -> !defaultAssetsToAdd.contains(asset)) + .map(Asset::getId) + .toList(); Set uniqueAssetsIds = new HashSet<>(); List newListOfAssets = - Stream.concat(currentAssets.stream(), defaultAssetsToAdd.stream()) - .filter(asset -> !assetIdsToRemove.contains(asset.getId())) - .filter(asset -> uniqueAssetsIds.add(asset.getId())) - .collect(Collectors.toList()); + Stream.concat(currentAssets.stream(), defaultAssetsToAdd.stream()) + .filter(asset -> !assetIdsToRemove.contains(asset.getId())) + .filter(asset -> uniqueAssetsIds.add(asset.getId())) + .collect(Collectors.toList()); if (new HashSet<>(currentAssets).equals(new HashSet<>(newListOfAssets))) { return inject; @@ -201,4 +202,4 @@ private InjectStatus saveInjectStatusAsQueuing(Inject inject) { this.injectStatusRepository.save(injectStatus); return injectStatus; } -} \ No newline at end of file +} From 5d300f17ace2e7681f0c7b631b6603b3fbcd5392 Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 17:39:28 +0100 Subject: [PATCH 14/16] spotless --- .../exercise/service/ExerciseService.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java b/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java index 5bcbce7de4..464f670262 100644 --- a/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java +++ b/openbas-api/src/main/java/io/openbas/rest/exercise/service/ExerciseService.java @@ -629,30 +629,30 @@ public Iterable removeTeams( @Transactional public Exercise updateExercice( @NotNull final Exercise exercise, @NotNull final Set currentTags, boolean applyRule) { - if(applyRule) { + if (applyRule) { // Get assets from the TagRule of the added tags List defaultAssetsToAdd = - tagRuleService.getAssetsFromTagIds( - exercise.getTags().stream() - .filter(tag -> !currentTags.contains(tag)) - .map(Tag::getId) - .toList()); + tagRuleService.getAssetsFromTagIds( + exercise.getTags().stream() + .filter(tag -> !currentTags.contains(tag)) + .map(Tag::getId) + .toList()); // Get assets from the TagRule of the removed tags List defaultAssetsToRemove = - tagRuleService.getAssetsFromTagIds( - currentTags.stream() - .filter(tag -> !exercise.getTags().contains(tag)) - .map(Tag::getId) - .toList()); + tagRuleService.getAssetsFromTagIds( + currentTags.stream() + .filter(tag -> !exercise.getTags().contains(tag)) + .map(Tag::getId) + .toList()); // Add/remove the default assets to/from the injects exercise - .getInjects() - .forEach( - inject -> - injectService.applyDefaultAssetsToInject( - inject.getId(), defaultAssetsToAdd, defaultAssetsToRemove)); + .getInjects() + .forEach( + inject -> + injectService.applyDefaultAssetsToInject( + inject.getId(), defaultAssetsToAdd, defaultAssetsToRemove)); } exercise.setUpdatedAt(now()); return exerciseRepository.save(exercise); From 08965a2ce38245eecae7e111021e8f98e78434fe Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Fri, 3 Jan 2025 17:42:31 +0100 Subject: [PATCH 15/16] spotless --- .../io/openbas/service/ScenarioService.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) 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 b0be7c882d..abfcaf50e6 100644 --- a/openbas-api/src/main/java/io/openbas/service/ScenarioService.java +++ b/openbas-api/src/main/java/io/openbas/service/ScenarioService.java @@ -307,30 +307,30 @@ public Scenario updateScenario(@NotNull final Scenario scenario) { @Transactional public Scenario updateScenario( @NotNull final Scenario scenario, Set currentTags, boolean applyRule) { - if(applyRule) { + if (applyRule) { // Get assets from the TagRule of the added tags List defaultAssetsToAdd = - tagRuleService.getAssetsFromTagIds( - scenario.getTags().stream() - .filter(tag -> !currentTags.contains(tag)) - .map(Tag::getId) - .toList()); + tagRuleService.getAssetsFromTagIds( + scenario.getTags().stream() + .filter(tag -> !currentTags.contains(tag)) + .map(Tag::getId) + .toList()); // Get assets from the TagRule of the removed tags List defaultAssetsToRemove = - tagRuleService.getAssetsFromTagIds( - currentTags.stream() - .filter(tag -> !scenario.getTags().contains(tag)) - .map(Tag::getId) - .toList()); + tagRuleService.getAssetsFromTagIds( + currentTags.stream() + .filter(tag -> !scenario.getTags().contains(tag)) + .map(Tag::getId) + .toList()); // Add/remove the default assets to/from the injects scenario - .getInjects() - .forEach( - inject -> - injectService.applyDefaultAssetsToInject( - inject.getId(), defaultAssetsToAdd, defaultAssetsToRemove)); + .getInjects() + .forEach( + inject -> + injectService.applyDefaultAssetsToInject( + inject.getId(), defaultAssetsToAdd, defaultAssetsToRemove)); } scenario.setUpdatedAt(now()); return this.scenarioRepository.save(scenario); From c7d0ec238706f855284cabc5d14f07363272983b Mon Sep 17 00:00:00 2001 From: Hedi Tarchouni Date: Tue, 7 Jan 2025 14:13:11 +0100 Subject: [PATCH 16/16] removed uncomplete fixture --- .../exercise/service/ExerciseServiceTest.java | 21 ++++++++++++++----- .../openbas/service/ScenarioServiceTest.java | 12 +++++++++-- .../openbas/utils/fixtures/AssetFixture.java | 11 +++++++--- .../utils/fixtures/ExerciseFixture.java | 11 ---------- .../utils/fixtures/ScenarioFixture.java | 8 ------- 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java b/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java index 6b04e99bf7..284e2e8770 100644 --- a/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/exercise/service/ExerciseServiceTest.java @@ -5,6 +5,7 @@ import io.openbas.database.model.Asset; import io.openbas.database.model.Exercise; +import io.openbas.database.model.Inject; import io.openbas.database.model.Tag; import io.openbas.database.repository.*; import io.openbas.rest.exercise.form.ExercisesGlobalScoresInput; @@ -114,10 +115,15 @@ public void testUpdateExercise_WITH_apply_rule_true() { Asset asset1 = AssetFixture.createDefaultAsset("asset1"); Asset asset2 = AssetFixture.createDefaultAsset("asset2"); Asset asset3 = AssetFixture.createDefaultAsset("asset3"); - io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); - io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); - io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); - Exercise exercise = ExerciseFixture.getExerciseWithInjects(); + Tag tag1 = TagFixture.getTag("Tag1"); + Tag tag2 = TagFixture.getTag("Tag2"); + Tag tag3 = TagFixture.getTag("Tag3"); + Inject inject1 = new Inject(); + inject1.setId("1"); + Inject inject2 = new Inject(); + inject1.setId("2"); + Exercise exercise = ExerciseFixture.getExercise(null); + exercise.setInjects(List.of(inject1, inject2)); exercise.setTags(Set.of(tag1, tag2)); Set currentTags = Set.of(tag2, tag3); List assetsToAdd = List.of(asset1, asset2); @@ -143,7 +149,12 @@ public void testUpdateExercise_WITH_apply_rule_false() { io.openbas.database.model.Tag tag1 = TagFixture.getTag("Tag1"); io.openbas.database.model.Tag tag2 = TagFixture.getTag("Tag2"); io.openbas.database.model.Tag tag3 = TagFixture.getTag("Tag3"); - Exercise exercise = ExerciseFixture.getExerciseWithInjects(); + Inject inject1 = new Inject(); + inject1.setId("1"); + Inject inject2 = new Inject(); + inject1.setId("2"); + Exercise exercise = ExerciseFixture.getExercise(null); + exercise.setInjects(List.of(inject1, inject2)); exercise.setTags(Set.of(tag1, tag2)); Set currentTags = Set.of(tag2, tag3); 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 db65a95674..8b9233e0e9 100644 --- a/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/service/ScenarioServiceTest.java @@ -212,7 +212,11 @@ public void testUpdateScenario_WITH_applyRule_true() { Tag tag1 = TagFixture.getTag("Tag1"); Tag tag2 = TagFixture.getTag("Tag2"); Tag tag3 = TagFixture.getTag("Tag3"); - Scenario scenario = ScenarioFixture.getScenarioWithInjects(); + Inject inject1 = new Inject(); + inject1.setId("1"); + Inject inject2 = new Inject(); + inject1.setId("2"); + Scenario scenario = ScenarioFixture.getScenario(null, Set.of(inject1, inject2)); scenario.setTags(Set.of(tag1, tag2)); Set currentTags = Set.of(tag2, tag3); List assetsToAdd = List.of(asset1, asset2); @@ -242,7 +246,11 @@ public void testUpdateScenario_WITH_applyRule_false() { Tag tag1 = TagFixture.getTag("Tag1"); Tag tag2 = TagFixture.getTag("Tag2"); Tag tag3 = TagFixture.getTag("Tag3"); - Scenario scenario = ScenarioFixture.getScenarioWithInjects(); + Inject inject1 = new Inject(); + inject1.setId("1"); + Inject inject2 = new Inject(); + inject1.setId("2"); + Scenario scenario = ScenarioFixture.getScenario(null, Set.of(inject1, inject2)); scenario.setTags(Set.of(tag1, tag2)); Set currentTags = Set.of(tag2, tag3); List assetsToAdd = List.of(asset1, asset2); diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/AssetFixture.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/AssetFixture.java index f7c10c2824..9104b5d3d9 100644 --- a/openbas-api/src/test/java/io/openbas/utils/fixtures/AssetFixture.java +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/AssetFixture.java @@ -1,12 +1,17 @@ package io.openbas.utils.fixtures; import io.openbas.database.model.Asset; +import java.time.Instant; import org.jetbrains.annotations.NotNull; public class AssetFixture { public static Asset createDefaultAsset(@NotNull final String id) { - Asset assetGroup = new Asset(); - assetGroup.setId(id); - return assetGroup; + Asset asset = new Asset(); + asset.setId(id); + asset.setCreatedAt(Instant.now()); + asset.setUpdatedAt(Instant.now()); + asset.setName("asset name"); + asset.setDescription("asset description"); + return asset; } } 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 index fe2691a5fc..265bd545a5 100644 --- a/openbas-api/src/test/java/io/openbas/utils/fixtures/ExerciseFixture.java +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/ExerciseFixture.java @@ -4,7 +4,6 @@ import io.openbas.database.model.Exercise; import io.openbas.database.model.ExerciseStatus; -import io.openbas.database.model.Inject; import io.openbas.database.model.Team; import java.time.Instant; import java.util.List; @@ -26,16 +25,6 @@ public static Exercise getExercise(List exerciseTeams) { return exercise; } - public static Exercise getExerciseWithInjects() { - Exercise exercise = getExercise(null); - Inject inject1 = new Inject(); - inject1.setId("1"); - Inject inject2 = new Inject(); - inject1.setId("2"); - exercise.setInjects(List.of(inject1, inject2)); - return exercise; - } - public static Exercise createDefaultCrisisExercise() { Exercise exercise = new Exercise(); exercise.setName("Crisis exercise"); 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 e7fb74565e..af95b6d80f 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 @@ -49,12 +49,4 @@ public static Scenario createDefaultIncidentResponseScenario() { scenario.setSeverity(critical); return scenario; } - - public static Scenario getScenarioWithInjects() { - Inject inject1 = new Inject(); - inject1.setId("1"); - Inject inject2 = new Inject(); - inject1.setId("2"); - return getScenario(null, Set.of(inject1, inject2)); - } }