From d8ce7194338bd8800a7ddc225af7493950c0ef2a Mon Sep 17 00:00:00 2001 From: Keith Solomon Date: Sun, 9 Aug 2026 23:17:51 -0500 Subject: [PATCH] Add provider dropdown and per-project Gitea base URL to metabox --- admin/metabox.php | 93 +++++++++++++++++++++++++++++++++++------- tests/test-metabox.php | 73 +++++++++++++++++++++++++++++++++ tests/wp-stubs.php | 12 ++++++ 3 files changed, 163 insertions(+), 15 deletions(-) create mode 100644 tests/test-metabox.php diff --git a/admin/metabox.php b/admin/metabox.php index 9ffc72b..3772561 100644 --- a/admin/metabox.php +++ b/admin/metabox.php @@ -6,15 +6,15 @@ if ( ! defined( 'WPINC' ) ) { } /** - * Add GitHub Repository URL meta box. + * Add Repository meta box (provider-aware). * * @since 1.0.0 * @return void */ function projects_portfolio_add_meta_boxes() { add_meta_box( - 'projects_portfolio_github_url', - esc_html__( 'GitHub URL', 'projects-wp' ), + 'projects_portfolio_repo', + esc_html__( 'Repository', 'projects-wp' ), 'projects_portfolio_render_meta_box', 'projects', 'side' @@ -23,27 +23,64 @@ function projects_portfolio_add_meta_boxes() { add_action( 'add_meta_boxes', 'projects_portfolio_add_meta_boxes' ); /** - * Renders the GitHub Repository URL meta box for the Projects WP plugin. + * Render the Repository meta box. * - * Outputs a label and input field for setting the GitHub repository URL, - * as well as a nonce for security. - * - * @param WP_Post $post The post object currently being edited. + * @param WP_Post $post * * @since 1.0.0 * @return void */ function projects_portfolio_render_meta_box( $post ) { wp_nonce_field( 'projects_portfolio_save_meta_box', 'projects_portfolio_meta_box_nonce' ); - $github_url = get_post_meta( $post->ID, '_projects_portfolio_github_url', true ); - echo ''; - echo ''; + + $provider = get_post_meta( $post->ID, '_projects_portfolio_provider', true ); + if ( '' === $provider ) { + $provider = 'github'; + } + $repo_url = get_post_meta( $post->ID, '_projects_portfolio_repo_url', true ); + if ( '' === $repo_url ) { + $repo_url = get_post_meta( $post->ID, '_projects_portfolio_github_url', true ); + } + $gitea_base_url = get_post_meta( $post->ID, '_projects_portfolio_gitea_base_url', true ); + ?> +

+ + +

+

+ + +

+

> + + + +

+ + */ + private array $saved = []; + + protected function setUpSaveStubs(): void { + $this->saved = []; + \Brain\Monkey\Functions\stubs( [ + 'update_post_meta' => function ( $post_id, $key, $value ) { + $this->saved[ $key ] = $value; + return true; + }, + 'wp_verify_nonce' => function () { return true; }, + 'wp_nonce_field' => function () { /* noop */ }, + ] ); + } + + public function test_save_persists_provider_and_repo_url(): void { + $this->setUpSaveStubs(); + $_POST['projects_portfolio_meta_box_nonce'] = 'nonce'; + $_POST['projects_portfolio_provider'] = 'gitea'; + $_POST['projects_portfolio_repo_url'] = 'https://codeberg.org/owner/repo'; + $_POST['projects_portfolio_gitea_base_url'] = 'https://codeberg.org'; + + projects_portfolio_save_meta_box( 42 ); + + $this->assertSame( 'gitea', $this->saved['_projects_portfolio_provider'] ); + $this->assertSame( 'https://codeberg.org/owner/repo', $this->saved['_projects_portfolio_repo_url'] ); + $this->assertSame( 'https://codeberg.org', $this->saved['_projects_portfolio_gitea_base_url'] ); + } + + public function test_lazy_migration_from_legacy_url(): void { + $existing = [ + '_projects_portfolio_provider' => '', + '_projects_portfolio_repo_url' => '', + '_projects_portfolio_github_url' => 'https://github.com/owner/repo', + ]; + \Brain\Monkey\Functions\stubs( [ + 'get_post_meta' => function ( $post_id, $key, $single = false ) use ( &$existing ) { + return $existing[ $key ] ?? ''; + }, + 'update_post_meta' => function ( $post_id, $key, $value ) use ( &$existing ) { + $existing[ $key ] = $value; + return true; + }, + 'wp_verify_nonce' => function () { return true; }, + 'wp_nonce_field' => function () { /* noop */ }, + ] ); + + // No $_POST provider/repo_url. Lazy migration should fire. + $_POST['projects_portfolio_meta_box_nonce'] = 'nonce'; + + projects_portfolio_save_meta_box( 1 ); + + $this->assertSame( 'github', $existing['_projects_portfolio_provider'] ); + $this->assertSame( 'https://github.com/owner/repo', $existing['_projects_portfolio_repo_url'] ); + } +} diff --git a/tests/wp-stubs.php b/tests/wp-stubs.php index 41f8ae9..9d4bb35 100644 --- a/tests/wp-stubs.php +++ b/tests/wp-stubs.php @@ -65,6 +65,18 @@ if ( ! function_exists( 'wp_remote_retrieve_header' ) ) { if ( ! function_exists( 'error_log' ) ) { function error_log( $message ) { /* swallow during tests */ } } +if ( ! function_exists( 'get_post_meta' ) ) { + function get_post_meta( $post_id, $key = '', $single = false ) { return ''; } +} +if ( ! function_exists( 'update_post_meta' ) ) { + function update_post_meta( $post_id, $key, $value ) { return true; } +} +if ( ! function_exists( 'wp_unslash' ) ) { + function wp_unslash( $value ) { return $value; } +} +if ( ! function_exists( 'esc_url_raw' ) ) { + function esc_url_raw( $url ) { return $url; } +} // Minimal WP_Error stub if Brain\Monkey doesn't supply one. if ( ! class_exists( 'WP_Error' ) ) {