diff --git a/admin/metabox.php b/admin/metabox.php index 3772561..e3a7b6c 100644 --- a/admin/metabox.php +++ b/admin/metabox.php @@ -114,7 +114,16 @@ function projects_portfolio_save_meta_box( $post_id ) { // Maintain the legacy key for backward-compat reads (only when this is a GitHub project). $provider_now = get_post_meta( $post_id, '_projects_portfolio_provider', true ); if ( 'github' === $provider_now ) { - update_post_meta( $post_id, '_projects_portfolio_github_url', $repo_url ); + if ( '' === $repo_url ) { + // Clearing the field on a GitHub project should clear the legacy key too. + delete_post_meta( $post_id, '_projects_portfolio_github_url' ); + } else { + update_post_meta( $post_id, '_projects_portfolio_github_url', $repo_url ); + } + } else { + // Provider is gitea (or any non-github): ensure no stale GitHub URL can + // resurrect via the legacy fallback chain. + delete_post_meta( $post_id, '_projects_portfolio_github_url' ); } } diff --git a/tests/test-metabox.php b/tests/test-metabox.php index 348b666..eb88532 100644 --- a/tests/test-metabox.php +++ b/tests/test-metabox.php @@ -70,4 +70,76 @@ class Metabox_Test extends \PHPUnit\Framework\TestCase { $this->assertSame( 'github', $existing['_projects_portfolio_provider'] ); $this->assertSame( 'https://github.com/owner/repo', $existing['_projects_portfolio_repo_url'] ); } + + public function test_switching_to_gitea_deletes_legacy_github_url(): void { + $existing = [ + '_projects_portfolio_provider' => 'github', + '_projects_portfolio_repo_url' => 'https://github.com/owner/repo', + '_projects_portfolio_github_url' => 'https://github.com/owner/repo', + ]; + $deleted = []; + \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; + }, + 'delete_post_meta' => function ( $post_id, $key ) use ( &$existing, &$deleted ) { + unset( $existing[ $key ] ); + $deleted[] = $key; + return true; + }, + 'wp_verify_nonce' => function () { return true; }, + 'wp_nonce_field' => function () { /* noop */ }, + ] ); + + $_POST['projects_portfolio_meta_box_nonce'] = 'nonce'; + $_POST['projects_portfolio_provider'] = 'gitea'; + $_POST['projects_portfolio_repo_url'] = 'https://codeberg.org/owner/repo'; + + projects_portfolio_save_meta_box( 7 ); + + $this->assertSame( 'gitea', $existing['_projects_portfolio_provider'] ); + $this->assertSame( 'https://codeberg.org/owner/repo', $existing['_projects_portfolio_repo_url'] ); + $this->assertArrayNotHasKey( '_projects_portfolio_github_url', $existing ); + $this->assertContains( '_projects_portfolio_github_url', $deleted ); + } + + public function test_github_with_empty_repo_url_deletes_legacy_github_url(): void { + $existing = [ + '_projects_portfolio_provider' => 'github', + '_projects_portfolio_repo_url' => 'https://github.com/owner/repo', + '_projects_portfolio_github_url' => 'https://github.com/owner/repo', + ]; + $deleted = []; + \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; + }, + 'delete_post_meta' => function ( $post_id, $key ) use ( &$existing, &$deleted ) { + unset( $existing[ $key ] ); + $deleted[] = $key; + return true; + }, + 'wp_verify_nonce' => function () { return true; }, + 'wp_nonce_field' => function () { /* noop */ }, + ] ); + + $_POST['projects_portfolio_meta_box_nonce'] = 'nonce'; + $_POST['projects_portfolio_provider'] = 'github'; + $_POST['projects_portfolio_repo_url'] = ''; + + projects_portfolio_save_meta_box( 9 ); + + $this->assertSame( 'github', $existing['_projects_portfolio_provider'] ); + $this->assertSame( '', $existing['_projects_portfolio_repo_url'] ); + $this->assertArrayNotHasKey( '_projects_portfolio_github_url', $existing ); + $this->assertContains( '_projects_portfolio_github_url', $deleted ); + } } diff --git a/tests/wp-stubs.php b/tests/wp-stubs.php index 9d4bb35..6bc1544 100644 --- a/tests/wp-stubs.php +++ b/tests/wp-stubs.php @@ -71,6 +71,9 @@ if ( ! function_exists( 'get_post_meta' ) ) { if ( ! function_exists( 'update_post_meta' ) ) { function update_post_meta( $post_id, $key, $value ) { return true; } } +if ( ! function_exists( 'delete_post_meta' ) ) { + function delete_post_meta( $post_id, $key ) { return true; } +} if ( ! function_exists( 'wp_unslash' ) ) { function wp_unslash( $value ) { return $value; } }