#!/bin/sh
# The tree page. The checks against foo+bar cover a file name and a branch
# name that both contain a plus, which cgit percent-encodes in a path as
# well as in a query, since a bare plus in a served path reads back as a
# space through a query string.
test_description='Check content on tree page'
. ./setup.sh
test_expect_success 'generate bar/tree' 'cgit_url "bar/tree" >tmp'
test_expect_success 'find file-1' 'grep "file-1" tmp'
test_expect_success 'find file-50' 'grep "file-50" tmp'
test_expect_success 'generate bar/tree/file-50' 'cgit_url "bar/tree/file-50" >tmp'
test_expect_success 'find line 1' '
grep "1" tmp
'
test_expect_success 'no line 2' '
! grep "2" tmp
'
# The numbers and the code are two columns of text that a browser keeps in
# step only while both are set in one font. Only a browser shows the drift,
# so this checks the rule that prevents it.
test_expect_success 'the code is set in the font of its line numbers' '
sed -n "/^div#cgit table.blob code {/,/^}/p" \
"$TEST_OUTPUT_DIRECTORY/../assets/cgit.css" >rule &&
grep "^ font: inherit;$" rule
'
# A browser starts a new line at more characters than git ends one at, and
# each would push the rest of the code a line below its numbers.
test_expect_success 'set up a file holding the characters a browser breaks at' '
test_create_repo repos/breaks &&
(
cd repos/breaks &&
printf "a\\rb\\vc\\fd\\302\\205e\\342\\200\\250f\\342\\200\\251g\\nh\\r\\ni\\r" >breaks.txt &&
git add breaks.txt &&
git commit -m breaks
) &&
{
echo "virtual-root=/" &&
echo "cache-size=0" &&
echo "enable-blame=1" &&
echo "repo.url=breaks" &&
echo "repo.path=$PWD/repos/breaks/.git"
} >breaksrc
'
test_expect_success 'each of them is shown as an escape in the tree' '
CGIT_CONFIG="$PWD/breaksrc" QUERY_STRING="url=breaks/tree/breaks.txt" cgit >tmp &&
grep "a\\\\rb\\\\vc" tmp &&
grep "c\\\\fd\\\\u0085e" tmp &&
grep "e\\\\u2028f\\\\u2029g$" tmp
'
test_expect_success 'only a carriage return before a line feed is left as it is' '
printf "h\\r\\n" >expect &&
grep "^h" tmp >actual &&
test_cmp expect actual &&
grep "^i\\\\r" tmp
'
test_expect_success 'the numbers count only the lines git counts' '
grep "3" tmp &&
! grep "4" tmp
'
test_expect_success 'the blame page escapes them the same way' '
CGIT_CONFIG="$PWD/breaksrc" QUERY_STRING="url=breaks/blame/breaks.txt" cgit >tmp &&
grep "a\\\\rb\\\\vc" tmp &&
grep "e\\\\u2028f\\\\u2029g$" tmp &&
grep "^i\\\\r" tmp
'
# The striped background is padded with spaces to the widest line, which is
# 31 columns once its six escapes are written out, though it is 18 bytes.
test_expect_success 'the blame stripes are as wide as the escaped line' '
grep "^ \\{31\\}" tmp
'
test_expect_success 'generate foo+bar/tree' 'cgit_url "foo%2bbar/tree" >tmp'
test_expect_success 'verify a+b link' '
grep "/foo%2Bbar/tree/a%2Bb" tmp
'
test_expect_success 'generate foo+bar/tree?h=1+2' 'cgit_url "foo%2bbar/tree&h=1%2b2" >tmp'
test_expect_success 'verify a+b?h=1+2 link' '
grep "/foo%2Bbar/tree/a%2Bb?h=1%2B2" tmp
'
test_expect_success 'set up a repo with a nested submodule' '
mkrepo repos/submodules 1 &&
(
cd repos/submodules &&
sub=$(git rev-parse HEAD) &&
git update-index --add --cacheinfo 160000,$sub,vendor/sub &&
git commit -m gitlink
) &&
{
echo "virtual-root=/" &&
echo "cache-size=0" &&
echo "enable-blame=1" &&
echo "repo.url=submodules" &&
echo "repo.path=$PWD/repos/submodules/.git"
} >submodrc
'
test_expect_success 'generate submodules/tree/vendor' '
CGIT_CONFIG="$PWD/submodrc" QUERY_STRING="url=submodules/tree/vendor" cgit >tmp
'
test_expect_success 'a submodule row shows the entry name alone' '
grep "class=.ls-mod.>sub" tmp &&
! grep ">vendor/sub" tmp
'
test_expect_success 'the submodule hash is titled with the full id' '
sub=$(git -C repos/submodules rev-parse HEAD~1) &&
grep "class=.ls-mod-hash. title=.$sub.>" tmp
'
test_expect_success 'a submodule row shows no size' '
grep "ls-mod" tmp >row &&
grep "class=.ls-size.>-" row
'
test_expect_success 'a submodule row offers log but not blame or plain' '
grep "ls-mod" tmp >row &&
grep ">log" row &&
! grep ">blame" row &&
! grep ">plain" row
'
test_expect_success 'a file row still offers blame' '
CGIT_CONFIG="$PWD/submodrc" QUERY_STRING="url=submodules/tree/" cgit >tmp &&
grep ">blame" tmp
'
# A link target inside the tree becomes a link, while an absolute one names a
# file on whatever machine checks the tree out, not a path in the tree.
test_expect_success 'only a link target inside the tree is linked' '
test_create_repo repos/links &&
(
cd repos/links &&
echo hi >target.txt &&
git add target.txt &&
rel=$(printf target.txt | git hash-object -w --stdin) &&
abs=$(printf /etc/passwd | git hash-object -w --stdin) &&
git update-index --add --cacheinfo 120000,$rel,rel &&
git update-index --add --cacheinfo 120000,$abs,abs &&
git commit -m links
) &&
{
echo "virtual-root=/" &&
echo "cache-size=0" &&
echo "repo.url=links" &&
echo "repo.path=$PWD/repos/links/.git"
} >linksrc &&
CGIT_CONFIG="$PWD/linksrc" QUERY_STRING="url=links/tree/" cgit >tmp &&
grep " -> target.txt" tmp &&
grep " -> /etc/passwd" tmp &&
! grep "href=./links/tree/etc/passwd" tmp
'
# A row follows a chain of single directories for a set number of levels and
# stops on the last one it links, with no separator left hanging after it.
test_expect_success 'a long directory chain ends on a link' '
test_create_repo repos/deep &&
(
cd repos/deep &&
p=d1 &&
for i in $(test_seq 2 17)
do
p=$p/d$i || return 1
done &&
mkdir -p $p &&
echo deep >$p/file &&
git add . &&
git commit -m deep
) &&
{
echo "virtual-root=/" &&
echo "cache-size=0" &&
echo "repo.url=deep" &&
echo "repo.path=$PWD/repos/deep/.git"
} >deeprc &&
CGIT_CONFIG="$PWD/deeprc" QUERY_STRING="url=deep/tree/" cgit >tmp &&
grep ">d15" tmp &&
! grep " / " tmp
'
test_expect_success 'a binary file in the tree shows as a hex dump' '
test_create_repo repos/bin &&
(
cd repos/bin &&
printf "\\000\\001\\002bin" >blob.bin &&
git add blob.bin &&
git commit -m binary
) &&
{
echo "virtual-root=/" &&
echo "cache-size=0" &&
echo "repo.url=bin" &&
echo "repo.path=$PWD/repos/bin/.git"
} >binrc &&
CGIT_CONFIG="$PWD/binrc" QUERY_STRING="url=bin/tree/blob.bin" cgit >tmp &&
grep "
| 0000 | 00 01 02 62 69 6e" tmp ' test_done |