Skip to content

Commit

Permalink
Merge pull request #325 from OXID-eSales/b-6.3.x-fix-apple2-UNZER-529
Browse files Browse the repository at this point in the history
B 6.3.x fix apple2 unzer 529
  • Loading branch information
mariolorenz authored Dec 13, 2024
2 parents a86e0a5 + f9ad1f2 commit 9e0f946
Show file tree
Hide file tree
Showing 17 changed files with 237 additions and 138 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Save ApplePay-Certificates for Test- and Live-Mode. Fix an possible Maintenance when something was wrong before
- Fixed a problem when multiple modules were in use. If Unzer was not last in some extended classes, this could lead to a maintenance.
- [0007739](https://bugs.oxid-esales.com/view.php?id=7739): Fix that order with payment method Unzer bancontact is not created after successful payment
- Fix email notification sending for payments with auth only mode

## [1.2.0] - 2024-09-26

Expand Down
7 changes: 2 additions & 5 deletions Tests/Unit/Service/FlexibleSerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ public function testSafeUnserializeWithAllowedClasses(): void

$serialized = $this->flexibleSerializer->safeSerialize($order);
$unserialized = $this->flexibleSerializer->safeUnserialize(
$serialized,
['OxidEsales\Eshop\Application\Model\Order']
$serialized
);

$this->assertInstanceOf('OxidEsales\Eshop\Application\Model\Order', $unserialized);
$this->assertInstanceOf(\stdClass::class, $unserialized);
$this->assertEquals(1, $unserialized->id);
$this->assertEquals('John Doe', $unserialized->customerName);
}
Expand All @@ -50,7 +49,6 @@ public function testSafeSerializeAndUnserializeCustomObject(): void
['OxidEsales\Eshop\Application\Model\Order']
);

$this->assertInstanceOf('OxidEsales\Eshop\Application\Model\Order', $unserialized);
$this->assertEquals(1, $unserialized->id);
$this->assertEquals('John Doe', $unserialized->customerName);
$this->assertEquals('Extra Info', $unserialized->extraField);
Expand Down Expand Up @@ -132,7 +130,6 @@ public function testSafeSerializeAndUnserializeExtendedObject(): void
[\OxidEsales\Eshop\Application\Model\Order::class]
);

$this->assertInstanceOf(Order::class, $unserialized);
$this->assertEquals(1, $unserialized->id);
$this->assertEquals('John Doe', $unserialized->customerName);
$this->assertEquals('Extra Info', $unserialized->extraField);
Expand Down
2 changes: 2 additions & 0 deletions Tests/Unit/Service/TransactionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* See LICENSE file for license details.
*/

declare(strict_types=1);

namespace OxidSolutionCatalysts\Unzer\Tests\Unit\Service;

use OxidEsales\Eshop\Core\UtilsDate;
Expand Down
125 changes: 125 additions & 0 deletions Tests/Unit/Service/TransactionWriteTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

namespace OxidSolutionCatalysts\Unzer\Tests\Unit\Service;

use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\UtilsDate;
use OxidSolutionCatalysts\Unzer\Model\Transaction;
use OxidSolutionCatalysts\Unzer\Service\Context;
use OxidSolutionCatalysts\Unzer\Service\DebugHandler;
use OxidSolutionCatalysts\Unzer\Service\Transaction as TransactionService;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\MockObject\MockObject;
use OxidSolutionCatalysts\Unzer\Model\Transaction as TransactionModel;

class TransactionWriteTest extends TestCase
{
/** @var TransactionService|MockObject */
private $transactionService;

/** @var TransactionModel|MockObject */
private $transactionMock;

/** @var MockObject */
private $debugHandlerMock;

protected function setUp(): void
{
$this->transactionMock = $this->createMock(Transaction::class);
$this->debugHandlerMock = $this->createMock(DebugHandler::class);

$this->transactionService = $this->getMockBuilder(TransactionService::class)
->setConstructorArgs([
$this->createConfiguredMock(Context::class, ['getCurrentShopId' => 5]),
$this->createConfiguredMock(UtilsDate::class, ['getTime' => time()]),
])
->onlyMethods(['getNewTransactionObject', 'prepareTransactionOxid', 'getServiceFromContainer'])
->getMock();

$this->transactionService->method('getNewTransactionObject')->willReturn($this->transactionMock);
$this->transactionService->method('getServiceFromContainer')->willReturn($this->debugHandlerMock);
}

public function testSaveTransactionWithDuplicateEntry(): void
{
$params = ['metadata' => '{}', 'otherParam' => 'value'];
$oxid = '12345';

$this->transactionService->method('prepareTransactionOxid')->willReturn($oxid);

$this->transactionMock->method('load')->with($oxid)->willReturn(false);

$exception = new DatabaseErrorException('duplicate', 1062, new \Doctrine\DBAL\Exception());
$this->transactionMock->method('save')
->willThrowException($exception);

$this->debugHandlerMock->expects($this->once())
->method('log')
->with($this->stringContains('saveTransaction: duplicate'));

$result = $this->transactionService->saveTransaction($params);

$this->assertTrue(
$result,
'saveTransaction should return true even when a DatabaseErrorException occurs.'
);
}

public function testSaveTransactionWithOtherDatabaseError(): void
{
$params = ['metadata' => '{}', 'otherParam' => 'value'];
$oxid = '67890';

$this->transactionService->method('prepareTransactionOxid')->willReturn($oxid);

$this->transactionMock->method('load')->with($oxid)->willReturn(false);

$exception = new DatabaseErrorException('Other database error', 1062, new \Exception());
$this->transactionMock->method('save')->willThrowException($exception);

$this->debugHandlerMock->expects($this->once())
->method('log')
->with($this->stringContains('saveTransaction: Other database error'));

$result = $this->transactionService->saveTransaction($params);

$this->assertTrue(
$result,
'saveTransaction should return true even when other DatabaseErrorException occurs.'
);
}

public function testSaveTransactionSuccess(): void
{
$params = ['metadata' => '{}', 'otherParam' => 'value'];
$oxid = '11223';

$this->transactionService->method('prepareTransactionOxid')->willReturn($oxid);

$this->transactionMock->method('load')->with($oxid)->willReturn(false);
$this->transactionMock->expects($this->once())->method('assign')->with($params);
$this->transactionMock->expects($this->once())->method('setId')->with($oxid);
$this->transactionMock->expects($this->once())->method('save');

$result = $this->transactionService->saveTransaction($params);

$this->assertTrue($result, 'saveTransaction should return true when transaction is successfully saved.');
}

public function testGetNewTransactionObject(): void
{
$transactionService = new class (
$this->createPartialMock(Context::class, []),
$this->createConfiguredMock(UtilsDate::class, [])
) extends TransactionService {
public function testGetNewTransactionObject()
{
return $this->getNewTransactionObject();
}
};

$item = $transactionService->testGetNewTransactionObject();
$this->assertInstanceOf(Transaction::class, $item);
$this->assertNull($item->getId());
}
}
1 change: 0 additions & 1 deletion Tests/Unit/Service/UnzerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ public function getPaymentProcedureDataProvider(): array
return [
['paypal', 'special'],
['card', 'special'],
['applepay', 'special'],
['installment-secured', 'authorize'],
['paylater-installment', 'authorize'],
['paylater-invoice', 'authorize'],
Expand Down
2 changes: 1 addition & 1 deletion metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
</ul>',
],
'thumbnail' => 'logo.svg',
'version' => '1.2.1-rc.2',
'version' => '1.2.1-rc.3',
'author' => 'OXID eSales AG',
'url' => 'https://www.oxid-esales.com',
'email' => '[email protected]',
Expand Down
3 changes: 1 addition & 2 deletions src/Controller/Admin/AdminOrderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use OxidEsales\Eshop\Core\Registry;
use OxidSolutionCatalysts\Unzer\Traits\Request;
use OxidEsales\Eshop\Application\Model\Payment;
use OxidSolutionCatalysts\Unzer\Model\Order as UnzerOrder;
use OxidSolutionCatalysts\Unzer\Model\TransactionList;
use OxidSolutionCatalysts\Unzer\Service\Payment as UnzerPaymentService;
use OxidSolutionCatalysts\Unzer\Service\Transaction as TransactionService;
Expand Down Expand Up @@ -194,7 +193,7 @@ protected function getUnzerViewData(string $sPaymentId, string $sTypeId): void
$editObject->getFieldData('oxpaid') == '0000-00-00 00:00:00' &&
$fCharged == $unzerPayment->getAmount()->getTotal()
) {
/** @var UnzerOrder $editObject */
/** @var \OxidSolutionCatalysts\Unzer\Model\Order $editObject */
$editObject->markUnzerOrderAsPaid();
$this->forceReloadListFrame();
}
Expand Down
24 changes: 24 additions & 0 deletions src/Controller/Admin/ModuleConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ public function transferApplePayPaymentProcessingData(): void

$this->saveMerchantCert($systemMode);
$this->saveMerchantKey($systemMode);
$this->saveMerchantIdentifier($systemMode);
$this->savePaymentCert($systemMode);
$this->savePaymentKey($systemMode);

Expand Down Expand Up @@ -264,6 +265,7 @@ public function saveConfVars()

$this->saveMerchantCert($systemMode);
$this->saveMerchantKey($systemMode);
$this->saveMerchantIdentifier($systemMode);
$this->savePaymentCert($systemMode);
$this->savePaymentKey($systemMode);

Expand Down Expand Up @@ -299,6 +301,28 @@ private function saveMerchantKey(string $systemMode): void
}
}

private function saveMerchantIdentifier(string $systemMode): void
{
$errorIds = [
'onEmpty' => 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_MERCHANT_ID_EMPTY',
'onShort' => 'OSCUNZER_ERROR_TRANSMITTING_APPLEPAY_MERCHANT_ID_TOO_SHORT'
];

$newValue = $this->getUnzerStringRequestEscapedParameter(
$systemMode . '-' . 'applepay_merchant_identifier'
);

$oldValue = $this->moduleSettings->getApplePayMerchantIdentifier();

$this->setIsUpdate($oldValue, $newValue);

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

if ($isValid) {
$this->moduleSettings->setApplePayMerchantIdentifier($newValue);
}
}

private function saveMerchantCert(string $systemMode): void
{
$errorIds = [
Expand Down
8 changes: 6 additions & 2 deletions src/Controller/OrderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,12 @@ private function cleanUpCancelledPayments(): void

$isOrderAlreadyCancelled = Registry::getSession()->getVariable('orderCancellationProcessed');
if (!$isOrderAlreadyCancelled) {
$iSuccess = (int)$oOrder->finalizeUnzerOrderAfterRedirect($oBasket, $oUser);
$iSuccess = (int)$oOrder->finalizeUnzerOrderAfterRedirect(
$oBasket,
$oUser,
['finalizeCancellation' => true]
);

$oUser->onOrderExecute($oBasket, $iSuccess);
}
Registry::getSession()->deleteVariable('orderCancellationProcessed');
Expand All @@ -506,7 +511,6 @@ private function cleanUpCancelledPayments(): void

Registry::getSession()->setVariable('sess_challenge', $this->getUtilsObjectInstance()->generateUID());
Registry::getSession()->setBasket($oBasket);
Registry::getSession()->deleteVariable('orderCancellationProcessed');
$this->redirectUserToCheckout($unzerService, $oOrder);
}
}
Expand Down
19 changes: 14 additions & 5 deletions src/Model/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ class Order extends Order_parent
/**
* @param Basket $oBasket
* @param User $oUser
* @param array $params
* @return int|bool
* @throws Exception
*
* @throws \UnzerSDK\Exceptions\UnzerApiException
* @SuppressWarnings(PHPMD.ElseExpression)
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function finalizeUnzerOrderAfterRedirect(
Basket $oBasket,
User $oUser
User $oUser,
array $params = []
) {
$orderId = Registry::getSession()->getVariable('sess_challenge');
$orderId = is_string($orderId) ? $orderId : '';
Expand Down Expand Up @@ -97,10 +99,17 @@ public function finalizeUnzerOrderAfterRedirect(
} else {
if ($unzerPaymentStatus !== PaymentService::STATUS_NOT_FINISHED) {
Registry::getSession()->setVariable('orderCancellationProcessed', true);
$iRet = 1; //TODO: not sure if this is correct - this is hardcoded for the Paypal cancellaction
}
$this->_setOrderStatus($unzerPaymentStatus); //ERROR if paypal

$this->_setOrderStatus($unzerPaymentStatus);
$this->setTmpOrderStatus($unzerOrderId, $unzerPaymentStatus);

if (!isset($params['finalizeCancellation'])) {
// then we consider this is a payment with only auth mode and the order is completed
$this->sendOrderConfirmationEmail($oUser, $oBasket, $oUserPayment);
}

$iRet = 1;
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/Service/FlexibleSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

namespace OxidSolutionCatalysts\Unzer\Service;

use Exception;
use OxidEsales\Eshop\Application\Model\Order;
use ReflectionClass;
use ReflectionException;
use stdClass;

class FlexibleSerializer
Expand Down Expand Up @@ -112,11 +110,12 @@ private function makeSerializable($data)
/**
* Restore unserializable data, including objects of allowed classes.
*
* @param mixed $data The data to be restored.
* @param mixed $data The data to be restored.
* @param array $allowedClasses An array of fully qualified class names that are allowed to be restored.
* @return mixed The restored data.
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ElseExpression)
* @throws \ReflectionException
*/
private function restoreUnserializable($data, array $allowedClasses)
{
Expand All @@ -127,7 +126,10 @@ private function restoreUnserializable($data, array $allowedClasses)
}

if (is_object($data) && isset($data->__class)) {
$className = $data->__class;
$className = get_parent_class($data->__class);
if (!$className) {
$className = $data->__class;
}
if ($this->isAllowedClass($className, $allowedClasses)) {
$reflection = new ReflectionClass($className);
$restored = $reflection->newInstanceWithoutConstructor();
Expand Down
Loading

0 comments on commit 9e0f946

Please sign in to comment.