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

[frontend/backend] add inject result inside report #1519

Merged
merged 12 commits into from
Oct 3, 2024
15 changes: 15 additions & 0 deletions openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,21 @@
));
}

@GetMapping(EXERCISE_URI + "/{exerciseId}/injects/resultdto")
@PreAuthorize("isExerciseObserver(#exerciseId)")
@Transactional(readOnly = true)
public List<InjectResultDTO> exerciseInjectsWithExpectations(@PathVariable final String exerciseId) {
return this.injectRepository.findAll(InjectSpecification.fromExercise(exerciseId)).stream()
.map(inject -> AtomicTestingMapper.toDto(
inject, getTargets(
inject.getTeams(),
inject.getAssets(),
inject.getAssetGroups()

Check warning on line 222 in openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java#L217-L222

Added lines #L217 - L222 were not covered by tests
)
))
.collect(Collectors.toList());

Check warning on line 225 in openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java#L225

Added line #L225 was not covered by tests
}

@GetMapping(EXERCISE_URI + "/{exerciseId}/injects/{injectId}")
@PreAuthorize("isExerciseObserver(#exerciseId)")
public Inject exerciseInject(@PathVariable String exerciseId, @PathVariable String injectId) {
Expand Down
14 changes: 14 additions & 0 deletions openbas-api/src/main/java/io/openbas/rest/report/ReportApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import io.openbas.database.model.*;
import io.openbas.rest.exercise.ExerciseService;
import io.openbas.rest.helper.RestBehavior;
import io.openbas.rest.report.form.ReportInjectCommentInput;
import io.openbas.rest.report.form.ReportInput;
import io.openbas.service.InjectService;
import io.openbas.service.ReportService;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
Expand All @@ -23,6 +25,7 @@ public class ReportApi extends RestBehavior {

private final ExerciseService exerciseService;
private final ReportService reportService;
private final InjectService injectService;

@GetMapping("/api/reports/{reportId}")
savacano28 marked this conversation as resolved.
Show resolved Hide resolved
@PreAuthorize("isObserver()")
Expand All @@ -46,6 +49,17 @@ public Report createExerciseReport(@PathVariable String exerciseId, @Valid @Requ
return this.reportService.updateReport(report, input);
}

@PutMapping("/api/exercises/{exerciseId}/reports/{reportId}/inject-comments")
@PreAuthorize("isExercisePlanner(#exerciseId)")
@Transactional(rollbackOn = Exception.class)
public Iterable<ReportInjectComment> updateReportInjectComment(@PathVariable String exerciseId, @PathVariable String reportId, @Valid @RequestBody ReportInjectCommentInput input) {
Report report = this.reportService.report(UUID.fromString(reportId));
assert exerciseId.equals(report.getExercise().getId());
Inject inject = this.injectService.inject(input.getInjectId());
assert exerciseId.equals(inject.getExercise().getId());
return this.reportService.updateReportInjectComment(report, inject, input);
}

@PutMapping("/api/exercises/{exerciseId}/reports/{reportId}")
@PreAuthorize("isExercisePlanner(#exerciseId)")
@Transactional(rollbackOn = Exception.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.openbas.rest.report.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;

import static io.openbas.config.AppConfig.MANDATORY_MESSAGE;

@Data
public class ReportInjectCommentInput {
@NotBlank(message = MANDATORY_MESSAGE)
@JsonProperty("inject_id")
private String injectId;

@JsonProperty("report_inject_comment")
private String comment;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.*;
import jakarta.transaction.Transactional;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import lombok.extern.java.Log;
import org.apache.commons.io.FilenameUtils;
Expand Down Expand Up @@ -145,6 +146,11 @@
}
}

public Inject inject(@NotBlank final String injectId) {
return this.injectRepository.findById(injectId)
.orElseThrow(() -> new ElementNotFoundException("Inject not found"));

Check warning on line 151 in openbas-api/src/main/java/io/openbas/service/InjectService.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/service/InjectService.java#L150-L151

Added lines #L150 - L151 were not covered by tests
}

@Tracing(name = "Fetch injects with criteria builder", layer = "service", operation = "GET")
public List<InjectOutput> injects(Specification<Inject> specification) {
CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
Expand Down
32 changes: 32 additions & 0 deletions openbas-api/src/main/java/io/openbas/service/ReportService.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package io.openbas.service;

import io.openbas.database.model.Inject;
import io.openbas.database.model.Report;
import io.openbas.database.model.ReportInformation;
import io.openbas.database.model.ReportInjectComment;
import io.openbas.database.repository.ReportRepository;
import io.openbas.database.specification.ReportSpecification;
import io.openbas.rest.exception.ElementNotFoundException;
import io.openbas.rest.report.form.ReportInjectCommentInput;
import io.openbas.rest.report.form.ReportInput;
import jakarta.persistence.EntityManager;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
Expand All @@ -20,6 +24,7 @@
@Service
public class ReportService {
private final ReportRepository reportRepository;
private final EntityManager entityManager;

public Report report(@NotNull final UUID reportId) {
return this.reportRepository.findById(reportId).orElseThrow(ElementNotFoundException::new);
Expand Down Expand Up @@ -50,6 +55,33 @@ public Report updateReport(@NotNull final Report report, @NotNull final ReportIn
return this.reportRepository.save(report);
}

public List<ReportInjectComment> updateReportInjectComment(@NotNull final Report report, @NotNull final Inject inject, @NotNull final ReportInjectCommentInput input){
ReportInjectComment reportInjectComment = findReportInjectComment(report.getId(), inject.getId());

if (reportInjectComment != null) {
reportInjectComment.setComment(input.getComment());
} else {
reportInjectComment = new ReportInjectComment();
reportInjectComment.setInject(inject);
reportInjectComment.setReport(report);
reportInjectComment.setComment(input.getComment());
report.getReportInjectsComments().add(reportInjectComment);
}
this.reportRepository.save(report);
return report.getReportInjectsComments();
}

private ReportInjectComment findReportInjectComment(String reportId, String injectId) {
String jpql = "SELECT r FROM ReportInjectComment r WHERE r.report.id = :reportId AND r.inject.id = :injectId";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be better to have this directly in the ReportRepository

@Query(value = "SELECT r FROM ReportInjectComment r WHERE r.report.id = :reportId AND r.inject.id = :injectId", nativeQuery = true)
Optional<ReportInjectComment> method(@Param("PARAM")...);


return this.entityManager.createQuery(jpql, ReportInjectComment.class)
.setParameter("reportId", UUID.fromString(reportId))
.setParameter("injectId", injectId)
.getResultStream()
.findFirst()
.orElse(null);
savacano28 marked this conversation as resolved.
Show resolved Hide resolved
}

public void deleteReport(@NotBlank final UUID reportId) {
this.reportRepository.deleteById(reportId);
}
Expand Down
43 changes: 42 additions & 1 deletion openbas-api/src/test/java/io/openbas/rest/ReportApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import io.openbas.rest.exercise.ExerciseService;
import io.openbas.rest.mapper.MapperApi;
import io.openbas.rest.report.ReportApi;
import io.openbas.rest.report.form.ReportInjectCommentInput;
import io.openbas.rest.report.form.ReportInput;
import io.openbas.service.InjectService;
import io.openbas.service.ReportService;
import io.openbas.utils.fixtures.PaginationFixture;
import io.openbas.utils.mockUser.WithMockPlannerUser;
Expand All @@ -21,6 +23,7 @@
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

Expand All @@ -44,6 +47,8 @@ public class ReportApiTest {
private ReportService reportService;
@Mock
private ExerciseService exerciseService;
@Mock
private InjectService injectService;

@Autowired
private ObjectMapper objectMapper;
Expand All @@ -54,7 +59,7 @@ public class ReportApiTest {

@BeforeEach
void before() throws IllegalAccessException, NoSuchFieldException {
ReportApi reportApi = new ReportApi(exerciseService, reportService);
ReportApi reportApi = new ReportApi(exerciseService, reportService, injectService);
Field sessionContextField = MapperApi.class.getSuperclass().getDeclaredField("mapper");
sessionContextField.setAccessible(true);
sessionContextField.set(reportApi, objectMapper);
Expand Down Expand Up @@ -149,6 +154,42 @@ void updateReportForExercise() throws Exception {
assertEquals(JsonPath.read(response, "$.report_id"), report.getId());
}

@DisplayName("Update report inject comment")
@Test
void updateReportInjectCommentTest() throws Exception {
// -- PREPARE --
Inject inject = new Inject();
inject.setTitle("Test inject");
inject.setId(UUID.randomUUID().toString());
inject.setExercise(exercise);
report.setExercise(exercise);
ReportInjectCommentInput injectCommentInput = new ReportInjectCommentInput();
injectCommentInput.setInjectId(inject.getId());
injectCommentInput.setComment("Comment test");

when(reportService.report(any())).thenReturn(report);
when(injectService.inject(any())).thenReturn(inject);
when(reportService.updateReportInjectComment(any(Report.class), any(Inject.class), any(ReportInjectCommentInput.class)))
.thenReturn(null);

// -- EXECUTE --
String response = mvc
.perform(MockMvcRequestBuilders.put("/api/exercises/"+ exercise.getId() +"/reports/"+ report.getId()+"/inject-comments")
.content(asJsonString(injectCommentInput))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().is2xxSuccessful())
.andReturn()
.getResponse()
.getContentAsString();

// -- ASSERT --
verify(reportService).report(UUID.fromString(report.getId()));
verify(injectService).inject(inject.getId());
verify(reportService).updateReportInjectComment(report, inject, injectCommentInput);
assertNotNull(response);
}

@DisplayName("Delete Report")
@Test
void deleteReportForExercise() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package io.openbas.service;

import io.openbas.database.model.Report;
import io.openbas.database.model.ReportInformation;
import io.openbas.database.model.ReportInformationsType;
import io.openbas.database.model.*;
import io.openbas.database.repository.ReportRepository;
import io.openbas.rest.report.form.ReportInformationInput;
import io.openbas.rest.report.form.ReportInjectCommentInput;
import io.openbas.rest.report.form.ReportInput;
import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
Expand All @@ -16,9 +18,10 @@
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand All @@ -28,13 +31,17 @@ public class ReportServiceTest {

@Mock
private ReportRepository reportRepository;
@Mock
private EntityManager entityManager;
@Mock
private TypedQuery<ReportInjectComment> reportInjectCommentQuery;

private ReportService reportService;

@BeforeEach
void before() {
// Injecting mocks into the controller
reportService = new ReportService(reportRepository);
reportService = new ReportService(reportRepository, entityManager);
}

@DisplayName("Test create a report")
Expand Down Expand Up @@ -99,7 +106,7 @@ void updateReport() throws Exception {
when(reportRepository.save(any(Report.class))).thenReturn(report);

// -- EXECUTE --
reportService.updateReport(report, reportInput);
reportService.updateReport(report, reportInput);

// -- ASSERT --
ArgumentCaptor<Report> reportCaptor = ArgumentCaptor.forClass(Report.class);
Expand All @@ -109,6 +116,80 @@ void updateReport() throws Exception {
assertEquals(1, capturedReport.getReportInformations().size());
assertEquals(true, capturedReport.getReportInformations().getFirst().getReportInformationsDisplay());
}

@Nested
@DisplayName("Reports inject comment")
class ReportInjectCommentTest {
@DisplayName("Test update existing report inject comment")
@Test
void updateExistingReportInjectComment() {
// -- PREPARE --
Report report = new Report();
report.setName("test");
report.setId(UUID.randomUUID().toString());
Inject inject = new Inject();
inject.setId("fakeID123");

// add report inject comment
ReportInjectComment existingReportInjectComment = new ReportInjectComment();
existingReportInjectComment.setReport(report);
existingReportInjectComment.setComment("comment");
existingReportInjectComment.setInject(inject);
report.setReportInjectsComments(List.of(existingReportInjectComment));

ReportInjectCommentInput commentInput = new ReportInjectCommentInput();
commentInput.setInjectId(inject.getId());
commentInput.setComment("New comment");

// Mock
when(entityManager.createQuery(anyString(), eq(ReportInjectComment.class))).thenReturn(reportInjectCommentQuery);
when(reportInjectCommentQuery.setParameter(eq("reportId"), eq(UUID.fromString(report.getId())))).thenReturn(reportInjectCommentQuery);
when(reportInjectCommentQuery.setParameter(eq("injectId"), eq(inject.getId()))).thenReturn(reportInjectCommentQuery);
when(reportInjectCommentQuery.getResultStream()).thenReturn(java.util.stream.Stream.of(existingReportInjectComment));

// -- EXECUTE --
reportService.updateReportInjectComment(report, inject, commentInput);

// -- ASSERT --
ArgumentCaptor<Report> reportCaptor = ArgumentCaptor.forClass(Report.class);
verify(reportRepository).save(reportCaptor.capture());
Report capturedReport= reportCaptor.getValue();
assertEquals(1, capturedReport.getReportInjectsComments().size());
assertEquals(commentInput.getComment(), capturedReport.getReportInjectsComments().getFirst().getComment());
}

@DisplayName("Test add new report inject comment")
@Test
void addReportInjectComment() throws Exception {
// -- PREPARE --
Report report = new Report();
report.setName("test");
report.setId(UUID.randomUUID().toString());
Inject inject = new Inject();
inject.setId("fakeID123");

ReportInjectCommentInput commentInput = new ReportInjectCommentInput();
commentInput.setInjectId(inject.getId());
commentInput.setComment("New test comment");

// Mock
when(reportRepository.save(any(Report.class))).thenReturn(report);
when(entityManager.createQuery(anyString(), eq(ReportInjectComment.class))).thenReturn(reportInjectCommentQuery);
when(reportInjectCommentQuery.setParameter(eq("reportId"), eq(UUID.fromString(report.getId())))).thenReturn(reportInjectCommentQuery);
when(reportInjectCommentQuery.setParameter(eq("injectId"), eq(inject.getId()))).thenReturn(reportInjectCommentQuery);
when(reportInjectCommentQuery.getResultStream()).thenReturn(java.util.stream.Stream.of());

// -- EXECUTE --
reportService.updateReportInjectComment(report, inject, commentInput);

// -- ASSERT --
ArgumentCaptor<Report> reportCaptor = ArgumentCaptor.forClass(Report.class);
verify(reportRepository).save(reportCaptor.capture());
Report capturedReport= reportCaptor.getValue();
assertEquals(1, capturedReport.getReportInjectsComments().size());
assertEquals(commentInput.getComment(), capturedReport.getReportInjectsComments().getFirst().getComment());
}
}
}


Expand Down
5 changes: 5 additions & 0 deletions openbas-front/src/actions/exercises/exercise-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ export const searchExerciseInjects = (exerciseId: Exercise['exercise_id'], searc
return simplePostCall(uri, data);
};

export const exerciseInjectsResultDTO = (exerciseId: Exercise['exercise_id']) => {
const uri = `${EXERCISE_URI}${exerciseId}/injects/resultdto`;
return simpleCall(uri);
};

// -- IMPORT --

export const importXlsForExercise = (exerciseId: Exercise['exercise_id'], importId: string, input: InjectsImportInput) => {
Expand Down
Loading