export( $this->package() ); self::assertStringContainsString( "\n", $json ); self::assertStringContainsString( '"schema_version": "1.0"', $json ); } public function test_it_imports_valid_json_packages(): void { $transport = new JsonFileTransport( new PackageValidator() ); $package = $transport->import( $transport->export( $this->package() ) ); self::assertSame( '1.0', $package->schemaVersion() ); self::assertSame( 'https://example.test', $package->source()['site_url'] ); } public function test_it_rejects_invalid_json(): void { $transport = new JsonFileTransport( new PackageValidator() ); $this->expectException( \InvalidArgumentException::class ); $this->expectExceptionMessage( 'The selected file is not valid JSON.' ); $transport->import( '{"schema_version":' ); } public function test_it_rejects_schema_errors(): void { $transport = new JsonFileTransport( new PackageValidator() ); $this->expectException( \InvalidArgumentException::class ); $this->expectExceptionMessage( 'records is required.' ); $transport->import( '{"schema_version":"1.0"}' ); } private function package(): ContentPackage { $records = array( 'posts' => array(), 'terms' => array(), 'media' => array(), 'custom_post_types' => array(), ); return ContentPackage::fromArray( array( 'schema_version' => '1.0', 'generated_at' => '2026-04-26T20:30:00+00:00', 'source' => array( 'site_url' => 'https://example.test', 'name' => 'Example Production', ), 'destination' => array( 'site_url' => 'https://staging.example.test', 'name' => 'Example Staging', ), 'manifest' => array( 'posts' => 0, 'terms' => 0, 'media' => 0, 'custom_post_types' => 0, ), 'records' => $records, 'checksums' => array( 'records' => PackageChecksum::records( $records ), ), ) ); } }