Skip to content

Commit

Permalink
pkp#10127 Add Guzzle client mocking and test mail swap functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
ewhanson committed Jul 24, 2024
1 parent c111708 commit 9d00557
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 5 deletions.
7 changes: 7 additions & 0 deletions classes/core/PKPApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use PKP\site\Version;
use PKP\site\VersionDAO;
use PKP\submission\RepresentationDAOInterface;
use PKP\tests\PKPTestCase;

interface iPKPApplicationInfoProvider
{
Expand Down Expand Up @@ -307,6 +308,12 @@ public function getUUID(): string
*/
public function getHttpClient()
{
if (PKPContainer::getInstance()->runningUnitTests()) {
$client = Registry::get(PKPTestCase::MOCKED_GUZZLE_CLIENT_NAME);
if ($client) {
return $client;
}
}
$application = Application::get();
$userAgent = $application->getName() . '/';
if (static::isInstalled() && !static::isUpgrading()) {
Expand Down
30 changes: 25 additions & 5 deletions classes/core/PKPContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@

class PKPContainer extends Container
{
/**
* Define if the app is currently running a unit test
*/
private bool $isRunningUnitTest = false;
/**
* @var string The base path of the application, needed for base_path helper
*/
Expand Down Expand Up @@ -175,12 +179,14 @@ public function register(\Illuminate\Support\ServiceProvider $provider)
// will spin through them and register them with the application, which
// serves as a convenience layer while registering a lot of bindings.
if (property_exists($provider, 'bindings')) {
/** @disregard P1014 PHP Intelephense error suppression */
foreach ($provider->bindings as $key => $value) {
$this->bind($key, $value);
}
}

if (property_exists($provider, 'singletons')) {
/** @disregard P1014 PHP Intelephense error suppression */
foreach ($provider->singletons as $key => $value) {
$key = is_int($key) ? $value : $key;
$this->singleton($key, $value);
Expand Down Expand Up @@ -523,14 +529,28 @@ protected function settingProxyForStreamContext(): void
}

/**
* Override Laravel method; always false.
* Override the Laravel method--defaults to false.
* Prevents the undefined method error when the Log Manager tries to determine the driver
*
* @return bool
*/
public function runningUnitTests()
public function runningUnitTests(): bool
{
return $this->isRunningUnitTest;
}

/**
* Set the app running unit test
*/
public function setRunningUnitTests(): void
{
$this->isRunningUnitTest = true;
}

/**
* Unset the app running unit test
*/
public function unsetRunningUnitTests(): void
{
return false;
$this->isRunningUnitTest = false;
}

/**
Expand Down
55 changes: 55 additions & 0 deletions tests/PKPTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,19 @@
use APP\core\Application;
use APP\core\PageRouter;
use APP\core\Request;
use Illuminate\Support\Facades\Mail;
use Mockery;
use PHPUnit\Framework\TestCase;
use PKP\config\Config;
use PKP\core\Core;
use PKP\core\Dispatcher;
use PKP\core\PKPContainer;
use PKP\core\Registry;
use PKP\db\DAORegistry;

abstract class PKPTestCase extends TestCase
{
const MOCKED_GUZZLE_CLIENT_NAME = 'GuzzleClient';
private array $daoBackup = [];
private array $registryBackup = [];
private array $containerBackup = [];
Expand Down Expand Up @@ -79,6 +82,9 @@ protected function setUp(): void
parent::setUp();
$this->setBackupGlobals(true);

// Set application running unit test
PKPContainer::getInstance()->setRunningUnitTests();

// Rather than using "include_once()", ADOdb uses
// a global variable to maintain the information
// whether its library has been included before (wtf!).
Expand Down Expand Up @@ -127,6 +133,12 @@ protected function tearDown(): void
DAORegistry::registerDAO($mockedDao, $this->daoBackup[$mockedDao]);
}

// Delete the mocked guzzle client from registry
Registry::delete(self::MOCKED_GUZZLE_CLIENT_NAME);

// Unset application running unit test
PKPContainer::getInstance()->unsetRunningUnitTests();

Mockery::close();
parent::tearDown();
}
Expand Down Expand Up @@ -239,6 +251,49 @@ protected function localeToRegExp(string $translation): string
$escapedPieces = array_map(fn ($piece) => preg_quote($piece, '/'), $pieces);
return '/^' . implode('.*?', $escapedPieces) . '$/u';
}

/**
* Mock the mail facade
* @see https://laravel.com/docs/10.x/mocking
*/
protected function mockMail(): void
{
/**
* @disregard P1013 PHP Intelephense error suppression
* @see https://github.com/bmewburn/vscode-intelephense/issues/568
*/
Mail::shouldReceive()
->withAnyArgs()
->andReturn(null)
->shouldReceive('compileParams')
->withAnyArgs()
->andReturn('');
}

/**
* Create mockable guzzle client
* @see https://docs.guzzlephp.org/en/stable/testing.html
*
* @param bool $setToRegistry Should store it in app registry to be used by call
* as `Application::get()->getHttpClient()`
*
* @return \Mockery\MockInterface|\Mockery\LegacyMockInterface
*/
protected function mockGuzzleClient(bool $setToRegistry = true): Mockery\MockInterface|Mockery\LegacyMockInterface
{
$guzzleClientMock = Mockery::mock(\GuzzleHttp\Client::class)
->makePartial()
->shouldReceive('request')
->withAnyArgs()
->andReturn(new \GuzzleHttp\Psr7\Response)
->getMock();

if ($setToRegistry) {
Registry::set(self::MOCKED_GUZZLE_CLIENT_NAME, $guzzleClientMock);
}

return $guzzleClientMock;
}
}

if (!PKP_STRICT_MODE) {
Expand Down

0 comments on commit 9d00557

Please sign in to comment.