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(),
],
);
}
}
}
