<?php

declare(strict_types=1);

namespace Drupal\Tests\visitors\Unit\Form;

use Drupal\Tests\UnitTestCase;
use Drupal\visitors\Form\UpgradeForm;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Upgrade form test.
 *
 * @group visitors
 * @coversDefaultClass \Drupal\visitors\Form\UpgradeForm
 */
class UpgradeFormTest extends UnitTestCase {

  /**
   * The form.
   *
   * @var \Drupal\visitors\Form\UpgradeForm
   */
  protected $form;

  /**
   * The upgrade service.
   *
   * @var \Drupal\visitors\Service\UpgradeService|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $service;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $container = new ContainerBuilder();

    $this->service = $this->createMock('Drupal\visitors\Service\UpgradeService');
    $container->set('visitors.upgrade', $this->service);

    $container->set('string_translation', $this->getStringTranslationStub());

    \Drupal::setContainer($container);

    $this->form = new UpgradeForm();
  }

  /**
   * Test get form id.
   *
   * @covers ::getFormId
   */
  public function testGetFormId() {
    $this->assertEquals('visitors_upgrade', $this->form->getFormId());
  }

  /**
   * Test get question.
   *
   * @covers ::getQuestion
   */
  public function testGetQuestion() {
    $this->assertEquals('Migrate Visitors 8.x-2.x to 3.0.x', (string) $this->form->getQuestion());
  }

  /**
   * Test get description.
   *
   * @covers ::getDescription
   */
  public function testGetDescription() {
    $this->assertEquals('This action will upgrade the data.', (string) $this->form->getDescription());
  }

  /**
   * Test get submit button label.
   *
   * @covers ::getCancelUrl
   */
  public function testGetCancelUrl() {
    $url = $this->form->getCancelUrl();
    $this->assertEquals('visitors.settings', $url->getRouteName());
  }

  /**
   * Test submit form.
   *
   * @covers ::submitForm
   */
  public function testSubmitForm() {
    $form = [];
    $form_state = $this->createMock('Drupal\Core\Form\FormStateInterface');

    $ret = $this->form->submitForm($form, $form_state);
    $this->assertEquals(1, $ret);
  }

  /**
   * Test upgrade.
   *
   * @covers ::upgrade
   */
  public function testUpgrade() {
    $record = new \stdClass();
    $this->service->expects($this->once())
      ->method('getVisitorsRows')
      ->with(50)
      ->willReturn([$record]);

    $context = [
      'sandbox' => [
        'max' => 1,
        'current' => 0,
      ],
    ];

    $this->form::upgrade($context);

    $this->assertEquals(1, $context['sandbox']['max']);
  }

  /**
   * Test upgrade.
   *
   * @covers ::upgrade
   */
  public function testUpgradeNoRecords() {
    $this->service->expects($this->once())
      ->method('getTotal')
      ->willReturn(0);

    $context = [];

    $this->form::upgrade($context);

    $this->assertEquals(0, $context['sandbox']['max']);
  }

}
