From e01ac8a69c4c2e6a244152bef561f6bf51d13c31 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Fri, 21 Sep 2018 10:26:03 -0300 Subject: [PATCH] Bug 21393: Move missing filters code to a module To make it reusable easily from QA test tools https://gitlab.com/koha-community/qa-test-tools/issues/3 --- t/lib/QA/TemplateFilters.pm | 133 ++++++++++++++++++++++++++++++++++++++++++++ xt/find-missing-filters.t | 83 +-------------------------- 2 files changed, 135 insertions(+), 81 deletions(-) create mode 100644 t/lib/QA/TemplateFilters.pm diff --git a/t/lib/QA/TemplateFilters.pm b/t/lib/QA/TemplateFilters.pm new file mode 100644 index 0000000000..0185565ef5 --- /dev/null +++ b/t/lib/QA/TemplateFilters.pm @@ -0,0 +1,133 @@ +package t::lib::QA::TemplateFilters; + +use Modern::Perl; + +our @tt_directives = ( + qr{^\s*INCLUDE}, + qr{^\s*USE}, + qr{^\s*IF}, + qr{^\s*UNLESS}, + qr{^\s*ELSE}, + qr{^\s*ELSIF}, + qr{^\s*END}, + qr{^\s*SET}, + qr{^\s*FOR}, + qr{^\s*FOREACH}, + qr{^\s*MACRO}, + qr{^\s*SWITCH}, + qr{^\s*CASE}, + qr{^\s*PROCESS}, + qr{^\s*DEFAULT}, + qr{^\s*TRY}, + qr{^\s*CATCH}, + qr{^\s*BLOCK}, + qr{^\s*FILTER}, + qr{^\s*STOP}, + qr{^\s*NEXT}, +); + +sub missing_filters { + my ($content) = @_; + my ( $use_raw, $has_use_raw ); + my @errors; + for my $line ( split "\n", $content ) { + if ( $line =~ m{\[%[^%]+%\]} ) { + + # handle exceptions first + $use_raw = 1 + if $line =~ m{|\s*\$raw}; # Is the file use the raw filter? + + # Do we have Asset without the raw filter? + if ( $line =~ m{^\s*\[% Asset} ) { + push @errors, { error => 'asset_must_be_raw', line => $line } + and next + unless $line =~ m{\|\s*\$raw}; + } + + $has_use_raw++ + if $line =~ m{\[% USE raw %\]}; # Does [% Use raw %] exist? + + # Loop on TT blocks + while ( + $line =~ m{ + \[% + (?(\s|\-|~)*) + (?[^%\-~]+) + (?(\s|\-|~)*) + %\]}gmxs + ) + { + my $tt_block = $+{tt_block}; + + # It's a TT directive, no filters needed + next if grep { $tt_block =~ $_ } @tt_directives; + + next + if $tt_block =~ m{\s?\|\s?\$KohaDates\s?$} + ; # We could escape it but should be safe + next if $tt_block =~ m{^\#}; # Is a comment, skip it + + push @errors, { error => 'missing_filter', line => $line } + if $tt_block !~ m{\|\s?\$raw} # already escaped correctly with raw + && $tt_block !~ m{=} # assignment, maybe we should require to use SET (?) + && $tt_block !~ m{\|\s?ur(l|i)} # already has url or uri filter + && $tt_block !~ m{\|\s?html} # already has html filter + && $tt_block !~ m{^(?\S+)\s+UNLESS\s+(?\S+)} # Specific for [% foo UNLESS bar %] + ; + } + } + } + + return @errors; +} + +1; + +=head1 NAME + +t::lib::QA::TemplateFilters - Module used by tests and QA script to catch missing filters in template files + +=head1 SYNOPSIS + + my $content = read_file($filename); + my @e = t::lib::QA::TemplateFilters::missing_filters($content); + +=head1 DESCRIPTION + +The goal of this module is to make the subroutine reusable from the QA scripts +and to not duplicate the code. + +=head1 METHODS + +=head2 missing_filters + + Take a template content file in parameter and return an array of errors. + An error is a hashref with 2 keys, error and line. + * error can be: + asset_must_be_raw - When Asset is called without using raw + missing_filter - When a TT variable is displayed without filter + + * line is the line where the error has been found. + +=head1 AUTHORS + +Jonathan Druart + +=head1 COPYRIGHT + +Copyright 2017 - Koha Development Team + +=head1 LICENSE + +This file is part of Koha. + +Koha is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your option) any later version. + +Koha is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with Koha; if not, see . + +=cut + +1; diff --git a/xt/find-missing-filters.t b/xt/find-missing-filters.t index b7891e28f4..6b7e80f4aa 100755 --- a/xt/find-missing-filters.t +++ b/xt/find-missing-filters.t @@ -20,6 +20,7 @@ use Test::More tests => 1; use File::Find; use File::Slurp; use Data::Dumper; +use t::lib::QA::TemplateFilters; my @themes; @@ -46,92 +47,12 @@ sub wanted { if $name =~ m[\.(tt|inc)$] and -f $name; } -my @tt_directives = ( - qr{^\s*INCLUDE}, - qr{^\s*USE}, - qr{^\s*IF}, - qr{^\s*UNLESS}, - qr{^\s*ELSE}, - qr{^\s*ELSIF}, - qr{^\s*END}, - qr{^\s*SET}, - qr{^\s*FOR}, - qr{^\s*FOREACH}, - qr{^\s*MACRO}, - qr{^\s*SWITCH}, - qr{^\s*CASE}, - qr{^\s*PROCESS}, - qr{^\s*DEFAULT}, - qr{^\s*TRY}, - qr{^\s*CATCH}, - qr{^\s*BLOCK}, - qr{^\s*FILTER}, - qr{^\s*STOP}, - qr{^\s*NEXT}, -); - -sub process_tt_content { - my ($content) = @_; - my ( $use_raw, $has_use_raw ); - my @errors; - for my $line ( split "\n", $content ) { - if ( $line =~ m{\[%[^%]+%\]} ) { - - # handle exceptions first - $use_raw = 1 - if $line =~ m{|\s*\$raw}; # Is the file use the raw filter? - - # Do we have Asset without the raw filter? - if ( $line =~ m{^\s*\[% Asset} ) { - push @errors, { error => 'asset_must_be_raw', line => $line } - and next - unless $line =~ m{\|\s*\$raw}; - } - - $has_use_raw++ - if $line =~ m{\[% USE raw %\]}; # Does [% Use raw %] exist? - - # Loop on TT blocks - while ( - $line =~ m{ - \[% - (?(\s|\-|~)*) - (?[^%\-~]+) - (?(\s|\-|~)*) - %\]}gmxs - ) - { - my $tt_block = $+{tt_block}; - - # It's a TT directive, no filters needed - next if grep { $tt_block =~ $_ } @tt_directives; - - next - if $tt_block =~ m{\s?\|\s?\$KohaDates\s?$} - ; # We could escape it but should be safe - next if $tt_block =~ m{^\#}; # Is a comment, skip it - - push @errors, { error => 'missing_filter', line => $line } - if $tt_block !~ m{\|\s?\$raw} # already escaped correctly with raw - && $tt_block !~ m{=} # assignment, maybe we should require to use SET (?) - && $tt_block !~ m{\|\s?ur(l|i)} # already has url or uri filter - && $tt_block !~ m{\|\s?html} # already has html filter - && $tt_block !~ m{^(?\S+)\s+UNLESS\s+(?\S+)} # Specific for [% foo UNLESS bar %] - ; - } - } - } - - return @errors; -} - find({ wanted => \&wanted, no_chdir => 1 }, @themes ); my @errors; for my $file ( @files ) { - say $file; my $content = read_file($file); - my @e = process_tt_content($content); + my @e = t::lib::QA::TemplateFilters::missing_filters($content); push @errors, { file => $file, errors => \@e } if @e; } -- 2.11.0