diff options
Diffstat (limited to 't')
-rw-r--r-- | t/01-load.t | 4 | ||||
-rw-r--r-- | t/04-template-handling.t | 171 | ||||
-rw-r--r-- | t/98-pod-coverage.t | 3 | ||||
-rw-r--r-- | t/data/04-template.html | 2 |
4 files changed, 178 insertions, 2 deletions
diff --git a/t/01-load.t b/t/01-load.t index 60461f02..d2cde8f1 100644 --- a/t/01-load.t +++ b/t/01-load.t @@ -2,7 +2,7 @@ use strict; use warnings; -use Test::More tests => 30; +use Test::More tests => 32; use_ok('LedgerSMB'); use_ok('LedgerSMB::AA'); @@ -32,6 +32,8 @@ use_ok('LedgerSMB::RP'); use_ok('LedgerSMB::Session'); use_ok('LedgerSMB::Sysconfig'); use_ok('LedgerSMB::Tax'); +use_ok('LedgerSMB::Template'); +use_ok('LedgerSMB::Template::HTML'); use_ok('LedgerSMB::User'); SKIP: { diff --git a/t/04-template-handling.t b/t/04-template-handling.t new file mode 100644 index 00000000..8399a8b1 --- /dev/null +++ b/t/04-template-handling.t @@ -0,0 +1,171 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +$ENV{TMPDIR} = 't/var'; + +use Test::More 'no_plan'; +use Test::Trap qw(trap $trap); +use Test::Exception; + +use Error qw(:try); + +use LedgerSMB::AM; +use LedgerSMB::Form; +use LedgerSMB::Sysconfig; +use LedgerSMB::Template; +use LedgerSMB::Template::HTML; + +my @r; +my $temp; +my $form; +my $myconfig; +my $template; +my $FH; + +# AM->check_template_name checks +# check_template operates by calling $form->error if the checks fail +$form = new Form; +$myconfig = {'templates' => 'test'}; +for my $ext ('css', 'tex', 'txt', 'html', 'xml') { + $form->{file} = "test/apples.${ext}"; + @r = trap{AM->check_template_name($myconfig, $form)}; + ok(!defined $trap->die, + "AM, check_template_name: Template directory, ${ext}"); +} +$form->{file} = 'css/apples.txt'; +@r = trap{AM->check_template_name($myconfig, $form)}; +ok(!defined $trap->die, + 'AM, check_template_name: CSS directory, txt'); +$form->{file} = 'test2/apples.txt'; +@r = trap{AM->check_template_name($myconfig, $form)}; +is($trap->die, "Error: Not in a whitelisted directory: test2/apples.txt\n", + 'AM, check_template_name: Invalid directory, non-css denial'); +$form->{file} = 'test/apples.exe'; +@r = trap{AM->check_template_name($myconfig, $form)}; +is($trap->die, "Error: Error: File is of type that is not allowed.\n", + 'AM, check_template_name: Disallowed type denial'); + +# adjusting backuppath to avoid triggering directory traversal detection +$temp = ${LedgerSMB::Sysconfig::backuppath}; +${LedgerSMB::Sysconfig::backuppath} = "foo"; +$form->{file} = "${LedgerSMB::Sysconfig::backuppath}/apples.txt"; +@r = trap{AM->check_template_name($myconfig, $form)}; +is($trap->die, "Error: Not allowed to access foo/ with this method\n", + 'AM, check_template_name: Backup path denial'); +${LedgerSMB::Sysconfig::backuppath} = $temp; + +$form->{file} = "css/../apples.txt"; +@r = trap{AM->check_template_name($myconfig, $form)}; +is($trap->die, "Error: Directory transversal not allowed.\n", + 'AM, check_template_name: Directory transversal denial 1'); +$form->{file} = "/tmp/apples.txt"; +@r = trap{AM->check_template_name($myconfig, $form)}; +is($trap->die, "Error: Directory transversal not allowed.\n", + 'AM, check_template_name: Directory transversal denial 2'); +$form->{file} = "test/apples.txt:evil"; +@r = trap{AM->check_template_name($myconfig, $form)}; +is($trap->die, "Error: Directory transversal not allowed.\n", + 'AM, check_template_name: Directory transversal denial 3'); +$form->{file} = "c:\\evil.txt"; +@r = trap{AM->check_template_name($myconfig, $form)}; +is($trap->die, "Error: Directory transversal not allowed.\n", + 'AM, check_template_name: Directory transversal denial 4'); + +# AM->load_template checks +# load_template takes its file name from form +$form = new Form; +$myconfig = {'templates' => 't/data'}; +$form->{file} = 't/data/04-not-there.txt'; +@r = trap{AM->load_template($myconfig, $form)}; +is($trap->die, "Error: t/data/04-not-there.txt : No such file or directory\n", + 'AM, load_template: Die on non-existent file'); +$form->{file} = 't/data/04-template.html'; +AM->load_template($myconfig, $form); +is($form->{body}, "I am a template.\nLook at me <?lsmb login ?>.\n", + 'AM, load_template: Read existing file'); + +# AM->save_template checks +$form = new Form; +$myconfig = {'templates' => 't/var/not here'}; +$form->{body} = "I am a template.\nLook at me.\n"; +$form->{file} = "$myconfig->{templates}/test.txt"; +@r = trap{AM->save_template($myconfig, $form)}; +is($trap->die, + "Error: t/var/not here/test.txt : No such file or directory\n", + 'AM, save_template: Die on unwritable file'); +$myconfig = {'templates' => 't/var'}; +$form->{body} = "I am a template.\nLook at me."; +$form->{file} = "$myconfig->{templates}/04-template-save-test-$$.txt"; +ok(!-e $form->{file}, 'AM, save_template: Environment clean'); +AM->save_template($myconfig, $form); +ok(-e $form->{file}, 'AM, save_template: File created'); +open($FH, '<', $form->{file}); +@r = <$FH>; +close($FH); +chomp(@r); +is(join("\n", @r), $form->{body}, 'AM, save_template: Good save'); +is(unlink($form->{file}), 1, 'AM, save_template: removing testfile'); +ok(!-e $form->{file}, 'AM, save_template: testfile removed'); + +# Template->new +$myconfig = {'templates' => 't/data'}; +throws_ok{new LedgerSMB::Template('user' => $myconfig, 'language' => 'x/0')} + qr/Invalid language/, 'Template, new: Invalid language caught 1'; +throws_ok{new LedgerSMB::Template('user' => $myconfig, 'language' => '1\\2')} + qr/Invalid language/, 'Template, new: Invalid language caught 2'; +throws_ok{new LedgerSMB::Template('user' => $myconfig, 'language' => '1:2')} + qr/Invalid language/, 'Template, new: Invalid language caught 3'; +throws_ok{new LedgerSMB::Template('user' => $myconfig, 'language' => '..')} + qr/Invalid language/, 'Template, new: Invalid language caught 4'; +throws_ok{new LedgerSMB::Template('user' => $myconfig, 'language' => '.svn')} + qr/Invalid language/, + 'Template, new: Invalid language caught 5'; +$template = undef; +$template = new LedgerSMB::Template('user' => $myconfig, 'language' => 'de'); +ok(defined $template, 'Template, new: Object creation with valid language'); +isa_ok($template, 'LedgerSMB::Template', + 'Template, new: Object creation with valid language'); +is($template->{include_path}, 't/data/de;t/data', + 'Template, new: Object creation with valid language has good include_path'); +$template = undef; +$template = new LedgerSMB::Template('user' => $myconfig, 'language' => 'de', + 'path' => 't/data'); +ok(defined $template, + 'Template, new: Object creation with valid language and path'); +isa_ok($template, 'LedgerSMB::Template', + 'Template, new: Object creation with valid language and path'); +is($template->{include_path}, 't/data', + 'Template, new: Object creation with valid path overrides language'); +$template = undef; +$template = new LedgerSMB::Template('user' => $myconfig, 'format' => 'HTML', + 'template' => '04-template'); +is(LedgerSMB::Template::HTML::get_template('04-template'), '04-template.html', + 'HTML, get_template: Returned correct template file name'); +is(LedgerSMB::Template::HTML::preprocess('04-template'), '04-template', + 'HTML, preprocess: Returned simple string unchanged'); +is(LedgerSMB::Template::HTML::preprocess('14 > 12'), '14 > 12', + 'HTML, preprocess: Returned properly escaped string'); +is_deeply(LedgerSMB::Template::HTML::preprocess([0, 'apple', 'mango&durian']), + [0, 'apple', 'mango&durian'], + 'HTML, preprocess: Returned properly escaped array ref contents'); +is_deeply(LedgerSMB::Template::HTML::preprocess({'fruit' => '&veggies', + 'test' => 1}), + {'fruit' => '&veggies', 'test' => 1}, + 'HTML, preprocess: Returned properly escaped hash ref contents'); +is_deeply(LedgerSMB::Template::HTML::preprocess({'fruit' => '&veggies', + 'test' => ['nest', 'bird', '0 < 15', 1]}), + {'fruit' => '&veggies', 'test' => ['nest', 'bird', '0 < 15', 1]}, + 'HTML, preprocess: Returned properly escaped nested contents'); +is(LedgerSMB::Template::HTML::postprocess('04-template'), undef, + 'HTML, postprocess: Return undef'); +ok(defined $template, + 'Template, new: Object creation with format and template'); +isa_ok($template, 'LedgerSMB::Template', + 'Template, new: Object creation with format and template'); +is($template->{include_path}, 't/data', + 'Template, new: Object creation with format and template'); +is($template->render({'login' => 'foo'}), + "I am a template.\nLook at me foo.\n", + 'Template, render: Simple HTML template'); diff --git a/t/98-pod-coverage.t b/t/98-pod-coverage.t index f2b04717..cd1b6ef2 100644 --- a/t/98-pod-coverage.t +++ b/t/98-pod-coverage.t @@ -8,7 +8,7 @@ use strict; use warnings; -use Test::More tests => 4; +use Test::More tests => 5; use Test::More; eval "use Test::Pod::Coverage"; plan skip_all => "Test::Pod::Coverage required for testing POD coverage" if $@; @@ -17,3 +17,4 @@ pod_coverage_ok("LedgerSMB"); pod_coverage_ok("LedgerSMB::Locale"); pod_coverage_ok("LedgerSMB::Log"); pod_coverage_ok("LedgerSMB::Menufile"); +pod_coverage_ok("LedgerSMB::Template::HTML"); diff --git a/t/data/04-template.html b/t/data/04-template.html new file mode 100644 index 00000000..3b236040 --- /dev/null +++ b/t/data/04-template.html @@ -0,0 +1,2 @@ +I am a template. +Look at me <?lsmb login ?>. |