Skip to content

Commit

Permalink
refactoring internal (#13)
Browse files Browse the repository at this point in the history
* Improve Module::class + test.

* Refactoring internals.
  • Loading branch information
zerai authored Sep 5, 2023
1 parent c840b23 commit 30aab80
Show file tree
Hide file tree
Showing 16 changed files with 443 additions and 20 deletions.
8 changes: 3 additions & 5 deletions config/di/service.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
<?php declare(strict_types=1);

use Http\Discovery\HttpClientDiscovery;


use OpenEMR\Modules\Marketplace\Adapter\Http\Web\AboutController;
use OpenEMR\Modules\Marketplace\Adapter\PackagistFinder\PackagistModuleFinder;
use OpenEMR\Modules\Marketplace\Adapter\Http\Web\DefaultController;
use OpenEMR\Modules\Marketplace\Adapter\Http\Web\NotFoundController;
use OpenEMR\Modules\Marketplace\Finder\ModuleFinder;
use OpenEMR\Modules\Marketplace\Finder\PackagistModuleFinder;
use OpenEMR\Modules\Marketplace\Application\ModuleFinder;
use Twig\Environment;


return [
PackagistModuleFinder::class => DI\create()
->constructor(DI\factory([HttpClientDiscovery::class, 'find'])),
Expand Down
6 changes: 2 additions & 4 deletions public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,17 @@
use Laminas\HttpHandlerRunner\Emitter\SapiStreamEmitter;
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7Server\ServerRequestCreator;


use OpenEMR\Modules\Marketplace\Adapter\PackagistFinder\PackagistModuleFinder;
use OpenEMR\Modules\Marketplace\Adapter\Http\Web\AboutController;
use OpenEMR\Modules\Marketplace\Adapter\Http\Web\DefaultController;
use OpenEMR\Modules\Marketplace\Adapter\Http\Web\NotFoundController;
use OpenEMR\Modules\Marketplace\Finder\PackagistModuleFinder;
use OpenEMR\Modules\Marketplace\Module;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

use Twig\Environment;


require __DIR__ . '/../src/Module.php';

if (Module::isStandAlone()) {
Expand Down
3 changes: 1 addition & 2 deletions src/Adapter/Http/Web/DefaultController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
namespace OpenEMR\Modules\Marketplace\Adapter\Http\Web;

use Nyholm\Psr7\Factory\Psr17Factory;

use OpenEMR\Modules\Marketplace\Finder\ModuleFinder;
use OpenEMR\Modules\Marketplace\Application\ModuleFinder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Twig\Environment;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<?php declare(strict_types=1);

namespace OpenEMR\Modules\Marketplace\Finder;
namespace OpenEMR\Modules\Marketplace\Adapter\PackagistFinder;

use GuzzleHttp\Psr7\Request;
use Http\Client\HttpClient;
use OpenEMR\Modules\Marketplace\Application\ModuleFinder;
use OpenEMR\Modules\Marketplace\Application\ModuleItemCollection;
use OpenEMR\Modules\Marketplace\Application\PackagistItem;
use OpenEMR\Modules\Marketplace\Application\PackagistItemCollection;
use RuntimeException;

class PackagistModuleFinder implements ModuleFinder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace OpenEMR\Modules\Marketplace\Finder;
namespace OpenEMR\Modules\Marketplace\Application;

interface ModuleFinder
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace OpenEMR\Modules\Marketplace\Finder;
namespace OpenEMR\Modules\Marketplace\Application;

interface ModuleItem
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace OpenEMR\Modules\Marketplace\Finder;
namespace OpenEMR\Modules\Marketplace\Application;

interface ModuleItemCollection
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace OpenEMR\Modules\Marketplace\Finder;
namespace OpenEMR\Modules\Marketplace\Application;

class PackagistItem implements ModuleItem
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace OpenEMR\Modules\Marketplace\Finder;
namespace OpenEMR\Modules\Marketplace\Application;

use Doctrine\Common\Collections\ArrayCollection;
use Webmozart\Assert\Assert;
Expand Down
12 changes: 9 additions & 3 deletions src/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use DI\ContainerBuilder;
use Psr\Container\ContainerInterface;

class Module
final class Module
{
public const MODULE_NAME = 'Modules Marketplace';

Expand All @@ -22,9 +22,15 @@ class Module
public const LICENSE_URL = 'https://github.com/medicalmundi/oe-module-marketplace/blob/main/LICENSE';

/**
* @var null|ContainerInterface
* @var ContainerInterface
*
* @psalm-suppress PropertyNotSetInConstructor
*/
protected $container = null;
protected $container;

private function __construct()
{
}

public static function bootstrap(): self
{
Expand Down
Empty file removed tests/Unit/.gitignore
Empty file.
72 changes: 72 additions & 0 deletions tests/Unit/Adapter/PackagistFinder/PackagistHttpResponseTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php declare(strict_types=1);

namespace OpenEMR\Modules\Marketplace\Tests\Unit\Adapter\PackagistFinder;

trait PackagistHttpResponseTrait
{
private function packagistEmptyResponseContent(): string
{
return <<<JSON
{
"results": [],
"total": 0
}
JSON;
}

private function packagistDefaultSingleResultResponseContent(): string
{
return <<<JSON
{
"results": [
{
"name": "openemr/oe-module-faxsms",
"description": "OpenEMR Fax and SMS module",
"url": "https://packagist.org/packages/openemr/oe-module-faxsms",
"repository": "https://github.com/openemr/oe-module-faxsms",
"downloads": 36,
"favers": 1
}
],
"total": 1
}
JSON;
}

private function packagistDefaultMultipleResultResponseContent(): string
{
return <<<JSON
{
"results": [
{
"name": "zerai/oe-module-demo-farm-add-ons",
"description": "OpenEMR Demo Farm Add-ons module",
"url": "https://packagist.org/packages/zerai/oe-module-demo-farm-add-ons",
"repository": "https://github.com/zerai/oe-module-demo-farm-add-ons",
"downloads": 7,
"favers": 0
},
{
"name": "openemr/oe-module-faxsms",
"description": "OpenEMR Fax and SMS module",
"url": "https://packagist.org/packages/openemr/oe-module-faxsms",
"repository": "https://github.com/openemr/oe-module-faxsms",
"downloads": 36,
"favers": 1
}
],
"total": 2
}
JSON;
}

private function packagistEmptyResultResponseContent(): string
{
return <<<JSON
{
"results": [],
"total": 0
}
JSON;
}
}
145 changes: 145 additions & 0 deletions tests/Unit/Adapter/PackagistFinder/PackagistModuleFinderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php declare(strict_types=1);

namespace OpenEMR\Modules\Marketplace\Tests\Unit\Adapter\PackagistFinder;

use Exception;
use Http\Mock\Client;
use OpenEMR\Modules\Marketplace\Adapter\PackagistFinder\PackagistModuleFinder;
use PHPUnit\Framework\TestCase;

class PackagistModuleFinderTest extends TestCase
{
use PackagistHttpResponseTrait;

/**
* @test
*/
public function can_find_one_module(): void
{
$client = $this->createHttpClientWithDefaultResponse($this->packagistDefaultSingleResultResponseContent());
$packagistModuleFinder = new PackagistModuleFinder($client);

$foundedModulesCollection = $packagistModuleFinder->searchModule();

self::assertEquals(1, $foundedModulesCollection->count());
}

/**
* @test
*/
public function can_find_multiple_module(): void
{
$client = $this->createHttpClientWithDefaultResponse($this->packagistDefaultMultipleResultResponseContent());
$packagistModuleFinder = new PackagistModuleFinder($client);

$foundedModulesCollection = $packagistModuleFinder->searchModule();

self::assertEquals(2, $foundedModulesCollection->count());
}

/**
* @test
*/
public function can_handle_http_exception(): void
{
$this->expectException(\RuntimeException::class);

$clientException = new \RuntimeException('Whoops! The server is down.');
$client = $this->createHttpClientWithExceptionResponse($clientException, 500);
$packagistModuleFinder = new PackagistModuleFinder($client);

$packagistModuleFinder->searchModule();
}

/**
* This is an edge case, the module system is based on "openemr/oe-module-installer-plugin"
* it should always appear in the search results.
* 0 result should never happen.
*
* @test
*/
public function can_handle_a_empty_respose_content(): void
{
$client = $this->createHttpClientWithDefaultResponse($this->packagistEmptyResponseContent());
$packagistModuleFinder = new PackagistModuleFinder($client);

$foundedModulesCollection = $packagistModuleFinder->searchModule();

self::assertEquals(0, $foundedModulesCollection->count());
}

/**
* @test
*/
public function can_generate_an_valid_http_endpoint_without_an_input_queryString_parameter(): void
{
$expectedEndpoint = 'https://packagist.org/search.json?q=&type=openemr-module';

$packagistModuleFinder = new PackagistModuleFinder($client = new Client());

$endpoint = $packagistModuleFinder->endpoint();

self::assertStringContainsString('type=openemr-module', $endpoint);
self::assertSame($expectedEndpoint, $endpoint);
self::assertTrue((bool) filter_var($endpoint, FILTER_VALIDATE_URL));
}

/**
* @test
*/
public function can_generate_an_valid_http_endpoint_from_an_input_queryString_parameter(): void
{
$queryString = 'vendor_1';

$expectedEndpoint = 'https://packagist.org/search.json?q=' . $queryString . '&type=openemr-module';

$packagistModuleFinder = new PackagistModuleFinder($client = new Client());

$endpoint = $packagistModuleFinder->endpoint($queryString);

self::assertStringContainsString('type=openemr-module', $endpoint);
self::assertSame($expectedEndpoint, $endpoint);
self::assertTrue((bool) filter_var($endpoint, FILTER_VALIDATE_URL));
}

private function createHttpClientWithDefaultResponse(string $contentResponse, int $httpStatusCode = 200): Client
{
$client = new Client();

$stream = $this->createMock('Psr\Http\Message\StreamInterface');
$stream->expects(self::any())->method('getContents')->willReturn($contentResponse);

$response = $this->createMock('Psr\Http\Message\ResponseInterface');
$response->expects(self::any())->method('getStatusCode')->willReturn($httpStatusCode);
$response->expects(self::any())->method('getBody')->willReturn($stream);

$client->setDefaultResponse($response);

return $client;
}

private function createHttpClientWithExceptionResponse(Exception $exception, int $httpStatusCode): Client
{
$client = new Client();
$client->addException($exception);

return $client;
}

/**
* @test
*/
public function httpClientTest(): void
{
$stream = $this->createMock('Psr\Http\Message\StreamInterface');
$stream->method('getContents')->willReturn($this->packagistDefaultSingleResultResponseContent());
$response = $this->createMock('Psr\Http\Message\ResponseInterface');
$response->method('getBody')->willReturn($stream);
$client = $this->createHttpClientWithDefaultResponse($this->packagistDefaultSingleResultResponseContent());

$returnedResponse = $client->sendRequest($this->createMock('Psr\Http\Message\RequestInterface'));

$this->assertEquals($response, $returnedResponse);
$this->assertEquals(200, $returnedResponse->getStatusCode());
}
}
Loading

0 comments on commit 30aab80

Please sign in to comment.