- Timestamp:
- 03/30/2026 02:25:32 PM (4 days ago)
- Location:
- trunk
- Files:
-
- 1 added
- 4 edited
-
src/wp-includes/class-wp-connector-registry.php (modified) (5 diffs)
-
src/wp-includes/connectors.php (modified) (14 diffs)
-
tests/phpunit/includes/wp-ai-client-mock-provider-trait.php (modified) (1 diff)
-
tests/phpunit/tests/connectors/wpConnectorRegistry.php (modified) (9 diffs)
-
tests/phpunit/tests/connectors/wpConnectorsGetApiKeySource.php (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-connector-registry.php
r62116 r62180 32 32 * description: non-empty-string, 33 33 * logo_url?: non-empty-string, 34 * type: 'ai_provider',34 * type: non-empty-string, 35 35 * authentication: array{ 36 36 * method: 'api_key'|'none', 37 37 * credentials_url?: non-empty-string, 38 * setting_name?: non-empty-string 38 * setting_name?: non-empty-string, 39 * constant_name?: non-empty-string, 40 * env_var_name?: non-empty-string 39 41 * }, 40 42 * plugin?: array{ … … 67 69 * 68 70 * Validates the provided arguments and stores the connector in the registry. 69 * For connectors with `api_key` authentication, a `setting_name` is automatically70 * generated using the pattern `connectors_ai_{$id}_api_key`, with hyphens in the ID71 * normalized to underscores (e.g., connector ID `openai` produces72 * `connectors_ai_openai_api_key`, and `azure-openai` produces73 * `connectors_ ai_azure_openai_api_key`). This setting name is used for the Settings74 * API registration and REST API exposure.71 * For connectors with `api_key` authentication, a `setting_name` can be provided 72 * explicitly. If omitted, one is automatically generated using the pattern 73 * `connectors_{$type}_{$id}_api_key`, with hyphens in the type and ID normalized 74 * to underscores (e.g., connector type `spam_filtering` with ID `akismet` produces 75 * `connectors_spam_filtering_akismet_api_key`). This setting name is used for the 76 * Settings API registration and REST API exposure. 75 77 * 76 78 * Registering a connector with an ID that is already registered will trigger a … … 90 92 * @type string $description Optional. The connector's description. Default empty string. 91 93 * @type string $logo_url Optional. URL to the connector's logo image. 92 * @type string $type Required. The connector type . Currently, only 'ai_provider' is supported.94 * @type string $type Required. The connector type, e.g. 'ai_provider'. 93 95 * @type array $authentication { 94 96 * Required. Authentication configuration. … … 96 98 * @type string $method Required. The authentication method: 'api_key' or 'none'. 97 99 * @type string $credentials_url Optional. URL where users can obtain API credentials. 100 * @type string $setting_name Optional. The setting name for the API key. 101 * When omitted, auto-generated as 102 * `connectors_{$type}_{$id}_api_key`. 103 * Must be a non-empty string when provided. 104 * @type string $constant_name Optional. PHP constant name for the API key 105 * (e.g. 'ANTHROPIC_API_KEY'). Only checked when provided. 106 * @type string $env_var_name Optional. Environment variable name for the API key 107 * (e.g. 'ANTHROPIC_API_KEY'). Only checked when provided. 98 108 * } 99 109 * @type array $plugin { … … 193 203 $connector['authentication']['credentials_url'] = $args['authentication']['credentials_url']; 194 204 } 195 if ( ! empty( $args['authentication']['setting_name'] ) && is_string( $args['authentication']['setting_name'] ) ) { 205 if ( isset( $args['authentication']['setting_name'] ) ) { 206 if ( ! is_string( $args['authentication']['setting_name'] ) || '' === $args['authentication']['setting_name'] ) { 207 _doing_it_wrong( 208 __METHOD__, 209 /* translators: %s: Connector ID. */ 210 sprintf( __( 'Connector "%s" authentication setting_name must be a non-empty string.' ), esc_html( $id ) ), 211 '7.0.0' 212 ); 213 return null; 214 } 196 215 $connector['authentication']['setting_name'] = $args['authentication']['setting_name']; 197 216 } else { 198 $connector['authentication']['setting_name'] = 'connectors_ai_' . str_replace( '-', '_', $id ) . '_api_key'; 217 $connector['authentication']['setting_name'] = str_replace( '-', '_', "connectors_{$connector['type']}_{$id}_api_key" ); 218 } 219 if ( isset( $args['authentication']['constant_name'] ) ) { 220 if ( ! is_string( $args['authentication']['constant_name'] ) || '' === $args['authentication']['constant_name'] ) { 221 _doing_it_wrong( 222 __METHOD__, 223 /* translators: %s: Connector ID. */ 224 sprintf( __( 'Connector "%s" authentication constant_name must be a non-empty string.' ), esc_html( $id ) ), 225 '7.0.0' 226 ); 227 return null; 228 } 229 $connector['authentication']['constant_name'] = $args['authentication']['constant_name']; 230 } 231 if ( isset( $args['authentication']['env_var_name'] ) ) { 232 if ( ! is_string( $args['authentication']['env_var_name'] ) || '' === $args['authentication']['env_var_name'] ) { 233 _doing_it_wrong( 234 __METHOD__, 235 /* translators: %s: Connector ID. */ 236 sprintf( __( 'Connector "%s" authentication env_var_name must be a non-empty string.' ), esc_html( $id ) ), 237 '7.0.0' 238 ); 239 return null; 240 } 241 $connector['authentication']['env_var_name'] = $args['authentication']['env_var_name']; 199 242 } 200 243 } -
trunk/src/wp-includes/connectors.php
r62067 r62180 44 44 * @type string $description The connector's description. 45 45 * @type string $logo_url Optional. URL to the connector's logo image. 46 * @type string $type The connector type . Currently, only 'ai_provider' is supported.46 * @type string $type The connector type, e.g. 'ai_provider'. 47 47 * @type array $authentication { 48 48 * Authentication configuration. When method is 'api_key', includes 49 * credentials_url and setting_name. When 'none', only method is present. 49 * credentials_url, setting_name, and optionally constant_name and 50 * env_var_name. When 'none', only method is present. 50 51 * 51 52 * @type string $method The authentication method: 'api_key' or 'none'. 52 53 * @type string $credentials_url Optional. URL where users can obtain API credentials. 53 54 * @type string $setting_name Optional. The setting name for the API key. 55 * @type string $constant_name Optional. PHP constant name for the API key. 56 * @type string $env_var_name Optional. Environment variable name for the API key. 54 57 * } 55 58 * @type array $plugin { … … 63 66 * description: non-empty-string, 64 67 * logo_url?: non-empty-string, 65 * type: 'ai_provider',68 * type: non-empty-string, 66 69 * authentication: array{ 67 70 * method: 'api_key'|'none', 68 71 * credentials_url?: non-empty-string, 69 * setting_name?: non-empty-string 72 * setting_name?: non-empty-string, 73 * constant_name?: non-empty-string, 74 * env_var_name?: non-empty-string 70 75 * }, 71 76 * plugin?: array{ … … 99 104 * @type string $description The connector's description. 100 105 * @type string $logo_url Optional. URL to the connector's logo image. 101 * @type string $type The connector type . Currently, only 'ai_provider' is supported.106 * @type string $type The connector type, e.g. 'ai_provider'. 102 107 * @type array $authentication { 103 108 * Authentication configuration. When method is 'api_key', includes 104 * credentials_url and setting_name. When 'none', only method is present. 109 * credentials_url, setting_name, and optionally constant_name and 110 * env_var_name. When 'none', only method is present. 105 111 * 106 112 * @type string $method The authentication method: 'api_key' or 'none'. 107 113 * @type string $credentials_url Optional. URL where users can obtain API credentials. 108 114 * @type string $setting_name Optional. The setting name for the API key. 115 * @type string $constant_name Optional. PHP constant name for the API key. 116 * @type string $env_var_name Optional. Environment variable name for the API key. 109 117 * } 110 118 * @type array $plugin { … … 119 127 * description: non-empty-string, 120 128 * logo_url?: non-empty-string, 121 * type: 'ai_provider',129 * type: non-empty-string, 122 130 * authentication: array{ 123 131 * method: 'api_key'|'none', 124 132 * credentials_url?: non-empty-string, 125 * setting_name?: non-empty-string 133 * setting_name?: non-empty-string, 134 * constant_name?: non-empty-string, 135 * env_var_name?: non-empty-string 126 136 * }, 127 137 * plugin?: array{ … … 217 227 * 218 228 * add_action( 'wp_connectors_init', function ( WP_Connector_Registry $registry ) { 219 * if ( $registry->is_registered( ' openai' ) ) {220 * $connector = $registry->unregister( ' openai' );221 * $connector['description'] = __( 'Custom description for OpenAI.', 'my-plugin' );222 * $registry->register( ' openai', $connector );229 * if ( $registry->is_registered( 'anthropic' ) ) { 230 * $connector = $registry->unregister( 'anthropic' ); 231 * $connector['description'] = __( 'Custom description for Anthropic.', 'my-plugin' ); 232 * $registry->register( 'anthropic', $connector ); 223 233 * } 224 234 * } ); … … 336 346 // Register all default connectors directly on the registry. 337 347 foreach ( $defaults as $id => $args ) { 348 if ( 'api_key' === $args['authentication']['method'] ) { 349 $sanitized_id = str_replace( '-', '_', $id ); 350 351 if ( ! isset( $args['authentication']['setting_name'] ) ) { 352 $args['authentication']['setting_name'] = "connectors_ai_{$sanitized_id}_api_key"; 353 } 354 355 // All AI providers use the {CONSTANT_CASE_ID}_API_KEY naming convention. 356 if ( ! isset( $args['authentication']['constant_name'] ) || ! isset( $args['authentication']['env_var_name'] ) ) { 357 $constant_case_key = strtoupper( preg_replace( '/([a-z])([A-Z])/', '$1_$2', $sanitized_id ) ) . '_API_KEY'; 358 359 if ( ! isset( $args['authentication']['constant_name'] ) ) { 360 $args['authentication']['constant_name'] = $constant_case_key; 361 } 362 363 if ( ! isset( $args['authentication']['env_var_name'] ) ) { 364 $args['authentication']['env_var_name'] = $constant_case_key; 365 } 366 } 367 } 338 368 $registry->register( $id, $args ); 339 369 } … … 358 388 359 389 /** 360 * Determines the source of an API key for a given provider.390 * Determines the source of an API key for a given connector. 361 391 * 362 392 * Checks in order: environment variable, PHP constant, database. 363 * Uses the same naming convention as the WP AI Client ProviderRegistry. 364 * 365 * @since 7.0.0 366 * @access private 367 * 368 * @param string $provider_id The provider ID (e.g., 'openai', 'anthropic', 'google'). 369 * @param string $setting_name The option name for the API key (e.g., 'connectors_ai_openai_api_key'). 393 * Environment variable and constant are only checked when their 394 * respective names are provided. 395 * 396 * @since 7.0.0 397 * @access private 398 * 399 * @param string $setting_name The option name for the API key (e.g., 'connectors_spam_filtering_akismet_api_key'). 400 * @param string $env_var_name Optional. Environment variable name to check (e.g., 'AKISMET_API_KEY'). 401 * @param string $constant_name Optional. PHP constant name to check (e.g., 'AKISMET_API_KEY'). 370 402 * @return string The key source: 'env', 'constant', 'database', or 'none'. 371 403 */ 372 function _wp_connectors_get_api_key_source( string $provider_id, string $setting_name ): string { 373 // Convert provider ID to CONSTANT_CASE for env var name. 374 // e.g., 'openai' -> 'OPENAI', 'anthropic' -> 'ANTHROPIC'. 375 $constant_case_id = strtoupper( 376 preg_replace( '/([a-z])([A-Z])/', '$1_$2', str_replace( '-', '_', $provider_id ) ) 377 ); 378 $env_var_name = "{$constant_case_id}_API_KEY"; 379 404 function _wp_connectors_get_api_key_source( string $setting_name, string $env_var_name = '', string $constant_name = '' ): string { 380 405 // Check environment variable first. 381 $env_value = getenv( $env_var_name ); 382 if ( false !== $env_value && '' !== $env_value ) { 383 return 'env'; 406 if ( '' !== $env_var_name ) { 407 $env_value = getenv( $env_var_name ); 408 if ( false !== $env_value && '' !== $env_value ) { 409 return 'env'; 410 } 384 411 } 385 412 386 413 // Check PHP constant. 387 if ( defined( $env_var_name ) ) {388 $const_value = constant( $ env_var_name );414 if ( '' !== $constant_name && defined( $constant_name ) ) { 415 $const_value = constant( $constant_name ); 389 416 if ( is_string( $const_value ) && '' !== $const_value ) { 390 417 return 'constant'; … … 471 498 foreach ( wp_get_connectors() as $connector_id => $connector_data ) { 472 499 $auth = $connector_data['authentication']; 473 if ( 'a i_provider' !== $connector_data['type'] || 'api_key' !== $auth['method'] || empty( $auth['setting_name'] ) ) {500 if ( 'api_key' !== $auth['method'] || empty( $auth['setting_name'] ) ) { 474 501 continue; 475 502 } … … 482 509 $value = $data[ $setting_name ]; 483 510 484 // On update, validate the key before masking. 485 if ( $is_update && is_string( $value ) && '' !== $value ) { 511 // On update, validate AI provider keys before masking. 512 // Non-AI connectors accept keys as-is; the service plugin handles its own validation. 513 if ( $is_update && is_string( $value ) && '' !== $value && 'ai_provider' === $connector_data['type'] ) { 486 514 if ( true !== _wp_connectors_is_ai_api_key_valid( $value, $connector_id ) ) { 487 515 update_option( $setting_name, '' ); … … 509 537 */ 510 538 function _wp_register_default_connector_settings(): void { 511 $ai_registry = AiClient::defaultRegistry(); 539 $ai_registry = AiClient::defaultRegistry(); 540 $registered_settings = get_registered_settings(); 512 541 513 542 foreach ( wp_get_connectors() as $connector_id => $connector_data ) { 514 543 $auth = $connector_data['authentication']; 515 if ( 'a i_provider' !== $connector_data['type'] || 'api_key' !== $auth['method'] || empty( $auth['setting_name'] ) ) {544 if ( 'api_key' !== $auth['method'] || empty( $auth['setting_name'] ) ) { 516 545 continue; 517 546 } 518 547 519 // Skip registering the setting if the provider is not in the registry. 520 if ( ! $ai_registry->hasProvider( $connector_id ) ) { 548 // Skip if the setting is already registered (e.g. by an owning plugin). 549 if ( isset( $registered_settings[ $auth['setting_name'] ] ) ) { 550 continue; 551 } 552 553 // For AI providers, skip if the provider is not in the AI Client registry. 554 if ( 'ai_provider' === $connector_data['type'] && ! $ai_registry->hasProvider( $connector_id ) ) { 521 555 continue; 522 556 } … … 528 562 'type' => 'string', 529 563 'label' => sprintf( 530 /* translators: %s: AI provider name. */564 /* translators: %s: Connector name. */ 531 565 __( '%s API Key' ), 532 566 $connector_data['name'] 533 567 ), 534 568 'description' => sprintf( 535 /* translators: %s: AI provider name. */536 __( 'API key for the %s AI provider.' ),569 /* translators: %s: Connector name. */ 570 __( 'API key for the %s connector.' ), 537 571 $connector_data['name'] 538 572 ), … … 570 604 571 605 // Skip if the key is already provided via env var or constant. 572 $key_source = _wp_connectors_get_api_key_source( $ connector_id, $auth['setting_name']);606 $key_source = _wp_connectors_get_api_key_source( $auth['setting_name'], $auth['env_var_name'] ?? '', $auth['constant_name'] ?? '' ); 573 607 if ( 'env' === $key_source || 'constant' === $key_source ) { 574 608 continue; … … 621 655 $auth_out['settingName'] = $auth['setting_name'] ?? ''; 622 656 $auth_out['credentialsUrl'] = $auth['credentials_url'] ?? null; 623 $auth_out['keySource'] = _wp_connectors_get_api_key_source( $connector_id, $auth['setting_name'] ?? '' ); 624 try { 625 $auth_out['isConnected'] = $registry->hasProvider( $connector_id ) && $registry->isProviderConfigured( $connector_id ); 626 } catch ( Exception $e ) { 627 $auth_out['isConnected'] = false; 657 $key_source = _wp_connectors_get_api_key_source( $auth['setting_name'] ?? '', $auth['env_var_name'] ?? '', $auth['constant_name'] ?? '' ); 658 $auth_out['keySource'] = $key_source; 659 660 if ( 'ai_provider' === $connector_data['type'] ) { 661 try { 662 $auth_out['isConnected'] = $registry->hasProvider( $connector_id ) && $registry->isProviderConfigured( $connector_id ); 663 } catch ( Exception $e ) { 664 $auth_out['isConnected'] = false; 665 } 666 } else { 667 $auth_out['isConnected'] = 'none' !== $key_source; 628 668 } 629 669 } … … 646 686 $connector_out['plugin'] = array( 647 687 'slug' => $plugin_slug, 648 'isInstalled' => $is_installed, 688 'pluginFile' => $is_installed 689 ? ( str_ends_with( $plugin_file, '.php' ) ? substr( $plugin_file, 0, -4 ) : $plugin_file ) 690 : null, 649 691 'isActivated' => $is_activated, 650 692 ); -
trunk/tests/phpunit/includes/wp-ai-client-mock-provider-trait.php
r62056 r62180 173 173 'method' => 'api_key', 174 174 'credentials_url' => null, 175 'setting_name' => 'connectors_ai_mock_connectors_test_api_key', 175 176 ), 176 177 ) -
trunk/tests/phpunit/tests/connectors/wpConnectorRegistry.php
r62067 r62180 33 33 34 34 self::$default_args = array( 35 'name' => 'Test Provider',36 'description' => 'A test AI provider.',37 'type' => ' ai_provider',35 'name' => 'Test Connector', 36 'description' => 'A test connector.', 37 'type' => 'test_type', 38 38 'authentication' => array( 39 39 'method' => 'api_key', … … 50 50 51 51 $this->assertIsArray( $result ); 52 $this->assertSame( 'Test Provider', $result['name'] );53 $this->assertSame( 'A test AI provider.', $result['description'] );54 $this->assertSame( ' ai_provider', $result['type'] );52 $this->assertSame( 'Test Connector', $result['name'] ); 53 $this->assertSame( 'A test connector.', $result['description'] ); 54 $this->assertSame( 'test_type', $result['type'] ); 55 55 $this->assertSame( 'api_key', $result['authentication']['method'] ); 56 56 $this->assertSame( 'https://example.com/keys', $result['authentication']['credentials_url'] ); 57 $this->assertSame( 'connectors_ ai_test_provider_api_key', $result['authentication']['setting_name'] );57 $this->assertSame( 'connectors_test_type_test_provider_api_key', $result['authentication']['setting_name'] ); 58 58 } 59 59 … … 64 64 $result = $this->registry->register( 'myai', self::$default_args ); 65 65 66 $this->assertSame( 'connectors_ ai_myai_api_key', $result['authentication']['setting_name'] );66 $this->assertSame( 'connectors_test_type_myai_api_key', $result['authentication']['setting_name'] ); 67 67 } 68 68 … … 73 73 $result = $this->registry->register( 'my-ai', self::$default_args ); 74 74 75 $this->assertSame( 'connectors_ai_my_ai_api_key', $result['authentication']['setting_name'] ); 75 $this->assertSame( 'connectors_test_type_my_ai_api_key', $result['authentication']['setting_name'] ); 76 } 77 78 /** 79 * @ticket 64957 80 */ 81 public function test_register_generates_setting_name_using_type_and_id() { 82 $args = self::$default_args; 83 $args['type'] = 'email_delivery'; 84 85 $result = $this->registry->register( 'sendgrid', $args ); 86 87 $this->assertSame( 'connectors_email_delivery_sendgrid_api_key', $result['authentication']['setting_name'] ); 88 } 89 90 /** 91 * @ticket 64957 92 */ 93 public function test_register_uses_custom_setting_name_when_provided() { 94 $args = self::$default_args; 95 $args['authentication']['setting_name'] = 'wordpress_api_key'; 96 97 $result = $this->registry->register( 'custom-setting', $args ); 98 99 $this->assertSame( 'wordpress_api_key', $result['authentication']['setting_name'] ); 100 } 101 102 /** 103 * @ticket 64957 104 */ 105 public function test_register_rejects_empty_setting_name() { 106 $this->setExpectedIncorrectUsage( 'WP_Connector_Registry::register' ); 107 108 $args = self::$default_args; 109 $args['authentication']['setting_name'] = ''; 110 111 $result = $this->registry->register( 'empty-setting', $args ); 112 113 $this->assertNull( $result ); 114 } 115 116 /** 117 * @ticket 64957 118 */ 119 public function test_register_rejects_non_string_setting_name() { 120 $this->setExpectedIncorrectUsage( 'WP_Connector_Registry::register' ); 121 122 $args = self::$default_args; 123 $args['authentication']['setting_name'] = 123; 124 125 $result = $this->registry->register( 'non-string-setting', $args ); 126 127 $this->assertNull( $result ); 128 } 129 130 /** 131 * @ticket 64957 132 */ 133 public function test_register_stores_constant_name_when_provided() { 134 $args = self::$default_args; 135 $args['authentication']['constant_name'] = 'MY_PROVIDER_API_KEY'; 136 137 $result = $this->registry->register( 'my-provider', $args ); 138 139 $this->assertSame( 'MY_PROVIDER_API_KEY', $result['authentication']['constant_name'] ); 140 } 141 142 /** 143 * @ticket 64957 144 */ 145 public function test_register_omits_constant_name_when_not_provided() { 146 $result = $this->registry->register( 'no-const', self::$default_args ); 147 148 $this->assertArrayNotHasKey( 'constant_name', $result['authentication'] ); 149 } 150 151 /** 152 * @ticket 64957 153 */ 154 public function test_register_rejects_empty_constant_name() { 155 $this->setExpectedIncorrectUsage( 'WP_Connector_Registry::register' ); 156 157 $args = self::$default_args; 158 $args['authentication']['constant_name'] = ''; 159 160 $result = $this->registry->register( 'empty-const', $args ); 161 162 $this->assertNull( $result ); 163 } 164 165 /** 166 * @ticket 64957 167 */ 168 public function test_register_rejects_non_string_constant_name() { 169 $this->setExpectedIncorrectUsage( 'WP_Connector_Registry::register' ); 170 171 $args = self::$default_args; 172 $args['authentication']['constant_name'] = 123; 173 174 $result = $this->registry->register( 'bad-const', $args ); 175 176 $this->assertNull( $result ); 177 } 178 179 /** 180 * @ticket 64957 181 */ 182 public function test_register_stores_env_var_name_when_provided() { 183 $args = self::$default_args; 184 $args['authentication']['env_var_name'] = 'MY_PROVIDER_API_KEY'; 185 186 $result = $this->registry->register( 'my-provider', $args ); 187 188 $this->assertSame( 'MY_PROVIDER_API_KEY', $result['authentication']['env_var_name'] ); 189 } 190 191 /** 192 * @ticket 64957 193 */ 194 public function test_register_omits_env_var_name_when_not_provided() { 195 $result = $this->registry->register( 'no-env', self::$default_args ); 196 197 $this->assertArrayNotHasKey( 'env_var_name', $result['authentication'] ); 198 } 199 200 /** 201 * @ticket 64957 202 */ 203 public function test_register_rejects_empty_env_var_name() { 204 $this->setExpectedIncorrectUsage( 'WP_Connector_Registry::register' ); 205 206 $args = self::$default_args; 207 $args['authentication']['env_var_name'] = ''; 208 209 $result = $this->registry->register( 'empty-env', $args ); 210 211 $this->assertNull( $result ); 212 } 213 214 /** 215 * @ticket 64957 216 */ 217 public function test_register_rejects_non_string_env_var_name() { 218 $this->setExpectedIncorrectUsage( 'WP_Connector_Registry::register' ); 219 220 $args = self::$default_args; 221 $args['authentication']['env_var_name'] = 123; 222 223 $result = $this->registry->register( 'bad-env', $args ); 224 225 $this->assertNull( $result ); 76 226 } 77 227 … … 81 231 public function test_register_no_setting_name_for_none_auth() { 82 232 $args = array( 83 'name' => 'No Auth Provider',84 'type' => ' ai_provider',233 'name' => 'No Auth Connector', 234 'type' => 'test_type', 85 235 'authentication' => array( 'method' => 'none' ), 86 236 ); … … 97 247 $args = array( 98 248 'name' => 'Minimal', 99 'type' => ' ai_provider',249 'type' => 'test_type', 100 250 'authentication' => array( 'method' => 'none' ), 101 251 ); … … 309 459 310 460 $this->assertIsArray( $result ); 311 $this->assertSame( 'Test Provider', $result['name'] );461 $this->assertSame( 'Test Connector', $result['name'] ); 312 462 } 313 463 … … 356 506 357 507 $this->assertIsArray( $result ); 358 $this->assertSame( 'Test Provider', $result['name'] );508 $this->assertSame( 'Test Connector', $result['name'] ); 359 509 $this->assertFalse( $this->registry->is_registered( 'to-remove' ) ); 360 510 } … … 405 555 add_filter( 'wp_supports_ai', '__return_false' ); 406 556 407 $this->registry->register( 'first', self::$default_args ); 557 $args = self::$default_args; 558 $args['type'] = 'ai_provider'; 559 $this->registry->register( 'first', $args ); 408 560 409 561 $all = $this->registry->get_all_registered();
Note: See TracChangeset
for help on using the changeset viewer.