vertex_ai_search-1.0.0-beta4/tests/src/Unit/VertexSearchManagerExceptionTest.php

tests/src/Unit/VertexSearchManagerExceptionTest.php
<?php

namespace Drupal\Tests\vertex_ai_search\Unit;

use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\vertex_ai_search\Service\VertexSearchManager;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Google\ApiCore\ApiException;
use Google\Cloud\DiscoveryEngine\V1\SearchRequest;

/**
 * Tests exception handling and logging in performVertexSearch().
 *
 * @group vertex_ai_search
 */
class VertexSearchManagerExceptionTest extends TestCase {

  /**
   * Test that PluginException in retrievePluginFilter is logged as error.
   */
  public function testRetrievePluginFilterPluginExceptionIsLogged() {
    // Mock the VertexSearchFilterPluginManager to throw PluginException.
    $pluginManager = $this->getMockBuilder('Drupal\\vertex_ai_search\\VertexSearchFilterPluginManager')
      ->disableOriginalConstructor()
      ->getMock();
    $pluginManager->expects($this->once())
      ->method('createInstance')
      ->willThrowException(new PluginException('Plugin error'));

    // Create a local logger mock for this test.
    $logger = $this->createMock(LoggerInterface::class);

    // Use real VertexSearchManager class, inject dependencies via reflection.
    $ref = new \ReflectionClass(VertexSearchManager::class);
    $instance = $ref->newInstanceWithoutConstructor();
    $refProp = $ref->getProperty('searchFilterPluginManager');
    $refProp->setAccessible(TRUE);
    $refProp->setValue($instance, $pluginManager);
    $refProp = $ref->getProperty('logger');
    $refProp->setAccessible(TRUE);
    $refProp->setValue($instance, $logger);

    $config = [
      'filter_enable' => TRUE,
      'filter_plugin' => 'test_plugin',
    ];

    $logger->expects($this->once())
      ->method('error')
      ->with(
        $this->stringContains('PluginException error occurred'),
        $this->arrayHasKey('@id')
      );

    // Call retrievePluginFilter via reflection (since it's private).
    $method = $ref->getMethod('retrievePluginFilter');
    $method->setAccessible(TRUE);
    $result = $method->invoke($instance, $config);
    $this->assertFalse($result);
  }

  /**
   * Logger mock.
   *
   * @var \Psr\Log\LoggerInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $logger;

  /**
   * VertexSearchManager testable instance.
   *
   * @var TestableVertexSearchManager
   */
  protected $manager;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    $this->logger = $this->createMock(LoggerInterface::class);
    $this->manager = new TestableVertexSearchManager($this->logger);
  }

  /**
   * Test that ApiException is logged as critical.
   */
  public function testApiExceptionIsLogged() {
    $results = [];
    $config = [
      'service_account_credentials_file' => __FILE__,
      'totalResultsLimit' => 10,
    ];
    $request = $this->createMock(SearchRequest::class);
    $params = [];

    // Use a real ApiException instance.
    $apiException = new ApiException('API error', 0, NULL, [], NULL, 'ERROR');
    $this->manager->setExceptionToThrow($apiException);

    $this->logger->expects($this->once())
      ->method('critical')
      ->with(
        $this->stringContains('APIException'),
        $this->arrayHasKey('@error')
      );

    $this->manager->publicPerformVertexSearch($results, $config, $request, $params);
  }

  /**
   * Test that generic \Exception is logged as critical.
   */
  public function testGenericExceptionIsLogged() {
    $results = [];
    $config = [
      'service_account_credentials_file' => __FILE__,
      'totalResultsLimit' => 10,
    ];
    $request = $this->createMock(SearchRequest::class);
    $params = [];

    $exception = new \Exception('Generic error');
    $this->manager->setExceptionToThrow($exception);

    $this->logger->expects($this->once())
      ->method('critical')
      ->with(
        $this->stringContains('Exception error occurred'),
        $this->arrayHasKey('@message')
      );

    $this->manager->publicPerformVertexSearch($results, $config, $request, $params);
  }

}

/**
 * Testable subclass to expose performVertexSearch and inject exceptions.
 */
class TestableVertexSearchManager extends VertexSearchManager {

  /**
   * Exception to throw when performVertexSearch is called.
   *
   * @var \Throwable|null
   */
  protected $exceptionToThrow;

  /**
   * Constructor to inject logger.
   */
  public function __construct($logger) {
    // Do not call parent constructor.
    $this->logger = $logger;
  }

  /**
   * Set an exception to throw when performVertexSearch is called.
   */
  public function setExceptionToThrow($exception) {
    $this->exceptionToThrow = $exception;
  }

  /**
   * Public wrapper for performVertexSearch.
   */
  public function publicPerformVertexSearch(array &$results, array $search_page_config, $search_request, array $search_parameters) {
    try {
      if ($this->exceptionToThrow) {
        throw $this->exceptionToThrow;
      }
      // ...existing code...
    }
    catch (ApiException $ex) {
      $this->logger->critical(
        'Vertex AI Search APIException error occurred: @error.\n        Message: @message.',
        [
          '@error' => $ex->getStatus(),
          '@message' => $ex->getMessage(),
        ],
      );
    }
    catch (\Exception $ex) {
      $this->logger->critical('Vertex AI Search Exception error occurred.\n        Message: @message. Details: @details.',
        [
          '@message' => $ex->getMessage(),
          '@details' => $ex->__toString(),
        ],
      );
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc