diff --git a/phpbb-test-board/README.md b/phpbb-test-board/README.md index 930949a..89d315c 100644 --- a/phpbb-test-board/README.md +++ b/phpbb-test-board/README.md @@ -124,6 +124,8 @@ phpbb-test-board/db-matrix.sh path/to/extension [-b 3.3,master] [-d sqlite,mysql For each phpBB branch and database, builds a seed-forum board with the extension enabled (bind-mounted from the checkout as it is on disk), runs `feature_checks.py --seed-board` against it, and stops that board's database container. It prints a line per board and a summary. Boards and logs go in `--work-dir` (default `~/.cache/phpbb-release-tools/db-matrix`) and are rebuilt on every run; ports start at `--base-port` (default 8130). Oracle isn't covered: phpBB is dropping it. +To test against a phpBB core change that isn't merged yet, `-P N` (`--phpbb-pull-request`) builds the `master` boards from open phpbb/phpbb pull request N instead of the `master` branch, through seed-forum's `board.phpbb_pull_request`. Those boards get their own folders (`master-prN-`). For example, phpbbmodders/restorejumpbox only does anything once phpbb/phpbb#6927 removes core's jumpbox: `db-matrix.sh -b master -P 6927 path/to/restorejumpbox`. + The MSSQL container accepts Microsoft's SQL Server Developer licence; leave `mssql` out of `-d` if that hasn't been agreed. Needs Docker and a seed-forum checkout with `board.database` support. Exit status: 0 when every board passed, 1 when one failed, 2 for bad arguments. diff --git a/phpbb-test-board/db-matrix.sh b/phpbb-test-board/db-matrix.sh index 993beb0..a5c8a7f 100755 --- a/phpbb-test-board/db-matrix.sh +++ b/phpbb-test-board/db-matrix.sh @@ -25,6 +25,7 @@ WORK_DIR="$HOME/.cache/phpbb-release-tools/db-matrix" SEED_FORUM="$(cd "$SCRIPT_DIR/../.." && pwd)/seed-forum" BASE_PORT=8130 KEEP=0 +PHPBB_PULL_REQUEST="" usage() { cat <<'EOF' @@ -38,6 +39,9 @@ Options: -w, --work-dir DIR where boards and their configs go (default: ~/.cache/phpbb-release-tools/db-matrix) -s, --seed-forum DIR seed-forum checkout (default: seed-forum next to this repository) -p, --base-port PORT first port for the boards; each board gets the next one (default: 8130) + -P, --phpbb-pull-request N + build the master boards from open phpbb/phpbb pull request N + (seed-forum board.phpbb_pull_request); their names get -prN -k, --keep leave the extensions mounted and the database containers running after the checks -h, --help show this help and exit @@ -59,6 +63,7 @@ while [ $# -gt 0 ]; do -w|--work-dir) WORK_DIR="${2:?}"; shift 2 ;; -s|--seed-forum) SEED_FORUM="${2:?}"; shift 2 ;; -p|--base-port) BASE_PORT="${2:?}"; shift 2 ;; + -P|--phpbb-pull-request) PHPBB_PULL_REQUEST="${2:?}"; shift 2 ;; -k|--keep) KEEP=1; shift ;; -h|--help) usage; exit 0 ;; -*) die "unknown option $1 (see --help)" ;; @@ -70,6 +75,7 @@ if [ ${#EXTENSIONS[@]} -eq 0 ]; then exit 0 fi [[ "$BASE_PORT" =~ ^[0-9]+$ ]] || die "--base-port must be a number" +[ -z "$PHPBB_PULL_REQUEST" ] || [[ "$PHPBB_PULL_REQUEST" =~ ^[1-9][0-9]*$ ]] || die "--phpbb-pull-request must be a pull request number" [ -f "$SEED_FORUM/bin/db-container.py" ] || die "$SEED_FORUM has no board.database support (bin/db-container.py)" for ext in "${EXTENSIONS[@]}"; do [ -f "$ext/composer.json" ] || die "$ext has no composer.json" @@ -87,6 +93,9 @@ write_config() { echo "board:" echo " root: '$root'" echo " phpbb_branch: '$branch'" + if [ "$branch" = master ] && [ -n "$PHPBB_PULL_REQUEST" ]; then + echo " phpbb_pull_request: $PHPBB_PULL_REQUEST" + fi echo " database: $database" echo " server_name: localhost" echo " server_port: '$port'" @@ -107,6 +116,11 @@ port="$BASE_PORT" for branch in "${branch_list[@]}"; do for database in "${database_list[@]}"; do name="${branch//./}-$database" + # A pull-request board keeps its own folder, as seed-forum refuses to + # reuse a folder filled from another phpBB source. + if [ "$branch" = master ] && [ -n "$PHPBB_PULL_REQUEST" ]; then + name="${branch//./}-pr$PHPBB_PULL_REQUEST-$database" + fi root="$WORK_DIR/boards/$name" config="$WORK_DIR/$name.yml" log="$WORK_DIR/$name.log" diff --git a/phpbb-test-board/feature_checks.py b/phpbb-test-board/feature_checks.py index 12e5c75..9dd1783 100755 --- a/phpbb-test-board/feature_checks.py +++ b/phpbb-test-board/feature_checks.py @@ -207,6 +207,61 @@ def links_to(page: str, path: str) -> bool: ok(not links_to(guest.get(f"{b.base}/index.php").text, rss_path), "links go away when the forum is set to none") +def check_restorejumpbox(b: Board) -> None: + """phpbbmodders/restorejumpbox: on a phpBB 4.0 build with the public jumpbox removed (phpbb/phpbb#6927, + seed-forum board.phpbb_pull_request), the "Jump to" selector is back on forum and topic pages, nested and + filtered by permissions, and the ACP setting hides it while keeping its links. On a phpBB that still has + its own jumpbox, the extension stays out of the way.""" + def forum_id(name: str) -> int: + return int(b.sql("SELECT forum_id FROM phpbb_forums WHERE forum_name = ?", (name,))[0][0]) + + def jumpbox(page: str) -> str: + """The extension's selector markup, or "" when the page has none.""" + m = re.search(r'(?s)
]*>.*?id="restorejumpbox-links".*?', page) + return m.group(0) if m else "" + + discussion, staff = forum_id("General Discussion"), forum_id("Staff Room") + topic_id = int(b.sql("SELECT MIN(topic_id) FROM phpbb_topics WHERE forum_id = ?", (discussion,))[0][0]) + guest = requests.Session() + forum_page = guest.get(f"{b.base}/viewforum.php?f={discussion}").text + if b.sql("SELECT config_value FROM phpbb_config WHERE config_name = 'load_jumpbox'"): + ok(not jumpbox(forum_page) and 'id="jumpbox"' in forum_page, + "on a phpBB that still has its own jumpbox, only core's selector is shown") + return + + box = jumpbox(forum_page) + ok(box, "guests get the selector on a forum page") + ok(f"f={discussion}" in box and re.search(r'class="jumpbox-sub-link"[^>]*>(?:(?!).)*Member Projects', box, re.S), + "it lists forums in order, with a subforum marked as nested") + ok(f"f={staff}" not in box, "a forum guests can't see is left out") + ok(re.search(r"restorejumpbox/[^\"]*jumpbox\.js", forum_page), "its keyboard script is loaded") + ok(jumpbox(guest.get(f"{b.base}/viewtopic.php?t={topic_id}").text), "the topic page has the selector") + ok(not jumpbox(guest.get(f"{b.base}/viewtopic.php?t={topic_id}&view=print").text), + "the printable topic view does not") + ok(not jumpbox(guest.get(f"{b.base}/index.php").text), "the board index does not") + + admin = requests.Session() + sid = b.login(admin, acp=True) + ok(f"f={staff}" in jumpbox(admin.get(f"{b.base}/viewforum.php?f={discussion}").text), + "an administrator's selector includes the staff-only forum") + settings = admin.get(f"{b.base}/adm/index.php?i=acp_board&mode=load&sid={sid}").text + ok('name="config[restorejumpbox_visible]"' in settings, "ACP Load settings has the visibility setting") + action, fields = form_fields(settings, "acp_board") + # acp_board only saves the settings a form sends, so the others stay as they are. + data = {**fields, "config[restorejumpbox_visible]": "0", "submit": "Submit"} + post_back(admin, f"{b.base}/adm", f"{b.base}/adm/index.php?i=acp_board&mode=load&sid={sid}", action, data) + saved = b.sql("SELECT config_value FROM phpbb_config WHERE config_name = 'restorejumpbox_visible'") + ok(saved and str(saved[0][0]) == "0", "saving the setting as No stores it") + b.purge_cache() + hidden_page = guest.get(f"{b.base}/viewforum.php?f={discussion}").text + box = jumpbox(hidden_page) + ok(box and re.search(r'