diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f0d4975b..a26252606 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# ALEX 1.5.1 + +This release only contains some bug fixes. + + # ALEX 1.5.0 ## Breaking Changes diff --git a/README.md b/README.md index 82d5a0541..03a9e117b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Make sure you have Java 8 installed on your system. We advise to use a modern web browser like Google Chrome, Mozilla Firefox or Microsoft Edge with JavaScript enabled. 1. [Download](https://github.com/LearnLib/alex/releases/latest) the latest version. -2. Open a terminal and start ALEX via `java -jar alex-1.5.0.war [--alex.port=XXXX]`. +2. Open a terminal and start ALEX via `java -jar alex-1.5.1.war [--alex.port=XXXX]`. 3. Wait until the command line prints something like `de.learnlib.alex.App - Started App in XX.XXX seconds`. 3. Open *http://localhost:8000* in a web browser. @@ -48,7 +48,7 @@ cd alex mvn install package [-DskipTests] ``` -The bundle can then be found at `build/target/alex-build-1.5.0.war`. +The bundle can then be found at `build/target/alex-build-1.5.1.war`. ## Further reading diff --git a/backend/pom.xml b/backend/pom.xml index cdbb80a2c..b27b25a7e 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -23,7 +23,7 @@ de.learnlib.alex alex-parent - 1.5.0 + 1.5.1 ../pom.xml diff --git a/backend/src/main/java/de/learnlib/alex/data/dao/ProjectDAOImpl.java b/backend/src/main/java/de/learnlib/alex/data/dao/ProjectDAOImpl.java index 954a113c7..abf53b263 100644 --- a/backend/src/main/java/de/learnlib/alex/data/dao/ProjectDAOImpl.java +++ b/backend/src/main/java/de/learnlib/alex/data/dao/ProjectDAOImpl.java @@ -26,6 +26,7 @@ import de.learnlib.alex.learning.entities.LearnerResult; import de.learnlib.alex.learning.repositories.LearnerResultRepository; import de.learnlib.alex.testing.entities.TestSuite; +import de.learnlib.alex.testing.repositories.TestReportRepository; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; @@ -68,6 +69,9 @@ public class ProjectDAOImpl implements ProjectDAO { /** The repository for learner results. */ private LearnerResultRepository learnerResultRepository; + /** The repository for test reports. */ + private TestReportRepository testReportRepository; + /** The FileDAO to use. Will be injected. */ private FileDAO fileDAO; @@ -85,14 +89,17 @@ public class ProjectDAOImpl implements ProjectDAO { * The FileDAO to use. * @param projectUrlDAO * The ProjectUrlDAO to use. + * @param testReportRepository + * The repository for test reports. */ @Inject public ProjectDAOImpl(ProjectRepository projectRepository, LearnerResultRepository learnerResultRepository, - @Lazy FileDAO fileDAO, @Lazy ProjectUrlDAO projectUrlDAO) { + TestReportRepository testReportRepository, @Lazy FileDAO fileDAO, @Lazy ProjectUrlDAO projectUrlDAO) { this.projectRepository = projectRepository; this.learnerResultRepository = learnerResultRepository; this.fileDAO = fileDAO; this.projectUrlDAO = projectUrlDAO; + this.testReportRepository = testReportRepository; } @Override @@ -111,6 +118,10 @@ public Project create(final Project project) throws ValidationException { testSuite.setProject(project); project.getTests().add(testSuite); + if (project.getUrls().isEmpty()) { + throw new ValidationException("The project has to have at least one URL."); + } + project.getUrls().forEach(url -> { url.setId(null); url.setProject(project); @@ -164,6 +175,10 @@ public Project update(User user, Project project) throws NotFoundException, Vali .collect(Collectors.toList()); projectUrlDAO.checkAccess(user, project, urls); + if (project.getUrls().isEmpty()) { + throw new ValidationException("The project has to have at least one URL."); + } + try { project.setUser(user); project.setGroups(projectInDb.getGroups()); @@ -204,6 +219,8 @@ public void delete(User user, Long projectId) throws NotFoundException { final Project project = projectRepository.findOne(projectId); checkAccess(user, project); + testReportRepository.deleteAllByProject_Id(projectId); + learnerResultRepository.deleteAllByProject_Id(projectId); projectRepository.delete(project); // delete the project directory diff --git a/backend/src/main/java/de/learnlib/alex/learning/repositories/LearnerResultRepository.java b/backend/src/main/java/de/learnlib/alex/learning/repositories/LearnerResultRepository.java index 0041bde2d..f8f244d1e 100644 --- a/backend/src/main/java/de/learnlib/alex/learning/repositories/LearnerResultRepository.java +++ b/backend/src/main/java/de/learnlib/alex/learning/repositories/LearnerResultRepository.java @@ -116,4 +116,15 @@ public interface LearnerResultRepository extends JpaRepository { @Transactional(readOnly = true) @SuppressWarnings("checkstyle:methodname") List findAllByProject_Id(Long projectId); + + /** + * Delete all test reports by project id. + * + * @param projectId + * The id of the project. + * @return The number of deleted test reports. + */ + @Transactional + @SuppressWarnings("checkstyle:methodname") + Long deleteAllByProject_Id(Long projectId); } diff --git a/backend/src/test/java/de/learnlib/alex/data/dao/ProjectDAOImplTest.java b/backend/src/test/java/de/learnlib/alex/data/dao/ProjectDAOImplTest.java index d80d8ff08..208f30a75 100644 --- a/backend/src/test/java/de/learnlib/alex/data/dao/ProjectDAOImplTest.java +++ b/backend/src/test/java/de/learnlib/alex/data/dao/ProjectDAOImplTest.java @@ -23,6 +23,7 @@ import de.learnlib.alex.data.entities.SymbolGroup; import de.learnlib.alex.data.repositories.ProjectRepository; import de.learnlib.alex.learning.repositories.LearnerResultRepository; +import de.learnlib.alex.testing.repositories.TestReportRepository; import org.hamcrest.MatcherAssert; import org.junit.Before; import org.junit.Test; @@ -35,6 +36,7 @@ import javax.persistence.RollbackException; import javax.validation.ConstraintViolationException; import javax.validation.ValidationException; +import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -65,11 +67,15 @@ public class ProjectDAOImplTest { @Mock private ProjectUrlDAO projectUrlDAO; + @Mock + private TestReportRepository testReportRepository; + private ProjectDAO projectDAO; @Before public void setUp() { - projectDAO = new ProjectDAOImpl(projectRepository, learnerResultRepository, fileDAO, projectUrlDAO); + projectDAO = new ProjectDAOImpl(projectRepository, learnerResultRepository, testReportRepository, fileDAO, + projectUrlDAO); } @Test @@ -91,6 +97,30 @@ public void shouldCreateAValidEmptyProject() { assertThat(p.getId(), is(equalTo(1L))); } + @Test(expected = ValidationException.class) + public void shouldNotCreateAProjectIfUrlsAreEmpty() throws NotFoundException { + User user = new User(USER_ID); + + Project project = new Project(); + project.setId(PROJECT_ID); + project.setUser(user); + + projectDAO.create(project); + } + + @Test(expected = ValidationException.class) + public void shouldNotUpdateAProjectIfUrlsAreEmpty() throws NotFoundException { + User user = new User(USER_ID); + + Project project = new Project(); + project.setId(PROJECT_ID); + project.setUser(user); + + given(projectRepository.findOne(PROJECT_ID)).willReturn(project); + + projectDAO.update(user, project); + } + @Test public void shouldCreateAValidPreFilledProject() { SymbolGroup testGroup = new SymbolGroup(); @@ -111,6 +141,7 @@ public void shouldCreateAValidPreFilledProject() { @Test(expected = ValidationException.class) public void shouldHandleConstraintViolationExceptionOnProjectCreationGracefully() { Project project = new Project(); + project.setUrls(Collections.singletonList(new ProjectUrl())); // given(projectRepository.save(project)).willThrow(ConstraintViolationException.class); @@ -120,6 +151,7 @@ public void shouldHandleConstraintViolationExceptionOnProjectCreationGracefully( @Test(expected = ValidationException.class) public void shouldHandleDataIntegrityViolationExceptionOnProjectCreationGracefully() { Project project = new Project(); + project.setUrls(Collections.singletonList(new ProjectUrl())); // given(projectRepository.save(project)).willThrow(DataIntegrityViolationException.class); @@ -129,6 +161,7 @@ public void shouldHandleDataIntegrityViolationExceptionOnProjectCreationGraceful @Test(expected = ValidationException.class) public void shouldHandleTransactionSystemExceptionOnProjectCreationGracefully() { Project project = new Project(); + project.setUrls(Collections.singletonList(new ProjectUrl())); // ConstraintViolationException constraintViolationException; constraintViolationException = new ConstraintViolationException("Project is not valid!", new HashSet<>()); @@ -218,6 +251,7 @@ public void shouldHandleConstraintViolationExceptionOnProjectUpdateGracefully() user.setId(USER_ID); Project project = new Project(); + project.setUrls(Collections.singletonList(new ProjectUrl())); project.setUser(user); project.setId(PROJECT_ID); @@ -235,6 +269,7 @@ public void shouldHandleDataIntegrityViolationExceptionOnProjectUpdateGracefully Project project = new Project(); project.setUser(user); project.setId(PROJECT_ID); + project.setUrls(Collections.singletonList(new ProjectUrl())); given(projectRepository.save(project)).willThrow(DataIntegrityViolationException.class); given(projectRepository.findOne(PROJECT_ID)).willReturn(project); @@ -248,6 +283,7 @@ public void shouldHandleTransactionSystemExceptionOnProjectUpdateGracefully() th user.setId(USER_ID); Project project = new Project(); + project.setUrls(Collections.singletonList(new ProjectUrl())); project.setUser(user); project.setId(PROJECT_ID); diff --git a/backend/src/test/java/de/learnlib/alex/learning/rest/LearnerResourceTest.java b/backend/src/test/java/de/learnlib/alex/learning/rest/LearnerResourceTest.java index 1f3654eb8..68a65b1f6 100644 --- a/backend/src/test/java/de/learnlib/alex/learning/rest/LearnerResourceTest.java +++ b/backend/src/test/java/de/learnlib/alex/learning/rest/LearnerResourceTest.java @@ -297,7 +297,7 @@ public void shouldStopIfTheLearningIsActive() { Response response = target("/learner/" + PROJECT_TEST_ID + "/stop").request().header("Authorization", adminToken).get(); assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); - verify(learner).stop(admin); + verify(learner).stop(PROJECT_TEST_ID); } @Test @@ -312,7 +312,7 @@ public void shouldNotStopIfTheLearningIsNotActive() { assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); String expectedJSON = "{\"active\":false}"; assertEquals(expectedJSON, response.readEntity(String.class)); - verify(learner, never()).stop(admin); + verify(learner, never()).stop(PROJECT_TEST_ID); } @Test diff --git a/backend/src/test/java/de/learnlib/alex/learning/services/LearnerTest.java b/backend/src/test/java/de/learnlib/alex/learning/services/LearnerTest.java index 35fef0556..eedf8f972 100644 --- a/backend/src/test/java/de/learnlib/alex/learning/services/LearnerTest.java +++ b/backend/src/test/java/de/learnlib/alex/learning/services/LearnerTest.java @@ -118,7 +118,7 @@ public void shouldResumeAThread() throws NotFoundException { @Test public void shouldStopAThread() throws NotFoundException { - learner.stop(user); + learner.stop(-1L); } @Test diff --git a/build/pom.xml b/build/pom.xml index da677bbb3..c91427fea 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -23,7 +23,7 @@ alex-parent de.learnlib.alex - 1.5.0 + 1.5.1 ../pom.xml diff --git a/frontend/pom.xml b/frontend/pom.xml index a9dcb2cfa..a48705a92 100644 --- a/frontend/pom.xml +++ b/frontend/pom.xml @@ -24,7 +24,7 @@ alex-parent de.learnlib.alex - 1.5.0 + 1.5.1 ../pom.xml diff --git a/frontend/src/main/javascript/environments.js b/frontend/src/main/javascript/environments.js index f36ff3181..eb97476a8 100644 --- a/frontend/src/main/javascript/environments.js +++ b/frontend/src/main/javascript/environments.js @@ -18,7 +18,7 @@ * The version of ALEX. * @type {string} */ -export const version = '1.5.0'; +export const version = '1.5.1'; /** * API URL @@ -30,4 +30,3 @@ export const version = '1.5.0'; */ export const apiUrl = '/rest'; // export const apiUrl = 'http://localhost:8000/rest'; -// diff --git a/frontend/src/main/javascript/package-lock.json b/frontend/src/main/javascript/package-lock.json index 4004e6041..48aa4a555 100644 --- a/frontend/src/main/javascript/package-lock.json +++ b/frontend/src/main/javascript/package-lock.json @@ -1,6 +1,6 @@ { "name": "ALEX", - "version": "1.5.0", + "version": "1.5.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/frontend/src/main/javascript/package.json b/frontend/src/main/javascript/package.json index 569abef57..cf822ce8d 100644 --- a/frontend/src/main/javascript/package.json +++ b/frontend/src/main/javascript/package.json @@ -1,6 +1,6 @@ { "name": "ALEX", - "version": "1.5.0", + "version": "1.5.1", "description": "A web application for interring Mealy machines of web applications and RESTful web services via active automata learning.", "repository": { "type": "git", diff --git a/frontend/src/main/javascript/src/js/components/modals/project-edit-modal/project-edit-modal.component.html b/frontend/src/main/javascript/src/js/components/modals/project-edit-modal/project-edit-modal.component.html index e470204e6..1e88a047c 100644 --- a/frontend/src/main/javascript/src/js/components/modals/project-edit-modal/project-edit-modal.component.html +++ b/frontend/src/main/javascript/src/js/components/modals/project-edit-modal/project-edit-modal.component.html @@ -8,6 +8,10 @@