1#!perl
2#
3# The attribute given must have unique values over the entries
4# returned from the search. This is because this test checks
5# that the order of entries returned by 'attr' is the exact
6# opposite of '-attr' this is not guaranteed if two entries have
7# the same value for attr.
8
9use Test::More;
10
11BEGIN { require "t/common.pl" }
12
13use Net::LDAP::LDIF;
14use Net::LDAP::Control::Sort;
15use Net::LDAP::Constant qw(
16	LDAP_CONTROL_SORTREQUEST
17	LDAP_CONTROL_SORTRESULT
18	LDAP_SUCCESS
19);
20
21
22# @testcases is a list of ($order => $reversed) tuples
23my @testcases = (
24	[ 'cn:2.5.13.3' => '-cn:2.5.13.3' ] ,
25	[ 'sn:2.5.13.3 uid:2.5.13.3' => '-sn:2.5.13.3 -uid:2.5.13.3' ]
26);
27
28start_server()
29? plan tests => (4 + scalar(@testcases) * 9)
30: plan skip_all => 'no server';
31
32
33$ldap = client();
34isa_ok($ldap, Net::LDAP, "client");
35
36$rootdse = $ldap->root_dse;
37isa_ok($rootdse, Net::LDAP::RootDSE, "root_dse");
38
39
40SKIP: {
41  skip("RootDSE does not offer sort control", 2 + scalar(@testcases) * 9)
42    unless($rootdse->supported_control(LDAP_CONTROL_SORTREQUEST));
43
44  #$mesg = $ldap->start_tls;
45  #ok(!$mesg->code, "start_tls: " . $mesg->code . ": " . $mesg->error);
46
47  $mesg = $ldap->bind($MANAGERDN, password => $PASSWD);
48  ok(!$mesg->code, "bind: " . $mesg->code . ": " . $mesg->error);
49
50  ok(ldif_populate($ldap, "data/40-in.ldif"), "data/40-in.ldif");
51
52  foreach my $elem (@testcases) {
53    my ($ordered,$reversed) = @{$elem};
54    my @attrs = map { s/:.*$//; $_ } split(/\s+/, $ordered);
55    my $sort = Net::LDAP::Control::Sort->new(order => $ordered);
56    isa_ok($sort, Net::LDAP::Control::Sort, "sort control object");
57
58    my $mesg = $ldap->search(
59	      base	=> $BASEDN,
60	      filter	=> '(objectclass=OpenLDAPperson)',
61	      control	=> [ $sort ],
62	    );
63    is($mesg->code, LDAP_SUCCESS, "search: " . $mesg->code . ": " . $mesg->error);
64
65    my ($resp) = $mesg->control( LDAP_CONTROL_SORTRESULT );
66    ok($resp, 'LDAP_CONTROL_SORTRESULT response');
67
68    ok($resp && $resp->result == LDAP_SUCCESS , 'LDAP_CONTROL_SORTRESULT success');
69
70    if ($ENV{TEST_VERBOSE}) {
71      my $rank = 0;
72      foreach my $e ($mesg->entries) {
73        note(++$rank, '. ', join(':', map { join(',',$e->get_value($_)) } @attrs));
74      }
75    }
76
77    my $dn1 = join ";", map { $_->dn } $mesg->entries;
78
79    $sort = Net::LDAP::Control::Sort->new(order => $reversed);
80    isa_ok($sort, Net::LDAP::Control::Sort, "sort control object (reversed)");
81
82    $mesg = $ldap->search(
83	  base		=> $BASEDN,
84	  filter	=> '(objectclass=OpenLDAPperson)',
85	  control	=> [ $sort ],
86	);
87    is($mesg->code, LDAP_SUCCESS, 'search result');
88
89    ($resp) = $mesg->control( LDAP_CONTROL_SORTRESULT );
90    ok($resp, 'LDAP_CONTROL_SORTRESULT response');
91
92    ok($resp && $resp->result == LDAP_SUCCESS , 'LDAP_CONTROL_SORTRESULT success');
93
94    if ($ENV{TEST_VERBOSE}) {
95      my $rank = 0;
96      foreach my $e (reverse $mesg->entries) {
97        note(++$rank,'. ',join(':', map { join(',',$e->get_value($_)) } @attrs));
98      }
99    }
100
101    my $dn2 = join ";", map { $_->dn } reverse $mesg->entries;
102
103    is($dn1, $dn2, 'sort order');
104  }
105}
106