t: Consistently remove temp directory before testing, not after
[ikiwiki] / t / passwordauth.t
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4
5 use Cwd qw(getcwd);
6 use Test::More;
7
8 BEGIN {
9         plan(skip_all => "Authen::Passphrase not available")
10                 unless eval q{
11                         use Authen::Passphrase qw();
12                         1;
13                 };
14
15         plan(skip_all => "CGI not available")
16                 unless eval q{
17                         use CGI qw();
18                         1;
19                 };
20
21         plan(skip_all => "IPC::Run not available")
22                 unless eval q{
23                         use IPC::Run qw(run);
24                         1;
25                 };
26
27         use_ok('IkiWiki');
28         use_ok('IkiWiki::Plugin::passwordauth');
29         use_ok('IkiWiki::Setup');
30         use_ok('IkiWiki::UserInfo');
31         use_ok('YAML::XS');
32 }
33
34 # We check for English messages
35 $ENV{LC_ALL} = 'C';
36
37 my $installed = $ENV{INSTALLED_TESTS};
38
39 my @command;
40 if ($installed) {
41         @command = qw(ikiwiki);
42 }
43 else {
44         ok(! system("make -s ikiwiki.out"));
45         @command = ("perl", "-I".getcwd."/blib/lib", './ikiwiki.out',
46                 '--underlaydir='.getcwd.'/underlays/basewiki',
47                 '--set', 'underlaydirbase='.getcwd.'/underlays',
48                 '--templatedir='.getcwd.'/templates');
49 }
50
51 sub write_setup_file {
52         my %setup = (
53                 wikiname => 'this is the name of my wiki',
54                 srcdir => getcwd.'/t/tmp/in',
55                 destdir => getcwd.'/t/tmp/out',
56                 url => 'http://example.com',
57                 cgiurl => 'http://example.com/cgi-bin/ikiwiki.cgi',
58                 cgi_wrapper => getcwd.'/t/tmp/ikiwiki.cgi',
59                 cgi_wrappermode => '0751',
60                 add_plugins => [qw(anonok attachment lockedit passwordauth recentchanges)],
61                 adminuser => [qw(alice)],
62                 disable_plugins => [qw(emailauth openid)],
63                 locked_pages => '*',
64         );
65         unless ($installed) {
66                 $setup{ENV} = { 'PERL5LIB' => getcwd.'/blib/lib' };
67         }
68         writefile("test.setup", "t/tmp",
69                 "# IkiWiki::Setup::Yaml - YAML formatted setup file\n" .
70                 Dump(\%setup));
71         %IkiWiki::config = IkiWiki::defaultconfig();
72         IkiWiki::Setup::load("t/tmp/test.setup");
73         IkiWiki::loadplugins();
74         IkiWiki::checkconfig();
75 }
76
77 sub thoroughly_rebuild {
78         ok(unlink("t/tmp/ikiwiki.cgi") || $!{ENOENT});
79         ok(unlink("t/tmp/in/.git/hooks/post-commit") || $!{ENOENT});
80         ok(! system(@command, qw(--setup t/tmp/test.setup --rebuild --wrappers)));
81 }
82
83 sub run_cgi {
84         my (%args) = @_;
85         my ($in, $out);
86         my $method = $args{method} || 'GET';
87         my $environ = $args{environ} || {};
88         my $params = $args{params} || { do => 'prefs' };
89
90         my %defaults = (
91                 SCRIPT_NAME     => '/cgi-bin/ikiwiki.cgi',
92                 HTTP_HOST       => 'example.com',
93         );
94
95         my $cgi = CGI->new($args{params});
96         my $query_string = $cgi->query_string();
97
98         if ($method eq 'POST') {
99                 $defaults{REQUEST_METHOD} = 'POST';
100                 $in = $query_string;
101                 $defaults{CONTENT_LENGTH} = length $in;
102         } else {
103                 $defaults{REQUEST_METHOD} = 'GET';
104                 $defaults{QUERY_STRING} = $query_string;
105         }
106
107         my %envvars = (
108                 %defaults,
109                 %$environ,
110         );
111         print("# $query_string\n");
112         run(["./t/tmp/ikiwiki.cgi"], \$in, \$out, init => sub {
113                 map {
114                         $ENV{$_} = $envvars{$_}
115                 } keys(%envvars);
116         });
117
118         return $out;
119 }
120
121 sub test_prefs {
122         my $content;
123         my $status;
124
125         IkiWiki::userinfo_setall('alice', {regdate => time, email => 'alice@example.com'});
126         IkiWiki::userinfo_setall('bob', {regdate => time, email => 'bob@example.com'});
127         IkiWiki::userinfo_setall('name', {regdate => time, email => 'nobody@example.com'});
128         IkiWiki::Plugin::passwordauth::setpassword('alice', "Alice's password");
129         IkiWiki::Plugin::passwordauth::setpassword('bob', "Bob's password");
130
131         $content = run_cgi(
132                 params => {
133                         do => 'prefs',
134                 },
135         );
136
137         # prefs requires signing in so we are redirected, with the postsignin
138         # action saved in the session
139         like($content, qr/<form .*name="signin"/);
140
141         # remember the cookie so we can continue to act in that session
142         my ($cookie) = ($content =~ m/^Set-Cookie: (.*)$/im);
143
144         # sign in
145         $content = run_cgi(
146                 environ => {
147                         HTTP_COOKIE => $cookie,
148                 },
149                 params => {
150                         do => 'signin',
151                         name => 'bob',
152                         password => "Bob's password",
153                         _submit => 'Login',
154                         _submitted_signin => '1',
155                 },
156         );
157
158         # We are signed-in as bob now
159         like($content, qr{page=bob.*Create your user page});
160         like($content, qr{<input.*name="name".*value="bob"});
161         like($content, qr{<input.*name="email".*value="bob\@example.com"});
162 }
163
164 sub test_formbuilder_disaster {
165         my $content;
166         my $status;
167
168         ok(! system(qw(rm -rf t/tmp)));
169         ok(! system(qw(mkdir t/tmp)));
170         ok(! system(qw(mkdir t/tmp/in)));
171
172         write_setup_file();
173         thoroughly_rebuild();
174
175         IkiWiki::userinfo_setall('alice', {regdate => time, email => 'alice@example.com'});
176         IkiWiki::userinfo_setall('bob', {regdate => time, email => 'bob@example.com'});
177         IkiWiki::userinfo_setall('name', {regdate => time, email => 'nobody@example.com'});
178         IkiWiki::Plugin::passwordauth::setpassword('alice', "Alice's password");
179         IkiWiki::Plugin::passwordauth::setpassword('bob', "Bob's password");
180
181         $content = run_cgi(
182                 params => {
183                         do => 'prefs',
184                 },
185         );
186
187         # prefs requires signing in so we are redirected, with the postsignin
188         # action saved in the session
189         like($content, qr/<form .*name="signin"/);
190
191         # remember the cookie so we can continue to act in that session
192         my ($cookie) = ($content =~ m/^Set-Cookie: (.*)$/im);
193
194         # sign in
195         $content = run_cgi(
196                 environ => {
197                         HTTP_COOKIE => $cookie,
198                 },
199                 params => {
200                         do => 'signin',
201                         name => ['bob', 'name', 'alice'],
202                         password => "Bob's password",
203                         _submit => 'Login',
204                         _submitted_signin => '1',
205                 },
206         );
207
208         like($content, qr{page=bob.*Create your user page});
209         like($content, qr{<input.*name="name".*value="bob"});
210         like($content, qr{<input.*name="email".*value="bob\@example.com"});
211
212         unlike($content, qr{alice});
213 }
214
215 ok(! system(qw(rm -rf t/tmp)));
216 ok(! system(qw(mkdir t/tmp)));
217 ok(! system(qw(mkdir t/tmp/in)));
218
219 write_setup_file();
220 thoroughly_rebuild();
221
222 test_prefs();
223 test_formbuilder_disaster();
224
225 done_testing();