merging RT 4.0.6
[freeside.git] / rt / t / fts / indexed_pg.t
1 #!/usr/bin/perl -w
2
3 use strict;
4 use warnings;
5
6 use RT::Test tests => undef;
7 plan skip_all => 'Not Pg' unless RT->Config->Get('DatabaseType') eq 'Pg';
8
9 my ($major, $minor) = $RT::Handle->dbh->get_info(18) =~ /^0*(\d+)\.0*(\d+)/;
10 plan skip_all => "Need Pg 8.2 or higher; we have $major.$minor"
11     if "$major.$minor" < 8.2;
12
13 plan tests => 36;
14
15 RT->Config->Set( FullTextSearch => Enable => 1, Indexed => 1, Column => 'ContentIndex', Table => 'Attachments' );
16
17 setup_indexing();
18
19 my $q = RT::Test->load_or_create_queue( Name => 'General' );
20 ok $q && $q->id, 'loaded or created queue';
21 my $queue = $q->Name;
22
23 sub setup_indexing {
24     my %args = (
25         'no-ask'       => 1,
26         command        => $RT::SbinPath .'/rt-setup-fulltext-index',
27         dba            => $ENV{'RT_DBA_USER'},
28         'dba-password' => $ENV{'RT_DBA_PASSWORD'},
29     );
30     my ($exit_code, $output) = RT::Test->run_and_capture( %args );
31     ok(!$exit_code, "setted up index") or diag "output: $output";
32 }
33
34 sub sync_index {
35     my %args = (
36         command => $RT::SbinPath .'/rt-fulltext-indexer',
37     );
38     my ($exit_code, $output) = RT::Test->run_and_capture( %args );
39     ok(!$exit_code, "setted up index") or diag "output: $output";
40 }
41
42 sub run_tests {
43     my @test = @_;
44     while ( my ($query, $checks) = splice @test, 0, 2 ) {
45         run_test( $query, %$checks );
46     }
47 }
48
49 my @tickets;
50 sub run_test {
51     my ($query, %checks) = @_;
52     my $query_prefix = join ' OR ', map 'id = '. $_->id, @tickets;
53
54     my $tix = RT::Tickets->new(RT->SystemUser);
55     $tix->FromSQL( "( $query_prefix ) AND ( $query )" );
56
57     my $error = 0;
58
59     my $count = 0;
60     $count++ foreach grep $_, values %checks;
61     is($tix->Count, $count, "found correct number of ticket(s) by '$query'") or $error = 1;
62
63     my $good_tickets = ($tix->Count == $count);
64     while ( my $ticket = $tix->Next ) {
65         next if $checks{ $ticket->id };
66         diag $ticket->Subject ." ticket has been found when it's not expected";
67         $good_tickets = 0;
68     }
69     ok( $good_tickets, "all tickets are good with '$query'" ) or $error = 1;
70
71     diag "Wrong SQL query for '$query':". $tix->BuildSelectQuery if $error;
72 }
73
74 @tickets = RT::Test->create_tickets(
75     { Queue => $q->id },
76     { Subject => 'fts test 1', Content => 'book' },
77     { Subject => 'fts test 2', Content => 'bars'  },
78 );
79 sync_index();
80
81 my $book = $tickets[0];
82 my $bars = $tickets[1];
83
84 run_tests(
85     "Content LIKE 'book'" => { $book->id => 1, $bars->id => 0 },
86     "Content LIKE 'bars'" => { $book->id => 0, $bars->id => 1 },
87
88     # make sure that Pg stemming works
89     "Content LIKE 'books'" => { $book->id => 1, $bars->id => 0 },
90     "Content LIKE 'bar'"   => { $book->id => 0, $bars->id => 1 },
91
92     # no matches
93     "Content LIKE 'baby'" => { $book->id => 0, $bars->id => 0 },
94     "Content LIKE 'pubs'" => { $book->id => 0, $bars->id => 0 },
95 );
96
97 # Test the "ts_vector too long" skip
98 my $content = "";
99 $content .= "$_\n" for 1..200_000;
100 @tickets = RT::Test->create_tickets(
101     { Queue => $q->id },
102     { Subject => 'Short content', Content => '50' },
103     { Subject => 'Long content',  Content => $content  },
104     { Subject => 'More short',    Content => '50' },
105 );
106
107 my ($exit_code, $output) = RT::Test->run_and_capture(
108     command => $RT::SbinPath .'/rt-fulltext-indexer'
109 );
110 like($output, qr/string is too long for tsvector/, "Got a warning for the ticket");
111 ok(!$exit_code, "set up index");
112
113 # The long content is skipped entirely
114 run_tests(
115     "Content LIKE '1'"  => { $tickets[0]->id => 0, $tickets[1]->id => 0, $tickets[2]->id => 0 },
116     "Content LIKE '50'" => { $tickets[0]->id => 1, $tickets[1]->id => 0, $tickets[2]->id => 1 },
117 );
118
119 @tickets = ();