Skip to content

Commit

Permalink
[backend/frontend] Fix removing a team from the context doesn't work
Browse files Browse the repository at this point in the history
  • Loading branch information
RomuDeuxfois committed Oct 2, 2024
1 parent e044e47 commit 8d5e4b3
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -230,14 +230,7 @@ public Iterable<Team> addExerciseTeams(
@PreAuthorize("isExercisePlanner(#exerciseId)")
public Iterable<Team> removeExerciseTeams(@PathVariable String exerciseId,
@Valid @RequestBody ExerciseUpdateTeamsInput input) {
Exercise exercise = this.exerciseService.exercise(exerciseId);
// Remove teams from exercise
List<Team> teams = exercise.getTeams().stream().filter(team -> !input.getTeamIds().contains(team.getId())).toList();
exercise.setTeams(new ArrayList<>(teams));
this.exerciseService.updateExercise(exercise);
// Remove all association between users / exercises / teams
input.getTeamIds().forEach(exerciseTeamUserRepository::deleteTeamFromAllReferences);
return teamRepository.findAllById(input.getTeamIds());
return this.exerciseService.removeTeams(exerciseId, input.getTeamIds());
}

@Transactional(rollbackOn = Exception.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import io.openbas.config.OpenBASConfig;
import io.openbas.database.model.*;
import io.openbas.database.repository.ArticleRepository;
import io.openbas.database.repository.ExerciseRepository;
import io.openbas.database.repository.*;
import io.openbas.rest.exception.ElementNotFoundException;
import io.openbas.database.repository.TeamRepository;
import io.openbas.rest.exercise.form.ExerciseSimple;
import io.openbas.rest.inject.service.InjectDuplicateService;
import io.openbas.service.GrantService;
Expand All @@ -20,7 +18,6 @@
import jakarta.persistence.Tuple;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.*;
import jakarta.transaction.Transactional;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
Expand All @@ -30,6 +27,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.Instant;
Expand Down Expand Up @@ -65,6 +63,8 @@ public class ExerciseService {
private final ArticleRepository articleRepository;
private final ExerciseRepository exerciseRepository;
private final TeamRepository teamRepository;
private final ExerciseTeamUserRepository exerciseTeamUserRepository;
private final InjectRepository injectRepository;

// region properties
@Value("${openbas.mail.imap.enabled}")
Expand Down Expand Up @@ -195,7 +195,7 @@ private List<ExerciseSimple> execution(TypedQuery<Tuple> query) {

// -- CREATION --

@Transactional(rollbackOn = Exception.class)
@Transactional(rollbackFor = Exception.class)
public Exercise createExercise(@NotNull final Exercise exercise){
if (imapEnabled) {
exercise.setFrom(imapUsername);
Expand Down Expand Up @@ -407,4 +407,20 @@ private void getObjectives(Exercise duplicatedExercise, Exercise originalExercis
duplicatedExercise.setObjectives(duplicatedObjectives);
}

// -- TEAMS --

@Transactional(rollbackFor = Exception.class)
public Iterable<Team> removeTeams(@NotBlank final String exerciseId, @NotNull final List<String> teamIds) {
Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(ElementNotFoundException::new);
// Remove teams from exercise
List<Team> teams = this.exerciseRepository.teams(exercise.getId(), teamIds);
exercise.setTeams(fromIterable(teams));
this.exerciseRepository.save(exercise);
// Remove all association between users / exercises / teams
teamIds.forEach(exerciseTeamUserRepository::deleteTeamFromAllReferences);
// Remove all association between injects and teams
this.injectRepository.removeTeams(teamIds);
return teamRepository.findAllById(teamIds);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public class ScenarioService {
private final TeamService teamService;
private final FileService fileService;
private final InjectDuplicateService injectDuplicateService;
private final InjectRepository injectRepository;

@Transactional
public Scenario createScenario(@NotNull final Scenario scenario) {
Expand Down Expand Up @@ -440,13 +441,16 @@ public Iterable<Team> addTeams(@NotBlank final String scenarioId, @NotNull final
return teamsToAdd;
}

@Transactional(rollbackFor = Exception.class)
public Iterable<Team> removeTeams(@NotBlank final String scenarioId, @NotNull final List<String> teamIds) {
Scenario scenario = this.scenario(scenarioId);
List<Team> teams = scenario.getTeams().stream().filter(team -> !teamIds.contains(team.getId())).toList();
List<Team> teams = this.scenarioRepository.teams(scenario.getId(), teamIds);
scenario.setTeams(new ArrayList<>(teams));
this.updateScenario(scenario);
// Remove all association between users / exercises / teams
teamIds.forEach(this.scenarioTeamUserRepository::deleteTeamFromAllReferences);
// Remove all association between injects and teams
this.injectRepository.removeTeams(teamIds);
return teamRepository.findAllById(teamIds);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package io.openbas.service;

import io.openbas.database.model.*;
import io.openbas.database.repository.ArticleRepository;
import io.openbas.database.repository.ExerciseRepository;
import io.openbas.database.repository.TeamRepository;
import io.openbas.database.repository.*;
import io.openbas.rest.exercise.ExerciseService;
import io.openbas.rest.inject.service.InjectDuplicateService;
import io.openbas.utils.fixtures.ExerciseFixture;
import jakarta.transaction.Transactional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.*;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -18,12 +15,16 @@
import java.util.ArrayList;
import java.util.List;

import static io.openbas.utils.fixtures.TeamFixture.getTeam;
import static io.openbas.injectors.email.EmailContract.EMAIL_DEFAULT;
import static io.openbas.utils.fixtures.ExerciseFixture.getExercise;
import static io.openbas.utils.fixtures.InjectFixture.getInjectForEmailContract;
import static io.openbas.utils.fixtures.TeamFixture.getTeam;
import static io.openbas.utils.fixtures.UserFixture.getUser;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;

@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class ExerciseServiceTest {
@Mock
GrantService grantService;
Expand All @@ -43,12 +44,33 @@ public class ExerciseServiceTest {
@Autowired
private TeamRepository teamRepository;

@Autowired
private UserRepository userRepository;
@Autowired
private InjectRepository injectRepository;
@Autowired
private ExerciseTeamUserRepository exerciseTeamUserRepository;
@Autowired
private InjectorContractRepository injectorContractRepository;

private static String USER_ID;
private static String TEAM_ID;
private static String INJECT_ID;

@InjectMocks
private ExerciseService exerciseService;
@BeforeEach
void setUp() {
exerciseService = new ExerciseService(grantService, injectService, injectDuplicateService,
teamService,variableService, articleRepository,exerciseRepository,teamRepository);
teamService,variableService, articleRepository,exerciseRepository,teamRepository,
exerciseTeamUserRepository, injectRepository);
}

@AfterAll
public void teardown() {
this.userRepository.deleteById(USER_ID);
this.teamRepository.deleteById(TEAM_ID);
this.injectRepository.deleteById(INJECT_ID);
}

@DisplayName("Should create new contextual teams while exercise duplication")
Expand Down Expand Up @@ -78,4 +100,36 @@ void createNewContextualTeamsWhileExerciseDuplication(){
}
});
}

@DisplayName("Should remove team from exercise")
@Test
void testRemoveTeams() {
// -- PREPARE --
User user = getUser();
User userSaved = this.userRepository.saveAndFlush(user);
USER_ID = userSaved.getId();
Team team = getTeam(user);
Team teamSaved = this.teamRepository.saveAndFlush(team);
TEAM_ID = teamSaved.getId();
Exercise exercise = ExerciseFixture.getExercise();
exercise.setTeams(List.of(teamSaved));
exercise.setFrom(user.getEmail());
Exercise exerciseSaved = this.exerciseRepository.saveAndFlush(exercise);

InjectorContract injectorContract = this.injectorContractRepository.findById(EMAIL_DEFAULT).orElseThrow();
Inject injectDefaultEmail = getInjectForEmailContract(injectorContract);
injectDefaultEmail.setExercise(exerciseSaved);
injectDefaultEmail.setTeams(List.of(teamSaved));
Inject injectDefaultEmailSaved = this.injectRepository.saveAndFlush(injectDefaultEmail);
INJECT_ID = injectDefaultEmailSaved.getId();

// -- EXECUTE --
this.exerciseService.removeTeams(exerciseSaved.getId(), List.of(teamSaved.getId()));

// -- ASSERT --
List<Team> teams = this.exerciseRepository.teams(exerciseSaved.getId(), List.of(TEAM_ID));
assertEquals(0, teams.size());
Inject injectAssert = this.injectRepository.findById(INJECT_ID).orElseThrow();
assertEquals(0, injectAssert.getTeams().size());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@
import io.openbas.database.repository.*;
import io.openbas.rest.inject.service.InjectDuplicateService;
import io.openbas.utils.fixtures.ScenarioFixture;
import jakarta.transaction.Transactional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
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.context.SpringBootTest;
import static io.openbas.utils.fixtures.TeamFixture.getTeam;
import static io.openbas.utils.fixtures.ScenarioFixture.getScenario;

import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static io.openbas.injectors.email.EmailContract.EMAIL_DEFAULT;
import static io.openbas.utils.fixtures.InjectFixture.getInjectForEmailContract;
import static io.openbas.utils.fixtures.TeamFixture.getTeam;
import static io.openbas.utils.fixtures.UserFixture.getUser;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;

@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class ScenarioServiceTest {

@Autowired
Expand Down Expand Up @@ -51,22 +54,33 @@ public class ScenarioServiceTest {
FileService fileService;
@Autowired
private InjectDuplicateService injectDuplicateService;

@Autowired
private InjectorContractRepository injectorContractRepository;

@InjectMocks
private ScenarioService scenarioService;

private static String USER_ID;
private static String TEAM_ID;
private static String INJECT_ID;

@BeforeEach
void setUp() {
scenarioService = new ScenarioService(scenarioRepository, teamRepository, userRepository, documentRepository,
scenarioTeamUserRepository, articleRepository, grantService, variableService, challengeService,
teamService, fileService, injectDuplicateService
teamService, fileService, injectDuplicateService, injectRepository
);
}

@AfterAll
public void teardown() {
this.userRepository.deleteById(USER_ID);
this.teamRepository.deleteById(TEAM_ID);
this.injectRepository.deleteById(INJECT_ID);
}

@DisplayName("Should create new contextual teams during scenario duplication")
@Test
@Transactional(rollbackOn = Exception.class)
void createNewContextualTeamsDuringScenarioDuplication(){
// -- PREPARE --
List<Team> scenarioTeams = new ArrayList<>();;
Expand Down Expand Up @@ -110,4 +124,36 @@ void createNewContextualTeamsDuringScenarioDuplication(){
}
});
}

@DisplayName("Should remove team from scenario")
@Test
void testRemoveTeams() {
// -- PREPARE --
User user = getUser();
User userSaved = this.userRepository.saveAndFlush(user);
USER_ID = userSaved.getId();
Team team = getTeam(user);
Team teamSaved = this.teamRepository.saveAndFlush(team);
TEAM_ID = teamSaved.getId();
Scenario scenario = ScenarioFixture.getScenario();
scenario.setTeams(List.of(teamSaved));
Scenario scenarioSaved = this.scenarioRepository.saveAndFlush(scenario);

InjectorContract injectorContract = this.injectorContractRepository.findById(EMAIL_DEFAULT).orElseThrow();
Inject injectDefaultEmail = getInjectForEmailContract(injectorContract);
injectDefaultEmail.setScenario(scenarioSaved);
injectDefaultEmail.setTeams(List.of(teamSaved));
Inject injectDefaultEmailSaved = this.injectRepository.saveAndFlush(injectDefaultEmail);
INJECT_ID = injectDefaultEmailSaved.getId();

// -- EXECUTE --
this.scenarioService.removeTeams(scenarioSaved.getId(), List.of(teamSaved.getId()));

// -- ASSERT --
List<Team> teams = this.scenarioRepository.teams(scenarioSaved.getId(), List.of(TEAM_ID));
assertEquals(0, teams.size());
Inject injectAssert = this.injectRepository.findById(INJECT_ID).orElseThrow();
assertEquals(0, injectAssert.getTeams().size());
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package io.openbas.database.repository;

import io.openbas.database.model.Exercise;
import io.openbas.database.model.Team;
import io.openbas.database.raw.RawExercise;
import io.openbas.database.raw.RawGlobalInjectExpectation;
import io.openbas.database.raw.RawInjectExpectation;
import jakarta.validation.constraints.NotNull;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
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;

Expand All @@ -16,7 +17,7 @@
import java.util.Optional;

@Repository
public interface ExerciseRepository extends CrudRepository<Exercise, String>,
public interface ExerciseRepository extends JpaRepository<Exercise, String>,
StatisticRepository,
JpaSpecificationExecutor<Exercise> {

Expand Down Expand Up @@ -186,4 +187,14 @@ public interface ExerciseRepository extends CrudRepository<Exercise, String>,
"WHERE ex.exercise_id = :exerciseId " +
"GROUP BY ex.exercise_id, inj.inject_scenario, se.scenario_id ;", nativeQuery = true)
RawExercise rawDetailsById(@Param("exerciseId") String exerciseId);

// -- TEAM --

@Query(value = "SELECT t.* "
+ "FROM teams t "
+ "JOIN exercises_teams et ON t.team_id = et.team_id "
+ "WHERE et.exercise_id = :exerciseId "
+ " AND t.team_id NOT IN (:teamIds) ", nativeQuery = true)
List<Team> teams(@Param("exerciseId") final String exerciseId, @Param("teamIds") final List<String> teamIds);

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
Expand All @@ -26,6 +27,7 @@ public interface ExerciseTeamUserRepository extends CrudRepository<ExerciseTeamU

@Modifying
@Query(value = "delete from exercises_teams_users i where i.team_id = :teamId", nativeQuery = true)
@Transactional
void deleteTeamFromAllReferences(@Param("teamId") String teamId);

@Modifying
Expand Down
Loading

0 comments on commit 8d5e4b3

Please sign in to comment.