paid_ads-8.x-1.x-dev/tests/src/Unit/PaypalGatewayTest.php

tests/src/Unit/PaypalGatewayTest.php
<?php

namespace Drupal\Tests\paid_ads\Unit;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormState;
use Drupal\Core\Logger\LoggerChannel;
use Drupal\Core\Logger\LoggerChannelFactory;
use Drupal\paid_ads\Entity\PaidPaymentInterface;
use Drupal\paid_ads\Plugin\PaidGateways\PaypalGateway;
use Drupal\Tests\UnitTestCase;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
use PHPUnit\Framework\MockObject\Stub;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

/**
 * Class PaypalGatewayTest.
 *
 * @group paid_ads
 */
class PaypalGatewayTest extends UnitTestCase {

  /**
   * Logger mock.
   *
   * @var \Psr\Log\LoggerInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $logger;

  /**
   * Http Client mock.
   *
   * @var \GuzzleHttp\ClientInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $httpClient;

  /**
   * Drupal entity type manager mock.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $entityTypeManager;

  /**
   * Debug flag.
   *
   * @var bool
   */
  protected $debug = FALSE;

  /**
   * Module configuration.
   *
   * @var array
   */
  private $config = [
    'paid_ads.gateways' => [
      'paid_ads' => [
        'gateways' => [
          'plugin_id' => [
            'mode' => 'https://api.sandbox.paypal.com',
            'client_id' => 'sometext',
            'secret_id' => 'someothertext',
          ],
        ],
      ],
    ],
  ];

  private $storages = [];

  /**
   * Mocks storages and methods for entity type manager.
   *
   * @param string $storage
   *   Storage name.
   * @param array $methods
   *   Methods to mock.
   *
   * @return \PHPUnit\Framework\MockObject\MockObject
   *   Storage mock.
   */
  private function mockStorage($storage, array $methods) {
    if (!isset($this->storages[$storage])) {
      $this->storages[$storage]['mock'] = $this->getMockBuilder(
        EntityStorageInterface::class
      )
        ->disableOriginalConstructor()
        ->getMock();
      $this->storages[$storage]['methods'] = [];
    }
    foreach ($methods as $name => $data) {
      if (!isset($this->storages[$storage]['methods'][$name])) {
        $this->storages[$storage]['methods'][$name] = $this->storages[$storage]['mock']->method(
          $name
        );
      }
      /** @var \PHPUnit\Framework\MockObject\Builder\InvocationMocker $method */
      $method = $this->storages[$storage]['methods'][$name];
      if (is_callable($data)) {
        $method->willReturnCallback($data);
      }
      elseif (is_array($data)) {
        $method->willReturnMap($data);
      }
      elseif ($data instanceof Stub) {
        $method->will($data);
      }
      else {
        $method->willReturn($data);
      }
    }
    return $this->storages[$storage]['mock'];
  }

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    $channel = $this->getMockBuilder(LoggerChannel::class)
      ->setConstructorArgs(['some'])
      ->setMethods(['log'])
      ->getMock();
    $channel->method('log')
      ->willReturnCallback(
        function ($level, $message, array $context = []) {
          if ($this->debug) {
            fwrite(STDOUT, $message . PHP_EOL);
          }
        }
      );
    $this->logger = $this->createConfiguredMock(
      LoggerChannelFactory::class,
      [
        'get' => $channel,
      ]
    );

    $this->entityTypeManager = $this->getMockBuilder(
      EntityTypeManagerInterface::class
    )
      ->disableOriginalConstructor()
      ->getMock();
    $this->entityTypeManager->method('getStorage')
      ->willReturnCallback(
        function ($name) {
          if (isset($this->storages[$name])) {
            return $this->storages[$name]['mock'];
          }
          else {
            throw new InvalidPluginDefinitionException($name);
          }
        }
      );

    $this->httpClient = $this->createPartialMock(Client::class, ['request']);
  }

  /**
   * Creates a new testing object.
   *
   * @return \Drupal\paid_ads\Plugin\PaidGateways\PaypalGateway
   *   New instance.
   */
  protected function getInstance($methods = NULL) {
    $mock = $this->getMockBuilder(PaypalGateway::class)
      ->setConstructorArgs(
        [
          [],
          'plugin_id',
          [],
          $this->getConfigFactoryStub($this->config),
          $this->logger,
          $this->entityTypeManager,
          $this->httpClient,
        ]
      )
      ->setMethods($methods)
      ->getMock();
    $mock->setStringTranslation($this->getStringTranslationStub());
    return $mock;
  }

  /**
   * Tests if the configuration is read properly.
   */
  public function testConfiguration() {
    $instance = $this->getInstance();
    $options = $this->config['paid_ads.gateways']['paid_ads']['gateways']['plugin_id'];
    self::assertEquals($options, $instance->getOptions());

    $form = $instance->buildConfigurationForm([], new FormState());
    self::assertEquals(
      $options['client_id'],
      $form['client_id']['#default_value']
    );
    self::assertEquals(
      $options['secret_id'],
      $form['secret_id']['#default_value']
    );
    self::assertEquals($options['mode'], $form['mode']['#default_value']);
  }

  /**
   * Tests if create order event handler calls to PayPal.
   */
  public function testPayPalApiCalledOnCreateOrder() {
    $config = &$this->config['paid_ads.gateways']['paid_ads']['gateways']['plugin_id'];
    $config['mode'] = $this->randomMachineName(16);
    $currency = $this->randomMachineName(3);
    $amount = random_int(1, 500);
    $payment = $this->getMockBuilder(PaidPaymentInterface::class)
      ->getMock();
    $payment->expects(self::atLeastOnce())
      ->method('setOrderId')
      ->with("someid");
    $payment->expects(self::atLeastOnce())
      ->method('getAmount')
      ->willReturn($amount);
    $payment->expects(self::atLeastOnce())
      ->method('getCurrency')
      ->willReturn($currency);

    $instance = $this->getInstance();
    $this->httpClient->expects(self::atLeastOnce())
      ->method('request')
      ->willReturnCallback(
        function ($method, $uri, array $options = []) use ($config, $amount, $currency) {
          self::assertEquals('post', $method);
          self::assertEquals($config['mode'] . '/v2/checkout/orders', $uri);
          self::assertEquals(
            [$config['client_id'], $config['secret_id']],
            $options['auth']
          );
          self::assertEquals(
            $amount,
            $options['json']['purchase_units'][0]['amount']['value']
          );
          self::assertEquals(
            $currency,
            $options['json']['purchase_units'][0]['amount']['currency_code']
          );
          return new Response(200, [], '{"id":"someid"}');
        }
      );

    $result = $instance->onCreatePayment(['payment' => $payment]);

    self::assertInstanceOf(JsonResponse::class, $result);
    self::assertEquals(200, $result->getStatusCode());
  }

  /**
   * Tests if exceptions are handled in create order request handler.
   */
  public function testOnCreateOrderHandlesExceptions() {
    $instance = $this->getInstance();
    $payment = $this->getMockBuilder(PaidPaymentInterface::class)
      ->getMock();
    $this->httpClient->expects(self::atLeastOnce())
      ->method('request')
      ->willThrowException(new Exception());
    $result = $instance->onCreatePayment(['payment' => $payment]);
    self::assertInstanceOf(JsonResponse::class, $result);
    self::assertEquals(500, $result->getStatusCode());

  }

  /**
   * Tests approve order event handler.
   */
  public function testPayPalApiCalledOnApprove() {
    $config = &$this->config['paid_ads.gateways']['paid_ads']['gateways']['plugin_id'];
    $config['mode'] = $this->randomMachineName(16);

    $paymentId = $this->randomMachineName();
    $payerId = $this->randomMachineName();

    // Fake request data.
    $request = $this->getMockBuilder(Request::class)
      ->setMethods(['get'])
      ->getMock();
    $request->method('get')
      ->willReturnMap(
        [
          ['paymentID', NULL, $paymentId],
          ['payerID', NULL, $payerId],
        ]
      );

    $paymentEntity = $this->getMockBuilder(PaidPaymentInterface::class)
      ->getMock();
    $paymentEntity->expects(self::any())
      ->method('execute');

    // "Add" entity with given id to the storage.
    $this->mockStorage(
      'paid_payment',
      [
        'loadByProperties' => [
          [['order_id' => $paymentId], [$paymentEntity]],
        ],
      ]
    );

    $this->httpClient->expects(self::atLeastOnce())
      ->method('request')
      ->willReturnCallback(
        // Check API call params.
        function ($method, $uri, $options) use ($config, $paymentId) {
          self::assertArraySubset(
            [
              'auth' => [$config['client_id'], $config['secret_id']],
              'headers' => ['Content-Type' => 'application/json'],
            ],
            $options
          );
          self::assertEquals('get', $method);
          self::assertEquals(
            $config['mode'] . '/v2/checkout/orders/' . $paymentId,
            $uri
          );
          // Return successfull response.
          return new Response(
            200,
            [],
            '{ "status": "COMPLETED","id":"' . $paymentId . '"}'
          );
        }
      );

    $instance = $this->getInstance();
    $result = $instance->onApprovePayment(['request' => $request]);

    self::assertInstanceOf(JsonResponse::class, $result);
    self::assertEquals(200, $result->getStatusCode());
  }

  /**
   * Tests if exceptions are handled correctly on approving an order.
   */
  public function testOnApproveOrderHandlesExceptions() {
    $instance = $this->getInstance();
    $paymentId = $this->randomMachineName();
    $payerId = $this->randomMachineName();

    $request = $this->getMockBuilder(Request::class)
      ->getMock();
    $request->method('get')
      ->willReturnMap(['paymentID', $paymentId, 'payerID', $payerId]);
    $this->httpClient->expects(self::atLeastOnce())
      ->method('request')
      ->willThrowException(new Exception());
    $result = $instance->onApprovePayment(['request' => $request]);
    self::assertInstanceOf(JsonResponse::class, $result);
    self::assertEquals(500, $result->getStatusCode());

  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc