Skip to content

Commit d8e4c5e

Browse files
committed
feat: optionally include all message headers in scenario execution response
1 parent 0fd05fd commit d8e4c5e

File tree

6 files changed

+193
-8
lines changed

6 files changed

+193
-8
lines changed

simulator-spring-boot/src/main/java/org/citrusframework/simulator/repository/ScenarioExecutionRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,6 @@ public interface ScenarioExecutionRepository extends JpaRepository<ScenarioExecu
4343
Optional<ScenarioExecution> findOneByExecutionId(@Param("executionId") Long executionId);
4444

4545
@Query("FROM ScenarioExecution WHERE executionId IN :scenarioExecutionIds")
46-
@EntityGraph(attributePaths = {"testResult", "scenarioParameters", "scenarioActions", "scenarioMessages"})
46+
@EntityGraph(attributePaths = {"testResult", "scenarioParameters", "scenarioActions", "scenarioMessages", "scenarioMessages.headers"})
4747
Page<ScenarioExecution> findAllWhereExecutionIdIn(@Param("scenarioExecutionIds") List<Long> scenarioExecutionIds, Pageable pageable);
4848
}

simulator-spring-boot/src/main/java/org/citrusframework/simulator/web/rest/ScenarioExecutionResource.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,15 @@
3434
import org.springframework.web.bind.annotation.GetMapping;
3535
import org.springframework.web.bind.annotation.PathVariable;
3636
import org.springframework.web.bind.annotation.RequestMapping;
37+
import org.springframework.web.bind.annotation.RequestParam;
3738
import org.springframework.web.bind.annotation.RestController;
3839
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
3940

4041
import java.util.List;
4142
import java.util.Optional;
4243

44+
import static java.lang.Boolean.FALSE;
45+
4346
/**
4447
* REST controller for managing {@link ScenarioExecution}.
4548
*/
@@ -56,7 +59,8 @@ public class ScenarioExecutionResource {
5659

5760
public ScenarioExecutionResource(
5861
ScenarioExecutionService scenarioExecutionService,
59-
ScenarioExecutionQueryService scenarioExecutionQueryService, ScenarioExecutionMapper scenarioExecutionMapper
62+
ScenarioExecutionQueryService scenarioExecutionQueryService,
63+
ScenarioExecutionMapper scenarioExecutionMapper
6064
) {
6165
this.scenarioExecutionService = scenarioExecutionService;
6266
this.scenarioExecutionQueryService = scenarioExecutionQueryService;
@@ -71,10 +75,17 @@ public ScenarioExecutionResource(
7175
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of scenarioExecutions in body.
7276
*/
7377
@GetMapping("/scenario-executions")
74-
public ResponseEntity<List<ScenarioExecutionDTO>> getAllScenarioExecutions(ScenarioExecutionCriteria criteria, @ParameterObject Pageable pageable) {
78+
public ResponseEntity<List<ScenarioExecutionDTO>> getAllScenarioExecutions(
79+
ScenarioExecutionCriteria criteria,
80+
@RequestParam(name = "includeActions", required = false, defaultValue = "false") Boolean includeActions,
81+
@RequestParam(name = "includeMessages", required = false, defaultValue = "false") Boolean includeMessages,
82+
@RequestParam(name = "includeParameters", required = false, defaultValue = "false") Boolean includeParameters,
83+
@ParameterObject Pageable pageable
84+
) {
7585
logger.debug("REST request to get ScenarioExecutions by criteria: {}", criteria);
7686

7787
Page<ScenarioExecution> page = scenarioExecutionQueryService.findByCriteria(criteria, pageable);
88+
stripPageContents(page, includeActions, includeMessages, includeParameters);
7889
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
7990
return ResponseEntity.ok().headers(headers).body(page.getContent().stream().map(scenarioExecutionMapper::toDto).toList());
8091
}
@@ -103,4 +114,16 @@ public ResponseEntity<ScenarioExecutionDTO> getScenarioExecution(@PathVariable("
103114
Optional<ScenarioExecution> scenarioExecution = scenarioExecutionService.findOne(id);
104115
return ResponseUtil.wrapOrNotFound(scenarioExecution.map(scenarioExecutionMapper::toDto));
105116
}
117+
118+
private void stripPageContents(Page<ScenarioExecution> page, Boolean includeActions, Boolean includeMessages, Boolean includeParameters) {
119+
if (FALSE.equals(includeActions)) {
120+
page.getContent().forEach(scenarioExecution -> scenarioExecution.getScenarioActions().clear());
121+
}
122+
if (FALSE.equals(includeMessages)) {
123+
page.getContent().forEach(scenarioExecution -> scenarioExecution.getScenarioMessages().clear());
124+
}
125+
if (FALSE.equals(includeParameters)) {
126+
page.getContent().forEach(scenarioExecution -> scenarioExecution.getScenarioParameters().clear());
127+
}
128+
}
106129
}

simulator-spring-boot/src/test/java/org/citrusframework/simulator/web/rest/ScenarioExecutionResourceIT.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ void getNonExistingScenarioExecution() throws Exception {
560560

561561
@Nested
562562
class CorrectTimeOnScenarioExecution {
563+
563564
public static final TemporalUnitLessThanOffset LESS_THAN_5_SECONDS = new TemporalUnitLessThanOffset(5, SECONDS);
564565

565566
@Autowired
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Copyright the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.citrusframework.simulator.web.rest;
18+
19+
import org.citrusframework.simulator.model.Message;
20+
import org.citrusframework.simulator.model.ScenarioAction;
21+
import org.citrusframework.simulator.model.ScenarioExecution;
22+
import org.citrusframework.simulator.model.ScenarioParameter;
23+
import org.citrusframework.simulator.service.ScenarioExecutionQueryService;
24+
import org.citrusframework.simulator.service.ScenarioExecutionService;
25+
import org.citrusframework.simulator.service.criteria.ScenarioExecutionCriteria;
26+
import org.citrusframework.simulator.web.rest.dto.ScenarioExecutionDTO;
27+
import org.citrusframework.simulator.web.rest.dto.mapper.ScenarioExecutionMapper;
28+
import org.junit.jupiter.api.BeforeEach;
29+
import org.junit.jupiter.api.Nested;
30+
import org.junit.jupiter.api.Test;
31+
import org.junit.jupiter.api.extension.ExtendWith;
32+
import org.mockito.Mock;
33+
import org.mockito.junit.jupiter.MockitoExtension;
34+
import org.springframework.data.domain.PageImpl;
35+
import org.springframework.data.domain.Pageable;
36+
import org.springframework.mock.web.MockHttpServletRequest;
37+
import org.springframework.web.context.request.RequestContextHolder;
38+
import org.springframework.web.context.request.ServletRequestAttributes;
39+
40+
import static java.lang.Boolean.FALSE;
41+
import static java.lang.Boolean.TRUE;
42+
import static java.util.Collections.singletonList;
43+
import static org.assertj.core.api.Assertions.assertThat;
44+
import static org.mockito.Mockito.doReturn;
45+
import static org.mockito.Mockito.mock;
46+
import static org.springframework.http.HttpStatus.OK;
47+
48+
@ExtendWith({MockitoExtension.class})
49+
class ScenarioExecutionResourceTest {
50+
51+
@Mock
52+
private ScenarioExecutionService scenarioExecutionServiceMock;
53+
54+
@Mock
55+
private ScenarioExecutionQueryService scenarioExecutionQueryServiceMock;
56+
57+
@Mock
58+
private ScenarioExecutionMapper scenarioExecutionMapperMock;
59+
60+
private ScenarioExecutionResource fixture;
61+
62+
@BeforeEach
63+
void beforeEachSetup() {
64+
fixture = new ScenarioExecutionResource(scenarioExecutionServiceMock, scenarioExecutionQueryServiceMock, scenarioExecutionMapperMock);
65+
}
66+
67+
@Nested
68+
class GetAllScenarioExecutions {
69+
70+
@Mock
71+
private ScenarioExecutionCriteria criteriaMock;
72+
73+
@Mock
74+
private Pageable pageableMock;
75+
76+
@Mock
77+
private ScenarioExecutionDTO scenarioExecutionDTOMock;
78+
79+
private ScenarioExecution scenarioExecution;
80+
81+
@BeforeEach
82+
void beforeEachSetup() {
83+
var request = new MockHttpServletRequest();
84+
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
85+
86+
scenarioExecution = new ScenarioExecution();
87+
scenarioExecution.getScenarioActions().add(mock(ScenarioAction.class));
88+
scenarioExecution.getScenarioMessages().add(mock(Message.class));
89+
scenarioExecution.getScenarioParameters().add(mock(ScenarioParameter.class));
90+
91+
var scenarioExecutions = new PageImpl<>(singletonList(scenarioExecution));
92+
doReturn(scenarioExecutions).when(scenarioExecutionQueryServiceMock).findByCriteria(criteriaMock, pageableMock);
93+
94+
doReturn(scenarioExecutionDTOMock).when(scenarioExecutionMapperMock).toDto(scenarioExecution);
95+
}
96+
97+
@Test
98+
void stripsIncludedActions() {
99+
var response = fixture.getAllScenarioExecutions(criteriaMock, FALSE, TRUE, TRUE, pageableMock);
100+
101+
assertThat(response)
102+
.satisfies(
103+
r -> assertThat(r.getStatusCode()).isEqualTo(OK),
104+
r -> assertThat(r.getBody())
105+
.singleElement()
106+
.isEqualTo(scenarioExecutionDTOMock)
107+
);
108+
109+
assertThat(scenarioExecution.getScenarioActions()).isEmpty();
110+
assertThat(scenarioExecution.getScenarioMessages()).isNotEmpty();
111+
assertThat(scenarioExecution.getScenarioParameters()).isNotEmpty();
112+
}
113+
114+
@Test
115+
void stripsIncludedMessages() {
116+
var response = fixture.getAllScenarioExecutions(criteriaMock, TRUE, FALSE, TRUE, pageableMock);
117+
118+
assertThat(response)
119+
.satisfies(
120+
r -> assertThat(r.getStatusCode()).isEqualTo(OK),
121+
r -> assertThat(r.getBody())
122+
.singleElement()
123+
.isEqualTo(scenarioExecutionDTOMock)
124+
);
125+
126+
assertThat(scenarioExecution.getScenarioActions()).isNotEmpty();
127+
assertThat(scenarioExecution.getScenarioMessages()).isEmpty();
128+
assertThat(scenarioExecution.getScenarioParameters()).isNotEmpty();
129+
}
130+
131+
@Test
132+
void stripsIncludedParameters() {
133+
var response = fixture.getAllScenarioExecutions(criteriaMock, TRUE, TRUE, FALSE, pageableMock);
134+
135+
assertThat(response)
136+
.satisfies(
137+
r -> assertThat(r.getStatusCode()).isEqualTo(OK),
138+
r -> assertThat(r.getBody())
139+
.singleElement()
140+
.isEqualTo(scenarioExecutionDTOMock)
141+
);
142+
143+
assertThat(scenarioExecution.getScenarioActions()).isNotEmpty();
144+
assertThat(scenarioExecution.getScenarioMessages()).isNotEmpty();
145+
assertThat(scenarioExecution.getScenarioParameters()).isEmpty();
146+
}
147+
}
148+
}

simulator-spring-boot/src/test/java/org/citrusframework/simulator/web/rest/ScenarioResourceTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import static java.util.Arrays.asList;
4444
import static org.assertj.core.api.Assertions.assertThat;
45+
import static org.assertj.core.api.InstanceOfAssertFactories.LIST;
4546
import static org.assertj.core.api.InstanceOfAssertFactories.type;
4647
import static org.citrusframework.simulator.web.rest.ScenarioResource.Scenario.ScenarioType.STARTER;
4748
import static org.junit.jupiter.params.provider.Arguments.arguments;
@@ -122,7 +123,7 @@ void doesFilterCacheWithNameContains(String filterLetter, String expectedScenari
122123

123124
assertThat(result)
124125
.extracting(ResponseEntity::getBody)
125-
.asList()
126+
.asInstanceOf(LIST)
126127
.hasSize(1)
127128
.first()
128129
.asInstanceOf(type(Scenario.class))
@@ -141,7 +142,7 @@ void doesFilterCacheWithNameStartsOrEndsWith() {
141142

142143
assertThat(result)
143144
.extracting(ResponseEntity::getBody)
144-
.asList()
145+
.asInstanceOf(LIST)
145146
.hasSize(2)
146147
.noneSatisfy(scenario ->
147148
assertThat(scenario)
@@ -161,7 +162,7 @@ void doesNotFilterCacheWithoutNameContains() {
161162

162163
assertThat(result)
163164
.extracting(ResponseEntity::getBody)
164-
.asList()
165+
.asInstanceOf(LIST)
165166
.isEqualTo(SCENARIO_CACHE);
166167
}
167168

simulator-ui/src/main/webapp/app/entities/scenario-execution/service/scenario-execution.service.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,20 @@ export class ScenarioExecutionService {
3636
.pipe(map(res => this.convertResponseFromServer(res)));
3737
}
3838

39-
query(req?: any): Observable<EntityArrayResponseType> {
40-
const options = createRequestOption(req);
39+
query(
40+
req?: any,
41+
responseConfig: { includeActions: boolean; includeMessages: boolean; includeParameters: boolean } = {
42+
includeActions: false,
43+
includeMessages: false,
44+
includeParameters: false,
45+
},
46+
): Observable<EntityArrayResponseType> {
47+
let options = createRequestOption(req);
48+
49+
for (const key of Object.keys(responseConfig)) {
50+
options = options.append(key, responseConfig[key as keyof typeof responseConfig]);
51+
}
52+
4153
return this.http
4254
.get<RestScenarioExecution[]>(this.resourceUrl, { params: options, observe: 'response' })
4355
.pipe(map(res => this.convertResponseArrayFromServer(res)));

0 commit comments

Comments
 (0)