diff --git a/tests/hook.bats b/tests/hook.bats index d54e570..e5576b4 100644 --- a/tests/hook.bats +++ b/tests/hook.bats @@ -4,6 +4,8 @@ # the system (systemctl, redis-cli, nginx, runuser, chown) is a PATH stub # that records its arguments. Nothing here needs root or a network. +bats_require_minimum_version 1.5.0 + setup() { ROOT="$BATS_TEST_DIRNAME/.." HOOK="$ROOT/overlay/usr/lib/inithooks/firstboot.d/40nodebb" @@ -115,7 +117,7 @@ assert c["admin:username"] == "admin", c' "$NODEBB_DIR/config.json" write_conf run "$HOOK" [ "$status" -eq 0 ] - ! grep -q -- '--skip-build' "$CALLS" + run ! grep -q -- '--skip-build' "$CALLS" } @test "the hook is idempotent: a second run changes nothing" { @@ -157,7 +159,7 @@ assert c["admin:username"] == "admin", c' "$NODEBB_DIR/config.json" run "$HOOK" [ "$status" -eq 0 ] grep -q '^geo \$realip_remote_addr \$nodebb_trusted_proxy {$' "$NGINX_PROXY_CONF" - ! grep -q '^set_real_ip_from' "$NGINX_PROXY_CONF" + run ! grep -q '^set_real_ip_from' "$NGINX_PROXY_CONF" } @test "the hook falls back to the hostname when no domain is declared" { diff --git a/tests/nginx.bats b/tests/nginx.bats index 4b1c62e..6c3c996 100644 --- a/tests/nginx.bats +++ b/tests/nginx.bats @@ -4,6 +4,8 @@ # default and the rendered file must not drift apart, since the rendered one # replaces the other and only the rendered one is exercised in production). +bats_require_minimum_version 1.5.0 + setup() { ROOT="$BATS_TEST_DIRNAME/.." LIB="$ROOT/overlay/usr/lib/inithooks/lib/nodebb.sh" @@ -16,8 +18,8 @@ setup() { @test "the shipped conf.d default trusts nobody" { grep -q '^ default 0;$' "$DEFAULT_CONF" - ! grep -q ' 1;$' "$DEFAULT_CONF" - ! grep -q '^set_real_ip_from' "$DEFAULT_CONF" + run ! grep -q ' 1;$' "$DEFAULT_CONF" + run ! grep -q '^set_real_ip_from' "$DEFAULT_CONF" } @test "the shipped conf.d default uses the same geo variable as the rendered file" { @@ -26,8 +28,8 @@ setup() { } @test "the shipped conf.d default never matches geo on remote_addr" { - ! grep -q '^geo \$remote_addr' "$DEFAULT_CONF" - ! grep -q '^geo \$nodebb_trusted_proxy' "$DEFAULT_CONF" + run ! grep -q '^geo \$remote_addr' "$DEFAULT_CONF" + run ! grep -q '^geo \$nodebb_trusted_proxy' "$DEFAULT_CONF" } @test "the shipped conf.d default carries the same map as the rendered file" { @@ -61,7 +63,7 @@ setup() { @test "the shared proxy directives forward the trusted scheme, not the raw one" { grep -q '^proxy_set_header X-Forwarded-Proto \$nodebb_scheme;$' "$INCLUDE" - ! grep -q 'X-Forwarded-Proto \$scheme;' "$INCLUDE" + run ! grep -q 'X-Forwarded-Proto \$scheme;' "$INCLUDE" } @test "the shared proxy directives carry the websocket upgrade headers" { diff --git a/tests/nodebb.bats b/tests/nodebb.bats index 356a7b0..50ef83b 100644 --- a/tests/nodebb.bats +++ b/tests/nodebb.bats @@ -3,6 +3,8 @@ # scratch directories for every path, a PATH stub for redis-cli, python3 # real (it only encodes and decodes JSON here). +bats_require_minimum_version 1.5.0 + setup() { LIB="$BATS_TEST_DIRNAME/../overlay/usr/lib/inithooks/lib/nodebb.sh" # shellcheck source=../overlay/usr/lib/inithooks/lib/nodebb.sh @@ -14,7 +16,7 @@ setup() { @test "needs_setup is true without config.json and false with it" { nodebb_needs_setup "$scratch" touch "$scratch/config.json" - ! nodebb_needs_setup "$scratch" + run ! nodebb_needs_setup "$scratch" } @test "first_value skips empty values and the DEFAULT placeholder" { @@ -114,8 +116,8 @@ assert c == {"url": "https://forum.example.org", "secret": "s", nodebb_valid_proxy 2001:db8::13 nodebb_valid_proxy 2001:db8::/64 nodebb_valid_proxy 192.0.2.7 - ! nodebb_valid_proxy "2001:db8::13; }" - ! nodebb_valid_proxy "hello" + run ! nodebb_valid_proxy "2001:db8::13; }" + run ! nodebb_valid_proxy "hello" } @test "proxy_conf lists the trusted proxy from APP_TRUSTED_PROXY in geo" { @@ -128,12 +130,14 @@ assert c == {"url": "https://forum.example.org", "secret": "s", @test "proxy_conf matches geo on realip_remote_addr, never on remote_addr" { run nodebb_proxy_conf 2001:db8::13 [ "$status" -eq 0 ] - grep -q '^geo \$realip_remote_addr \$nodebb_trusted_proxy {$' <<< "$output" + # every `run` below replaces $output, so keep the rendered file first + local conf=$output + grep -q '^geo \$realip_remote_addr \$nodebb_trusted_proxy {$' <<< "$conf" # the regression this guards: set_real_ip_from below has already # rewritten $remote_addr by the time geo is evaluated, so a geo block on # $remote_addr never matches the proxy and port 80 answers 307 forever - ! grep -q '^geo \$remote_addr' <<< "$output" - ! grep -q '^geo \$nodebb_trusted_proxy' <<< "$output" + run ! grep -q '^geo \$remote_addr' <<< "$conf" + run ! grep -q '^geo \$nodebb_trusted_proxy' <<< "$conf" } @test "proxy_conf keeps the geo variable the same when nobody is trusted" { @@ -174,9 +178,13 @@ assert c == {"url": "https://forum.example.org", "secret": "s", @test "proxy_conf without an address trusts nobody" { run nodebb_proxy_conf "" [ "$status" -eq 0 ] - ! grep -q ' 1;$' <<< "$output" - ! grep -q set_real_ip_from <<< "$output" - grep -q 'default 0;' <<< "$output" + # every `run` below replaces $output, so keep the rendered file first + local conf=$output + run ! grep -q ' 1;$' <<< "$conf" + # anchored: the comment this file carries names the directive, so an + # unanchored match finds the explanation and never the directive + run ! grep -q '^set_real_ip_from' <<< "$conf" + grep -q '^ default 0;$' <<< "$conf" } @test "proxy_conf rejects an address nginx would not accept" {