View | Details | Raw Unified | Return to bug 21576
Collapse All | Expand All

(-)a/misc/devel/add_missing_filters.pl (+93 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
use Modern::Perl;
4
5
use File::Slurp;
6
use Pod::Usage;
7
use Getopt::Long;
8
9
use t::lib::QA::TemplateFilters;
10
11
my ( $help, $verbose, @files );
12
GetOptions(
13
    'h|help'                 => \$help,
14
    'v|verbose'              => \$verbose,
15
) || pod2usage(1);
16
17
@files = @ARGV;
18
19
pod2usage(1) if $help or not @files;
20
21
my $i;
22
my $total = scalar @files;
23
my $num_width = length $total;
24
for my $file ( @ARGV ) {
25
    if ( $verbose ) {
26
        print sprintf "|%-25s| %${num_width}s / %s (%.2f%%)\r",
27
            '=' x (24*$i++/$total). '>',
28
            $i, $total, 100*$i/+$total;
29
        flush STDOUT;
30
    }
31
32
    my $content = read_file( $file );
33
    my $new_content = t::lib::QA::TemplateFilters::fix_filters($content);
34
    $new_content .= "\n";
35
    if ( $content ne $new_content ) {
36
        say "$file -- Modified";
37
        write_file($file, $new_content);
38
    }
39
}
40
41
42
=head1 NAME
43
44
add_missing_filters.pl - Will add the missing filters to the template files given in parameters.
45
46
=head1 SYNOPSIS
47
48
perl misc/devel/add_missing_filters.pl **/*.tt
49
50
/!\ It is highly recommended to execute this script on a clean git install, with all your files and changes committed.
51
52
 Options:
53
   -?|--help        brief help message
54
   -v|--verbose     verbose mode
55
56
=head1 OPTIONS
57
58
=over 8
59
60
=item B<--help|-?>
61
62
Print a brief help message and exits
63
64
=item B<-v|--verbose>
65
66
Verbose mode.
67
68
=back
69
70
=head1 AUTHOR
71
72
Jonathan Druart <jonathan.druart@bugs.koha-community.org>
73
74
=head1 COPYRIGHT
75
76
Copyright 2018 Koha Development Team
77
78
=head1 LICENSE
79
80
This file is part of Koha.
81
82
Koha is free software; you can redistribute it and/or modify it
83
under the terms of the GNU General Public License as published by
84
the Free Software Foundation; either version 3 of the License, or
85
(at your option) any later version.
86
87
Koha is distributed in the hope that it will be useful, but
88
WITHOUT ANY WARRANTY; without even the implied warranty of
89
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
90
GNU General Public License for more details.
91
92
You should have received a copy of the GNU General Public License
93
along with Koha; if not, see <http://www.gnu.org/licenses>.
(-)a/t/lib/QA/TemplateFilters.pm (-26 / +160 lines)
Lines 26-49 our @tt_directives = ( Link Here
26
    qr{^\s*NEXT},
26
    qr{^\s*NEXT},
27
);
27
);
28
28
29
sub missing_filters {
29
sub fix_filters {
30
    return _process_tt_content( @_ )->{new_content};
31
}
32
33
sub search_missing_filters {
34
    return _process_tt_content( @_ )->{errors};
35
36
}
37
38
sub _process_tt_content {
30
    my ($content) = @_;
39
    my ($content) = @_;
31
    my ( $use_raw, $has_use_raw );
40
    my ( $use_raw, $has_use_raw );
32
    my @errors;
41
    my @errors;
42
    my @new_lines;
33
    my $line_number;
43
    my $line_number;
34
    for my $line ( split "\n", $content ) {
44
    for my $line ( split "\n", $content ) {
45
        my $new_line = $line;
35
        $line_number++;
46
        $line_number++;
36
        if ( $line =~ m{\[%[^%]+%\]} ) {
47
        if ( $line =~ m{\[%[^%]+%\]} ) {
37
48
38
            # handle exceptions first
49
            # handle exceptions first
39
            $use_raw = 1
50
            if ( $line =~ m{\|\s*\$raw} ) {    # Is the file use the raw filter?
40
              if $line =~ m{|\s*\$raw};    # Is the file use the raw filter?
51
                $use_raw = 1;
52
            }
41
53
42
            # Do we have Asset without the raw filter?
54
            # Do we have Asset without the raw filter?
43
            if ( $line =~ m{^\s*\[% Asset} ) {
55
            if ( $line =~ m{^\s*\[% Asset} && $line !~ m{\|\s*\$raw} ) {
44
                push @errors, { error => 'asset_must_be_raw', line => $line, line_number => $line_number }
56
                push @errors,
45
                  and next
57
                  {
46
                  unless $line =~ m{\|\s*\$raw};
58
                    error       => 'asset_must_be_raw',
59
                    line        => $line,
60
                    line_number => $line_number
61
                  };
62
                $new_line =~ s/\)\s*%]/) | \$raw %]/;
63
                $use_raw = 1;
64
                push @new_lines, $new_line;
65
                next;
47
            }
66
            }
48
67
49
            $has_use_raw++
68
            $has_use_raw++
Lines 59-87 sub missing_filters { Link Here
59
                    %\]}gmxs
78
                    %\]}gmxs
60
              )
79
              )
61
            {
80
            {
62
                my $tt_block = $+{tt_block};
81
                my $tt_block   = $+{tt_block};
82
                my $pre_chomp  = $+{pre_chomp};
83
                my $post_chomp = $+{post_chomp};
84
85
                next if
86
                    # It's a TT directive, no filters needed
87
                    grep { $tt_block =~ $_ } @tt_directives
63
88
64
                # It's a TT directive, no filters needed
89
                    # It is a comment
65
                next if grep { $tt_block =~ $_ } @tt_directives;
90
                    or $tt_block =~ m{^\#}
66
91
67
                next
92
                    # Already escaped with a special filter
68
                  if   $tt_block =~ m{\s?\|\s?\$KohaDates\s?$}
93
                    # We could escape it but should be safe
94
                    or $tt_block =~ m{\s?\|\s?\$KohaDates\s?$}
69
                    or $tt_block =~ m{\s?\|\s?\$Price\s?$}
95
                    or $tt_block =~ m{\s?\|\s?\$Price\s?$}
70
                  ;    # We could escape it but should be safe
96
71
                next if $tt_block =~ m{^\#};    # Is a comment, skip it
97
                    # Already escaped correctly with raw
72
98
                    or $tt_block =~ m{\|\s?\$raw}
73
                push @errors, { error => 'missing_filter', line => $line, line_number => $line_number }
99
74
                  if $tt_block !~ m{\|\s?\$raw}   # already escaped correctly with raw
100
                    # Assignment, maybe we should require to use SET (?)
75
                  && $tt_block !~ m{=}            # assignment, maybe we should require to use SET (?)
101
                    or $tt_block =~ m{=}
76
                  && $tt_block !~ m{\|\s?ur(l|i)} # already has url or uri filter
102
77
                  && $tt_block !~ m{\|\s?html}    # already has html filter
103
                    # Already has url or uri filter
78
                  && $tt_block !~ m{^(?<before>\S+)\s+UNLESS\s+(?<after>\S+)} # Specific for [% foo UNLESS bar %]
104
                    or $tt_block =~ m{\|\s?ur(l|i)}
105
106
                    # Specific for [% foo UNLESS bar %]
107
                    or $tt_block =~ m{^(?<before>\S+)\s+UNLESS\s+(?<after>\S+)}
79
                ;
108
                ;
109
110
                $pre_chomp =
111
                    $pre_chomp
112
                  ? $pre_chomp =~ m|-|
113
                      ? q|- |
114
                      : $pre_chomp =~ m|~|
115
                        ? q|~ |
116
                        : q| |
117
                  : q| |;
118
                $post_chomp =
119
                    $post_chomp
120
                  ? $post_chomp =~ m|-|
121
                      ? q| -|
122
                      : $post_chomp =~ m|~|
123
                        ? q| ~|
124
                        : q| |
125
                  : q| |;
126
127
                if (
128
129
                    # Use the uri filter
130
                    # If html filtered or not filtered
131
                    $new_line =~ qr{
132
                        <a\shref="(tel:|mailto:)?
133
                        \[%
134
                            \s*$pre_chomp\s*
135
                            \Q$tt_block\E
136
                            \s*$post_chomp\s*
137
                            (\|\s*html)?
138
                            \s*
139
                        %\]
140
                    }xms
141
142
                    # And not already uri or url filtered
143
                    and not $new_line =~ qr{
144
                        <a\shref="(tel:|mailto:)?
145
                        \[%
146
                            \s*$pre_chomp\s*
147
                            \Q$tt_block\E
148
                            \s|\s(uri|url)
149
                            \s*$post_chomp\s*
150
                        %\]
151
                    }xms
152
                  )
153
                {
154
                    $tt_block =~ s/^\s*|\s*$//g;    # trim
155
                    $tt_block =~ s/\s*\|\s*html\s*//;
156
                    $new_line =~ s{
157
                            \[%
158
                            \s*$pre_chomp\s*
159
                            \Q$tt_block\E(\s*\|\s*html)?
160
                            \s*$post_chomp\s*
161
                            %\]
162
                        }{[%$pre_chomp$tt_block | uri$post_chomp%]}xms;
163
                    push @errors,
164
                      {
165
                        error       => 'wrong_html_filter',
166
                        line        => $line,
167
                        line_number => $line_number
168
                      };
169
                    next;
170
                }
171
                elsif (
172
                    $tt_block !~ m{\|\s?html} # already has html filter
173
                  )
174
                {
175
                    $tt_block =~ s/^\s*|\s*$//g; # trim
176
                    $new_line =~ s{
177
                        \[%
178
                        \s*$pre_chomp\s*
179
                        \Q$tt_block\E
180
                        \s*$post_chomp\s*
181
                        %\]
182
                    }{[%$pre_chomp$tt_block | html$post_chomp%]}xms;
183
184
                    push @errors,
185
                      {
186
                        error       => 'missing_filter',
187
                        line        => $line,
188
                        line_number => $line_number
189
                      };
190
                    next;
191
                }
80
            }
192
            }
193
            push @new_lines, $new_line;
194
        }
195
        else {
196
            push @new_lines, $new_line;
81
        }
197
        }
198
82
    }
199
    }
83
200
84
    return @errors;
201
    # Adding [% USE raw %] on top if the filter is used
202
    @new_lines = ( '[% USE raw %]', @new_lines )
203
      if $use_raw and not $has_use_raw;
204
205
    my $new_content = join "\n", @new_lines;
206
    return { errors => \@errors, new_content => $new_content };
85
}
207
}
86
208
87
1;
209
1;
Lines 93-99 t::lib::QA::TemplateFilters - Module used by tests and QA script to catch missin Link Here
93
=head1 SYNOPSIS
215
=head1 SYNOPSIS
94
216
95
    my $content = read_file($filename);
217
    my $content = read_file($filename);
96
    my @e = t::lib::QA::TemplateFilters::missing_filters($content);
218
    my $new_content = t::lib::QA::TemplateFilters::fix_filters($content);
219
    my $errors      = t::lib::QA::TemplateFilters::search_missing_filters($content);
97
220
98
=head1 DESCRIPTION
221
=head1 DESCRIPTION
99
222
Lines 102-116 and to not duplicate the code. Link Here
102
225
103
=head1 METHODS
226
=head1 METHODS
104
227
105
=head2 missing_filters
228
=head2 fix_filters
106
229
107
    Take a template content file in parameter and return an array of errors.
230
    Take a template content file in parameter and return the same content with
108
    An error is a hashref with 2 keys, error and line.
231
    the correct (guessed) filters.
232
    It will also add the [% USE raw %] statement if it is needed.
233
234
=head2 search_missing_filters
235
236
    Take a template content file in parameter and return an arrayref of errors.
237
238
    An error is a hashref with 3 keys, error and line, line_number.
109
    * error can be:
239
    * error can be:
110
    asset_must_be_raw - When Asset is called without using raw
240
    asset_must_be_raw - When Asset is called without using raw
111
    missing_filter    - When a TT variable is displayed without filter
241
    missing_filter    - When a TT variable is displayed without filter
242
    wrong_html_filter - When a TT variable is using the html filter when uri (or url)
243
                        should be used instead.
112
244
113
    * line is the line where the error has been found.
245
    * line is the line where the error has been found.
246
    * line_number is the line number where the error has been found.
247
114
248
115
=head1 AUTHORS
249
=head1 AUTHORS
116
250
(-)a/t/template_filters.t (-94 / +207 lines)
Lines 16-43 Link Here
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
use Test::More tests => 1;
19
use Test::More tests => 5;
20
use t::lib::QA::TemplateFilters;
20
use t::lib::QA::TemplateFilters;
21
21
22
my $input = <<INPUT;
22
subtest 'Asset must use raw' => sub {
23
[% USE Asset %]
23
    plan tests => 2;
24
[% INCLUDE 'doc-head-open.inc' %]
24
    my $input = <<INPUT;
25
[% Asset.css("css/one.css") %]
26
[% Asset.css("js/two.js") %]
27
INPUT
28
    my $expected = <<EXPECTED;
29
[% USE raw %]
30
[% Asset.css("css/one.css") | \$raw %]
31
[% Asset.css("js/two.js") | \$raw %]
32
EXPECTED
33
34
    my $new_content = t::lib::QA::TemplateFilters::fix_filters($input);
35
    is( $new_content . "\n", $expected, );
36
    my $missing_filters = t::lib::QA::TemplateFilters::search_missing_filters($input);
37
    is_deeply(
38
        $missing_filters,
39
        [
40
            {
41
                error       => "asset_must_be_raw",
42
                line        => '[% Asset.css("css/one.css") %]',
43
                line_number => 1,
44
            },
45
            {
46
                error       => "asset_must_be_raw",
47
                line        => '[% Asset.css("js/two.js") %]',
48
                line_number => 2,
49
            }
50
51
        ],
52
    );
53
};
54
55
subtest 'Variables must be html escaped' => sub {
56
    plan tests => 2;
57
58
    my $input = <<INPUT;
25
<title>Koha &rsaquo; Patrons &rsaquo;
59
<title>Koha &rsaquo; Patrons &rsaquo;
26
    [% UNLESS blocking_error %]
60
    [% UNLESS blocking_error %]
27
        Patron details for [% INCLUDE 'patron-title.inc' no_html = 1 %]
61
        [% just_a_var %]
28
        [% just_a_var %] A N D [% another_one_on_same_line %]
62
        [% just_a_var %] A N D [% another_one_on_same_line %]
29
        [% just_a_var_filtered|html %]
30
        [% just_a_var_filtered |html %]
31
        [% just_a_var_filtered| html %]
32
        [% just_a_var_filtered | html %]
33
    [% END %]
63
    [% END %]
34
    [% IF ( patron.othernames | html ) %]&ldquo;[% patron.othernames %]&rdquo;[% END %]
64
    [% IF ( patron.othernames ) %]&ldquo;[% patron.othernames %]&rdquo;[% END %]
35
    [% Asset.css("css/datatables.css").raw %]
36
    [% Asset.css("css/datatables.css") | \$raw %]
37
</title>
65
</title>
38
<a href="tel:[% patron.phone %]">[% patron.phone %]</a>
39
<a title="[% patron.emailpro %]" href="mailto:[% patron.emailpro | uri %]">[% patron.emailpro %]</a>
40
[% patron_message.get_column('manager_surname') %]
66
[% patron_message.get_column('manager_surname') %]
67
INPUT
68
69
    my $expected = <<EXPECTED;
70
<title>Koha &rsaquo; Patrons &rsaquo;
71
    [% UNLESS blocking_error %]
72
        [% just_a_var | html %]
73
        [% just_a_var | html %] A N D [% another_one_on_same_line | html %]
74
    [% END %]
75
    [% IF ( patron.othernames ) %]&ldquo;[% patron.othernames | html %]&rdquo;[% END %]
76
</title>
77
[% patron_message.get_column('manager_surname') | html %]
78
EXPECTED
79
80
    my $new_content = t::lib::QA::TemplateFilters::fix_filters($input);
81
    is( $new_content . "\n", $expected, );
82
    my $missing_filters = t::lib::QA::TemplateFilters::search_missing_filters($input);
83
    is_deeply(
84
        $missing_filters,
85
        [{
86
                error => "missing_filter",
87
                line => "        [% just_a_var %]",
88
                line_number => 3,
89
            },
90
            {
91
                error => "missing_filter",
92
                line => "        [% just_a_var %] A N D [% another_one_on_same_line %]",
93
                line_number => 4,
94
            },
95
            {
96
                error => "missing_filter",
97
                line => "        [% just_a_var %] A N D [% another_one_on_same_line %]",
98
                line_number => 4,
99
            },
100
            {
101
                error => "missing_filter",
102
                line => "    [% IF ( patron.othernames ) %]&ldquo;[% patron.othernames %]&rdquo;[% END %]",
103
                line_number => 6,
104
            },
105
            {
106
                error => "missing_filter",
107
                line  => "[% patron_message.get_column('manager_surname') %]",
108
                line_number => 8
109
            }
110
        ],
111
112
    );
113
};
114
115
subtest 'TT directives, assignments and already filtered variables must not be escaped' => sub {
116
    plan tests => 2;
117
    my $input = <<INPUT;
118
#[% USE Asset %]
119
[% INCLUDE 'doc-head-open.inc' %]
120
[%# do_nothing %]
121
[% # do_nothing %]
122
[% SWITCH var %]
123
[% CASE 'foo' %]foo
124
[% CASE %]
125
[% END %]
126
[%- SWITCH var -%]
127
[%- CASE 'foo' -%]foo
128
[%- CASE -%]
129
[%- END -%]
130
[% foo UNLESS bar %]
131
[% SET var = val %]
132
[% var = val %]
133
[% var | \$Price %]
134
[% just_a_var_filtered|html %]
135
[% just_a_var_filtered |html %]
136
[% just_a_var_filtered| html %]
137
[% just_a_var_filtered | html %]
138
[%END%]
139
INPUT
140
    my $expected = <<EXPECTED;
141
#[% USE Asset %]
142
[% INCLUDE 'doc-head-open.inc' %]
41
[%# do_nothing %]
143
[%# do_nothing %]
42
[% # do_nothing %]
144
[% # do_nothing %]
43
[% SWITCH var %]
145
[% SWITCH var %]
Lines 48-137 my $input = <<INPUT; Link Here
48
[%- CASE 'foo' -%]foo
150
[%- CASE 'foo' -%]foo
49
[%- CASE -%]
151
[%- CASE -%]
50
[%- END -%]
152
[%- END -%]
51
[%- var -%]
52
[% - var - %]
53
[%~ var ~%]
54
[% ~ var ~ %]
55
[% var | \$raw %]
56
[% foo UNLESS bar %]
153
[% foo UNLESS bar %]
57
[% SET var = val %]
154
[% SET var = val %]
58
[% var = val %]
155
[% var = val %]
59
[% var | \$Price %]
156
[% var | \$Price %]
157
[% just_a_var_filtered|html %]
158
[% just_a_var_filtered |html %]
159
[% just_a_var_filtered| html %]
160
[% just_a_var_filtered | html %]
60
[%END%]
161
[%END%]
162
EXPECTED
163
164
    my $new_content = t::lib::QA::TemplateFilters::fix_filters($input);
165
    is( $new_content . "\n", $expected, );
166
    my $missing_filters = t::lib::QA::TemplateFilters::search_missing_filters($input);
167
    is_deeply(
168
        $missing_filters,[],);
169
};
170
171
subtest 'Preserve pre/post chomps' => sub {
172
    plan tests => 1;
173
    my $input = <<INPUT;
174
[% USE raw %]
175
[%- var -%]
176
[% - var - %]
177
[%~ var ~%]
178
[% ~ var ~ %]
179
[%- var | html -%]
180
[%~ var | html ~%]
181
[%- var | uri -%]
182
[%~ var | uri ~%]
183
INPUT
184
    my $expected = <<EXPECTED;
185
[% USE raw %]
186
[%- var | html -%]
187
[%- var | html -%]
188
[%~ var | html ~%]
189
[%~ var | html ~%]
190
[%- var | html -%]
191
[%~ var | html ~%]
192
[%- var | uri -%]
193
[%~ var | uri ~%]
194
EXPECTED
195
196
    my $new_content = t::lib::QA::TemplateFilters::fix_filters($input);
197
    is( $new_content . "\n", $expected, );
198
};
199
200
subtest 'Use uri filter if needed' => sub {
201
    plan tests => 3;
202
    my $input = <<INPUT;
203
<a href="tel:[% patron.phone %]">[% patron.phone %]</a>
204
<a href="mailto:[% patron.emailpro %]" title="[% patron.emailpro %]">[% patron.emailpro %]</a>
205
<a href="mailto:[% patron.emailpro | html %]" title="[% patron.emailpro %]">[% patron.emailpro %]</a>
206
<a href="mailto:[% patron.emailpro | uri %]" title="[% patron.emailpro %]">[% patron.emailpro %]</a>
207
<a href="[% myuri %]" title="[% myuri %]">[% myuri %]</a>
208
<a href="[% myuri | uri %]" title="[% myuri %]">[% myuri %]</a>
209
<a href="[% myurl | html %]" title="[% myurl %]">[% myurl %]</a>
210
<a href="[% myurl | url %]" title="[% myurl %]">[% myurl %]</a>
61
INPUT
211
INPUT
62
212
63
my @expected_errors = (
213
    # Note: [% myurl %] will be uri escaped, we cannot know url should be used
64
    {
214
    my $expected = <<EXPECTED;
65
        error => q{missing_filter},
215
<a href="tel:[% patron.phone | uri %]">[% patron.phone | html %]</a>
66
        line =>
216
<a href="mailto:[% patron.emailpro | uri %]" title="[% patron.emailpro | html %]">[% patron.emailpro | html %]</a>
67
q{        [% just_a_var %] A N D [% another_one_on_same_line %]},
217
<a href="mailto:[% patron.emailpro | uri %]" title="[% patron.emailpro | html %]">[% patron.emailpro | html %]</a>
68
        line_number => 6,
218
<a href="mailto:[% patron.emailpro | uri %]" title="[% patron.emailpro | html %]">[% patron.emailpro | html %]</a>
69
    },
219
<a href="[% myuri | uri %]" title="[% myuri | html %]">[% myuri | html %]</a>
70
    {
220
<a href="[% myuri | uri %]" title="[% myuri | html %]">[% myuri | html %]</a>
71
        error => q{missing_filter},
221
<a href="[% myurl | uri %]" title="[% myurl | html %]">[% myurl | html %]</a>
72
        line =>
222
<a href="[% myurl | url %]" title="[% myurl | html %]">[% myurl | html %]</a>
73
q{        [% just_a_var %] A N D [% another_one_on_same_line %]},
223
EXPECTED
74
        line_number => 6,
224
75
    },
225
    my $new_content = t::lib::QA::TemplateFilters::fix_filters($input);
76
    {
226
    is( $new_content . "\n", $expected, );
77
        error => q{missing_filter},
227
78
        line =>
228
    $input = <<INPUT;
79
q{    [% IF ( patron.othernames | html ) %]&ldquo;[% patron.othernames %]&rdquo;[% END %]},
229
<a href="[% wrong_filter | html %]">[% var | html %]</a>
80
        line_number => 12,
230
INPUT
81
    },
231
    my $missing_filters = t::lib::QA::TemplateFilters::search_missing_filters($input);
82
    {
232
    is_deeply(
83
        error       => q{asset_must_be_raw},
233
        $missing_filters,
84
        line        => q{    [% Asset.css("css/datatables.css").raw %]},
234
        [
85
        line_number => 13,
235
            {
86
    },
236
                error => "wrong_html_filter",
87
    {
237
                line =>
88
        error => q{missing_filter},
238
                  '<a href="[% wrong_filter | html %]">[% var | html %]</a>',
89
        line  => q{<a href="tel:[% patron.phone %]">[% patron.phone %]</a>},
239
                line_number => 1
90
        line_number => 16,
240
            }
91
    },
241
92
    {
242
        ],
93
        error => q{missing_filter},
243
    );
94
        line  => q{<a href="tel:[% patron.phone %]">[% patron.phone %]</a>},
244
95
        line_number => 16,
245
    $input = <<INPUT;
96
    },
246
<a href="[% good_raw_filter | \$raw %]">[% var | html %]</a>
97
    {
247
INPUT
98
        error => q{missing_filter},
248
    $missing_filters = t::lib::QA::TemplateFilters::search_missing_filters($input);
99
        line =>
249
    is_deeply( $missing_filters, [], );
100
q{<a title="[% patron.emailpro %]" href="mailto:[% patron.emailpro | uri %]">[% patron.emailpro %]</a>},
250
};
101
        line_number => 17,
102
    },
103
    {
104
        error => q{missing_filter},
105
        line =>
106
q{<a title="[% patron.emailpro %]" href="mailto:[% patron.emailpro | uri %]">[% patron.emailpro %]</a>},
107
        line_number => 17,
108
    },
109
    {
110
        error       => q{missing_filter},
111
        line        => q{[% patron_message.get_column('manager_surname') %]},
112
        line_number => 18,
113
    },
114
    {
115
        error       => q{missing_filter},
116
        line        => q{[%- var -%]},
117
        line_number => 29,
118
    },
119
    {
120
        error       => q{missing_filter},
121
        line        => q{[% - var - %]},
122
        line_number => 30,
123
    },
124
    {
125
        error       => q{missing_filter},
126
        line        => q{[%~ var ~%]},
127
        line_number => 31,
128
    },
129
    {
130
        error       => q{missing_filter},
131
        line        => q{[% ~ var ~ %]},
132
        line_number => 32,
133
    }
134
);
135
136
my @get = t::lib::QA::TemplateFilters::missing_filters($input);
137
is_deeply( \@get, \@expected_errors);
(-)a/xt/find-missing-filters.t (-3 / +2 lines)
Lines 52-59 find({ wanted => \&wanted, no_chdir => 1 }, @themes ); Link Here
52
my @errors;
52
my @errors;
53
for my $file ( @files ) {
53
for my $file ( @files ) {
54
    my $content = read_file($file);
54
    my $content = read_file($file);
55
    my @e = t::lib::QA::TemplateFilters::missing_filters($content);
55
    my $e = t::lib::QA::TemplateFilters::search_missing_filters($content);
56
    push @errors, { file => $file, errors => \@e } if @e;
56
    push @errors, { file => $file, errors => $e } if @$e;
57
}
57
}
58
58
59
is( @errors, 0, "Template variables should be correctly escaped" )
59
is( @errors, 0, "Template variables should be correctly escaped" )
60
- 

Return to bug 21576