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