1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
#!perl
use Test::More;
use Net::LDAP::Entry;
use Net::LDAP::Filter;
use Net::LDAP::FilterMatch qw(Text::Soundex);
# Each line consists of an OPCODE-LIST and a DN,
# where
# - OPCODE-LIST is a comma separated list of OPCODES,
# each potentially prefixed with a TESTCASE prefix followed by :
# OPCODE-LIST = OPCODE (, [ TESTCASE:] OPCODE )+
# - within the OPCODE-LIST each TESTCASE prefix needs to be unique
# - no TESTCASE prefix means: default result
# - OPCODES are
# yes $filter->match() returns true
# no $filter->match() returns false
# fail $filter->match() returns undef
# To keep the order of tests, @tests is an array of ($filterstring => @ops) tuples
my @tests = map { /^([\w:,]+)\s+(\(.*\))/ && { $2 => [ split(/,/, $1) ] } }
grep(/^[\w:,]+\s+\(.*\)/, <DATA>);
# The elements of the @testcases array are the TESTCASE prefixes described above
my @testcases = qw/raw schema/;
# calculate number of tests:
plan tests => 3 + # general preparation
scalar(@tests) * # @tests is a list of ($filter => \@ops) pairs
( 1 + # one Net::LDAP::Filter test per ...
scalar(@testcases)); # ... every test case
my $entry = Net::LDAP::Entry->new(
'cn=John Doe, ou=Information Technology Division, ou=People, o=University of Michigan, c=US',
objectClass => [ 'OpenLDAPperson' ],
cn => [ 'John Doe', 'Jonathon Doe' ],
uid => [ 'john' ],
sn => [ 'Doe' ],
givenName => [ qw/John Jonathon/ ],
mailPreferenceOption => 2,
# uidnumber is not a legal attribute of OpenLDAPperson:
# does not matter here, but will not load into an LDAP server
uidNumber => 1012,
o => 'University of Michigan',
postalAddress => [ 'ITD $ 535 W. William $ Ann Arbor, MI 48109' ],
seeAlso => [ 'cn=All Staff, ou=Groups, o=University of Michigan, c=US' ],
homePostalAddress => [ '912 East Bllvd $ Ann Arbor, MI 48104' ],
title => [ 'System Administrator, Information Technology Division' ],
description => [ 'overworked!' ],
mail => [ 'johnd@mailgw.umich.edu' ],
homePhone => [ '+1 313 555 3774' ],
pager => [ '+1 313 555 6573' ],
facsimileTelephoneNumber => [ '+1 313 555 4544' ],
telephoneNumber => [ '+1 313 555 9394' ],
createTimestamp => '20090209123456Z',
creatorsName => 'cn=James A Jones 2, ou=Information Technology Division, ou=People, o=University of Michigan, c=US',
modifyTimestamp => '20121102212634Z',
modifiersName => 'cn=John Doe, ou=Information Technology Division, ou=People, o=University of Michigan, c=US');
isa_ok($entry, Net::LDAP::Entry, 'entry object created');
my $schema = Net::LDAP::Schema->new();
isa_ok($schema, Net::LDAP::Schema, 'schema object created');
ok($schema->parse('data/schema.in'), "schema loaded: ".($schema->error ? $schema->error : ''));
note('Schema: ', explain($schema)) if ($ENV{TEST_VERBOSE});
foreach my $elem (@tests) {
my ($filterstring, $ops) = %{$elem};
my $filter = Net::LDAP::Filter->new($filterstring);
isa_ok($filter, Net::LDAP::Filter, 'filter object created');
#note("$filterstring => ", explain($filter));
SKIP: {
eval { require Text::Soundex };
skip("Text::Soundex not installed", scalar(@testcases)) if ($@);
for my $case (@testcases) {
my ($op) = grep(/^$case:/, @{$ops});
($op) = grep(/^[^:]+$/, @{$ops}) if (!$op);
$op =~ s/^$case://;
my $match = $filter->match($entry, $case eq 'schema' ? $schema : undef);
foreach ($op) {
/fail/ && ok(!defined($match), "$filterstring should cause failure in $case mode");
/yes/ && ok($match, "$filterstring should match in $case mode");
/(todo|no)/ && ok(!$match, "$filterstring should not match in $case mode");
}
}
}
}
__DATA__
## "basic" match
# caseIgnoreIA5Match
yes (mail=johnd@mailgw.umich.edu)
# caseIgnoreListMatch
yes (postaladdress=ITD $ 535 W. William $ Ann Arbor, MI 48109)
# caseIgnoreMatch
no (cn=Babs Jensen)
yes (!(cn=Tim Howes))
yes (cn=John Doe)
# distinguishedNameMatch
yes,raw:no (seeAlso=cn=All Staff, OU=Groups, o=University of Michigan,c=US)
# facsimileNumberMatch
#yes (facsimiletelephoneNumber=+1 313 555 4544)
# generalizedTimeMatch
yes (createTimestamp>=19970101120000Z)
yes (createTimestamp<=25250101000000Z)
# integerMatch
yes (uidNumber=1012)
no (uidNumber=1011)
# integerMatch not listed in attributeType => fail with schema
fail,raw:yes (mailPreferenceOption=2)
# objectIdentifierMatch
no (objectclass=top)
yes (objectclass=OpenLDAPPerson)
# telephoneNumberMatch
yes (telephoneNumber=+1 313 555 9394)
yes,raw:no (homephone=+13135553774)
yes,raw:no (homephone=001313 5553774)
# generalizedTimeOrderingMatch
yes (createTimestamp>=19970101120000Z)
yes (createTimestamp<=25250101000000Z)
# integerOrderingMatch
yes (uidNumber>=1000)
yes (uidNumber<=2000)
# integerOrderingMatch not listed in attributeType => fail with schema
fail,raw:yes (mailpreferenceOption>=2)
# caseIgnoreIA5SubstringsMatch
yes (mail=johnd@*)
yes (mail=johnd*@*umich.edu)
# caseIgnoreListSubstringsMatch
yes (postaladdress=ITD $ * William $ Ann Arbor, MI 48109)
# caseIgnoreSubstringsMatch
yes (cn=j*)
no (cn=*a)
yes (cn=*a*)
yes (o=univ*of*mich*)
# facsimileNumberSubstringsMatch
#yes (facsimiletelephoneNumber=*1 313 555 4544)
#yes (facsimiletelephoneNumber=+1*555*)
# telephoneNumberSubstringsMatch
yes (telephoneNumber=+1*313 555 9394)
yes (telephoneNumber=+1*313*)
yes,raw:no (homephone=+131355*)
yes,raw:no (homephone=0013*774)
## presence match
yes (cn=*)
## approx match
yes (cn~=Jonathon Doe)
yes (cn~=jonathon doe)
yes (cn~=jonathan doe)
yes (cn~=jonothan doe)
yes (cn~=jonathan do)
yes (cn~=john doe)
yes (cn~=jon doe)
yes (cn~=jomatan doe)
yes (cn~=jonatan oe)
yes (cn~=jon dee)
## extensible match
yes (cn:dn:=John Doe)
yes (:dn:caseIgnoreMatch:=People)
yes (mailPreferenceOption:integerBitAndMatch:=2)
yes,raw:no (mailPreferenceOption:integerBitOrMatch:=3)
yes (!(mailPreferenceOption:integerBitAndMatch:=1))
yes (!(mailPreferenceOption:integerBitAndMatch:=3))
yes,raw:fail (:caseignoreMatch:=University of michigan)
# EOF
|