Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cancel action - empty orderId in details #34

Merged
merged 2 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/Action/CancelAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ public function execute($request): void
$payment = PaymentHelper::ensurePayment($request->getFirstModel());
$orderId = PaymentHelper::getOrderId($model, $payment);
Assert::notEmpty($orderId, 'OrderId must be set on cancel action.');
$configKey = PaymentHelper::getConfigKey($model, $payment);

if (!$this->canCancelPayment($model, $payment)) {
if (!$this->canCancelPayment($orderId, $configKey)) {
throw new CannotCancelPaymentException('Order status is final, cannot cancel payment.');
}

$this->orderRequestService->cancel($model->orderId(), PaymentHelper::getConfigKey($model, $payment));
$this->orderRequestService->cancel($orderId, $configKey);
}

public function supports($request): bool
Expand All @@ -55,9 +56,9 @@ public function supports($request): bool
/**
* @throws PayUException
*/
private function canCancelPayment(Model $model, PaymentInterface $payment): bool
private function canCancelPayment(string $orderId, ?string $configKey): bool
{
$response = $this->orderRequestService->retrieve($model->orderId(), PaymentHelper::getConfigKey($model, $payment));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the orderId from the model was used, but it does not always have to exist, PaymentHelper::getOrderId tries to take the orderId from firstModel in the first place

$response = $this->orderRequestService->retrieve($orderId, $configKey);

return !$response->orders[0]->status->isFinal();
}
Expand Down
34 changes: 34 additions & 0 deletions tests/Unit/Action/CancelActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function successTest(): void
);

$payment = new Payment();
$payment->setConfigKey('pos2');
$payment->setDetails(FileTestUtil::decodeJsonFromFile(__DIR__ . '/../../Integration/Action/data/detailsWithOrderId.json'));

$request = new Cancel($payment);
Expand All @@ -61,6 +62,7 @@ public function orderHasFinalStatusTest(): void
);

$payment = new Payment();
$payment->setConfigKey('pos2');
$payment->setDetails(FileTestUtil::decodeJsonFromFile(__DIR__ . '/../../Integration/Action/data/detailsWithOrderId.json'));

$request = new Cancel($payment);
Expand All @@ -69,6 +71,38 @@ public function orderHasFinalStatusTest(): void
$action->execute($request);
}

/**
* @test
*/
public function emptyOrderIdInDetails(): void
{
$action = $this->getCancelAction(
OrderCanceledResponse::fromResponse(
FileTestUtil::decodeJsonFromFile(
__DIR__ . '/../../Integration/Request/data/orderCanceledResponse.json'
)
),
OrderRetrieveResponse::fromResponse(
FileTestUtil::decodeJsonFromFile(
__DIR__ . '/../../Integration/Request/data/retrieveOrderResponse.json'
)
)
);

$details = FileTestUtil::decodeJsonFromFile(__DIR__ . '/../../Integration/Action/data/detailsWithOrderId.json');
$details['orderId'] = null;

$payment = new Payment();
$payment->setConfigKey('pos2');
$payment->setDetails($details);
$payment->setOrderId('123');

$request = new Cancel($payment);
$request->setModel($payment->getDetails());

$action->execute($request);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see test with empty orderId in details and firstModel - we expect exception then. It's also nice to test this behavior

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


private function getCancelAction(
?OrderCanceledResponse $orderCanceledResponse,
OrderRetrieveResponse $retrieveOrderResponse
Expand Down
Loading