diff --git a/t/headers.t b/t/headers.t
new file mode 100644
index 00000000..3b093614
--- /dev/null
+++ b/t/headers.t
@@ -0,0 +1,44 @@
+require 't/test.pl';
+package OddMuse;
+use Test::More tests => 13;
+
+clear_pages();
+
+# without portrait-support
+
+# nothing
+update_page('headers', "== no header ==\n\ntext\n");
+test_page(get_page('headers'), '== no header ==');
+
+# usemod only
+add_module('usemod.pl');
+update_page('headers', "== is header ==\n\ntext\n");
+test_page(get_page('headers'), '
',
+ '
',
+ '
text
',
+ '', );
+remove_module('toc.pl');
+remove_rule(\&TocRule);
+remove_module('usemod.pl');
+remove_rule(\&UsemodRule);
+
+# headers only
+add_module('headers.pl');
+update_page('headers', "[new]foo\nis header\n=========\n\ntext\n");
+test_page(get_page('headers'), '
is header
');
+remove_module('headers.pl');
+remove_rule(\&HeadersRule);
+
+# portrait-support, toc, and usemod
+
+add_module('usemod.pl');
+add_module('toc.pl');
+update_page('headers', "[new]foo\n== one ==\ntext\n== two ==\ntext\n== three ==\ntext\n");
+test_page(get_page('headers'),
+ '
one',
+ '
two',
+ '
',
+ '',
+ '', );
+
+run_tests(split('\n',<<'EOT'));
+[new]\nfoo
+
+:[new]\nfoo
+
+::[new]\nfoo
+
+EOT
diff --git a/t/sidebar.t b/t/sidebar.t
new file mode 100644
index 00000000..11827bad
--- /dev/null
+++ b/t/sidebar.t
@@ -0,0 +1,69 @@
+require 't/test.pl';
+package OddMuse;
+use Test::More tests => 17;
+
+clear_pages();
+
+add_module('sidebar.pl');
+
+test_page(update_page('SideBar', 'mu'), '');
+test_page(get_page('HomePage'), '');
+
+# with toc
+
+add_module('toc.pl');
+add_module('usemod.pl');
+
+AppendStringToFile($ConfigFile, "\$TocAutomatic = 0;\n");
+
+update_page('SideBar', "bla\n\n"
+ . "== mu ==\n\n"
+ . "bla");
+
+test_page(update_page('test', "bla\n"
+ . "
\n"
+ . "murks\n"
+ . "==two=\n"
+ . "bla\n"
+ . "===three==\n"
+ . "bla\n"
+ . "=one=\n"),
+ quotemeta('- two
- three
- one
'),
+ quotemeta(''),
+ quotemeta('two
'),
+ quotemeta('one
'),
+ quotemeta('bla murks'));
+
+update_page('SideBar', "");
+test_page(update_page('test', "bla\n"
+ . "murks\n"
+ . "==two=\n"
+ . "bla\n"
+ . "===three==\n"
+ . "bla\n"
+ . "=one=\n"),
+ quotemeta('- two
- three
- one
'),
+ quotemeta('two
'),
+ quotemeta('one
'),
+ quotemeta(''));
+
+remove_rule(\&TocRule);
+remove_rule(\&UsemodRule);
+
+# with forms
+
+add_module('forms.pl');
+
+test_page(update_page('SideBar', '
'),
+ '');
+xpath_test(get_page('action=pagelock id=SideBar set=1 pwd=foo'),
+ '//p/text()[string()="Lock for "]/following-sibling::a[@href="http://localhost/wiki.pl/SideBar"][@class="local"][text()="SideBar"]/following-sibling::text()[string()=" created."]');
+test_page(get_page('SideBar'), '');
+# While rendering the SideBar as part of the HomePage, it should still
+# be considered "locked", and therefore the form should render
+# correctly.
+test_page(get_page('HomePage'),
+ '');
+# test_page(get_page('HomePage'), '');
diff --git a/t/toc.t b/t/toc.t
new file mode 100644
index 00000000..a05d3d45
--- /dev/null
+++ b/t/toc.t
@@ -0,0 +1,94 @@
+require 't/test.pl';
+package OddMuse;
+use Test::More tests => 22;
+
+clear_pages();
+
+add_module('toc.pl');
+add_module('usemod.pl');
+
+InitVariables(); # do this after loading usemod.pl!
+
+run_tests(split('\n',<<'EOT'));
+== make honey ==\n\nMoo.\n
+
make honey
Moo.
+EOT
+
+test_page(update_page('toc', "bla\n"
+ . "=one=\n"
+ . "blarg\n"
+ . "==two==\n"
+ . "bla\n"
+ . "==two==\n"
+ . "mu."),
+ quotemeta('
- one
- two
- two
'),
+ quotemeta('
one
'),
+ quotemeta('
two
'),
+ quotemeta('bla
one
'),);
+
+test_page(update_page('toc', "bla\n"
+ . "==two=\n"
+ . "bla\n"
+ . "===three==\n"
+ . "bla\n"
+ . "==two==\n"),
+ quotemeta('
- two
- three
- two
'),
+ quotemeta('
two
'),
+ quotemeta('
three
'));
+
+test_page(update_page('toc', "bla\n"
+ . "
\n"
+ . "murks\n"
+ . "==two=\n"
+ . "bla\n"
+ . "===three==\n"
+ . "bla\n"
+ . "=one=\n"),
+ quotemeta('- two
- three
- one
'),
+ quotemeta('two
'),
+ quotemeta('one
'),
+ quotemeta('bla murks'),);
+
+test_page(update_page('toc', "bla\n"
+ . "=one=\n"
+ . "blarg\n"
+ . "==two==\n"
+ . "bla\n"
+ . "==two==\n"
+ . "mu.\n"
+ . "bla\n"
+ . "==two==\n"
+ . "mu.\n"
+ . "yadda bla\n"
+ . "==two==\n"
+ . "mu.\n"
+ . "yadda
has no effect! \n"
+ . "##bla\n"
+ . "==three==\n"
+ . "mu.##\n"
+ . "=one=\n"
+ . "blarg
\n"),
+ quotemeta('- one
- two
- three
- one
'),
+ quotemeta('one
'),
+ quotemeta('two
'),
+ quotemeta('three
'),
+ quotemeta('one
'),);
+
+add_module('markup.pl');
+
+test_page(update_page('toc', "bla\n"
+ . "=one=\n"
+ . "blarg\n"
+ . "bla\n"
+ . "=two=\n"
+ . "mu.\n"
+ . "##bla\n"
+ . "=three=\n"
+ . "mu.##\n"
+ . "=four=\n"
+ . "blarg\n"),
+ quotemeta('- one
- four
'),
+ quotemeta('one
'),
+ quotemeta('four
'),);