Meta-fields for InvoiceTemplate, structured Customer address (#5519)

This commit is contained in:
Kevin Papst
2025-11-02 11:24:17 +01:00
committed by GitHub
parent 76821c24ed
commit cc64acf0f8
72 changed files with 2111 additions and 801 deletions

View File

@@ -487,6 +487,12 @@ abstract class APIControllerBaseTestCase extends AbstractControllerBaseTestCase
'timeBudget' => 'int',
'vatId' => '@string', // since 1.10
'budgetType' => '@string', // since 1.15
'addressLine1' => '@string', // since 2.32
'addressLine2' => '@string', // since 2.32
'addressLine3' => '@string', // since 2.32
'city' => '@string', // since 2.32
'postCode' => '@string', // since 2.32
'buyerReference' => '@string', // since 2.41
];
// if a project is embedded

View File

@@ -102,9 +102,9 @@ class InvoiceControllerTest extends AbstractControllerBaseTestCase
$form = $client->getCrawler()->filter('form[name=invoice_template_form]')->form();
$client->submit($form, [
'invoice_template_form' => [
'name' => 'Test',
'name' => 'FooBar Template',
'title' => 'Test invoice template',
'company' => 'Company name',
'customer' => 1,
'renderer' => 'default',
'calculator' => 'default',
'vat' => '27,937',
@@ -117,9 +117,9 @@ class InvoiceControllerTest extends AbstractControllerBaseTestCase
$this->assertHasFlashSuccess($client);
$template = $this->getEntityManager()->getRepository(InvoiceTemplate::class)->findAll()[0];
self::assertEquals('Test', $template->getName());
self::assertEquals('FooBar Template', $template->getName());
self::assertEquals('Test invoice template', $template->getTitle());
self::assertEquals('Company name', $template->getCompany());
self::assertEquals('Test', $template->getCompany());
self::assertEquals('default', $template->getRenderer());
self::assertEquals('default', $template->getCalculator());
self::assertEquals('27.937', $template->getVat());
@@ -145,8 +145,6 @@ class InvoiceControllerTest extends AbstractControllerBaseTestCase
self::assertEquals($template->getCalculator(), $values['calculator']);
self::assertEquals($template->getVat(), $values['vat']);
self::assertEquals($template->getRenderer(), $values['renderer']);
self::assertEquals($template->getCompany(), $values['company']);
self::assertEquals($template->getAddress(), $values['address']);
self::assertEquals($template->getPaymentTerms(), $values['paymentTerms']);
}
@@ -408,7 +406,7 @@ class InvoiceControllerTest extends AbstractControllerBaseTestCase
'invoice_template_form' => [
'name' => 'Test 2!',
'title' => 'Test invoice template',
'company' => 'Company name',
'customer' => 1,
'renderer' => 'default',
'calculator' => 'default',
]

View File

@@ -9,6 +9,7 @@
namespace App\Tests\DataFixtures;
use App\Entity\Customer;
use App\Entity\InvoiceTemplate;
use Doctrine\Persistence\ObjectManager;
use Faker\Factory;
@@ -27,10 +28,21 @@ class InvoiceTemplateFixtures implements TestFixture
$faker = Factory::create();
$customer = new Customer($faker->company());
$customer->setCountry($faker->countryCode());
$customer->setTimezone($faker->timezone());
$customer->setCompany('Company name');
$customer->setAddressLine1($faker->streetAddress());
$customer->setAddressLine2($faker->streetAddress());
$customer->setPostCode($faker->postcode());
$customer->setCity($faker->city());
$manager->persist($customer);
$template = new InvoiceTemplate();
$template->setName('Invoice');
$template->setTitle('Your company name');
$template->setCompany($faker->company());
$template->setCustomer($customer);
$template->setVat(19);
$template->setDueDays(14);
$template->setPaymentTerms(
@@ -39,9 +51,7 @@ class InvoiceTemplateFixtures implements TestFixture
'Please transfer the total amount within 14 days to the given account and use the invoice number ' .
'as reference.'
);
$template->setAddress(
$faker->streetAddress() . PHP_EOL .
$faker->city() . ' ' . $faker->postcode() . ', ' . $faker->country() . PHP_EOL .
$template->setContact(
'Phone: ' . $faker->phoneNumber() . PHP_EOL .
'Email: ' . $faker->safeEmail()
);

View File

@@ -35,6 +35,13 @@ class CustomerTest extends AbstractEntityTestCase
self::assertNull($sut->getVatId());
self::assertNull($sut->getContact());
self::assertNull($sut->getAddress());
self::assertNull($sut->getAddressLine1());
self::assertNull($sut->getAddressLine2());
self::assertNull($sut->getAddressLine3());
self::assertNull($sut->getFormattedAddress());
self::assertNull($sut->getCity());
self::assertNull($sut->getPostCode());
self::assertNull($sut->getBuyerReference());
self::assertNull($sut->getCountry());
self::assertEquals('EUR', $sut->getCurrency());
self::assertEquals('EUR', Customer::DEFAULT_CURRENCY);
@@ -137,6 +144,51 @@ class CustomerTest extends AbstractEntityTestCase
$sut->setCurrency(null);
self::assertNull($sut->getCurrency());
$sut->setBuyerReference('BR-876876876876');
self::assertEquals('BR-876876876876', $sut->getBuyerReference());
$sut->setBuyerReference(null);
self::assertNull($sut->getBuyerReference());
$sut->setAddressLine1('address line 1');
$sut->setAddressLine2('address line 2');
$sut->setAddressLine3('address line 3');
$sut->setCity('looney toon');
$sut->setPostcode('zip 12345');
$sut->setAddress('foo bar
sdfsadf
sdfarwt34
786876 uitiutziuz');
self::assertEquals('address line 1', $sut->getAddressLine1());
self::assertEquals('address line 2', $sut->getAddressLine2());
self::assertEquals('address line 3', $sut->getAddressLine3());
self::assertEquals('looney toon', $sut->getCity());
self::assertEquals('zip 12345', $sut->getPostCode());
self::assertEquals('foo bar
sdfsadf
sdfarwt34
786876 uitiutziuz', $sut->getAddress());
self::assertEquals('address line 1
address line 2
address line 3
zip 12345 looney toon', $sut->getFormattedAddress());
$sut->setAddressLine1(null);
$sut->setAddressLine2(null);
$sut->setAddressLine3(null);
$sut->setCity(null);
$sut->setPostcode(null);
$sut->setAddress(null);
self::assertNull($sut->getAddress());
self::assertNull($sut->getAddressLine1());
self::assertNull($sut->getAddressLine2());
self::assertNull($sut->getAddressLine3());
self::assertNull($sut->getFormattedAddress());
self::assertNull($sut->getCity());
self::assertNull($sut->getPostCode());
}
public function testMetaFields(): void
@@ -212,6 +264,11 @@ class CustomerTest extends AbstractEntityTestCase
['mobile', 'string'],
['fax', 'string'],
['homepage', 'string'],
['address_line1', 'string'],
['address_line2', 'string'],
['address_line3', 'string'],
['postcode', 'string'],
['city', 'string'],
['country', 'string'],
['currency', 'string'],
['timezone', 'string'],
@@ -222,6 +279,7 @@ class CustomerTest extends AbstractEntityTestCase
['visible', 'boolean'],
['comment', 'string'],
['billable', 'boolean'],
['buyer_reference', 'string'],
];
self::assertCount(\count($expected), $columns);

View File

@@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Entity;
use App\Entity\EntityWithMetaFields;
use App\Entity\InvoiceTemplate;
use App\Entity\InvoiceTemplateMeta;
use App\Entity\MetaTableTypeInterface;
use App\Entity\Timesheet;
use PHPUnit\Framework\Attributes\CoversClass;
#[CoversClass(InvoiceTemplateMeta::class)]
class InvoiceTemplateMetaTest extends AbstractMetaEntityTestCase
{
protected function getEntity(): EntityWithMetaFields
{
return new InvoiceTemplate();
}
protected function getMetaEntity(): MetaTableTypeInterface
{
return new InvoiceTemplateMeta();
}
public function testSetEntityThrowsException(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Expected instanceof InvoiceTemplate, received "App\Entity\Timesheet"');
$sut = new InvoiceTemplateMeta();
$sut->setEntity(new Timesheet());
}
}

View File

@@ -9,7 +9,11 @@
namespace App\Tests\Entity;
use App\Entity\Customer;
use App\Entity\CustomerMeta;
use App\Entity\InvoiceTemplate;
use App\Entity\InvoiceTemplateMeta;
use Doctrine\Common\Collections\Collection;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
@@ -35,59 +39,118 @@ class InvoiceTemplateTest extends TestCase
self::assertEquals('default', $sut->getRenderer());
self::assertEquals(30, $sut->getDueDays());
self::assertTrue($sut->isDecimalDuration()); // @phpstan-ignore method.deprecated
}
public function testSetNullForOptionalValues(): void
{
$sut = new InvoiceTemplate();
self::assertInstanceOf(InvoiceTemplate::class, $sut->setPaymentDetails(null));
self::assertInstanceOf(InvoiceTemplate::class, $sut->setVatId(null));
self::assertInstanceOf(InvoiceTemplate::class, $sut->setContact(null));
self::assertInstanceOf(InvoiceTemplate::class, $sut->setAddress(null));
self::assertInstanceOf(InvoiceTemplate::class, $sut->setPaymentTerms(null));
self::assertInstanceOf(Collection::class, $sut->getMetaFields());
self::assertEquals(0, $sut->getMetaFields()->count());
self::assertNull($sut->getMetaField('foo'));
}
public function testSetterAndGetter(): void
{
$sut = new InvoiceTemplate();
self::assertInstanceOf(InvoiceTemplate::class, $sut->setPaymentTerms('foo bar'));
$sut->setPaymentTerms('foo bar');
self::assertEquals('foo bar', $sut->getPaymentTerms());
self::assertInstanceOf(InvoiceTemplate::class, $sut->setPaymentDetails('iuasdzgf isdfhvlksdjfbnvl ksdfbglisbdf'));
$sut->setPaymentDetails('iuasdzgf isdfhvlksdjfbnvl ksdfbglisbdf');
self::assertEquals('iuasdzgf isdfhvlksdjfbnvl ksdfbglisbdf', $sut->getPaymentDetails());
self::assertInstanceOf(InvoiceTemplate::class, $sut->setContact('hello world'));
$sut->setContact('hello world');
self::assertEquals('hello world', $sut->getContact());
self::assertInstanceOf(InvoiceTemplate::class, $sut->setVat(7.31));
$sut->setVat(7.31);
self::assertEquals(7.31, $sut->getVat());
self::assertInstanceOf(InvoiceTemplate::class, $sut->setVatId('1234567890'));
$sut->setVatId('1234567890'); // @phpstan-ignore method.deprecated
self::assertEquals('1234567890', $sut->getVatId());
self::assertInstanceOf(InvoiceTemplate::class, $sut->setLanguage('de'));
$sut->setLanguage('de');
self::assertEquals('de', $sut->getLanguage());
self::assertInstanceOf(InvoiceTemplate::class, $sut->setNumberGenerator('foo'));
$sut->setNumberGenerator('foo');
self::assertEquals('foo', $sut->getNumberGenerator());
self::assertInstanceOf(InvoiceTemplate::class, $sut->setRenderer('bar'));
$sut->setRenderer('bar');
self::assertEquals('bar', $sut->getRenderer());
self::assertInstanceOf(InvoiceTemplate::class, $sut->setCalculator('fooBar'));
$sut->setCalculator('fooBar');
self::assertEquals('fooBar', $sut->getCalculator());
$sut->setCompany('looney toon'); // @phpstan-ignore method.deprecated
self::assertEquals('looney toon', $sut->getCompany());
$sut->setAddress('acme street, 1234 looney town, rainbow'); // @phpstan-ignore method.deprecated
self::assertEquals('acme street, 1234 looney town, rainbow', $sut->getAddress());
self::assertEquals($sut, clone $sut);
$customer = new Customer('foo');
$customer->setVatId('0987654321');
$customer->setCompany('bar');
$customer->setAddressLine1('elmstreet');
$customer->setAddressLine2('2nd floor');
$customer->setPostCode('4711');
$customer->setCity('Over the rainbow');
$sut->setCustomer($customer);
self::assertEquals('elmstreet
2nd floor
4711 Over the rainbow', $sut->getAddress());
self::assertEquals('bar', $sut->getCompany());
self::assertEquals('0987654321', $sut->getVatId());
}
public function testToString(): void
{
$sut = new InvoiceTemplate();
self::assertInstanceOf(InvoiceTemplate::class, $sut->setName('a template name'));
$sut->setName('a template name');
self::assertEquals('a template name', $sut->__toString());
self::assertEquals('a template name', (string) $sut);
}
public function testMetaFields(): void
{
$sut = new InvoiceTemplate();
$meta = new InvoiceTemplateMeta();
$meta->setName('foo')->setValue('bar2')->setType('test');
self::assertInstanceOf(InvoiceTemplate::class, $sut->setMetaField($meta));
self::assertEquals(1, $sut->getMetaFields()->count());
$result = $sut->getMetaField('foo');
self::assertSame($result, $meta);
self::assertEquals('test', $result->getType());
self::assertEquals('bar2', $result->getValue());
$meta2 = new InvoiceTemplateMeta();
$meta2->setName('foo')->setValue('bar')->setType('test2');
self::assertInstanceOf(InvoiceTemplate::class, $sut->setMetaField($meta2));
self::assertEquals(1, $sut->getMetaFields()->count());
self::assertCount(0, $sut->getVisibleMetaFields());
$result = $sut->getMetaField('foo');
self::assertSame($result, $meta);
self::assertEquals('test2', $result->getType());
$sut->setMetaField((new InvoiceTemplateMeta())->setName('blub')->setIsVisible(true));
$sut->setMetaField((new InvoiceTemplateMeta())->setName('blab')->setIsVisible(true));
self::assertEquals(3, $sut->getMetaFields()->count());
self::assertCount(2, $sut->getVisibleMetaFields());
}
public function testThrowsOnMetaFieldWithoutName(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Meta-field needs to have a name');
$sut = new InvoiceTemplate();
$sut->setMetaField(new CustomerMeta());
}
public function testThrowsOnMetaFieldsWrongType(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Meta-field needs to be an instanceof InvoiceTemplateMeta');
$sut = new InvoiceTemplate();
$meta = new CustomerMeta();
$meta->setName('foo');
$sut->setMetaField($meta);
}
}

View File

@@ -0,0 +1,26 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Event;
use App\Entity\InvoiceTemplate;
use App\Event\InvoiceTemplateMetaDefinitionEvent;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
#[CoversClass(InvoiceTemplateMetaDefinitionEvent::class)]
class InvoiceTemplateMetaDefinitionEventTest extends TestCase
{
public function testGetterAndSetter(): void
{
$invoiceTemplate = new InvoiceTemplate();
$sut = new InvoiceTemplateMetaDefinitionEvent($invoiceTemplate);
self::assertSame($invoiceTemplate, $sut->getEntity());
}
}

View File

@@ -52,6 +52,13 @@ class CustomerExporterTest extends TestCase
$customer->setMetaField((new CustomerMeta())->setName('foo meta')->setValue('some magic')->setIsVisible(true));
$customer->setMetaField((new CustomerMeta())->setName('hidden meta')->setValue('will not be seen')->setIsVisible(false));
$customer->setMetaField((new CustomerMeta())->setName('bar meta')->setValue('is happening')->setIsVisible(true));
$customer->setCountry('AT');
$customer->setAddressLine1('1234 Main Road');
$customer->setAddressLine2('Third Floor');
$customer->setAddressLine3('Golden Office Tower');
$customer->setCity('Acme City');
$customer->setPostCode('MT 543.6');
$customer->setBuyerReference('BR-0987654321');
$sut = new EntityWithMetaFieldsExporter($spreadsheetExporter, $annotationExtractor, $metaFieldExtractor);
$spreadsheet = $sut->export(Customer::class, [$customer], new CustomerMetaDisplayEvent(new CustomerQuery(), CustomerMetaDisplayEvent::EXPORT));
@@ -71,7 +78,12 @@ class CustomerExporterTest extends TestCase
self::assertEquals(null, $worksheet->getCell([++$i, 2])->getValue()); // mobile
self::assertEquals(null, $worksheet->getCell([++$i, 2])->getValue()); // fax
self::assertEquals(null, $worksheet->getCell([++$i, 2])->getValue()); // homepage
self::assertEquals(null, $worksheet->getCell([++$i, 2])->getValue()); // country
self::assertEquals('1234 Main Road', $worksheet->getCell([++$i, 2])->getValue()); // address_line1
self::assertEquals('Third Floor', $worksheet->getCell([++$i, 2])->getValue()); // address_line2
self::assertEquals('Golden Office Tower', $worksheet->getCell([++$i, 2])->getValue()); // address_line3
self::assertEquals('MT 543.6', $worksheet->getCell([++$i, 2])->getValue()); // postcode
self::assertEquals('Acme City', $worksheet->getCell([++$i, 2])->getValue()); // city
self::assertEquals('AT', $worksheet->getCell([++$i, 2])->getValue()); // country
self::assertEquals('EUR', $worksheet->getCell([++$i, 2])->getValue()); // currency
self::assertEquals(null, $worksheet->getCell([++$i, 2])->getValue()); // timezone
self::assertEquals('123456.789', $worksheet->getCell([++$i, 2])->getValue()); // budget
@@ -81,6 +93,7 @@ class CustomerExporterTest extends TestCase
self::assertFalse($worksheet->getCell([++$i, 2])->getValue()); // visible
self::assertEquals('Lorem Ipsum', $worksheet->getCell([++$i, 2])->getValue()); // comment
self::assertTrue($worksheet->getCell([++$i, 2])->getValue()); // billable
self::assertEquals('BR-0987654321', $worksheet->getCell([++$i, 2])->getValue()); // buyer reference
self::assertEquals('some magic', $worksheet->getCell([++$i, 2])->getValue());
self::assertEquals('is happening', $worksheet->getCell([++$i, 2])->getValue());
}

View File

@@ -17,6 +17,7 @@ use App\Entity\Timesheet;
use App\Entity\User;
use App\Invoice\CalculatorInterface;
use App\Invoice\InvoiceModel;
use App\Invoice\TaxRow;
use App\Repository\Query\InvoiceQuery;
use App\Tests\Invoice\DebugFormatter;
use App\Tests\Mocks\InvoiceModelFactoryFactory;
@@ -43,11 +44,21 @@ abstract class AbstractCalculatorTestCase extends TestCase
$sut->setModel($model);
self::assertEquals(0, $sut->getTotal());
self::assertEquals(0, $sut->getVat());
self::assertEquals(0, $sut->getSubtotal());
self::assertEquals(0, $sut->getTimeWorked());
self::assertEquals(0, \count($sut->getEntries()));
self::assertEquals(0, $sut->getTax());
self::assertTax($sut, 0);
}
protected function assertTax(CalculatorInterface $sut, int $rate): void
{
self::assertEquals($rate, $sut->getVat()); // @phpstan-ignore method.deprecated
$rows = $sut->getTaxRows();
self::assertCount(1, $rows);
self::assertInstanceOf(TaxRow::class, $rows[0]);
self::assertEquals($rate, $rows[0]->getTax()->getRate());
}
private function getEmptyModel(): InvoiceModel

View File

@@ -138,7 +138,7 @@ class ActivityInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('activity', $sut->getId());
self::assertEquals(3000.13, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(2521.12, $sut->getSubtotal());
self::assertEquals(6600, $sut->getTimeWorked());

View File

@@ -150,7 +150,7 @@ class ActivityUserInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('activity_user', $sut->getId());
self::assertEquals(3100.09, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(2605.12, $sut->getSubtotal());
self::assertEquals(7000, $sut->getTimeWorked());

View File

@@ -114,7 +114,7 @@ class DateInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('date', $sut->getId());
self::assertEquals(3000.13, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(2521.12, $sut->getSubtotal());
self::assertEquals(6600, $sut->getTimeWorked());

View File

@@ -116,7 +116,7 @@ class DateUserInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('date_user', $sut->getId());
self::assertEquals(3000.13, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(2521.12, $sut->getSubtotal());
self::assertEquals(6600, $sut->getTimeWorked());

View File

@@ -72,7 +72,7 @@ class DefaultCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('default', $sut->getId());
self::assertEquals(581.17, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(488.38, $sut->getSubtotal());
self::assertEquals(5800, $sut->getTimeWorked());

View File

@@ -117,7 +117,7 @@ class PriceInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('price', $sut->getId());
self::assertEquals(3000.13, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(2521.12, $sut->getSubtotal());
self::assertEquals(6600, $sut->getTimeWorked());

View File

@@ -113,7 +113,7 @@ class ProjectInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('project', $sut->getId());
self::assertEquals(3000.13, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(2521.12, $sut->getSubtotal());
self::assertEquals(6600, $sut->getTimeWorked());

View File

@@ -116,7 +116,7 @@ class ProjectUserInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('project_user', $sut->getId());
self::assertEquals(3000.13, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(2521.12, $sut->getSubtotal());
self::assertEquals(6600, $sut->getTimeWorked());

View File

@@ -95,7 +95,7 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('short', $sut->getId());
self::assertEquals(562.28, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(472.5, $sut->getSubtotal());
self::assertEquals(5800, $sut->getTimeWorked());
@@ -171,7 +171,7 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('short', $sut->getId());
self::assertEquals(581.17, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(488.38, $sut->getSubtotal());
self::assertEquals(5800, $sut->getTimeWorked());
@@ -241,7 +241,7 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('short', $sut->getId());
self::assertEquals(581.17, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(488.38, $sut->getSubtotal());
self::assertEquals(5800, $sut->getTimeWorked());

View File

@@ -110,7 +110,7 @@ class UserInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('user', $sut->getId());
self::assertEquals(3000.13, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(2521.12, $sut->getSubtotal());
self::assertEquals(6600, $sut->getTimeWorked());

View File

@@ -116,7 +116,7 @@ class WeeklyInvoiceCalculatorTest extends AbstractCalculatorTestCase
self::assertEquals('weekly', $sut->getId());
self::assertEquals(3000.13, $sut->getTotal());
self::assertEquals(19, $sut->getVat());
$this->assertTax($sut, 19);
self::assertEquals('EUR', $model->getCurrency());
self::assertEquals(2521.12, $sut->getSubtotal());
self::assertEquals(6600, $sut->getTimeWorked());

View File

@@ -36,6 +36,12 @@ class InvoiceModelCustomerHydratorTest extends TestCase
self::assertEquals([
'customer.id' => null,
'customer.address' => "Foo\nStreet\n1111 City",
'customer.address_line1' => '',
'customer.address_line2' => '',
'customer.address_line3' => '',
'customer.buyer_reference' => '',
'customer.city' => '',
'customer.postcode' => '',
'customer.name' => 'customer,with/special#name',
'customer.contact' => '',
'customer.company' => '',
@@ -43,6 +49,7 @@ class InvoiceModelCustomerHydratorTest extends TestCase
'customer.vat_id' => '',
'customer.number' => '',
'customer.country' => 'AT',
'customer.country_name' => 'Austria',
'customer.homepage' => '',
'customer.comment' => '',
'customer.email' => '',
@@ -63,12 +70,19 @@ class InvoiceModelCustomerHydratorTest extends TestCase
$keys = [
'customer.id',
'customer.address',
'customer.address_line1',
'customer.address_line2',
'customer.address_line3',
'customer.buyer_reference',
'customer.city',
'customer.postcode',
'customer.name',
'customer.contact',
'customer.company',
'customer.vat',
'customer.vat_id',
'customer.country',
'customer.country_name',
'customer.number',
'customer.homepage',
'customer.comment',

View File

@@ -33,12 +33,12 @@ class InvoiceModelDefaultHydratorTest extends TestCase
public function testHydrateThrowsOnMissing(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('InvoiceModel needs a template');
$this->expectExceptionMessage('InvoiceModel needs a calculator');
$model = $this->getInvoiceModel();
$obj = new ReflectionObject($model);
$prop = $obj->getProperty('template');
$prop = $obj->getProperty('calculator');
$prop->setAccessible(true);
$prop->setValue($model, null);
@@ -63,6 +63,7 @@ class InvoiceModelDefaultHydratorTest extends TestCase
'invoice.tax_hide',
'invoice.tax_nc',
'invoice.tax_plain',
'invoice.tax_rows',
'invoice.total_time',
'invoice.duration_decimal',
'invoice.first',

View File

@@ -28,8 +28,6 @@ class InvoiceModelTest extends TestCase
$sut = (new InvoiceModelFactoryFactory($this))->create()->createModel($formatter, new Customer('foo'), new InvoiceTemplate(), new InvoiceQuery());
self::assertNotNull($sut->getQuery());
self::assertNotNull($sut->getCustomer());
self::assertNotNull($sut->getTemplate());
self::assertFalse($sut->isPreview());
self::assertFalse($sut->isHideZeroTax());

View File

@@ -96,6 +96,7 @@ class DebugRendererTest extends TestCase
'invoice.language',
'invoice.tax_nc',
'invoice.tax_plain',
'invoice.tax_rows',
'invoice.total_time',
'invoice.duration_decimal',
'invoice.first',
@@ -137,12 +138,19 @@ class DebugRendererTest extends TestCase
'query.end_year',
'customer.id',
'customer.address',
'customer.address_line1',
'customer.address_line2',
'customer.address_line3',
'customer.buyer_reference',
'customer.city',
'customer.postcode',
'customer.name',
'customer.contact',
'customer.company',
'customer.vat',
'customer.vat_id',
'customer.country',
'customer.country_name',
'customer.number',
'customer.homepage',
'customer.comment',

View File

@@ -95,6 +95,7 @@ trait RendererTestTrait
$template->setTitle('a very *long* test invoice / template title with [ßpecial] chäracter');
$template->setVat(19);
$template->setLanguage('en');
$template->setCustomer($customer);
$pMeta = new ProjectMeta();
$pMeta->setName('foo-project')->setValue('bar-project')->setIsVisible(true);
@@ -279,6 +280,7 @@ trait RendererTestTrait
$template->setTitle('a test invoice template title');
$template->setVat(19);
$template->setLanguage('it');
$template->setCustomer($customer);
$project = new Project();
$project->setName('project name');

View File

@@ -59,7 +59,7 @@ class TwigRendererTest extends KernelTestCase
$sut = new TwigRenderer($twig);
$model = $this->getInvoiceModel();
$model->getTemplate()?->setLanguage('de');
$model->getTemplate()->setLanguage('de');
$document = $this->getInvoiceDocument('timesheet.html.twig');
$response = $sut->render($document, $model);
@@ -118,7 +118,7 @@ class TwigRendererTest extends KernelTestCase
$sut = new TwigRenderer($twig);
$model = $this->getInvoiceModel();
$model->getTemplate()?->setLanguage('de');
$model->getTemplate()->setLanguage('de');
foreach ($files as $filename) {
$document = new InvoiceDocument(new \SplFileInfo($filename));

View File

@@ -19,14 +19,20 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
#[Group('integration')]
class MPdfConverterTest extends KernelTestCase
{
public function test()
public function testConvertToPdf(): void
{
$kernel = self::bootKernel();
$cacheDir = $kernel->getContainer()->getParameter('kernel.cache_dir');
$options = [
'foo' => 'bar',
'additional_xmp_rdf' => '<rdf:Description rdf:about="" xmlns:zf="urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#"></rdf:Description>',
'margin_top' => 2,
];
$sut = new MPdfConverter((new FileHelperFactory($this))->create(), $cacheDir);
$result = $sut->convertToPdf('<h1>Test</h1>');
// Yeah, thats not a real test, I know ;-)
$result = $sut->convertToPdf('<h1>Test</h1>', $options);
// Yeah, that's not a real test, I know ;-)
self::assertNotEmpty($result);
preg_match('/\/Creator \((.*)\)/', $result, $matches);
self::assertCount(2, $matches);

View File

@@ -16,7 +16,7 @@ use PHPUnit\Framework\TestCase;
#[CoversClass(JavascriptFormatConverter::class)]
class JavascriptFormatConverterTest extends TestCase
{
public function test()
public function testConvert(): void
{
$sut = new JavascriptFormatConverter();
self::assertEquals('DD.MM.YYYY HH:mm', $sut->convert('dd.MM.y HH:mm'));

View File

@@ -1721,11 +1721,6 @@ parameters:
count: 1
path: Invoice/Renderer/XlsxRendererTest.php
-
message: "#^Cannot call method getLanguage\\(\\) on App\\\\Entity\\\\InvoiceTemplate\\|null\\.$#"
count: 1
path: Invoice/ServiceInvoiceTest.php
-
message: "#^Cannot call method getTotal\\(\\) on App\\\\Invoice\\\\CalculatorInterface\\|null\\.$#"
count: 4
@@ -1855,11 +1850,6 @@ parameters:
count: 1
path: Model/Statistic/MonthTest.php
-
message: "#^Method App\\\\Tests\\\\Pdf\\\\MPdfConverterTest\\:\\:test\\(\\) has no return type specified\\.$#"
count: 1
path: Pdf/MPdfConverterTest.php
-
message: "#^Parameter \\#2 \\$cacheDirectory of class App\\\\Pdf\\\\MPdfConverter constructor expects string, array\\|bool\\|float\\|int\\|string\\|null given\\.$#"
count: 1
@@ -2685,11 +2675,6 @@ parameters:
count: 1
path: Utils/FormFormatConverterTest.php
-
message: "#^Method App\\\\Tests\\\\Utils\\\\JavascriptFormatConverterTest\\:\\:test\\(\\) has no return type specified\\.$#"
count: 1
path: Utils/JavascriptFormatConverterTest.php
-
message: "#^Method App\\\\Tests\\\\Utils\\\\ProfileManagerTest\\:\\:getCookieProfiles\\(\\) has no return type specified\\.$#"
count: 1