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();
}
}