11 plan(skip_all => 'git not available') unless -x $git;
13 plan(skip_all => "IPC::Run not available")
15 use IPC::Run qw(run start);
23 # We check for English error messages
29 my $installed = $ENV{INSTALLED_TESTS};
30 my $tmp = File::Temp->newdir(CLEANUP => 0);
34 @command = qw(ikiwiki);
37 ok(! system("make -s ikiwiki.out"));
38 @command = ("perl", "-I".getcwd."/blib/lib", './ikiwiki.out',
39 '--underlaydir='.getcwd.'/underlays/basewiki',
40 '--set', 'underlaydirbase='.getcwd.'/underlays',
41 '--templatedir='.getcwd.'/templates');
48 writefile($name, $dir, $content);
49 ok(utime(333333333, 333333333, "$dir/$name"));
52 sub write_setup_file {
55 wikiname => 'this is the name of my wiki',
56 srcdir => "$tmp/srcdir",
57 destdir => "$tmp/out",
58 url => 'http://example.com',
59 cgiurl => 'http://example.com/cgi-bin/ikiwiki.cgi',
60 cgi_wrapper => "$tmp/ikiwiki.cgi",
61 cgi_wrappermode => '0755',
62 add_plugins => [qw(anonok attachment lockedit recentchanges)],
63 disable_plugins => [qw(emailauth openid passwordauth)],
64 anonok_pagespec => 'writable/*',
65 locked_pages => '!writable/*',
67 git_wrapper => "$tmp/repo.git/hooks/post-update",
68 git_wrappermode => '0755',
69 gitorigin_branch => 'test-repo',
70 gitmaster_branch => 'master',
71 untrusted_committers => [$params{trustme} ? 'nobody' : scalar getpwuid($<)],
72 git_test_receive_wrapper => "$tmp/repo.git/hooks/pre-receive",
73 ENV => { LC_ALL => 'C' },
77 $setup{ENV}{'PERL5LIB'} = getcwd.'/blib/lib';
79 writefile("test.setup", "$tmp",
80 "# IkiWiki::Setup::Yaml - YAML formatted setup file\n" .
84 sub thoroughly_rebuild {
85 ok(unlink("$tmp/ikiwiki.cgi") || $!{ENOENT});
86 ok(unlink("$tmp/repo.git/hooks/post-update") || $!{ENOENT});
87 ok(unlink("$tmp/repo.git/hooks/pre-receive") || $!{ENOENT});
88 ok(! system(@command, qw(--setup), "$tmp/test.setup", qw(--rebuild --wrappers)));
94 my $git_dir = $params{chdir} || "$tmp/srcdir";
96 my @redirections = ('>', \$in);
97 if ($params{capture_stdout}) {
98 push @redirections, '>', \$out;
101 push @redirections, '>', \*STDERR;
103 push @redirections, '2>', \$err if $params{capture_stderr};
104 my $h = start(['git', @$args], @redirections, init => sub {
105 chdir $git_dir or die $!;
106 my $name = 'The IkiWiki Tests';
107 my $email = 'nobody@ikiwiki-tests.invalid';
108 if ($args->[0] eq 'commit') {
109 $ENV{GIT_AUTHOR_NAME} = $ENV{GIT_COMMITTER_NAME} = $name;
110 $ENV{GIT_AUTHOR_EMAIL} = $ENV{GIT_COMMITTER_EMAIL} = $email;
115 return $h, $out, $err;
119 my (undef, $filename, $line) = caller;
122 my $git_dir = $params{chdir} || "$tmp/srcdir";
123 my $desc = $params{desc} || join(' ', 'git', @$args);
124 my ($h, $out, $err) = try_run_git($args, capture_stdout => 1, %params);
125 is($h->full_result(0), 0, "'$desc' in $git_dir at $filename:$line");
133 write_old_file('.gitignore', "$tmp/srcdir", "/.ikiwiki/\n");
134 write_old_file('writable/one.mdwn', "$tmp/srcdir", 'This is the first test page');
135 write_old_file('writable/two.bin', "$tmp/srcdir", 'An attachment');
137 unless ($installed) {
138 ok(! system(qw(cp -pRL doc/wikiicons), "$tmp/srcdir/"));
139 ok(! system(qw(cp -pRL doc/recentchanges.mdwn), "$tmp/srcdir/"));
142 ok(mkdir "$tmp/repo.git");
143 run_git(['init', '--bare'], chdir => "$tmp/repo.git");
146 run_git(['add', '.']);
147 run_git(['commit', '-m', 'Initial commit']);
148 my $initial_sha1 = run_git(['rev-list', '--max-count=1', 'HEAD']);
149 run_git(['remote', 'add', 'test-repo', "$tmp/repo.git"]);
150 run_git(['push', 'test-repo', 'master:master']);
151 run_git(['branch', '--set-upstream-to=test-repo/master']);
153 run_git(['clone', '-otest-repo', "$tmp/repo.git", "$tmp/clone"], chdir => $tmp);
154 writefile('writable/untrusted_user_says_hi.mdwn', "$tmp/clone", 'Hi!');
155 run_git(['add', 'writable'], chdir => "$tmp/clone");
156 run_git(['commit', '-m', 'Hi'], chdir => "$tmp/clone");
157 my $allowed_sha1 = run_git(['rev-list', '--max-count=1', 'HEAD'],
158 chdir => "$tmp/clone");
160 diag 'Pushing unrestricted change as untrusted user';
161 write_setup_file(trustme => 0);
162 thoroughly_rebuild();
165 'push', 'test-repo', 'master:master',
166 ], chdir => "$tmp/clone");
167 $sha1 = run_git(['rev-list', '--max-count=1', 'HEAD'], chdir => "$tmp/repo.git");
168 is($sha1, $allowed_sha1, 'allowed commit was pushed');
169 $sha1 = run_git(['rev-list', '--max-count=1', 'HEAD']);
170 is($sha1, $allowed_sha1, 'allowed commit was pushed');
171 ok(-e "$tmp/srcdir/writable/untrusted_user_says_hi.mdwn");
172 ok(-e "$tmp/out/writable/untrusted_user_says_hi/index.html");
174 diag 'Pushing restricted change as untrusted user';
175 writefile('staff_only.mdwn', "$tmp/clone", 'Hi!');
176 run_git(['add', 'staff_only.mdwn'], chdir => "$tmp/clone");
177 run_git(['commit', '-m', 'Hi'], chdir => "$tmp/clone");
178 my $proposed_sha1 = run_git(['rev-list', '--max-count=1', 'HEAD'],
179 chdir => "$tmp/clone");
181 ($h, $out, $err) = try_run_git([
182 'push', 'test-repo', 'master:master',
183 ], chdir => "$tmp/clone", capture_stdout => 1, capture_stderr => 1);
184 isnt($h->full_result(0), 0);
186 like($err, qr{remote: <.*>staff only</.*> is locked and cannot be edited});
187 $sha1 = run_git(['rev-list', '--max-count=1', 'HEAD'], chdir => "$tmp/repo.git");
188 is($sha1, $allowed_sha1, 'proposed commit was not pushed');
189 $sha1 = run_git(['rev-list', '--max-count=1', 'HEAD']);
190 is($sha1, $allowed_sha1, 'proposed commit was not pushed');
191 ok(! -e "$tmp/srcdir/staff_only.mdwn");
192 ok(! -e "$tmp/out/staff_only/index.html");
194 diag 'Pushing restricted change as trusted user';
195 write_setup_file(trustme => 1);
196 thoroughly_rebuild();
199 'push', 'test-repo', 'master:master',
200 ], chdir => "$tmp/clone");
201 $sha1 = run_git(['rev-list', '--max-count=1', 'HEAD'], chdir => "$tmp/repo.git");
202 is($sha1, $proposed_sha1, 'proposed commit was pushed');
203 $sha1 = run_git(['rev-list', '--max-count=1', 'HEAD']);
204 is($sha1, $proposed_sha1, 'proposed commit was pushed');
205 ok(-e "$tmp/srcdir/staff_only.mdwn");
206 ok(-e "$tmp/out/staff_only/index.html");