summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/01-load.t4
-rw-r--r--t/04-template-handling.t171
-rw-r--r--t/98-pod-coverage.t3
-rw-r--r--t/data/04-template.html2
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 &gt; 12',
+ 'HTML, preprocess: Returned properly escaped string');
+is_deeply(LedgerSMB::Template::HTML::preprocess([0, 'apple', 'mango&durian']),
+ [0, 'apple', 'mango&amp;durian'],
+ 'HTML, preprocess: Returned properly escaped array ref contents');
+is_deeply(LedgerSMB::Template::HTML::preprocess({'fruit' => '&veggies',
+ 'test' => 1}),
+ {'fruit' => '&amp;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' => '&amp;veggies', 'test' => ['nest', 'bird', '0 &lt; 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 ?>.