@@ -146,6 +146,61 @@ require_once ABSPATH . 'wp-settings.php';
146146 assert . deepEqual ( aggregate . counts , { total : 2 , succeeded : 2 , failed : 0 , timedOut : 0 , cancelled : 0 } )
147147 assert . deepEqual ( aggregate . entries . map ( ( entry : { artifactNamespace : string } ) => entry . artifactNamespace ) , [ "phpunit/one" , "phpunit/two" ] )
148148 assert . deepEqual ( aggregate . entries . map ( ( entry : { inputIndex : number } ) => entry . inputIndex ) , [ 0 , 1 ] )
149+
150+ const multisitePlugin = join ( directory , "managed-multisite-fixture" )
151+ const multisiteRecipePath = join ( directory , "managed-multisite-recipe.json" )
152+ await mkdir ( join ( multisitePlugin , "tests" ) , { recursive : true } )
153+ await writeFile ( join ( multisitePlugin , "managed-multisite-fixture.php" ) , `<?php
154+ /** Plugin Name: Managed Multisite Fixture */
155+ add_action('init', static function (): void {
156+ update_option('wp_codebox_parent_init_ran', 1);
157+ add_action('init', static function (): void {
158+ update_option('wp_codebox_nested_init_ran', 1);
159+ do_action('wp_codebox_nested_init_replayed');
160+ }, 15);
161+ }, 0);
162+ ` )
163+ await writeFile ( join ( multisitePlugin , "phpunit.xml.dist" ) , "<?xml version=\"1.0\"?><phpunit><testsuites><testsuite name=\"managed-multisite\"><directory>tests</directory></testsuite></testsuites></phpunit>\n" )
164+ await writeFile ( join ( multisitePlugin , "tests" , "ManagedMultisiteTest.php" ) , `<?php
165+ final class ManagedMultisiteTest extends WP_UnitTestCase {
166+ public function test_external_mysql_preserves_multisite_blog_switching(): void {
167+ $this->assertTrue(is_multisite());
168+ $original = get_current_blog_id();
169+ $blog_id = self::factory()->blog->create();
170+ switch_to_blog($blog_id);
171+ $this->assertSame($blog_id, get_current_blog_id());
172+ $this->assertTrue(ms_is_switched());
173+ restore_current_blog();
174+ $this->assertSame($original, get_current_blog_id());
175+ $this->assertFalse(ms_is_switched());
176+ }
177+
178+ public function test_external_mysql_replays_wordpress_lifecycle_in_order(): void {
179+ $this->assertGreaterThan(0, did_action('init'));
180+ $this->assertSame(1, (int) get_option('wp_codebox_parent_init_ran'));
181+ $this->assertSame(1, (int) get_option('wp_codebox_nested_init_ran'));
182+ $this->assertSame(1, did_action('wp_codebox_nested_init_replayed'));
183+ }
184+
185+ public function test_runtime_uses_real_mysql(): void {
186+ global $wpdb;
187+ $this->assertInstanceOf(mysqli::class, $wpdb->dbh);
188+ $this->assertSame('1', (string) $wpdb->get_var("SELECT JSON_VALID('{\\"valid\\":true}')"));
189+ }
190+ }
191+ ` )
192+ const multisiteRecipe = buildWordPressPhpunitRecipe ( {
193+ pluginSlug : "managed-multisite-fixture" ,
194+ phpVersion : "8.3" ,
195+ databaseType : "mysql" ,
196+ multisite : true ,
197+ pluginSource : multisitePlugin ,
198+ dependencyMounts : [ "/wordpress/wp-content/plugins/managed-multisite-fixture" ] ,
199+ mounts : [ { source : join ( harness , "vendor" ) , target : "/wp-codebox-vendor" , mode : "readonly" } ] ,
200+ } )
201+ await writeFile ( multisiteRecipePath , `${ JSON . stringify ( multisiteRecipe ) } \n` )
202+ const multisiteResult = await runRecipe ( { recipePath : multisiteRecipePath , previewHoldBlocking : false , previewLeaseRequested : false , previewLeaseChild : false , timeoutMs : 300_000 , json : true , summary : false , dryRun : false } )
203+ assert . equal ( multisiteResult . success , true , JSON . stringify ( multisiteResult ) )
149204 console . log ( "disposable MySQL and MariaDB mysqli E2E passed" )
150205 } finally {
151206 await rm ( directory , { recursive : true , force : true } )
0 commit comments