Skip to content

Commit

Permalink
OXDEV-8489 Prepared & Consumed ModuleBlocklistService
Browse files Browse the repository at this point in the history
Prepared this service ModuleBlocklistService
Consumed above service in ModuleSwitchService
  • Loading branch information
RahatHameed committed Jul 15, 2024
1 parent 7d0e0eb commit eda1e03
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 6 deletions.
3 changes: 3 additions & 0 deletions module_blocklist.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
modules:
- oe_graphql_base
- oe_graphql_configuration_access
22 changes: 22 additions & 0 deletions src/Module/Exception/ModuleBlockListException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GraphQL\ConfigurationAccess\Module\Exception;

use OxidEsales\GraphQL\Base\Exception\NotFound;

final class ModuleBlockListException extends NotFound
{
public const EXCEPTION_MESSAGE = "Failed to load module blocklist from YAML file.";

public function __construct()
{
parent::__construct(self::EXCEPTION_MESSAGE);
}
}
2 changes: 1 addition & 1 deletion src/Module/Exception/ModuleDeactivationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

final class ModuleDeactivationException extends NotFound
{
public const EXCEPTION_MESSAGE = "An error occurred while deactivating the module.";
public const EXCEPTION_MESSAGE = "This Module is in the blocklist and cannot be deactivated.";

public function __construct()
{
Expand Down
37 changes: 37 additions & 0 deletions src/Module/Service/ModuleBlocklistService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GraphQL\ConfigurationAccess\Module\Service;

use OxidEsales\GraphQL\ConfigurationAccess\Module\Exception\ModuleBlockListException;
use OxidEsales\GraphQL\ConfigurationAccess\Module\Infrastructure\YamlFileLoaderInfrastructureInterface;

class ModuleBlocklistService implements ModuleBlocklistServiceInterface
{
public function __construct(
private readonly string $moduleBlocklist,
private readonly YamlFileLoaderInfrastructureInterface $yamlFileLoader
) {
}

/**
* @inheritDoc
*/
public function isModuleBlocked(string $moduleId): bool
{
try {
$resolvedPath = dirname(__FILE__) . '/' . $this->moduleBlocklist;
$blocklistData = $this->yamlFileLoader->load($resolvedPath);

return in_array($moduleId, $blocklistData['modules'], true);
} catch (\Exception $e) {
throw new ModuleBlockListException();
}
}
}
18 changes: 18 additions & 0 deletions src/Module/Service/ModuleBlocklistServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

namespace OxidEsales\GraphQL\ConfigurationAccess\Module\Service;

use OxidEsales\GraphQL\ConfigurationAccess\Module\Exception\ModuleBlockListException;

interface ModuleBlocklistServiceInterface
{
/**
* @throws ModuleBlockListException
*/
public function isModuleBlocked(string $moduleId): bool;
}
13 changes: 12 additions & 1 deletion src/Module/Service/ModuleSwitchService.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,33 @@

namespace OxidEsales\GraphQL\ConfigurationAccess\Module\Service;

use OxidEsales\GraphQL\ConfigurationAccess\Module\Exception\ModuleDeactivationException;
use OxidEsales\GraphQL\ConfigurationAccess\Module\Infrastructure\ModuleSwitchInfrastructureInterface;

class ModuleSwitchService implements ModuleSwitchServiceInterface
{
public function __construct(
private readonly ModuleSwitchInfrastructureInterface $moduleSwitchInfrastructure
private readonly ModuleSwitchInfrastructureInterface $moduleSwitchInfrastructure,
private readonly ModuleBlocklistServiceInterface $moduleBlocklistService
) {
}

/**
* @inheritDoc
*/
public function activateModule(string $moduleId): bool
{
return $this->moduleSwitchInfrastructure->activateModule(moduleId: $moduleId);
}

/**
* @inheritDoc
*/
public function deactivateModule(string $moduleId): bool
{
if ($this->moduleBlocklistService->isModuleBlocked($moduleId)) {
throw new ModuleDeactivationException();
}
return $this->moduleSwitchInfrastructure->deactivateModule(moduleId: $moduleId);
}
}
7 changes: 7 additions & 0 deletions src/Module/Service/ModuleSwitchServiceInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@

namespace OxidEsales\GraphQL\ConfigurationAccess\Module\Service;

use OxidEsales\GraphQL\ConfigurationAccess\Module\Exception\ModuleActivationException;
use OxidEsales\GraphQL\ConfigurationAccess\Module\Exception\ModuleDeactivationException;

interface ModuleSwitchServiceInterface
{
public function activateModule(string $moduleId): bool;

/**
* @throws ModuleDeactivationException
*/
public function deactivateModule(string $moduleId): bool;
}
11 changes: 11 additions & 0 deletions src/Module/services.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
parameters:
oxidesales.graphqlconfigurationaccess.modules_block_list: '../../../module_blocklist.yaml'

services:
_defaults:
public: false
Expand All @@ -15,3 +18,11 @@ services:

OxidEsales\GraphQL\ConfigurationAccess\Module\Service\ModuleSwitchServiceInterface:
class: OxidEsales\GraphQL\ConfigurationAccess\Module\Service\ModuleSwitchService

OxidEsales\GraphQL\ConfigurationAccess\Module\Infrastructure\YamlFileLoaderInfrastructureInterface:
class: OxidEsales\GraphQL\ConfigurationAccess\Module\Infrastructure\YamlFileLoaderInfrastructure

OxidEsales\GraphQL\ConfigurationAccess\Module\Service\ModuleBlocklistServiceInterface:
class: OxidEsales\GraphQL\ConfigurationAccess\Module\Service\ModuleBlocklistService
arguments:
$moduleBlocklist: '%oxidesales.graphqlconfigurationaccess.modules_block_list%'
27 changes: 27 additions & 0 deletions tests/Unit/Module/Exception/ModuleBlockListExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GraphQL\ConfigurationAccess\Tests\Unit\Module\Exception;

use OxidEsales\GraphQL\ConfigurationAccess\Module\Exception\ModuleBlockListException;
use PHPUnit\Framework\TestCase;

/**
* @covers \OxidEsales\GraphQL\ConfigurationAccess\Module\Exception\ModuleBlockListException
*/
final class ModuleBlockListExceptionTest extends TestCase
{
public function testException(): void
{
$exception = new ModuleBlockListException();

$this->assertInstanceOf(ModuleBlockListException::class, $exception);
$this->assertSame(ModuleBlockListException::EXCEPTION_MESSAGE, $exception->getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,10 @@ public static function activationDataProvider(): \Generator

public static function exceptionDataProvider(): \Generator
{
$moduleId = uniqid();
yield 'test activate module throws exception' => [
'method' => 'activate',
'moduleId' => uniqid(),
'moduleId' => $moduleId,
'exceptionClass' => ModuleActivationException::class,

];
Expand Down
82 changes: 82 additions & 0 deletions tests/Unit/Module/Service/ModuleBlocklistServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidEsales\GraphQL\ConfigurationAccess\Tests\Unit\Module\Service;

use OxidEsales\GraphQL\ConfigurationAccess\Module\Exception\ModuleBlockListException;
use OxidEsales\GraphQL\ConfigurationAccess\Module\Infrastructure\YamlFileLoaderInfrastructureInterface;
use OxidEsales\GraphQL\ConfigurationAccess\Module\Service\ModuleBlocklistService;
use PHPUnit\Framework\TestCase;

/**
* @covers \OxidEsales\GraphQL\ConfigurationAccess\Module\Service\ModuleBlocklistService
*/
class ModuleBlocklistServiceTest extends TestCase
{
/**
* @dataProvider blockListDataProvider
*/
public function testIsModuleBlocked(
string $moduleId,
bool $expectedResult
): void {
$filePath = 'testFilePath.yaml';
$expectedData = ['modules' => ['module1', 'module2']];

$yamlFileLoaderMock = $this->createMock(YamlFileLoaderInfrastructureInterface::class);
$yamlFileLoaderMock
->method('load')
->with($this->stringContains($filePath))
->willReturn($expectedData);

$sut = $this->getSut(moduleBlockList: $filePath, yamlFileLoader: $yamlFileLoaderMock);
$actualResult = $sut->isModuleBlocked(moduleId: $moduleId);

$this->assertSame($expectedResult, $actualResult);
}

public static function blockListDataProvider(): \Generator
{
yield 'isModuleBlocked returns true if Module is in the BlockList' => [
'moduleId' => 'module1',
'expectedResult' => true
];

yield 'isModuleBlocked returns false if Module is not in the BlockList' => [
'moduleId' => 'unknownModuleId',
'expectedResult' => false
];
}

public function testGetModuleBlocklistThrowsExceptionOnFailure(): void
{
$moduleId = uniqid();
$yamlFileLoaderMock = $this->createMock(YamlFileLoaderInfrastructureInterface::class);
$yamlFileLoaderMock
->method('load')
->will($this->throwException(new \Exception('Failed to load YAML file')));

$this->expectException(ModuleBlockListException::class);

$sut = $this->getSut(yamlFileLoader: $yamlFileLoaderMock);
$sut->isModuleBlocked(moduleId: $moduleId);
}

private function getSut(
string $moduleBlockList = null,
YamlFileLoaderInfrastructureInterface $yamlFileLoader = null
): ModuleBlocklistService {
return new ModuleBlocklistService(
moduleBlocklist: $moduleBlockList
?? 'testFilePath.yaml',
yamlFileLoader: $yamlFileLoader
?? $this->createStub(YamlFileLoaderInfrastructureInterface::class)
);
}
}
19 changes: 16 additions & 3 deletions tests/Unit/Module/Service/ModuleSwitchServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace OxidEsales\GraphQL\ConfigurationAccess\Tests\Unit\Module\Service;

use OxidEsales\GraphQL\ConfigurationAccess\Module\Infrastructure\ModuleSwitchInfrastructureInterface;
use OxidEsales\GraphQL\ConfigurationAccess\Module\Service\ModuleBlocklistServiceInterface;
use OxidEsales\GraphQL\ConfigurationAccess\Module\Service\ModuleSwitchService;
use PHPUnit\Framework\TestCase;

Expand All @@ -31,7 +32,16 @@ public function testModuleActivationAndDeactivation(
->with($moduleId)
->willReturn(true);

$sut = $this->getSut(moduleSwitchInfrastructure: $moduleSwitchInfrastructureMock);
$moduleBlocklistServiceMock = $this->createMock(ModuleBlocklistServiceInterface::class);
$moduleBlocklistServiceMock
->method('isModuleBlocked')
->with($moduleId)
->willReturn(false);

$sut = $this->getSut(
moduleSwitchInfrastructure: $moduleSwitchInfrastructureMock,
moduleBlocklistService: $moduleBlocklistServiceMock
);
$actualResult = ($method == 'activateModule')
? $sut->activateModule(moduleId: $moduleId)
: $sut->deactivateModule(moduleId: $moduleId);
Expand All @@ -40,11 +50,14 @@ public function testModuleActivationAndDeactivation(
}

private function getSut(
ModuleSwitchInfrastructureInterface $moduleSwitchInfrastructure = null
ModuleSwitchInfrastructureInterface $moduleSwitchInfrastructure = null,
ModuleBlocklistServiceInterface $moduleBlocklistService = null
): ModuleSwitchService {
return new ModuleSwitchService(
moduleSwitchInfrastructure: $moduleSwitchInfrastructure
?? $this->createStub(ModuleSwitchInfrastructureInterface::class)
?? $this->createStub(ModuleSwitchInfrastructureInterface::class),
moduleBlocklistService: $moduleBlocklistService
?? $this->createStub(ModuleBlocklistServiceInterface::class)
);
}

Expand Down

0 comments on commit eda1e03

Please sign in to comment.