Skip to content

Commit

Permalink
update tests adn styles
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniil Tkachev committed Feb 17, 2025
1 parent 1653eb7 commit e236bc9
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 28 deletions.
1 change: 1 addition & 0 deletions .github/workflows/development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ jobs:
- name: Activate theme
run: |
docker compose exec -T php bin/oe-console oe:theme:activate apex
cp source/var/configuration/environment/shops/1/modules/osc-unzer.yaml.bak source/var/configuration/environment/shops/1/modules/osc-unzer.yaml
- name: Run tests
run: |
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Admin/ModuleConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ private function saveMerchantIdentifier(string $systemMode): void

$isValid = $this->validateCredentialsForSaving($newValue, $errorIds);

if ($isValid && $this->isUpdate) {
if ($isValid && $this->isUpdate && $newValue !== null) {
$this->moduleSettings->setApplePayMerchantIdentifier($newValue);
}
}
Expand Down
53 changes: 42 additions & 11 deletions src/Service/ModuleSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use OxidEsales\EshopCommunity\Core\Exception\FileException;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleConfigurationDaoBridgeInterface;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleSettingBridgeInterface;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingServiceInterface;
use OxidEsales\Facts\Facts;
use OxidSolutionCatalysts\Unzer\Module;
use Exception;
Expand Down Expand Up @@ -42,18 +43,18 @@ class ModuleSettings
'visa' => '1'
];

private ModuleSettingBridgeInterface $moduleSettingBridge;
private ModuleSettingServiceInterface $moduleSettingService;
private ModuleConfigurationDaoBridgeInterface $moduleInfoBridge;
private Session $session;
private Config $config;

public function __construct(
ModuleSettingBridgeInterface $moduleSettingBridge,
ModuleSettingServiceInterface $moduleSettingService,
ModuleConfigurationDaoBridgeInterface $moduleInfoBridge,
Session $session,
Config $config
) {
$this->moduleSettingBridge = $moduleSettingBridge;
$this->moduleSettingService = $moduleSettingService;
$this->moduleInfoBridge = $moduleInfoBridge;
$this->session = $session;
$this->config = $config;
Expand Down Expand Up @@ -340,7 +341,11 @@ public function saveApplePayNetworks(array $networks): void

public function saveWebhookConfiguration(array $webhookConfig): void
{
$this->moduleSettingBridge->save('webhookConfiguration', $webhookConfig, Module::MODULE_ID);
$this->moduleSettingService->saveCollection(
'webhookConfiguration',
$webhookConfig,
Module::MODULE_ID
);
}

public function getWebhookConfiguration(): array
Expand Down Expand Up @@ -380,20 +385,46 @@ public function getPrivateKeysWithContext(): array

private function saveSetting(string $name, bool|int|string|array $setting): void
{
$this->moduleSettingBridge->save($name, $setting, Module::MODULE_ID);
if (is_string($setting)) {
$this->moduleSettingService->saveString($name, $setting, Module::MODULE_ID);
}
if (is_bool($setting)) {
$this->moduleSettingService->saveBoolean($name, $setting, Module::MODULE_ID);
} elseif (is_int($setting)) {
$this->moduleSettingService->saveInteger($name, $setting, Module::MODULE_ID);
} elseif (is_array($setting)) {
$this->moduleSettingService->saveCollection($name, $setting, Module::MODULE_ID);
}
}

private function getSettingValue(string $key): mixed
{
$result = '';
try {
$result = $this->moduleSettingBridge->get($key, Module::MODULE_ID);
} catch (ModuleConfigurationNotFoundException $exception) {
//todo: improve
if (!$this->moduleSettingService->exists($key, Module::MODULE_ID)) {
return '';
}

// Try to get as boolean first for known boolean settings
if (in_array($key, ['UnzerDebug', 'UnzerjQuery'])) {
return $this->moduleSettingService->getBoolean($key, Module::MODULE_ID);
}

// Try to get as integer for known integer settings
if ($key === 'UnzerSystemMode') {
return $this->moduleSettingService->getInteger($key, Module::MODULE_ID);
}

// Try to get as array for known array settings
if (in_array($key, ['webhookConfiguration', 'applepay_merchant_capabilities', 'applepay_networks'])) {
return $this->moduleSettingService->getCollection($key, Module::MODULE_ID);
}

// Default to string for all other settings
return $this->moduleSettingService->getString($key, Module::MODULE_ID)->toString();
} catch (\Exception $exception) {
return '';
}
return $result;
}

/**
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
*/
Expand Down
3 changes: 2 additions & 1 deletion tests/Integration/Service/PaymentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public function testRemoveTemporaryOrder($sessionValue, $expectedResult): void
$this->createPartialMock(Translator::class, []),
$this->createPartialMock(UnzerService::class, []),
$this->createPartialMock(UnzerSDKLoader::class, []),
$this->createPartialMock(TransactionService::class, [])
$this->createPartialMock(TransactionService::class, []),
new \OxidSolutionCatalysts\Unzer\Service\TmpOrderService()
);

$this->assertSame($expectedResult, $sut->removeTemporaryOrder());
Expand Down
212 changes: 204 additions & 8 deletions tests/Unit/Service/ModuleSettingsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,79 @@
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Session;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleConfigurationDaoBridgeInterface;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleSettingBridgeInterface;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingServiceInterface;
use OxidSolutionCatalysts\Unzer\Module;
use OxidSolutionCatalysts\Unzer\Service\ModuleSettings;
use PHPUnit\Framework\TestCase;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use Symfony\Component\String\UnicodeString;

class ModuleSettingsTest extends TestCase
{
private ModuleSettingServiceInterface $moduleSettingService;
private array $originalSettings = [];
private array $settingsToBackup = [
'UnzerDebug',
'UnzerjQuery',
'UnzerSystemMode',
'sandbox-UnzerPublicKey',
'production-UnzerPublicKey',
'sandbox-UnzerPrivateKey',
'production-UnzerPrivateKey',
'webhookConfiguration',
// Sandbox Invoice keys
'sandbox-UnzerPayLaterInvoiceB2BEURPublicKey',
'sandbox-UnzerPayLaterInvoiceB2CEURPrivateKey',
'sandbox-UnzerPayLaterInvoiceB2CCHFPublicKey',
'sandbox-UnzerPayLaterInvoiceB2CEURPublicKey',
'sandbox-UnzerPayLaterInvoiceB2BEURPrivateKey',
'sandbox-UnzerPayLaterInvoiceB2CCHFPrivateKey',
'sandbox-UnzerPayLaterInvoiceB2BCHFPrivateKey',
'sandbox-UnzerPayLaterInvoiceB2BCHFPublicKey',
// Sandbox Installment keys
'sandbox-UnzerPayLaterInstallmentB2CEURPrivateKey',
'sandbox-UnzerPayLaterInstallmentB2CEURPublicKey',
'sandbox-UnzerPayLaterInstallmentB2CCHFPrivateKey',
'sandbox-UnzerPayLaterInstallmentB2CCHFPublicKey',
// Production Invoice keys
'production-UnzerPayLaterInvoiceB2BEURPublicKey',
'production-UnzerPayLaterInvoiceB2CEURPrivateKey',
'production-UnzerPayLaterInvoiceB2CCHFPublicKey',
'production-UnzerPayLaterInvoiceB2CEURPublicKey',
'production-UnzerPayLaterInvoiceB2BEURPrivateKey',
'production-UnzerPayLaterInvoiceB2CCHFPrivateKey',
'production-UnzerPayLaterInvoiceB2BCHFPrivateKey',
'production-UnzerPayLaterInvoiceB2BCHFPublicKey',
// Production Installment keys
'production-UnzerPayLaterInstallmentB2CEURPrivateKey',
'production-UnzerPayLaterInstallmentB2CEURPublicKey',
'production-UnzerPayLaterInstallmentB2CCHFPrivateKey',
'production-UnzerPayLaterInstallmentB2CCHFPublicKey'
];

/**
* @dataProvider getSettingsDataProvider
*/
public function testSettings($values, $settingMethod, $settingValue): void
{
$mockModuleSettingService = $this->createMock(ModuleSettingServiceInterface::class);
$session = $this->createConfiguredMock(Session::class, []);
$config = $this->createConfiguredMock(Config::class, []);


foreach ($values as [$name, $moduleId, $value]) {
$this->configureModuleSettingServiceMock($mockModuleSettingService, $name, $moduleId, $value);
}

$sut = new ModuleSettings(
$this->getBridgeStub($values),
$mockModuleSettingService,
$this->getMockBuilder(ModuleConfigurationDaoBridgeInterface::class)
->disableOriginalConstructor()
->getMock(),
$session,
$config
);

$this->assertSame($settingValue, $sut->$settingMethod());
}

Expand Down Expand Up @@ -126,13 +177,158 @@ public function getSettingsDataProvider(): array
];
}

private function getBridgeStub($valueMap): ModuleSettingBridgeInterface
protected function setUp(): void
{
parent::setUp();

// Backup the var directory
$this->backupVarDirectory();

$container = ContainerFactory::getInstance()->getContainer();
$this->moduleSettingService = $container->get(ModuleSettingServiceInterface::class);
}

/**
* @throws \Exception
*/
protected function tearDown(): void
{
$bridgeStub = $this->getMockBuilder(ModuleSettingBridgeInterface::class)
->onlyMethods(['save', 'get'])
->getMock();
$bridgeStub->method('get')->willReturnMap($valueMap);
// Restore var directory first
$this->restoreVarDirectory();

// Get fresh instance of module setting service
$container = ContainerFactory::getInstance()->getContainer();
$moduleSettingService = $container->get(ModuleSettingServiceInterface::class);

// Set sandbox mode
$moduleSettingService->saveInteger('UnzerSystemMode', 0, Module::MODULE_ID);

// Clear all production-related fields
$productionFields = array_filter($this->settingsToBackup, function($setting) {
return str_starts_with($setting, 'production-');
});

foreach ($productionFields as $field) {
try {
if (strpos($field, 'Key') !== false) {
$moduleSettingService->saveString($field, '', Module::MODULE_ID);
} elseif (strpos($field, 'webhookConfiguration') !== false) {
$moduleSettingService->saveCollection($field, [], Module::MODULE_ID);
}
} catch (\Exception $e) {
continue;
}
}

// Reinitialize module events
(new \OxidSolutionCatalysts\Unzer\Core\Events())->onActivate();

parent::tearDown();
}

private function backupVarDirectory(): void
{
$varDir = '/var/www/var';
$this->varDirBackup = '/tmp/var_backup_' . uniqid();

if (is_dir($varDir)) {
exec("cp -r {$varDir} {$this->varDirBackup}");
}
}

private function restoreVarDirectory(): void
{
$varDir = '/var/www/var';
$confModuleYamlBkp = '/var/www/var/configuration/environment/shops/1/modules/osc-unzer.yaml.bak';
$conModuleYaml = '/var/www/var/configuration/environment/shops/1/modules/osc-unzer.yaml';

if (is_dir($this->varDirBackup)) {
// Remove current var directory
exec("rm -rf {$varDir}");
// Restore from backup
exec("cp -r {$this->varDirBackup} {$varDir}");
// Clean up backup
exec("rm -rf {$this->varDirBackup}");

exec("cp {$confModuleYamlBkp} {$conModuleYaml}");
}
}

private function restoreSettings(): void
{
foreach ($this->originalSettings as $settingName => $data) {
try {
$this->restoreSetting($settingName, $data);
} catch (\Exception $e) {
continue;
}
}
}

private function restoreSetting(string $settingName, array $data): void
{
switch ($data['type']) {
case 'boolean':
$this->moduleSettingService->saveBoolean($settingName, $data['value'], Module::MODULE_ID);
break;
case 'integer':
$this->moduleSettingService->saveInteger($settingName, $data['value'], Module::MODULE_ID);
break;
case 'string':
$this->moduleSettingService->saveString($settingName, $data['value'], Module::MODULE_ID);
break;
case 'collection':
$this->moduleSettingService->saveCollection($settingName, $data['value'], Module::MODULE_ID);
break;
}
}

private function configureModuleSettingServiceMock(
ModuleSettingServiceInterface $mock,
string $name,
string $moduleId,
$value
): void {
$mock->method('exists')
->willReturn(true);

if ($name === 'UnzerSystemMode') {
$mock->method('getInteger')
->with($name, $moduleId)
->willReturn($value);
} elseif (
strpos($name, 'UnzerPrivateKey') !== false || strpos($name, 'UnzerPublicKey') !== false
|| $name === 'UnzerPublicKey' || $name === 'UnzerPrivateKey'
) {
static $keyMap = [];
$keyMap[$moduleId][$name] = $value;

$mock->method('getString')
->willReturnCallback(function ($callName, $callModuleId) use ($keyMap, $mock) {
if (isset($keyMap[$callModuleId][$callName])) {
return new UnicodeString($keyMap[$callModuleId][$callName]);
}

if ($callName === 'UnzerPublicKey' || $callName === 'UnzerPrivateKey') {
$systemMode = $mock->getInteger('UnzerSystemMode', $callModuleId);
$prefix = $systemMode === 1 ? 'production-' : 'sandbox-';
$fullKey = $prefix . $callName;

if (isset($keyMap[$callModuleId][$fullKey])) {
return new UnicodeString($keyMap[$callModuleId][$fullKey]);
}
}

return $bridgeStub;
return new UnicodeString('');
});
} elseif (in_array($name, ['UnzerDebug', 'UnzerjQuery'])) {
$mock->method('getBoolean')
->with($name, $moduleId)
->willReturn($value);
} elseif ($name === 'webhookConfiguration' || strpos($name, 'applepay_') === 0) {
$mock->method('getCollection')
->with($name, $moduleId)
->willReturn($value);
}
}
}
Loading

0 comments on commit e236bc9

Please sign in to comment.