blob: 2445faa0838423fcac3b9a664c77706bb12e495c [file] [log] [blame]
/*
* 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
*
* https://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.api.ldap.model.name;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Iterator;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
import org.apache.directory.api.ldap.model.name.Ava;
import org.apache.directory.api.ldap.model.name.Rdn;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
import org.apache.directory.api.util.Strings;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
/**
* Test the class Rdn
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
@Execution(ExecutionMode.CONCURRENT)
public class RdnTest
{
/** A null schemaManager used in tests */
SchemaManager schemaManager = null;
/**
* Test a null Rdn
*/
@Test
public void testRdnNull()
{
assertEquals( "", new Rdn().toString() );
}
/**
* test an empty Rdn
*
* @throws LdapException
*/
@Test
public void testRdnEmpty() throws LdapException
{
assertEquals( "", new Rdn( "" ).toString() );
}
/**
* test a simple Rdn : a = b
*
* @throws LdapException
*/
@Test
public void testRdnSimple() throws LdapException
{
assertEquals( "a = b", new Rdn( "a = b" ).getName() );
}
/**
* test a composite Rdn : a = b, d = e
*
* @throws LdapException
*/
@Test
public void testRdnComposite() throws LdapException
{
assertEquals( "a = b + c = d", new Rdn( "a = b + c = d" ).getName() );
}
/**
* test a composite Rdn with or without spaces: a=b, a =b, a= b, a = b, a =
* b
*
* @throws LdapException
*/
@Test
public void testRdnCompositeWithSpace() throws LdapException
{
assertEquals( "a=b", new Rdn( "a", "b" ).getName() );
assertEquals( " a=b", new Rdn( " a", "b" ).getName() );
assertEquals( "a =b", new Rdn( "a ", "b" ).getName() );
assertEquals( "a= b", new Rdn( "a", " b" ).getName() );
assertEquals( "a=b ", new Rdn( "a", "b " ).getName() );
assertEquals( " a =b", new Rdn( " a ", "b" ).getName() );
assertEquals( " a= b", new Rdn( " a", " b" ).getName() );
assertEquals( " a=b ", new Rdn( " a", "b " ).getName() );
assertEquals( "a = b", new Rdn( "a ", " b" ).getName() );
assertEquals( "a =b ", new Rdn( "a ", "b " ).getName() );
assertEquals( "a= b ", new Rdn( "a", " b " ).getName() );
assertEquals( " a = b", new Rdn( " a ", " b" ).getName() );
assertEquals( " a =b ", new Rdn( " a ", "b " ).getName() );
assertEquals( " a= b ", new Rdn( " a", " b " ).getName() );
assertEquals( "a = b ", new Rdn( "a ", " b " ).getName() );
assertEquals( " a = b ", new Rdn( " a ", " b " ).getName() );
}
/**
* test a simple Rdn with differents separators : a = b + c = d
*
* @throws LdapException
*/
@Test
public void testRdnSimpleMultivaluedAttribute() throws LdapException
{
String result = new Rdn( "a = b + c = d" ).getName();
assertEquals( "a = b + c = d", result );
}
/**
* test a composite Rdn with differents separators : a=b+c=d, e=f + g=h +
* i=j
*
* @throws LdapException
*/
@Test
public void testRdnCompositeMultivaluedAttribute() throws LdapException
{
Rdn rdn = new Rdn( "a =b+c=d + e=f + g =h + i =j " );
// NameComponent are not ordered
assertEquals( "b", rdn.getValue( "a" ) );
assertEquals( "d", rdn.getValue( "c" ) );
assertEquals( "f", rdn.getValue( " E " ) );
assertEquals( "h", rdn.getValue( "g" ) );
assertEquals( "j", rdn.getValue( "i" ) );
}
/**
* test a simple Rdn with an oid prefix (uppercase) : OID.12.34.56 = azerty
*
* @throws LdapException
*/
@Test
public void testRdnOidUpper() throws LdapException
{
assertEquals( "OID.12.34.56 = azerty", new Rdn( "OID.12.34.56 = azerty" ).getName() );
}
/**
* test a simple Rdn with an oid prefix (lowercase) : oid.12.34.56 = azerty
*
* @throws LdapException
*/
@Test
public void testRdnOidLower() throws LdapException
{
assertEquals( "oid.12.34.56 = azerty", new Rdn( "oid.12.34.56 = azerty" ).getName() );
}
/**
* test a simple Rdn with an oid attribut wiithout oid prefix : 12.34.56 =
* azerty
*
* @throws LdapException
*/
@Test
public void testRdnOidWithoutPrefix() throws LdapException
{
assertEquals( "12.34.56 = azerty", new Rdn( "12.34.56 = azerty" ).getName() );
}
/**
* test a composite Rdn with an oid attribut wiithout oid prefix : 12.34.56 =
* azerty; 7.8 = test
*
* @throws LdapException
*/
@Test
public void testRdnCompositeOidWithoutPrefix() throws LdapException
{
String result = new Rdn( "12.34.56 = azerty + 7.8 = test" ).getName();
assertEquals( "12.34.56 = azerty + 7.8 = test", result );
}
/**
* test a simple Rdn with pair char attribute value : a = \,\=\+\<\>\#\;\\\"\C3\A9"
*
* @throws LdapException
*/
@Test
public void testRdnPairCharAttributeValue() throws LdapException
{
String rdn = Strings.utf8ToString( new byte[]
{ 'a', '=', '\\', ',', '\\', '=', '\\', '+', '\\', '<', '\\', '>', '#', '\\', ';', '\\', '\\', '\\', '"', '\\',
'C', '3', '\\', 'A', '9' } );
assertEquals( "a=\\,\\=\\+\\<\\>#\\;\\\\\\\"\\C3\\A9", new Rdn( rdn ).getName() );
assertEquals( "a=\\,=\\+\\<\\>#\\;\\\\\\\"\u00e9", new Rdn( rdn ).getEscaped() );
}
/**
* test a simple Rdn with hexString attribute value : a = #0010A0AAFF
*/
@Test
public void testRdnHexStringAttributeValue() throws LdapException
{
assertEquals( "a = #0010A0AAFF", new Rdn( "a = #0010A0AAFF" ).getName() );
}
/**
* test exception from illegal hexString attribute value : a=#zz.
*/
@Test
public void testBadRdnHexStringAttributeValue() throws LdapException
{
try
{
new Rdn( "a=#zz" );
fail();
}
catch ( LdapException ine )
{
assertTrue( true );
}
}
/**
* test a simple Rdn with quoted attribute value : a = "quoted \"value"
*
* @throws LdapException
*/
@Test
public void testRdnQuotedAttributeValue() throws LdapException
{
Rdn rdn = new Rdn( "a = quoted \\\"value" );
assertEquals( "a = quoted \\\"value", rdn.getName() );
assertEquals( "quoted \"value", rdn.getValue( "a" ) );
}
/**
* Test the clone method for a Rdn.
*
* @throws LdapException
*/
@Test
public void testRDNCloningOneNameComponent() throws LdapException
{
Rdn rdn = new Rdn( "a", "b" );
Rdn rdnClone = rdn.clone();
rdn = new Rdn( "c=d" );
assertEquals( "b", rdnClone.getValue( "a" ) );
}
/**
* Test the creation of a new Rdn
*
* @throws org.apache.directory.api.ldap.model.exception.LdapException
*/
@Test
public void testRDNCreation() throws LdapException
{
Rdn rdn = new Rdn( "A", " b " );
assertEquals( "A= b ", rdn.getName() );
assertEquals( "A=\\ b \\ ", rdn.getEscaped() );
}
/**
* Test the clone method for a Rdn.
*
* @throws LdapException
*/
@Test
public void testRDNCloningTwoNameComponent() throws LdapException
{
Rdn rdn = new Rdn( "a = b + aa = bb" );
Rdn rdnClone = rdn.clone();
rdn.clear();
rdn = new Rdn( "c=d" );
assertEquals( "b", rdnClone.getValue( "a" ) );
assertEquals( "bb", rdnClone.getValue( "aa" ) );
assertEquals( null, rdnClone.getValue( "c" ) );
}
/**
* Test the equals method for a Rdn.
*
* @throws LdapException
*/
@Test
public void testRDNCompareToNull() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b + c = d + e = f + g = h " );
Rdn rdn2 = null;
assertFalse( rdn1.equals( rdn2 ) );
}
/**
* Compares a composite NC to a single NC.
*
* @throws LdapException
*/
@Test
public void testRDNCompareToNCS2NC() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b + c = d + e = f + g = h " );
Rdn rdn2 = new Rdn( " a = b " );
assertFalse( rdn1.equals( rdn2 ) );
}
/**
* Compares a single NC to a composite NC.
*
* @throws LdapException
*/
@Test
public void testRDNCompareToNC2NCS() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b " );
Rdn rdn2 = new Rdn( " a = b + c = d + e = f + g = h " );
assertFalse( rdn1.equals( rdn2 ) );
}
/**
* Compares a composite NCS to a composite NCS in the same order.
*
* @throws LdapException
*/
@Test
public void testRDNCompareToNCS2NCSOrdered() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b + c = d + e = f + g = h " );
Rdn rdn2 = new Rdn( " a = b + c = d + e = f + g = h " );
assertTrue( rdn1.equals( rdn2 ) );
}
/**
* Compares a composite NCS to a composite NCS in a different order.
*
* @throws LdapException
*/
@Test
public void testRDNCompareToNCS2NCSUnordered() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b + b = f + g = h + c = d " );
Rdn rdn2 = new Rdn( " a = b + c = d + b = f + g = h " );
assertTrue( rdn1.equals( rdn2 ) );
}
/**
* Compares a composite NCS to a different composite NCS.
*
* @throws LdapException
*/
@Test
public void testRDNCompareToNCS2NCSNotEquals() throws LdapException
{
Rdn rdn1 = new Rdn( " a = f + g = h + c = d " );
Rdn rdn2 = new Rdn( " c = d + a = h + g = h " );
assertFalse( rdn1.equals( rdn2 ) );
assertFalse( rdn2.equals( rdn1 ) );
}
/**
* Test for DIRSHARED-2.
* The first ATAV is equal, the second or following ATAV differs.
*
* @throws LdapException
*/
@Test
public void testCompareSecondAtav() throws LdapException
{
// the second ATAV differs
Rdn rdn1 = new Rdn( " a = b + c = d " );
Rdn rdn2 = new Rdn( " a = b + c = y " );
assertFalse( rdn1.equals( rdn2 ) );
assertFalse( rdn2.equals( rdn1 ) );
// the third ATAV differs
Rdn rdn3 = new Rdn( " a = b + c = d + e = f " );
Rdn rdn4 = new Rdn( " a = b + c = d + e = y " );
assertFalse( rdn3.equals( rdn4 ) );
assertFalse( rdn4.equals( rdn3 ) );
// the second ATAV differs in value only
Rdn rdn5 = new Rdn( " a = b + b = c " );
Rdn rdn6 = new Rdn( " a = b + b = y " );
assertFalse( rdn5.equals( rdn6 ) );
assertFalse( rdn6.equals( rdn5 ) );
}
/**
* Test for DIRSHARED-2.
* The compare operation should return a correct value (1 or -1)
* depending on the ATAVs, not on their position.
*
* @throws LdapException
*/
@Test
public void testCompareIndependentFromOrder() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b + c = d " );
Rdn rdn2 = new Rdn( " c = d + a = b " );
assertTrue( rdn1.equals( rdn2 ) );
rdn1 = new Rdn( " a = b + c = e " );
rdn2 = new Rdn( " c = d + a = b " );
assertFalse( rdn1.equals( rdn2 ) );
assertFalse( rdn2.equals( rdn1 ) );
rdn1 = new Rdn( " a = b + c = d " );
rdn2 = new Rdn( " e = f + g = h " );
assertFalse( rdn1.equals( rdn2 ) );
assertFalse( rdn2.equals( rdn1 ) );
}
/**
* Test for DIRSHARED-3.
* Tests that equals() is invertable for single-valued RDNs.
*
* @throws LdapException
*/
@Test
public void testCompareInvertableNC2NC() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b " );
Rdn rdn2 = new Rdn( " a = c " );
assertFalse( rdn1.equals( rdn2 ) );
assertFalse( rdn2.equals( rdn1 ) );
}
/**
* Test for DIRSHARED-3.
* Tests that equals() is invertable for multi-valued RDNs with different values.
*
* @throws LdapException
*/
@Test
public void testCompareInvertableNCS2NCSDifferentValues() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b + b = c " );
Rdn rdn2 = new Rdn( " a = b + b = y " );
assertFalse( rdn1.equals( rdn2 ) );
assertFalse( rdn2.equals( rdn1 ) );
}
/**
* Test for DIRSHARED-3.
* Tests that equals() is invertable for multi-valued RDNs with different types.
*
* @throws org.apache.directory.api.ldap.model.exception.LdapException
*/
@Test
public void testCompareInvertableNCS2NCSDifferentTypes() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b + c = d " );
Rdn rdn2 = new Rdn( " e = f + g = h " );
assertFalse( rdn1.equals( rdn2 ) );
assertFalse( rdn2.equals( rdn1 ) );
}
/**
* Test for DIRSHARED-3.
* Tests that equals() is invertable for multi-valued RDNs with different order.
*
* @throws LdapException
*/
@Test
public void testCompareInvertableNCS2NCSUnordered() throws LdapException
{
Rdn rdn1 = new Rdn( " c = d + a = b " );
Rdn rdn2 = new Rdn( " a = b + e = f " );
assertFalse( rdn1.equals( rdn2 ) );
assertFalse( rdn2.equals( rdn1 ) );
}
/**
* Compares with a null Rdn.
*
* @throws LdapException
*/
@Test
public void testRDNCompareToNullRdn() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b " );
assertFalse( rdn1.equals( null ) );
}
/**
* Compares a simple NC to a simple NC.
*
* @throws LdapException
*/
@Test
public void testRDNCompareToNC2NC() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b " );
Rdn rdn2 = new Rdn( " a = b " );
assertTrue( rdn1.equals( rdn2 ) );
}
/**
* Compares a simple NC to a simple NC in UperCase.
*
* @throws LdapException
*/
@Test
public void testRDNCompareToNC2NCUperCase() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b " );
Rdn rdn2 = new Rdn( " A = b " );
assertTrue( rdn1.equals( rdn2 ) );
}
/**
* Compares a simple NC to a different simple NC.
*
* @throws LdapException
*/
@Test
public void testRDNCompareToNC2NCNotEquals() throws LdapException
{
Rdn rdn1 = new Rdn( " a = b " );
Rdn rdn2 = new Rdn( " A = d " );
assertFalse( rdn1.equals( rdn2 ) );
}
/**
*
* Test the getValue method.
*
* @throws LdapException
*/
@Test
public void testGetValue() throws LdapException
{
Rdn rdn = new Rdn( " a = b + b = f + g = h + c = d " );
assertEquals( "b", rdn.getValue() );
}
/**
*
* Test the getType method.
*
* @throws LdapException
*/
@Test
public void testGetType() throws LdapException
{
Rdn rdn = new Rdn( " a = b + b = f + g = h + c = d " );
assertEquals( "a", rdn.getNormType() );
}
/**
* Test the getSize method.
*
* @throws LdapException
*/
@Test
public void testGetSize() throws LdapException
{
Rdn rdn = new Rdn( " a = b + b = f + g = h + c = d " );
assertEquals( 4, rdn.size() );
}
/**
* Test the getSize method.
*
*/
@Test
public void testGetSize0()
{
Rdn rdn = new Rdn();
assertEquals( 0, rdn.size() );
}
/**
* Test the equals method
*
* @throws LdapException
*/
@Test
public void testEquals() throws LdapException
{
Rdn rdn = new Rdn( "a=b + c=d + e=f" );
assertFalse( rdn.equals( null ) );
assertFalse( rdn.equals( "test" ) );
assertFalse( rdn.equals( new Rdn( "a=c + c=d + e=f" ) ) );
assertFalse( rdn.equals( new Rdn( "a=b" ) ) );
assertTrue( rdn.equals( new Rdn( "a=b + c=d + e=f" ) ) );
assertTrue( rdn.equals( new Rdn( "a=b + C=d + E=f" ) ) );
assertTrue( rdn.equals( new Rdn( "c=d + e=f + a=b" ) ) );
}
@Test
public void testUnescapeValueHexa()
{
byte[] res = ( byte[] ) Rdn.unescapeValue( "#fF" );
assertEquals( "0xFF ", Strings.dumpBytes( res ) );
res = ( byte[] ) Rdn.unescapeValue( "#0123456789aBCDEF" );
assertEquals( "0x01 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF ", Strings.dumpBytes( res ) );
}
@Test
public void testUnescapeValueHexaWrong()
{
try
{
Rdn.unescapeValue( "#fF1" );
fail(); // Should not happen
}
catch ( IllegalArgumentException iae )
{
assertTrue( true );
}
}
@Test
public void testUnescapeValueString()
{
String res = ( String ) Rdn.unescapeValue( "azerty" );
assertEquals( "azerty", res );
}
@Test
public void testUnescapeValueStringSpecial()
{
String res = ( String ) Rdn.unescapeValue( "\\\\\\#\\,\\+\\;\\<\\>\\=\\\"\\ " );
assertEquals( "\\#,+;<>=\" ", res );
}
@Test
public void testUnescapeValueStringWithSpaceInTheMiddle()
{
String res = ( String ) Rdn.unescapeValue( "a b" );
assertEquals( "a b", res );
}
@Test
public void testUnescapeValueStringWithSpaceInAtTheBeginning()
{
String res = ( String ) Rdn.unescapeValue( "\\ a b" );
assertEquals( " a b", res );
}
@Test
public void testUnescapeValueStringWithSpaceInAtTheEnd()
{
String res = ( String ) Rdn.unescapeValue( "a b\\ " );
assertEquals( "a b ", res );
}
@Test
public void testUnescapeValueStringWithPoundInTheMiddle()
{
String res = ( String ) Rdn.unescapeValue( "a#b" );
assertEquals( "a#b", res );
}
@Test
public void testUnescapeValueStringWithPoundAtTheEnd()
{
String res = ( String ) Rdn.unescapeValue( "ab#" );
assertEquals( "ab#", res );
}
@Test
public void testUnescapeValueStringWithEqualInTheMiddle()
{
String res = ( String ) Rdn.unescapeValue( "a=b" );
assertEquals( "a=b", res );
}
@Test
public void testEscapeValueString()
{
String res = Rdn.escapeValue( Strings.getBytesUtf8( "azerty" ) );
assertEquals( "azerty", res );
}
@Test
public void testEscapeValueStringSpecial()
{
String res = Rdn.escapeValue( Strings.getBytesUtf8( "\\#,+;<>=\" " ) );
assertEquals( "\\\\#\\,\\+\\;\\<\\>\\=\\\"\\ ", res );
}
@Test
public void testEscapeValueNumeric()
{
String res = Rdn.escapeValue( new byte[]
{ '-', 0x00, '-', 0x1F, '-', 0x7F, '-' } );
assertEquals( "-\\00-\\1F-\\7F-", res );
}
@Test
public void testEscapeValueMix()
{
String res = Rdn.escapeValue( new byte[]
{ '\\', 0x00, '-', '+', '#', 0x7F, '-' } );
assertEquals( "\\\\\\00-\\+#\\7F-", res );
}
@Test
public void testDIRSERVER_703() throws LdapException
{
Rdn rdn = new Rdn( "cn=Kate Bush+sn=Bush" );
assertEquals( "cn=Kate Bush+sn=Bush", rdn.getName() );
}
@Test
public void testMultiValuedIterator() throws LdapException
{
Rdn rdn = new Rdn( "cn=Kate Bush+sn=Bush" );
Iterator<Ava> iterator = rdn.iterator();
assertNotNull( iterator );
assertTrue( iterator.hasNext() );
assertNotNull( iterator.next() );
assertTrue( iterator.hasNext() );
assertNotNull( iterator.next() );
assertFalse( iterator.hasNext() );
}
@Test
public void testSingleValuedIterator() throws LdapException
{
Rdn rdn = new Rdn( "cn=Kate Bush" );
Iterator<Ava> iterator = rdn.iterator();
assertNotNull( iterator );
assertTrue( iterator.hasNext() );
assertNotNull( iterator.next() );
assertFalse( iterator.hasNext() );
}
@Test
public void testEmptyIterator()
{
Rdn rdn = new Rdn();
Iterator<Ava> iterator = rdn.iterator();
assertNotNull( iterator );
assertFalse( iterator.hasNext() );
}
@Test
public void testRdnWithSpaces() throws LdapException
{
Rdn rdn = new Rdn( "cn=a\\ b\\ c" );
assertEquals( "cn=a\\ b\\ c", rdn.getName() );
}
@Test
public void testEscapedSpaceInValue() throws LdapException
{
Rdn rdn1 = new Rdn( "cn=a b c" );
Rdn rdn2 = new Rdn( "cn=a\\ b\\ c" );
assertEquals( "cn=a b c", rdn1.getName() );
assertTrue( rdn1.equals( rdn2 ) );
Rdn rdn3 = new Rdn( "cn= \\ a b c\\ " );
Rdn rdn4 = new Rdn( "cn=\\ a\\ b\\ c\\ " );
assertEquals( "cn= \\ a b c\\ ", rdn3.getName() );
assertEquals( "cn=\\ a b c\\ ", rdn3.getEscaped() );
assertTrue( rdn3.equals( rdn4 ) );
}
@Test
public void testEscapedHashInValue() throws LdapException
{
Rdn rdn1 = new Rdn( "cn=a#b#c" );
Rdn rdn2 = new Rdn( "cn=a\\#b\\#c" );
assertEquals( "cn=a#b#c", rdn1.getName() );
assertTrue( rdn1.equals( rdn2 ) );
Rdn rdn3 = new Rdn( "cn=\\#a#b#c\\#" );
Rdn rdn4 = new Rdn( "cn=\\#a\\#b\\#c\\#" );
assertEquals( "cn=\\#a#b#c\\#", rdn3.getName() );
assertEquals( "cn=\\#a#b#c#", rdn3.getEscaped() );
assertTrue( rdn3.equals( rdn4 ) );
}
@Test
public void testEscapedAttributeValue()
{
// space doesn't need to be escaped in the middle of a string
assertEquals( "a b", Rdn.escapeValue( "a b" ) );
assertEquals( "a b c", Rdn.escapeValue( "a b c" ) );
assertEquals( "a b c d", Rdn.escapeValue( "a b c d" ) );
// space must be escaped at the beginning and the end of a string
assertEquals( "\\ a b", Rdn.escapeValue( " a b" ) );
assertEquals( "a b\\ ", Rdn.escapeValue( "a b " ) );
assertEquals( "\\ a b\\ ", Rdn.escapeValue( " a b " ) );
assertEquals( "\\ a b \\ ", Rdn.escapeValue( " a b " ) );
// hash doesn't need to be escaped in the middle and the end of a string
assertEquals( "a#b", Rdn.escapeValue( "a#b" ) );
assertEquals( "a#b#", Rdn.escapeValue( "a#b#" ) );
assertEquals( "a#b#c", Rdn.escapeValue( "a#b#c" ) );
assertEquals( "a#b#c#", Rdn.escapeValue( "a#b#c#" ) );
assertEquals( "a#b#c#d", Rdn.escapeValue( "a#b#c#d" ) );
assertEquals( "a#b#c#d#", Rdn.escapeValue( "a#b#c#d#" ) );
// hash must be escaped at the beginning of a string
assertEquals( "\\#a#b", Rdn.escapeValue( "#a#b" ) );
assertEquals( "\\##a#b", Rdn.escapeValue( "##a#b" ) );
// other characters that need to be escaped
// '"', '+', ',', ';', '<', '>', '\', the null (U+0000) character
assertEquals( "\\\"\\+\\,\\;\\<\\>\\\\\\00", Rdn.escapeValue( "\"+,;<>\\\u0000" ) );
// unicode characters don't need to be escaped
// \u00e9 - e with acute - 2 bytes in UTF-8
// \u20ac - Euro character - 3 bytes in UTF-8
// \uD83D\uDE08 - Smiley - 4 bytes in UTF-8
assertEquals( "\u00e9\u20AC\uD83D\uDE08", Rdn.escapeValue( "\u00e9\u20AC\uD83D\uDE08" ) );
}
/** Serialization tests ------------------------------------------------- */
/**
* Test serialization of an empty Rdn
*/
@Test
public void testEmptyRDNSerialization() throws LdapException, IOException, ClassNotFoundException
{
Rdn rdn = new Rdn( "" );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream( baos );
out.writeObject( rdn );
ObjectInputStream in = null;
byte[] data = baos.toByteArray();
in = new ObjectInputStream( new ByteArrayInputStream( data ) );
Rdn rdn2 = ( Rdn ) in.readObject();
assertEquals( rdn, rdn2 );
}
@Test
public void testNullRdnSerialization() throws IOException, ClassNotFoundException
{
Rdn rdn = new Rdn();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream( baos );
out.writeObject( rdn );
ObjectInputStream in = null;
byte[] data = baos.toByteArray();
in = new ObjectInputStream( new ByteArrayInputStream( data ) );
Rdn rdn2 = ( Rdn ) in.readObject();
assertEquals( rdn, rdn2 );
}
/**
* Test serialization of a simple Rdn
*/
@Test
public void testSimpleRdnSerialization() throws LdapException, IOException, ClassNotFoundException
{
Rdn rdn = new Rdn( "a=b" );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream( baos );
out.writeObject( rdn );
ObjectInputStream in = null;
byte[] data = baos.toByteArray();
in = new ObjectInputStream( new ByteArrayInputStream( data ) );
Rdn rdn2 = ( Rdn ) in.readObject();
assertEquals( rdn, rdn2 );
}
/**
* Test serialization of a simple Rdn
*/
@Test
public void testSimpleRdn2Serialization() throws LdapException, IOException, ClassNotFoundException
{
Rdn rdn = new Rdn( " ABC = DEF " );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream( baos );
out.writeObject( rdn );
ObjectInputStream in = null;
byte[] data = baos.toByteArray();
in = new ObjectInputStream( new ByteArrayInputStream( data ) );
Rdn rdn2 = ( Rdn ) in.readObject();
assertEquals( rdn, rdn2 );
}
/**
* Test serialization of a simple Rdn with no value
*/
@Test
public void testSimpleRdnNoValueSerialization() throws LdapException, IOException, ClassNotFoundException
{
Rdn rdn = new Rdn( " ABC =" );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream( baos );
out.writeObject( rdn );
ObjectInputStream in = null;
byte[] data = baos.toByteArray();
in = new ObjectInputStream( new ByteArrayInputStream( data ) );
Rdn rdn2 = ( Rdn ) in.readObject();
assertEquals( rdn, rdn2 );
}
/**
* Test serialization of a simple Rdn with one value
*/
@Test
public void testSimpleRdnOneValueSerialization() throws LdapException, IOException, ClassNotFoundException
{
Rdn rdn = new Rdn( " ABC = def " );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream( baos );
out.writeObject( rdn );
ObjectInputStream in = null;
byte[] data = baos.toByteArray();
in = new ObjectInputStream( new ByteArrayInputStream( data ) );
Rdn rdn2 = ( Rdn ) in.readObject();
assertEquals( rdn, rdn2 );
}
/**
* Test serialization of a simple Rdn with three values
*/
@Test
public void testSimpleRdnThreeValuesSerialization() throws LdapException, IOException, ClassNotFoundException
{
Rdn rdn = new Rdn( " A = a + B = b + C = c " );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream( baos );
out.writeObject( rdn );
ObjectInputStream in = null;
byte[] data = baos.toByteArray();
in = new ObjectInputStream( new ByteArrayInputStream( data ) );
Rdn rdn2 = ( Rdn ) in.readObject();
assertEquals( rdn, rdn2 );
}
/**
* Test serialization of a simple Rdn with three unordered values
*/
@Test
public void testSimpleRdnThreeValuesUnorderedSerialization() throws LdapException, IOException,
ClassNotFoundException
{
Rdn rdn = new Rdn( " B = b + A = a + C = c " );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream( baos );
out.writeObject( rdn );
ObjectInputStream in = null;
byte[] data = baos.toByteArray();
in = new ObjectInputStream( new ByteArrayInputStream( data ) );
Rdn rdn2 = ( Rdn ) in.readObject();
assertEquals( rdn, rdn2 );
}
/**
* test an Rdn with empty value
*/
@Test
public void testRdnWithEmptyValue() throws LdapException
{
assertTrue( Rdn.isValid( "a=" ) );
assertTrue( Rdn.isValid( "a=\"\"" ) );
assertEquals( "a=\"\"", new Rdn( "a=\"\"" ).getName() );
assertEquals( "a=", new Rdn( "a=" ).getName() );
}
/**
* test an Rdn with escaped comma
*/
@Test
public void testRdnWithEscapedComa() throws LdapException
{
assertTrue( Rdn.isValid( "a=b\\,c" ) );
assertEquals( "a=b\\,c", new Rdn( "a=b\\,c" ).getName() );
assertTrue( Rdn.isValid( "a=\"b,c\"" ) );
assertEquals( "a=\"b,c\"", new Rdn( "a=\"b,c\"" ).getName() );
assertEquals( "a=b\\,c", new Rdn( "a=\"b,c\"" ).getEscaped() );
assertEquals( "a=\"b,c\"", new Rdn( "a=\"b,c\"" ).getName() );
assertTrue( Rdn.isValid( "a=\"b\\,c\"" ) );
Rdn rdn = new Rdn( "a=\"b\\,c\"" );
assertEquals( "a=\"b\\,c\"", rdn.getName() );
assertEquals( "a=b\\,c", rdn.getEscaped() );
}
/**
* Tests the equals and equals results of cloned multi-valued RDNs.
* Test for DIRSHARED-9.
*
* @throws LdapException
*/
@Test
public void testComparingOfClonedMultiValuedRDNs() throws LdapException
{
// Use upper case attribute types to test if normalized types are used
// for comparison
Rdn rdn = new Rdn( " A = b + C = d" );
Rdn clonedRdn = rdn.clone();
assertTrue( rdn.equals( clonedRdn ) );
}
/**
* Tests the equals and equals results of copy constructed multi-valued RDNs.
* Test for DIRSHARED-9.
*
* @throws LdapException
*/
@Test
public void testComparingOfCopyConstructedMultiValuedRDNs() throws LdapException
{
// Use upper case attribute types to test if normalized types are used
// for comparison
Rdn rdn = new Rdn( " A = b + C = d" );
Rdn copiedRdn = new Rdn( rdn );
assertTrue( rdn.equals( copiedRdn ) );
}
/**
* test the UpName method on a Rdn with more than one atav
*/
@Test
public void testGetUpNameMultipleAtav() throws LdapException
{
Rdn rdn = new Rdn( " A = b + C = d " );
assertEquals( " A = b + C = d ", rdn.getName() );
}
/**
* test the iterator over a RDN
*/
@Test
public void testIterator() throws LdapException
{
Rdn rdn = new Rdn( "cn=John + sn=Doe" );
String[] expected = new String[]
{ "cn=John ", " sn=Doe" };
int i = 0;
for ( Ava ava : rdn )
{
assertEquals( expected[i], ava.getName() );
i++;
}
}
/**
* test that a RDN with two AVAs throws an exception
*/
@Test
public void testWrongRdn() throws LdapException
{
assertThrows( LdapInvalidDnException.class, () ->
{
new Rdn( " A = b, C = d " );
} );
}
/**
* test that a RDN can have an attributeType twice
*/
@Test
public void testRdnAtUsedTwice() throws LdapException
{
Rdn rdn = new Rdn( " A = b + A = d " );
assertEquals( " A = b + A = d ", rdn.getName() );
}
@Test
public void testAvaConstructor() throws LdapInvalidDnException
{
Rdn rdn = new Rdn( new Ava( "CN", "\u00E4" ), new Ava( "A", "d" ) );
assertEquals( "CN=\u00E4+A=d", rdn.getName() );
assertEquals( "\u00E4", rdn.getValue( "CN" ) );
assertEquals( "\u00E4", rdn.getValue() );
assertEquals( "CN", rdn.getType() );
assertEquals( "cn", rdn.getNormType() );
}
/**
* test that a RDN can have an attributeType twice
*/
@Test
public void testAvaConstructorRdnAtUsedTwice() throws LdapException
{
Rdn rdn = new Rdn( new Ava( "A", "b" ), new Ava( "A", "d" ) );
assertEquals( "A=b+A=d", rdn.getName() );
}
}