date_recur-8.x-2.2/tests/src/Kernel/DateRecurBasicFormatterTest.php

tests/src/Kernel/DateRecurBasicFormatterTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\date_recur\Kernel;

use Drupal\Core\Datetime\DateFormatInterface;
use Drupal\Core\Datetime\Entity\DateFormat;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\date_recur\Entity\DateRecurInterpreter;
use Drupal\date_recur\Entity\DateRecurInterpreterInterface;
use Drupal\date_recur_entity_test\Entity\DrEntityTestEntity as DrEntityTest;
use Drupal\KernelTests\KernelTestBase;
use Drupal\user\Entity\User;

/**
 * Tests date recur formatter.
 *
 * @group date_recur
 * @coversDefaultClass \Drupal\date_recur\Plugin\Field\FieldFormatter\DateRecurBasicFormatter
 */
class DateRecurBasicFormatterTest extends KernelTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'date_recur_entity_test',
    'entity_test',
    'datetime',
    'datetime_range',
    'date_recur',
    'field',
    'user',
    // System provides 'time' template.
    'system',
  ];

  /**
   * A date format for testing.
   *
   * @var \Drupal\Core\Datetime\DateFormatInterface
   */
  private DateFormatInterface $dateFormat;

  /**
   * An interpreter for testing.
   *
   * @var \Drupal\date_recur\Entity\DateRecurInterpreterInterface
   */
  private DateRecurInterpreterInterface $interpreter;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $this->installEntitySchema('dr_entity_test');

    $this->dateFormat = DateFormat::create([
      'id' => $this->randomMachineName(),
      'pattern' => 'r',
    ]);
    $this->dateFormat->save();
    $this->interpreter = DateRecurInterpreter::create([
      'id' => $this->randomMachineName(),
      'plugin' => 'rl',
      'settings' => [
        'show_start_date' => TRUE,
        'show_until' => TRUE,
        'date_format' => $this->dateFormat->id(),
        'show_infinite' => TRUE,
      ],
    ]);
    $this->interpreter->save();
  }

  /**
   * Tests interpretation.
   */
  public function testFormatterInterpretation(): void {
    $dateFormatId = $this->dateFormat->id();
    $settings = [
      'format_type' => $dateFormatId,
      'occurrence_format_type' => $dateFormatId,
      'same_end_date_format_type' => $dateFormatId,
      'interpreter' => $this->interpreter->id(),
    ];
    $this->renderFormatterSettings($this->createRecurringEntity(), $settings);

    $interpretation = $this->cssSelect('.date-recur-interpretation');
    static::assertCount(1, $interpretation);
    $assertInnerText = (string) $interpretation[0];
    static::assertEquals('weekly on Monday, Tuesday, Wednesday, Thursday and Friday, starting from Mon, 16 Jun 2014 09:00:00 +1000, forever', $assertInnerText);
  }

  /**
   * Tests occurrences.
   */
  public function testFormatterOccurrencesPerItem(): void {
    $this->dateFormat = DateFormat::create([
      'id' => $this->randomMachineName(),
      'pattern' => 'H:i',
    ]);
    $this->dateFormat->save();
    $dateFormatId = $this->dateFormat->id();
    $settings = [
      'show_next' => 2,
      'count_per_item' => TRUE,
      'format_type' => $dateFormatId,
      'occurrence_format_type' => $dateFormatId,
      'same_end_date_format_type' => $dateFormatId,
      'interpreter' => $this->interpreter->id(),
    ];

    $entity = DrEntityTest::create();
    $entity->dr = [
      [
        // 10am-4pm weekdaily.
        'value' => '2008-06-16T00:00:00',
        'end_value' => '2008-06-16T06:00:00',
        'rrule' => 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR',
        'infinite' => '1',
        'timezone' => 'Australia/Sydney',
      ],
      [
        // 9am-5pm weekdaily.
        'value' => '2014-06-15T23:00:00',
        'end_value' => '2014-06-16T07:00:00',
        'rrule' => 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR',
        'infinite' => '1',
        'timezone' => 'Australia/Sydney',
      ],
    ];
    $this->renderFormatterSettings($entity, $settings);

    $occurrences = $this->cssSelect('.date-recur-occurrences li');
    static::assertCount(4, $occurrences);
    static::assertEquals('10:00', (string) $occurrences[0]->time[0]);
    static::assertEquals('16:00', (string) $occurrences[0]->time[1]);
    static::assertEquals('10:00', (string) $occurrences[1]->time[0]);
    static::assertEquals('16:00', (string) $occurrences[1]->time[1]);
    static::assertEquals('09:00', (string) $occurrences[2]->time[0]);
    static::assertEquals('17:00', (string) $occurrences[2]->time[1]);
    static::assertEquals('09:00', (string) $occurrences[3]->time[0]);
    static::assertEquals('17:00', (string) $occurrences[3]->time[1]);
  }

  /**
   * Tests occurrences.
   */
  public function testFormatterOccurrencesNotPerItem(): void {
    $this->dateFormat = DateFormat::create([
      'id' => $this->randomMachineName(),
      'pattern' => 'H:i',
    ]);
    $this->dateFormat->save();
    $dateFormatId = $this->dateFormat->id();
    $settings = [
      'show_next' => 2,
      'count_per_item' => FALSE,
      'format_type' => $dateFormatId,
      'occurrence_format_type' => $dateFormatId,
      'same_end_date_format_type' => $dateFormatId,
      'interpreter' => $this->interpreter->id(),
    ];

    $entity = DrEntityTest::create();
    $entity->dr = [
      [
        // 10am-4pm weekdaily.
        'value' => '2008-06-16T00:00:00',
        'end_value' => '2008-06-16T06:00:00',
        'rrule' => 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR',
        'infinite' => '1',
        'timezone' => 'Australia/Sydney',
      ],
      [
        // 9am-5pm weekdaily.
        'value' => '2014-06-15T23:00:00',
        'end_value' => '2014-06-16T07:00:00',
        'rrule' => 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR',
        'infinite' => '1',
        'timezone' => 'Australia/Sydney',
      ],
    ];
    $this->renderFormatterSettings($entity, $settings);

    $occurrences = $this->cssSelect('.date-recur-occurrences li');
    static::assertCount(2, $occurrences);
    static::assertEquals('10:00', (string) $occurrences[0]->time[0]);
    static::assertEquals('16:00', (string) $occurrences[0]->time[1]);
    static::assertEquals('10:00', (string) $occurrences[1]->time[0]);
    static::assertEquals('16:00', (string) $occurrences[1]->time[1]);
  }

  /**
   * Tests setting summary.
   */
  public function testFormatterSettingsSummary(): void {
    /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $efm */
    $efm = $this->container->get(EntityFieldManagerInterface::class);
    $definitions = $efm->getBaseFieldDefinitions('dr_entity_test');

    $separator = $this->randomMachineName(4);

    $dateFormatId = $this->dateFormat->id();
    $options = [
      'configuration' => [
        'label' => 'above',
        'type' => 'date_recur_basic_formatter',
        'settings' => [
          'format_type' => $dateFormatId,
          'occurrence_format_type' => $dateFormatId,
          'same_end_date_format_type' => $dateFormatId,
          'interpreter' => $this->interpreter->id(),
          'count_per_item' => TRUE,
          'separator' => $separator,
          'show_next' => 5,
        ],
      ],
      'field_definition' => $definitions['dr'],
      'prepare' => TRUE,
      'view_mode' => 'full',
    ];

    /** @var \Drupal\Core\Field\FormatterPluginManager $fieldFormatterManager */
    $fieldFormatterManager = $this->container->get('plugin.manager.field.formatter');
    $instance = $fieldFormatterManager->getInstance($options);

    // Generate after summary to prevent random test failures.
    $now = new \DateTime('now');
    $formatSample = $now->format($this->dateFormat->getPattern());

    /** @var array<string|\Drupal\Core\StringTranslation\TranslatableMarkup|array{'#context': array{label: \Drupal\Core\StringTranslation\TranslatableMarkup}}> $summary */
    $summary = $instance->settingsSummary();
    $summary = array_map(function (string|TranslatableMarkup|array $summary): string {
      return (string) (is_array($summary) ? $summary['#context']['label'] : $summary);
    }, $summary);
    static::assertContains('Format: ' . $formatSample, $summary);
    static::assertContains('Separator: <em class="placeholder">' . $separator . '</em>', $summary);
    static::assertContains('Show maximum of 5 occurrences per field item', $summary);
  }

  /**
   * Tests setting summary where count is shared across items.
   */
  public function testFormatterSettingsSummaryNotPerItem(): void {
    /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $efm */
    $efm = $this->container->get(EntityFieldManagerInterface::class);
    $definitions = $efm->getBaseFieldDefinitions('dr_entity_test');

    $dateFormatId = $this->dateFormat->id();
    $options = [
      'configuration' => [
        'label' => 'above',
        'type' => 'date_recur_basic_formatter',
        'settings' => [
          'format_type' => $dateFormatId,
          'occurrence_format_type' => $dateFormatId,
          'same_end_date_format_type' => $dateFormatId,
          'interpreter' => $this->interpreter->id(),
          'count_per_item' => FALSE,
          'separator' => '-',
          'show_next' => 10,
        ],
      ],
      'field_definition' => $definitions['dr'],
      'prepare' => TRUE,
      'view_mode' => 'full',
    ];

    /** @var \Drupal\Core\Field\FormatterPluginManager $fieldFormatterManager */
    $fieldFormatterManager = $this->container->get('plugin.manager.field.formatter');
    $instance = $fieldFormatterManager->getInstance($options);
    /** @var array<string|\Drupal\Core\StringTranslation\TranslatableMarkup|array{'#context': array{label: \Drupal\Core\StringTranslation\TranslatableMarkup}}> $summary */
    $summary = $instance->settingsSummary();
    $summary = array_map(function (string|TranslatableMarkup|array $summary): string {
      return (string) (is_array($summary) ? $summary['#context']['label'] : $summary);
    }, $summary);
    static::assertContains('Show maximum of 10 occurrences across all field items', $summary);
  }

  /**
   * Tests setting summary occurrence sample for same day.
   */
  public function testFormatterSettingsSummarySampleOccurrenceSameDay(): void {
    /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $efm */
    $efm = $this->container->get('entity_field.manager');
    $definitions = $efm->getBaseFieldDefinitions('dr_entity_test');

    $dateFormatId = $this->dateFormat->id();
    $options = [
      'configuration' => [
        'label' => 'above',
        'type' => 'date_recur_basic_formatter',
        'settings' => [
          'format_type' => $dateFormatId,
          'occurrence_format_type' => $dateFormatId,
          'same_end_date_format_type' => $dateFormatId,
          'interpreter' => $this->interpreter->id(),
          'count_per_item' => FALSE,
          'separator' => '-',
          'show_next' => 10,
        ],
      ],
      'field_definition' => $definitions['dr'],
      'prepare' => TRUE,
      'view_mode' => 'full',
    ];

    /** @var \Drupal\Core\Field\FormatterPluginManager $fieldFormatterManager */
    $fieldFormatterManager = $this->container->get('plugin.manager.field.formatter');
    $instance = $fieldFormatterManager->getInstance($options);
    $summary = $instance->settingsSummary();

    $start = new \DateTime('today 9am');
    $endSameDay = clone $start;
    $endSameDay->setTime(17, 0, 0);

    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = $this->container->get('renderer');
    $rendered = $renderer->renderRoot($summary['sample_same_day']);
    // Remove newlines from Twig templates.
    $rendered = preg_replace('/\n/', '', (string) $rendered);
    $this->setRawContent($rendered);
    $this->removeWhiteSpace();
    $pattern = $this->dateFormat->getPattern();
    static::assertEquals(sprintf('Same day range: %s-%s', $start->format($pattern), $endSameDay->format($pattern)), $this->getTextContent());
  }

  /**
   * Tests setting summary occurrence sample for different day.
   */
  public function testFormatterSettingsSummarySampleOccurrenceDifferentDay(): void {
    /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $efm */
    $efm = $this->container->get('entity_field.manager');
    $definitions = $efm->getBaseFieldDefinitions('dr_entity_test');

    $dateFormatId = $this->dateFormat->id();
    $options = [
      'configuration' => [
        'label' => 'above',
        'type' => 'date_recur_basic_formatter',
        'settings' => [
          'format_type' => $dateFormatId,
          'occurrence_format_type' => $dateFormatId,
          'same_end_date_format_type' => $dateFormatId,
          'interpreter' => $this->interpreter->id(),
          'count_per_item' => FALSE,
          'separator' => '-',
          'show_next' => 10,
        ],
      ],
      'field_definition' => $definitions['dr'],
      'prepare' => TRUE,
      'view_mode' => 'full',
    ];

    /** @var \Drupal\Core\Field\FormatterPluginManager $fieldFormatterManager */
    $fieldFormatterManager = $this->container->get('plugin.manager.field.formatter');
    $instance = $fieldFormatterManager->getInstance($options);
    $summary = $instance->settingsSummary();

    $start = new \DateTime('today 9am');
    $endDifferentDay = clone $start;
    $endDifferentDay->setTime(17, 0, 0);
    $endDifferentDay->modify('+1 day');

    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = $this->container->get('renderer');
    $rendered = $renderer->renderRoot($summary['sample_different_day']);
    // Remove newlines from Twig templates.
    $rendered = preg_replace('/\n/', '', (string) $rendered);
    $this->setRawContent($rendered);
    $this->removeWhiteSpace();
    $pattern = $this->dateFormat->getPattern();
    static::assertEquals(sprintf('Different day range: %s-%s', $start->format($pattern), $endDifferentDay->format($pattern)), $this->getTextContent());
  }

  /**
   * Tests setting summary occurrence sample for different day.
   */
  public function testFormatterDependencies(): void {
    /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $efm */
    $efm = $this->container->get('entity_field.manager');
    $definitions = $efm->getBaseFieldDefinitions('dr_entity_test');

    $dateFormat1 = DateFormat::create(['id' => $this->randomMachineName()]);
    $dateFormat1->save();
    $dateFormat2 = DateFormat::create(['id' => $this->randomMachineName()]);
    $dateFormat2->save();
    $dateFormat3 = DateFormat::create(['id' => $this->randomMachineName()]);
    $dateFormat3->save();
    $options = [
      'configuration' => [
        'label' => 'above',
        'type' => 'date_recur_basic_formatter',
        'settings' => [
          'format_type' => $dateFormat1->id(),
          'occurrence_format_type' => $dateFormat2->id(),
          'same_end_date_format_type' => $dateFormat3->id(),
          'interpreter' => $this->interpreter->id(),
          'count_per_item' => FALSE,
          'separator' => '-',
          'show_next' => 10,
        ],
      ],
      'field_definition' => $definitions['dr'],
      'prepare' => TRUE,
      'view_mode' => 'full',
    ];

    /** @var \Drupal\Core\Field\FormatterPluginManager $fieldFormatterManager */
    $fieldFormatterManager = $this->container->get('plugin.manager.field.formatter');
    /** @var \Drupal\date_recur\Plugin\Field\FieldFormatter\DateRecurBasicFormatter $instance */
    $instance = $fieldFormatterManager->getInstance($options);
    $expectedConfigDependencies = [
      'core.date_format.' . $dateFormat1->id(),
      'core.date_format.' . $dateFormat2->id(),
      'core.date_format.' . $dateFormat3->id(),
      'date_recur.interpreter.' . $this->interpreter->id(),
    ];
    sort($expectedConfigDependencies);
    static::assertEquals($expectedConfigDependencies, $instance->calculateDependencies()['config']);
  }

  /**
   * Tests formatter output for same start/end date.
   *
   * It doesn't matter which time zone the data is in, we only check same date
   * for the current logged in user.
   */
  public function testFormatterSameDay(): void {
    $user = User::create([
      'uid' => 2,
      // UTC+10.
      'timezone' => 'Pacific/Port_Moresby',
    ]);
    $this->container->get('current_user')->setAccount($user);

    $dateFormatSameDate = DateFormat::create([
      'id' => $this->randomMachineName(),
      'pattern' => '\s\a\m\e \d\a\t\e',
    ]);
    $dateFormatSameDate->save();
    $settings = [
      'format_type' => $this->dateFormat->id(),
      'occurrence_format_type' => $this->dateFormat->id(),
      'same_end_date_format_type' => $dateFormatSameDate->id(),
      'interpreter' => $this->interpreter->id(),
    ];
    $entity = DrEntityTest::create();
    $entity->dr = [
      // 10pm-9:59:59pm HK time.
      'value' => '2014-06-14T14:00:00',
      'end_value' => '2014-06-15T13:59:59',
      'rrule' => '',
      'infinite' => '0',
      // HK is UTC+8.
      'timezone' => 'Asia/Hong_Kong',
    ];
    $this->renderFormatterSettings($entity, $settings);

    $dates = $this->cssSelect('time');
    static::assertCount(2, $dates);

    // First time is start date.
    static::assertEquals('Sun, 15 Jun 2014 00:00:00 +1000', (string) $dates[0]);

    // Second time is end date.
    static::assertEquals('same date', (string) $dates[1]);
  }

  /**
   * Renders the date recur formatter and sets the HTML ready to be asserted.
   *
   * @param \Drupal\date_recur_entity_test\Entity\DrEntityTestEntity $entity
   *   A date recur test entity.
   * @param array $settings
   *   Settings for date recur basic formatter.
   */
  protected function renderFormatterSettings(DrEntityTest $entity, array $settings): void {
    /** @var \Drupal\date_recur\Plugin\Field\FieldType\DateRecurFieldItemList $field */
    $field = $entity->dr;
    $build = $field->view([
      'type' => 'date_recur_basic_formatter',
      'settings' => $settings,
    ]);
    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = $this->container->get(RendererInterface::class);
    $this->setRawContent((string) $renderer->renderInIsolation($build));
  }

  /**
   * Creates a recurring entity.
   *
   * @return \Drupal\date_recur_entity_test\Entity\DrEntityTestEntity
   *   A recurring entity.
   */
  protected function createRecurringEntity(): DrEntityTest {
    $entity = DrEntityTest::create();
    $entity->dr = [
      'value' => '2014-06-15T23:00:00',
      'end_value' => '2014-06-16T07:00:00',
      'rrule' => 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR',
      'infinite' => '1',
      'timezone' => 'Australia/Sydney',
    ];
    return $entity;
  }

}

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

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