Skip to content

Commit 4b7a932

Browse files
author
Alexander Bainczyk
committed
minor fixes
1 parent 0d273f5 commit 4b7a932

File tree

20 files changed

+183
-95
lines changed

20 files changed

+183
-95
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# ALEX 2.1.1
2+
3+
## Fixes
4+
5+
* Fix bug where test cases could not be executed.
6+
* Fix bug where tests could not be saved when pre steps have changed.
7+
8+
19
# ALEX 2.1.0
210

311
## Breaking Changes

backend/src/main/java/de/learnlib/alex/learning/services/TestGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public TestSuite generate(User user, Long projectId, Long testNo, TestSuiteGener
169169
}
170170

171171
for (TestCase tc : testSuite.getTestCases()) {
172-
testDAO.update(user, project.getId(), tc);
172+
testDAO.update(user, project.getId(), tc.getId(), tc);
173173
}
174174

175175
return testSuite;

backend/src/main/java/de/learnlib/alex/testing/dao/TestDAO.java

Lines changed: 61 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,11 @@ private List<Test> create(User user, Long projectId, List<Test> tests, TestSuite
238238
}
239239

240240
public Test get(User user, Long projectId, Long testId) {
241-
final Project project = projectRepository.findById(projectId).orElse(null);
242-
return get(user, project, testId);
241+
final var project = projectRepository.findById(projectId).orElse(null);
242+
final var test = testRepository.findById(testId).orElse(null);
243+
checkAccess(user, project, test);
244+
loadLazyRelations(test);
245+
return test;
243246
}
244247

245248
public List<Test> get(User user, Long projectId, List<Long> ids) {
@@ -262,67 +265,75 @@ public Test getRoot(User user, Long projectId) {
262265
return root;
263266
}
264267

265-
public void update(User user, Long projectId, Test test) {
266-
final Project project = projectRepository.findById(projectId).orElse(null);
268+
public Test update(User user, Long projectId, Long testId, Test test) {
269+
final var project = projectRepository.findById(projectId).orElse(null);
270+
final var testInDB = testRepository.findById(testId).orElse(null);
267271
checkAccess(user, project, test);
268272
checkRunningTestProcess(user, project, test);
269273

270274
// check lock status
271275
testPresenceService.checkLockStatus(projectId, test.getId(), user.getId());
272276

273277
// make sure the name of the Test Case is unique
274-
Test testInDB = testRepository.findOneByParent_IdAndName(test.getParentId(), test.getName());
275-
if (testInDB != null && !testInDB.getId().equals(test.getId())) {
278+
final var testWithSameName = testRepository.findOneByParent_IdAndName(test.getParentId(), test.getName());
279+
if (testWithSameName != null && !testWithSameName.getId().equals(testInDB.getId())) {
276280
throw new ValidationException("To update a test case or suite its name must be unique within its parent.");
277281
}
278282

279-
final Test root = testRepository.findFirstByProject_IdOrderByIdAsc(test.getProjectId());
280-
if (test.getId().equals(root.getId()) && !test.getName().equals("Root")) {
283+
final var rootTestSuite = testRepository.findFirstByProject_IdOrderByIdAsc(test.getProjectId());
284+
if (test.getId().equals(rootTestSuite.getId()) && !test.getName().equals("Root")) {
281285
throw new ValidationException("The name of the root test suite may not be changed.");
282286
}
283287

284-
testInDB = get(user, test.getProjectId(), test.getId());
285-
286-
test.setId(testInDB.getId());
287-
test.setProject(testInDB.getProject());
288-
test.setParent(getParent(user, projectId, testInDB.getParentId()));
289-
290-
if (test instanceof TestSuite) {
291-
updateTestSuite(user, (TestSuite) test, test.getProject());
292-
} else if (test instanceof TestCase) {
293-
updateTestCase(user, (TestCase) test, test.getProject());
288+
if (testInDB instanceof TestSuite && test instanceof TestSuite) {
289+
final var updatedTestSuite = updateTestSuite((TestSuite) testInDB, (TestSuite) test);
290+
loadLazyRelations(updatedTestSuite);
291+
return updatedTestSuite;
292+
} else if (testInDB instanceof TestCase && test instanceof TestCase) {
293+
final var updatedTestCase = updateTestCase(user, (TestCase) testInDB, (TestCase) test);
294+
loadLazyRelations(updatedTestCase);
295+
return updatedTestCase;
296+
} else {
297+
throw new IllegalStateException("Cannot update a test case with a test suite or vice versa.");
294298
}
295299
}
296300

297-
private List<Long> getStepsWithIds(List<TestCaseStep> steps) {
298-
return steps.stream()
299-
.filter(s -> s.getId() != null)
300-
.map(TestCaseStep::getId)
301-
.collect(Collectors.toList());
302-
}
303-
304-
private void updateTestCase(User user, TestCase testCase, Project project) {
301+
private Test updateTestCase(User user, TestCase testCaseInDB, TestCase testCase) {
305302
checkIfOutputMappingNamesAreUnique(testCase);
306303

307-
beforeSaving(user, project, testCase);
308-
309-
testCase.setGenerated(false);
310-
testCase.setUpdatedOn(ZonedDateTime.now());
311-
testCase.setLastUpdatedBy(user);
312-
313-
final List<Long> allStepIds = new ArrayList<>(); // all ids that still exist in the db
314-
allStepIds.addAll(getStepsWithIds(testCase.getPreSteps()));
315-
allStepIds.addAll(getStepsWithIds(testCase.getSteps()));
316-
allStepIds.addAll(getStepsWithIds(testCase.getPostSteps()));
317-
318-
testCaseStepRepository.deleteAllByTestCase_IdAndIdNotIn(testCase.getId(), allStepIds);
319-
320-
// delete all test case steps that have been removed in the update.
321-
saveTestCaseSteps(testCase.getPreSteps());
322-
saveTestCaseSteps(testCase.getSteps());
323-
saveTestCaseSteps(testCase.getPostSteps());
324-
325-
testRepository.save(testCase);
304+
testCaseInDB.setName(testCase.getName());
305+
testCaseInDB.setGenerated(false);
306+
testCaseInDB.setUpdatedOn(ZonedDateTime.now());
307+
testCaseInDB.setLastUpdatedBy(user);
308+
309+
testCaseInDB.getPreSteps().clear();
310+
testCaseInDB.getSteps().clear();
311+
testCaseInDB.getPostSteps().clear();
312+
testRepository.save(testCaseInDB);
313+
314+
testCaseInDB.getPreSteps().addAll(testCase.getPreSteps());
315+
testCaseInDB.getSteps().addAll(testCase.getSteps());
316+
testCaseInDB.getPostSteps().addAll(testCase.getPostSteps());
317+
removeIdsFromSteps(testCaseInDB);
318+
beforeSaving(user, testCaseInDB.getProject(), testCaseInDB);
319+
320+
saveTestCaseSteps(testCaseInDB.getPreSteps());
321+
saveTestCaseSteps(testCaseInDB.getSteps());
322+
saveTestCaseSteps(testCaseInDB.getPostSteps());
323+
testRepository.save(testCaseInDB);
324+
325+
return testCaseInDB;
326+
}
327+
328+
private void removeIdsFromSteps(TestCase testCase) {
329+
Stream.of(testCase.getPreSteps(), testCase.getSteps(), testCase.getPostSteps())
330+
.flatMap(Collection::stream)
331+
.forEach(s -> {
332+
s.setId(null);
333+
s.getPSymbol().setId(null);
334+
s.getPSymbol().getOutputMappings().forEach(om -> om.setId(null));
335+
s.getPSymbol().getParameterValues().forEach(om -> om.setId(null));
336+
});
326337
}
327338

328339
private void checkIfOutputMappingNamesAreUnique(TestCase testCase) {
@@ -336,10 +347,9 @@ private void checkIfOutputMappingNamesAreUnique(TestCase testCase) {
336347
SymbolOutputMappingUtils.checkIfMappedNamesAreUnique(oms);
337348
}
338349

339-
private void updateTestSuite(User user, TestSuite testSuite, Project project) {
340-
testSuite.getTests().forEach(t -> t.setParent(null));
341-
beforeSaving(user, project, testSuite);
342-
testRepository.save(testSuite);
350+
private Test updateTestSuite(TestSuite testSuiteInDB, TestSuite testSuite) {
351+
testSuiteInDB.setName(testSuite.getName());
352+
return testRepository.save(testSuiteInDB);
343353
}
344354

345355
public void delete(User user, Long projectId, Long testId) {
@@ -568,13 +578,6 @@ private void saveTestCaseSteps(List<TestCaseStep> steps) {
568578
});
569579
}
570580

571-
private Test get(User user, Project project, Long testId) {
572-
final Test test = testRepository.findById(testId).orElse(null);
573-
checkAccess(user, project, test);
574-
loadLazyRelations(test);
575-
return test;
576-
}
577-
578581
private void loadLazyRelations(TestResult testResult) {
579582
if (testResult instanceof TestCaseResult) {
580583
Hibernate.initialize(((TestCaseResult) testResult).getOutputs());
@@ -606,7 +609,8 @@ private void beforeSaving(User user, Project project, Test test) {
606609
if (test instanceof TestSuite) {
607610
TestSuite testSuite = (TestSuite) test;
608611
for (Long testId : testSuite.getTestsAsIds()) {
609-
Test otherTest = get(user, project, testId);
612+
final var otherTest = testRepository.findById(testId).orElse(null);
613+
checkAccess(user, project, otherTest);
610614
testSuite.addTest(otherTest);
611615
}
612616
} else if (test instanceof TestCase) {

backend/src/main/java/de/learnlib/alex/testing/rest/TestResource.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,9 @@ public ResponseEntity<Test> update(@PathVariable("projectId") Long projectId,
250250
@PathVariable("testId") Long testId,
251251
@RequestBody Test test) {
252252
final var user = authContext.getUser();
253-
testDAO.update(user, projectId, test);
254-
webhookService.fireEvent(user, new TestEvent.Updated(test));
255-
return ResponseEntity.ok(test);
253+
final var updatedTest = testDAO.update(user, projectId, testId, test);
254+
webhookService.fireEvent(user, new TestEvent.Updated(updatedTest));
255+
return ResponseEntity.ok(updatedTest);
256256
}
257257

258258
/**

backend/src/test/java/de/learnlib/alex/integrationtests/resources/ATestResourceIT.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package de.learnlib.alex.integrationtests.resources;
1818

1919
import static org.awaitility.Awaitility.await;
20+
import static org.junit.jupiter.api.Assertions.assertAll;
2021
import static org.junit.jupiter.api.Assertions.assertEquals;
2122
import static org.junit.jupiter.api.Assertions.assertNotNull;
2223
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -270,6 +271,42 @@ public void shouldUpdateTest() throws Exception {
270271
assertEquals(testCase.getName(), testCaseIdDb.getName());
271272
}
272273

274+
@Test
275+
public void shouldUpdateTestMoveStepToPreSteps() throws Exception {
276+
final var testCase = createTestCaseWithSteps(project.getId(), "test", null, jwtUser1);
277+
278+
final var step = testCase.getSteps().remove(0);
279+
testCase.getPreSteps().add(step);
280+
281+
final var res = testApi.update(testCase.getProjectId(), testCase.getId(), objectMapper.writeValueAsString(testCase), jwtUser1);
282+
assertEquals(HttpStatus.OK.value(), res.getStatus());
283+
284+
final var updatedTestCase = res.readEntity(TestCase.class);
285+
assertAll(
286+
() -> assertEquals(2, updatedTestCase.getPreSteps().size()),
287+
() -> assertEquals(1, updatedTestCase.getSteps().size()),
288+
() -> assertEquals(0, updatedTestCase.getPostSteps().size())
289+
);
290+
}
291+
292+
@Test
293+
public void shouldUpdateTestMoveStepToPostSteps() throws Exception {
294+
final var testCase = createTestCaseWithSteps(project.getId(), "test", null, jwtUser1);
295+
296+
final var step = testCase.getSteps().remove(0);
297+
testCase.getPostSteps().add(step);
298+
299+
final var res = testApi.update(testCase.getProjectId(), testCase.getId(), objectMapper.writeValueAsString(testCase), jwtUser1);
300+
assertEquals(HttpStatus.OK.value(), res.getStatus());
301+
302+
final var updatedTestCase = res.readEntity(TestCase.class);
303+
assertAll(
304+
() -> assertEquals(1, updatedTestCase.getPreSteps().size()),
305+
() -> assertEquals(1, updatedTestCase.getSteps().size()),
306+
() -> assertEquals(1, updatedTestCase.getPostSteps().size())
307+
);
308+
}
309+
273310
@Test
274311
public void shouldUpdateTestLockedByUser() throws Exception {
275312
WebSocketUser webSocketUser = new WebSocketUser("webSocketUser", client, port);

frontend/src/app/common/test-status-widget/test-status-widget.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
<ng-container *ngIf="status != null">
77

88
<div class="card-body" *ngIf="!status.active">
9-
<div class="alert alert-info mb-0" [class.no-border-radius]="flush">
9+
<div class="alert alert-info mb-0">
1010
There is no active test run.
1111
</div>
1212
</div>
1313

1414
<div class="list-container" *ngIf="status.active">
15-
<div class="list-group mb-0" [class.list-group-flush]="flush">
15+
<div class="list-group list-group-flush mb-0">
1616
<div class="list-group-item d-flex flex-row align-items-center" *ngFor="let testRun of allTestRuns">
1717
<ng-container *ngIf="testRun != null">
1818
<a

frontend/src/app/common/test-status-widget/test-status-widget.component.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ import { ToastService } from '../../services/toast.service';
2828
})
2929
export class TestStatusWidgetComponent implements OnInit, OnDestroy {
3030

31-
@Input()
32-
flush = true;
33-
3431
status: TestStatus;
3532

3633
testReportStatus: any = TestReportStatus;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2015 - 2021 TU Dortmund
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+
import { WebDriverConfig } from './web-driver-config';
18+
import { ProjectEnvironment } from './project-environment';
19+
20+
export class TestExecutionConfig {
21+
22+
id: number;
23+
name: string;
24+
tests: number[] = [];
25+
driverConfig = new WebDriverConfig();
26+
environment: ProjectEnvironment;
27+
environmentId: number;
28+
default: boolean = false;
29+
30+
static isValid(config: any): boolean {
31+
return config != null
32+
&& config.driverConfig.browser != null
33+
&& config.driverConfig.browser != ''
34+
&& config.driverConfig.platform != null
35+
&& config.driverConfig.width > 0
36+
&& config.driverConfig.height > 0;
37+
}
38+
}

frontend/src/app/views/project-view/project-details-widget/project-details-widget.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<tr>
1818
<td><strong>Default URL</strong></td>
1919
<td class="text-break">
20-
<a [href]="project.getDefaultEnvironment().getDefaultUrl().url">
20+
<a [href]="project.getDefaultEnvironment().getDefaultUrl().url" target="_blank">
2121
{{project.getDefaultEnvironment().getDefaultUrl().url}}
2222
</a>
2323
</td>

frontend/src/app/views/project-view/project-view.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
</div>
1414

1515
<div class="col-lg-4 col-md-6">
16-
<test-status-widget class="d-block mb-4" [flush]="true"></test-status-widget>
16+
<test-status-widget class="d-block mb-4"></test-status-widget>
1717
<latest-test-report-widget [project]="project" class="d-block mb-4"></latest-test-report-widget>
1818
</div>
1919

0 commit comments

Comments
 (0)