party list already shows invite-only parties; knock closes the loop. The knocker can't run any tmux command against the server, so the channel is write(1), the same one invite uses toward guests, except here delivery failure is surfaced: the ping is the whole feature.
81 lines
2.1 KiB
Bash
81 lines
2.1 KiB
Bash
#!/usr/bin/env bats
|
|
#
|
|
# party knock: ask a party's host for an invite via write(1). The
|
|
# unauthorized-party resolution path needs a foreign-owned dir, which a
|
|
# single-uid run can't create (roster_read anchors on dir ownership),
|
|
# so the send is tested through knock_send with a stubbed write(1) and
|
|
# the CLI paths through parties we can fake: our own.
|
|
|
|
load 'helpers'
|
|
|
|
setup() {
|
|
setup_party_sandbox
|
|
load_party_lib
|
|
}
|
|
|
|
teardown() { teardown_party_sandbox; }
|
|
|
|
# Put a stub write(1) on PATH. $1 = exit status. Records its user
|
|
# argument and stdin under $PARTY_TMP.
|
|
stub_write() {
|
|
mkdir -p "$PARTY_TMP/bin"
|
|
cat > "$PARTY_TMP/bin/write" <<EOF
|
|
#!/bin/sh
|
|
printf '%s\n' "\$1" > "$PARTY_TMP/write.user"
|
|
cat > "$PARTY_TMP/write.msg"
|
|
exit $1
|
|
EOF
|
|
chmod +x "$PARTY_TMP/bin/write"
|
|
PATH="$PARTY_TMP/bin:$PATH"
|
|
}
|
|
|
|
@test "knock_send pings the host with the exact invite command" {
|
|
stub_write 0
|
|
knock_send alice fiesta
|
|
[ "$(cat "$PARTY_TMP/write.user")" = alice ]
|
|
grep -q "$USER wants to join 'fiesta'" "$PARTY_TMP/write.msg"
|
|
grep -q "party invite $USER --party fiesta" "$PARTY_TMP/write.msg"
|
|
}
|
|
|
|
@test "knock_send propagates write(1) failure" {
|
|
stub_write 1
|
|
run knock_send alice fiesta
|
|
[ "$status" -ne 0 ]
|
|
}
|
|
|
|
@test "knock on an unknown party fails with not-found" {
|
|
run "$PARTY_BIN" knock nowhere
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"not found"* ]]
|
|
}
|
|
|
|
@test "knock rejects unknown flags and extra args" {
|
|
run "$PARTY_BIN" knock --frob
|
|
[ "$status" -eq 2 ]
|
|
run "$PARTY_BIN" knock a b
|
|
[ "$status" -eq 2 ]
|
|
}
|
|
|
|
@test "knock on your own party is refused" {
|
|
# Live-looking own party via an always-ok tmux stub (rc 0, silent).
|
|
cat > "$PARTY_TMP/tmux-ok" <<'EOF'
|
|
#!/bin/sh
|
|
exit 0
|
|
EOF
|
|
chmod +x "$PARTY_TMP/tmux-ok"
|
|
export PARTY_TMUX="$PARTY_TMP/tmux-ok"
|
|
ensure_party_dir "$USER" mine
|
|
d="$PARTY_SOCKET_DIR/party-$USER:mine.d"
|
|
cat > "$d/roster" <<EOF
|
|
HOST_USER=$USER
|
|
PARTY_NAME=mine
|
|
SOCKET=$d/sock
|
|
SERVER_PID=12345
|
|
GROUP=$TMUX_PARTY_GROUP
|
|
CREATED=2026-07-11T00:00:00Z
|
|
EOF
|
|
chmod 0640 "$d/roster"
|
|
run "$PARTY_BIN" knock mine
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"your own party"* ]]
|
|
}
|