diff --git a/app/Helpers/Filter/AmountFilter.php b/app/Helpers/Filter/AmountFilter.php deleted file mode 100644 index e977e4d0a0..0000000000 --- a/app/Helpers/Filter/AmountFilter.php +++ /dev/null @@ -1,72 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - -use FireflyIII\Models\Transaction; -use Illuminate\Support\Collection; -use Log; - -/** - * Class AmountFilter. - * - * This filter removes transactions with either a positive amount ($parameters = 1) or a negative amount - * ($parameter = -1). This is helpful when a Collection has you with both transactions in a journal. - */ -class AmountFilter implements FilterInterface -{ - /** @var int Either -1 or +1 for the filter. */ - private $modifier; - - /** - * AmountFilter constructor. - * - * @param int $modifier - */ - public function __construct(int $modifier) - { - $this->modifier = $modifier; - } - - /** - * Filter on amount. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - return $set->filter( - function (Transaction $transaction) { - // remove by amount - if (bccomp($transaction->transaction_amount, '0') === $this->modifier) { - Log::debug(sprintf('Filtered #%d because amount is %f.', $transaction->id, $transaction->transaction_amount)); - - return null; - } - - return $transaction; - } - ); - } -} diff --git a/app/Helpers/Filter/CountAttachmentsFilter.php b/app/Helpers/Filter/CountAttachmentsFilter.php deleted file mode 100644 index 6c67591299..0000000000 --- a/app/Helpers/Filter/CountAttachmentsFilter.php +++ /dev/null @@ -1,71 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - - -use DB; -use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionJournal; -use Illuminate\Support\Collection; - -/** - * Class CountAttachmentsFilter - * - * @codeCoverageIgnore - */ -class CountAttachmentsFilter implements FilterInterface -{ - - /** - * Adds the number of transactions to each given transaction. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - // grab journal ID's: - $ids = $set->pluck('journal_id')->toArray(); - - $result = DB::table('attachments') - ->whereNull('deleted_at') - ->whereIn('attachable_id', $ids) - ->where('attachable_type', TransactionJournal::class) - ->groupBy('attachable_id')->get(['attachable_id', DB::raw('COUNT(*) as number')]); - $counter = []; - foreach ($result as $row) { - $counter[$row->attachable_id] = $row->number; - } - $set->each( - function (Transaction $transaction) use ($counter) { - $id = (int)$transaction->journal_id; - $count = (int)($counter[$id] ?? 0.0); - $transaction->attachmentCount = $count; - } - ); - - return $set; - } -} diff --git a/app/Helpers/Filter/DoubleTransactionFilter.php b/app/Helpers/Filter/DoubleTransactionFilter.php deleted file mode 100644 index 02eb5db062..0000000000 --- a/app/Helpers/Filter/DoubleTransactionFilter.php +++ /dev/null @@ -1,62 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - - -use FireflyIII\Models\Transaction; -use Illuminate\Support\Collection; - -/** - * - * Used when the final collection contains double transactions, which can happen when viewing the tag report. - * Class DoubleTransactionFilter - * - * @codeCoverageIgnore - */ -class DoubleTransactionFilter implements FilterInterface -{ - - /** - * Apply the filter. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - $count = []; - $result = new Collection; - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - $id = (int)$transaction->id; - $count[$id] = isset($count[$id]) ? $count[$id] + 1 : 1; - if (1 === $count[$id]) { - $result->push($transaction); - } - } - - return $result; - } -} diff --git a/app/Helpers/Filter/EmptyFilter.php b/app/Helpers/Filter/EmptyFilter.php deleted file mode 100644 index 716b3d9cdb..0000000000 --- a/app/Helpers/Filter/EmptyFilter.php +++ /dev/null @@ -1,45 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - -use Illuminate\Support\Collection; - -/** - * Class EmptyFilter. - * - * @codeCoverageIgnore - */ -class EmptyFilter implements FilterInterface -{ - /** - * Simply returns the set. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - return $set; - } -} diff --git a/app/Helpers/Filter/FilterInterface.php b/app/Helpers/Filter/FilterInterface.php deleted file mode 100644 index 4b08036b51..0000000000 --- a/app/Helpers/Filter/FilterInterface.php +++ /dev/null @@ -1,40 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - -use Illuminate\Support\Collection; - -/** - * Interface FilterInterface - */ -interface FilterInterface -{ - /** - * Apply the filter. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection; -} diff --git a/app/Helpers/Filter/InternalTransferFilter.php b/app/Helpers/Filter/InternalTransferFilter.php deleted file mode 100644 index a72474c4e0..0000000000 --- a/app/Helpers/Filter/InternalTransferFilter.php +++ /dev/null @@ -1,86 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - -use FireflyIII\Models\Transaction; -use Illuminate\Support\Collection; -use Log; - -/** - * Class InternalTransferFilter. - * - * This filter removes any filters that are from A to B or from B to A given a set of - * account id's (in $parameters) where A and B are mentioned. So transfers between the mentioned - * accounts will be removed. - * - * @codeCoverageIgnore - */ -class InternalTransferFilter implements FilterInterface -{ - /** @var array The accounts */ - private $accounts; - - /** - * InternalTransferFilter constructor. - * - * @param array $accounts - */ - public function __construct(array $accounts) - { - $this->accounts = $accounts; - } - - /** - * See class description. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - return $set->filter( - function (Transaction $transaction) { - if (null === $transaction->opposing_account_id) { - return $transaction; - } - // both id's in $parameters? - if (\in_array($transaction->account_id, $this->accounts, true) && \in_array($transaction->opposing_account_id, $this->accounts, true)) { - Log::debug( - sprintf( - 'Transaction #%d has #%d and #%d in set, so removed', - $transaction->id, - $transaction->account_id, - $transaction->opposing_account_id - ), - $this->accounts - ); - - return false; - } - - return $transaction; - } - ); - } -} diff --git a/app/Helpers/Filter/NegativeAmountFilter.php b/app/Helpers/Filter/NegativeAmountFilter.php deleted file mode 100644 index 58ebc6ed3b..0000000000 --- a/app/Helpers/Filter/NegativeAmountFilter.php +++ /dev/null @@ -1,60 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - -use FireflyIII\Models\Transaction; -use Illuminate\Support\Collection; -use Log; - -/** - * Class NegativeAmountFilter. - * - * This filter removes entries with a negative amount (the original modifier is -1). - * - * @codeCoverageIgnore - */ -class NegativeAmountFilter implements FilterInterface -{ - /** - * See class description. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - return $set->filter( - function (Transaction $transaction) { - // remove by amount - if (bccomp($transaction->transaction_amount, '0') === -1) { - Log::debug(sprintf('Filtered #%d because amount is %f.', $transaction->id, $transaction->transaction_amount)); - - return null; - } - - return $transaction; - } - ); - } -} diff --git a/app/Helpers/Filter/OpposingAccountFilter.php b/app/Helpers/Filter/OpposingAccountFilter.php deleted file mode 100644 index 681a4c26b2..0000000000 --- a/app/Helpers/Filter/OpposingAccountFilter.php +++ /dev/null @@ -1,75 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - -use FireflyIII\Models\Transaction; -use Illuminate\Support\Collection; -use Log; - -/** - * Class OpposingAccountFilter. - * - * This filter is similar to the internal transfer filter but only removes transactions when the opposing account is - * amongst $parameters (list of account ID's). - * - * @codeCoverageIgnore - */ -class OpposingAccountFilter implements FilterInterface -{ - /** @var array The asset accounts. */ - private $accounts; - - /** - * InternalTransferFilter constructor. - * - * @param array $accounts - */ - public function __construct(array $accounts) - { - $this->accounts = $accounts; - } - - /** - * Only return specific transactions. See class description. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - return $set->filter( - function (Transaction $transaction) { - $opposing = $transaction->opposing_account_id; - // remove internal transfer - if (\in_array($opposing, $this->accounts, true)) { - Log::debug(sprintf('Filtered #%d because its opposite is in accounts.', $transaction->id), $this->accounts); - - return null; - } - - return $transaction; - } - ); - } -} diff --git a/app/Helpers/Filter/PositiveAmountFilter.php b/app/Helpers/Filter/PositiveAmountFilter.php deleted file mode 100644 index 257bdf43b4..0000000000 --- a/app/Helpers/Filter/PositiveAmountFilter.php +++ /dev/null @@ -1,63 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - -use FireflyIII\Models\Transaction; -use Illuminate\Support\Collection; -use Log; - -/** - * Class PositiveAmountFilter. - * - * This filter removes entries with a negative amount (the original modifier is -1). - * - * This filter removes transactions with either a positive amount ($parameters = 1) or a negative amount - * ($parameter = -1). This is helpful when a Collection has you with both transactions in a journal. - * - * @codeCoverageIgnore - */ -class PositiveAmountFilter implements FilterInterface -{ - /** - * See class description. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - return $set->filter( - function (Transaction $transaction) { - // remove by amount - if (1 === bccomp($transaction->transaction_amount, '0')) { - Log::debug(sprintf('Filtered #%d because amount is %f.', $transaction->id, $transaction->transaction_amount)); - - return null; - } - - return $transaction; - } - ); - } -} diff --git a/app/Helpers/Filter/SplitIndicatorFilter.php b/app/Helpers/Filter/SplitIndicatorFilter.php deleted file mode 100644 index 609c3a424e..0000000000 --- a/app/Helpers/Filter/SplitIndicatorFilter.php +++ /dev/null @@ -1,71 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - - -use DB; -use FireflyIII\Models\Transaction; -use Illuminate\Support\Collection; - -/** - * Class SplitIndicatorFilter - * - * @codeCoverageIgnore - */ -class SplitIndicatorFilter implements FilterInterface -{ - - /** - * Adds a property if the journal is a split one. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - // grab journal ID's: - $ids = $set->pluck('journal_id')->toArray(); - - $result = DB::table('transactions') - ->whereNull('deleted_at')->whereIn('transaction_journal_id', $ids) - ->groupBy('transaction_journal_id')->get(['transaction_journal_id', DB::raw('COUNT(*) as number')]); - $counter = []; - foreach ($result as $row) { - $counter[$row->transaction_journal_id] = $row->number; - } - $set->each( - function (Transaction $transaction) use ($counter) { - $id = (int)$transaction->journal_id; - $count = (int)($counter[$id] ?? 0.0); - $transaction->is_split = false; - if ($count > 2) { - $transaction->is_split = true; - } - } - ); - - return $set; - } -} diff --git a/app/Helpers/Filter/TransactionViewFilter.php b/app/Helpers/Filter/TransactionViewFilter.php deleted file mode 100644 index baae12173d..0000000000 --- a/app/Helpers/Filter/TransactionViewFilter.php +++ /dev/null @@ -1,85 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - -use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionType; -use Illuminate\Support\Collection; -use Log; - -/** - * Class TransactionViewFilter. - * - * This filter removes the entry with a negative amount when it's a withdrawal - * And the positive amount when it's a deposit or transfer - * - * This is used in the mass-edit routine. - * - * @codeCoverageIgnore - * - */ -class TransactionViewFilter implements FilterInterface -{ - /** - * See class description. - * - * @param Collection $set - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - return $set->filter( - function (Transaction $transaction) { - // remove if amount is less than zero and type is withdrawal. - if ($transaction->transaction_type_type === TransactionType::WITHDRAWAL && 1 === bccomp($transaction->transaction_amount, '0')) { - Log::debug( - sprintf( - 'Filtered #%d because amount is %f and type is %s.', $transaction->id, $transaction->transaction_amount, - $transaction->transaction_type_type - ) - ); - - return null; - } - - if ($transaction->transaction_type_type === TransactionType::DEPOSIT && -1 === bccomp($transaction->transaction_amount, '0')) { - Log::debug( - sprintf( - 'Filtered #%d because amount is %f and type is %s.', $transaction->id, $transaction->transaction_amount, - $transaction->transaction_type_type - ) - ); - - return null; - } - Log::debug( - sprintf('#%d: amount is %f and type is %s.', $transaction->id, $transaction->transaction_amount, $transaction->transaction_type_type) - ); - - return $transaction; - } - ); - } -} diff --git a/app/Helpers/Filter/TransferFilter.php b/app/Helpers/Filter/TransferFilter.php deleted file mode 100644 index ed0dec3350..0000000000 --- a/app/Helpers/Filter/TransferFilter.php +++ /dev/null @@ -1,79 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Helpers\Filter; - -use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionType; -use Illuminate\Support\Collection; -use Log; - -/** - * Class TransferFilter. - * - * This filter removes any transfers that are in the collection twice (from A to B and from B to A). - * - * @codeCoverageIgnore - */ -class TransferFilter implements FilterInterface -{ - /** - * See class transaction. - * - * @param Collection $set - * - * @return Collection - */ - public function filter(Collection $set): Collection - { - $count = []; - $new = new Collection; - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - if (TransactionType::TRANSFER !== $transaction->transaction_type_type) { - Log::debug(sprintf('Transaction #%d is not a transfer, add it.', $transaction->id)); - $new->push($transaction); - continue; - } - // make property string: - $journalId = $transaction->transaction_journal_id; - $amount = app('steam')->positive($transaction->transaction_amount); - $accountIds = [(int)$transaction->account_id, (int)$transaction->opposing_account_id]; - $transactionIds = [$transaction->id, (int)$transaction->opposing_id]; - sort($accountIds); - sort($transactionIds); - $key = $journalId . '-' . implode(',', $transactionIds) . '-' . implode(',', $accountIds) . '-' . $amount; - Log::debug(sprintf('Current transaction key is "%s"', $key)); - if (!isset($count[$key])) { - Log::debug(sprintf('First instance of transaction #%d, add it.', $transaction->id)); - // not yet counted? add to new set and count it: - $new->push($transaction); - $count[$key] = 1; - } - if (isset($count[$key])) { - Log::debug(sprintf('Second instance of transaction #%d, do NOT add it.', $transaction->id)); - } - } - - return $new; - } -} diff --git a/app/Helpers/FiscalHelper.php b/app/Helpers/Fiscal/FiscalHelper.php similarity index 100% rename from app/Helpers/FiscalHelper.php rename to app/Helpers/Fiscal/FiscalHelper.php diff --git a/app/Helpers/FiscalHelperInterface.php b/app/Helpers/Fiscal/FiscalHelperInterface.php similarity index 100% rename from app/Helpers/FiscalHelperInterface.php rename to app/Helpers/Fiscal/FiscalHelperInterface.php diff --git a/tests/Unit/Handlers/Events/StoredJournalEventHandlerTest.php b/tests/Unit/Handlers/Events/StoredJournalEventHandlerTest.php deleted file mode 100644 index 71ef373ba6..0000000000 --- a/tests/Unit/Handlers/Events/StoredJournalEventHandlerTest.php +++ /dev/null @@ -1,81 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace Tests\Unit\Handlers\Events; - - -use FireflyIII\Events\StoredTransactionJournal; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Handlers\Events\StoredJournalEventHandler; -use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; -use FireflyIII\TransactionRules\Processor; -use Log; -use Tests\TestCase; - -/** - * - * Class StoredJournalEventHandlerTest - */ -class StoredJournalEventHandlerTest extends TestCase -{ - /** - * - */ - public function setUp(): void - { - parent::setUp(); - Log::info(sprintf('Now in %s.', get_class($this))); - } - - /** - */ - public function testProcessRules(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); - $processor = $this->mock(Processor::class); - - $journal = $this->user()->transactionJournals()->inRandomOrder()->first(); - $piggy = $this->user()->piggyBanks()->inRandomOrder()->first(); - $event = new StoredTransactionJournal($journal, $piggy->id); - $ruleGroups = $this->user()->ruleGroups()->take(1)->get(); - $rules = $this->user()->rules()->take(1)->get(); - - // mock calls: - $ruleGroupRepos->shouldReceive('setUser')->once(); - $ruleGroupRepos->shouldReceive('getActiveGroups')->andReturn($ruleGroups)->once(); - $ruleGroupRepos->shouldReceive('getActiveStoreRules')->andReturn($rules)->once(); - $processor->shouldReceive('make')->once(); - $processor->shouldReceive('handleTransactionJournal')->once(); - - - $handler = new StoredJournalEventHandler; - try { - $handler->processRules($event); - } catch (FireflyException $e) { - $this->assertTrue(false, $e->getMessage()); - } - } -} diff --git a/tests/Unit/Handlers/Events/UpdatedGroupEventHandlerTest.php b/tests/Unit/Handlers/Events/UpdatedGroupEventHandlerTest.php new file mode 100644 index 0000000000..4d16374769 --- /dev/null +++ b/tests/Unit/Handlers/Events/UpdatedGroupEventHandlerTest.php @@ -0,0 +1,67 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Handlers\Events; + +use FireflyIII\Events\StoredTransactionGroup; +use FireflyIII\Events\UpdatedTransactionGroup; +use FireflyIII\Handlers\Events\StoredGroupEventHandler; +use FireflyIII\Handlers\Events\UpdatedGroupEventHandler; +use FireflyIII\TransactionRules\Engine\RuleEngine; +use Log; +use Tests\TestCase; + +/** + * Class UpdatedJournalEventHandlerTest + */ +class UpdatedJournalEventHandlerTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Log::info(sprintf('Now in %s.', get_class($this))); + } + + + /** + * @covers \FireflyIII\Handlers\Events\UpdatedGroupEventHandler + */ + public function testProcessRules(): void + { + $group = $this->getRandomWithdrawalGroup(); + $ruleEngine = $this->mock(RuleEngine::class); + + $ruleEngine->shouldReceive('setUser')->atLeast()->once(); + $ruleEngine->shouldReceive('setAllRules')->atLeast()->once()->withArgs([true]); + $ruleEngine->shouldReceive('setTriggerMode')->atLeast()->once()->withArgs([RuleEngine::TRIGGER_STORE]); + $ruleEngine->shouldReceive('processTransactionJournal')->atLeast()->once(); + + $event = new UpdatedTransactionGroup($group); + $handler = new UpdatedGroupEventHandler; + $handler->processRules($event); + } + +} diff --git a/tests/Unit/Handlers/Events/UpdatedJournalEventHandlerTest.php b/tests/Unit/Handlers/Events/UpdatedJournalEventHandlerTest.php deleted file mode 100644 index c5961261eb..0000000000 --- a/tests/Unit/Handlers/Events/UpdatedJournalEventHandlerTest.php +++ /dev/null @@ -1,79 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace Tests\Unit\Handlers\Events; - -use FireflyIII\Events\UpdatedTransactionJournal; -use FireflyIII\Handlers\Events\UpdatedJournalEventHandler; -use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; -use FireflyIII\TransactionRules\Processor; -use Log; -use Tests\TestCase; - -/** - * Class UpdatedJournalEventHandlerTest - */ -class UpdatedJournalEventHandlerTest extends TestCase -{ - /** - * - */ - public function setUp(): void - { - parent::setUp(); - Log::info(sprintf('Now in %s.', get_class($this))); - } - - - /** - */ - public function testProcessRules(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); - $processor = $this->mock(Processor::class); - - $journal = $this->user()->transactionJournals()->inRandomOrder()->first(); - $event = new UpdatedTransactionJournal($journal); - $ruleGroups = $this->user()->ruleGroups()->take(1)->get(); - $rules = $this->user()->rules()->take(1)->get(); - - // mock calls: - $ruleGroupRepos->shouldReceive('setUser')->once(); - $ruleGroupRepos->shouldReceive('getActiveGroups')->andReturn($ruleGroups)->once(); - $ruleGroupRepos->shouldReceive('getActiveUpdateRules')->andReturn($rules)->once(); - $processor->shouldReceive('make')->once(); - $processor->shouldReceive('handleTransactionJournal')->once(); - - - $handler = new UpdatedJournalEventHandler; - try { - $handler->processRules($event); - } catch (FireflyException $e) { - $this->assertTrue(false, $e->getMessage()); - } - } - -} diff --git a/tests/Unit/Helpers/Filter/AmountFilterTest.php b/tests/Unit/Helpers/Filter/AmountFilterTest.php deleted file mode 100644 index 6800ec833a..0000000000 --- a/tests/Unit/Helpers/Filter/AmountFilterTest.php +++ /dev/null @@ -1,69 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace Tests\Unit\Helpers\Filter; - - -use FireflyIII\Helpers\Filter\AmountFilter; -use FireflyIII\Models\Transaction; -use Illuminate\Support\Collection; -use Log; -use Tests\TestCase; - -/** - * - * Class AmountFilterTest - */ -class AmountFilterTest extends TestCase -{ - /** - * - */ - public function setUp(): void - { - parent::setUp(); - Log::info(sprintf('Now in %s.', get_class($this))); - } - - /** - * @covers \FireflyIII\Helpers\Filter\AmountFilter - */ - public function testBasicPositive(): void - { - $count = 0; - $collection = new Collection; - for ($i = 0; $i < 10; $i++) { - $amount = random_int(-10, 10); - $transaction = new Transaction; - $transaction->transaction_amount = (string)$amount; - if ($amount <= 0) { - $count++; - } - $collection->push($transaction); - } - - $filter = new AmountFilter(1); - $result = $filter->filter($collection); - $this->assertCount($count, $result); - } -} diff --git a/tests/Unit/Helpers/FiscalHelperTest.php b/tests/Unit/Helpers/Fiscal/FiscalHelperTest.php similarity index 100% rename from tests/Unit/Helpers/FiscalHelperTest.php rename to tests/Unit/Helpers/Fiscal/FiscalHelperTest.php