From 0d27e3361bb1f30b173432ae9db923d2e55c03e1 Mon Sep 17 00:00:00 2001 From: Tomi Virtanen Date: Mon, 2 Sep 2024 09:24:08 +0300 Subject: [PATCH] chore: add premiumFeatures.enable token to build info (#19846) * chore: add premiumFeatures.enable token to build info * dropped _TOKEN from constant name * formatting * Update flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com> * Update flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java --------- Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com> --- .../flow/plugin/base/BuildFrontendUtil.java | 13 +- .../plugin/base/BuildFrontendUtilTest.java | 191 ++++++++++-------- .../com/vaadin/flow/server/Constants.java | 1 + 3 files changed, 120 insertions(+), 85 deletions(-) diff --git a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java index 3087237392a..01e499aa190 100644 --- a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java +++ b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java @@ -755,9 +755,16 @@ public static void updateBuildFile(PluginAdapterBuild adapter, buildInfo.put(SERVLET_PARAMETER_PRODUCTION_MODE, true); buildInfo.put(APPLICATION_IDENTIFIER, adapter.applicationIdentifier()); - if (licenseRequired && LocalSubscriptionKey.get() != null) { - adapter.logInfo("Daily Active User tracking enabled"); - buildInfo.put(DAU_TOKEN, true); + if (licenseRequired) { + if (LocalSubscriptionKey.get() != null) { + adapter.logInfo("Daily Active User tracking enabled"); + buildInfo.put(DAU_TOKEN, true); + } + if (LicenseChecker.isValidLicense("vaadin-commercial-cc-client", + null, BuildType.PRODUCTION)) { + adapter.logInfo("Premium Features are enabled"); + buildInfo.put(Constants.PREMIUM_FEATURES, true); + } } FileUtils.write(tokenFile, JsonUtil.stringify(buildInfo, 2) + "\n", diff --git a/flow-plugins/flow-plugin-base/src/test/java/com/vaadin/flow/plugin/base/BuildFrontendUtilTest.java b/flow-plugins/flow-plugin-base/src/test/java/com/vaadin/flow/plugin/base/BuildFrontendUtilTest.java index 98cb8b636fa..4528975cd4f 100644 --- a/flow-plugins/flow-plugin-base/src/test/java/com/vaadin/flow/plugin/base/BuildFrontendUtilTest.java +++ b/flow-plugins/flow-plugin-base/src/test/java/com/vaadin/flow/plugin/base/BuildFrontendUtilTest.java @@ -28,7 +28,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.mockito.ArgumentMatchers; import org.mockito.InOrder; import org.mockito.MockedConstruction; import org.mockito.MockedStatic; @@ -50,6 +49,7 @@ import com.vaadin.flow.server.frontend.scanner.ClassFinder; import com.vaadin.flow.server.frontend.scanner.FrontendDependenciesScanner; import com.vaadin.flow.utils.LookupImpl; +import com.vaadin.pro.licensechecker.LicenseChecker; import com.vaadin.pro.licensechecker.Product; import elemental.json.Json; @@ -219,24 +219,13 @@ public void detectsUsedCommercialComponents() { @Test public void propagateBuildInfo_tokenFileNotExisting_createTokenFile() throws Exception { - fillAdapter(); - - BuildFrontendUtil.propagateBuildInfo(adapter); - File tokenFile = new File(resourceOutput, TOKEN_FILE); - Assert.assertTrue("Token file should have been created", - tokenFile.exists()); + prepareAndAssertTokenFile(); } @Test public void propagateBuildInfo_existingTokenFileWithDifferentContent_overwritesTokenFile() throws Exception { - fillAdapter(); - - BuildFrontendUtil.propagateBuildInfo(adapter); - - File tokenFile = new File(resourceOutput, TOKEN_FILE); - Assert.assertTrue("Token file should have been created", - tokenFile.exists()); + File tokenFile = prepareAndAssertTokenFile(); long lastModified = tokenFile.lastModified(); Thread.sleep(100); @@ -250,13 +239,7 @@ public void propagateBuildInfo_existingTokenFileWithDifferentContent_overwritesT @Test public void propagateBuildInfo_existingTokenFileWithSameContent_doesNotWriteTokenFile() throws Exception { - fillAdapter(); - - BuildFrontendUtil.propagateBuildInfo(adapter); - - File tokenFile = new File(resourceOutput, TOKEN_FILE); - Assert.assertTrue("Token file should have been created", - tokenFile.exists()); + File tokenFile = prepareAndAssertTokenFile(); long lastModified = tokenFile.lastModified(); Thread.sleep(100); @@ -321,13 +304,7 @@ public void updateBuildFile_tokenFileNotExisting_doNothing() @Test public void updateBuildFile_tokenExisting_developmentEntriesRemoved() throws Exception { - fillAdapter(); - - BuildFrontendUtil.propagateBuildInfo(adapter); - - File tokenFile = new File(resourceOutput, TOKEN_FILE); - Assert.assertTrue("Token file should have been created", - tokenFile.exists()); + File tokenFile = prepareAndAssertTokenFile(); JsonObject buildInfoJsonDev = Json .parse(Files.readString(tokenFile.toPath())); @@ -347,13 +324,7 @@ public void updateBuildFile_tokenExisting_developmentEntriesRemoved() @Test public void updateBuildFile_tokenExisting_applicationIdentifierAdded() throws Exception { - fillAdapter(); - - BuildFrontendUtil.propagateBuildInfo(adapter); - - File tokenFile = new File(resourceOutput, TOKEN_FILE); - Assert.assertTrue("Token file should have been created", - tokenFile.exists()); + File tokenFile = prepareAndAssertTokenFile(); BuildFrontendUtil.updateBuildFile(adapter, false); Assert.assertTrue("Token file should still exist", tokenFile.exists()); @@ -367,42 +338,34 @@ public void updateBuildFile_tokenExisting_applicationIdentifierAdded() @Test public void updateBuildFile_tokenExisting_licenseRequiredAndSubscriptionKey_dauFlagAdded() throws Exception { - fillAdapter(); - - BuildFrontendUtil.propagateBuildInfo(adapter); - - File tokenFile = new File(resourceOutput, TOKEN_FILE); - Assert.assertTrue("Token file should have been created", - tokenFile.exists()); - - String subscriptionKey = System.getProperty("vaadin.subscriptionKey"); - System.setProperty("vaadin.subscriptionKey", "sub-123"); - try { - BuildFrontendUtil.updateBuildFile(adapter, true); - } finally { - if (subscriptionKey != null) { - System.setProperty("vaadin.subscriptionKey", subscriptionKey); - } else { - System.clearProperty("vaadin.subscriptionKey"); + File tokenFile = prepareAndAssertTokenFile(); + withMockedLicenseChecker(false, () -> { + String subscriptionKey = System + .getProperty("vaadin.subscriptionKey"); + System.setProperty("vaadin.subscriptionKey", "sub-123"); + try { + BuildFrontendUtil.updateBuildFile(adapter, true); + } finally { + if (subscriptionKey != null) { + System.setProperty("vaadin.subscriptionKey", + subscriptionKey); + } else { + System.clearProperty("vaadin.subscriptionKey"); + } } - } - Assert.assertTrue("Token file should still exist", tokenFile.exists()); - JsonObject buildInfoJsonProd = Json - .parse(Files.readString(tokenFile.toPath())); - Assert.assertTrue("DAU flag should be active in token file", - buildInfoJsonProd.getBoolean(Constants.DAU_TOKEN)); + Assert.assertTrue("Token file should still exist", + tokenFile.exists()); + JsonObject buildInfoJsonProd = Json + .parse(Files.readString(tokenFile.toPath())); + Assert.assertTrue("DAU flag should be active in token file", + buildInfoJsonProd.getBoolean(Constants.DAU_TOKEN)); + }); } @Test public void updateBuildFile_tokenExisting_licenseNotRequiredAndSubscriptionKey_dauFlagNotAdded() throws Exception { - fillAdapter(); - - BuildFrontendUtil.propagateBuildInfo(adapter); - - File tokenFile = new File(resourceOutput, TOKEN_FILE); - Assert.assertTrue("Token file should have been created", - tokenFile.exists()); + File tokenFile = prepareAndAssertTokenFile(); String subscriptionKey = System.getProperty("vaadin.subscriptionKey"); System.setProperty("vaadin.subscriptionKey", "sub-123"); @@ -425,6 +388,86 @@ public void updateBuildFile_tokenExisting_licenseNotRequiredAndSubscriptionKey_d @Test public void updateBuildFile_tokenExisting_licenseRequiredNoSubscriptionKey_dauFlagNotAdded() throws Exception { + File tokenFile = prepareAndAssertTokenFile(); + withMockedLicenseChecker(false, () -> { + String subscriptionKey = System + .getProperty("vaadin.subscriptionKey"); + System.clearProperty("vaadin.subscriptionKey"); + try { + BuildFrontendUtil.updateBuildFile(adapter, true); + } finally { + if (subscriptionKey != null) { + System.setProperty("vaadin.subscriptionKey", + subscriptionKey); + } else { + System.clearProperty("vaadin.subscriptionKey"); + } + } + Assert.assertTrue("Token file should still exist", + tokenFile.exists()); + JsonObject buildInfoJsonProd = Json + .parse(Files.readString(tokenFile.toPath())); + Assert.assertFalse("DAU flag should not be present in token file", + buildInfoJsonProd.hasKey(Constants.DAU_TOKEN)); + }); + } + + @Test + public void updateBuildFile_tokenExisting_licenseRequiredAndIsPremiumLike_premiumFeaturesFlagAdded() + throws Exception { + File tokenFile = prepareAndAssertTokenFile(); + + withMockedLicenseChecker(true, () -> { + BuildFrontendUtil.updateBuildFile(adapter, true); + Assert.assertTrue("Token file should still exist", + tokenFile.exists()); + JsonObject buildInfoJsonProd = Json + .parse(Files.readString(tokenFile.toPath())); + Assert.assertTrue( + Constants.PREMIUM_FEATURES + + " flag should be active in token file", + buildInfoJsonProd.getBoolean(Constants.PREMIUM_FEATURES)); + }); + } + + @Test + public void updateBuildFile_tokenExisting_licenseRequiredAndIsNotPremiumLike_premiumFeaturesFlagNotAdded() + throws Exception { + File tokenFile = prepareAndAssertTokenFile(); + + withMockedLicenseChecker(false, () -> { + BuildFrontendUtil.updateBuildFile(adapter, true); + Assert.assertTrue("Token file should still exist", + tokenFile.exists()); + JsonObject buildInfoJsonProd = Json + .parse(Files.readString(tokenFile.toPath())); + Assert.assertFalse( + Constants.PREMIUM_FEATURES + + " flag should not be active in token file", + buildInfoJsonProd.hasKey(Constants.PREMIUM_FEATURES)); + }); + } + + private void withMockedLicenseChecker(boolean isValidLicense, + ThrowingRunnable test) throws IOException { + try (MockedStatic licenseChecker = Mockito + .mockStatic(LicenseChecker.class)) { + licenseChecker + .when(() -> LicenseChecker.isValidLicense(Mockito.any(), + Mockito.any(), Mockito.any())) + .thenReturn(isValidLicense); + licenseChecker.when(LicenseChecker::getLogger) + .thenReturn(Mockito.mock(org.slf4j.Logger.class)); + test.run(); + } + } + + @FunctionalInterface + private interface ThrowingRunnable { + void run() throws IOException; + } + + private File prepareAndAssertTokenFile() throws URISyntaxException { fillAdapter(); BuildFrontendUtil.propagateBuildInfo(adapter); @@ -432,23 +475,7 @@ public void updateBuildFile_tokenExisting_licenseRequiredNoSubscriptionKey_dauFl File tokenFile = new File(resourceOutput, TOKEN_FILE); Assert.assertTrue("Token file should have been created", tokenFile.exists()); - - String subscriptionKey = System.getProperty("vaadin.subscriptionKey"); - System.clearProperty("vaadin.subscriptionKey"); - try { - BuildFrontendUtil.updateBuildFile(adapter, true); - } finally { - if (subscriptionKey != null) { - System.setProperty("vaadin.subscriptionKey", subscriptionKey); - } else { - System.clearProperty("vaadin.subscriptionKey"); - } - } - Assert.assertTrue("Token file should still exist", tokenFile.exists()); - JsonObject buildInfoJsonProd = Json - .parse(Files.readString(tokenFile.toPath())); - Assert.assertFalse("DAU flag should not be present in token file", - buildInfoJsonProd.hasKey(Constants.DAU_TOKEN)); + return tokenFile; } @Test diff --git a/flow-server/src/main/java/com/vaadin/flow/server/Constants.java b/flow-server/src/main/java/com/vaadin/flow/server/Constants.java index 46f87c07e92..4b93a0d1280 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/Constants.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/Constants.java @@ -46,6 +46,7 @@ public final class Constants implements Serializable { public static final String EXTERNAL_STATS_FILE_TOKEN = "externalStatsFile"; public static final String EXTERNAL_STATS_URL_TOKEN = "externalStatsUrl"; public static final String DAU_TOKEN = "dau.enable"; + public static final String PREMIUM_FEATURES = "premiumFeatures.enable"; public static final String POLYFILLS_DEFAULT_VALUE = "";