Skip to content

Commit 53f6e4f

Browse files
committed
feat(server, ui): fix endpoint with POST, fix callback front
1 parent f95c207 commit 53f6e4f

File tree

9 files changed

+115
-13
lines changed

9 files changed

+115
-13
lines changed

chutney/server-core/src/main/java/com/chutneytesting/server/core/domain/scenario/campaign/Campaign.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class Campaign {
2727
public final List<CampaignScenario> scenarios;
2828
public final boolean parallelRun;
2929
public final boolean retryAuto;
30-
public final String externalDatasetId;
30+
public String externalDatasetId;
3131
public final List<String> tags;
3232

3333
private String environment;
@@ -56,6 +56,10 @@ public void executionEnvironment(String environment) {
5656
this.environment = environment;
5757
}
5858

59+
public void executionDataset(String externalDatasetId) {
60+
this.externalDatasetId = externalDatasetId;
61+
}
62+
5963
public String executionEnvironment() {
6064
return this.environment;
6165
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2017-2023 Enedis
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+
18+
package com.chutneytesting.dataset.api;
19+
20+
import static java.util.Collections.emptyList;
21+
22+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
23+
import com.fasterxml.jackson.annotation.JsonProperty;
24+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
25+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
26+
import java.util.List;
27+
import java.util.Optional;
28+
import org.immutables.value.Value;
29+
30+
@Value.Immutable
31+
@JsonSerialize(as = ImmutableExternalDatasetDto.class)
32+
@JsonDeserialize(as = ImmutableExternalDatasetDto.class)
33+
@Value.Style(jdkOnly = true)
34+
@JsonIgnoreProperties(ignoreUnknown = true)
35+
public interface ExternalDatasetDto {
36+
Optional<String> id();
37+
38+
@Value.Default()
39+
@JsonProperty("uniqueValues")
40+
default List<KeyValue> constants() {
41+
return emptyList();
42+
}
43+
44+
@Value.Default()
45+
@JsonProperty("multipleValues")
46+
default List<List<KeyValue>> datatable() {
47+
return emptyList();
48+
}
49+
}

chutney/server/src/main/java/com/chutneytesting/dataset/domain/DatasetService.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static java.util.stream.Collectors.toList;
2121

2222
import com.chutneytesting.campaign.domain.CampaignRepository;
23+
import com.chutneytesting.dataset.api.DataSetDto;
2324
import com.chutneytesting.scenario.domain.gwt.GwtTestCase;
2425
import com.chutneytesting.server.core.domain.dataset.DataSet;
2526
import com.chutneytesting.server.core.domain.dataset.DataSetNotFoundException;
@@ -107,4 +108,11 @@ public void remove(String datasetName) {
107108
updateCampaigns(datasetName, "");
108109
}
109110

111+
public static void hasNoDuplicatedHeaders(DataSetDto dataset) {
112+
List<String> duplicates = dataset.duplicatedHeaders();
113+
if (!duplicates.isEmpty()) {
114+
throw new IllegalArgumentException( duplicates.size() + " column(s) have duplicated headers: [" + String.join(", ", duplicates) +"]");
115+
}
116+
}
117+
110118
}

chutney/server/src/main/java/com/chutneytesting/execution/api/CampaignExecutionUiController.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,29 @@
1717
package com.chutneytesting.execution.api;
1818

1919
import static com.chutneytesting.campaign.api.dto.CampaignExecutionReportMapper.toDto;
20+
import static com.chutneytesting.dataset.api.DataSetMapper.fromDto;
21+
import static com.chutneytesting.dataset.domain.DatasetService.hasNoDuplicatedHeaders;
22+
import static java.util.Optional.ofNullable;
2023

2124
import com.chutneytesting.campaign.api.dto.CampaignExecutionReportDto;
2225
import com.chutneytesting.campaign.api.dto.CampaignExecutionReportMapper;
2326
import com.chutneytesting.dataset.api.DataSetDto;
2427
import com.chutneytesting.dataset.api.DataSetMapper;
28+
import com.chutneytesting.dataset.api.ExternalDatasetDto;
29+
import com.chutneytesting.dataset.api.KeyValue;
2530
import com.chutneytesting.execution.api.report.surefire.SurefireCampaignExecutionReportBuilder;
2631
import com.chutneytesting.execution.api.report.surefire.SurefireScenarioExecutionReportBuilder;
2732
import com.chutneytesting.execution.domain.campaign.CampaignExecutionEngine;
2833
import com.chutneytesting.security.infra.SpringUserService;
34+
import com.chutneytesting.server.core.domain.dataset.DataSet;
35+
import com.chutneytesting.server.core.domain.scenario.ExternalDataset;
2936
import com.chutneytesting.server.core.domain.scenario.campaign.CampaignExecution;
3037
import jakarta.servlet.http.HttpServletResponse;
3138
import java.util.List;
39+
import java.util.Map;
3240
import java.util.Optional;
3341
import java.util.stream.Collectors;
42+
import javax.xml.crypto.Data;
3443
import org.slf4j.Logger;
3544
import org.slf4j.LoggerFactory;
3645
import org.springframework.http.HttpStatus;
@@ -40,6 +49,7 @@
4049
import org.springframework.web.bind.annotation.GetMapping;
4150
import org.springframework.web.bind.annotation.PathVariable;
4251
import org.springframework.web.bind.annotation.PostMapping;
52+
import org.springframework.web.bind.annotation.RequestBody;
4353
import org.springframework.web.bind.annotation.RequestMapping;
4454
import org.springframework.web.bind.annotation.RequestParam;
4555
import org.springframework.web.bind.annotation.ResponseStatus;
@@ -124,11 +134,26 @@ public void stopExecution(@PathVariable("executionId") Long executionId) {
124134
}
125135

126136
@PreAuthorize("hasAuthority('CAMPAIGN_EXECUTE')")
127-
@GetMapping(path = {"/byID/{campaignId}", "/byID/{campaignId}/{env}"}, produces = MediaType.APPLICATION_JSON_VALUE)
128-
public CampaignExecutionReportDto executeCampaignById(@PathVariable("campaignId") Long campaignId, @PathVariable("env") Optional<String> environment, @RequestParam("dataset") Optional<DataSetDto> dataset) {
137+
@PostMapping(path = {"/byID/{campaignId}", "/byID/{campaignId}/{env}"}, produces = MediaType.APPLICATION_JSON_VALUE)
138+
public CampaignExecutionReportDto executeCampaignById(
139+
@PathVariable("campaignId") Long campaignId,
140+
@PathVariable("env") Optional<String> environment,
141+
@RequestBody ExternalDatasetDto externalDataset
142+
) {
129143
String userId = userService.currentUser().getId();
130144
CampaignExecution report;
131-
report = campaignExecutionEngine.executeByIdWithEnvAndDataset(campaignId, environment.orElse(null), dataset.map(DataSetMapper::fromDto).orElse(null), userId);
145+
DataSet dataset;
146+
if (externalDataset == null) {
147+
dataset = null;
148+
} else {
149+
dataset = DataSet.builder()
150+
.withId(externalDataset.id().orElse(null))
151+
.withName(externalDataset.id().orElse(""))
152+
.withConstants(KeyValue.toMap(externalDataset.constants()))
153+
.withDatatable(externalDataset.datatable().stream().map(KeyValue::toMap).toList())
154+
.build();
155+
}
156+
report = campaignExecutionEngine.executeByIdWithEnvAndDataset(campaignId, environment.orElse(null), dataset, userId);
132157
return toDto(report);
133158
}
134159
}

chutney/server/src/main/java/com/chutneytesting/execution/domain/campaign/CampaignExecutionEngine.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ public CampaignExecution executeByIdWithEnvAndDataset(Long campaignId, String en
135135
.map(campaign -> selectExecutionEnvironment(campaign, environment))
136136
.map(campaign -> {
137137
ExternalDataset externalDataset = ofNullable(dataset).map(ds -> new ExternalDataset(ds.id, ds.constants, ds.datatable)).orElse(null);
138+
if (externalDataset != null) {
139+
campaign.executionDataset(null);
140+
}
138141
return executeScenarioInCampaign(campaign, userId, externalDataset);
139142
})
140143
.orElseThrow(() -> new CampaignNotFoundException(campaignId));
@@ -339,13 +342,15 @@ private ExecutionRequest buildExecutionRequest(Campaign campaign, TestCaseDatase
339342
}
340343
return DataSet
341344
.builder()
345+
.withName("")
342346
.withDatatable(externalDataset.getDatatable())
343347
.withConstants(externalDataset.getConstants())
344348
.build();
345349
});
346350
if (dataset.isEmpty()) {
347351
dataset = ofNullable(campaignExecution.externalDataset).map(externalDataset -> DataSet.builder()
348352
.withId(externalDataset.getDatasetId())
353+
.withName("")
349354
.withConstants(externalDataset.getConstants())
350355
.withDatatable(externalDataset.getDatatable())
351356
.build());

chutney/server/src/main/java/com/chutneytesting/tools/ExternalDatasetEntityMapper.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ public class ExternalDatasetEntityMapper {
3434
private static ObjectMapper mapper = new ObjectMapper();
3535

3636
private static List<Map<String, String>> datasetDatatableFromString(String datasetDatatable) {
37+
if (datasetDatatable == null) {
38+
return null;
39+
}
3740
try {
3841
return mapper.readValue(datasetDatatable, new TypeReference<>() {
3942
});
@@ -43,6 +46,9 @@ private static List<Map<String, String>> datasetDatatableFromString(String datas
4346
}
4447

4548
private static Map<String, String> datasetConstantsFromString(String datasetConstants) {
49+
if (datasetConstants == null) {
50+
return null;
51+
}
4652
try {
4753
return mapper.readValue(datasetConstants, new TypeReference<>() {
4854
});
@@ -52,6 +58,9 @@ private static Map<String, String> datasetConstantsFromString(String datasetCons
5258
}
5359

5460
public static String datasetDatatableToString(List<Map<String, String>> datatable) {
61+
if (datatable == null) {
62+
return null;
63+
}
5564
try {
5665
return mapper.writeValueAsString(datatable);
5766
} catch (JsonProcessingException e) {
@@ -60,6 +69,9 @@ public static String datasetDatatableToString(List<Map<String, String>> datatabl
6069
}
6170

6271
public static String datasetConstantsToString(Map<String, String> constants) {
72+
if (constants == null) {
73+
return null;
74+
}
6375
try {
6476
return mapper.writeValueAsString(constants);
6577
} catch (JsonProcessingException e) {

chutney/ui/src/app/core/components/execution/execute-modal/scenario-execute-modal.component.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export class ScenarioExecuteModalComponent implements OnInit {
4949
editionDatasetValues?: Dataset;
5050

5151

52-
@Input() executeCallback: (env: string, dataset: string) => void;
52+
@Input() executeCallback: (env: string, dataset: Dataset) => void;
5353
@Input() changeModalSize: (size: "lg" | "xl") => void;
5454

5555
isCollapsed = true;
@@ -115,7 +115,6 @@ export class ScenarioExecuteModalComponent implements OnInit {
115115
}
116116
})
117117
} else {
118-
console.log(editedDataset)
119118
this.execute(editedDataset)
120119
}
121120
} else {
@@ -125,7 +124,7 @@ export class ScenarioExecuteModalComponent implements OnInit {
125124

126125
execute(dataset: Dataset) {
127126
if (this.selectedEnv) {
128-
this.executeCallback(this.selectedEnv, dataset?.id)
127+
this.executeCallback(this.selectedEnv, dataset)
129128
this.activeModal.close();
130129
} else {
131130
this.translateService.get('scenarios.execution.errors.environment').subscribe((res: string) => {

chutney/ui/src/app/core/services/campaign.service.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { Injectable } from '@angular/core';
1818
import { Observable } from 'rxjs';
1919
import { map } from 'rxjs/operators';
2020
import { environment } from '@env/environment';
21-
import { Campaign, CampaignExecutionFullReport, CampaignExecutionReport, ScenarioIndex } from '@model';
21+
import {Campaign, CampaignExecutionFullReport, CampaignExecutionReport, Dataset, ScenarioIndex} from '@model';
2222
import { HttpClient } from '@angular/common/http';
2323
import { distinct } from '@shared/tools';
2424

@@ -92,9 +92,8 @@ export class CampaignService {
9292
return this.http.put<Campaign>(environment.backend + this.resourceUrl, copy);
9393
}
9494

95-
executeCampaign(campaignId: number, env: string, dataset?: string): Observable<CampaignExecutionReport> {
96-
const datasetQueryParam = dataset == null ? "" : "?dataset=" + dataset;
97-
return this.http.get<CampaignExecutionReport>(environment.backend + `${this.ressourceUrlExecution}/byID/${campaignId}/${env}` + datasetQueryParam);
95+
executeCampaign(campaignId: number, env: string, dataset?: Dataset): Observable<CampaignExecutionReport> {
96+
return this.http.post<CampaignExecutionReport>(environment.backend + `${this.ressourceUrlExecution}/byID/${campaignId}/${env}`, dataset);
9897
}
9998

10099
stopExecution(campaignId: number, executionId: number): Observable<void> {

chutney/ui/src/app/modules/campaign/components/execution/sub/right-side-bar/campaign-execution-menu.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { FileSaverService } from 'ngx-filesaver';
2727
import * as JSZip from 'jszip';
2828

2929
import { CampaignService, EnvironmentService, JiraPluginService, LoginService, ScenarioService } from '@core/services';
30-
import { Authorization, Campaign, ScenarioIndex, TestCase } from '@model';
30+
import {Authorization, Campaign, Dataset, ScenarioIndex, TestCase} from '@model';
3131
import { EventManagerService } from '@shared';
3232
import { MenuItem } from '@shared/components/layout/menuItem';
3333
import { HttpErrorResponse } from '@angular/common/http';
@@ -100,7 +100,8 @@ export class CampaignExecutionMenuComponent implements OnInit, OnChanges {
100100
}
101101

102102
private executeCampaign() {
103-
const executeCallback = (env: string, dataset: string) => {
103+
const executeCallback = (env: string, dataset: Dataset) => {
104+
console.log(dataset)
104105
this.broadcastCatchError(this.campaignService.executeCampaign(this.campaign.id, env, dataset)).subscribe();
105106
timer(1000).pipe(
106107
switchMap(() => of(this.eventManagerService.broadcast({ name: 'execute', env: env })))

0 commit comments

Comments
 (0)