invoicemgmt-1.0.0/tests/src/Kernel/InvoicePreprocessTest.php

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

declare(strict_types=1);

namespace Drupal\Tests\invoicemgmt\Kernel;

use Drupal\file\Entity\File;
use Drupal\KernelTests\KernelTestBase;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\paragraphs\Entity\Paragraph;
use Drupal\paragraphs\Entity\ParagraphsType;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;

/**
 * Kernel tests for invoicemgmt template preprocessing.
 *
 * @group invoicemgmt
 */
class InvoicePreprocessTest extends KernelTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'system',
    'user',
    'field',
    'text',
    'node',
    'paragraphs',
    'entity_reference_revisions',
    'file',
    'taxonomy',
    'invoicemgmt',
  ];

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

    $this->installEntitySchema('user');
    $this->installEntitySchema('node');
    $this->installEntitySchema('paragraph');
    $this->installEntitySchema('file');
    $this->installEntitySchema('taxonomy_term');
    $this->installSchema('system', ['sequences']);
    $this->installSchema('node', ['node_access']);
    $this->installSchema('file', ['file_usage']);
    $this->installConfig(['system', 'field', 'node', 'paragraphs', 'taxonomy', 'invoicemgmt']);

    // Create content types and fields.
    $this->createContentTypes();
    $this->createVocabulary();
  }

  /**
   * Tests invoicemgmt_preprocess_node for invoice nodes.
   *
   * @covers invoicemgmt_preprocess_node
   */
  public function testInvoicePreprocessWithFullData(): void {
    // Set up configuration.
    $config = \Drupal::configFactory()->getEditable('invoicemgmt.settings');
    $config->set('seller_name', 'Test Company')
      ->set('seller_address', '123 Test Street')
      ->set('terms_conditions', 'Test terms and conditions')
      ->set('bank_details', 'Test bank details')
      ->set('currency', 'USD')
      ->set('footer_text', 'Thank you for your business!')
      ->set('primary_color', '#FF0000')
      ->set('secondary_color', '#00FF00')
      ->set('accent_color', '#0000FF')
      ->save();

    // Create client node.
    $client = Node::create([
      'type' => 'client',
      'title' => 'Test Client',
      'field_client_email' => 'client@test.com',
      'field_client_address' => '456 Client Street',
    ]);
    $client->save();

    // Create taxonomy term for item name.
    $term = Term::create([
      'vid' => 'invoice_items',
      'name' => 'Test Service',
    ]);
    $term->save();

    // Create invoice items.
    $item1 = Paragraph::create([
      'type' => 'invoice_item',
      'field_item_name' => $term->id(),
      'field_amount' => 100.50,
    ]);
    $item1->save();

    $item2 = Paragraph::create([
      'type' => 'invoice_item',
      'field_item_name' => $term->id(),
      'field_amount' => 200.25,
    ]);
    $item2->save();

    // Create invoice node.
    $invoice = Node::create([
      'type' => 'invoice',
      'title' => 'Test Invoice',
      'field_client' => $client->id(),
      'field_items' => [
        ['target_id' => $item1->id(), 'target_revision_id' => $item1->getRevisionId()],
        ['target_id' => $item2->id(), 'target_revision_id' => $item2->getRevisionId()],
      ],
    ]);
    $invoice->save();

    // Prepare variables for preprocessing.
    $variables = [
      'node' => $invoice,
      'view_mode' => 'full',
    ];

    // Call the preprocess function.
    invoicemgmt_preprocess_node($variables);

    // Assert invoice data.
    $this->assertEquals('Test Company', $variables['invoice_data']['seller_name']);
    $this->assertEquals('123 Test Street', $variables['invoice_data']['seller_address']);
    $this->assertEquals('Test terms and conditions', $variables['invoice_data']['terms_conditions']);
    $this->assertEquals('Test bank details', $variables['invoice_data']['bank_details']);
    $this->assertEquals('USD', $variables['invoice_data']['currency']);
    $this->assertEquals('$', $variables['invoice_data']['currency_symbol']);
    $this->assertEquals('Thank you for your business!', $variables['invoice_data']['footer_text']);
    $this->assertEquals('#FF0000', $variables['invoice_data']['primary_color']);
    $this->assertEquals('#00FF00', $variables['invoice_data']['secondary_color']);
    $this->assertEquals('#0000FF', $variables['invoice_data']['accent_color']);

    // Assert client data.
    $this->assertEquals('Test Client', $variables['client_data']['title']);
    $this->assertEquals('client@test.com', $variables['client_data']['field_client_email']);
    $this->assertEquals('456 Client Street', $variables['client_data']['field_client_address']);

    // Assert invoice items.
    $this->assertCount(2, $variables['invoice_items']);
    $this->assertEquals('Test Service', $variables['invoice_items'][0]['field_item_name']);
    $this->assertEquals('100.50', $variables['invoice_items'][0]['field_amount']);
    $this->assertEquals('Test Service', $variables['invoice_items'][1]['field_item_name']);
    $this->assertEquals('200.25', $variables['invoice_items'][1]['field_amount']);

    // Assert total.
    $this->assertEquals('300.75', $variables['invoice_items_total']);
  }

  /**
   * Tests preprocessing with minimal data.
   *
   * @covers invoicemgmt_preprocess_node
   */
  public function testInvoicePreprocessWithMinimalData(): void {
    // Create invoice node without client or items.
    $invoice = Node::create([
      'type' => 'invoice',
      'title' => 'Minimal Invoice',
    ]);
    $invoice->save();

    $variables = [
      'node' => $invoice,
      'view_mode' => 'full',
    ];

    invoicemgmt_preprocess_node($variables);

    // Should have default configuration values.
    $this->assertEquals('GBP', $variables['invoice_data']['currency']);
    $this->assertEquals('£', $variables['invoice_data']['currency_symbol']);
    $this->assertEquals('Thank you for your business!', $variables['invoice_data']['footer_text']);
    $this->assertEquals('#667eea', $variables['invoice_data']['primary_color']);
    $this->assertEquals('#764ba2', $variables['invoice_data']['secondary_color']);
    $this->assertEquals('#4299e1', $variables['invoice_data']['accent_color']);

    // Client data should be null.
    $this->assertNull($variables['client_data']);

    // Invoice items should be empty.
    $this->assertEmpty($variables['invoice_items']);
    $this->assertEquals('0.00', $variables['invoice_items_total']);
  }

  /**
   * Tests preprocessing with logo.
   *
   * @covers invoicemgmt_preprocess_node
   */
  public function testInvoicePreprocessWithLogo(): void {
    // Create a test file.
    $file = File::create([
      'filename' => 'test-logo.png',
      'uri' => 'public://test-logo.png',
      'status' => 1,
    ]);
    $file->save();

    // Set logo in configuration.
    $config = \Drupal::configFactory()->getEditable('invoicemgmt.settings');
    $config->set('logo', $file->id())
      ->set('seller_name', 'Logo Company')
      ->save();

    $invoice = Node::create([
      'type' => 'invoice',
      'title' => 'Invoice with Logo',
    ]);
    $invoice->save();

    $variables = [
      'node' => $invoice,
      'view_mode' => 'full',
    ];

    invoicemgmt_preprocess_node($variables);

    // Assert logo data.
    $this->assertArrayHasKey('logo', $variables['invoice_data']);
    $this->assertArrayHasKey('url', $variables['invoice_data']['logo']);
    $this->assertArrayHasKey('alt', $variables['invoice_data']['logo']);
    $this->assertEquals('Logo Company', $variables['invoice_data']['logo']['alt']);
  }

  /**
   * Tests preprocessing doesn't affect non-invoice nodes.
   *
   * @covers invoicemgmt_preprocess_node
   */
  public function testPreprocessDoesNotAffectNonInvoiceNodes(): void {
    $client = Node::create([
      'type' => 'client',
      'title' => 'Test Client',
    ]);
    $client->save();

    $variables = [
      'node' => $client,
      'view_mode' => 'full',
    ];

    invoicemgmt_preprocess_node($variables);

    // Should not add invoice-specific variables.
    $this->assertArrayNotHasKey('invoice_data', $variables);
    $this->assertArrayNotHasKey('client_data', $variables);
    $this->assertArrayNotHasKey('invoice_items', $variables);
    $this->assertArrayNotHasKey('invoice_items_total', $variables);
  }

  /**
   * Tests preprocessing doesn't affect other view modes.
   *
   * @covers invoicemgmt_preprocess_node
   */
  public function testPreprocessDoesNotAffectOtherViewModes(): void {
    $invoice = Node::create([
      'type' => 'invoice',
      'title' => 'Test Invoice',
    ]);
    $invoice->save();

    $variables = [
      'node' => $invoice,
      'view_mode' => 'teaser',
    ];

    invoicemgmt_preprocess_node($variables);

    // Should not add invoice-specific variables for non-full view modes.
    $this->assertArrayNotHasKey('invoice_data', $variables);
    $this->assertArrayNotHasKey('client_data', $variables);
    $this->assertArrayNotHasKey('invoice_items', $variables);
    $this->assertArrayNotHasKey('invoice_items_total', $variables);
  }

  /**
   * Tests currency symbol mapping.
   *
   * @covers invoicemgmt_preprocess_node
   */
  public function testCurrencySymbolMapping(): void {
    $currencies = [
      'GBP' => '£',
      'USD' => '$',
      'AED' => 'د.إ',
      'INR' => '₹',
      'EUR' => '€',
      'OTHER' => 'OTHER', // Unknown currency should return itself.
    ];

    foreach ($currencies as $currency => $expected_symbol) {
      $config = \Drupal::configFactory()->getEditable('invoicemgmt.settings');
      $config->set('currency', $currency)->save();

      $invoice = Node::create([
        'type' => 'invoice',
        'title' => "Invoice with {$currency}",
      ]);
      $invoice->save();

      $variables = [
        'node' => $invoice,
        'view_mode' => 'full',
      ];

      invoicemgmt_preprocess_node($variables);

      $this->assertEquals($expected_symbol, $variables['invoice_data']['currency_symbol']);

      // Clean up.
      $invoice->delete();
    }
  }

  /**
   * Creates content types and fields for testing.
   */
  protected function createContentTypes(): void {
    // Create invoice content type.
    $invoice_type = NodeType::create([
      'type' => 'invoice',
      'name' => 'Invoice',
    ]);
    $invoice_type->save();

    // Create client content type.
    $client_type = NodeType::create([
      'type' => 'client',
      'name' => 'Client',
    ]);
    $client_type->save();

    // Create paragraph type.
    $paragraph_type = ParagraphsType::create([
      'id' => 'invoice_item',
      'label' => 'Invoice Item',
    ]);
    $paragraph_type->save();

    // Create fields.
    $this->createEntityReferenceField('node', 'invoice', 'field_client', 'Client', 'node', 1, ['client']);
    $this->createEntityReferenceRevisionsField('node', 'invoice', 'field_items', 'Invoice Items', 'paragraph', -1);
    $this->createTextField('node', 'client', 'field_client_email', 'Client Email', 1);
    $this->createTextField('node', 'client', 'field_client_address', 'Client Address', 1);
    $this->createTaxonomyReferenceField('paragraph', 'invoice_item', 'field_item_name', 'Item Name', 'invoice_items', 1);
    $this->createDecimalField('paragraph', 'invoice_item', 'field_amount', 'Amount', 1);
  }

  /**
   * Creates vocabulary for testing.
   */
  protected function createVocabulary(): void {
    $vocabulary = Vocabulary::create([
      'vid' => 'invoice_items',
      'name' => 'Invoice Items',
    ]);
    $vocabulary->save();
  }

  /**
   * Helper method to create entity reference fields.
   */
  protected function createEntityReferenceField(string $entity_type, string $bundle, string $field_name, string $label, string $target_type, int $cardinality, array $target_bundles): void {
    $field_storage = \Drupal::entityTypeManager()->getStorage('field_storage_config')->create([
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'type' => 'entity_reference',
      'cardinality' => $cardinality,
      'settings' => [
        'target_type' => $target_type,
      ],
    ]);
    $field_storage->save();

    $field_config = \Drupal::entityTypeManager()->getStorage('field_config')->create([
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'bundle' => $bundle,
      'label' => $label,
      'settings' => [
        'handler' => 'default:' . $target_type,
        'handler_settings' => [
          'target_bundles' => array_combine($target_bundles, $target_bundles),
        ],
      ],
    ]);
    $field_config->save();
  }

  /**
   * Helper method to create entity reference revisions fields.
   */
  protected function createEntityReferenceRevisionsField(string $entity_type, string $bundle, string $field_name, string $label, string $target_type, int $cardinality): void {
    $field_storage = \Drupal::entityTypeManager()->getStorage('field_storage_config')->create([
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'type' => 'entity_reference_revisions',
      'cardinality' => $cardinality,
      'settings' => [
        'target_type' => $target_type,
      ],
    ]);
    $field_storage->save();

    $field_config = \Drupal::entityTypeManager()->getStorage('field_config')->create([
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'bundle' => $bundle,
      'label' => $label,
      'settings' => [
        'handler' => 'default:' . $target_type,
        'handler_settings' => [
          'target_bundles' => ['invoice_item'],
        ],
      ],
    ]);
    $field_config->save();
  }

  /**
   * Helper method to create text fields.
   */
  protected function createTextField(string $entity_type, string $bundle, string $field_name, string $label, int $cardinality): void {
    $field_storage = \Drupal::entityTypeManager()->getStorage('field_storage_config')->create([
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'type' => 'string',
      'cardinality' => $cardinality,
    ]);
    $field_storage->save();

    $field_config = \Drupal::entityTypeManager()->getStorage('field_config')->create([
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'bundle' => $bundle,
      'label' => $label,
    ]);
    $field_config->save();
  }

  /**
   * Helper method to create decimal fields.
   */
  protected function createDecimalField(string $entity_type, string $bundle, string $field_name, string $label, int $cardinality): void {
    $field_storage = \Drupal::entityTypeManager()->getStorage('field_storage_config')->create([
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'type' => 'decimal',
      'cardinality' => $cardinality,
      'settings' => [
        'precision' => 10,
        'scale' => 2,
      ],
    ]);
    $field_storage->save();

    $field_config = \Drupal::entityTypeManager()->getStorage('field_config')->create([
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'bundle' => $bundle,
      'label' => $label,
    ]);
    $field_config->save();
  }

  /**
   * Helper method to create taxonomy reference fields.
   */
  protected function createTaxonomyReferenceField(string $entity_type, string $bundle, string $field_name, string $label, string $vocabulary, int $cardinality): void {
    $field_storage = \Drupal::entityTypeManager()->getStorage('field_storage_config')->create([
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'type' => 'entity_reference',
      'cardinality' => $cardinality,
      'settings' => [
        'target_type' => 'taxonomy_term',
      ],
    ]);
    $field_storage->save();

    $field_config = \Drupal::entityTypeManager()->getStorage('field_config')->create([
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'bundle' => $bundle,
      'label' => $label,
      'settings' => [
        'handler' => 'default:taxonomy_term',
        'handler_settings' => [
          'target_bundles' => [$vocabulary => $vocabulary],
        ],
      ],
    ]);
    $field_config->save();
  }

}

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

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