Skip to content

Commit

Permalink
[backend/frontend] Improve UI of score settings/validation (#1198)
Browse files Browse the repository at this point in the history
  • Loading branch information
johanah29 authored Sep 16, 2024
1 parent 5ef7a1a commit bd65d3e
Show file tree
Hide file tree
Showing 13 changed files with 736 additions and 515 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.openbas.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.Statement;

@Component
public class V3_36__Alter_inject_expectation_score extends BaseJavaMigration {

@Override
public void migrate(Context context) throws Exception {
Connection connection = context.getConnection();
Statement select = connection.createStatement();
select.execute(
"ALTER TABLE injects_expectations ALTER COLUMN inject_expectation_expected_score SET NOT NULL,\n"
+ "ALTER COLUMN inject_expectation_expected_score SET DEFAULT 100;");
}
}
640 changes: 315 additions & 325 deletions openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.openbas.database.model.Team;
import io.openbas.database.repository.*;
import io.openbas.rest.exercise.form.ExpectationUpdateInput;
import io.openbas.utils.fixtures.InjectExpectationFixture;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
Expand All @@ -26,96 +27,91 @@
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class ExerciseExpectationServiceTest {

public static final String EXPECTATION_NAME = "The animation team can validate the audience reaction";
@Autowired
private ExerciseExpectationService exerciseExpectationService;

@Autowired
private ExerciseRepository exerciseRepository;

@Autowired
private InjectRepository injectRepository;

@Autowired
private TeamRepository teamRepository;

@Autowired
private InjectExpectationRepository injectExpectationRepository;

@Autowired
private InjectorContractRepository injectorContractRepository;

static String EXERCISE_ID;

@BeforeAll
void beforeAll() {
Exercise exerciseCreated = getExercise();
EXERCISE_ID = exerciseCreated.getId();
Team teamCreated = getTeam();
Inject injectCreated = getInject(exerciseCreated);
getInjectExpectation(injectCreated, teamCreated, exerciseCreated);
}

@DisplayName("Retrieve inject expectations")
@Test
void retrieveInjectExpectations() {
List<InjectExpectation> expectations = this.exerciseExpectationService.injectExpectations(EXERCISE_ID);
assertNotNull(expectations);

assertEquals(EXPECTATION_NAME, expectations.getFirst().getName());
}

@DisplayName("Update inject expectation")
@Test
void updateInjectExpectation() {
// -- PREPARE --
List<InjectExpectation> expectations = this.exerciseExpectationService.injectExpectations(EXERCISE_ID);
assertNotNull(expectations);
String id = expectations.getFirst().getId();

// -- EXECUTE --
ExpectationUpdateInput input = new ExpectationUpdateInput();
input.setScore(7.0);
InjectExpectation expectation = this.exerciseExpectationService.updateInjectExpectation(id, input);

// -- ASSERT --
assertNotNull(expectation);
assertEquals(7, expectation.getScore());
}

protected Exercise getExercise() {
Exercise exercise = new Exercise();
exercise.setName("Exercice name");
exercise.setStatus(SCHEDULED);
exercise.setFrom("test@test.com");
exercise.setReplyTos(List.of("test@test.com"));
exercise.setStart(Instant.now());
return this.exerciseRepository.save(exercise);
}

private Team getTeam() {
Team team = new Team();
team.setName("test");
return this.teamRepository.save(team);
}

private Inject getInject(Exercise exerciseCreated) {
Inject inject = new Inject();
inject.setTitle("test");
inject.setInjectorContract(this.injectorContractRepository.findById(EMAIL_DEFAULT).orElseThrow());
inject.setExercise(exerciseCreated);
inject.setDependsDuration(0L);
return this.injectRepository.save(inject);
}

private void getInjectExpectation(Inject injectCreated, Team teamCreated, Exercise exerciseCreated) {
InjectExpectation expectation = new InjectExpectation();
expectation.setInject(injectCreated);
expectation.setTeam(teamCreated);
expectation.setType(MANUAL);
expectation.setName(EXPECTATION_NAME);
expectation.setExpectedScore(10.0);
expectation.setExercise(exerciseCreated);
this.injectExpectationRepository.save(expectation);
}
public static final String EXPECTATION_NAME = "The animation team can validate the audience reaction";
@Autowired
private ExerciseExpectationService exerciseExpectationService;

@Autowired
private ExerciseRepository exerciseRepository;

@Autowired
private InjectRepository injectRepository;

@Autowired
private TeamRepository teamRepository;

@Autowired
private InjectExpectationRepository injectExpectationRepository;

@Autowired
private InjectorContractRepository injectorContractRepository;

static String EXERCISE_ID;

@BeforeAll
void beforeAll() {
Exercise exerciseCreated = getExercise();
EXERCISE_ID = exerciseCreated.getId();
Team teamCreated = getTeam();
Inject injectCreated = getInject(exerciseCreated);
getInjectExpectation(injectCreated, teamCreated, exerciseCreated);
}

@DisplayName("Retrieve inject expectations")
@Test
void retrieveInjectExpectations() {
List<InjectExpectation> expectations = this.exerciseExpectationService.injectExpectations(EXERCISE_ID);
assertNotNull(expectations);

assertEquals(EXPECTATION_NAME, expectations.getFirst().getName());
}

@DisplayName("Update inject expectation")
@Test
void updateInjectExpectation() {
// -- PREPARE --
List<InjectExpectation> expectations = this.exerciseExpectationService.injectExpectations(EXERCISE_ID);
assertNotNull(expectations);
String id = expectations.getFirst().getId();

// -- EXECUTE --
ExpectationUpdateInput input = new ExpectationUpdateInput();
input.setScore(7.0);
InjectExpectation expectation = this.exerciseExpectationService.updateInjectExpectation(id, input);

// -- ASSERT --
assertNotNull(expectation);
assertEquals(7, expectation.getScore());
}

protected Exercise getExercise() {
Exercise exercise = new Exercise();
exercise.setName("Exercice name");
exercise.setStatus(SCHEDULED);
exercise.setFrom("test@test.com");
exercise.setReplyTos(List.of("test@test.com"));
exercise.setStart(Instant.now());
return this.exerciseRepository.save(exercise);
}

private Team getTeam() {
Team team = new Team();
team.setName("test");
return this.teamRepository.save(team);
}

private Inject getInject(Exercise exerciseCreated) {
Inject inject = new Inject();
inject.setTitle("test");
inject.setInjectorContract(this.injectorContractRepository.findById(EMAIL_DEFAULT).orElseThrow());
inject.setExercise(exerciseCreated);
inject.setDependsDuration(0L);
return this.injectRepository.save(inject);
}

private void getInjectExpectation(Inject injectCreated, Team teamCreated, Exercise exerciseCreated) {
this.injectExpectationRepository.save(
InjectExpectationFixture.createManualInjectExpectationWithExercise(teamCreated, injectCreated,
exerciseCreated, EXPECTATION_NAME));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.openbas.utils.fixtures;

import io.openbas.database.model.Exercise;
import io.openbas.database.model.Inject;
import io.openbas.database.model.InjectExpectation;
import io.openbas.database.model.Team;

public class InjectExpectationFixture {

public static InjectExpectation createPreventionInjectExpectation(Team team, Inject inject) {
InjectExpectation injectExpectation = new InjectExpectation();
injectExpectation.setInject(inject);
injectExpectation.setType(InjectExpectation.EXPECTATION_TYPE.PREVENTION);
injectExpectation.setTeam(team);
injectExpectation.setExpectedScore(100.0);
return injectExpectation;
}

public static InjectExpectation createDetectionInjectExpectation(Team team, Inject inject) {
InjectExpectation injectExpectation = new InjectExpectation();
injectExpectation.setInject(inject);
injectExpectation.setType(InjectExpectation.EXPECTATION_TYPE.DETECTION);
injectExpectation.setTeam(team);
injectExpectation.setExpectedScore(100.0);
return injectExpectation;
}

public static InjectExpectation createManualInjectExpectation(Team team, Inject inject) {
InjectExpectation injectExpectation = new InjectExpectation();
injectExpectation.setInject(inject);
injectExpectation.setType(InjectExpectation.EXPECTATION_TYPE.MANUAL);
injectExpectation.setTeam(team);
injectExpectation.setExpectedScore(100.0);
return injectExpectation;
}

public static InjectExpectation createArticleInjectExpectation(Team team, Inject inject) {
InjectExpectation injectExpectation = new InjectExpectation();
injectExpectation.setInject(inject);
injectExpectation.setType(InjectExpectation.EXPECTATION_TYPE.ARTICLE);
injectExpectation.setTeam(team);
injectExpectation.setExpectedScore(100.0);
return injectExpectation;
}

public static InjectExpectation createManualInjectExpectationWithExercise(Team team, Inject inject,
Exercise exercise, String expectationName) {
InjectExpectation injectExpectation = new InjectExpectation();
injectExpectation.setInject(inject);
injectExpectation.setType(InjectExpectation.EXPECTATION_TYPE.MANUAL);
injectExpectation.setTeam(team);
injectExpectation.setExpectedScore(100.0);
injectExpectation.setExercise(exercise);
injectExpectation.setName(expectationName);
return injectExpectation;

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
isPayload={isNotEmptyField(inject.inject_injector_contract?.injector_contract_payload)}
type={inject.inject_injector_contract?.injector_contract_payload
? inject.inject_injector_contract.injector_contract_payload.payload_collector_type
|| inject.inject_injector_contract.injector_contract_payload.payload_type
|| inject.inject_injector_contract.injector_contract_payload.payload_type
: inject.inject_type}
/>
);
Expand Down Expand Up @@ -341,9 +341,11 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
const newSteps = Array.from(groupedBy).flatMap(([targetType, results]) => results.sort((a: InjectExpectationsStore, b: InjectExpectationsStore) => {
if (a.inject_expectation_name && b.inject_expectation_name) {
return a.inject_expectation_name.localeCompare(b.inject_expectation_name);
} if (a.inject_expectation_name && !b.inject_expectation_name) {
}
if (a.inject_expectation_name && !b.inject_expectation_name) {
return -1; // a comes before b
} if (!a.inject_expectation_name && b.inject_expectation_name) {
}
if (!a.inject_expectation_name && b.inject_expectation_name) {
return 1; // b comes before a
}
return a.inject_expectation_id.localeCompare(b.inject_expectation_id);
Expand All @@ -352,7 +354,7 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
label: (
<span>
{getStatusLabel(targetType, [expectation.inject_expectation_status])}
<br/>{truncate(expectation.inject_expectation_name, 20)}
<br />{truncate(expectation.inject_expectation_name, 20)}
</span>
),
type: targetType,
Expand Down Expand Up @@ -490,9 +492,11 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
.toSorted((a, b) => {
if (a.inject_expectation_name && b.inject_expectation_name) {
return a.inject_expectation_name.localeCompare(b.inject_expectation_name);
} if (a.inject_expectation_name && !b.inject_expectation_name) {
}
if (a.inject_expectation_name && !b.inject_expectation_name) {
return -1; // a comes before b
} if (!a.inject_expectation_name && b.inject_expectation_name) {
}
if (!a.inject_expectation_name && b.inject_expectation_name) {
return 1; // b comes before a
}
return a.inject_expectation_id.localeCompare(b.inject_expectation_id);
Expand Down Expand Up @@ -525,7 +529,7 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
<Grid container={true} spacing={2}>
{injectExpectation.inject_expectation_results && injectExpectation.inject_expectation_results.map((expectationResult, index) => (
<Grid key={index} item xs={4}>
<Card key={injectExpectation.inject_expectation_id} >
<Card key={injectExpectation.inject_expectation_id}>
<CardHeader
avatar={getAvatar(injectExpectation, expectationResult)}
action={
Expand Down Expand Up @@ -555,32 +559,32 @@ const TargetResultsDetailFlow: FunctionComponent<Props> = ({
</MenuItem>
</Menu>
</>
}
}
title={expectationResult.sourceName ? t(expectationResult.sourceName) : t('Unknown')}
subheader={nsdt(expectationResult.date)}
/>
<CardContent sx={{ display: 'flex', alignItems: 'center' }}>
<ItemResult label={expectationResult.result} status={expectationResult.result} />
<Tooltip title={t('Score')}><Chip classes={{ root: classes.score }} label={expectationResult.score}/></Tooltip>
<Tooltip title={t('Score')}><Chip classes={{ root: classes.score }} label={expectationResult.score} /></Tooltip>
</CardContent>
</Card>
</Grid>
))}
{(['DETECTION', 'PREVENTION'].includes(injectExpectation.inject_expectation_type) || (injectExpectation.inject_expectation_type === 'MANUAL' && injectExpectation.inject_expectation_results && injectExpectation.inject_expectation_results.length === 0))
&& (
<Grid item xs={4}>
<Card classes={{ root: classes.resultCardDummy }}>
<CardActionArea classes={{ root: classes.area }}
onClick={() => setSelectedExpectationForCreation({
injectExpectation,
sourceIds: computeExistingSourceIds(injectExpectation.inject_expectation_results ?? []),
})
}
>
<AddBoxOutlined />
</CardActionArea>
</Card>
</Grid>
<Grid item xs={4}>
<Card classes={{ root: classes.resultCardDummy }}>
<CardActionArea classes={{ root: classes.area }}
onClick={() => setSelectedExpectationForCreation({
injectExpectation,
sourceIds: computeExistingSourceIds(injectExpectation.inject_expectation_results ?? []),
})
}
>
<AddBoxOutlined />
</CardActionArea>
</Card>
</Grid>
)}
</Grid>
<Divider style={{ marginTop: 20 }} />
Expand Down
Loading

0 comments on commit bd65d3e

Please sign in to comment.