summaryrefslogtreecommitdiff
path: root/t/10-form.t
blob: 0920d0584e9d311eaae0a6c0c0c45b190169df07 (plain)
  1. #!/usr/bin/perl
  2. ##format_amount in 02-number-handling.t
  3. ##parse_amount in 02-number-handling.t
  4. ##round_amount in 02-number-handling.t
  5. ##current_date in 03-date-handling.t
  6. ##split_date in 03-date-handling.t
  7. ##format_date in 03-date-handling.t
  8. ##from_to in 03-date-handling.t
  9. ##datetonum in 03-date-handling.t
  10. ##add_date in 03-date-handling.t
  11. ##escape in 10-form.t
  12. ##unescape in 10-form.t
  13. ##quote in 10-form.t
  14. ##unquote in 10-form.t
  15. ##numtextrows in 10-form.t
  16. ##debug in 10-form.t
  17. ##hide_form in 10-form.t
  18. ##info in 10-form.t
  19. ##error in 10-form.t
  20. ##isblank in 10-form.t
  21. ##header in 10-form.t
  22. ##sort_columns in 10-form.t
  23. ##sort_order in 10-form.t
  24. ##print_button in 10-form.t
  25. ##encode_all null
  26. ##decode_all null
  27. ##sub new {
  28. ##sub dberror {
  29. ##sub redirect {
  30. ##sub db_parse_numeric {
  31. ##sub callproc {
  32. ##sub get_my_emp_num {
  33. ##sub parse_template {
  34. ##sub format_line {
  35. ##sub cleanup {
  36. ##sub rerun_latex {
  37. ##sub format_string {
  38. ##sub db_init {
  39. ##sub run_custom_queries {
  40. ##sub dbconnect {
  41. ##sub dbconnect_noauto {
  42. ##sub dbquote {
  43. ##sub update_balance {
  44. ##sub update_exchangerate {
  45. ##sub save_exchangerate {
  46. ##sub get_exchangerate {
  47. ##sub check_exchangerate {
  48. ##sub add_shipto {
  49. ##sub get_employee {
  50. ##sub get_name {
  51. ##sub all_vc {
  52. ##sub all_taxaccounts {
  53. ##sub all_employees {
  54. ##sub all_projects {
  55. ##sub all_departments {
  56. ##sub all_years {
  57. ##sub create_links {
  58. ##sub lastname_used {
  59. ##sub like {
  60. ##sub redo_rows {
  61. ##sub get_partsgroup {
  62. ##sub update_status {
  63. ##sub save_status {
  64. ##sub get_recurring {
  65. ##sub save_recurring {
  66. ##sub save_intnotes {
  67. ##sub update_defaults {
  68. ##sub db_prepare_vars {
  69. ##sub audittrail {
  70. use strict;
  71. use warnings;
  72. use Test::More;
  73. plan skip_all => 'Trap tests could crash Perl on Windows' if $^O eq 'MSWin32';
  74. eval "use Test::Trap";
  75. plan skip_all => 'Test::Trap required for testing Form functions' if $@;
  76. use Test::Trap qw(trap $trap);
  77. plan 'no_plan';
  78. use Math::BigFloat;
  79. use IO::String;
  80. use LedgerSMB::Form;
  81. $ENV{TMPDIR} = "t/var";
  82. sub form_info_func {
  83. return $_[0];
  84. }
  85. sub form_error_func {
  86. print $_[0];
  87. }
  88. sub redirect {
  89. print "redirected\n";
  90. }
  91. my $form = new Form;
  92. my %myconfig;
  93. my $utfstr;
  94. my @r;
  95. my @ary;
  96. my $aryref;
  97. ok(defined $form);
  98. isa_ok($form, 'Form');
  99. ## $form->escape checks
  100. $utfstr = "\xd8\xad";
  101. utf8::decode($utfstr);
  102. for my $sig ('1.3.37', '2.2.4', '2.0.59') {
  103. $ENV{SERVER_SIGNATURE} = 'Apache/'.$sig;
  104. cmp_ok($form->escape('foo'), 'eq', 'foo',
  105. "($sig) escape: foo");
  106. cmp_ok($form->escape('foo bar'), 'eq', 'foo%20bar',
  107. "($sig) escape: foo bar");
  108. cmp_ok($form->escape($utfstr), 'eq', '%d8%ad',
  109. "($sig) escape: U+D8AD");
  110. }
  111. $ENV{SERVER_SIGNATURE} = 'Apache/2.0.22';
  112. cmp_ok($form->escape('foo'), 'eq', 'foo',
  113. '(2.0.22) escape: foo');
  114. cmp_ok($form->escape('foo bar'), 'eq', 'foo%2520bar',
  115. '(2.0.22) escape: foo bar');
  116. cmp_ok($form->escape($utfstr), 'eq', '%25d8%25ad',
  117. '(2.0.22) escape: U+D8AD');
  118. cmp_ok($form->escape('foo%20bar', 1), 'eq', 'foo%2520bar',
  119. '(2.0.22, been) escape: foo bar');
  120. ## $form->unescape checks
  121. $utfstr = "\xd8\xad";
  122. utf8::decode($utfstr);
  123. cmp_ok($form->unescape('+'), 'eq', ' ', 'unescape: +');
  124. cmp_ok($form->unescape('\\'), 'eq', '', 'unescape: \\');
  125. cmp_ok($form->unescape('%20'), 'eq', ' ', 'unescape: %20');
  126. cmp_ok($form->unescape("foo\r\n"), 'eq', "foo\n", 'unescape: foo\r\n');
  127. ok(utf8::is_utf8($form->unescape('foo%d8%ad')), 'unescape: (utf8 output)');
  128. cmp_ok(unpack("H*", $form->unescape('%d8%ad')), 'eq',
  129. unpack("H*", $utfstr), 'unescape: %d8%ad');
  130. cmp_ok(unpack("H*", $form->unescape($form->unescape('%d8%ad'))), 'eq',
  131. unpack("H*", $utfstr), '(2x) unescape: %d8%ad');
  132. ## $form->quote checks
  133. ok(!defined $form->quote(), 'quote: (undef)');
  134. cmp_ok($form->quote(\%myconfig), '==', \%myconfig, 'quote: (reference)');
  135. cmp_ok($form->quote('hello'), 'eq', 'hello', 'quote: hello');
  136. cmp_ok($form->quote('hello"world'), 'eq', 'hello"world',
  137. 'quote: hello"world');
  138. ## $form->unquote checks
  139. ok(!defined $form->unquote(), 'unquote: (undef)');
  140. cmp_ok($form->unquote(\%myconfig), '==', \%myconfig, 'unquote: (reference)');
  141. cmp_ok($form->unquote('hello'), 'eq', 'hello', 'unquote: hello');
  142. cmp_ok($form->unquote('hello"world'), 'eq', 'hello"world',
  143. 'unquote: hello"world');
  144. ## $form->numtextrows checks
  145. cmp_ok($form->numtextrows("hello world\n12345678901234567890\n", 20), '==', 2,
  146. 'numtextrows: 2 rows');
  147. cmp_ok($form->numtextrows("hello world12345678901234567890\n", 20), '==', 2,
  148. 'numtextrows: 2 rows (no space)');
  149. cmp_ok($form->numtextrows("hello world\n12345678901234567890\n", 20, 1), '==', 1,
  150. 'numtextrows: 2 rows (1 max)');
  151. cmp_ok($form->numtextrows("hello world\n12345678901234567890\n", 20, 3), '==', 2,
  152. 'numtextrows: 2 rows (3 max)');
  153. ## $form->debug checks
  154. $form = new Form;
  155. @r = trap{$form->debug};
  156. like($trap->stdout, qr/\naction = \ndbversion = \d+\.\d+\.\d+\nlogin = \nnextsub = \npath = bin\/mozilla\nversion = \d+\.\d+\.\d+\n/, 'debug: STDOUT');
  157. SKIP: {
  158. skip 'Environment for file test not clean' if -f "t/lsmb-10.$$";
  159. $form->debug("t/lsmb-10.$$");
  160. ok(-f "t/lsmb-10.$$", "debug: output file t/lsmb-10.$$ created");
  161. open(my $FH, '<', "t/lsmb-10.$$");
  162. my @str = <$FH>;
  163. close($FH);
  164. chomp(@str);
  165. like(join("\n", @str), qr/action = \ndbversion = \d+\.\d+\.\d+\nlogin = \nnextsub = \npath = bin\/mozilla\nversion = \d+\.\d+\.\d+/, "debug: t/lsmb-10.$$ contents");
  166. is(unlink("t/lsmb-10.$$"), 1, "debug: removing t/lsmb-10.$$");
  167. ok(!-e "t/lsmb-10.$$", "debug: t/lsmb-10.$$ removed");
  168. };
  169. ## $form->hide_form checks
  170. $form = new Form;
  171. $form->{header} = 1;
  172. @r = trap{$form->hide_form};
  173. like($trap->stdout, qr/<input type="hidden" name="action" value="" \/>\n<input type="hidden" name="dbversion" value="\d+\.\d+\.\d+" \/>\n<input type="hidden" name="login" value="" \/>\n<input type="hidden" name="nextsub" value="" \/>\n<input type="hidden" name="path" value="bin\/mozilla" \/>\n<input type="hidden" name="version" value="1.2.5" \/>/,
  174. 'hide_form: base');
  175. ok(!$form->{header}, 'hide_form: header flag cleared');
  176. $form->{header} = 1;
  177. @r = trap{$form->hide_form('path')};
  178. is($trap->stdout, "<input type=\"hidden\" name=\"path\" value=\"bin/mozilla\" />\n",
  179. 'hide_form: path');
  180. ok($form->{header}, 'hide_form: header flag not cleared');
  181. ## $form->info checks
  182. $form = new Form;
  183. $ENV{GATEWAY_INTERFACE} = 'yes';
  184. $form->{pre} = 'Blah';
  185. $form->{header} = 'Blah';
  186. @r = trap{$form->info('hello world')};
  187. is($trap->stdout, '<b>hello world</b>',
  188. 'info: CGI, pre-set header content');
  189. ok(!$form->{pre}, 'info: CGI, removed $self->{pre}');
  190. delete $form->{header};
  191. @r = trap{$form->info('hello world')};
  192. like($trap->stdout, qr|Content-Type: text/html; charset=utf-8\n\n+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n\s+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head>\n\s+<title></title>\n\s+<meta http-equiv="Pragma" content="no-cache" />\n\s+<meta http-equiv="Expires" content="-1" />\n\s+<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />[\n\s]+<meta http-equiv="content-type" content="text/html; charset=utf-8" />[\n\s]+<meta name="robots" content="noindex,nofollow" />[\n\s]+</head>[\n\s]+<body><b>hello world</b>|,
  193. 'info: CGI, header content');
  194. delete $ENV{GATEWAY_INTERFACE};
  195. delete $ENV{info_function};
  196. $form->{pre} = 'Blah';
  197. $form->{header} = 'Blah';
  198. @r = trap{$form->info('hello world')};
  199. is($trap->stdout, "hello world\n",
  200. 'info: CLI, content');
  201. ok($form->{pre}, 'info: CLI, ignored $self->{pre}');
  202. $ENV{info_function} = 'main::form_info_func';
  203. SKIP: {
  204. skip 'Environment variable info_function could not be set' unless
  205. $ENV{info_function} eq 'main::form_info_func';
  206. is($form->info('hello world'), 'hello world',
  207. 'info: CLI, function call');
  208. };
  209. delete $ENV{info_function};
  210. ## $form->error checks
  211. $form = new Form;
  212. $ENV{GATEWAY_INTERFACE} = 'yes';
  213. $form->{pre} = 'Blah';
  214. $form->{header} = 'Blah';
  215. @r = trap{$form->error('hello world')};
  216. is($trap->exit, 0,
  217. 'error: CGI, normal termination');
  218. is($trap->stdout, '<body><h2 class="error">Error!</h2> <p><b>hello world</b></body>',
  219. 'error: CGI, pre-set header content');
  220. ok(!$form->{pre}, 'error: CGI, removed $self->{pre}');
  221. delete $form->{header};
  222. @r = trap{$form->error('hello world')};
  223. is($trap->exit, 0,
  224. 'error: CGI, normal termination');
  225. like($trap->stdout, qr|Content-Type: text/html; charset=utf-8\n\n+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n\s+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head>\n\s+<title></title>\n\s+<meta http-equiv="Pragma" content="no-cache" />\n\s+<meta http-equiv="Expires" content="-1" />\n\s+<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />[\n\s]+<meta http-equiv="content-type" content="text/html; charset=utf-8" />[\n\s]+<meta name="robots" content="noindex,nofollow" />[\n\s]+</head>[\n\s]+<body><h2 class="error">Error!</h2> <p><b>hello world</b></body>|,
  226. 'error: CGI, header content');
  227. delete $ENV{GATEWAY_INTERFACE};
  228. delete $ENV{error_function};
  229. $form->{pre} = 'Blah';
  230. $form->{header} = 'Blah';
  231. @r = trap{$form->error('hello world')};
  232. is($trap->die, "Error: hello world\n",
  233. 'error: CLI, content, terminated');
  234. ok($form->{pre}, 'error: CLI, ignored $self->{pre}');
  235. $ENV{error_function} = 'main::form_error_func';
  236. SKIP: {
  237. skip 'Environment variable error_function could not be set' unless
  238. $ENV{error_function} eq 'main::form_error_func';
  239. @r = trap{$form->error('hello world')};
  240. is($trap->stdout, 'hello world',
  241. 'error: CLI, function call called');
  242. is($trap->die, "Error: hello world\n",
  243. 'error: CLI, function call termination');
  244. };
  245. ## $form->isblank checks
  246. $form = new Form;
  247. $ENV{GATEWAY_INTERFACE} = 'yes';
  248. $form->{header} = 'yes';
  249. $form->{blank} = ' ';
  250. ok(!$form->isblank('version'), 'isblank: Not blank');
  251. @r = trap{$form->isblank('blank', 'hello world')};
  252. is($trap->stdout, '<body><h2 class="error">Error!</h2> <p><b>hello world</b></body>',
  253. 'isblank: Blank');
  254. is($trap->exit, 0,
  255. 'isblank: Blank, termination');
  256. ## $form->header checks
  257. $form = new Form;
  258. $form->{header} = 'yes';
  259. ok(!$form->header, 'header: preset');
  260. $ENV{GATEWAY_INTERFACE} = 'yes';
  261. delete $form->{header};
  262. delete $form->{stylesheet};
  263. delete $form->{charset};
  264. delete $form->{titlebar};
  265. delete $form->{title};
  266. delete $form->{pre};
  267. @r = trap{$form->header};
  268. like($trap->stdout, qr|Content-Type: text/html; charset=utf-8\n\n+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n\s+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head>\n\s+<title></title>\n\s+<meta http-equiv="Pragma" content="no-cache" />\n\s+<meta http-equiv="Expires" content="-1" />\n\s+<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />[\n\s]+<meta http-equiv="content-type" content="text/html; charset=utf-8" />[\n\s]+<meta name="robots" content="noindex,nofollow" />[\n\s]+</head>[\n\s]+|,
  269. 'header: unset');
  270. delete $form->{header};
  271. @r = trap{$form->header(1, 'hello world')};
  272. like($trap->stdout, qr|Content-Type: text/html; charset=utf-8\n\n+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n\s+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head>\n\s+<title></title>\n\s+<meta http-equiv="Pragma" content="no-cache" />\n\s+<meta http-equiv="Expires" content="-1" />\n\s+<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />[\n\s]+<meta http-equiv="content-type" content="text/html; charset=utf-8" />[\n\s]+<meta name="robots" content="noindex,nofollow" />[\n\s]+hello world[\n\s]+</head>[\n\s]+|,
  273. 'header: headeradd');
  274. delete $form->{header};
  275. $form->{pre} = 'hello world';
  276. @r = trap{$form->header};
  277. like($trap->stdout, qr|Content-Type: text/html; charset=utf-8\n\n+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n\s+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head>\n\s+<title></title>\n\s+<meta http-equiv="Pragma" content="no-cache" />\n\s+<meta http-equiv="Expires" content="-1" />\n\s+<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />[\n\s]+<meta http-equiv="content-type" content="text/html; charset=utf-8" />[\n\s]+<meta name="robots" content="noindex,nofollow" />[\n\s]+</head>[\n\s]+hello world \n|,
  278. 'header: pre => \'hello world\'');
  279. delete $form->{pre};
  280. delete $form->{header};
  281. $form->{titlebar} = 'hello';
  282. @r = trap{$form->header};
  283. like($trap->stdout, qr|Content-Type: text/html; charset=utf-8\n\n+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n\s+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head>\n\s+<title>hello</title>\n\s+<meta http-equiv="Pragma" content="no-cache" />\n\s+<meta http-equiv="Expires" content="-1" />\n\s+<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />[\n\s]+<meta http-equiv="content-type" content="text/html; charset=utf-8" />[\n\s]+<meta name="robots" content="noindex,nofollow" />[\n\s]+</head>[\n\s]+|,
  284. 'header: titlebar => \'hello\'');
  285. delete $form->{header};
  286. $form->{title} = 'world';
  287. @r = trap{$form->header};
  288. like($trap->stdout, qr|Content-Type: text/html; charset=utf-8\n\n+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n\s+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head>\n\s+<title>world - hello</title>\n\s+<meta http-equiv="Pragma" content="no-cache" />\n\s+<meta http-equiv="Expires" content="-1" />\n\s+<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />[\n\s]+<meta http-equiv="content-type" content="text/html; charset=utf-8" />[\n\s]+<meta name="robots" content="noindex,nofollow" />[\n\s]+</head>[\n\s]+|,
  289. 'header: titlebar => \'hello\', title => \'world\'');
  290. delete $form->{title};
  291. delete $form->{titlebar};
  292. delete $form->{header};
  293. $form->{charset} = 'UTF-8';
  294. @r = trap{$form->header};
  295. like($trap->stdout, qr|Content-Type: text/html; charset=utf-8\n\n+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n\s+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head>\n\s+<title></title>\n\s+<meta http-equiv="Pragma" content="no-cache" />\n\s+<meta http-equiv="Expires" content="-1" />\n\s+<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />[\n\s]+<meta http-equiv="content-type" content="text/html; charset=UTF-8" />[\n\s]+<meta name="robots" content="noindex,nofollow" />[\n\s]+</head>[\n\s]+|,
  296. 'header: charset => \'UTF-8\'');
  297. delete $form->{charset};
  298. delete $form->{header};
  299. $form->{stylesheet} = "not a real file.$$";
  300. @r = trap{$form->header};
  301. like($trap->stdout, qr|Content-Type: text/html; charset=utf-8\n\n+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n\s+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head>\n\s+<title></title>\n\s+<meta http-equiv="Pragma" content="no-cache" />\n\s+<meta http-equiv="Expires" content="-1" />\n\s+<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />[\n\s]+<meta http-equiv="content-type" content="text/html; charset=utf-8" />[\n\s]+<meta name="robots" content="noindex,nofollow" />[\n\s]+</head>[\n\s]+|,
  302. "header: stylesheet => 'not a real file.$$'");
  303. delete $form->{header};
  304. $form->{stylesheet} = 'ledger-smb.css';
  305. @r = trap{$form->header};
  306. like($trap->stdout, qr|Content-Type: text/html; charset=utf-8\n\n+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \n\s+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head>\n\s+<title></title>\n\s+<meta http-equiv="Pragma" content="no-cache" />\n\s+<meta http-equiv="Expires" content="-1" />\n\s+<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />[\n\s]+<link rel="stylesheet" href="css/ledger-smb.css" type="text/css" title="LedgerSMB stylesheet" />[\n\s]+<meta http-equiv="content-type" content="text/html; charset=utf-8" />[\n\s]+<meta name="robots" content="noindex,nofollow" />[\n\s]+</head>[\n\s]+|,
  307. 'header: stylesheet => \'ledgersmb.css\'');
  308. delete $ENV{GATEWAY_INTERFACE};
  309. delete $form->{header};
  310. is($form->header, 1, 'header: non-CGI');
  311. is($form->{header}, 1, 'header: non-CGI header flag set');
  312. ## $form->sort_column checks
  313. ## Note that sort_column merely sorts the value of $form->{sort} to being the
  314. ## first element of the list, adding it if needed
  315. $form = new Form;
  316. @ary = ('projectnumber', 'description', 'name', 'startdate');
  317. $form->{sort} = 'name';
  318. is_deeply([$form->sort_columns(@ary)],
  319. ['name', 'projectnumber', 'description', 'startdate'],
  320. 'sort_column: sort name');
  321. $form->{sort} = 'apple';
  322. is_deeply([$form->sort_columns(@ary)], ['apple', @ary],
  323. 'sort_column: sort non-existent');
  324. is($form->sort_columns, 0,
  325. 'sort_column: sort, no columns');
  326. delete $form->{sort};
  327. is_deeply([$form->sort_columns(@ary)], \@ary,
  328. 'sort_column: sort unset');
  329. ## $form->sort_order checks
  330. ## Note that $ordinal is intended to be a hashref mapping column names to
  331. ## position
  332. $form = new Form;
  333. $aryref = ['projectnumber', 'description', 'name', 'startdate'];
  334. delete $form->{direction};
  335. delete $form->{sort};
  336. delete $form->{oldsort};
  337. is($form->sort_order($aryref),
  338. 'projectnumber ASC,description,name,startdate',
  339. 'sort_order: unset, no ordinal');
  340. is($form->{direction}, 'ASC', 'sort_order: unset direction ASC');
  341. $form->{direction} = 'ASC';
  342. delete $form->{sort};
  343. delete $form->{oldsort};
  344. is($form->sort_order($aryref),
  345. 'projectnumber DESC,description,name,startdate',
  346. 'sort_order: direction => \'ASC\', no ordinal');
  347. is($form->{direction}, 'DESC', 'sort_order: ASC -> DESC, sort unset');
  348. $form->{direction} = 'DESC';
  349. delete $form->{sort};
  350. delete $form->{oldsort};
  351. is($form->sort_order($aryref),
  352. 'projectnumber ASC,description,name,startdate',
  353. 'sort_order: direction => \'DESC\', no ordinal');
  354. is($form->{direction}, 'ASC', 'sort_order: DESC -> ASC, sort unset');
  355. $form->{direction} = 'DESC';
  356. $form->{sort} = 'name';
  357. $form->{oldsort} = 'startdate';
  358. is($form->sort_order($aryref),
  359. 'name DESC,projectnumber,description,startdate',
  360. 'sort_order: direction => \'DESC\', sort => \'name\', no ordinal');
  361. is($form->{direction}, 'DESC', 'sort_order: DESC -/-> ASC, sort != oldsort');
  362. $form->{direction} = 'DESC';
  363. $form->{sort} = 'name';
  364. $form->{oldsort} = 'startdate';
  365. is($form->sort_order($aryref, {name => 2, projectnumber => 3, startdate => 1}),
  366. '2 DESC,3,description,1',
  367. 'sort_order: direction => \'DESC\', sort => \'name\', ordinal');
  368. $form->{direction} = 'DESC';
  369. $form->{sort} = 'name';
  370. $form->{oldsort} = 'startdate';
  371. is($form->sort_order($aryref, {name => 0, projectnumber => 3, startdate => 1}),
  372. 'name DESC,3,description,1',
  373. 'sort_order: direction => \'DESC\', sort => \'name\', ordinal b');
  374. ## $form->print_button checks
  375. $form = new Form;
  376. @r = trap{$form->print_button({'pear' => {'key' => 'P', 'value' => 'Pears'}}, 'pear')};
  377. is($trap->stdout, "<button class=\"submit\" type=\"submit\" name=\"action\" value=\"pear\" accesskey=\"P\" title=\"Pears [Alt-P]\">Pears</button>\n", 'print_button');
  378. ## $form->like checks
  379. $form = new Form;
  380. is($form->like('hello world'), '%hello world%', 'like');
  381. ## $form->redirect checks
  382. $form = new Form;
  383. ok(!defined $form->{callback}, 'redirect: No callback set');
  384. @r = trap{$form->redirect};
  385. is($trap->stdout, "redirected\n", 'redirect: No message or callback redirect');
  386. @r = trap{$form->redirect('hello world')};
  387. is($trap->stdout, "hello world\n",
  388. 'redirect: message, no callback redirect');
  389. $form->{callback} = 1;
  390. @r = trap{$form->redirect};
  391. is($trap->stdout, "redirected\n", 'redirect: callback, no message redirect');
  392. @r = trap{$form->redirect("hello world\n")};
  393. is($trap->stdout, "redirected\n", 'redirect: callback and message redirect');