<?php

namespace TbiBank\FusionPay\Test\Unit\Model;

use PHPUnit\Framework\TestCase;
use TbiBank\FusionPay\Model\ProgrammaticOrderContext;

/**
 * Behaviour under test: TbiBank\FusionPay\Model\ProgrammaticOrderContext
 *
 * ProgrammaticOrderContext replaces the deprecated Magento\Framework\Registry usage that used
 * to flag "is_programmatic_order" globally (CKT-3844). It is a per-instance (per-request, since
 * it is wired as a normal DI object, not a singleton-shared global) boolean flag with exactly
 * two states: activate() flips it on, it starts and otherwise stays off.
 *
 * Given a freshly constructed ProgrammaticOrderContext
 * When  nothing has called activate() yet
 * Then  isActive() reports false (fail-closed default — a Gateway-created request must not
 *       silently bypass payment-method visibility unless explicitly activated).
 */
class ProgrammaticOrderContextTest extends TestCase
{
    public function testIsActiveDefaultsToFalse(): void
    {
        // Given a freshly constructed context / When we ask isActive() without ever activating
        $context = new ProgrammaticOrderContext();

        // Then it reports inactive
        $this->assertFalse($context->isActive());
    }

    /**
     * Given a freshly constructed context
     * When activate() is called
     * Then isActive() flips to true
     */
    public function testActivateFlipsIsActiveToTrue(): void
    {
        $context = new ProgrammaticOrderContext();

        $context->activate();

        $this->assertTrue($context->isActive());
    }

    /**
     * Given a context that has already been activated
     * When activate() is called again
     * Then it stays active (idempotent — Gateway::execute() may reach the activation line more
     * than once in a single request in principle; the flag must never "toggle back off").
     */
    public function testActivateIsIdempotent(): void
    {
        $context = new ProgrammaticOrderContext();

        $context->activate();
        $context->activate();

        $this->assertTrue($context->isActive());
    }

    /**
     * Given two independently constructed contexts
     * When one is activated
     * Then the other is unaffected — this class must NOT behave like a shared/static registry,
     * which is exactly the bug class this replacement was introduced to avoid.
     */
    public function testActivatingOneInstanceDoesNotAffectAnother(): void
    {
        $activated = new ProgrammaticOrderContext();
        $untouched = new ProgrammaticOrderContext();

        $activated->activate();

        $this->assertTrue($activated->isActive());
        $this->assertFalse($untouched->isActive());
    }
}
