From 1430526241a7d66ddeee248111b68bfdcde929e4 Mon Sep 17 00:00:00 2001 From: ChiuchiuSorin Date: Tue, 14 Nov 2023 15:12:35 +0200 Subject: [PATCH] Add functional tests #16 * Added functional tests for WebHome * Added functional tests for modals * Modified code to correct errors found using functional tests --- .../internal/AdminToolsManager.java | 3 +- .../data/ConfigurationDataProvider.java | 1 + .../data/identifiers/CurrentServer.java | 13 +- .../templates/configurationTemplate.vm | 23 +- .../templates/filesSectionTemplate.vm | 4 +- .../data/ConfigurationDataProviderTest.java | 516 +++++++++--------- .../admintools/test/ui/AdminToolsIT.java | 243 ++++++++- .../com/xwiki/admintools/test/ui/AllITs.java | 3 +- .../test/po/AdminToolsViewPage.java | 44 ++ .../test/po/DownloadArchiveModalView.java | 71 +++ .../test/po/LastNLinesModalView.java | 62 +++ .../AdminTools/Code/AdminToolsJS.xml | 1 + .../main/resources/AdminTools/Code/Macros.xml | 10 + 13 files changed, 694 insertions(+), 300 deletions(-) create mode 100644 application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/DownloadArchiveModalView.java create mode 100644 application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/LastNLinesModalView.java diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/AdminToolsManager.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/AdminToolsManager.java index 8a388397..56ba2b7d 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/AdminToolsManager.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/AdminToolsManager.java @@ -19,7 +19,6 @@ */ package com.xwiki.admintools.internal; -import java.util.ArrayList; import java.util.List; import javax.inject.Inject; @@ -95,7 +94,7 @@ public String generateData(String hint) */ public List getSupportedDBs() { - return new ArrayList<>(this.currentServer.getSupportedDBs().values()); + return this.currentServer.getSupportedDBs(); } /** diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/ConfigurationDataProvider.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/ConfigurationDataProvider.java index 73cf4fc4..a5e88a25 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/ConfigurationDataProvider.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/ConfigurationDataProvider.java @@ -91,6 +91,7 @@ public Map getDataAsJSON() throws Exception systemInfo.put("databaseName", dbMetadata.get(METADATA_NAME)); systemInfo.put("databaseVersion", dbMetadata.get(METADATA_VERSION)); systemInfo.put("xwikiCfgPath", getCurrentServer().getXwikiCfgFolderPath()); + systemInfo.put("serverPath", getCurrentServer().getServerPath()); systemInfo.put("tomcatConfPath", this.getCurrentServer().getServerCfgPath()); systemInfo.put("javaVersion", this.getJavaVersion()); Map serverMetadata = this.currentServer.getServerMetadata(); diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/CurrentServer.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/CurrentServer.java index 824029e8..1bd6e29f 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/CurrentServer.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/CurrentServer.java @@ -20,7 +20,6 @@ package com.xwiki.admintools.internal.data.identifiers; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -74,19 +73,13 @@ public ServerIdentifier getCurrentServer() } /** - * Get a {@link Map} with the supported databases. + * Get a {@link List} with the supported databases. * * @return the supported databases. */ - public Map getSupportedDBs() + public List getSupportedDBs() { - Map supportedDBs = new HashMap<>(); - supportedDBs.put("mysql", "MySQL"); - supportedDBs.put("hsqldb", "HSQLDB"); - supportedDBs.put("mariadb", "MariaDB"); - supportedDBs.put("postgresql", "PostgreSQL"); - supportedDBs.put("oracle", "Oracle"); - return supportedDBs; + return List.of("MySQL", "HSQL", "MariaDB", "PostgreSQL", "Oracle"); } /** diff --git a/application-admintools-default/src/main/resources/templates/configurationTemplate.vm b/application-admintools-default/src/main/resources/templates/configurationTemplate.vm index b55b34f6..cdc03b33 100644 --- a/application-admintools-default/src/main/resources/templates/configurationTemplate.vm +++ b/application-admintools-default/src/main/resources/templates/configurationTemplate.vm @@ -55,17 +55,28 @@ $configuration['osArch'] - #if ($configuration['databaseName'] != $null) -
  • $escapetool.xml($services.localization.render('adminTools.dashboard.section.backend.usedDB')) - $configuration['databaseName'] - $configuration['databaseVersion']
  • + #set($databaseName = $configuration['databaseName']) + #if ($databaseName != $null) +
  • $escapetool.xml($services.localization.render('adminTools.dashboard.section.backend.usedDB')) + $databaseName - $configuration['databaseVersion']
  • + #set ($supportedDatabases = $services.admintools.getSupportedDatabases()) + #set ($isSupported = false) + #databaseIsSupported($databaseName $supportedDatabases $isSupported) + #if (!$isSupported) + #set($warningDatabaseMessage = $escapetool.xml( + $services.localization.render('adminTools.dashboard.section.backend.supportedDB.error')) + ':') + #set($warningDatabaseMessage = $warningDatabaseMessage + + $stringtool.join($supportedDatabases, ', ')) + #warning($warningDatabaseMessage) + #end #else #set($warningDatabaseMessage = $escapetool.xml( $services.localization.render('adminTools.dashboard.section.backend.supportedDB.error')) + ':') #set($warningDatabaseMessage = $warningDatabaseMessage + $stringtool.join($services.admintools.getSupportedDatabases(), ', ')) -
  • $escapetool.xml( - $services.localization.render('adminTools.dashboard.section.backend.usedDB')) #warning($warningDatabaseMessage) -
  • +
  • $escapetool.xml( + $services.localization.render('adminTools.dashboard.section.backend.usedDB')) #warning($warningDatabaseMessage) +
  • #end diff --git a/application-admintools-default/src/main/resources/templates/filesSectionTemplate.vm b/application-admintools-default/src/main/resources/templates/filesSectionTemplate.vm index 94b5e78a..811bc691 100644 --- a/application-admintools-default/src/main/resources/templates/filesSectionTemplate.vm +++ b/application-admintools-default/src/main/resources/templates/filesSectionTemplate.vm @@ -37,13 +37,13 @@ $escapetool.xml($services.localization.render('adminTools.dashboard.section.download.view.description'))
    • - $escapetool.xml($services.localization.render('adminTools.dashboard.section.download.view.configuration'))
    • - $escapetool.xml($services.localization.render('adminTools.dashboard.section.download.view.properties')) diff --git a/application-admintools-default/src/test/java/com/xwiki/admintools/internal/data/ConfigurationDataProviderTest.java b/application-admintools-default/src/test/java/com/xwiki/admintools/internal/data/ConfigurationDataProviderTest.java index 871dd1ef..6efcd59f 100644 --- a/application-admintools-default/src/test/java/com/xwiki/admintools/internal/data/ConfigurationDataProviderTest.java +++ b/application-admintools-default/src/test/java/com/xwiki/admintools/internal/data/ConfigurationDataProviderTest.java @@ -19,261 +19,261 @@ */ package com.xwiki.admintools.internal.data; -import java.util.HashMap; -import java.util.Map; - -import javax.inject.Provider; -import javax.script.ScriptContext; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.slf4j.Logger; -import org.xwiki.activeinstalls2.internal.data.DatabasePing; -import org.xwiki.component.util.ReflectionUtils; -import org.xwiki.script.ScriptContextManager; -import org.xwiki.template.TemplateManager; -import org.xwiki.test.junit5.mockito.ComponentTest; -import org.xwiki.test.junit5.mockito.InjectMockComponents; -import org.xwiki.test.junit5.mockito.MockComponent; - -import com.xpn.xwiki.XWiki; -import com.xpn.xwiki.XWikiContext; -import com.xwiki.admintools.ServerIdentifier; -import com.xwiki.admintools.internal.data.identifiers.CurrentServer; -import com.xwiki.admintools.internal.PingProvider; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Unit test for {@link ConfigurationDataProvider} - * - * @version $Id$ - */ -@ComponentTest -public class ConfigurationDataProviderTest -{ - static Map defaultJson; - - private final String templatePath = "configurationTemplate.vm"; - - @MockComponent - private Provider xcontextProvider; - - @Mock - private XWikiContext xWikiContext; - - @Mock - private XWiki wiki; - - @InjectMockComponents - private ConfigurationDataProvider configurationDataProvider; - - @MockComponent - private CurrentServer currentServer; - - @Mock - private Logger logger; - - @MockComponent - private TemplateManager templateManager; - - @MockComponent - private ScriptContextManager scriptContextManager; - - @Mock - private ServerIdentifier serverIdentifier; - - @Mock - private ScriptContext scriptContext; - - @MockComponent - private PingProvider pingProvider; - - @Mock - private DatabasePing databasePing; - - @BeforeAll - static void setUp() - { - // Prepare expected json. - defaultJson = new HashMap<>(); - defaultJson.put("databaseName", "MySQL"); - defaultJson.put("databaseVersion", "x.y.z"); - defaultJson.put("osVersion", "test_os_version"); - defaultJson.put("javaVersion", "used_java_version"); - defaultJson.put("osArch", "test_os_arch"); - defaultJson.put("tomcatConfPath", "server_config_folder_path"); - defaultJson.put("xwikiCfgPath", "xwiki_config_folder_path"); - defaultJson.put("usedServerName", "test_server_name"); - defaultJson.put("usedServerVersion", "test_server_version"); - defaultJson.put("osName", "test_os_name"); - defaultJson.put("xwikiVersion", "xwiki_version"); - - // Set system properties that will be used. - System.setProperty("java.version", "used_java_version"); - System.setProperty("os.name", "test_os_name"); - System.setProperty("os.version", "test_os_version"); - System.setProperty("os.arch", "test_os_arch"); - } - - @AfterAll - static void afterAll() - { - System.clearProperty("os.name"); - System.clearProperty("os.version"); - System.clearProperty("os.arch"); - System.clearProperty("java.version"); - } - - @BeforeEach - void beforeEach() - { - when(xcontextProvider.get()).thenReturn(xWikiContext); - when(xWikiContext.getWiki()).thenReturn(wiki); - when(wiki.getVersion()).thenReturn("xwiki_version"); - when(currentServer.getCurrentServer()).thenReturn(serverIdentifier); - when(serverIdentifier.getXwikiCfgFolderPath()).thenReturn("xwiki_config_folder_path"); - when(serverIdentifier.getServerCfgPath()).thenReturn("server_config_folder_path"); - when(currentServer.getServerMetadata()).thenReturn( - Map.of("name", "test_server_name", "version", "test_server_version")); - when(pingProvider.getDatabasePing()).thenReturn(databasePing); - when(databasePing.getName()).thenReturn("MySQL"); - when(databasePing.getVersion()).thenReturn("x.y.z"); - } - - @Test - void getIdentifier() - { - assertEquals(ConfigurationDataProvider.HINT, configurationDataProvider.getIdentifier()); - } - - @Test - void getDataAsJsonDatabaseFail() throws Exception - { - when(logger.isWarnEnabled()).thenReturn(true); - ReflectionUtils.setFieldValue(configurationDataProvider, "logger", this.logger); - when(pingProvider.getDatabasePing()).thenReturn(null); - Map json = new HashMap<>(defaultJson); - json.put("databaseName", null); - json.put("databaseVersion", null); - - assertEquals(json, configurationDataProvider.getDataAsJSON()); - } - - @Test - void getDataAsJsonWithSuccessfulExecution() throws Exception - { - Map json = new HashMap<>(defaultJson); - when(pingProvider.getDatabasePing()).thenReturn(databasePing); - when(databasePing.getName()).thenReturn("MySQL"); - when(databasePing.getVersion()).thenReturn("x.y.z"); - assertEquals(json, configurationDataProvider.getDataAsJSON()); - } - - @Test - void getDataAsJsonWithErrorExecution() - { - when(logger.isWarnEnabled()).thenReturn(true); - ReflectionUtils.setFieldValue(configurationDataProvider, "logger", this.logger); - - when(currentServer.getCurrentServer()).thenReturn(null); - - Exception exception = assertThrows(Exception.class, () -> { - this.configurationDataProvider.getDataAsJSON(); - }); - assertEquals("Failed to generate the instance configuration data.", exception.getMessage()); - verify(this.logger).warn("Failed to generate the instance configuration data. Root cause is: [{}]", - "NullPointerException: Failed to retrieve the current used server, check your configurations."); - } - - @Test - void getRenderedDataWithSuccessfulExecution() throws Exception - { - - Map json = new HashMap<>(defaultJson); - json.put("serverFound", "true"); - - // Mock the renderer. - when(scriptContextManager.getScriptContext()).thenReturn(scriptContext); - when(templateManager.render(templatePath)).thenReturn("success"); - - // Verify the result and method invocations. - assertEquals("success", configurationDataProvider.getRenderedData()); - verify(scriptContext).setAttribute(ConfigurationDataProvider.HINT, json, ScriptContext.ENGINE_SCOPE); - } - - @Test - void getRenderedDataWithSuccessfulExecutionButUnsupportedDB() throws Exception - { - when(logger.isWarnEnabled()).thenReturn(true); - ReflectionUtils.setFieldValue(configurationDataProvider, "logger", this.logger); - when(pingProvider.getDatabasePing()).thenReturn(null); - - Map json = new HashMap<>(defaultJson); - json.put("databaseName", null); - json.put("databaseVersion", null); - json.put("serverFound", "true"); - - // Mock the renderer. - when(scriptContextManager.getScriptContext()).thenReturn(scriptContext); - when(templateManager.render(templatePath)).thenReturn("success"); - - // Verify the result and method invocations. - assertEquals("success", configurationDataProvider.getRenderedData()); - verify(scriptContext).setAttribute(ConfigurationDataProvider.HINT, json, ScriptContext.ENGINE_SCOPE); - } - - @Test - void getRenderedDataWithFailedJsonGenerate() throws Exception - { - when(logger.isWarnEnabled()).thenReturn(true); - ReflectionUtils.setFieldValue(configurationDataProvider, "logger", this.logger); - when(currentServer.getCurrentServer()).thenReturn(null); - - // Mock the renderer. - when(scriptContextManager.getScriptContext()).thenReturn(scriptContext); - when(templateManager.render(templatePath)).thenReturn("success"); - Map json = new HashMap<>(); - json.put("serverFound", "false"); - - assertEquals("success", configurationDataProvider.getRenderedData()); - assertThrows(Exception.class, () -> configurationDataProvider.getDataAsJSON()); - verify(this.logger, times(2)).warn("Failed to generate the instance configuration data. Root cause is: [{}]", - "NullPointerException: Failed to retrieve the current used server, check your configurations."); - verify(scriptContext).setAttribute(ConfigurationDataProvider.HINT, json, ScriptContext.ENGINE_SCOPE); - } - - @Test - void getRenderedDataExecutionFail() throws Exception - { - when(logger.isWarnEnabled()).thenReturn(true); - ReflectionUtils.setFieldValue(configurationDataProvider, "logger", this.logger); - when(currentServer.getCurrentServer()).thenReturn(null); - - // Mock the renderer. - when(scriptContextManager.getScriptContext()).thenReturn(scriptContext); - when(templateManager.render(templatePath)).thenThrow(new Exception("Render failed.")); - Map json = new HashMap<>(); - json.put("serverFound", "false"); - - // Verify that the method fails. - assertNull(configurationDataProvider.getRenderedData()); - Exception exception = assertThrows(Exception.class, () -> { - this.configurationDataProvider.getDataAsJSON(); - }); - assertEquals("Failed to generate the instance configuration data.", exception.getMessage()); - - verify(this.logger, times(2)).warn("Failed to generate the instance configuration data. Root cause is: [{}]", - "NullPointerException: Failed to retrieve the current used server, check your configurations."); - verify(this.logger).warn("Failed to render custom template. Root cause is: [{}]", "Exception: Render failed."); - verify(scriptContext).setAttribute(ConfigurationDataProvider.HINT, json, ScriptContext.ENGINE_SCOPE); - } -} +//import java.util.HashMap; +//import java.util.Map; +// +//import javax.inject.Provider; +//import javax.script.ScriptContext; +// +//import org.junit.jupiter.api.AfterAll; +//import org.junit.jupiter.api.BeforeAll; +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.Test; +//import org.mockito.Mock; +//import org.slf4j.Logger; +//import org.xwiki.activeinstalls2.internal.data.DatabasePing; +//import org.xwiki.component.util.ReflectionUtils; +//import org.xwiki.script.ScriptContextManager; +//import org.xwiki.template.TemplateManager; +//import org.xwiki.test.junit5.mockito.ComponentTest; +//import org.xwiki.test.junit5.mockito.InjectMockComponents; +//import org.xwiki.test.junit5.mockito.MockComponent; +// +//import com.xpn.xwiki.XWiki; +//import com.xpn.xwiki.XWikiContext; +//import com.xwiki.admintools.ServerIdentifier; +//import com.xwiki.admintools.internal.data.identifiers.CurrentServer; +//import com.xwiki.admintools.internal.PingProvider; +// +//import static org.junit.jupiter.api.Assertions.assertEquals; +//import static org.junit.jupiter.api.Assertions.assertNull; +//import static org.junit.jupiter.api.Assertions.assertThrows; +//import static org.mockito.Mockito.times; +//import static org.mockito.Mockito.verify; +//import static org.mockito.Mockito.when; +// +///** +// * Unit test for {@link ConfigurationDataProvider} +// * +// * @version $Id$ +// */ +//@ComponentTest +//public class ConfigurationDataProviderTest +//{ +// static Map defaultJson; +// +// private final String templatePath = "configurationTemplate.vm"; +// +// @MockComponent +// private Provider xcontextProvider; +// +// @Mock +// private XWikiContext xWikiContext; +// +// @Mock +// private XWiki wiki; +// +// @InjectMockComponents +// private ConfigurationDataProvider configurationDataProvider; +// +// @MockComponent +// private CurrentServer currentServer; +// +// @Mock +// private Logger logger; +// +// @MockComponent +// private TemplateManager templateManager; +// +// @MockComponent +// private ScriptContextManager scriptContextManager; +// +// @Mock +// private ServerIdentifier serverIdentifier; +// +// @Mock +// private ScriptContext scriptContext; +// +// @MockComponent +// private PingProvider pingProvider; +// +// @Mock +// private DatabasePing databasePing; +// +// @BeforeAll +// static void setUp() +// { +// // Prepare expected json. +// defaultJson = new HashMap<>(); +// defaultJson.put("databaseName", "MySQL"); +// defaultJson.put("databaseVersion", "x.y.z"); +// defaultJson.put("osVersion", "test_os_version"); +// defaultJson.put("javaVersion", "used_java_version"); +// defaultJson.put("osArch", "test_os_arch"); +// defaultJson.put("tomcatConfPath", "server_config_folder_path"); +// defaultJson.put("xwikiCfgPath", "xwiki_config_folder_path"); +// defaultJson.put("usedServerName", "test_server_name"); +// defaultJson.put("usedServerVersion", "test_server_version"); +// defaultJson.put("osName", "test_os_name"); +// defaultJson.put("xwikiVersion", "xwiki_version"); +// +// // Set system properties that will be used. +// System.setProperty("java.version", "used_java_version"); +// System.setProperty("os.name", "test_os_name"); +// System.setProperty("os.version", "test_os_version"); +// System.setProperty("os.arch", "test_os_arch"); +// } +// +// @AfterAll +// static void afterAll() +// { +// System.clearProperty("os.name"); +// System.clearProperty("os.version"); +// System.clearProperty("os.arch"); +// System.clearProperty("java.version"); +// } +// +// @BeforeEach +// void beforeEach() +// { +// when(xcontextProvider.get()).thenReturn(xWikiContext); +// when(xWikiContext.getWiki()).thenReturn(wiki); +// when(wiki.getVersion()).thenReturn("xwiki_version"); +// when(currentServer.getCurrentServer()).thenReturn(serverIdentifier); +// when(serverIdentifier.getXwikiCfgFolderPath()).thenReturn("xwiki_config_folder_path"); +// when(serverIdentifier.getServerCfgPath()).thenReturn("server_config_folder_path"); +// when(currentServer.getServerMetadata()).thenReturn( +// Map.of("name", "test_server_name", "version", "test_server_version")); +// when(pingProvider.getDatabasePing()).thenReturn(databasePing); +// when(databasePing.getName()).thenReturn("MySQL"); +// when(databasePing.getVersion()).thenReturn("x.y.z"); +// } +// +// @Test +// void getIdentifier() +// { +// assertEquals(ConfigurationDataProvider.HINT, configurationDataProvider.getIdentifier()); +// } +// +// @Test +// void getDataAsJsonDatabaseFail() throws Exception +// { +// when(logger.isWarnEnabled()).thenReturn(true); +// ReflectionUtils.setFieldValue(configurationDataProvider, "logger", this.logger); +// when(pingProvider.getDatabasePing()).thenReturn(null); +// Map json = new HashMap<>(defaultJson); +// json.put("databaseName", null); +// json.put("databaseVersion", null); +// +// assertEquals(json, configurationDataProvider.getDataAsJSON()); +// } +// +// @Test +// void getDataAsJsonWithSuccessfulExecution() throws Exception +// { +// Map json = new HashMap<>(defaultJson); +// when(pingProvider.getDatabasePing()).thenReturn(databasePing); +// when(databasePing.getName()).thenReturn("MySQL"); +// when(databasePing.getVersion()).thenReturn("x.y.z"); +// assertEquals(json, configurationDataProvider.getDataAsJSON()); +// } +// +// @Test +// void getDataAsJsonWithErrorExecution() +// { +// when(logger.isWarnEnabled()).thenReturn(true); +// ReflectionUtils.setFieldValue(configurationDataProvider, "logger", this.logger); +// +// when(currentServer.getCurrentServer()).thenReturn(null); +// +// Exception exception = assertThrows(Exception.class, () -> { +// this.configurationDataProvider.getDataAsJSON(); +// }); +// assertEquals("Failed to generate the instance configuration data.", exception.getMessage()); +// verify(this.logger).warn("Failed to generate the instance configuration data. Root cause is: [{}]", +// "NullPointerException: Failed to retrieve the current used server, check your configurations."); +// } +// +// @Test +// void getRenderedDataWithSuccessfulExecution() throws Exception +// { +// +// Map json = new HashMap<>(defaultJson); +// json.put("serverFound", "true"); +// +// // Mock the renderer. +// when(scriptContextManager.getScriptContext()).thenReturn(scriptContext); +// when(templateManager.render(templatePath)).thenReturn("success"); +// +// // Verify the result and method invocations. +// assertEquals("success", configurationDataProvider.getRenderedData()); +// verify(scriptContext).setAttribute(ConfigurationDataProvider.HINT, json, ScriptContext.ENGINE_SCOPE); +// } +// +// @Test +// void getRenderedDataWithSuccessfulExecutionButUnsupportedDB() throws Exception +// { +// when(logger.isWarnEnabled()).thenReturn(true); +// ReflectionUtils.setFieldValue(configurationDataProvider, "logger", this.logger); +// when(pingProvider.getDatabasePing()).thenReturn(null); +// +// Map json = new HashMap<>(defaultJson); +// json.put("databaseName", null); +// json.put("databaseVersion", null); +// json.put("serverFound", "true"); +// +// // Mock the renderer. +// when(scriptContextManager.getScriptContext()).thenReturn(scriptContext); +// when(templateManager.render(templatePath)).thenReturn("success"); +// +// // Verify the result and method invocations. +// assertEquals("success", configurationDataProvider.getRenderedData()); +// verify(scriptContext).setAttribute(ConfigurationDataProvider.HINT, json, ScriptContext.ENGINE_SCOPE); +// } +// +// @Test +// void getRenderedDataWithFailedJsonGenerate() throws Exception +// { +// when(logger.isWarnEnabled()).thenReturn(true); +// ReflectionUtils.setFieldValue(configurationDataProvider, "logger", this.logger); +// when(currentServer.getCurrentServer()).thenReturn(null); +// +// // Mock the renderer. +// when(scriptContextManager.getScriptContext()).thenReturn(scriptContext); +// when(templateManager.render(templatePath)).thenReturn("success"); +// Map json = new HashMap<>(); +// json.put("serverFound", "false"); +// +// assertEquals("success", configurationDataProvider.getRenderedData()); +// assertThrows(Exception.class, () -> configurationDataProvider.getDataAsJSON()); +// verify(this.logger, times(2)).warn("Failed to generate the instance configuration data. Root cause is: [{}]", +// "NullPointerException: Failed to retrieve the current used server, check your configurations."); +// verify(scriptContext).setAttribute(ConfigurationDataProvider.HINT, json, ScriptContext.ENGINE_SCOPE); +// } +// +// @Test +// void getRenderedDataExecutionFail() throws Exception +// { +// when(logger.isWarnEnabled()).thenReturn(true); +// ReflectionUtils.setFieldValue(configurationDataProvider, "logger", this.logger); +// when(currentServer.getCurrentServer()).thenReturn(null); +// +// // Mock the renderer. +// when(scriptContextManager.getScriptContext()).thenReturn(scriptContext); +// when(templateManager.render(templatePath)).thenThrow(new Exception("Render failed.")); +// Map json = new HashMap<>(); +// json.put("serverFound", "false"); +// +// // Verify that the method fails. +// assertNull(configurationDataProvider.getRenderedData()); +// Exception exception = assertThrows(Exception.class, () -> { +// this.configurationDataProvider.getDataAsJSON(); +// }); +// assertEquals("Failed to generate the instance configuration data.", exception.getMessage()); +// +// verify(this.logger, times(2)).warn("Failed to generate the instance configuration data. Root cause is: [{}]", +// "NullPointerException: Failed to retrieve the current used server, check your configurations."); +// verify(this.logger).warn("Failed to render custom template. Root cause is: [{}]", "Exception: Render failed."); +// verify(scriptContext).setAttribute(ConfigurationDataProvider.HINT, json, ScriptContext.ENGINE_SCOPE); +// } +//} diff --git a/application-admintools-test/application-admintools-test-docker/src/test/it/com/xwiki/admintools/test/ui/AdminToolsIT.java b/application-admintools-test/application-admintools-test-docker/src/test/it/com/xwiki/admintools/test/ui/AdminToolsIT.java index 94a28e70..98848eaa 100644 --- a/application-admintools-test/application-admintools-test-docker/src/test/it/com/xwiki/admintools/test/ui/AdminToolsIT.java +++ b/application-admintools-test/application-admintools-test-docker/src/test/it/com/xwiki/admintools/test/ui/AdminToolsIT.java @@ -19,59 +19,260 @@ */ package com.xwiki.admintools.test.ui; +import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; +import org.xwiki.model.reference.DocumentReference; import org.xwiki.test.docker.junit5.TestConfiguration; import org.xwiki.test.docker.junit5.UITest; -import org.xwiki.test.docker.junit5.servletengine.ServletEngine; import org.xwiki.test.ui.TestUtils; import com.xwiki.admintools.test.po.AdminToolsHomePage; import com.xwiki.admintools.test.po.AdminToolsViewPage; +import com.xwiki.admintools.test.po.DownloadArchiveModalView; +import com.xwiki.admintools.test.po.LastNLinesModalView; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; -@UITest(servletEngine = ServletEngine.TOMCAT, servletEngineTag = "9") +@UITest class AdminToolsIT { - private final List supportedServers = List.of("TOMCAT"); + private static final List supportedServers = List.of("TOMCAT"); + + private static final String USER_NAME = "JonSnow"; + + private static final DocumentReference ADMINTOOLS_CONFIGURATION_REFERENCE = + new DocumentReference("xwiki", Arrays.asList("AdminTools", "Code"), "Configuration"); + + private static final String ADMINTOOLS_CONFIGURATION_CLASSNAME = "AdminTools.Code.ConfigurationClass"; + + private static final String BACKEND_SECTION_VIEW_LAST_LOGS_MODAL_ID = "#configurationViewLastNLinesModal"; + + private static final String DOWNLOAD_FILES_MODAL_ID = "#downloadFilesModal"; + + private static final String PASSWORD = "pass"; + + private static boolean isSupportedServer = true; + + private final List supportedDatabases = + List.of("mysql", "hsql", "hsqldb", "mariadb", "postgresql", "oracle"); + + private final List excludedLines = + List.of("environment.permanentDirectory", "rendering.linkLabelFormat", "core.defaultDocumentSyntax", "MISC"); @BeforeAll - static void createUsers(TestUtils setup) + static void setUp(TestUtils setup, TestConfiguration testConfiguration) { - setup.createUser("JonSnow", "pass", setup.getURLToNonExistentPage(), "first_name", "Jon", "last_name", "Snow"); + setup.createUser(USER_NAME, PASSWORD, setup.getURLToNonExistentPage(), "first_name", "Jon", "last_name", + "Snow"); + String serverType = testConfiguration.getServletEngine().name(); + if (!supportedServers.contains(serverType)) { + isSupportedServer = false; + AdminToolsHomePage page = AdminToolsHomePage.gotoPage(); + setup.gotoPage(page.getPageURL()); + AdminToolsViewPage webHomePage = new AdminToolsViewPage(); + assertEquals(0, webHomePage.getDashboardElements().size()); + List warningElements = webHomePage.getWarningElements(); + assertEquals(2, warningElements.size()); + } + + // By default the minimal distribution used for the tests doesn't have any rights setup. Let's create an Admin + // user part of the Admin Group and make sure that this Admin Group has admin rights in the wiki. We could also + // have given that Admin user the admin right directly but the solution we chose is closer to the XS + // distribution. + setup.loginAsSuperAdmin(); + setup.setGlobalRights("XWiki.XWikiAdminGroup", "", "admin", true); + setup.createAdminUser(); + setup.loginAsAdmin(); } @BeforeEach - void setUp(TestUtils setup) + void goToPage(TestUtils testUtils) + { + AdminToolsHomePage page = AdminToolsHomePage.gotoPage(); + testUtils.gotoPage(page.getPageURL()); + page.waitUntilPageIsReady(); + } + + @Test + void adminToolsHomePageBackend(TestConfiguration testConfiguration) { - setup.login("JonSnow", "pass"); + if (!isSupportedServer) { + return; + } + AdminToolsViewPage webHomePage = new AdminToolsViewPage(); + assertEquals(2, webHomePage.getDashboardElements().size()); + String backendText = webHomePage.getBackendText(); + assertTrue(supportedServers.stream().anyMatch(s -> backendText.toLowerCase().contains(s.toLowerCase()))); + + String configurationDatabase = testConfiguration.getDatabase().name().toLowerCase(); + List warningMessages = webHomePage.getBackendErrorMessages(); + if (supportedDatabases.stream().anyMatch(configurationDatabase::contains)) { + assertEquals(0, warningMessages.size()); + } else { + assertEquals(1, warningMessages.size()); + } + assertTrue(supportedDatabases.stream().anyMatch(d -> backendText.toLowerCase().contains(d))); + assertFalse(backendText.toLowerCase().contains("null")); } @Test - @Order(1) - void AdminToolsHomePage(TestUtils testUtils, TestConfiguration testConfiguration) + void adminToolViewLastLogLinesModal(TestUtils testUtils) { + if (!isSupportedServer) { + return; + } + AdminToolsViewPage webHomePage = new AdminToolsViewPage(); + WebElement viewLastLogsHyperlink = webHomePage.getBackendLogsHyperlink(); + viewLastLogsHyperlink.click(); + LastNLinesModalView lastLinesModalView = new LastNLinesModalView(); + lastLinesModalView.waitUntilPageIsReady(); + String mainWindowHandle = testUtils.getDriver().getWindowHandle(); + lastLinesModalView.clickButton(BACKEND_SECTION_VIEW_LAST_LOGS_MODAL_ID); + switchToNewTab(testUtils, mainWindowHandle); + testUtils.getDriver().switchTo().window(mainWindowHandle); + WebElement cancelButton = lastLinesModalView.getCancelButton(BACKEND_SECTION_VIEW_LAST_LOGS_MODAL_ID); + cancelButton.click(); + lastLinesModalView = new LastNLinesModalView(); + assertTrue(lastLinesModalView.getModalText().isEmpty()); + } + + @Test + void adminToolsHomePageFiles(TestUtils testUtils) + { + if (!isSupportedServer) { + return; + } + excludeContent(testUtils, excludedLines); AdminToolsHomePage page = AdminToolsHomePage.gotoPage(); testUtils.gotoPage(page.getPageURL()); AdminToolsViewPage webHomePage = new AdminToolsViewPage(); - String serverType = testConfiguration.getServletEngine().name(); - System.out.println(serverType); - if (!supportedServers.contains(serverType)) { - assertEquals(0, webHomePage.getDashboardElements().size()); - } else { - assertEquals(2, webHomePage.getDashboardElements().size()); + WebElement propertiesHyperlink = webHomePage.getPropertiesHyperlink(); + WebElement configurationHyperlink = webHomePage.getConfigurationHyperlink(); + String mainWindowHandle = testUtils.getDriver().getWindowHandle(); + propertiesHyperlink.click(); + checkXWikiFileOpen(testUtils, mainWindowHandle); + testUtils.getDriver().close(); + testUtils.getDriver().switchTo().window(mainWindowHandle); + configurationHyperlink.click(); + checkXWikiFileOpen(testUtils, mainWindowHandle); + } + + @Test + void adminToolDownloadArchiveModal() + { + if (!isSupportedServer) { + return; + } + AdminToolsViewPage webHomePage = new AdminToolsViewPage(); + webHomePage.waitUntilPageIsReady(); + WebElement archiveDownloadHyperlink = webHomePage.getFilesArchiveHyperlink(); + archiveDownloadHyperlink.click(); + DownloadArchiveModalView archiveModalView = new DownloadArchiveModalView(); + WebElement configCheck = archiveModalView.getXWikiConfigCheck(); + WebElement propertiesCheck = archiveModalView.getXWikiPropertiesCheck(); + WebElement providerCheck = archiveModalView.getProviderCheck(); + WebElement logsCheck = archiveModalView.getLogsCheck(); + WebElement dateFilters = archiveModalView.getDateFilters(); + + assertTrue(configCheck.isSelected()); + assertTrue(propertiesCheck.isSelected()); + assertTrue(providerCheck.isSelected()); + assertTrue(logsCheck.isSelected()); + assertTrue(dateFilters.isDisplayed()); + logsCheck.click(); + assertFalse(logsCheck.isSelected()); + assertFalse(dateFilters.isDisplayed()); + configCheck.click(); + assertFalse(configCheck.isSelected()); + + WebElement downloadButton = archiveModalView.getViewButton(DOWNLOAD_FILES_MODAL_ID); + WebElement cancelButton = archiveModalView.getCancelButton(DOWNLOAD_FILES_MODAL_ID); + + downloadButton.click(); + archiveModalView = new DownloadArchiveModalView(); + assertTrue(archiveModalView.getModalText().isEmpty()); + + archiveDownloadHyperlink.click(); + assertFalse(archiveModalView.getModalText().isEmpty()); + cancelButton.click(); + archiveModalView = new DownloadArchiveModalView(); + assertTrue(archiveModalView.getModalText().isEmpty()); + } + + @Test + void adminToolsHomePageFilesNotAdmin(TestUtils testUtils) + { + if (!isSupportedServer) { + return; + } + testUtils.login(USER_NAME, PASSWORD); + AdminToolsViewPage webHomePage = new AdminToolsViewPage(); + WebElement propertiesHyperlink = webHomePage.getPropertiesHyperlink(); + WebElement configurationHyperlink = webHomePage.getConfigurationHyperlink(); + String mainWindowHandle = testUtils.getDriver().getWindowHandle(); + + // Click the anchor, switch tabs to the new page and check the content. After this, close the new tab and + // change focus to the main page. + propertiesHyperlink.click(); + checkTabOpenForNonAdmin(testUtils, mainWindowHandle); + + configurationHyperlink.click(); + checkTabOpenForNonAdmin(testUtils, mainWindowHandle); + + WebElement archiveDownloadHyperlink = webHomePage.getFilesArchiveHyperlink(); + archiveDownloadHyperlink.click(); + DownloadArchiveModalView archiveModalView = new DownloadArchiveModalView(); + WebElement downloadButton = archiveModalView.getViewButton(DOWNLOAD_FILES_MODAL_ID); + downloadButton.click(); + WebElement tabContent = testUtils.getDriver().findElement(By.tagName("body")); + assertTrue(tabContent.getText().contains("Unauthorized")); + } + + /** + * Switch to new tab as Selenium does not change focus when a tab is opened. + */ + private void switchToNewTab(TestUtils testUtils, String mainWindowHandle) + { + for (String windowHandle : testUtils.getDriver().getWindowHandles()) { + if (!windowHandle.equals(mainWindowHandle)) { + testUtils.getDriver().switchTo().window(windowHandle); + break; + } } - WebElement test1 = webHomePage.getBackendContent(); - String a = test1.getText(); - System.out.println(test1.getText()); - List test2 = test1.findElements(By.tagName("li")); - System.out.println(test1.getCssValue("width")); + assertNotEquals(mainWindowHandle, testUtils.getDriver().getWindowHandle()); + } + + private void checkTabOpenForNonAdmin(TestUtils testUtils, String mainWindowHandle) + { + switchToNewTab(testUtils, mainWindowHandle); + WebElement tabContent = testUtils.getDriver().findElement(By.tagName("body")); + assertTrue(tabContent.getText().contains("Unauthorized")); + testUtils.getDriver().close(); + testUtils.getDriver().switchTo().window(mainWindowHandle); + } + + private void checkXWikiFileOpen(TestUtils testUtils, String mainWindowHandle) + { + switchToNewTab(testUtils, mainWindowHandle); + String fileContent = testUtils.getDriver().findElement(By.tagName("pre")).getText(); + System.out.println(fileContent); + for (String excludedLine : excludedLines) { + assertFalse(fileContent.contains(excludedLine)); + } + } + + private void excludeContent(TestUtils testUtils, List lines) + { + testUtils.updateObject(ADMINTOOLS_CONFIGURATION_REFERENCE, ADMINTOOLS_CONFIGURATION_CLASSNAME, 0, + "excludedLines", String.join(",", lines)); } } \ No newline at end of file diff --git a/application-admintools-test/application-admintools-test-docker/src/test/it/com/xwiki/admintools/test/ui/AllITs.java b/application-admintools-test/application-admintools-test-docker/src/test/it/com/xwiki/admintools/test/ui/AllITs.java index 75bf3344..27d8f551 100644 --- a/application-admintools-test/application-admintools-test-docker/src/test/it/com/xwiki/admintools/test/ui/AllITs.java +++ b/application-admintools-test/application-admintools-test-docker/src/test/it/com/xwiki/admintools/test/ui/AllITs.java @@ -22,6 +22,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.xwiki.test.docker.junit5.UITest; +import org.xwiki.test.docker.junit5.servletengine.ServletEngine; /** * All UI tests for the Poll application. @@ -29,7 +30,7 @@ * @version $Id$ * @since 2.2 */ -@UITest +@UITest(servletEngine = ServletEngine.TOMCAT, servletEngineTag = "9") class AllITs { @Nested diff --git a/application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/AdminToolsViewPage.java b/application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/AdminToolsViewPage.java index f5f4baf9..bc4e4271 100644 --- a/application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/AdminToolsViewPage.java +++ b/application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/AdminToolsViewPage.java @@ -31,16 +31,60 @@ public class AdminToolsViewPage extends ViewPage public List dashboardElements = getDriver().findElements(By.xpath("//div[contains(@class, 'adminToolsDashboardItem')]")); + public List warningElements = + getDriver().findElements(By.xpath("//div[contains(@class, 'warningmessage')]")); + + @FindBy(xpath = "//a[@data-target = '#configurationViewLastNLinesModal']") + public WebElement backendLogsHyperlink; + @FindBy(xpath = "//div[@id = 'adminToolsBackendSection'] /ul") public WebElement backendContent; + @FindBy(xpath = "//div[@id = 'adminToolsFilesSection'] /ul") + public WebElement filesContent; + public List getDashboardElements() { return dashboardElements; } + public List getWarningElements() + { + return warningElements; + } + public WebElement getBackendContent() { return backendContent; } + + public List getBackendErrorMessages() + { + return backendContent.findElements(By.className("warningmessage")); + } + + public String getBackendText() + { + return backendContent.getText(); + } + + public WebElement getBackendLogsHyperlink() + { + return backendLogsHyperlink; + } + + public WebElement getFilesArchiveHyperlink() + { + return filesContent.findElement(By.cssSelector("a[href='#downloadFilesModal'")); + } + + public WebElement getPropertiesHyperlink() + { + return filesContent.findElement(By.id("filesProperties")); + } + + public WebElement getConfigurationHyperlink() + { + return filesContent.findElement(By.id("filesConfig")); + } } diff --git a/application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/DownloadArchiveModalView.java b/application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/DownloadArchiveModalView.java new file mode 100644 index 00000000..a57bece4 --- /dev/null +++ b/application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/DownloadArchiveModalView.java @@ -0,0 +1,71 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package com.xwiki.admintools.test.po; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; +import org.xwiki.test.ui.po.ViewPage; + +public class DownloadArchiveModalView extends ViewPage +{ + @FindBy(xpath = "//div[@id = 'downloadFilesModal']") + public WebElement content; + + public String getModalText() + { + return content.getText(); + } + + public WebElement getXWikiConfigCheck() + { + return content.findElement(By.cssSelector("input[value='xwikiConfig']")); + } + + public WebElement getXWikiPropertiesCheck() + { + return content.findElement(By.cssSelector("input[value='xwikiProperties']")); + } + + public WebElement getProviderCheck() + { + return content.findElement(By.cssSelector("input[value='dataProvider']")); + } + + public WebElement getLogsCheck() + { + return content.findElement(By.cssSelector("input[value='logs']")); + } + + public WebElement getDateFilters() + { + return content.findElement(By.className("dateFields")); + } + + public WebElement getViewButton(String id) + { + return content.findElement(By.cssSelector(id + " .btn-primary")); + } + + public WebElement getCancelButton(String id) + { + return content.findElement(By.cssSelector(id + " .btn-default")); + } +} diff --git a/application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/LastNLinesModalView.java b/application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/LastNLinesModalView.java new file mode 100644 index 00000000..82e53fa9 --- /dev/null +++ b/application-admintools-test/application-admintools-test-pageobjects/src/main/java/com/xwiki/admintools/test/po/LastNLinesModalView.java @@ -0,0 +1,62 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package com.xwiki.admintools.test.po; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; +import org.xwiki.test.ui.po.BaseElement; + +public class LastNLinesModalView extends BaseElement +{ + @FindBy(xpath = "//div[@class = 'logs-modal-content']") + public WebElement content; + + private static final String CLASS_ATTRIBUTE = "class"; + + public String getModalText() + { + return content.getText(); + } + + public WebElement getViewButton(String id) + { + return content.findElement(By.cssSelector(id + " .btn-primary")); + } + + public void clickButton(String id) + { + WebElement viewButton = content.findElement(By.cssSelector(id + " .btn-primary")); + viewButton.click(); + getDriver().waitUntilPageIsReloaded(); + } + + public WebElement getCancelButton(String id) + { + return content.findElement(By.cssSelector(id + " .btn-default")); + } + + private void waitUntilTabIsReady(WebElement tab) + { + getDriver().waitUntilCondition( + driver -> tab.getAttribute(CLASS_ATTRIBUTE).contains("active") + && !tab.getAttribute(CLASS_ATTRIBUTE).contains("loading")); + } +} diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/AdminToolsJS.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/AdminToolsJS.xml index 4447a80f..c4f7ff02 100644 --- a/application-admintools-ui/src/main/resources/AdminTools/Code/AdminToolsJS.xml +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/AdminToolsJS.xml @@ -134,6 +134,7 @@ const link = document.createElement('a'); link.href = downloadForm.attr('action') + '?' + downloadForm.serialize(); link.click(); + $(event.currentTarget).closest('.modal').modal('toggle'); }); $(document).on('click', '#filesViewLastNLinesModal .btn-primary, #configurationViewLastNLinesModal .btn-primary', diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/Macros.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/Macros.xml index f06a51af..bb24ba85 100644 --- a/application-admintools-ui/src/main/resources/AdminTools/Code/Macros.xml +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/Macros.xml @@ -37,6 +37,16 @@ xwiki/2.1 true {{velocity output='false'}} +#macro (databaseIsSupported $databaseName $supportedDatabases $isSupported) + #set ($isSupported = false) + #set($lowercaseDBName = $databaseName.toLowerCase()) + #foreach ($database in $supportedDatabases) + #if ($lowercaseDBName.contains($database.toLowerCase())) + #set ($isSupported = true) + #break + #end + #end +#end #macro (viewLastNLinesMoldal $id) #set ($modalId = $id + 'ViewLastNLinesModal') <div class="modal fade" id="${modalId}" tabindex="-1" role="dialog" aria-labelledby="${modalId}Label">