blob: 6d33803f7817c6a3db6934bc48c293257b7d476b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/bin/sh

# Checks the source, about, commit and email filters, which hand a piece of
# page content to an outside program before it is written out. The whole
# body runs once per kind of filter, the exec kind always and the lua kind
# only where cgit was built with lua, because both have to produce the same
# page from the same repository.

test_description='Check filtered content'
. ./setup.sh

prefixes="exec"
if test "$CGIT_HAS_LUA" -eq 1
then
	prefixes="$prefixes lua"
fi

for prefix in $prefixes
do
	test_expect_success "generate filter-$prefix/tree/a%2bb" "
		cgit_url 'filter-$prefix/tree/a%2bb' >tmp
	"

	test_expect_success "check whether the $prefix source filter works" '
		grep "<code>a+b HELLO$" tmp
	'

	test_expect_success "generate filter-$prefix/about/" "
		cgit_url 'filter-$prefix/about/' >tmp
	"

	test_expect_success "check whether the $prefix about filter works" '
		grep "<div id='"'"'about'"'"'>a+b /filter-$prefix/tree/  HELLO$" tmp
	'

	test_expect_success "generate filter-$prefix/commit/" "
		cgit_url 'filter-$prefix/commit/' >tmp
	"

	test_expect_success "check whether the $prefix commit filter works" '
		grep "<div class='"'"'commit-subject'"'"'>ADD A+B" tmp
	'

	test_expect_success "check whether the $prefix email filter works for authors" '
		grep "<author@example.com> commit A U THOR &LT;AUTHOR@EXAMPLE.COM&GT;" tmp
	'

	test_expect_success "check whether the $prefix email filter works for committers" '
		grep "<committer@example.com> commit C O MITTER &LT;COMMITTER@EXAMPLE.COM&GT;" tmp
	'

	# Page output is buffered and has to be flushed as stdout is handed
	# to a filter and back. A missed flush reorders the page rather than
	# losing any of it, so the two tests below watch which side of the
	# filtered text the surrounding markup lands on.
	test_expect_success "the $prefix source filter output stays inside its cell" "
		cgit_url 'filter-$prefix/tree/a%2bb' >tmp &&
		tr -d '\n' <tmp >flat.out &&
		grep '<code>a+b HELLO</code>' flat.out
	"

	test_expect_success "the $prefix about filter output stays inside its div" "
		cgit_url 'filter-$prefix/about/' >tmp &&
		grep \"<div id='about'>a+b /filter-$prefix/tree/  HELLO\" tmp
	"
done

test_expect_success 'the blame page goes through the source filter too' '
	echo "enable-blame=1" >blamerc &&
	sed "s/^cache-size=.*/cache-size=0/" cgitrc >>blamerc &&
	CGIT_CONFIG="$PWD/blamerc" QUERY_STRING="url=filter-exec/blame/a%2bb" cgit >tmp &&
	grep "<td class=.linenumbers.>" tmp &&
	grep "<code>a+b HELLO$" tmp
'

# A readme read at another branch links into the tree at that branch, which
# the filter is told as the query to follow a path with.
test_expect_success 'the about filter gets the tree url at the readme branch' '
	{
		echo "virtual-root=/" &&
		echo "cache-size=0" &&
		echo "readme=:a+b" &&
		echo "about-filter=exec:$FILTER_DIRECTORY/dump.sh" &&
		echo "root-readme=$PWD/root.txt" &&
		echo "repo.url=filtered" &&
		echo "repo.path=$PWD/repos/filter/.git"
	} >aboutargsrc &&
	CGIT_CONFIG="$PWD/aboutargsrc" QUERY_STRING="url=filtered/about/&h=1%2b2" cgit >tmp &&
	grep "<div id=.about.>a+b /filtered/tree/ ?h=1%2B2 HELLO" tmp
'

test_expect_success 'the site readme leaves the tree url empty' '
	echo site >root.txt &&
	CGIT_CONFIG="$PWD/aboutargsrc" QUERY_STRING="p=about" cgit >tmp &&
	grep "root.txt   SITE" tmp
'

test_expect_success 'only a repository page hands filters its variables' '
	write_script env.sh <<-\EOF &&
	cat >/dev/null
	echo "repo url: $CGIT_REPO_URL."
	EOF
	sed "s|^about-filter=.*|about-filter=exec:$PWD/env.sh|" aboutargsrc >envrc &&
	CGIT_CONFIG="$PWD/envrc" QUERY_STRING="url=filtered/about/" cgit >tmp &&
	grep "repo url: filtered\." tmp &&
	CGIT_CONFIG="$PWD/envrc" QUERY_STRING="p=about" cgit >tmp &&
	grep "repo url: \." tmp
'

test "$CGIT_HAS_LUA" -eq 1 && test_set_prereq CGIT_LUA
test "$CGIT_HAS_LUA" -eq 1 || say 'cgit built without lua, error page check skipped'

# A die inside a lua filter has to reach the visitor as an error page rather
# than being fed back into the filter that just failed, and the reason goes to
# the log.
test_expect_success CGIT_LUA 'a failing lua filter still renders an error page' '
	cat >broken.lua <<-\EOF &&
	function filter_open(...) error("boom") end
	function filter_write(str) end
	function filter_close() return 0 end
	EOF
	{
		echo "cache-size=0" &&
		echo "repo.url=foo" &&
		echo "repo.path=$PWD/repos/foo/.git" &&
		echo "auth-filter=lua:$PWD/broken.lua"
	} >brokenrc &&
	CGIT_CONFIG="$PWD/brokenrc" QUERY_STRING="url=foo/commit" cgit >tmp 2>err &&
	grep "Status: 500" tmp &&
	grep "Lua error in" err
'

# A script may raise a value that is no string, which the log still names.
test_expect_success CGIT_LUA 'a lua filter raising a table is named by type' '
	cat >tabled.lua <<-\EOF &&
	function filter_open(...) error({}) end
	function filter_write(str) end
	function filter_close() return 0 end
	EOF
	sed "s|broken.lua|tabled.lua|" brokenrc >tabledrc &&
	CGIT_CONFIG="$PWD/tabledrc" QUERY_STRING="url=foo/commit" cgit >tmp 2>err &&
	grep "Status: 500" tmp &&
	grep "Lua error in .*tabled.lua: (error object is a table value)" err
'

# A script runs its top level before cgit hooks stdout for it, so what it
# writes there goes straight onto the page instead of tripping the hook.
test_expect_success CGIT_LUA 'a lua filter that writes while loading still renders' '
	cat >loud.lua <<-\EOF &&
	html("written while loading")
	function filter_open(...) end
	function filter_write(str) html(str) end
	function filter_close() return 0 end
	EOF
	{
		echo "cache-size=0" &&
		echo "repo.url=foo" &&
		echo "repo.path=$PWD/repos/foo/.git" &&
		echo "repo.commit-filter=lua:$PWD/loud.lua"
	} >loudrc &&
	CGIT_CONFIG="$PWD/loudrc" QUERY_STRING="url=foo/commit" cgit >tmp &&
	grep "written while loading" tmp &&
	grep "</html>" tmp
'

# A Lua build replaces write, and git writes its trace before cgit has run a
# line of its own.
test_expect_success CGIT_LUA 'git can trace before the filters are set up' '
	CGIT_CONFIG="$PWD/cgitrc" GIT_TRACE2="$PWD/trace2.out" QUERY_STRING="url=foo/" cgit >tmp &&
	grep "</html>" tmp &&
	test -s trace2.out
'

# html_url_arg and html_include are the two calls a Lua filter has beyond
# plain html, and nothing else drives them.
test_expect_success CGIT_LUA 'a lua filter can encode an argument and include a file' '
	echo "included <b>bold</b>" >include.txt &&
	cat >apis.lua <<-EOF &&
	function filter_open(...) end
	function filter_write(str)
		html_url_arg("a b&c")
		html("|")
		html_include("$PWD/include.txt")
	end
	function filter_close() return 0 end
	EOF
	{
		echo "cache-size=0" &&
		echo "repo.url=foo" &&
		echo "repo.path=$PWD/repos/foo/.git" &&
		echo "repo.commit-filter=lua:$PWD/apis.lua"
	} >apisrc &&
	CGIT_CONFIG="$PWD/apisrc" QUERY_STRING="url=foo/commit" cgit >tmp &&
	grep "a+b%26c|included <b>bold</b>" tmp
'

test_done