Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[backend] test injects execution (#1486) #1690

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
150 changes: 150 additions & 0 deletions openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java
Original file line number Diff line number Diff line change
@@ -1,37 +1,59 @@
package io.openbas.rest;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.jayway.jsonpath.JsonPath;
import io.openbas.IntegrationTest;
import io.openbas.database.model.InjectorContract;
import io.openbas.database.model.*;
import io.openbas.database.repository.*;
import io.openbas.rest.exercise.service.ExerciseService;
import io.openbas.rest.inject.form.DirectInjectInput;
import io.openbas.rest.inject.form.InjectInput;
import io.openbas.service.ScenarioService;
import io.openbas.utils.fixtures.InjectExpectationFixture;
import io.openbas.utils.mockUser.WithMockObserverUser;
import io.openbas.utils.mockUser.WithMockPlannerUser;
import jakarta.annotation.Resource;
import jakarta.mail.internet.MimeMessage;
import jakarta.servlet.ServletException;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentMatchers;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.time.Instant;
import java.util.List;

import static io.openbas.config.SessionHelper.currentUser;
import static io.openbas.database.model.ExerciseStatus.RUNNING;
import static io.openbas.injectors.email.EmailContract.EMAIL_DEFAULT;
import static io.openbas.rest.exercise.ExerciseApi.EXERCISE_URI;
import static io.openbas.rest.inject.InjectApi.INJECT_URI;
import static io.openbas.rest.scenario.ScenarioApi.SCENARIO_URI;
import static io.openbas.utils.JsonUtils.asJsonString;
import static io.openbas.utils.fixtures.InjectFixture.getInjectForEmailContract;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@TestInstance(PER_CLASS)
@ExtendWith(MockitoExtension.class)
class InjectApiTest extends IntegrationTest {

static Exercise EXERCISE;
Expand Down Expand Up @@ -63,6 +85,12 @@ class InjectApiTest extends IntegrationTest {
private TeamRepository teamRepository;
@Autowired
private InjectorContractRepository injectorContractRepository;
@Autowired
private UserRepository userRepository;
@Resource
private ObjectMapper objectMapper;
@MockBean
private JavaMailSender javaMailSender;

@BeforeAll
void beforeAll() {
Expand Down Expand Up @@ -327,6 +355,128 @@ void updateInjectForSimulationTest() throws Exception {
assertEquals(injectTitle, JsonPath.read(response, "$.inject_title"));
}

@DisplayName("Execute an email inject for exercise")
@Test
@WithMockPlannerUser
void executeEmailInjectForExerciseTest() throws Exception {
// -- PREPARE --
InjectorContract injectorContract = this.injectorContractRepository.findById(EMAIL_DEFAULT).orElseThrow();
Inject inject = getInjectForEmailContract(injectorContract);
User user = userRepository.findById(currentUser().getId()).orElseThrow();
DirectInjectInput input = new DirectInjectInput();
input.setTitle(inject.getTitle());
input.setDescription(inject.getDescription());
input.setInjectorContract(inject.getInjectorContract().orElseThrow().getId());
input.setUserIds(List.of(user.getId()));
ObjectNode content = objectMapper.createObjectNode();
content.set("subject", objectMapper.convertValue("Subject", JsonNode.class));
content.set("body", objectMapper.convertValue("Test body", JsonNode.class));
content.set("expectationType", objectMapper.convertValue("none", JsonNode.class));
input.setContent(content);

MockMultipartFile inputJson = new MockMultipartFile("input", null, "application/json",
objectMapper.writeValueAsString(input).getBytes());

// Getting a test file
File testFile = ResourceUtils.getFile("classpath:xls-test-files/test_file_1.xlsx");
InputStream in = new FileInputStream(testFile);
MockMultipartFile fileJson = new MockMultipartFile("file",
"my-awesome-file.xls",
"application/xlsx",
in.readAllBytes());

// Mock the behavior of JavaMailSender
doNothing().when(javaMailSender).send(ArgumentMatchers.any(SimpleMailMessage.class));
MimeMessage mimeMessage = mock(MimeMessage.class);
when(javaMailSender.createMimeMessage()).thenReturn(mimeMessage);

// -- EXECUTE --
String response = mvc.perform(multipart(EXERCISE_URI + "/" + EXERCISE.getId() + "/inject")
.file(inputJson)
.file(fileJson))
.andExpect(status().is2xxSuccessful())
.andReturn()
.getResponse()
.getContentAsString();

// -- ASSERT --
assertNotNull(response);
assertEquals("SUCCESS", JsonPath.read(response, "$.status_name"));

//-- THEN ---
userRepository.delete(user);

}

@DisplayName("Execute an email inject for exercise with no team")
@Test
@WithMockPlannerUser
void executeEmailInjectForExerciseWithNoTeam() throws Exception {
// -- PREPARE --
InjectorContract injectorContract = this.injectorContractRepository.findById(EMAIL_DEFAULT).orElseThrow();
Inject inject = getInjectForEmailContract(injectorContract);
User user = userRepository.findById(currentUser().getId()).orElseThrow();
DirectInjectInput input = new DirectInjectInput();
input.setTitle(inject.getTitle());
input.setDescription(inject.getDescription());
input.setInjectorContract(inject.getInjectorContract().orElseThrow().getId());
ObjectNode content = objectMapper.createObjectNode();
content.set("subject", objectMapper.convertValue("Subject", JsonNode.class));
content.set("body", objectMapper.convertValue("Test body", JsonNode.class));
content.set("expectationType", objectMapper.convertValue("none", JsonNode.class));
input.setContent(content);

MockMultipartFile inputJson = new MockMultipartFile("input", null, "application/json",
objectMapper.writeValueAsString(input).getBytes());

// -- EXECUTE --
String response = mvc.perform(multipart(EXERCISE_URI + "/" + EXERCISE.getId() + "/inject")
.file(inputJson))
.andExpect(status().is2xxSuccessful())
.andReturn()
.getResponse()
.getContentAsString();

// -- ASSERT --
assertNotNull(response);
assertEquals("ERROR", JsonPath.read(response, "$.status_name"));
assertEquals("Email needs at least one user", JsonPath.read(response, "$.status_traces[0].execution_message"));

//-- THEN ---
userRepository.delete(user);
}

@DisplayName("Execute an email inject for exercise with no content")
@Test
@WithMockPlannerUser
void executeEmailInjectForExerciseWithNoContentTest() throws Exception {
// -- PREPARE --
InjectorContract injectorContract = this.injectorContractRepository.findById(EMAIL_DEFAULT).orElseThrow();
Inject inject = getInjectForEmailContract(injectorContract);
User user = userRepository.findById(currentUser().getId()).orElseThrow();
DirectInjectInput input = new DirectInjectInput();
input.setTitle(inject.getTitle());
input.setDescription(inject.getDescription());
input.setInjectorContract(inject.getInjectorContract().orElseThrow().getId());
input.setUserIds(List.of(user.getId()));

MockMultipartFile inputJson = new MockMultipartFile("input", null, "application/json",
objectMapper.writeValueAsString(input).getBytes());

//-- ASSERT
Exception exception = assertThrows(ServletException.class,
() -> mvc.perform(multipart(EXERCISE_URI + "/" + EXERCISE.getId() + "/inject")
.file(inputJson)));

String expectedMessage = "Inject is empty";
String actualMessage = exception.getMessage();

assertTrue(actualMessage.contains(expectedMessage));

//-- THEN ---
userRepository.delete(user);
}

// -- BULK DELETE --

@DisplayName("Delete list of inject for exercise")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,49 @@

public class ExerciseFixture {

public static final String EXERCISE_NAME = "Exercise test";
public static final String EXERCISE_NAME = "Exercise test";

public static Exercise getExercise() {
return getExercise(null);
}

public static Exercise getExercise(List<Team> exerciseTeams) {
Exercise exercise = new Exercise();
exercise.setName(EXERCISE_NAME);
if(exerciseTeams != null){
exercise.setTeams(exerciseTeams);
}
return exercise;
}

public static Exercise createDefaultCrisisExercise() {
Exercise exercise = new Exercise();
exercise.setName("Crisis exercise");
exercise.setDescription("A crisis exercise for my enterprise");
exercise.setSubtitle("A crisis exercise");
exercise.setFrom("exercise@mail.fr");
exercise.setCategory("crisis-communication");
return exercise;
}
public static Exercise getExercise() {
return getExercise(null);
}

public static Exercise createDefaultIncidentResponseExercise() {
Exercise exercise = new Exercise();
exercise.setName("Incident response exercise");
exercise.setDescription("An incident response exercise for my enterprise");
exercise.setSubtitle("An incident response exercise");
exercise.setFrom("exercise@mail.fr");
exercise.setCategory("incident-response");
exercise.setStatus(ExerciseStatus.SCHEDULED);
exercise.setStart(Instant.now());
return exercise;
public static Exercise getExercise(List<Team> exerciseTeams) {
Exercise exercise = new Exercise();
exercise.setName(EXERCISE_NAME);
if (exerciseTeams != null) {
exercise.setTeams(exerciseTeams);
}
return exercise;
}

public static Exercise createDefaultCrisisExercise() {
Exercise exercise = new Exercise();
exercise.setName("Crisis exercise");
exercise.setDescription("A crisis exercise for my enterprise");
exercise.setSubtitle("A crisis exercise");
exercise.setFrom("exercise@mail.fr");
exercise.setCategory("crisis-communication");
return exercise;
}

public static Exercise createDefaultIncidentResponseExercise() {
Exercise exercise = new Exercise();
exercise.setName("Incident response exercise");
exercise.setDescription("An incident response exercise for my enterprise");
exercise.setSubtitle("An incident response exercise");
exercise.setFrom("exercise@mail.fr");
exercise.setCategory("incident-response");
exercise.setStatus(ExerciseStatus.SCHEDULED);
exercise.setStart(Instant.now());
return exercise;
}

/*
_ create exercise with team containing a user with email (user enabled)
_ create exercise with team containing a user with email (user not enabled)
_ create exercise without team
_ create exercise with team without user
_ create email
*/

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
import io.openbas.database.model.Inject;
import io.openbas.database.model.InjectorContract;

import static io.openbas.injectors.email.EmailContract.TYPE;

public class InjectFixture {

public static final String INJECT_EMAIL_NAME = "Test email inject";
public static final String INJECT_EMAIL_NAME = "Test email inject";

public static Inject getInjectForEmailContract(InjectorContract injectorContract) {
Inject inject = new Inject();
inject.setTitle(INJECT_EMAIL_NAME);
inject.setInjectorContract(injectorContract);
inject.setEnabled(true);
inject.setDependsDuration(0L);
return inject;
}

public static Inject getInjectForEmailContract(InjectorContract injectorContract) {
Inject inject = new Inject();
inject.setTitle(INJECT_EMAIL_NAME);
inject.setInjectorContract(injectorContract);
inject.setEnabled(true);
inject.setDependsDuration(0L);
return inject;
}
}
Loading