Bug 13618: Fix wrong condition in xt tests
[koha.git] / xt / find-missing-filters.t
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19 use Test::More tests => 1;
20 use File::Find;
21 use File::Slurp;
22 use Data::Dumper;
23
24 my @themes;
25
26 # OPAC themes
27 my $opac_dir  = 'koha-tmpl/opac-tmpl';
28 opendir ( my $dh, $opac_dir ) or die "can't opendir $opac_dir: $!";
29 for my $theme ( grep { not /^\.|lib|js|xslt/ } readdir($dh) ) {
30     push @themes, "$opac_dir/$theme/en";
31 }
32 close $dh;
33
34 # STAFF themes
35 my $staff_dir = 'koha-tmpl/intranet-tmpl';
36 opendir ( $dh, $staff_dir ) or die "can't opendir $staff_dir: $!";
37 for my $theme ( grep { not /^\.|lib|js/ } readdir($dh) ) {
38     push @themes, "$staff_dir/$theme/en";
39 }
40 close $dh;
41
42 my @files;
43 sub wanted {
44     my $name = $File::Find::name;
45     push @files, $name
46         if $name =~ m[\.(tt|inc)$] and -f $name;
47 }
48
49 my @tt_directives = (
50     qr{^\s*INCLUDE},
51     qr{^\s*USE},
52     qr{^\s*IF},
53     qr{^\s*UNLESS},
54     qr{^\s*ELSE},
55     qr{^\s*ELSIF},
56     qr{^\s*END},
57     qr{^\s*SET},
58     qr{^\s*FOR},
59     qr{^\s*FOREACH},
60     qr{^\s*MACRO},
61     qr{^\s*SWITCH},
62     qr{^\s*CASE},
63     qr{^\s*PROCESS},
64     qr{^\s*DEFAULT},
65     qr{^\s*TRY},
66     qr{^\s*CATCH},
67     qr{^\s*BLOCK},
68     qr{^\s*FILTER},
69     qr{^\s*STOP},
70     qr{^\s*NEXT},
71 );
72
73 sub process_tt_content {
74     my ($content) = @_;
75     my ( $use_raw, $has_use_raw );
76     my @errors;
77     for my $line ( split "\n", $content ) {
78         if ( $line =~ m{\[%[^%]+%\]} ) {
79
80             # handle exceptions first
81             $use_raw = 1
82               if $line =~ m{|\s*\$raw};    # Is the file use the raw filter?
83
84             # Do we have Asset without the raw filter?
85             if ( $line =~ m{^\s*\[% Asset} ) {
86                 push @errors, { error => 'asset_must_be_raw', line => $line }
87                   and next
88                   unless $line =~ m{\|\s*\$raw};
89             }
90
91             $has_use_raw++
92               if $line =~ m{\[% USE raw %\]};    # Does [% Use raw %] exist?
93
94             # Loop on TT blocks
95             while (
96                 $line =~ m{
97                     \[%
98                     (?<pre_chomp>(\s|\-|~)*)
99                     (?<tt_block>[^%\-~]+)
100                     (?<post_chomp>(\s|\-|~)*)
101                     %\]}gmxs
102               )
103             {
104                 my $tt_block = $+{tt_block};
105
106                 # It's a TT directive, no filters needed
107                 next if grep { $tt_block =~ $_ } @tt_directives;
108
109                 next
110                   if $tt_block =~ m{\s?\|\s?\$KohaDates\s?$}
111                   ;    # We could escape it but should be safe
112                 next if $tt_block =~ m{^\#};    # Is a comment, skip it
113
114                 push @errors, { error => 'missing_filter', line => $line }
115                   if $tt_block !~ m{\|\s?\$raw}   # already escaped correctly with raw
116                   && $tt_block !~ m{=}            # assignment, maybe we should require to use SET (?)
117                   && $tt_block !~ m{\|\s?ur(l|i)} # already has url or uri filter
118                   && $tt_block !~ m{\|\s?html}    # already has html filter
119                   && $tt_block !~ m{^(?<before>\S+)\s+UNLESS\s+(?<after>\S+)} # Specific for [% foo UNLESS bar %]
120                 ;
121             }
122         }
123     }
124
125     return @errors;
126 }
127
128 find({ wanted => \&wanted, no_chdir => 1 }, @themes );
129
130 my @errors;
131 for my $file ( @files ) {
132     say $file;
133     my $content = read_file($file);
134     my @e = process_tt_content($content);
135     push @errors, { file => $file, errors => \@e } if @e;
136 }
137
138 is( @errors, 0, "Template variables should be correctly escaped" )
139     or diag(Dumper @errors);