From cbb4803a812c06ab04c4e7897616515c689d2c52 Mon Sep 17 00:00:00 2001 From: Toni Rikkola Date: Thu, 6 Jun 2024 12:35:10 +0300 Subject: [PATCH] DROOLS-7618 : Project Editor: Long description should not freeze the UI (#3825) --- .../DescriptionLengthValidator.java | 33 ++++++++++ .../LibraryProjectPreferences.java | 3 +- .../DescriptionLengthValidatorTest.java | 57 +++++++++++++++++ .../resources/i18n/LibraryConstants.java | 3 + .../project/AddProjectPopUpPresenter.java | 21 ++++++- .../screens/project/AddProjectPopUpView.java | 5 ++ .../GeneralSettingsPresenter.java | 19 +++++- .../generalsettings/GeneralSettingsView.java | 5 ++ .../i18n/LibraryConstants.properties | 1 + .../project/AddProjectPopUpPresenterTest.java | 51 ++++++++++++++- .../GeneralSettingsPresenterTest.java | 63 +++++++++++++++++++ 11 files changed, 256 insertions(+), 5 deletions(-) create mode 100644 kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-api/src/main/java/org/kie/workbench/common/screens/library/api/preferences/DescriptionLengthValidator.java create mode 100644 kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-api/src/test/java/org/kie/workbench/common/screens/library/api/preferences/DescriptionLengthValidatorTest.java diff --git a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-api/src/main/java/org/kie/workbench/common/screens/library/api/preferences/DescriptionLengthValidator.java b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-api/src/main/java/org/kie/workbench/common/screens/library/api/preferences/DescriptionLengthValidator.java new file mode 100644 index 00000000000..62b5a42a313 --- /dev/null +++ b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-api/src/main/java/org/kie/workbench/common/screens/library/api/preferences/DescriptionLengthValidator.java @@ -0,0 +1,33 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.workbench.common.screens.library.api.preferences; + +import org.uberfire.preferences.shared.impl.validation.StringPropertyValidator; + +public class DescriptionLengthValidator extends StringPropertyValidator { + + private static final int DESCRIPTION_MAX_LENGTH = 3000; + + public DescriptionLengthValidator() { + super(DescriptionLengthValidator::lengthCheck, + "PropertyValidator.ConstrainedValuesValidator.NotAllowed"); + } + + private static boolean lengthCheck(final String description) { + return description == null || description.length() <= DESCRIPTION_MAX_LENGTH; + } +} diff --git a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-api/src/main/java/org/kie/workbench/common/screens/library/api/preferences/LibraryProjectPreferences.java b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-api/src/main/java/org/kie/workbench/common/screens/library/api/preferences/LibraryProjectPreferences.java index bc626e6131d..8d3211170eb 100644 --- a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-api/src/main/java/org/kie/workbench/common/screens/library/api/preferences/LibraryProjectPreferences.java +++ b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-api/src/main/java/org/kie/workbench/common/screens/library/api/preferences/LibraryProjectPreferences.java @@ -36,7 +36,8 @@ public class LibraryProjectPreferences implements BasePreference, HasBusyIndicator { @@ -133,6 +135,8 @@ void setTemplates(List templates, void enableBasedOnTemplatesCheckbox(boolean isEnabled); void enableTemplatesSelect(boolean isEnabled); + + String getDescriptionTooLongMessage(); } private Caller libraryService; @@ -300,6 +304,7 @@ private void createProject(final DeploymentMode mode) { groupId, artifactId, version, + description, () -> { Map, CommandWithThrowableDrivenErrorCallback.CommandWithThrowable> errors = new HashMap, CommandWithThrowableDrivenErrorCallback.CommandWithThrowable>() {{ put(GAVAlreadyExistsException.class, exception -> handleGAVAlreadyExistsException((GAVAlreadyExistsException) exception)); @@ -358,6 +363,7 @@ private void validateFields(final String name, final String groupId, final String artifactId, final String version, + final String description, final Command successCallback) { final Command validateVersion = () -> validateVersion(version, successCallback); @@ -365,8 +371,15 @@ private void validateFields(final String name, validateVersion); final Command validateGroupId = () -> validateGroupId(groupId, validateArtifactId); - validateName(name, - view.isAdvancedOptionsSelected() ? validateGroupId : successCallback); + + + if (!isDescriptionValid(description)) { + endProjectCreation(); + view.showError(view.getDescriptionTooLongMessage()); + } else { + validateName(name, + view.isAdvancedOptionsSelected() ? validateGroupId : successCallback); + } } private void validateName(final String name, @@ -389,6 +402,10 @@ private void validateName(final String name, }).isProjectNameValid(name); } + private boolean isDescriptionValid(final String description) { + return description == null || description.length() <= DESCRIPTION_MAX_LENGTH; + } + private void validateGroupId(final String groupId, final Command successCallback) { if (groupId == null || groupId.trim().isEmpty()) { diff --git a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/screens/project/AddProjectPopUpView.java b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/screens/project/AddProjectPopUpView.java index b725bddcc95..9ac3bfcda32 100644 --- a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/screens/project/AddProjectPopUpView.java +++ b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/screens/project/AddProjectPopUpView.java @@ -310,6 +310,11 @@ public void enableTemplatesSelect(boolean isEnabled) { enableBasedOnTemplate(isEnabled); } + @Override + public String getDescriptionTooLongMessage() { + return ts.format(LibraryConstants.DescriptionTooLong); + } + private void modalSetup() { this.modal = new CommonModalBuilder() .addHeader(ts.format(LibraryConstants.AddProject)) diff --git a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsPresenter.java b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsPresenter.java index fe10ad24232..33e46b41ea3 100644 --- a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsPresenter.java +++ b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsPresenter.java @@ -40,6 +40,8 @@ public class GeneralSettingsPresenter extends Section { + private static final int DESCRIPTION_MAX_LENGTH = 3000; + public interface View extends SectionView { String getName(); @@ -93,6 +95,8 @@ public interface View extends SectionView { String getInvalidVersionMessage(); String getDuplicatedProjectNameMessage(); + + String getDescriptionTooLongMessage(); } @@ -179,7 +183,10 @@ public Promise validate() { validateStringIsNotEmpty(pom.getGav().getVersion(), view.getEmptyVersionMessage()) .then(o -> executeValidation(s -> s.validateGAVVersion(pom.getGav().getVersion()), view.getInvalidVersionMessage())) - .catch_(this::showErrorAndReject) + .catch_(this::showErrorAndReject), + + + validateDescriptionLength().catch_(this::showErrorAndReject) ); } @@ -205,6 +212,16 @@ Promise validateStringIsNotEmpty(final String string, }); } + private Promise validateDescriptionLength() { + return promises.create((resolve, reject) -> { + if(pom.getDescription() != null && pom.getDescription().length() > DESCRIPTION_MAX_LENGTH){ + reject.onInvoke(view.getDescriptionTooLongMessage()); + } else { + resolve.onInvoke(true); + } + }); + } + Promise executeValidation(final Caller caller, final Function call, final String errorMessage) { diff --git a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsView.java b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsView.java index 737a2da1326..bb7d532b2e8 100644 --- a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsView.java +++ b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsView.java @@ -279,6 +279,11 @@ public String getDuplicatedProjectNameMessage() { return translationService.format(LibraryConstants.DuplicatedProjectName); } + @Override + public String getDescriptionTooLongMessage() { + return translationService.format(LibraryConstants.DescriptionTooLong); + } + @Override public String getTitle() { return title.textContent; diff --git a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/resources/org/kie/workbench/common/screens/library/client/resources/i18n/LibraryConstants.properties b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/resources/org/kie/workbench/common/screens/library/client/resources/i18n/LibraryConstants.properties index d2365287a13..47ef83ca2e2 100644 --- a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/resources/org/kie/workbench/common/screens/library/client/resources/i18n/LibraryConstants.properties +++ b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/main/resources/org/kie/workbench/common/screens/library/client/resources/i18n/LibraryConstants.properties @@ -605,3 +605,4 @@ ViewDeploymentDetails=View deployment details Archetypes=Archetypes ArchetypesDescription=Select all archetypes that will be available as templates for new projects, as well as a default one. This configuration is only applicable to this space. InvalidProjectPath=No project found in the informed path. +DescriptionTooLong=Description is too long. \ No newline at end of file diff --git a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/test/java/org/kie/workbench/common/screens/library/client/screens/project/AddProjectPopUpPresenterTest.java b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/test/java/org/kie/workbench/common/screens/library/client/screens/project/AddProjectPopUpPresenterTest.java index 67c3b1477f2..a9aceda65ea 100644 --- a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/test/java/org/kie/workbench/common/screens/library/client/screens/project/AddProjectPopUpPresenterTest.java +++ b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/test/java/org/kie/workbench/common/screens/library/client/screens/project/AddProjectPopUpPresenterTest.java @@ -223,6 +223,25 @@ public void newProjectIsCreated() throws Exception { verify(view).setAddButtonEnabled(true); } + @Test + public void newProjectIsCreatedDescriptionIsTooLong() throws Exception { + final OrganizationalUnit organizationalUnit = mock(OrganizationalUnit.class); + when(projectContext.getActiveOrganizationalUnit()).thenReturn(Optional.of(organizationalUnit)); + + doReturn("test").when(view).getName(); + doReturn(get3001CharString()).when(view).getDescription(); + + presenter.add(); + + + verify(libraryService, never()).createProject( + any(), + any(), + any(), + Mockito. any() + ); + } + @Test public void newWorkbenchProjectWithAdvancedSettingsIsCreated() throws Exception { final OrganizationalUnit organizationalUnit = mock(OrganizationalUnit.class); @@ -259,7 +278,29 @@ public void newWorkbenchProjectWithAdvancedSettingsIsCreated() throws Exception assertEquals("org.kie", pom.getBuild().getPlugins().get(0).getGroupId()); assertEquals("kie-maven-plugin", pom.getBuild().getPlugins().get(0).getArtifactId()); } - + + @Test + public void newWorkbenchProjectWithAdvancedSettingsTooLongDescription() throws Exception { + final OrganizationalUnit organizationalUnit = mock(OrganizationalUnit.class); + when(projectContext.getActiveOrganizationalUnit()).thenReturn(Optional.of(organizationalUnit)); + + doReturn("test").when(view).getName(); + doReturn(get3001CharString()).when(view).getDescription(); + doReturn("groupId").when(view).getGroupId(); + doReturn("artifactId").when(view).getArtifactId(); + doReturn("version").when(view).getVersion(); + doReturn(true).when(view).isAdvancedOptionsSelected(); + + presenter.add(); + + verify(libraryService, never()).createProject( + any(), + any(), + any(), + Mockito. any()); + + } + @Test public void newWorkbenchProjectWithQuickSettingsIsCreated() throws Exception { final OrganizationalUnit organizationalUnit = mock(OrganizationalUnit.class); @@ -776,4 +817,12 @@ public void testLoadTemplatesWhenNoOneAvailable() { verify(view).enableBasedOnTemplatesCheckbox(false); verify(view).enableTemplatesSelect(false); } + + private static String get3001CharString() { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < 3001; i++) { + builder.append("x"); + } + return builder.toString(); + } } diff --git a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/test/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsPresenterTest.java b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/test/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsPresenterTest.java index 32f4b582a9d..591924e5e95 100644 --- a/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/test/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsPresenterTest.java +++ b/kie-wb-common-screens/kie-wb-common-library/kie-wb-common-library-client/src/test/java/org/kie/workbench/common/screens/library/client/settings/sections/generalsettings/GeneralSettingsPresenterTest.java @@ -295,6 +295,69 @@ public void testValidateWithOneError() { never()).isProjectNameValid(any()); } + @Test + public void testValidateDescriptionDescriptionOk() { + + generalSettingsPresenter.pom = new POM("", + null, + "", + new GAV()); + + doReturn("DescriptionTooLong").when(view).getDescriptionTooLongMessage(); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < 3000; i++) { + builder.append("x"); + } + generalSettingsPresenter.setDescription(builder.toString()); + + generalSettingsPresenter.validate().then(i -> { + Assert.fail("Promise should've not been resolved!"); + return promises.resolve(); + }); + + verify(generalSettingsPresenter, never()).showErrorAndReject(eq("DescriptionTooLong")); + } + @Test + public void testValidateDescriptionDescriptionNull() { + + generalSettingsPresenter.pom = new POM("", + null, + "", + new GAV()); + + doReturn("DescriptionTooLong").when(view).getDescriptionTooLongMessage(); + + generalSettingsPresenter.validate().then(i -> { + Assert.fail("Promise should've not been resolved!"); + return promises.resolve(); + }); + + verify(generalSettingsPresenter, never()).showErrorAndReject(eq("DescriptionTooLong")); + } + + @Test + public void testValidateDescriptionDescriptionTooLong() { + + generalSettingsPresenter.pom = new POM("", + null, + "", + new GAV()); + + doReturn("DescriptionTooLong").when(view).getDescriptionTooLongMessage(); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < 3001; i++) { + builder.append("x"); + } + generalSettingsPresenter.setDescription(builder.toString()); + + generalSettingsPresenter.validate().then(i -> { + Assert.fail("Promise should've not been resolved!"); + return promises.resolve(); + }); + + verify(generalSettingsPresenter).showErrorAndReject(eq("DescriptionTooLong")); + } + @Test public void testShowErrorAndRejectWithException() { final RuntimeException testException = new RuntimeException("Test message");