From 6bdfc8f60aec913a3dac20180929d5d0e23a7a09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Dec 2024 09:45:57 +0100 Subject: [PATCH 01/15] chore(deps): bump com.nimbusds:nimbus-jose-jwt from 9.47 to 9.48 (#20779) Bumps [com.nimbusds:nimbus-jose-jwt](https://bitbucket.org/connect2id/nimbus-jose-jwt) from 9.47 to 9.48. - [Changelog](https://bitbucket.org/connect2id/nimbus-jose-jwt/src/master/CHANGELOG.txt) - [Commits](https://bitbucket.org/connect2id/nimbus-jose-jwt/branches/compare/9.48..9.47) --- updated-dependencies: - dependency-name: com.nimbusds:nimbus-jose-jwt dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- flow-tests/vaadin-spring-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-tests/vaadin-spring-tests/pom.xml b/flow-tests/vaadin-spring-tests/pom.xml index 417981f7bca..e11d87af7bf 100644 --- a/flow-tests/vaadin-spring-tests/pom.xml +++ b/flow-tests/vaadin-spring-tests/pom.xml @@ -17,7 +17,7 @@ true 24.6.0 - 9.47 + 9.48 From 4d1c045ab9b1f14ee02e97fc4fdbabd5e3e7a64e Mon Sep 17 00:00:00 2001 From: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com> Date: Fri, 27 Dec 2024 12:35:25 +0200 Subject: [PATCH 02/15] chore: Remove unused declarations in flow-server and flow-data (#20778) Related-to #16668 --- .../client/flow/GwtEventHandlerTest.java | 6 ---- .../vaadin/flow/dom/ChildElementConsumer.java | 2 -- .../main/java/com/vaadin/flow/dom/Node.java | 36 ------------------- .../flow/internal/menu/MenuRegistry.java | 3 -- .../nodefeature/ElementPropertyMap.java | 23 ++++++------ .../router/AbstractRouteNotFoundError.java | 4 +-- .../vaadin/flow/server/AppShellRegistry.java | 9 ++--- .../DeploymentConfigurationFactory.java | 5 ++- .../IndexHtmlRequestHandler.java | 2 +- .../server/communication/PushHandler.java | 3 +- .../communication/rpc/MapSyncRpcHandler.java | 9 ++--- .../dau/DAUVaadinRequestInterceptor.java | 2 -- .../flow/server/frontend/NodeUpdater.java | 5 +-- .../frontend/TaskCopyTemplateFiles.java | 4 --- .../server/frontend/TaskGeneratePWAIcons.java | 7 ---- .../server/frontend/TaskGenerateTsConfig.java | 2 +- .../frontend/TaskRunDevBundleBuild.java | 8 ++--- .../server/frontend/VersionsJsonFilter.java | 2 -- .../scanner/FullDependenciesScanner.java | 13 ------- .../flow/server/startup/ServletDeployer.java | 7 ++-- .../webcomponent/WebComponentGenerator.java | 1 - .../vaadin/flow/internal/JsonUtilsTest.java | 13 +------ 22 files changed, 29 insertions(+), 137 deletions(-) diff --git a/flow-client/src/test-gwt/java/com/vaadin/client/flow/GwtEventHandlerTest.java b/flow-client/src/test-gwt/java/com/vaadin/client/flow/GwtEventHandlerTest.java index 562bc6b5428..86f9ec59179 100644 --- a/flow-client/src/test-gwt/java/com/vaadin/client/flow/GwtEventHandlerTest.java +++ b/flow-client/src/test-gwt/java/com/vaadin/client/flow/GwtEventHandlerTest.java @@ -254,12 +254,6 @@ private void assertPublishedMethods(Element element, String[] expected) { expected); } - private void assertPolymerMethods(Element element, String[] expected) { - ServerEventObject object = WidgetUtil.crazyJsoCast(element); - assertEventHandlerMethods(() -> getPublishedServerMethods(object), - expected); - } - private void assertEventHandlerMethods( Supplier> methodsProvider, String... expected) { JsArray publishedServerMethods = methodsProvider.get(); diff --git a/flow-server/src/main/java/com/vaadin/flow/dom/ChildElementConsumer.java b/flow-server/src/main/java/com/vaadin/flow/dom/ChildElementConsumer.java index 23ce831b283..b5496df8054 100644 --- a/flow-server/src/main/java/com/vaadin/flow/dom/ChildElementConsumer.java +++ b/flow-server/src/main/java/com/vaadin/flow/dom/ChildElementConsumer.java @@ -22,8 +22,6 @@ * Callback which allows to handle request to map a client side DOM element to * the server {@link Element} instance. * - * @see Node#attachExistingElement(String, Element, ChildElementConsumer) - * * @author Vaadin Ltd * @since 1.0 * diff --git a/flow-server/src/main/java/com/vaadin/flow/dom/Node.java b/flow-server/src/main/java/com/vaadin/flow/dom/Node.java index 89716639b4f..8d43d0ebbcb 100644 --- a/flow-server/src/main/java/com/vaadin/flow/dom/Node.java +++ b/flow-server/src/main/java/com/vaadin/flow/dom/Node.java @@ -596,40 +596,4 @@ protected void ensureChildHasParent(Element child, boolean internalCheck) { } } } - - /** - * Attaches a child element with the given {@code tagName} which is the next - * sibling for the {@code previousSibling}. - *

- * The {@code previousSibling} parameter value can be {@code null} which - * means that the very first child with the given {@code tagName} will be - * used to attach (if any). - *

- * This method may be used to get a server side element for the client side - * DOM element which has been created on the client side aside of the - * server. - *

- * The element is not returned right away since it may not exist at all on - * the client side and its index in the children list is unknown. The - * provided {@code callback} is used instead to provide the mapped - * server-side element in case it has been found or report an error if it - * doesn't exist. - *

- * This API is experimental and disabled for public usage. - * - * @param tagName - * the tag name of the element to attach, not {@code null} - * @param previousSibling - * previous sibling, may be {@code null} - * @param callback - * the callback which will be invoked with a server side element - * instance or an error will be reported, not {@code null} - * @return this element - */ - private N attachExistingElement(String tagName, Element previousSibling, - ChildElementConsumer callback) { - getStateProvider().attachExistingElement(getNode(), tagName, - previousSibling, callback); - return getSelf(); - } } diff --git a/flow-server/src/main/java/com/vaadin/flow/internal/menu/MenuRegistry.java b/flow-server/src/main/java/com/vaadin/flow/internal/menu/MenuRegistry.java index 64c29b0f18f..481870df3ad 100644 --- a/flow-server/src/main/java/com/vaadin/flow/internal/menu/MenuRegistry.java +++ b/flow-server/src/main/java/com/vaadin/flow/internal/menu/MenuRegistry.java @@ -70,9 +70,6 @@ */ public class MenuRegistry { - private static final Logger log = LoggerFactory - .getLogger(MenuRegistry.class); - /** * File routes lazy loading and caching. */ diff --git a/flow-server/src/main/java/com/vaadin/flow/internal/nodefeature/ElementPropertyMap.java b/flow-server/src/main/java/com/vaadin/flow/internal/nodefeature/ElementPropertyMap.java index 9134c611280..e272798a2ba 100644 --- a/flow-server/src/main/java/com/vaadin/flow/internal/nodefeature/ElementPropertyMap.java +++ b/flow-server/src/main/java/com/vaadin/flow/internal/nodefeature/ElementPropertyMap.java @@ -200,7 +200,7 @@ protected Serializable remove(String key) { @Override protected boolean mayUpdateFromClient(String key, Serializable value) { - return allowUpdateFromClient(key, value); + return allowUpdateFromClient(key); } @Override @@ -212,7 +212,7 @@ protected boolean producePutChange(String key, boolean hadValueEarlier, return super.producePutChange(key, hadValueEarlier, newValue); } - private boolean allowUpdateFromClient(String key, Serializable value) { + private boolean allowUpdateFromClient(String key) { AllowUpdate isAllowed = isUpdateFromClientAllowedBeforeFilter(key); if (!AllowUpdate.NO_EXPLICIT_STATUS.equals(isAllowed)) { return AllowUpdate.EXPLICITLY_ALLOW.equals(isAllowed); @@ -476,19 +476,18 @@ private static Logger getLogger() { /** * The method first checks whether the update from client is allowed using - * the method {@link #allowUpdateFromClient(String, Serializable)}. Then if - * it's not allowed then it either throws or returns NO OPERATION runnable - * in case if {@link #updateFromClientFilter} disallows the update (in this - * case it's just an application business logic and we should not throw). + * the method {@link #allowUpdateFromClient(String)}. Then if it's not + * allowed then it either throws or returns NO OPERATION runnable in case if + * {@link #updateFromClientFilter} disallows the update (in this case it's + * just an application business logic and we should not throw). * - * The logic inside the {@link #allowUpdateFromClient(String, Serializable)} - * check block repeats its own logic to make sure that: + * The logic inside the {@link #allowUpdateFromClient(String)} check block + * repeats its own logic to make sure that: *

    - *
  • It's in sync with - * {@link #allowUpdateFromClient(String, Serializable)} (and + *
  • It's in sync with {@link #allowUpdateFromClient(String)} (and * {@link #mayUpdateFromClient(String, Serializable)} *
  • The update is disallowed by the filter (and not some other checks - * that are inside {@link #allowUpdateFromClient(String, Serializable)} + * that are inside {@link #allowUpdateFromClient(String)} *
      * * Here is the logic flow: @@ -555,7 +554,7 @@ private Runnable doDeferredUpdateFromClient(String key, Serializable value) // Use private allowUpdateFromClient method instead of // mayUpdateFromClient which may be overridden // The logic below - if (!allowUpdateFromClient(key, value)) { + if (!allowUpdateFromClient(key)) { if (isDisallowedByFilter(key)) { return () -> { // nop diff --git a/flow-server/src/main/java/com/vaadin/flow/router/AbstractRouteNotFoundError.java b/flow-server/src/main/java/com/vaadin/flow/router/AbstractRouteNotFoundError.java index 76e772f98d0..f2ea253d07b 100644 --- a/flow-server/src/main/java/com/vaadin/flow/router/AbstractRouteNotFoundError.java +++ b/flow-server/src/main/java/com/vaadin/flow/router/AbstractRouteNotFoundError.java @@ -131,12 +131,12 @@ private String getRoutes(BeforeEnterEvent event) { routeTemplates.forEach( (k, v) -> routeElements.add(routeTemplateToHtml(k, v))); - routeElements.addAll(getClientRoutes(event)); + routeElements.addAll(getClientRoutes()); return routeElements.stream().map(Element::outerHtml) .collect(Collectors.joining()); } - private List getClientRoutes(BeforeEnterEvent event) { + private List getClientRoutes() { return FrontendUtils.getClientRoutes().stream() .filter(route -> !route.contains("$layout")) .map(route -> route.replace("$index", "")) diff --git a/flow-server/src/main/java/com/vaadin/flow/server/AppShellRegistry.java b/flow-server/src/main/java/com/vaadin/flow/server/AppShellRegistry.java index e72876864f4..bde81ddd6d4 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/AppShellRegistry.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/AppShellRegistry.java @@ -36,7 +36,6 @@ import com.vaadin.flow.component.page.Push; import com.vaadin.flow.component.page.TargetElement; import com.vaadin.flow.component.page.Viewport; -import com.vaadin.flow.di.Lookup; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.theme.Theme; @@ -72,8 +71,6 @@ public class AppShellRegistry implements Serializable { private Class appShellClass; - private final Lookup lookup; - /** * A wrapper class for storing the {@link AppShellRegistry} instance in the * servlet context. @@ -92,8 +89,7 @@ public AppShellRegistryWrapper(AppShellRegistry registry) { } } - private AppShellRegistry(VaadinContext context) { - this.lookup = context.getAttribute(Lookup.class); + private AppShellRegistry() { } /** @@ -109,8 +105,7 @@ public static AppShellRegistry getInstance(VaadinContext context) { AppShellRegistryWrapper attribute = context .getAttribute(AppShellRegistryWrapper.class); if (attribute == null) { - attribute = new AppShellRegistryWrapper( - new AppShellRegistry(context)); + attribute = new AppShellRegistryWrapper(new AppShellRegistry()); context.setAttribute(attribute); } return attribute.registry; diff --git a/flow-server/src/main/java/com/vaadin/flow/server/DeploymentConfigurationFactory.java b/flow-server/src/main/java/com/vaadin/flow/server/DeploymentConfigurationFactory.java index 6e2a69194ef..128b6963fea 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/DeploymentConfigurationFactory.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/DeploymentConfigurationFactory.java @@ -105,12 +105,11 @@ protected Properties createInitParameters(Class systemPropertyBaseClass, } } - readBuildInfo(initParameters, vaadinConfig.getVaadinContext()); + readBuildInfo(initParameters); return initParameters; } - private void readBuildInfo(Properties initParameters, - VaadinContext context) { + private void readBuildInfo(Properties initParameters) { String json = getTokenFileContent(initParameters::getProperty); // Read the json and set the appropriate system properties if not // already set. diff --git a/flow-server/src/main/java/com/vaadin/flow/server/communication/IndexHtmlRequestHandler.java b/flow-server/src/main/java/com/vaadin/flow/server/communication/IndexHtmlRequestHandler.java index 36e3bfe1127..1d22fedf738 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/communication/IndexHtmlRequestHandler.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/communication/IndexHtmlRequestHandler.java @@ -226,7 +226,7 @@ private static void addDevBundleTheme(Document document, } private void applyThemeVariant(Document indexDocument, - VaadinContext context) throws IOException { + VaadinContext context) { ThemeUtils.getThemeAnnotation(context).ifPresent(theme -> { String variant = theme.variant(); if (!variant.isEmpty()) { diff --git a/flow-server/src/main/java/com/vaadin/flow/server/communication/PushHandler.java b/flow-server/src/main/java/com/vaadin/flow/server/communication/PushHandler.java index 06b0965b91f..e7ebe18d306 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/communication/PushHandler.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/communication/PushHandler.java @@ -545,8 +545,7 @@ private static UI findUiUsingResource(AtmosphereResource resource, * The atmosphere resource to send refresh to * */ - private static void sendRefreshAndDisconnect(AtmosphereResource resource) - throws IOException { + private static void sendRefreshAndDisconnect(AtmosphereResource resource) { sendNotificationAndDisconnect(resource, VaadinService .createCriticalNotificationJSON(null, null, null, null)); } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/communication/rpc/MapSyncRpcHandler.java b/flow-server/src/main/java/com/vaadin/flow/server/communication/rpc/MapSyncRpcHandler.java index eb41a716f02..9254039bf3b 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/communication/rpc/MapSyncRpcHandler.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/communication/rpc/MapSyncRpcHandler.java @@ -93,15 +93,13 @@ protected Optional handleNode(StateNode node, .reduce(DisabledUpdateMode::mostPermissive).orElse(null); if (isEnabled) { - return enqueuePropertyUpdate(node, invocationJson, feature, - property); + return enqueuePropertyUpdate(node, invocationJson, property); } else if (DisabledUpdateMode.ALWAYS.equals(updateMode)) { LoggerFactory.getLogger(MapSyncRpcHandler.class).trace( "Property update request for disabled element is received from the client side. " + "Change will be applied since the property '{}' always allows its update.", property); - return enqueuePropertyUpdate(node, invocationJson, feature, - property); + return enqueuePropertyUpdate(node, invocationJson, property); } else { final Logger logger = LoggerFactory .getLogger(MapSyncRpcHandler.class); @@ -124,8 +122,7 @@ protected Optional handleNode(StateNode node, } private Optional enqueuePropertyUpdate(StateNode node, - JsonObject invocationJson, Class feature, - String property) { + JsonObject invocationJson, String property) { Serializable value = JsonCodec.decodeWithoutTypeInfo( invocationJson.get(JsonConstants.RPC_PROPERTY_VALUE)); diff --git a/flow-server/src/main/java/com/vaadin/flow/server/dau/DAUVaadinRequestInterceptor.java b/flow-server/src/main/java/com/vaadin/flow/server/dau/DAUVaadinRequestInterceptor.java index 946defddee2..3c08eed80ce 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/dau/DAUVaadinRequestInterceptor.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/dau/DAUVaadinRequestInterceptor.java @@ -25,7 +25,6 @@ public class DAUVaadinRequestInterceptor implements VaadinRequestInterceptor, private final String applicationName; private final UserIdentitySupplier userIdentitySupplier; - private final DAUCustomizer dauCustomizer; public DAUVaadinRequestInterceptor( DeploymentConfiguration deploymentConfiguration, @@ -34,7 +33,6 @@ public DAUVaadinRequestInterceptor( this.userIdentitySupplier = dauCustomizer != null ? dauCustomizer.getUserIdentitySupplier() : null; - this.dauCustomizer = dauCustomizer; } @Override diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/NodeUpdater.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/NodeUpdater.java index 21f6f0fa1f6..67d8763f1e9 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/NodeUpdater.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/NodeUpdater.java @@ -583,11 +583,8 @@ protected void generateVersionsJson(JsonObject packageJson) * defined packages. * * @return versions Json based on package.json - * @throws IOException - * If reading package.json fails */ - private JsonObject generateVersionsFromPackageJson(JsonObject packageJson) - throws IOException { + private JsonObject generateVersionsFromPackageJson(JsonObject packageJson) { JsonObject versionsJson = Json.createObject(); // if we don't have versionsJson lock package dependency versions. final JsonObject dependencies = packageJson.getObject(DEPENDENCIES); diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskCopyTemplateFiles.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskCopyTemplateFiles.java index 93a41c70b66..3be0e1b456e 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskCopyTemplateFiles.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskCopyTemplateFiles.java @@ -107,8 +107,4 @@ private String getJsModuleAnnotationValue(Annotation jsmAnnotation) throw new ExecutionFailedException(e); } } - - Logger log() { - return LoggerFactory.getLogger(getClass()); - } } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskGeneratePWAIcons.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskGeneratePWAIcons.java index 52a0cbbead2..60e2af8cdb9 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskGeneratePWAIcons.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskGeneratePWAIcons.java @@ -182,13 +182,6 @@ private CompletableFuture generateIcon(InternalPwaIcon icon) { }); } - private BufferedImage getBaseImage(URL logo) throws IOException { - URLConnection logoResource = logo != null ? logo.openConnection() - : BootstrapHandler.class.getResource("default-logo.png") - .openConnection(); - return ImageIO.read(logoResource.getInputStream()); - } - private static class InternalPwaIcon extends PwaIcon { private final BufferedImage baseImage; diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskGenerateTsConfig.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskGenerateTsConfig.java index 256468962fe..d8b5eae9aa1 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskGenerateTsConfig.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskGenerateTsConfig.java @@ -174,7 +174,7 @@ protected boolean shouldGenerate() { return !getGeneratedFile().exists(); } - private void overrideIfObsolete() throws ExecutionFailedException { + private void overrideIfObsolete() { try { // Project's TS config File projectTsConfigFile = new File( diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskRunDevBundleBuild.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskRunDevBundleBuild.java index b260781858e..9be2a712008 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskRunDevBundleBuild.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskRunDevBundleBuild.java @@ -22,9 +22,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; @@ -98,8 +96,7 @@ public void execute() throws ExecutionFailedException { getLogger().info( "Creating a new development mode bundle. This can take a while but will only run when the project setup is changed, addons are added or frontend files are modified"); - runFrontendBuildTool("Vite", "vite/bin/vite.js", Collections.emptyMap(), - "build"); + runFrontendBuildTool("Vite", "vite/bin/vite.js", "build"); copyPackageLockToBundleFolder(); @@ -111,8 +108,7 @@ private static Logger getLogger() { } private void runFrontendBuildTool(String toolName, String executable, - Map environment, String... params) - throws ExecutionFailedException { + String... params) throws ExecutionFailedException { Logger logger = getLogger(); FrontendToolsSettings settings = new FrontendToolsSettings( diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/VersionsJsonFilter.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/VersionsJsonFilter.java index 3e603f3a52d..4f9914b04e9 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/VersionsJsonFilter.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/VersionsJsonFilter.java @@ -33,7 +33,6 @@ class VersionsJsonFilter { private final JsonObject userManagedDependencies; - private final JsonObject vaadinVersions; private final String dependenciesKey; @@ -42,7 +41,6 @@ class VersionsJsonFilter { VersionsJsonFilter(JsonObject packageJson, String dependenciesKey) { this.dependenciesKey = dependenciesKey; userManagedDependencies = collectUserManagedDependencies(packageJson); - vaadinVersions = collectFrameworkVersions(packageJson); } /** diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/scanner/FullDependenciesScanner.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/scanner/FullDependenciesScanner.java index 3f154b00fdd..420f64690a2 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/scanner/FullDependenciesScanner.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/scanner/FullDependenciesScanner.java @@ -81,19 +81,6 @@ class FullDependenciesScanner extends AbstractDependenciesScanner { private final SerializableBiFunction, Class, List> annotationFinder; - /** - * Creates a new scanner instance which discovers all dependencies in the - * classpath. - * - * @param finder - * a class finder - * @param featureFlags - * available feature flags and their status - */ - FullDependenciesScanner(ClassFinder finder, FeatureFlags featureFlags) { - this(finder, AnnotationReader::getAnnotationsFor, featureFlags, true); - } - /** * Creates a new scanner instance which discovers all dependencies in the * classpath. diff --git a/flow-server/src/main/java/com/vaadin/flow/server/startup/ServletDeployer.java b/flow-server/src/main/java/com/vaadin/flow/server/startup/ServletDeployer.java index ea03327d8c8..2dc6ba8f4d6 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/startup/ServletDeployer.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/startup/ServletDeployer.java @@ -39,7 +39,6 @@ import com.vaadin.flow.server.VaadinServlet; import com.vaadin.flow.server.VaadinServletConfig; import com.vaadin.flow.server.VaadinServletContext; -import com.vaadin.flow.server.frontend.FrontendUtils; /** * Context listener that automatically registers Vaadin servlets. @@ -161,11 +160,11 @@ public void contextInitialized(ServletContextEvent sce) { ? createAppServlet(context) : null; - logServletCreation(servletCreation, context, productionMode); + logServletCreation(servletCreation, productionMode); } private void logServletCreation(VaadinServletCreation servletCreation, - ServletContext servletContext, boolean productionMode) { + boolean productionMode) { Logger logger = getLogger(); if (servletCreation == null || productionMode) { @@ -180,8 +179,6 @@ private void logServletCreation(VaadinServletCreation servletCreation, logger.warn(servletCreationMessage); } else { logger.info(servletCreationMessage); - ServletRegistration vaadinServlet = findVaadinServlet( - servletContext); } } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/webcomponent/WebComponentGenerator.java b/flow-server/src/main/java/com/vaadin/flow/server/webcomponent/WebComponentGenerator.java index 0915a6f181e..dbf3b22beef 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/webcomponent/WebComponentGenerator.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/webcomponent/WebComponentGenerator.java @@ -50,7 +50,6 @@ public class WebComponentGenerator { private static final String TOKEN_ATTRIBUTE_NAME = "_AttributeName_"; private static final String TOKEN_CHANGE_EVENT_NAME = "_ChangeEventName_"; private static final String TOKEN_PROPERTY_NAME = "_PropertyName_"; - private static final String HTML_TEMPLATE = "webcomponent-template.html"; private static final String JS_TEMPLATE = "webcomponent-template.js"; private static final String SCRIPT_TEMPLATE = "webcomponent-script-template.js"; private static final String CODE_PROPERTY_DEFAULT = "webcomponent-property-default.js"; diff --git a/flow-server/src/test/java/com/vaadin/flow/internal/JsonUtilsTest.java b/flow-server/src/test/java/com/vaadin/flow/internal/JsonUtilsTest.java index 931fb873e7d..9d83a0a89ba 100644 --- a/flow-server/src/test/java/com/vaadin/flow/internal/JsonUtilsTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/internal/JsonUtilsTest.java @@ -136,18 +136,6 @@ public void collectEmptyStream() { Assert.assertEquals(0, a.length()); } - public void createObjectStreamForNull() { - Assert.assertEquals(Stream.empty(), JsonUtils.objectStream(null)); - } - - public void createNumberStreamForNull() { - Assert.assertEquals(Stream.empty(), JsonUtils.numberStream(null)); - } - - public void createStreamForNull() { - Assert.assertEquals(Stream.empty(), JsonUtils.stream(null)); - } - @Test public void testStream() { JsonArray array = createTestArray1(); @@ -331,6 +319,7 @@ public static class ListAndMapBean { childBeanList.add(secondChild); } + // these getters are needed for bean serialization: public Map getIntegerMap() { return integerMap; } From 041dead3cd694059b77485a404c65015452311ce Mon Sep 17 00:00:00 2001 From: Artur Date: Mon, 30 Dec 2024 17:53:10 +0200 Subject: [PATCH 03/15] chore: Bump frontend dependencies (#20790) --- .../frontend/dependencies/react-router/package.json | 4 ++-- .../server/frontend/dependencies/vite/package.json | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/react-router/package.json b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/react-router/package.json index 12c5544f529..9b281635166 100644 --- a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/react-router/package.json +++ b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/react-router/package.json @@ -7,7 +7,7 @@ "react-router": "7.0.2" }, "devDependencies": { - "@types/react": "18.3.13", - "@types/react-dom": "18.3.1" + "@types/react": "18.3.18", + "@types/react-dom": "18.3.5" } } diff --git a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json index d39f68b5952..64b68221118 100644 --- a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json +++ b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json @@ -9,13 +9,13 @@ "license": "Apache-2.0", "dependencies": {}, "devDependencies": { - "vite": "6.0.5", + "vite": "6.0.6", "@vitejs/plugin-react": "4.3.4", - "@preact/signals-react-transform": "0.4.0", - "@rollup/plugin-replace": "6.0.1", - "@rollup/pluginutils": "5.1.3", + "@preact/signals-react-transform": "0.5.0", + "@rollup/plugin-replace": "6.0.2", + "@rollup/pluginutils": "5.1.4", "@babel/preset-react": "7.26.3", - "rollup-plugin-visualizer": "5.12.0", + "rollup-plugin-visualizer": "5.13.1", "rollup-plugin-brotli": "3.1.0", "vite-plugin-checker": "0.8.0", "workbox-build": "7.3.0", From 68b0fba4524b6bb38982fe76625d1b6dfb5f139c Mon Sep 17 00:00:00 2001 From: Marco Collovati Date: Tue, 31 Dec 2024 10:22:20 +0100 Subject: [PATCH 04/15] chore: use custom thread pool for vaadin-dev-server tasks (#20795) * chore: use custom thread pool for vaadin-dev-server tasks Vaadin dev-server executes long-running tasks (e.g. npm install) using the common ForkJoin pool. This can cause a slow startup or even timeouts when the pool size is very small. Using a dedicated executor for dev-server tasks should prevent the above issues. Fixes #20793 * nullify executor on shutdown --- .../testutil/ClassesSerializableTest.java | 1 + .../devserver/DevModeHandlerManagerImpl.java | 39 ++++++++++++++++--- .../devserver/startup/DevModeInitializer.java | 38 ++++++++++++++++-- 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/flow-test-generic/src/main/java/com/vaadin/flow/testutil/ClassesSerializableTest.java b/flow-test-generic/src/main/java/com/vaadin/flow/testutil/ClassesSerializableTest.java index ec072787948..ad32d5a2a86 100644 --- a/flow-test-generic/src/main/java/com/vaadin/flow/testutil/ClassesSerializableTest.java +++ b/flow-test-generic/src/main/java/com/vaadin/flow/testutil/ClassesSerializableTest.java @@ -79,6 +79,7 @@ protected Stream getExcludedPatterns() { "com\\.vaadin\\.base\\.devserver\\.DebugWindowConnection", "com\\.vaadin\\.base\\.devserver\\.DebugWindowConnection\\$DevToolsInterfaceImpl", "com\\.vaadin\\.base\\.devserver\\.DevModeHandlerManagerImpl", + "com\\.vaadin\\.base\\.devserver\\.DevModeHandlerManagerImpl\\$InternalThreadFactory", "com\\.vaadin\\.base\\.devserver\\.DevServerWatchDog", "com\\.vaadin\\.base\\.devserver\\.DevServerWatchDog\\$WatchDogServer", "com\\.vaadin\\.base\\.devserver\\.DevToolsInterface", diff --git a/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/DevModeHandlerManagerImpl.java b/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/DevModeHandlerManagerImpl.java index cde5c77efcd..f14d02fe656 100644 --- a/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/DevModeHandlerManagerImpl.java +++ b/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/DevModeHandlerManagerImpl.java @@ -15,18 +15,20 @@ */ package com.vaadin.base.devserver; -import com.vaadin.flow.server.Command; import jakarta.servlet.annotation.HandlesTypes; import java.io.Closeable; import java.io.File; -import java.io.IOException; import java.io.Serializable; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +37,7 @@ import com.vaadin.base.devserver.startup.DevModeStartupListener; import com.vaadin.flow.internal.DevModeHandler; import com.vaadin.flow.internal.DevModeHandlerManager; +import com.vaadin.flow.server.Command; import com.vaadin.flow.server.Mode; import com.vaadin.flow.server.VaadinContext; import com.vaadin.flow.server.frontend.FrontendUtils; @@ -68,6 +71,7 @@ private static final class DevModeHandlerAlreadyStartedAttribute private DevModeHandler devModeHandler; private BrowserLauncher browserLauncher; private final Set shutdownCommands = new HashSet<>(); + private ExecutorService executorService; private String applicationUrl; private boolean fullyStarted = false; @@ -96,8 +100,11 @@ public DevModeHandler getDevModeHandler() { @Override public void initDevModeHandler(Set> classes, VaadinContext context) throws VaadinInitializerException { - setDevModeHandler( - DevModeInitializer.initDevModeHandler(classes, context)); + shutdownExecutorService(); + executorService = Executors.newFixedThreadPool(4, + new InternalThreadFactory()); + setDevModeHandler(DevModeInitializer.initDevModeHandler(classes, + context, executorService)); CompletableFuture.runAsync(() -> { DevModeHandler devModeHandler = getDevModeHandler(); if (devModeHandler instanceof AbstractDevServerRunner) { @@ -111,11 +118,18 @@ public void initDevModeHandler(Set> classes, VaadinContext context) startWatchingThemeFolder(context, config); watchExternalDependencies(context, config); setFullyStarted(true); - }); + }, executorService); setDevModeStarted(context); this.browserLauncher = new BrowserLauncher(context); } + private void shutdownExecutorService() { + if (executorService != null) { + executorService.shutdownNow(); + executorService = null; + } + } + private void watchExternalDependencies(VaadinContext context, ApplicationConfiguration config) { File frontendFolder = FrontendUtils.getProjectFrontendDir(config); @@ -159,6 +173,7 @@ public void stopDevModeHandler() { devModeHandler.stop(); devModeHandler = null; } + shutdownExecutorService(); for (Command shutdownCommand : shutdownCommands) { try { shutdownCommand.execute(); @@ -231,4 +246,18 @@ public static boolean isDevModeAlreadyStarted(VaadinContext context) { private static Logger getLogger() { return LoggerFactory.getLogger(DevModeHandlerManagerImpl.class); } + + private static class InternalThreadFactory implements ThreadFactory { + private final AtomicInteger threadNumber = new AtomicInteger(1); + + @Override + public Thread newThread(Runnable runnable) { + String threadName = "vaadin-dev-server-" + + threadNumber.getAndIncrement(); + Thread thread = new Thread(runnable, threadName); + thread.setDaemon(true); + thread.setPriority(Thread.NORM_PRIORITY); + return thread; + } + } } diff --git a/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/startup/DevModeInitializer.java b/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/startup/DevModeInitializer.java index 6b7da24ee24..e2cfd862a38 100644 --- a/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/startup/DevModeInitializer.java +++ b/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/startup/DevModeInitializer.java @@ -39,6 +39,8 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; +import java.util.concurrent.Executor; +import java.util.concurrent.ForkJoinPool; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -74,9 +76,6 @@ import com.vaadin.flow.server.startup.VaadinInitializerException; import com.vaadin.pro.licensechecker.LicenseChecker; -import elemental.json.Json; -import elemental.json.JsonObject; - import static com.vaadin.flow.server.Constants.PACKAGE_JSON; import static com.vaadin.flow.server.Constants.PROJECT_FRONTEND_GENERATED_DIR_TOKEN; import static com.vaadin.flow.server.Constants.VAADIN_SERVLET_RESOURCES; @@ -169,6 +168,12 @@ private static Set calculateApplicableClassNames() { /** * Initialize the devmode server if not in production mode or compatibility * mode. + *

      + *

      + * Uses common ForkJoin pool to execute asynchronous tasks. It is + * recommended to use + * {@link #initDevModeHandler(Set, VaadinContext, Executor)} and provide a a + * custom executor if initialization starts long-running tasks. * * @param classes * classes to check for npm- and js modules @@ -179,9 +184,34 @@ private static Set calculateApplicableClassNames() { * * @throws VaadinInitializerException * if dev mode can't be initialized + * @deprecated use {@link #initDevModeHandler(Set, VaadinContext, Executor)} + * providing a custom executor. */ + @Deprecated(forRemoval = true) public static DevModeHandler initDevModeHandler(Set> classes, VaadinContext context) throws VaadinInitializerException { + return initDevModeHandler(classes, context, ForkJoinPool.commonPool()); + } + + /** + * Initialize the devmode server if not in production mode or compatibility + * mode. + * + * @param classes + * classes to check for npm- and js modules + * @param context + * VaadinContext we are running in + * @param taskExecutor + * the executor to use for asynchronous execution + * @return the initialized dev mode handler or {@code null} if none was + * created + * + * @throws VaadinInitializerException + * if dev mode can't be initialized + */ + public static DevModeHandler initDevModeHandler(Set> classes, + VaadinContext context, Executor taskExecutor) + throws VaadinInitializerException { ApplicationConfiguration config = ApplicationConfiguration.get(context); if (config.isProductionMode()) { @@ -317,7 +347,7 @@ public static DevModeHandler initDevModeHandler(Set> classes, }; CompletableFuture nodeTasksFuture = CompletableFuture - .runAsync(runnable); + .runAsync(runnable, taskExecutor); Lookup devServerLookup = Lookup.compose(lookup, Lookup.of(config, ApplicationConfiguration.class)); From 82f6c04cbadf9813919176ca742e1f5cae171bff Mon Sep 17 00:00:00 2001 From: Artur Date: Wed, 1 Jan 2025 16:09:57 +0200 Subject: [PATCH 05/15] chore: Bump react router (#20791) --- .../flow/server/frontend/dependencies/react-router/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/react-router/package.json b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/react-router/package.json index 9b281635166..e9faa28d9c6 100644 --- a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/react-router/package.json +++ b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/react-router/package.json @@ -4,7 +4,7 @@ "dependencies": { "react": "18.3.1", "react-dom": "18.3.1", - "react-router": "7.0.2" + "react-router": "7.1.1" }, "devDependencies": { "@types/react": "18.3.18", From e5ecb7f74344c471a46ac0a2e698dba72b239c8b Mon Sep 17 00:00:00 2001 From: Marco Collovati Date: Thu, 2 Jan 2025 06:06:31 +0100 Subject: [PATCH 06/15] chore: log all flow-build-info.json locations (#20787) --- .../startup/DefaultApplicationConfigurationFactory.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flow-server/src/main/java/com/vaadin/flow/server/startup/DefaultApplicationConfigurationFactory.java b/flow-server/src/main/java/com/vaadin/flow/server/startup/DefaultApplicationConfigurationFactory.java index aa341e52ba4..fa95a11521c 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/startup/DefaultApplicationConfigurationFactory.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/startup/DefaultApplicationConfigurationFactory.java @@ -216,9 +216,9 @@ && countInstances(viteGenerated.getPath(), "jar!/") >= 2) { if (resources.size() > 1) { String warningMessage = String.format( "Unable to fully determine correct flow-build-info.%n" - + "Accepting file '%s' first match of '%s' possible.%n" + + "Accepting file '%s' first match of '%s' possible (%s).%n" + "Please verify flow-build-info file content.", - firstResource.getPath(), resources.size()); + firstResource.getPath(), resources.size(), resources); getLogger().warn(warningMessage); } else { String debugMessage = String.format( From f2830a337ecac2e7a64990515acd79880d18c734 Mon Sep 17 00:00:00 2001 From: Marco Collovati Date: Thu, 2 Jan 2025 06:43:28 +0100 Subject: [PATCH 07/15] fix: parse bot user agents (#20785) Add parsing for byte spider and duck duck bot user agents. Fixes #20784 --- .../vaadin/flow/shared/BrowserDetails.java | 18 +++++++++-- .../flow/shared/BrowserDetailsTest.java | 32 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/flow-server/src/main/java/com/vaadin/flow/shared/BrowserDetails.java b/flow-server/src/main/java/com/vaadin/flow/shared/BrowserDetails.java index 1f20da5851b..3209e522244 100644 --- a/flow-server/src/main/java/com/vaadin/flow/shared/BrowserDetails.java +++ b/flow-server/src/main/java/com/vaadin/flow/shared/BrowserDetails.java @@ -356,11 +356,25 @@ private void parseAndroidVersion(String userAgent) { return; } + if (userAgent.contains("ddg_android/")) { + int startIndex = userAgent.indexOf("ddg_android/"); + String osVersionString = safeSubstring(userAgent, + startIndex + "ddg_android/".length(), + userAgent.indexOf(' ', startIndex)); + String[] parts = osVersionString.split("\\."); + parseOsVersion(parts, userAgent); + return; + } + String osVersionString = safeSubstring(userAgent, userAgent.indexOf("android ") + "android ".length(), userAgent.length()); - osVersionString = safeSubstring(osVersionString, 0, - osVersionString.indexOf(";")); + int semicolonIndex = osVersionString.indexOf(";"); + int bracketIndex = osVersionString.indexOf(")"); + int endIndex = semicolonIndex != -1 && semicolonIndex < bracketIndex + ? semicolonIndex + : bracketIndex; + osVersionString = safeSubstring(osVersionString, 0, endIndex); String[] parts = osVersionString.split("\\."); parseOsVersion(parts, userAgent); } diff --git a/flow-server/src/test/java/com/vaadin/flow/shared/BrowserDetailsTest.java b/flow-server/src/test/java/com/vaadin/flow/shared/BrowserDetailsTest.java index 0db4e9e6677..1a57b339362 100644 --- a/flow-server/src/test/java/com/vaadin/flow/shared/BrowserDetailsTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/shared/BrowserDetailsTest.java @@ -113,6 +113,10 @@ public class BrowserDetailsTest extends TestCase { private static final String FIREFOX_100_MACOS = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0"; private static final String FIREFOX_100_LINUX = "Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0"; + // Web crawlers and bots + private static final String BYTE_SPIDER = "mozilla/5.0 (linux; android 5.0) applewebkit/537.36 (khtml, like gecko) mobile safari/537.36 (compatible; bytespider; spider-feedback@bytedance.com)"; + private static final String DUCK_DUCK_BOT = "ddg_android/5.169.0 (com.duckduckgo.mobile.android; android api 33)"; + public void testSafari3() { BrowserDetails bd = new BrowserDetails(SAFARI3_WINDOWS); assertWebKit(bd); @@ -737,6 +741,25 @@ public void testMobileUserAgents() throws IOException { assertAgentDetails(agents); } + public void testByteSpiderWebCrawler() { + BrowserDetails bd = new BrowserDetails(BYTE_SPIDER); + assertWebKit(bd); + assertSafari(bd); + assertBrowserMajorVersion(bd, -1); + assertBrowserMinorVersion(bd, -1); + assertEngineVersion(bd, 537.36f); + assertAndroid(bd, 5, 0); + } + + public void testDuckDuckBot() { + BrowserDetails bd = new BrowserDetails(DUCK_DUCK_BOT); + assertUnspecifiedBrowser(bd); + assertBrowserMajorVersion(bd, -1); + assertBrowserMinorVersion(bd, -1); + assertEngineVersion(bd, -1); + assertAndroid(bd, 5, 169); + } + private static UserAgent[] getUserAgentDetails(String agentFile) throws IOException { String userAgents = IOUtils.toString( @@ -920,6 +943,15 @@ private void assertEdge(BrowserDetails browserDetails) { assertTrue(browserDetails.isEdge()); } + private void assertUnspecifiedBrowser(BrowserDetails browserDetails) { + assertFalse(browserDetails.isFirefox()); + assertFalse(browserDetails.isChrome()); + assertFalse(browserDetails.isIE()); + assertFalse(browserDetails.isOpera()); + assertFalse(browserDetails.isSafari()); + assertFalse(browserDetails.isEdge()); + } + private void assertMacOSX(BrowserDetails browserDetails) { assertFalse(browserDetails.isLinux()); assertFalse(browserDetails.isWindows()); From cca0105d64c3e71b0006f6339047007b31075851 Mon Sep 17 00:00:00 2001 From: Artur Date: Thu, 2 Jan 2025 12:05:14 +0200 Subject: [PATCH 08/15] chore: Bump preact signals (#20798) --- .../vaadin/flow/server/frontend/dependencies/vite/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json index 64b68221118..fd246c79811 100644 --- a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json +++ b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/dependencies/vite/package.json @@ -11,7 +11,7 @@ "devDependencies": { "vite": "6.0.6", "@vitejs/plugin-react": "4.3.4", - "@preact/signals-react-transform": "0.5.0", + "@preact/signals-react-transform": "0.5.1", "@rollup/plugin-replace": "6.0.2", "@rollup/pluginutils": "5.1.4", "@babel/preset-react": "7.26.3", From d7258e01c3815d4396a420feae133e0bfec6b7a2 Mon Sep 17 00:00:00 2001 From: Marco Collovati Date: Fri, 3 Jan 2025 12:22:28 +0100 Subject: [PATCH 09/15] chore: apply sonarqube suggestions (#20786) * chore: apply sonarqube suggestions * additional fixes * additional fixes * additional fixes * additional fixes --- .../client/flow/GwtEventHandlerTest.java | 11 +- .../vaadin/flow/component/ComponentTest.java | 52 +++--- .../vaadin/flow/internal/JsonUtilsTest.java | 7 +- .../internal/NavigationStateRendererTest.java | 31 ++-- .../vaadin/flow/server/VaadinServiceTest.java | 49 +++--- .../communication/UidlRequestHandlerTest.java | 13 +- .../server/frontend/FrontendToolsTest.java | 44 ++--- .../server/frontend/FrontendUtilsTest.java | 27 ++-- .../frontend/TaskGenerateReactFilesTest.java | 150 ++++++------------ .../flow/shared/BrowserDetailsTest.java | 16 +- .../devserver/DebugWindowConnectionTest.java | 18 +-- 11 files changed, 160 insertions(+), 258 deletions(-) diff --git a/flow-client/src/test-gwt/java/com/vaadin/client/flow/GwtEventHandlerTest.java b/flow-client/src/test-gwt/java/com/vaadin/client/flow/GwtEventHandlerTest.java index 86f9ec59179..85466a93a3c 100644 --- a/flow-client/src/test-gwt/java/com/vaadin/client/flow/GwtEventHandlerTest.java +++ b/flow-client/src/test-gwt/java/com/vaadin/client/flow/GwtEventHandlerTest.java @@ -173,7 +173,7 @@ private static native boolean hasPromise(Element element, int promiseId) public void testClientCallableMethodInDom() { assertServerEventHandlerMethodInDom( NodeFeatures.CLIENT_DELEGATE_HANDLERS, - element -> assertPublishedMethods(element, + el -> assertPublishedMethods(el, new String[] { "publishedMethod" }), "publishedMethod"); } @@ -240,15 +240,6 @@ private JsArray getPublishedServerMethods(Element element) { } } - private JsArray getPublishedServerMethods( - ServerEventObject object) { - if (object == null) { - return JsCollections.array(); - } else { - return object.getMethods(); - } - } - private void assertPublishedMethods(Element element, String[] expected) { assertEventHandlerMethods(() -> getPublishedServerMethods(element), expected); diff --git a/flow-server/src/test/java/com/vaadin/flow/component/ComponentTest.java b/flow-server/src/test/java/com/vaadin/flow/component/ComponentTest.java index be48dc61cf0..bd83fc23a9f 100644 --- a/flow-server/src/test/java/com/vaadin/flow/component/ComponentTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/component/ComponentTest.java @@ -71,7 +71,7 @@ public class ComponentTest { - private UI ui; + private UI testUI; @After public void checkThreadLocal() { @@ -158,7 +158,6 @@ public static class TestOtherButton extends Component { private Component child2InputComponent; private Component shadowRootParent; private Component shadowChild; - private UI testUI; private MockServletServiceSessionSetup mocks; private VaadinSession session; @@ -187,7 +186,7 @@ default void assertDetachEvents(int detachEvents) { } } - public static abstract class TracksAttachDetachComponent extends Component + public abstract static class TracksAttachDetachComponent extends Component implements TracksAttachDetach { private AtomicInteger attachEvents = new AtomicInteger(); @@ -274,9 +273,6 @@ public BrokenComponent() { static class TestComponentContainer extends TestComponent { - public TestComponentContainer() { - } - public void add(Component c) { getElement().appendChild(c.getElement()); } @@ -287,14 +283,14 @@ public void remove(Component c) { } private UI createMockedUI() { - UI ui = new UI() { + UI mockUI = new UI() { @Override public VaadinSession getSession() { return session; } }; - ui.getInternals().setSession(session); - return ui; + mockUI.getInternals().setSession(session); + return mockUI; } @Before @@ -313,9 +309,9 @@ public void setup() throws Exception { mocks = new MockServletServiceSessionSetup(); session = mocks.getSession(); - ui = createMockedUI(); + testUI = createMockedUI(); - UI.setCurrent(ui); + UI.setCurrent(testUI); } @After @@ -440,8 +436,7 @@ public void defaultGetChildrenDirectlyAttached() { public static void assertChildren(Component parent, Component... expectedChildren) { - List children = parent.getChildren() - .collect(Collectors.toList()); + List children = parent.getChildren().toList(); Assert.assertArrayEquals(expectedChildren, children.toArray()); for (Component c : children) { Assert.assertEquals(c.getParent().get(), parent); @@ -491,20 +486,16 @@ public void defaultGetChildrenDirectlyDeepElementHierarchy() { child2.getElement(), new Element("level1b").appendChild(child3.getElement())); - List children = parent.getChildren() - .collect(Collectors.toList()); Assert.assertArrayEquals(new Component[] { child1, child2, child3 }, - children.toArray()); + parent.getChildren().toArray()); } @Test public void defaultGetChildrenNoChildren() { - List children = parentDivComponent.getChildren() - .collect(Collectors.toList()); Assert.assertArrayEquals( new Component[] { child1SpanComponent, child2InputComponent }, - children.toArray()); + parentDivComponent.getChildren().toArray()); } @@ -742,8 +733,7 @@ public void testDetachListener_eventOrder_childFirst() { public void testDetach_failingListeners_allListenersInvokedAndExceptionHandled() { Set expectedExceptions = new HashSet<>(); Set handledExceptions = new HashSet<>(); - VaadinSession session = new AlwaysLockedVaadinSession( - new MockVaadinServletService()); + session = new AlwaysLockedVaadinSession(new MockVaadinServletService()); session.setErrorHandler( event -> handledExceptions.add(event.getThrowable())); VaadinSession.setCurrent(session); @@ -908,7 +898,7 @@ public void testUIInitialAttach() { }); MockDeploymentConfiguration config = new MockDeploymentConfiguration(); - VaadinSession session = new AlwaysLockedVaadinSession( + session = new AlwaysLockedVaadinSession( new MockVaadinServletService(config)); ui.getInternals().setSession(session); Assert.assertTrue(initialAttach.get()); @@ -1459,7 +1449,7 @@ private Map getDependenciesMap( @Test // 3818 public void enabledStateChangeOnAttachCalledForParentState() { enabledStateChangeOnAttachCalledForParentState(false, - (parent, child) -> parent.add(child)); + HasComponents::add); } @Test // 7085 @@ -1533,8 +1523,7 @@ public void onEnabledStateChanged(boolean enabled) { @Test public void enabledStateChangeOnParentDetachReturnsOldState() { - enabledStateChangeOnParentDetachReturnsOldState( - (parent, child) -> parent.add(child)); + enabledStateChangeOnParentDetachReturnsOldState(HasComponents::add); } @Test @@ -1970,16 +1959,17 @@ public void onEnabledStateChanged(boolean enabled) { @Test public void scrollIntoView() { EnabledDiv div = new EnabledDiv(); - ui.add(div); + testUI.add(div); div.scrollIntoView(); assertPendingJs("scrollIntoView()"); } private void assertPendingJs(String expectedJs) { - ui.getInternals().getStateTree().runExecutionsBeforeClientResponse(); + testUI.getInternals().getStateTree() + .runExecutionsBeforeClientResponse(); - List pendingJs = ui.getInternals() + List pendingJs = testUI.getInternals() .dumpPendingJavaScriptInvocations(); Assert.assertEquals(1, pendingJs.size()); JavaScriptInvocation inv = pendingJs.get(0).getInvocation(); @@ -1990,7 +1980,7 @@ private void assertPendingJs(String expectedJs) { @Test public void scrollIntoViewSmooth() { EnabledDiv div = new EnabledDiv(); - ui.add(div); + testUI.add(div); div.scrollIntoView(new ScrollOptions(Behavior.SMOOTH)); assertPendingJs("scrollIntoView({\"behavior\":\"smooth\"})"); @@ -1999,7 +1989,7 @@ public void scrollIntoViewSmooth() { @Test public void scrollIntoViewAllParams() { EnabledDiv div = new EnabledDiv(); - ui.add(div); + testUI.add(div); div.scrollIntoView(new ScrollOptions(Behavior.SMOOTH, Alignment.END, Alignment.CENTER)); @@ -2015,7 +2005,7 @@ public void cannotMoveComponentsToOtherUI() { otherUI.add(button); IllegalStateException ex = Assert.assertThrows( - IllegalStateException.class, () -> ui.add(button)); + IllegalStateException.class, () -> testUI.add(button)); Assert.assertTrue(ex.getMessage(), ex.getMessage().startsWith( "Can't move a node from one state tree to another. If this is " + "intentional, first remove the node from its current " diff --git a/flow-server/src/test/java/com/vaadin/flow/internal/JsonUtilsTest.java b/flow-server/src/test/java/com/vaadin/flow/internal/JsonUtilsTest.java index 9d83a0a89ba..a407b813638 100644 --- a/flow-server/src/test/java/com/vaadin/flow/internal/JsonUtilsTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/internal/JsonUtilsTest.java @@ -27,7 +27,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import java.util.stream.DoubleStream; import java.util.stream.Stream; @@ -139,8 +138,7 @@ public void collectEmptyStream() { @Test public void testStream() { JsonArray array = createTestArray1(); - List list = JsonUtils.stream(array) - .collect(Collectors.toList()); + List list = JsonUtils.stream(array).toList(); Assert.assertEquals(2, list.size()); Assert.assertEquals("foo", list.get(0).asString()); @@ -153,8 +151,7 @@ public void testObjectStream() { JsonArray array = Stream.of(Json.createObject(), createTestObject1(), createTestObject2()).collect(JsonUtils.asArray()); - List objects = JsonUtils.objectStream(array) - .collect(Collectors.toList()); + List objects = JsonUtils.objectStream(array).toList(); Assert.assertEquals(3, objects.size()); Assert.assertTrue( diff --git a/flow-server/src/test/java/com/vaadin/flow/router/internal/NavigationStateRendererTest.java b/flow-server/src/test/java/com/vaadin/flow/router/internal/NavigationStateRendererTest.java index 41aa569bd41..a311d3aabff 100644 --- a/flow-server/src/test/java/com/vaadin/flow/router/internal/NavigationStateRendererTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/router/internal/NavigationStateRendererTest.java @@ -16,6 +16,7 @@ package com.vaadin.flow.router.internal; import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -34,9 +35,7 @@ import net.jcip.annotations.NotThreadSafe; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.mockito.MockedStatic; import org.mockito.Mockito; @@ -81,7 +80,6 @@ import com.vaadin.flow.server.MockVaadinServletService; import com.vaadin.flow.server.MockVaadinSession; import com.vaadin.flow.server.RouteRegistry; -import com.vaadin.flow.server.ServiceException; import com.vaadin.flow.server.WrappedSession; import com.vaadin.flow.server.menu.AvailableViewInfo; import com.vaadin.flow.server.startup.ApplicationRouteRegistry; @@ -162,9 +160,6 @@ public ProxyableView() { private Router router; - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Before public void init() { RouteRegistry registry = ApplicationRouteRegistry @@ -173,7 +168,7 @@ public void init() { } @Test - public void getRouterLayoutForSingle() throws Exception { + public void getRouterLayoutForSingle() { NavigationStateRenderer childRenderer = new NavigationStateRenderer( navigationStateFromTarget(RouteParentLayout.class)); @@ -186,7 +181,7 @@ public void getRouterLayoutForSingle() throws Exception { } @Test - public void getRouterLayoutForSingleParent() throws Exception { + public void getRouterLayoutForSingleParent() { NavigationStateRenderer childRenderer = new NavigationStateRenderer( navigationStateFromTarget(SingleView.class)); RouteConfiguration.forRegistry(router.getRegistry()) @@ -202,7 +197,7 @@ public void getRouterLayoutForSingleParent() throws Exception { } @Test - public void getRouterLayoutForMulipleLayers() throws Exception { + public void getRouterLayoutForMulipleLayers() { NavigationStateRenderer childRenderer = new NavigationStateRenderer( navigationStateFromTarget(ChildConfiguration.class)); RouteConfiguration.forRegistry(router.getRegistry()) @@ -220,7 +215,7 @@ public void getRouterLayoutForMulipleLayers() throws Exception { } @Test - public void instantiatorUse() throws ServiceException { + public void instantiatorUse() { MockVaadinServletService service = new MockVaadinServletService(); service.init(new MockInstantiator() { @@ -568,7 +563,7 @@ public void handle_preserveOnRefreshView_routerLayoutIsPreserved_oldUiIsClosed() session.setConfiguration(new MockDeploymentConfiguration()); // given a NavigationStateRenderer mapping to PreservedNestedView - Router router = session.getService().getRouter(); + router = session.getService().getRouter(); NavigationStateRenderer renderer = new NavigationStateRenderer( new NavigationStateBuilder(router) .withTarget(PreservedNestedView.class) @@ -676,7 +671,7 @@ public void handle_preserveOnRefreshView_refreshCurrentRouteRecreatesComponents( session.setConfiguration(new MockDeploymentConfiguration()); // given a NavigationStateRenderer mapping to PreservedNestedView - Router router = session.getService().getRouter(); + router = session.getService().getRouter(); NavigationStateRenderer renderer = new NavigationStateRenderer( new NavigationStateBuilder(router) .withTarget(PreservedNestedView.class) @@ -734,7 +729,7 @@ public void handle_normalView_refreshCurrentRouteRecreatesComponents() { session.setConfiguration(new MockDeploymentConfiguration()); // given a NavigationStateRenderer mapping to PreservedNestedView - Router router = session.getService().getRouter(); + router = session.getService().getRouter(); NavigationStateRenderer renderer = new NavigationStateRenderer( new NavigationStateBuilder(router).withTarget(SingleView.class) .withPath("single").build()); @@ -784,7 +779,7 @@ public void handle_clientNavigation_withMatchingFlowRoute() { session.setConfiguration(new MockDeploymentConfiguration()); // given a NavigationStateRenderer mapping to PreservedNestedView - Router router = session.getService().getRouter(); + router = session.getService().getRouter(); NavigationStateRenderer renderer = new NavigationStateRenderer( new NavigationStateBuilder(router) .withTarget(RootRouteWithParam.class).withPath("") @@ -833,7 +828,7 @@ public void handle_refreshRoute_modalComponentsDetached() { session.setConfiguration(new MockDeploymentConfiguration()); // given a NavigationStateRenderer mapping to PreservedNestedView - Router router = session.getService().getRouter(); + router = session.getService().getRouter(); NavigationStateRenderer renderer = new NavigationStateRenderer( new NavigationStateBuilder(router) .withTarget(RootRouteWithParam.class).withPath("") @@ -876,8 +871,10 @@ private MockVaadinServletService createMockServiceWithInstantiator() { public T createRouteTarget( Class routeTargetType, NavigationEvent event) { try { - return routeTargetType.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { + return routeTargetType.getDeclaredConstructor() + .newInstance(); + } catch (InstantiationException | IllegalAccessException + | NoSuchMethodException | InvocationTargetException e) { throw new RuntimeException(e); } } diff --git a/flow-server/src/test/java/com/vaadin/flow/server/VaadinServiceTest.java b/flow-server/src/test/java/com/vaadin/flow/server/VaadinServiceTest.java index 7d994330297..03537cc4057 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/VaadinServiceTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/VaadinServiceTest.java @@ -18,6 +18,7 @@ import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpSessionBindingEvent; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -140,7 +141,7 @@ private String createCriticalNotification(String caption, String message, details, url); } - private static abstract class TestVaadinService extends VaadinService { + private abstract static class TestVaadinService extends VaadinService { @Override protected List createRequestHandlers() @@ -400,8 +401,7 @@ private static Map createClientRoutesMap( } @Test - public void testFireSessionDestroy() - throws ServletException, ServiceException { + public void testFireSessionDestroy() { VaadinService service = createService(); TestSessionDestroyListener listener = new TestSessionDestroyListener(); @@ -426,8 +426,7 @@ public void testFireSessionDestroy() } @Test - public void testSessionDestroyListenerCalled_whenAnotherListenerThrows() - throws ServiceException { + public void testSessionDestroyListenerCalled_whenAnotherListenerThrows() { VaadinService service = createService(); ThrowingSessionDestroyListener throwingListener = new ThrowingSessionDestroyListener(); @@ -451,8 +450,7 @@ public void testSessionDestroyListenerCalled_whenAnotherListenerThrows() } @Test - public void testSessionDestroyListenerCalled_andOtherUiDetachCalled_whenUiClosingThrows() - throws ServiceException { + public void testSessionDestroyListenerCalled_andOtherUiDetachCalled_whenUiClosingThrows() { VaadinService service = createService(); TestSessionDestroyListener listener = new TestSessionDestroyListener(); @@ -460,11 +458,11 @@ public void testSessionDestroyListenerCalled_andOtherUiDetachCalled_whenUiClosin service.addSessionDestroyListener(listener); final AtomicBoolean secondUiDetached = new AtomicBoolean(); - List UIs = new ArrayList<>(); + List uis = new ArrayList<>(); MockVaadinSession vaadinSession = new MockVaadinSession(service) { @Override public Collection getUIs() { - return UIs; + return uis; } }; vaadinSession.lock(); @@ -481,7 +479,7 @@ public VaadinSession getSession() { }; throwingUI.getInternals().setSession(vaadinSession); - UIs.add(throwingUI); + uis.add(throwingUI); UI detachingUI = new UI() { @Override @@ -495,7 +493,7 @@ public VaadinSession getSession() { } }; detachingUI.getInternals().setSession(vaadinSession); - UIs.add(detachingUI); + uis.add(detachingUI); vaadinSession.unlock(); @@ -509,8 +507,7 @@ public VaadinSession getSession() { } @Test - public void testServiceDestroyListenerCalled_whenAnotherListenerThrows() - throws ServletException, ServiceException { + public void testServiceDestroyListenerCalled_whenAnotherListenerThrows() { VaadinService service = createService(); ThrowingServiceDestroyListener throwingListener = new ThrowingServiceDestroyListener(); @@ -519,7 +516,7 @@ public void testServiceDestroyListenerCalled_whenAnotherListenerThrows() service.addServiceDestroyListener(throwingListener); service.addServiceDestroyListener(listener); - assertThrows(RuntimeException.class, () -> service.destroy()); + assertThrows(RuntimeException.class, service::destroy); Assert.assertEquals("ServiceDestroyListener not called exactly once", 1, listener.callCount); @@ -602,8 +599,7 @@ public void serviceContainsStreamRequestHandler() .thenReturn(factory); VaadinServlet servlet = new VaadinServlet() { @Override - protected DeploymentConfiguration createDeploymentConfiguration() - throws ServletException { + protected DeploymentConfiguration createDeploymentConfiguration() { return new MockDeploymentConfiguration(); } }; @@ -615,8 +611,7 @@ protected DeploymentConfiguration createDeploymentConfiguration() } @Test - public void currentInstancesAfterPendingAccessTasks() - throws ServiceException { + public void currentInstancesAfterPendingAccessTasks() { VaadinService service = createService(); MockVaadinSession session = new MockVaadinSession(service); @@ -661,7 +656,7 @@ public void testServiceInitListener_accessApplicationRouteRegistry_registryAvail VaadinService.setCurrent(null); Assert.assertEquals(1, availableRoutes.size()); - Assert.assertEquals(availableRoutes.get(0).getTemplate(), "test"); + Assert.assertEquals("test", availableRoutes.get(0).getTemplate()); } @Test @@ -696,7 +691,7 @@ public void loadInstantiators_instantiatorIsLoadedUsingFactoryFromLookup() service.getContext().setAttribute(Lookup.class, lookup); - InstantiatorFactory factory = createInstantiatorFactory(lookup); + InstantiatorFactory factory = createInstantiatorFactory(); Mockito.when(lookup.lookupAll(InstantiatorFactory.class)) .thenReturn(Collections.singletonList(factory)); @@ -717,8 +712,8 @@ public void loadInstantiators_twoFactoriesInLookup_throws() service.getContext().setAttribute(Lookup.class, lookup); - InstantiatorFactory factory1 = createInstantiatorFactory(lookup); - InstantiatorFactory factory2 = createInstantiatorFactory(lookup); + InstantiatorFactory factory1 = createInstantiatorFactory(); + InstantiatorFactory factory2 = createInstantiatorFactory(); Mockito.when(lookup.lookupAll(InstantiatorFactory.class)) .thenReturn(Arrays.asList(factory1, factory2)); @@ -745,8 +740,7 @@ public void createRequestHandlers_pwaHandlerIsInList_webComponentHandlersAreInLi } @Test - public void fireSessionDestroy_sessionStateIsSetToClosed() - throws ServletException, ServiceException { + public void fireSessionDestroy_sessionStateIsSetToClosed() { VaadinService service = createService(); AtomicReference stateRef = new AtomicReference<>(); @@ -824,7 +818,7 @@ private WrappedSession mockSession(VaadinRequest request, return session; } - private InstantiatorFactory createInstantiatorFactory(Lookup lookup) { + private InstantiatorFactory createInstantiatorFactory() { InstantiatorFactory factory = Mockito.mock(InstantiatorFactory.class); Instantiator instantiator = Mockito.mock(Instantiator.class); @@ -834,8 +828,7 @@ private InstantiatorFactory createInstantiatorFactory(Lookup lookup) { return factory; } - private static VaadinService createService() throws ServiceException { - VaadinService service = new MockVaadinServletService(); - return service; + private static VaadinService createService() { + return new MockVaadinServletService(); } } diff --git a/flow-server/src/test/java/com/vaadin/flow/server/communication/UidlRequestHandlerTest.java b/flow-server/src/test/java/com/vaadin/flow/server/communication/UidlRequestHandlerTest.java index f9a26c7194e..3473d1a8300 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/communication/UidlRequestHandlerTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/communication/UidlRequestHandlerTest.java @@ -1,3 +1,4 @@ + /* * Copyright 2000-2024 Vaadin Ltd. * @@ -197,7 +198,7 @@ public void clientRequestsPreviousIdAndPayload_resendPreviousResponse() public void should_modifyUidl_when_MPR() throws Exception { UI ui = getUi(); - UidlRequestHandler handler = spy(new UidlRequestHandler()); + handler = spy(new UidlRequestHandler()); StringWriter writer = new StringWriter(); JsonObject uidl = generateUidl(true, true); @@ -218,7 +219,7 @@ public void should_modifyUidl_when_MPR() throws Exception { public void should_changeURL_when_v7LocationProvided() throws Exception { UI ui = getUi(); - UidlRequestHandler handler = spy(new UidlRequestHandler()); + handler = spy(new UidlRequestHandler()); StringWriter writer = new StringWriter(); JsonObject uidl = generateUidl(true, true); @@ -239,7 +240,7 @@ public void should_updateHash_when_v7LocationNotProvided() throws Exception { UI ui = getUi(); - UidlRequestHandler handler = spy(new UidlRequestHandler()); + handler = spy(new UidlRequestHandler()); StringWriter writer = new StringWriter(); JsonObject uidl = generateUidl(false, true); @@ -259,7 +260,7 @@ public void should_updateHash_when_v7LocationNotProvided() public void should_not_modify_non_MPR_Uidl() throws Exception { UI ui = getUi(); - UidlRequestHandler handler = spy(new UidlRequestHandler()); + handler = spy(new UidlRequestHandler()); StringWriter writer = new StringWriter(); JsonObject uidl = generateUidl(true, true); @@ -284,7 +285,7 @@ public void should_not_update_browser_history_if_no_hash_in_location() throws Exception { UI ui = getUi(); - UidlRequestHandler handler = spy(new UidlRequestHandler()); + handler = spy(new UidlRequestHandler()); StringWriter writer = new StringWriter(); JsonObject uidl = getUidlWithNoHashInLocation(); @@ -316,7 +317,7 @@ public void handleRpc(UI ui, String requestBody, } }; - UidlRequestHandler handler = new UidlRequestHandler() { + handler = new UidlRequestHandler() { @Override protected ServerRpcHandler createRpcHandler() { return serverRpcHandler; diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendToolsTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendToolsTest.java index 2aa9ac1a292..1b5f9c4ba30 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendToolsTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendToolsTest.java @@ -15,15 +15,8 @@ */ package com.vaadin.flow.server.frontend; -import static com.vaadin.flow.server.frontend.FrontendTools.NPM_BIN_PATH; -import static com.vaadin.flow.testutil.FrontendStubs.createStubNode; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertEquals; - import java.io.File; import java.io.FileOutputStream; -import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.net.URI; @@ -38,6 +31,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import net.jcip.annotations.NotThreadSafe; import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; @@ -52,6 +46,7 @@ import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.rules.TemporaryFolder; +import org.slf4j.LoggerFactory; import com.vaadin.flow.function.SerializableSupplier; import com.vaadin.flow.internal.Pair; @@ -60,10 +55,12 @@ import com.vaadin.flow.testcategory.SlowTests; import com.vaadin.flow.testutil.FrontendStubs; -import net.jcip.annotations.NotThreadSafe; -import org.slf4j.LoggerFactory; - +import static com.vaadin.flow.server.frontend.FrontendTools.NPM_BIN_PATH; +import static com.vaadin.flow.testutil.FrontendStubs.createStubNode; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; @NotThreadSafe @Category(SlowTests.class) @@ -491,7 +488,7 @@ public synchronized void getProxies_systemPropertiesAndNpmrcWithProxySetting_sho settings.setBaseDir(npmrc.getParent()); settings.setAlternativeDirGetter(null); - FrontendTools tools = new FrontendTools(settings); + tools = new FrontendTools(settings); Properties properties = new Properties(); properties.put(ProxyFactory.NPMRC_PROXY_PROPERTY_KEY, @@ -583,7 +580,7 @@ public synchronized void getProxies_npmrcWithProxySettingNoNoproxy_shouldReturnN settings.setBaseDir(npmrc.getParent()); settings.setAlternativeDirGetter(null); - FrontendTools tools = new FrontendTools(settings); + tools = new FrontendTools(settings); List proxyList = tools.getProxies(); Assert.assertEquals(2, proxyList.size()); @@ -625,7 +622,7 @@ public synchronized void getProxies_npmrcWithProxySetting_shouldReturnProxiesLis settings.setBaseDir(npmrc.getParent()); settings.setAlternativeDirGetter(null); - FrontendTools tools = new FrontendTools(settings); + tools = new FrontendTools(settings); List proxyList = tools.getProxies(); Assert.assertEquals(2, proxyList.size()); @@ -850,8 +847,8 @@ public void folderIsAcceptableByNpm_npm7_trueForWindows() } @Test - public void getNpmCacheDir_returnsCorrectPath() throws IOException, - InterruptedException, FrontendUtils.CommandExecutionException { + public void getNpmCacheDir_returnsCorrectPath() + throws IOException, FrontendUtils.CommandExecutionException { FrontendStubs.ToolStubInfo nodeStub = FrontendStubs.ToolStubInfo.none(); FrontendStubs.ToolStubInfo npmStub = FrontendStubs.ToolStubInfo .builder(FrontendStubs.Tool.NPM).withCacheDir("/foo/bar") @@ -906,23 +903,6 @@ private void assertFaultyNpmVersion(FrontendVersion version) { } } - private void createFakePnpm(String defaultPnpmVersion) throws Exception { - final String npxPath = NPM_BIN_PATH + "npx-cli.js"; - File npxJs = new File(baseDir, npxPath); - FileUtils.forceMkdir(npxJs.getParentFile()); - - FileWriter fileWriter = new FileWriter(npxJs); - try { - fileWriter.write( - "pnpmVersion = process.argv.filter(a=>a.startsWith('pnpm')).map(a=>a.substring(5))[0] || '" - + defaultPnpmVersion + "'\n" - + "if (process.argv.includes('--version') || process.argv.includes('-v')) {\n" - + " console.log(pnpmVersion);\n" + "}\n"); - } finally { - fileWriter.close(); - } - } - private void installGlobalPnpm(String pnpmVersion) { Optional npmInstalled = frontendToolsLocator .tryLocateTool(getCommand("npm")); diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendUtilsTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendUtilsTest.java index 5dbd1322b80..7c0b06f0ac3 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendUtilsTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/FrontendUtilsTest.java @@ -256,8 +256,8 @@ public void parseValidToolVersions() throws IOException { Assert.assertEquals("8.0.0", FrontendUtils.parseVersionString("v8.0.0")); Assert.assertEquals("8.0.0", FrontendUtils.parseVersionString("8.0.0")); - Assert.assertEquals("6.9.0", FrontendUtils.parseVersionString( - "Aktive Codepage: 1252\n" + "6.9.0\n" + "")); + Assert.assertEquals("6.9.0", FrontendUtils + .parseVersionString("Aktive Codepage: 1252\n6.9.0\n")); } @Test(expected = IOException.class) @@ -336,10 +336,14 @@ public void commandToString_longCommand_resultIsWrapped() { "--config", "./webpack.config.js", "--port 57799", "--env watchDogPort=57798", "-d", "--inline=false"); String wrappedCommand = FrontendUtils.commandToString(".", command); - Assert.assertEquals("\n" + "./node/node \\ \n" - + " ./node_modules/webpack-dev-server/bin/webpack-dev-server.js \\ \n" - + " --config ./webpack.config.js --port 57799 \\ \n" - + " --env watchDogPort=57798 -d --inline=false \n", + Assert.assertEquals( + """ + + ./node/node \\\s + ./node_modules/webpack-dev-server/bin/webpack-dev-server.js \\\s + --config ./webpack.config.js --port 57799 \\\s + --env watchDogPort=57798 -d --inline=false\s + """, wrappedCommand); } @@ -349,8 +353,12 @@ public void commandToString_commandContainsBaseDir_baseDirIsReplaced() { "/somewhere/not/disclosable/node_modules/webpack-dev-server/bin/webpack-dev-server.js"); String wrappedCommand = FrontendUtils .commandToString("/somewhere/not/disclosable", command); - Assert.assertEquals("\n" + "./node/node \\ \n" - + " ./node_modules/webpack-dev-server/bin/webpack-dev-server.js \n", + Assert.assertEquals( + """ + + ./node/node \\\s + ./node_modules/webpack-dev-server/bin/webpack-dev-server.js\s + """, wrappedCommand); } @@ -435,7 +443,8 @@ public void symlinkByNpm_deleteDirectory_doesNotDeleteSymlinkFolderFiles() NodeUpdater nodeUpdater = new NodeUpdater( Mockito.mock(FrontendDependencies.class), options) { @Override - public void execute() throws ExecutionFailedException { + public void execute() { + // no need to execute logic for this test } @Override diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskGenerateReactFilesTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskGenerateReactFilesTest.java index 37ea7d42149..af2c8357791 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskGenerateReactFilesTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskGenerateReactFilesTest.java @@ -19,6 +19,7 @@ import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.Collections; import org.apache.commons.io.FileUtils; @@ -100,8 +101,9 @@ public void layoutsJson_containsExpectedPaths() TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); task.execute(); - String layoutsContent = FileUtils.readFileToString( - new File(options.getFrontendGeneratedFolder(), "layouts.json")); + String layoutsContent = Files.readString( + new File(options.getFrontendGeneratedFolder(), "layouts.json") + .toPath()); Assert.assertEquals("[{\"path\":\"/test\"}]", layoutsContent); @@ -109,7 +111,7 @@ public void layoutsJson_containsExpectedPaths() @Test public void routesContainImportAndUsage_serverSideRoutes_noExceptionThrown() - throws IOException, ExecutionFailedException { + throws IOException { String content = """ import HelloWorldView from 'Frontend/views/helloworld/HelloWorldView.js'; import MainLayout from 'Frontend/views/MainLayout.js'; @@ -139,11 +141,7 @@ public void routesContainImportAndUsage_serverSideRoutes_noExceptionThrown() .build(); """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - task.execute(); + executeTask(content); } @Test @@ -153,14 +151,8 @@ public void routesContainOnlyImport_serverSideRoutes_exceptionThrown() import { serverSideRoutes } from 'Frontend/generated/flow/Flow'; """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - Exception exception = Assert.assertThrows( - ExecutionFailedException.class, () -> task.execute()); - Assert.assertEquals(String.format(TaskGenerateReactFiles.NO_IMPORT, - routesTsx.getPath()), exception.getMessage()); + assertTaskExecutionFails(content, String + .format(TaskGenerateReactFiles.NO_IMPORT, routesTsx.getPath())); } @Test @@ -172,19 +164,13 @@ public void routesContainNoImport_serverSideRoutes_exceptionThrown() ] as RouteObject[]; """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - Exception exception = Assert.assertThrows( - ExecutionFailedException.class, () -> task.execute()); - Assert.assertEquals(String.format(TaskGenerateReactFiles.NO_IMPORT, - routesTsx.getPath()), exception.getMessage()); + assertTaskExecutionFails(content, String + .format(TaskGenerateReactFiles.NO_IMPORT, routesTsx.getPath())); } @Test public void routesContainMultipleFlowImports_noExceptionThrown() - throws IOException, ExecutionFailedException { + throws IOException { String content = """ import HelloWorldView from 'Frontend/views/helloworld/HelloWorldView.js'; import MainLayout from 'Frontend/views/MainLayout.js'; @@ -210,16 +196,12 @@ public void routesContainMultipleFlowImports_noExceptionThrown() export default createBrowserRouter(routes); """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - task.execute(); + executeTask(content); } @Test public void routesMissingImportAndUsage_noBuildOrServerSideRoutes_exceptionThrown() - throws IOException, ExecutionFailedException { + throws IOException { String content = """ import HelloWorldView from 'Frontend/views/helloworld/HelloWorldView.js'; import MainLayout from 'Frontend/views/MainLayout.js'; @@ -244,14 +226,8 @@ public void routesMissingImportAndUsage_noBuildOrServerSideRoutes_exceptionThrow export default createBrowserRouter(routes); """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - Exception exception = Assert.assertThrows( - ExecutionFailedException.class, () -> task.execute()); - Assert.assertEquals(String.format(TaskGenerateReactFiles.NO_IMPORT, - routesTsx.getPath()), exception.getMessage()); + assertTaskExecutionFails(content, String + .format(TaskGenerateReactFiles.NO_IMPORT, routesTsx.getPath())); } @Test @@ -281,14 +257,8 @@ public void routesMissingImport_exceptionThrown() throws IOException { export default createBrowserRouter(routes); """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - Exception exception = Assert.assertThrows( - ExecutionFailedException.class, () -> task.execute()); - Assert.assertEquals(String.format(TaskGenerateReactFiles.NO_IMPORT, - routesTsx.getPath()), exception.getMessage()); + assertTaskExecutionFails(content, String + .format(TaskGenerateReactFiles.NO_IMPORT, routesTsx.getPath())); } @Test @@ -360,14 +330,8 @@ public void routesExportMissing_exceptionThrown() throws IOException { .build(); """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - Exception exception = Assert.assertThrows( - ExecutionFailedException.class, () -> task.execute()); - Assert.assertEquals(TaskGenerateReactFiles.MISSING_ROUTES_EXPORT, - exception.getMessage()); + assertTaskExecutionFails(content, + TaskGenerateReactFiles.MISSING_ROUTES_EXPORT); } @Test @@ -400,14 +364,8 @@ public void withFallbackMissing_exceptionThrown() throws IOException { .build(); """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - Exception exception = Assert.assertThrows( - ExecutionFailedException.class, () -> task.execute()); - Assert.assertEquals(String.format(TaskGenerateReactFiles.NO_IMPORT, - routesTsx.getPath()), exception.getMessage()); + assertTaskExecutionFails(content, String + .format(TaskGenerateReactFiles.NO_IMPORT, routesTsx.getPath())); } @Test @@ -422,14 +380,8 @@ public void withFallbackReceivesDifferentObject_exceptionThrown() .build(); """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - Exception exception = Assert.assertThrows( - ExecutionFailedException.class, () -> task.execute()); - Assert.assertEquals(String.format(TaskGenerateReactFiles.NO_IMPORT, - routesTsx.getPath()), exception.getMessage()); + assertTaskExecutionFails(content, String + .format(TaskGenerateReactFiles.NO_IMPORT, routesTsx.getPath())); } @Test @@ -443,14 +395,8 @@ public void withFallbackMissesImport_exceptionThrown() throws IOException { .build(); """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - Exception exception = Assert.assertThrows( - ExecutionFailedException.class, () -> task.execute()); - Assert.assertEquals(String.format(TaskGenerateReactFiles.NO_IMPORT, - routesTsx.getPath()), exception.getMessage()); + assertTaskExecutionFails(content, String + .format(TaskGenerateReactFiles.NO_IMPORT, routesTsx.getPath())); } @Test @@ -503,7 +449,7 @@ public void frontendCustomReactFilesAreCleanedAndBackUppedWhenReactIsDisabled() @Test public void routesContainExport_noConst_noExceptionThrown() - throws IOException, ExecutionFailedException { + throws IOException { String content = """ import { RouterConfigurationBuilder } from '@vaadin/hilla-file-router/runtime.js'; import Flow from 'Frontend/generated/flow/Flow'; @@ -516,16 +462,12 @@ public void routesContainExport_noConst_noExceptionThrown() export { router, routes } """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - task.execute(); + executeTask(content); } @Test public void routesContainExport_twoSingleExports_noExceptionThrown() - throws IOException, ExecutionFailedException { + throws IOException { String content = """ import { RouterConfigurationBuilder } from '@vaadin/hilla-file-router/runtime.js'; import Flow from 'Frontend/generated/flow/Flow'; @@ -540,16 +482,12 @@ public void routesContainExport_twoSingleExports_noExceptionThrown() export {router} """; - FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); - - TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - - task.execute(); + executeTask(content); } @Test public void routesContainExport_oneSingleExport_exceptionThrown() - throws IOException, ExecutionFailedException { + throws IOException { String content = """ import { RouterConfigurationBuilder } from '@vaadin/hilla-file-router/runtime.js'; import Flow from 'Frontend/generated/flow/Flow'; @@ -562,16 +500,32 @@ public void routesContainExport_oneSingleExport_exceptionThrown() export { routes } """; + assertTaskExecutionFails(content, + String.format(TaskGenerateReactFiles.MISSING_ROUTES_EXPORT, + routesTsx.getPath())); + } + + private void assertTaskExecutionFails(String content, String errorMessage) + throws IOException { FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); - Exception exception = Assert.assertThrows( - ExecutionFailedException.class, () -> task.execute()); - Assert.assertEquals( - String.format(TaskGenerateReactFiles.MISSING_ROUTES_EXPORT, - routesTsx.getPath()), - exception.getMessage()); + Exception exception = Assert + .assertThrows(ExecutionFailedException.class, task::execute); + Assert.assertEquals(errorMessage, exception.getMessage()); + } + + private void executeTask(String content) throws IOException { + FileUtils.write(routesTsx, content, StandardCharsets.UTF_8); + TaskGenerateReactFiles task = new TaskGenerateReactFiles(options); + try { + task.execute(); + } catch (ExecutionFailedException e) { + throw new AssertionError( + "Expected execution to complete successfully, but exception was thrown", + e); + } } @Tag("div") diff --git a/flow-server/src/test/java/com/vaadin/flow/shared/BrowserDetailsTest.java b/flow-server/src/test/java/com/vaadin/flow/shared/BrowserDetailsTest.java index 1a57b339362..c99958f8ab4 100644 --- a/flow-server/src/test/java/com/vaadin/flow/shared/BrowserDetailsTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/shared/BrowserDetailsTest.java @@ -73,8 +73,6 @@ public class BrowserDetailsTest extends TestCase { private static final String SAFARI4_MAC = "Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; en-us) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"; private static final String SAFARI10_WINDOWS = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8"; private static final String SAFARI11_MAC = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1 Safari/605.1.15"; - private static final String SAFARI13_MAC = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.4 Safari/605.1.15"; - private static final String SAFARI14_MAC = "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_6_2) AppleWebKit/611.3.10.1.5 (KHTML, like Gecko) Version/14.1.2 Safari/611.3.10.1.5"; private static final String IPHONE_IOS_5_1 = "Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B179 Safari/7534.48.3"; private static final String IPHONE_IOS_4_0 = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7"; @@ -96,16 +94,12 @@ public class BrowserDetailsTest extends TestCase { private static final String IPHONE_IOS_11_FACEBOOK_BROWSER = "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E302 [FBAN/MessengerForiOS;FBAV/165.0.0.45.95;FBBV/107115338;FBDV/iPhone10,6;FBMD/iPhone;FBSN/iOS;FBSV/11.3.1;FBSS/3;FBCR/DNA;FBID/phone;FBLC/en_GB;FBOP/5;FBRV/0]"; private static final String IPHONE_IOS_11_FIREFOX = "Mozilla/5.0 (iPhone; CPU iPhone OS 11_1_2 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) FxiOS/11.1b10377 Mobile/15B202 Safari/604.3.5"; - private static final String EDGE_18 = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; ServiceUI 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763"; - private static final String EDGE_79 = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 Edg/79.0.309.71"; private static final String EDGE_100 = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36 Edg/100.0.1185.29"; private static final String EDGE_99_MAC = "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_3_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/99.0.1150.36"; private static final String EDGE_97_ANDROID = "Mozilla/5.0 (Linux; Android 10; Pixel 3 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.79 Mobile Safari/537.36 EdgA/97.0.1072.69"; private static final String EDGE_97_IOS = "Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 EdgiOS/97.1072.69 Mobile/15E148 Safari/605.1.15"; - private static final String GOOGLE_APP_IPHONE_14_7 = "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/117.0.321844219 Mobile/15E148 Safari/604.1"; - // Version 100 Strings private static final String CHROME100_WINDOWS = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4844.84 Safari/537.36"; private static final String FIREFOX_100_WIN64 = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0"; @@ -162,9 +156,6 @@ public void testIPhoneIOS6Homescreen() { IPHONE_IOS_6_1_HOMESCREEN_SIMULATOR); assertWebKit(bd); // not identified as Safari, no browser version available - // assertSafari(bd); - // assertBrowserMajorVersion(bd, 6); - // assertBrowserMinorVersion(bd, 1); assertEngineVersion(bd, 536.26f); assertIPhone(bd); @@ -529,7 +520,6 @@ public void testIE9() { public void testIE9InIE7CompatibilityMode() { BrowserDetails bd = new BrowserDetails(IE9_IN_IE7_MODE_WINDOWS_7); - // bd.setIE8InCompatibilityMode(); assertTrident(bd); assertEngineVersion(bd, 5); @@ -543,7 +533,6 @@ public void testIE9InIE7CompatibilityMode() { public void testIE9InIE8CompatibilityMode() { BrowserDetails bd = new BrowserDetails(IE9_BETA_IN_IE8_MODE_WINDOWS_7); - // bd.setIE8InCompatibilityMode(); /* * Trident/4.0 in example user agent string based on beta even though it @@ -768,8 +757,7 @@ private static UserAgent[] getUserAgentDetails(String agentFile) StandardCharsets.UTF_8); ObjectMapper mapper = new ObjectMapper(); - UserAgent agents[] = mapper.readValue(userAgents, UserAgent[].class); - return agents; + return mapper.readValue(userAgents, UserAgent[].class); } private void assertAgentDetails(UserAgent[] agents) { @@ -818,6 +806,8 @@ private void assertOs(BrowserDetails bd, String os) { case "ANDROID": assertAndroid(bd); break; + default: + throw new AssertionError(os + " is not a supported OS"); } } diff --git a/vaadin-dev-server/src/test/java/com/vaadin/base/devserver/DebugWindowConnectionTest.java b/vaadin-dev-server/src/test/java/com/vaadin/base/devserver/DebugWindowConnectionTest.java index c6020cfd418..7b47aab393e 100644 --- a/vaadin-dev-server/src/test/java/com/vaadin/base/devserver/DebugWindowConnectionTest.java +++ b/vaadin-dev-server/src/test/java/com/vaadin/base/devserver/DebugWindowConnectionTest.java @@ -135,9 +135,9 @@ public void reload_twoConnections_sendReloadCommand() { reload.reload(); - JsonObject reload = Json.createObject(); - reload.put("command", "reload"); - String reloadJson = reload.toJson(); + JsonObject reloadCommand = Json.createObject(); + reloadCommand.put("command", "reload"); + String reloadJson = reloadCommand.toJson(); Mockito.verify(broadcaster).broadcast(reloadJson, resource1); Mockito.verify(broadcaster).broadcast(reloadJson, resource2); } @@ -204,7 +204,7 @@ public void reload_resourceIsDisconnected_reloadCommandIsNotSent() { public void getBackend_JRebelClassEventListenerClassLoaded_returnsJREBEL() { class JRebelInitializer { } - DebugWindowConnection reload = new DebugWindowConnection( + DebugWindowConnection connection = new DebugWindowConnection( new ClassLoader(getClass().getClassLoader()) { @Override protected Class findClass(String name) @@ -218,14 +218,14 @@ protected Class findClass(String name) } }, getMockContext()); Assert.assertEquals(BrowserLiveReload.Backend.JREBEL, - reload.getBackend()); + connection.getBackend()); } @Test public void getBackend_HotSwapVaadinIntegrationClassLoaded_returnsHOTSWAP_AGENT() { class VaadinIntegration { } - DebugWindowConnection reload = new DebugWindowConnection( + DebugWindowConnection connection = new DebugWindowConnection( new ClassLoader(getClass().getClassLoader()) { @Override protected Class findClass(String name) @@ -239,7 +239,7 @@ protected Class findClass(String name) } }, getMockContext()); Assert.assertEquals(BrowserLiveReload.Backend.HOTSWAP_AGENT, - reload.getBackend()); + connection.getBackend()); } @Test @@ -248,7 +248,7 @@ class SpringServlet { } class LiveReloadServer { } - DebugWindowConnection reload = new DebugWindowConnection( + DebugWindowConnection connection = new DebugWindowConnection( new ClassLoader(getClass().getClassLoader()) { @Override protected Class findClass(String name) @@ -264,7 +264,7 @@ protected Class findClass(String name) } }, getMockContext()); Assert.assertEquals(BrowserLiveReload.Backend.SPRING_BOOT_DEVTOOLS, - reload.getBackend()); + connection.getBackend()); } @Test From e365417d6cf0c15ebfe8aaba14073976eb31f220 Mon Sep 17 00:00:00 2001 From: caalador Date: Fri, 3 Jan 2025 13:40:03 +0200 Subject: [PATCH 10/15] chore: refactr navigation state renderer (#20777) Make the handle workflow easier to read. Add javadoc for clarification of parts that are executed. --- .../AbstractNavigationStateRenderer.java | 230 ++++++++++++------ 1 file changed, 158 insertions(+), 72 deletions(-) diff --git a/flow-server/src/main/java/com/vaadin/flow/router/internal/AbstractNavigationStateRenderer.java b/flow-server/src/main/java/com/vaadin/flow/router/internal/AbstractNavigationStateRenderer.java index 86092096d7f..aa74da5d6bd 100644 --- a/flow-server/src/main/java/com/vaadin/flow/router/internal/AbstractNavigationStateRenderer.java +++ b/flow-server/src/main/java/com/vaadin/flow/router/internal/AbstractNavigationStateRenderer.java @@ -114,7 +114,7 @@ public NavigationState getNavigationState() { *

      * Override this method to control the creation of view instances. *

      - * By default always creates new instances. + * By default, always creates new instances. * * @param * the route target type @@ -168,56 +168,25 @@ public int handle(NavigationEvent event) { clearContinueNavigationAction(ui); checkForDuplicates(routeTargetType, routeLayoutTypes); - BeforeLeaveEvent beforeNavigationDeactivating = new BeforeLeaveEvent( - event, routeTargetType, parameters, routeLayoutTypes); - - Optional result = executeBeforeLeaveNavigation(event, - beforeNavigationDeactivating); + Optional result = handleBeforeLeaveEvents(event, + routeTargetType, parameters); if (result.isPresent()) { return result.get(); } - // If navigation target is Hilla route, terminate Flow navigation logic - // here. - String route = event.getLocation().getPath().isEmpty() - ? event.getLocation().getPath() - : event.getLocation().getPath().startsWith("/") - ? event.getLocation().getPath() - : "/" + event.getLocation().getPath(); - if (MenuRegistry.hasClientRoute(route, true) && !MenuRegistry - .getClientRoutes(true).get(route).flowLayout()) { + String route = getFormattedRoute(event); + if (isClientHandled(route)) { return HttpStatusCode.OK.getCode(); } - final ArrayList chain; + final ArrayList chain = new ArrayList<>(); final boolean preserveOnRefreshTarget = isPreserveOnRefreshTarget( routeTargetType, routeLayoutTypes); - if (preserveOnRefreshTarget && !event.isForceInstantiation()) { - final Optional> maybeChain = getPreservedChain( - event); - if (maybeChain.isEmpty()) { - // We're returning because the preserved chain is not ready to - // be used as is, and requires client data requested within - // `getPreservedChain`. Once the data is retrieved from the - // client, `handle` method will be invoked with the same - // `NavigationEvent` argument. - return HttpStatusCode.OK.getCode(); - } else { - chain = maybeChain.get(); - } - } else { - - // Create an empty chain which gets populated later in - // `createChainIfEmptyAndExecuteBeforeEnterNavigation`. - chain = new ArrayList<>(); - - // Has any preserved components already been created here? If so, - // we don't want to navigate back to them ever so clear cache for - // window. - clearAllPreservedChains(ui); + if (populateChain(chain, preserveOnRefreshTarget, event)) { + return HttpStatusCode.OK.getCode(); } // Set navigationTrigger to RELOAD if this is a refresh of a preserve @@ -234,11 +203,8 @@ public int handle(NavigationEvent event) { // See https://github.com/vaadin/flow/issues/3619 for more info. pushHistoryStateIfNeeded(event, ui); - BeforeEnterEvent beforeNavigationActivating = new BeforeEnterEvent( - event, routeTargetType, parameters, routeLayoutTypes); - - result = createChainIfEmptyAndExecuteBeforeEnterNavigation( - beforeNavigationActivating, event, chain); + result = handleBeforeNavigationEvents(event, routeTargetType, + parameters, chain); if (result.isPresent()) { return result.get(); } @@ -255,18 +221,7 @@ public int handle(NavigationEvent event) { List routerLayouts = (List) (List) chain .subList(1, chain.size()); - // If a route refresh has been requested, remove all modal components. - // This is necessary because maintaining the correct modality - // cardinality and order is not feasible without knowing who opened them - // and when. - if (ui.hasModalComponent() - && event.getTrigger() == NavigationTrigger.REFRESH_ROUTE) { - Component modalComponent; - while ((modalComponent = ui.getInternals() - .getActiveModalComponent()) != null) { - modalComponent.removeFromParent(); - } - } + cleanModalComponents(event); // Change the UI according to the navigation Component chain. ui.getInternals().showRouteTarget(event.getLocation(), @@ -276,6 +231,109 @@ public int handle(NavigationEvent event) { validateStatusCode(statusCode, routeTargetType); // After navigation event + handleAfterNavigationEvents(ui, parameters); + + updatePageTitle(event, componentInstance, route); + + return statusCode; + } + + /** + * Populate element chain from a preserved chain or give clean chain to be + * populated. + * + * @param chain + * chain to populate + * @param preserveOnRefreshTarget + * preserve on refresh boolean + * @param event + * current navigation event + * @return {@code true} if additional client data requested, else + * {@code false} + */ + private boolean populateChain(ArrayList chain, + boolean preserveOnRefreshTarget, NavigationEvent event) { + if (preserveOnRefreshTarget && !event.isForceInstantiation()) { + final Optional> maybeChain = getPreservedChain( + event); + if (maybeChain.isEmpty()) { + // We're returning because the preserved chain is not ready to + // be used as is, and requires client data requested within + // `getPreservedChain`. Once the data is retrieved from the + // client, `handle` method will be invoked with the same + // `NavigationEvent` argument. + return true; + } + chain.addAll(maybeChain.get()); + } else { + // Create an empty chain which gets populated later in + // `createChainIfEmptyAndExecuteBeforeEnterNavigation`. + chain.clear(); + + // Has any preserved components already been created here? If so, + // we don't want to navigate back to them ever so clear cache for + // window. + clearAllPreservedChains(event.getUI()); + } + return false; + } + + /** + * Send before leave event to all listeners. + * + * @return optional return http status code + */ + private Optional handleBeforeLeaveEvents(NavigationEvent event, + Class routeTargetType, + RouteParameters parameters) { + BeforeLeaveEvent beforeNavigationDeactivating = new BeforeLeaveEvent( + event, routeTargetType, parameters, routeLayoutTypes); + + return executeBeforeLeaveNavigation(event, + beforeNavigationDeactivating); + } + + /** + * If a route refresh has been requested, remove all modal components. This + * is necessary because maintaining the correct modality cardinality and + * order is not feasible without knowing who opened them and when. + * + * @param event + * navigation event + */ + private static void cleanModalComponents(NavigationEvent event) { + if (event.getUI().hasModalComponent() + && event.getTrigger() == NavigationTrigger.REFRESH_ROUTE) { + Component modalComponent; + while ((modalComponent = event.getUI().getInternals() + .getActiveModalComponent()) != null) { + modalComponent.removeFromParent(); + } + } + } + + /** + * Send before navigation event to all listeners. + * + * @return optional return http status code + */ + private Optional handleBeforeNavigationEvents( + NavigationEvent event, Class routeTargetType, + RouteParameters parameters, ArrayList chain) { + BeforeEnterEvent beforeNavigationActivating = new BeforeEnterEvent( + event, routeTargetType, parameters, routeLayoutTypes); + + return createChainIfEmptyAndExecuteBeforeEnterNavigation( + beforeNavigationActivating, event, chain); + } + + /** + * Send after navigation event to all listeners. + * + * @return optional return http status code + */ + private void handleAfterNavigationEvents(UI ui, + RouteParameters parameters) { List afterNavigationHandlers = new ArrayList<>( ui.getNavigationListeners(AfterNavigationHandler.class)); afterNavigationHandlers @@ -284,10 +342,36 @@ public int handle(NavigationEvent event) { fireAfterNavigationListeners( new AfterNavigationEvent(locationChangeEvent, parameters), afterNavigationHandlers); + } - updatePageTitle(event, componentInstance, route); + /** + * Check if target route is client handled and Flow should not handle + * rendering. + * + * @param route + * formatted route target string + * @return {@code true} if client handled render for route + */ + private boolean isClientHandled(String route) { + // If navigation target is Hilla route, terminate Flow navigation logic + // here. + return MenuRegistry.hasClientRoute(route, true) + && !MenuRegistry.getClientRoutes(true).get(route).flowLayout(); + } - return statusCode; + /** + * Get the target location as a standardized route string. + * + * @param event + * navigation event + * @return route string + */ + private static String getFormattedRoute(NavigationEvent event) { + return event.getLocation().getPath().isEmpty() + ? event.getLocation().getPath() + : event.getLocation().getPath().startsWith("/") + ? event.getLocation().getPath() + : "/" + event.getLocation().getPath(); } /** @@ -315,8 +399,7 @@ protected List> getTargetParentLayouts( } private void pushHistoryStateIfNeeded(NavigationEvent event, UI ui) { - if (event instanceof ErrorNavigationEvent) { - ErrorNavigationEvent errorEvent = (ErrorNavigationEvent) event; + if (event instanceof ErrorNavigationEvent errorEvent) { if (isRouterLinkNotFoundNavigationError(errorEvent)) { // #8544 event.getState().ifPresent(s -> ui.getPage().executeJs( @@ -397,7 +480,11 @@ protected abstract void notifyNavigationTarget(Component componentInstance, protected abstract List> getRouterLayoutTypes( Class routeTargetType, Router router); - // The last element in the returned list is always a Component class + /** + * Collect the element types chain for the current navigation state. + * + * @return types chain for navigation target + */ private List> getTypesChain() { final Class routeTargetType = navigationState .getNavigationTarget(); @@ -406,10 +493,10 @@ private List> getTypesChain() { this.routeLayoutTypes); Collections.reverse(layoutTypes); - final ArrayList> chain = new ArrayList<>(); - for (Class parentType : layoutTypes) { - chain.add(parentType); - } + final ArrayList> chain = new ArrayList<>( + layoutTypes); + + // The last element in the returned list is always a Component class chain.add(routeTargetType); return chain; } @@ -496,7 +583,7 @@ private Deque getBeforeLeaveHandlers(UI ui) { /** * Inform any {@link BeforeEnterObserver}s in attaching element chain. The * event is sent first to the {@link BeforeEnterHandler}s registered within - * the {@link UI}, then to any element in the chain and to any of it's child + * the {@link UI}, then to any element in the chain and to any of its child * components in the hierarchy which implements {@link BeforeEnterHandler} * * If the chain argument is empty chainClasses is @@ -510,7 +597,7 @@ private Deque getBeforeLeaveHandlers(UI ui) { * @param chain * the chain of {@link HasElement} instances which will be * rendered. In case this is empty it'll be populated with - * instances according with the navigation event's location. + * instances according to the navigation event's location. * @return result of observer events */ private Optional createChainIfEmptyAndExecuteBeforeEnterNavigation( @@ -614,7 +701,7 @@ private Optional sendBeforeEnterEvent( if (chain != null) { // Reverse the chain to the stored ordered, since that is different - // than the notification order, and also to keep + // from the notification order, and also to keep // LocationChangeEvent.getRouteTargetChain backward compatible. chain = new ArrayList<>(chain); Collections.reverse(chain); @@ -692,8 +779,7 @@ private Optional notifyNavigationTarget(NavigationEvent event, */ private static boolean isComponentElementEqualsOrChild( BeforeEnterHandler eventHandler, Component component) { - if (eventHandler instanceof HasElement) { - HasElement hasElement = (HasElement) eventHandler; + if (eventHandler instanceof HasElement hasElement) { final Element componentElement = component.getElement(); @@ -850,11 +936,11 @@ private NavigationEvent getNavigationEvent(NavigationEvent event, /** * Checks if there exists a cached component chain of the route location in * the current window. - * + *

      * If retrieving the window name requires another round-trip, schedule it * and make a new call to the handle {@link #handle(NavigationEvent)} in the * callback. In this case, this method returns {@link Optional#empty()}. - * + *

      * If the chain is missing and needs to be created this method returns an * {@link Optional} wrapping an empty {@link ArrayList}. */ From f4eca62cdd0985f574b243e924b2b8e47327d02f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:32:01 +0100 Subject: [PATCH 11/15] chore(deps): bump org.springdoc:springdoc-openapi-starter-webmvc-ui (#20806) Bumps [org.springdoc:springdoc-openapi-starter-webmvc-ui](https://github.com/springdoc/springdoc-openapi) from 2.7.0 to 2.8.1. - [Release notes](https://github.com/springdoc/springdoc-openapi/releases) - [Changelog](https://github.com/springdoc/springdoc-openapi/blob/main/CHANGELOG.md) - [Commits](https://github.com/springdoc/springdoc-openapi/compare/v2.7.0...v2.8.1) --- updated-dependencies: - dependency-name: org.springdoc:springdoc-openapi-starter-webmvc-ui dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- flow-tests/vaadin-spring-tests/test-spring-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-tests/vaadin-spring-tests/test-spring-common/pom.xml b/flow-tests/vaadin-spring-tests/test-spring-common/pom.xml index f2fec609323..9fcb9f4b084 100644 --- a/flow-tests/vaadin-spring-tests/test-spring-common/pom.xml +++ b/flow-tests/vaadin-spring-tests/test-spring-common/pom.xml @@ -152,7 +152,7 @@ org.springdoc springdoc-openapi-starter-webmvc-ui - 2.7.0 + 2.8.1 From 234b72b3bed8ed5bc452edc7b82eb48cebd5052a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:32:39 +0100 Subject: [PATCH 12/15] chore(deps): bump com.nimbusds:nimbus-jose-jwt from 9.48 to 10.0.1 (#20805) Bumps [com.nimbusds:nimbus-jose-jwt](https://bitbucket.org/connect2id/nimbus-jose-jwt) from 9.48 to 10.0.1. - [Changelog](https://bitbucket.org/connect2id/nimbus-jose-jwt/src/master/CHANGELOG.txt) - [Commits](https://bitbucket.org/connect2id/nimbus-jose-jwt/branches/compare/10.0.1..9.48) --- updated-dependencies: - dependency-name: com.nimbusds:nimbus-jose-jwt dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- flow-tests/vaadin-spring-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-tests/vaadin-spring-tests/pom.xml b/flow-tests/vaadin-spring-tests/pom.xml index e11d87af7bf..391ad63a2d0 100644 --- a/flow-tests/vaadin-spring-tests/pom.xml +++ b/flow-tests/vaadin-spring-tests/pom.xml @@ -17,7 +17,7 @@ true 24.6.0 - 9.48 + 10.0.1 From d143ab9ddbcce5c8b0e5d804c5a9f1818ff6737e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:34:26 +0100 Subject: [PATCH 13/15] chore(deps): bump org.mockito:mockito-core from 5.14.2 to 5.15.2 (#20801) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.14.2 to 5.15.2. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.14.2...v5.15.2) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9591e43f9f0..f6fcbe31bb3 100644 --- a/pom.xml +++ b/pom.xml @@ -270,7 +270,7 @@ org.mockito mockito-core - 5.14.2 + 5.15.2 org.mockito From 19a4309ac062faacd7b2ca52d7487e8172a44fef Mon Sep 17 00:00:00 2001 From: Anton Platonov Date: Tue, 7 Jan 2025 13:57:09 +0200 Subject: [PATCH 14/15] refactor: remove dependencies --- .../main/resources/com/vaadin/flow/server/frontend/Flow.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/Flow.tsx b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/Flow.tsx index 5b308a6ce9b..a9292f4e5fa 100644 --- a/flow-server/src/main/resources/com/vaadin/flow/server/frontend/Flow.tsx +++ b/flow-server/src/main/resources/com/vaadin/flow/server/frontend/Flow.tsx @@ -14,8 +14,6 @@ * the License. */ /// -import { nanoid } from 'nanoid'; -import type { ReactAdapterElement } from 'Frontend/generated/flow/ReactAdapter.js'; import { Flow as _Flow } from "Frontend/generated/jar-resources/Flow.js"; import React, { useCallback, @@ -174,6 +172,8 @@ const prevent = () => postpone; type RouterContainer = Awaited>; +type ReactAdapterElement = HTMLElement; + type PortalEntry = { readonly children: ReactNode, readonly domNode: ReactAdapterElement, @@ -320,7 +320,7 @@ function Flow() { const addPortalEventHandler = useCallback((event: CustomEvent) => { event.preventDefault(); - const key = nanoid(); + const key = Math.random().toString(36).slice(2); dispatchPortalAction( addFlowPortal( Date: Tue, 7 Jan 2025 14:40:03 +0200 Subject: [PATCH 15/15] fix: ReactRouterOutlet interferes with layout (#20771) --- .../META-INF/resources/frontend/ReactRouterOutletElement.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/flow-react/src/main/resources/META-INF/resources/frontend/ReactRouterOutletElement.tsx b/flow-react/src/main/resources/META-INF/resources/frontend/ReactRouterOutletElement.tsx index 7cc6188626a..dfaf2c13072 100644 --- a/flow-react/src/main/resources/META-INF/resources/frontend/ReactRouterOutletElement.tsx +++ b/flow-react/src/main/resources/META-INF/resources/frontend/ReactRouterOutletElement.tsx @@ -3,6 +3,11 @@ import { ReactAdapterElement } from "Frontend/generated/flow/ReactAdapter.js"; import React from "react"; class ReactRouterOutletElement extends ReactAdapterElement { + connectedCallback() { + super.connectedCallback(); + this.style.display = 'contents'; + } + protected render(): React.ReactElement | null { return ; }