You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2020/05/09 18:34:30 UTC
[directory-studio] 01/01: DIRSTUDIO-1250: Fix paged search
This is an automated email from the ASF dual-hosted git repository.
seelmann pushed a commit to branch DIRSTUDIO-1250-fix-paged-search
in repository https://gitbox.apache.org/repos/asf/directory-studio.git
commit f592d7d033b2b1397125355b28f1f0b4430b8b84
Author: Stefan Seelmann <ma...@stefan-seelmann.de>
AuthorDate: Sat May 9 19:23:35 2020 +0200
DIRSTUDIO-1250: Fix paged search
* Do not use PagedResults.getCookieValue() which is ApacheDS specific
* Add tests against OpenLDAP
---
README.md | 11 +-
.../ldapbrowser/core/jobs/ExportLdifRunnable.java | 3 +-
.../core/jobs/InitializeChildrenRunnable.java | 12 +-
.../ldapbrowser/core/jobs/SearchRunnable.java | 12 +-
tests/test.integration.ui/pom-first.xml | 2 +
.../studio/test/integration/ui/OpenLdapTest.java | 296 +++++++++++++++++++++
.../studio/test/integration/ui/SearchTest.java | 1 -
.../integration/ui/bots/ConnectionsViewBot.java | 13 +-
.../studio/test/integration/ui/OpenLdapTest.ldif | 222 ++++++++++++++++
9 files changed, 550 insertions(+), 22 deletions(-)
diff --git a/README.md b/README.md
index 4809945..45b70e1 100644
--- a/README.md
+++ b/README.md
@@ -55,14 +55,17 @@ or on Windows :
### Tests
-* Unit tests included in src/test/java of each plugin are executed automatically and run in 'test' phase
-* Core integration tests in tests/test.integration.core are executed automatically and run in 'integration-test' phase
-* SWTBot based UI integration tests in tests/test.integration.ui are disabled by default. They can be enabled with `-Denable-ui-tests`.
- A failing test generates a screenshot. To not block the developer computer they can run within a virtual framebuffer:
+* Unit tests included in `src/test/java` of each plugin are executed automatically and run in 'test' phase
+* Core integration tests in `tests/test.integration.core` are executed automatically and run in 'integration-test' phase
+* UI integration tests based on SWTBot in `tests/test.integration.ui` are disabled by default. They can be enabled with `-Denable-ui-tests`. A failing test generates a screenshot. To not block the developer computer they can run within a virtual framebuffer:
export DISPLAY=:99
Xvfb :99 -screen 0 1024x768x16 &
+* Some UI integration tests expect a running OpenLDAP server and are skipped otherwise:
+
+ docker run -it --rm -p 20389:389 -p 20636:636 --name openldap osixia/openldap:1.3.0
+
### Build issues
Tycho doesn't handle snapshot dependencies well. The first time a snapshot dependency is used within the build it is cached in `~/.m2/repository/p2`. Afterwards any change in the dependency (e.g. ApacheDS or LDAP API) is not considered unless it is deleted from the cache.
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportLdifRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportLdifRunnable.java
index 2879339..f559468 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportLdifRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportLdifRunnable.java
@@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.ArrayUtils;
import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.entry.Value;
@@ -273,7 +274,7 @@ public class ExportLdifRunnable implements StudioConnectionRunnableWithProgress
if ( responseControl instanceof PagedResults )
{
PagedResults prc = ( PagedResults ) responseControl;
- if ( prc.getCookieValue() > 0 )
+ if ( ArrayUtils.isNotEmpty( prc.getCookie() ) )
{
// search again: pass the response control cookie to the request control
byte[] cookie = prc.getCookie();
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/InitializeChildrenRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/InitializeChildrenRunnable.java
index 47e1e14..32eeb12 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/InitializeChildrenRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/InitializeChildrenRunnable.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import org.apache.commons.lang3.ArrayUtils;
import org.apache.directory.api.ldap.model.message.Control;
import org.apache.directory.api.ldap.model.message.SearchScope;
import org.apache.directory.api.ldap.model.message.controls.PagedResults;
@@ -65,7 +66,6 @@ public class InitializeChildrenRunnable implements StudioConnectionBulkRunnableW
/** The paged search control, only used internally. */
private PagedResults pagedSearchControl;
-
/**
* Creates a new instance of InitializeChildrenRunnable.
*
@@ -198,7 +198,7 @@ public class InitializeChildrenRunnable implements StudioConnectionBulkRunnableW
{
monitor.reportProgress( BrowserCoreMessages.bind( BrowserCoreMessages.jobs__init_entries_progress_sub,
new String[]
- { parent.getDn().getName() } ) );
+ { parent.getDn().getName() } ) );
// clear old children
clearCaches( parent, purgeAllCaches );
@@ -262,7 +262,7 @@ public class InitializeChildrenRunnable implements StudioConnectionBulkRunnableW
{
if ( search.isPagedSearchScrollMode() )
{
- if ( prRequestControl.getCookieValue() > 0 )
+ if ( ArrayUtils.isNotEmpty( prRequestControl.getCookie() ) )
{
// create top page search runnable, same as original search
InitializeChildrenRunnable topPageChildrenRunnable = new InitializeChildrenRunnable(
@@ -270,7 +270,7 @@ public class InitializeChildrenRunnable implements StudioConnectionBulkRunnableW
parent.setTopPageChildrenRunnable( topPageChildrenRunnable );
}
- if ( prResponseControl.getCookieValue() > 0 )
+ if ( ArrayUtils.isNotEmpty( prResponseControl.getCookie() ) )
{
PagedResults newPrc = Controls.newPagedResultsControl( prRequestControl.getSize(),
prResponseControl.getCookie() );
@@ -282,7 +282,7 @@ public class InitializeChildrenRunnable implements StudioConnectionBulkRunnableW
else
{
// transparently continue search, till count limit is reached
- if ( prResponseControl.getCookieValue() > 0
+ if ( ArrayUtils.isNotEmpty( prResponseControl.getCookie() )
&& ( search.getCountLimit() == 0 || search.getSearchResults().length < search
.getCountLimit() ) )
{
@@ -359,7 +359,7 @@ public class InitializeChildrenRunnable implements StudioConnectionBulkRunnableW
ISearchResult[] srs = search.getSearchResults();
monitor.reportProgress( BrowserCoreMessages.bind( BrowserCoreMessages.jobs__init_entries_progress_subcount,
new String[]
- { srs == null ? Integer.toString( 0 ) : Integer.toString( srs.length ), parent.getDn().getName() } ) );
+ { srs == null ? Integer.toString( 0 ) : Integer.toString( srs.length ), parent.getDn().getName() } ) );
}
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/SearchRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/SearchRunnable.java
index e0cf39f..0932ac7 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/SearchRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/SearchRunnable.java
@@ -31,13 +31,13 @@ import java.util.Set;
import javax.naming.directory.SearchControls;
+import org.apache.commons.lang3.ArrayUtils;
import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.message.Control;
import org.apache.directory.api.ldap.model.message.SearchScope;
import org.apache.directory.api.ldap.model.message.controls.PagedResults;
-import org.apache.directory.api.ldap.model.message.controls.PagedResultsImpl;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.api.ldap.model.url.LdapUrl;
import org.apache.directory.api.util.Strings;
@@ -47,7 +47,6 @@ import org.apache.directory.studio.connection.core.Controls;
import org.apache.directory.studio.connection.core.Connection.AliasDereferencingMethod;
import org.apache.directory.studio.connection.core.Connection.ReferralHandlingMethod;
import org.apache.directory.studio.connection.core.StudioControl;
-import org.apache.directory.studio.connection.core.StudioPagedResultsControl;
import org.apache.directory.studio.connection.core.io.api.StudioSearchResult;
import org.apache.directory.studio.connection.core.io.api.StudioSearchResultEnumeration;
import org.apache.directory.studio.connection.core.jobs.StudioConnectionBulkRunnableWithProgress;
@@ -240,7 +239,7 @@ public class SearchRunnable implements StudioConnectionBulkRunnableWithProgress
nextPageSearch.getControls().add( nextPrc );
if ( search.isPagedSearchScrollMode() )
{
- if ( prRequestControl.getCookieValue() > 0 )
+ if ( ArrayUtils.isNotEmpty( prRequestControl.getCookie() ) )
{
// create top page search runnable, same as original search
ISearch topPageSearch = ( ISearch ) search.clone();
@@ -248,7 +247,7 @@ public class SearchRunnable implements StudioConnectionBulkRunnableWithProgress
SearchRunnable topPageSearchRunnable = new SearchRunnable( search, topPageSearch );
search.setTopPageSearchRunnable( topPageSearchRunnable );
}
- if ( prResponseControl.getCookieValue() > 0 )
+ if ( ArrayUtils.isNotEmpty( prResponseControl.getCookie() ) )
{
// create next page search runnable
SearchRunnable nextPageSearchRunnable = new SearchRunnable( search, nextPageSearch );
@@ -258,7 +257,7 @@ public class SearchRunnable implements StudioConnectionBulkRunnableWithProgress
else
{
// transparently continue search, till count limit is reached
- if ( prResponseControl.getCookieValue() > 0
+ if ( ArrayUtils.isNotEmpty( prResponseControl.getCookie() )
&& ( search.getCountLimit() == 0 || search.getSearchResults().length < search
.getCountLimit() ) )
{
@@ -406,7 +405,8 @@ public class SearchRunnable implements StudioConnectionBulkRunnableWithProgress
search.getResponseControls().add( control );
if ( control instanceof PagedResults )
{
- search.setCountLimitExceeded( ( ( PagedResults ) control ).getCookieValue() > 0 );
+ search.setCountLimitExceeded(
+ ArrayUtils.isNotEmpty( ( ( PagedResults ) control ).getCookie() ) );
}
}
}
diff --git a/tests/test.integration.ui/pom-first.xml b/tests/test.integration.ui/pom-first.xml
index b564e0d..9079550 100644
--- a/tests/test.integration.ui/pom-first.xml
+++ b/tests/test.integration.ui/pom-first.xml
@@ -69,6 +69,8 @@
org.apache.directory.api.ldap.codec.core;bundle-version="${org.apache.directory.api.bundleversion}",
org.apache.directory.api.ldap.model;bundle-version="${org.apache.directory.api.bundleversion}",
org.apache.directory.api.ldap.net.mina;bundle-version="${org.apache.directory.api.bundleversion}",
+ org.apache.directory.api.ldap.schema;bundle-version="${org.apache.directory.api.bundleversion}",
+ org.apache.directory.api.ldap.schema.converter;bundle-version="${org.apache.directory.api.bundleversion}",
org.apache.directory.api.util;bundle-version="${org.apache.directory.api.bundleversion}",
org.apache.mina.core;bundle-version="${org.apache.mina.bundleversion}",
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/OpenLdapTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/OpenLdapTest.java
new file mode 100644
index 0000000..72d94f4
--- /dev/null
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/OpenLdapTest.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.directory.studio.test.integration.ui;
+
+
+import static org.apache.directory.studio.test.integration.ui.Constants.LOCALHOST;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
+import org.apache.directory.api.ldap.model.ldif.LdifEntry;
+import org.apache.directory.api.ldap.model.ldif.LdifReader;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.directory.ldap.client.api.exception.InvalidConnectionException;
+import org.apache.directory.studio.connection.core.Connection;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.apache.directory.studio.test.integration.ui.bots.BrowserViewBot;
+import org.apache.directory.studio.test.integration.ui.bots.ConnectionsViewBot;
+import org.apache.directory.studio.test.integration.ui.bots.NewConnectionWizardBot;
+import org.apache.directory.studio.test.integration.ui.bots.SearchDialogBot;
+import org.apache.directory.studio.test.integration.ui.bots.StudioBot;
+import org.apache.directory.studio.test.integration.ui.bots.utils.Assertions;
+import org.apache.directory.studio.test.integration.ui.bots.utils.FrameworkRunnerWithScreenshotCaptureListener;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Tests against OpenLDAP.
+ *
+ * Expects a running OpenLDAP server with below default connection parameters
+ * which can be configured via environment variables.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+@RunWith(FrameworkRunnerWithScreenshotCaptureListener.class)
+public class OpenLdapTest
+{
+ static String getOrDefault( String key, String defaultValue )
+ {
+ return System.getenv().getOrDefault( key, defaultValue );
+ }
+
+ private static final String OPENLDAP_HOST = getOrDefault( "OPENLDAP_HOST", LOCALHOST );
+ private static final int OPENLDAP_PORT = Integer.parseInt( getOrDefault( "OPENLDAP_PORT", "20389" ) );
+ private static final String OPENLDAP_ADMIN_DN = getOrDefault( "OPENLDAP_ADMIN_DN", "cn=admin,dc=example,dc=org" );
+ private static final String OPENLDAP_ADMIN_PASSWORD = getOrDefault( "OPENLDAP_ADMIN_PASSWORD", "admin" );
+
+ @BeforeClass
+ public static void skipOpenLdapTestIfNotRunning() throws Exception
+ {
+
+ try ( LdapNetworkConnection connection = new LdapNetworkConnection( OPENLDAP_HOST, OPENLDAP_PORT ) )
+ {
+ connection.connect();
+ connection.bind( OPENLDAP_ADMIN_DN, OPENLDAP_ADMIN_PASSWORD );
+ }
+ catch ( InvalidConnectionException e )
+ {
+ Assume.assumeNoException(
+ "Skipping tests as connection to OpenLDAP server failed: " + OPENLDAP_HOST + ":" + OPENLDAP_PORT, e );
+ }
+ catch ( LdapAuthenticationException e )
+ {
+ Assume.assumeNoException(
+ "Skipping tests as bind to OpenLDAP server failed: " + OPENLDAP_HOST + ":" + OPENLDAP_PORT, e );
+ }
+ }
+
+ private StudioBot studioBot;
+ private ConnectionsViewBot connectionsViewBot;
+ private BrowserViewBot browserViewBot;
+
+ private Connection connection;
+
+ @Before
+ public void setUp() throws Exception
+ {
+ studioBot = new StudioBot();
+ studioBot.resetLdapPerspective();
+ connectionsViewBot = studioBot.getConnectionView();
+ connection = connectionsViewBot.createTestConnection( "OpenLdapTest", OPENLDAP_HOST, OPENLDAP_PORT,
+ OPENLDAP_ADMIN_DN, OPENLDAP_ADMIN_PASSWORD );
+ browserViewBot = studioBot.getBrowserView();
+
+ try ( LdapNetworkConnection connection = new LdapNetworkConnection( OPENLDAP_HOST, OPENLDAP_PORT );
+ LdifReader ldifReader = new LdifReader( OpenLdapTest.class.getResourceAsStream( "OpenLdapTest.ldif" ) ) )
+ {
+ connection.bind( OPENLDAP_ADMIN_DN, OPENLDAP_ADMIN_PASSWORD );
+ for ( LdifEntry entry : ldifReader )
+ {
+ connection.add( entry.getEntry() );
+ }
+ }
+ }
+
+
+ @After
+ public void tearDown() throws Exception
+ {
+ connectionsViewBot.deleteTestConnections();
+ Assertions.genericTearDownAssertions();
+
+ try ( LdapNetworkConnection connection = new LdapNetworkConnection( OPENLDAP_HOST, OPENLDAP_PORT );
+ LdifReader ldifReader = new LdifReader( OpenLdapTest.class.getResourceAsStream( "OpenLdapTest.ldif" ) ) )
+ {
+ connection.bind( OPENLDAP_ADMIN_DN, OPENLDAP_ADMIN_PASSWORD );
+ List<LdifEntry> ldifEntries = StreamSupport.stream( ldifReader.spliterator(), false )
+ .collect( Collectors.toList() );
+ Collections.reverse( ldifEntries );
+ for ( LdifEntry entry : ldifEntries )
+ {
+ connection.delete( entry.getDn() );
+ }
+ }
+ }
+
+
+ @Test
+ public void testBrowseWithPagingWithScrollMode()
+ {
+ browserViewBot.selectEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users" );
+
+ // enable Simple Paged Results control
+ connection.getConnectionParameter().setExtendedBoolProperty(
+ IBrowserConnection.CONNECTION_PARAMETER_PAGED_SEARCH, true );
+ connection.getConnectionParameter().setExtendedIntProperty(
+ IBrowserConnection.CONNECTION_PARAMETER_PAGED_SEARCH_SIZE, 3 );
+ connection.getConnectionParameter().setExtendedBoolProperty(
+ IBrowserConnection.CONNECTION_PARAMETER_PAGED_SEARCH_SCROLL_MODE, true );
+
+ // 1st page
+ browserViewBot.expandEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users" );
+ assertFalse(
+ browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Top Page ---" ) );
+ assertTrue(
+ browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Next Page ---" ) );
+
+ // next page
+ browserViewBot.selectEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Next Page ---" );
+ assertTrue(
+ browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Top Page ---" ) );
+ assertTrue(
+ browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Next Page ---" ) );
+
+ // last page
+ browserViewBot.selectEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Next Page ---" );
+ assertTrue(
+ browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Top Page ---" ) );
+ assertFalse(
+ browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Next Page ---" ) );
+
+ // back to top
+ browserViewBot.selectEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Top Page ---" );
+ assertFalse(
+ browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Top Page ---" ) );
+ assertTrue(
+ browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Next Page ---" ) );
+ }
+
+
+ @Test
+ public void testBrowseWithPagingWithoutScrollMode()
+ {
+ browserViewBot.selectEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users" );
+
+ // enable Simple Paged Results control
+ connection.getConnectionParameter().setExtendedBoolProperty(
+ IBrowserConnection.CONNECTION_PARAMETER_PAGED_SEARCH, true );
+ connection.getConnectionParameter().setExtendedIntProperty(
+ IBrowserConnection.CONNECTION_PARAMETER_PAGED_SEARCH_SIZE, 3 );
+ connection.getConnectionParameter().setExtendedBoolProperty(
+ IBrowserConnection.CONNECTION_PARAMETER_PAGED_SEARCH_SCROLL_MODE, false );
+
+ browserViewBot.expandEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users" );
+ assertFalse(
+ browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Top Page ---" ) );
+ assertFalse(
+ browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "--- Next Page ---" ) );
+ assertTrue( browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users (8)" ) );
+ assertTrue( browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "uid=user.1" ) );
+ assertTrue( browserViewBot.existsEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users", "uid=user.8" ) );
+ }
+
+
+ @Test
+ public void testSearchWithPagingWithScrollMode() throws Exception
+ {
+ String searchName = "Paged search with scroll mode";
+ browserViewBot.selectEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users" );
+ SearchDialogBot dialogBot = browserViewBot.openSearchDialog();
+ assertTrue( dialogBot.isVisible() );
+ dialogBot.setSearchName( searchName );
+ dialogBot.setFilter( "(objectClass=*)" );
+ dialogBot.setReturningAttributes( "objectClass,ou,cn,uid" );
+ dialogBot.setControlPagedSearch( true, 3, true );
+ dialogBot.clickSearchButton();
+
+ // 1st page
+ browserViewBot.expandEntry( "Searches", searchName );
+ assertFalse( browserViewBot.existsEntry( "Searches", searchName, "--- Top Page ---" ) );
+ assertTrue( browserViewBot.existsEntry( "Searches", searchName, "--- Next Page ---" ) );
+
+ // next page
+ browserViewBot.selectEntry( "Searches", searchName, "--- Next Page ---" );
+ assertTrue( browserViewBot.existsEntry( "Searches", searchName, "--- Top Page ---" ) );
+ assertTrue( browserViewBot.existsEntry( "Searches", searchName, "--- Next Page ---" ) );
+
+ // last page
+ browserViewBot.selectEntry( "Searches", searchName, "--- Next Page ---" );
+ assertTrue( browserViewBot.existsEntry( "Searches", searchName, "--- Top Page ---" ) );
+ assertFalse( browserViewBot.existsEntry( "Searches", searchName, "--- Next Page ---" ) );
+
+ // back to top
+ browserViewBot.selectEntry( "Searches", searchName, "--- Top Page ---" );
+ assertFalse( browserViewBot.existsEntry( "Searches", searchName, "--- Top Page ---" ) );
+ assertTrue( browserViewBot.existsEntry( "Searches", searchName, "--- Next Page ---" ) );
+ }
+
+
+ @Test
+ public void testSearchWithPagingWithoutScrollMode() throws Exception
+ {
+ String searchName = "Paged search without scroll mode";
+ browserViewBot.selectEntry( "DIT", "Root DSE", "dc=example,dc=org", "ou=users" );
+ SearchDialogBot dialogBot = browserViewBot.openSearchDialog();
+ assertTrue( dialogBot.isVisible() );
+ dialogBot.setSearchName( searchName );
+ dialogBot.setFilter( "(objectClass=*)" );
+ dialogBot.setReturningAttributes( "objectClass,ou,cn,uid" );
+ dialogBot.setControlPagedSearch( true, 3, false );
+ dialogBot.clickSearchButton();
+
+ browserViewBot.expandEntry( "Searches", searchName );
+ assertFalse( browserViewBot.existsEntry( "Searches", searchName, "--- Top Page ---" ) );
+ assertFalse( browserViewBot.existsEntry( "Searches", searchName, "--- Next Page ---" ) );
+ assertTrue( browserViewBot.existsEntry( "Searches", searchName + " (9+)" ) );
+ assertTrue( browserViewBot.existsEntry( "Searches", searchName, "uid=user.1" ) );
+ assertTrue( browserViewBot.existsEntry( "Searches", searchName, "uid=user.8" ) );
+ }
+
+
+ @Test
+ public void testCheckAuthenticationButtonNotOK()
+ {
+ // enter connection parameter
+ NewConnectionWizardBot wizardBot = connectionsViewBot.openNewConnectionWizard();
+ wizardBot.typeConnectionName( "OpenLDAP connection test not ok" );
+ wizardBot.typeHost( OPENLDAP_HOST );
+ wizardBot.typePort( OPENLDAP_PORT );
+ wizardBot.clickNextButton();
+
+ // enter incorrect authentication parameter
+ wizardBot.typeUser( OPENLDAP_ADMIN_DN );
+ wizardBot.typePassword( "wrongpassword" );
+
+ // click "Check Network Parameter" button
+ String result = wizardBot.clickCheckAuthenticationButton();
+ assertNotNull( "Expected Error", result );
+ assertThat( result, containsString( "[LDAP result code 49 - invalidCredentials]" ) );
+
+ wizardBot.clickCancelButton();
+ }
+
+}
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/SearchTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/SearchTest.java
index 71d6c61..eb07d1c 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/SearchTest.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/SearchTest.java
@@ -367,7 +367,6 @@ public class SearchTest extends AbstractLdapTestUnit
assertTrue( dialogBot.isVisible() );
dialogBot.setSearchName( searchName );
dialogBot.setReturningAttributes( "objectClass,ou,cn,uid" );
- dialogBot.setControlPagedSearch( true, 5, false );
FilterEditorDialogBot filterBot = dialogBot.openFilterEditor();
filterBot.setFilter( "(&(objectClass=*)(uid=user.1))" );
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ConnectionsViewBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ConnectionsViewBot.java
index cc39443..bd7ca88 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ConnectionsViewBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ConnectionsViewBot.java
@@ -48,7 +48,6 @@ public class ConnectionsViewBot
{
private SWTWorkbenchBot bot = new SWTWorkbenchBot();
-
public NewConnectionWizardBot openNewConnectionWizard()
{
ContextMenuHelper.clickContextMenu( getConnectionsTree(), "New Connection..." );
@@ -163,17 +162,23 @@ public class ConnectionsViewBot
*/
public Connection createTestConnection( String name, int port ) throws Exception
{
+ return createTestConnection( name, LOCALHOST, port, "uid=admin,ou=system", "secret" );
+ }
+
+
+ public Connection createTestConnection( String name, String host, int port, String bindDn, String bindPassword ) throws Exception
+ {
name = name + "_" + System.currentTimeMillis();
ConnectionManager connectionManager = ConnectionCorePlugin.getDefault().getConnectionManager();
ConnectionParameter connectionParameter = new ConnectionParameter();
connectionParameter.setName( name );
- connectionParameter.setHost( LOCALHOST );
+ connectionParameter.setHost( host );
connectionParameter.setPort( port );
connectionParameter.setEncryptionMethod( EncryptionMethod.NONE );
connectionParameter.setAuthMethod( AuthenticationMethod.SIMPLE );
- connectionParameter.setBindPrincipal( "uid=admin,ou=system" );
- connectionParameter.setBindPassword( "secret" );
+ connectionParameter.setBindPrincipal( bindDn );
+ connectionParameter.setBindPassword( bindPassword );
Connection connection = new Connection( connectionParameter );
connectionManager.addConnection( connection );
diff --git a/tests/test.integration.ui/src/main/resources/org/apache/directory/studio/test/integration/ui/OpenLdapTest.ldif b/tests/test.integration.ui/src/main/resources/org/apache/directory/studio/test/integration/ui/OpenLdapTest.ldif
new file mode 100644
index 0000000..d64ed89
--- /dev/null
+++ b/tests/test.integration.ui/src/main/resources/org/apache/directory/studio/test/integration/ui/OpenLdapTest.ldif
@@ -0,0 +1,222 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+dn: ou=users,dc=example,dc=org
+objectClass: top
+objectClass: organizationalUnit
+ou: users
+
+dn: uid=user.1,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Aaccf
+sn: Amar
+cn: Aaccf Amar
+initials: AA
+uid: user.1
+mail: user.1@null
+userPassword: password
+telephoneNumber: 976-893-3312
+homePhone: 337-310-0727
+pager: 185-156-4071
+mobile: 626-188-0934
+employeeNumber: 1
+street: 27919 Broadway Street
+l: Tallahassee
+st: DE
+postalCode: 67698
+postalAddress: Aaccf Amar$27919 Broadway Street$Tallahassee, DE 67698
+description: This is the description for Aaccf Amar.
+roomNumber: 1388
+
+dn: uid=user.2,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Aaren
+sn: Atp
+cn: Aaren Atp
+initials: AA
+uid: user.2
+mail: user.2@null
+userPassword: password
+telephoneNumber: 147-953-0396
+homePhone: 174-439-5329
+pager: 617-443-8449
+mobile: 045-464-2512
+employeeNumber: 2
+street: 36109 Center Street
+l: Harlingen
+st: CO
+postalCode: 21733
+postalAddress: Aaren Atp$36109 Center Street$Harlingen, CO 21733
+description: This is the description for Aaren Atp.
+roomNumber: 1198
+
+dn: uid=user.3,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Aarika
+sn: Atpco
+cn: Aarika Atpco
+initials: AA
+uid: user.3
+mail: user.3@null
+userPassword: password
+telephoneNumber: 925-356-4943
+homePhone: 099-983-0308
+pager: 806-672-7363
+mobile: 425-493-8009
+employeeNumber: 3
+street: 14730 Fourteenth Street
+l: Evansville
+st: ND
+postalCode: 95526
+postalAddress: Aarika Atpco$14730 Fourteenth Street$Evansville, ND 95526
+description: This is the description for Aarika Atpco.
+roomNumber: 1135
+
+dn: uid=user.4,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Aaron
+sn: Atrc
+cn: Aaron Atrc
+initials: AA
+uid: user.4
+mail: user.4@null
+userPassword: password
+telephoneNumber: 696-981-0488
+homePhone: 854-401-1330
+pager: 389-028-9518
+mobile: 117-882-4912
+employeeNumber: 4
+street: 98495 Fifteenth Street
+l: Miami
+st: PA
+postalCode: 16887
+postalAddress: Aaron Atrc$98495 Fifteenth Street$Miami, PA 16887
+description: This is the description for Aaron Atrc.
+roomNumber: 1311
+
+dn: uid=user.5,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Aartjan
+sn: Aalders
+cn: Aartjan Aalders
+initials: AA
+uid: user.5
+mail: user.5@null
+userPassword: password
+telephoneNumber: 657-627-9753
+homePhone: 109-158-4533
+pager: 801-392-0010
+mobile: 763-973-0947
+employeeNumber: 5
+street: 52408 Ridge Street
+l: Omaha
+st: AR
+postalCode: 08015
+postalAddress: Aartjan Aalders$52408 Ridge Street$Omaha, AR 08015
+description: This is the description for Aartjan Aalders.
+roomNumber: 1090
+
+dn: uid=user.6,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Abagael
+sn: Aasen
+cn: Abagael Aasen
+initials: AA
+uid: user.6
+mail: user.6@null
+userPassword: password
+telephoneNumber: 600-556-9017
+homePhone: 543-731-7797
+pager: 349-743-6572
+mobile: 042-921-9717
+employeeNumber: 6
+street: 87514 Dogwood Street
+l: Bloomington
+st: ID
+postalCode: 56762
+postalAddress: Abagael Aasen$87514 Dogwood Street$Bloomington, ID 56762
+description: This is the description for Abagael Aasen.
+roomNumber: 1449
+
+dn: uid=user.7,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Abagail
+sn: Abadines
+cn: Abagail Abadines
+initials: AA
+uid: user.7
+mail: user.7@null
+userPassword: password
+telephoneNumber: 628-294-0713
+homePhone: 313-764-3970
+pager: 118-541-2978
+mobile: 111-360-9243
+employeeNumber: 7
+street: 60751 Main Street
+l: Macon
+st: MI
+postalCode: 38755
+postalAddress: Abagail Abadines$60751 Main Street$Macon, MI 38755
+description: This is the description for Abagail Abadines.
+roomNumber: 1312
+
+dn: uid=user.8,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Abahri
+sn: Abazari
+cn: Abahri Abazari
+initials: AA
+uid: user.8
+mail: user.8@null
+userPassword: password
+telephoneNumber: 760-373-5805
+homePhone: 856-861-3648
+pager: 271-218-0027
+mobile: 957-465-6928
+employeeNumber: 8
+street: 81023 River Street
+l: Monroe
+st: SD
+postalCode: 51865
+postalAddress: Abahri Abazari$81023 River Street$Monroe, SD 51865
+description: This is the description for Abahri Abazari.
+roomNumber: 1963
+