Skip to content

SL-371 Auto-refresh account payment methods when settings open#335

Merged
justelis22 merged 3 commits into
feature/react-admin-settingsfrom
SL-350/settings-autorefresh
Jul 10, 2026
Merged

SL-371 Auto-refresh account payment methods when settings open#335
justelis22 merged 3 commits into
feature/react-admin-settingsfrom
SL-350/settings-autorefresh

Conversation

@justelis22

Copy link
Copy Markdown
Collaborator

Part of SL-350 settings redesign. Phase 3 — auto-refresh account config.

Ticket

  • SL-371 — re-read the account's payment methods when the Payment Methods settings open.
    • Reconcile the stored list against the account on page open (enabled flags preserved, newly added methods default to disabled), persisted for the front office — previously only on Save.
    • On API failure, fall back to the last-known stored list instead of an empty page; stored config is never wiped (new SaferPayPaymentRepository::getAllPaymentMethodsNames).

Tests

New unit test tests/Unit/Service/SaferPayRefreshPaymentsServiceTest.php (2 tests): reconcile preserves-enabled / adds-new-disabled / drops-removed, and the no-active-methods early return.

Verification

Unit tests green; php -l clean.

- Reconcile stored payment methods against the account on page open (persisted, enabled flags preserved, new methods disabled by default) instead of only on save
- On API failure, fall back to the last-known stored list instead of an empty page; never wipes stored config (new SaferPayPaymentRepository::getAllPaymentMethodsNames)
- Unit test for the refresh reconcile behavior (preserve/added-disabled/removed-dropped + early-return)

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the admin controller to automatically refresh and reconcile payment methods from the Saferpay API when opening the settings page, falling back to stored payment methods if the API is unreachable. It also introduces a new unit test suite for the refresh service. The review feedback highlights a performance issue due to redundant back-to-back API requests, suggesting runtime caching, and points out deprecated PHPUnit methods (withConsecutive and setMethods) in the new tests that should be updated for PHPUnit 10 compatibility.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 704 to 710
/** @var SaferPayRefreshPaymentsService $refreshPaymentsService */
$refreshPaymentsService = $this->module->getService(SaferPayRefreshPaymentsService::class);
$refreshPaymentsService->refreshPayments();

/** @var SaferPayObtainPaymentMethods $obtainMethods */
$obtainMethods = $this->module->getService(SaferPayObtainPaymentMethods::class);
$paymentMethods = $obtainMethods->obtainPaymentMethodsNamesAsArray();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Every time the Payment Methods settings page is opened, two identical, blocking HTTP requests are made to the Saferpay API back-to-back:

  1. First, inside $refreshPaymentsService->refreshPayments(), which calls $this->obtainPayments->obtainPaymentMethodsNamesAsArray().
  2. Second, immediately after, $obtainMethods->obtainPaymentMethodsNamesAsArray() is called directly in getPaymentMethodsData().

This significantly increases the page load time and performs redundant network requests.

Recommendation

To resolve this, implement a simple runtime cache (in-memory caching) inside the SaferPayObtainPaymentMethods service so that subsequent calls within the same request lifecycle return the cached result instantly.

For example, in src/Service/SaferPayObtainPaymentMethods.php:

class SaferPayObtainPaymentMethods
{
    /** @var array|null */
    private $cachedPaymentMethods;

    public function obtainPaymentMethods(): array
    {
        if ($this->cachedPaymentMethods !== null) {
            return $this->cachedPaymentMethods;
        }

        $paymentMethods = [];
        // ... existing fetching logic ...

        $this->cachedPaymentMethods = $paymentMethods;

        return $paymentMethods;
    }
}

Comment on lines +51 to +65
$paymentRepository->expects($this->exactly(2))
->method('insertPayment')
->withConsecutive(
[['name' => 'VISA', 'active' => 1]],
[['name' => 'TWINT', 'active' => 0]]
);
// Custom-form flag preserved for VISA (true -> 1), default 0 for the new TWINT.
$fieldRepository->expects($this->exactly(2))
->method('insertField')
->withConsecutive(
[['name' => 'VISA', 'active' => 1]],
[['name' => 'TWINT', 'active' => 0]]
);

$this->makeService($paymentRepository, $obtainPaymentMethods, $fieldRepository)->refreshPayments();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The withConsecutive() method is deprecated in PHPUnit 9.6 and completely removed in PHPUnit 10. Using it will trigger deprecation warnings and block future PHPUnit upgrades.

Recommendation

Instead of withConsecutive(), you can collect the arguments using willReturnCallback() and assert them afterward. This is fully compatible with PHPUnit 10+ and avoids deprecation warnings.

        $insertedPayments = [];
        $paymentRepository->expects($this->exactly(2))
            ->method('insertPayment')
            ->willReturnCallback(function ($data) use (&$insertedPayments) {
                $insertedPayments[] = $data;
            });

        // Custom-form flag preserved for VISA (true -> 1), default 0 for the new TWINT.
        $insertedFields = [];
        $fieldRepository->expects($this->exactly(2))
            ->method('insertField')
            ->willReturnCallback(function ($data) use (&$insertedFields) {
                $insertedFields[] = $data;
            });

        $this->makeService($paymentRepository, $obtainPaymentMethods, $fieldRepository)->refreshPayments();

        $this->assertEquals([
            ['name' => 'VISA', 'active' => 1],
            ['name' => 'TWINT', 'active' => 0],
        ], $insertedPayments);

        $this->assertEquals([
            ['name' => 'VISA', 'active' => 1],
            ['name' => 'TWINT', 'active' => 0],
        ], $insertedFields);

Comment on lines +128 to +136
private function createMockWithMethods($class, array $methods)
{
$builder = $this->getMockBuilder($class)->disableOriginalConstructor();
if (!empty($methods)) {
$builder->setMethods($methods);
}

return $builder->getMock();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The setMethods() method is deprecated in PHPUnit 9 and removed in PHPUnit 10. It should be replaced with onlyMethods() for existing methods on the class.

    private function createMockWithMethods($class, array $methods)
    {
        $builder = $this->getMockBuilder($class)->disableOriginalConstructor();
        if (!empty($methods)) {
            $builder->onlyMethods($methods);
        }

        return $builder->getMock();
    }

Justas and others added 2 commits July 10, 2026 11:36
Address review feedback: refreshPayments() already persists the account's methods, so read
the list back from storage instead of calling obtainPaymentMethodsNamesAsArray() a second
time. Falls back to a live fetch only when nothing was persisted (fresh setup / no-active
early return). Removes the redundant back-to-back API request.
@justelis22 justelis22 merged commit c493512 into feature/react-admin-settings Jul 10, 2026
0 of 2 checks passed
@justelis22 justelis22 deleted the SL-350/settings-autorefresh branch July 10, 2026 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant