You are here

SmsFrameworkDeliveryReportUpdateTest.php in SMS Framework 2.x

File

tests/src/Kernel/SmsFrameworkDeliveryReportUpdateTest.php
View source
<?php

declare (strict_types=1);
namespace Drupal\Tests\sms\Kernel;

use Drupal\Component\Serialization\Json;
use Drupal\KernelTests\KernelTestBase;
use Drupal\sms\Direction;
use Drupal\sms\Entity\SmsDeliveryReport;
use Drupal\sms\Message\SmsMessage;
use Drupal\sms\Message\SmsMessageReportStatus;
use Drupal\Tests\sms\Functional\SmsFrameworkTestTrait;
use Drupal\user\Entity\User;
use Symfony\Component\HttpFoundation\Request;

/**
 * Tests the update of SMS Delivery report entities.
 *
 * @group SMS Framework
 */
class SmsFrameworkDeliveryReportUpdateTest extends KernelTestBase {
  use SmsFrameworkTestTrait;

  /**
   * {@inheritdoc}
   */
  public static $modules = [
    'sms',
    'sms_test_gateway',
    'telephone',
    'dynamic_entity_reference',
    'user',
  ];

  /**
   * The default SMS provider service.
   *
   * @var \Drupal\sms\Provider\SmsProviderInterface
   */
  protected $defaultSmsProvider;

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    $this->httpClient = $this->container
      ->get('http_client');
    $this->defaultSmsProvider = $this->container
      ->get('sms.provider');
    $this
      ->installEntitySchema('sms');
    $this
      ->installEntitySchema('sms_result');
    $this
      ->installEntitySchema('sms_report');
    $this
      ->installEntitySchema('user');
  }

  /**
   * Tests that delivery reports are updated after initial sending.
   */
  public function testDeliveryReportUpdate() {
    $user = User::create();
    $request_time = $this->container
      ->get('datetime.time')
      ->getRequestTime();
    $test_gateway = $this
      ->createMemoryGateway();
    $test_gateway
      ->setRetentionDuration(Direction::OUTGOING, 1000)
      ->save();
    $this->container
      ->get('router.builder')
      ->rebuild();

    // Get the delivery reports url for simulating push delivery report.
    $url = $test_gateway
      ->getPushReportUrl()
      ->setAbsolute()
      ->toString();
    $sms_message = (new SmsMessage())
      ->setSender($this
      ->randomMachineName())
      ->addRecipients([
      '1234567890',
      '987654321',
    ])
      ->setMessage($this
      ->randomString())
      ->setUid($user
      ->id())
      ->setGateway($test_gateway)
      ->setDirection(Direction::OUTGOING);
    $this->defaultSmsProvider
      ->queue($sms_message);
    $this->container
      ->get('cron')
      ->run();
    $saved_reports = SmsDeliveryReport::loadMultiple();
    $this
      ->assertEquals(2, count($saved_reports));
    $this
      ->assertEquals(SmsMessageReportStatus::QUEUED, $saved_reports[1]
      ->getStatus());
    $this
      ->assertEquals(SmsMessageReportStatus::QUEUED, $saved_reports[2]
      ->getStatus());

    /** @var \Drupal\sms\Message\SmsDeliveryReportInterface $first_report */
    $first_report = reset($saved_reports);
    $this
      ->assertEquals($request_time, $first_report
      ->getStatusTime());
    $message_id = $first_report
      ->getMessageId();
    $status_time = $request_time + 100;

    // Simulate push delivery report.
    $request = $this
      ->buildDeliveryReportRequest($message_id, $first_report
      ->getRecipient(), 'pending', $status_time);
    $this->defaultSmsProvider
      ->processDeliveryReport($request, $test_gateway);
    $this->container
      ->get('entity_type.manager')
      ->getStorage('sms_report')
      ->resetCache();
    $updated_report = SmsDeliveryReport::load($first_report
      ->id());
    $this
      ->assertEquals('pending', $updated_report
      ->getStatus());
    $this
      ->assertEquals($status_time, $updated_report
      ->getStatusTime());
    $this
      ->assertNull($updated_report
      ->getTimeDelivered());

    // Simulate push delivery report.
    $status_time = $request_time + 500;
    $request = $this
      ->buildDeliveryReportRequest($message_id, $first_report
      ->getRecipient(), SmsMessageReportStatus::DELIVERED, $status_time);
    $this->defaultSmsProvider
      ->processDeliveryReport($request, $test_gateway);
    $this->container
      ->get('entity_type.manager')
      ->getStorage('sms_report')
      ->resetCache();
    $updated_report = SmsDeliveryReport::load($first_report
      ->id());
    $this
      ->assertEquals(SmsMessageReportStatus::DELIVERED, $updated_report
      ->getStatus());
    $this
      ->assertEquals($status_time, $updated_report
      ->getStatusTime());
    $this
      ->assertEquals($status_time, $updated_report
      ->getTimeDelivered());
  }

  /**
   * Builds a request containing a JSON-encoded delivery report.
   *
   * @param string $message_id
   *   The delivery report message ID.
   * @param string $recipient
   *   The delivery report recipient number.
   * @param string $status
   *   The message delivery status.
   * @param int $status_time
   *   The time for the current status update.
   *
   * @return \Symfony\Component\HttpFoundation\Request
   *   A request object containing JSON-encoded delivery reports.
   */
  protected function buildDeliveryReportRequest($message_id, $recipient, $status, $status_time) {
    $reports[] = [
      'message_id' => $message_id,
      'recipient' => $recipient,
      'status' => $status,
      'status_time' => $status_time,
      'status_message' => 'Message ' . $status,
    ];
    $request = new Request();
    $request->request
      ->set('delivery_report', Json::encode([
      'reports' => $reports,
    ]));
    return $request;
  }

}

Classes

Namesort descending Description
SmsFrameworkDeliveryReportUpdateTest Tests the update of SMS Delivery report entities.