From 06dc8a499b460b6dacd90dc5bc895ce9831ef68a Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 1 Mar 2018 20:54:50 +0100 Subject: [PATCH] Expand factory tests. --- app/Factory/AccountFactory.php | 14 +- app/Factory/BillFactory.php | 117 +-- app/Factory/BudgetFactory.php | 36 +- app/Factory/CategoryFactory.php | 27 +- app/Factory/PiggyBankFactory.php | 34 +- app/Factory/TransactionFactory.php | 3 - app/Factory/TransactionJournalFactory.php | 4 +- app/Factory/TransactionJournalMetaFactory.php | 9 +- app/Factory/TransactionTypeFactory.php | 1 + app/Repositories/Bill/BillRepository.php | 2 +- .../Internal/Support/AccountServiceTrait.php | 21 +- .../Internal/Support/BillServiceTrait.php | 2 + .../Internal/Support/JournalServiceTrait.php | 9 +- .../Support/TransactionServiceTrait.php | 30 +- tests/Unit/Factory/AccountFactoryTest.php | 396 +++++++++ tests/Unit/Factory/BillFactoryTest.php | 134 +++ tests/Unit/Factory/BudgetFactoryTest.php | 97 +++ tests/Unit/Factory/CategoryFactoryTest.php | 103 +++ .../Factory/PiggyBankEventFactoryTest.php | 135 +++ tests/Unit/Factory/PiggyBankFactoryTest.php | 96 ++ tests/Unit/Factory/TagFactoryTest.php | 63 ++ .../TransactionCurrencyFactoryTest.php | 81 ++ tests/Unit/Factory/TransactionFactoryTest.php | 823 ++++++++++++++++++ .../Factory/TransactionJournalFactoryTest.php | 177 ++++ .../TransactionJournalMetaFactoryTest.php | 105 +++ 25 files changed, 2384 insertions(+), 135 deletions(-) create mode 100644 tests/Unit/Factory/AccountFactoryTest.php create mode 100644 tests/Unit/Factory/BillFactoryTest.php create mode 100644 tests/Unit/Factory/BudgetFactoryTest.php create mode 100644 tests/Unit/Factory/CategoryFactoryTest.php create mode 100644 tests/Unit/Factory/PiggyBankEventFactoryTest.php create mode 100644 tests/Unit/Factory/PiggyBankFactoryTest.php create mode 100644 tests/Unit/Factory/TagFactoryTest.php create mode 100644 tests/Unit/Factory/TransactionCurrencyFactoryTest.php create mode 100644 tests/Unit/Factory/TransactionFactoryTest.php create mode 100644 tests/Unit/Factory/TransactionJournalFactoryTest.php create mode 100644 tests/Unit/Factory/TransactionJournalMetaFactoryTest.php diff --git a/app/Factory/AccountFactory.php b/app/Factory/AccountFactory.php index 57ec8d2c3d..88adfd287c 100644 --- a/app/Factory/AccountFactory.php +++ b/app/Factory/AccountFactory.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace FireflyIII\Factory; -use Exception; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Services\Internal\Support\AccountServiceTrait; @@ -44,8 +42,6 @@ class AccountFactory /** * @param array $data * - * @throws FireflyException - * @throws Exception * @return Account */ public function create(array $data): Account @@ -80,10 +76,10 @@ class AccountFactory $newAccount = Account::create($databaseData); $this->updateMetadata($newAccount, $data); - if ($this->validIBData($data)) { + if ($this->validIBData($data) && $type->type === AccountType::ASSET) { $this->updateIB($newAccount, $data); } - if (!$this->validIBData($data)) { + if (!$this->validIBData($data) && $type->type === AccountType::ASSET) { $this->deleteIB($newAccount); } // update note: @@ -99,8 +95,6 @@ class AccountFactory * @param string $accountType * * @return Account|null - * @throws Exception - * @throws FireflyException */ public function find(string $accountName, string $accountType): ?Account { @@ -122,8 +116,6 @@ class AccountFactory * @param string $accountType * * @return Account - * @throws Exception - * @throws FireflyException */ public function findOrCreate(string $accountName, string $accountType): Account { @@ -143,7 +135,7 @@ class AccountFactory 'name' => $accountName, 'account_type_id' => $type->id, 'accountType' => null, - 'virtualBalance' => '0', + 'virtualBalance' => '0', 'iban' => null, 'active' => true, ] diff --git a/app/Factory/BillFactory.php b/app/Factory/BillFactory.php index 3c190939a7..087ae39912 100644 --- a/app/Factory/BillFactory.php +++ b/app/Factory/BillFactory.php @@ -24,9 +24,10 @@ declare(strict_types=1); namespace FireflyIII\Factory; use FireflyIII\Models\Bill; -use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Services\Internal\Support\BillServiceTrait; use FireflyIII\User; +use Illuminate\Support\Collection; +use Log; /** * Class BillFactory @@ -34,66 +35,15 @@ use FireflyIII\User; class BillFactory { use BillServiceTrait; - /** @var BillRepositoryInterface */ - private $repository; /** @var User */ private $user; - /** - * BillFactory constructor. - */ - public function __construct() - { - $this->repository = app(BillRepositoryInterface::class); - } - - /** - * @param int|null $billId - * @param null|string $billName - * - * @return Bill|null - */ - public function find(?int $billId, ?string $billName): ?Bill - { - $billId = intval($billId); - $billName = strval($billName); - // first find by ID: - if ($billId > 0) { - /** @var Bill $bill */ - $bill = $this->repository->find($billId); - if (!is_null($bill)) { - return $bill; - } - } - - // then find by name: - if (strlen($billName) > 0) { - $bill = $this->repository->findByName($billName); - if (!is_null($bill)) { - return $bill; - } - } - - return null; - - } - - /** - * @param User $user - */ - public function setUser(User $user) - { - $this->user = $user; - $this->repository->setUser($user); - - } - /** * @param array $data * * @return Bill|null */ - public function store(array $data): ?Bill + public function create(array $data): ?Bill { $matchArray = explode(',', $data['match']); $matchArray = array_unique($matchArray); @@ -123,4 +73,65 @@ class BillFactory return $bill; } + /** + * @param int|null $billId + * @param null|string $billName + * + * @return Bill|null + */ + public function find(?int $billId, ?string $billName): ?Bill + { + $billId = intval($billId); + $billName = strval($billName); + + // first find by ID: + if ($billId > 0) { + /** @var Bill $bill */ + $bill = $this->user->bills()->find($billId); + if (!is_null($bill)) { + return $bill; + } + } + + // then find by name: + if (strlen($billName) > 0) { + $bill = $this->findByName($billName); + if (!is_null($bill)) { + return $bill; + } + } + + return null; + + } + + /** + * @param string $name + * + * @return Bill|null + */ + public function findByName(string $name): ?Bill + { + /** @var Collection $collection */ + $collection = $this->user->bills()->get(); + /** @var Bill $bill */ + foreach ($collection as $bill) { + Log::debug(sprintf('"%s" vs. "%s"', $bill->name, $name)); + if ($bill->name === $name) { + return $bill; + } + } + Log::debug(sprintf('Bill::Find by name returns NULL based on "%s"', $name)); + + return null; + } + + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + } \ No newline at end of file diff --git a/app/Factory/BudgetFactory.php b/app/Factory/BudgetFactory.php index bffde7d086..135663bb59 100644 --- a/app/Factory/BudgetFactory.php +++ b/app/Factory/BudgetFactory.php @@ -24,26 +24,17 @@ declare(strict_types=1); namespace FireflyIII\Factory; use FireflyIII\Models\Budget; -use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\User; +use Illuminate\Support\Collection; /** * Class BudgetFactory */ class BudgetFactory { - /** @var BudgetRepositoryInterface */ - private $repository; /** @var User */ private $user; - /** - * BudgetFactory constructor. - */ - public function __construct() - { - $this->repository = app(BudgetRepositoryInterface::class); - } /** * @param int|null $budgetId @@ -62,14 +53,15 @@ class BudgetFactory // first by ID: if ($budgetId > 0) { - $budget = $this->repository->findNull($budgetId); + /** @var Budget $budget */ + $budget = $this->user->budgets()->find($budgetId); if (!is_null($budget)) { return $budget; } } if (strlen($budgetName) > 0) { - $budget = $this->repository->findByName($budgetName); + $budget = $this->findByName($budgetName); if (!is_null($budget)) { return $budget; } @@ -78,13 +70,31 @@ class BudgetFactory return null; } + /** + * @param string $name + * + * @return Budget|null + */ + public function findByName(string $name): ?Budget + { + /** @var Collection $collection */ + $collection = $this->user->budgets()->get(); + /** @var Budget $budget */ + foreach ($collection as $budget) { + if ($budget->name === $name) { + return $budget; + } + } + + return null; + } + /** * @param User $user */ public function setUser(User $user) { $this->user = $user; - $this->repository->setUser($user); } } \ No newline at end of file diff --git a/app/Factory/CategoryFactory.php b/app/Factory/CategoryFactory.php index eec437cab1..ccc136eeed 100644 --- a/app/Factory/CategoryFactory.php +++ b/app/Factory/CategoryFactory.php @@ -25,8 +25,8 @@ namespace FireflyIII\Factory; use FireflyIII\Models\Category; -use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\User; +use Illuminate\Support\Collection; use Log; /** @@ -34,17 +34,26 @@ use Log; */ class CategoryFactory { - /** @var CategoryRepositoryInterface */ - private $repository; /** @var User */ private $user; /** - * CategoryFactory constructor. + * @param string $name + * + * @return Category|null */ - public function __construct() + public function findByName(string $name): ?Category { - $this->repository = app(CategoryRepositoryInterface::class); + /** @var Collection $collection */ + $collection = $this->user->categories()->get(); + /** @var Category $category */ + foreach ($collection as $category) { + if ($category->name === $name) { + return $category; + } + } + + return null; } /** @@ -65,14 +74,15 @@ class CategoryFactory } // first by ID: if ($categoryId > 0) { - $category = $this->repository->findNull($categoryId); + /** @var Category $category */ + $category = $this->user->categories()->find($categoryId); if (!is_null($category)) { return $category; } } if (strlen($categoryName) > 0) { - $category = $this->repository->findByName($categoryName); + $category = $this->findByName($categoryName); if (!is_null($category)) { return $category; } @@ -94,7 +104,6 @@ class CategoryFactory public function setUser(User $user) { $this->user = $user; - $this->repository->setUser($user); } } \ No newline at end of file diff --git a/app/Factory/PiggyBankFactory.php b/app/Factory/PiggyBankFactory.php index 163c48ee6c..3ded4bfe3c 100644 --- a/app/Factory/PiggyBankFactory.php +++ b/app/Factory/PiggyBankFactory.php @@ -25,7 +25,6 @@ namespace FireflyIII\Factory; use FireflyIII\Models\PiggyBank; -use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; use FireflyIII\User; /** @@ -33,19 +32,9 @@ use FireflyIII\User; */ class PiggyBankFactory { - /** @var PiggyBankRepositoryInterface */ - private $repository; /** @var User */ private $user; - /** - * PiggyBankFactory constructor. - */ - public function __construct() - { - $this->repository = app(PiggyBankRepositoryInterface::class); - } - /** * @param int|null $piggyBankId * @param null|string $piggyBankName @@ -62,7 +51,7 @@ class PiggyBankFactory // first find by ID: if ($piggyBankId > 0) { /** @var PiggyBank $piggyBank */ - $piggyBank = $this->repository->find($piggyBankId); + $piggyBank = $this->user->piggyBanks()->find($piggyBankId); if (!is_null($piggyBank)) { return $piggyBank; } @@ -71,7 +60,7 @@ class PiggyBankFactory // then find by name: if (strlen($piggyBankName) > 0) { /** @var PiggyBank $piggyBank */ - $piggyBank = $this->repository->findByName($piggyBankName); + $piggyBank = $this->findByName($piggyBankName); if (!is_null($piggyBank)) { return $piggyBank; } @@ -81,13 +70,30 @@ class PiggyBankFactory } + /** + * @param string $name + * + * @return PiggyBank|null + */ + public function findByName(string $name): ?PiggyBank + { + $set = $this->user->piggyBanks()->get(); + /** @var PiggyBank $piggy */ + foreach ($set as $piggy) { + if ($piggy->name === $name) { + return $piggy; + } + } + + return null; + } + /** * @param User $user */ public function setUser(User $user) { $this->user = $user; - $this->repository->setUser($user); } diff --git a/app/Factory/TransactionFactory.php b/app/Factory/TransactionFactory.php index f62147d3cb..50cf0b99b5 100644 --- a/app/Factory/TransactionFactory.php +++ b/app/Factory/TransactionFactory.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace FireflyIII\Factory; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Services\Internal\Support\TransactionServiceTrait; @@ -72,8 +71,6 @@ class TransactionFactory * @param array $data * * @return Collection - * @throws FireflyException - * @throws \Exception */ public function createPair(TransactionJournal $journal, array $data): Collection { diff --git a/app/Factory/TransactionJournalFactory.php b/app/Factory/TransactionJournalFactory.php index dbded6711c..77c9828a78 100644 --- a/app/Factory/TransactionJournalFactory.php +++ b/app/Factory/TransactionJournalFactory.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace FireflyIII\Factory; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Note; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; use FireflyIII\Services\Internal\Support\JournalServiceTrait; @@ -100,6 +99,7 @@ class TransactionJournalFactory $this->storeMeta($journal, $data, 'invoice_date'); $this->storeMeta($journal, $data, 'internal_reference'); Log::debug('End of TransactionJournalFactory::create()'); + return $journal; } @@ -145,7 +145,7 @@ class TransactionJournalFactory $factory = app(TransactionTypeFactory::class); $transactionType = $factory->find($type); if (is_null($transactionType)) { - throw new FireflyException(sprintf('Could not find transaction type for "%s"', $type)); + throw new FireflyException(sprintf('Could not find transaction type for "%s"', $type)); // @codeCoverageIgnore } return $transactionType; diff --git a/app/Factory/TransactionJournalMetaFactory.php b/app/Factory/TransactionJournalMetaFactory.php index a9c0ebcbed..999d4fb3d2 100644 --- a/app/Factory/TransactionJournalMetaFactory.php +++ b/app/Factory/TransactionJournalMetaFactory.php @@ -24,7 +24,9 @@ declare(strict_types=1); namespace FireflyIII\Factory; use Carbon\Carbon; +use Exception; use FireflyIII\Models\TransactionJournalMeta; +use Log; /** * Class TransactionJournalMetaFactory @@ -35,7 +37,6 @@ class TransactionJournalMetaFactory * @param array $data * * @return TransactionJournalMeta|null - * @throws \Exception */ public function updateOrCreate(array $data): ?TransactionJournalMeta { @@ -43,7 +44,11 @@ class TransactionJournalMetaFactory /** @var TransactionJournalMeta $entry */ $entry = $data['journal']->transactionJournalMeta()->where('name', $data['name'])->first(); if (is_null($value) && !is_null($entry)) { - $entry->delete(); + try { + $entry->delete(); + } catch (Exception $e) { // @codeCoverageIgnore + Log::error(sprintf('Could not delete transaction journal meta: %s', $e->getMessage())); // @codeCoverageIgnore + } return null; } diff --git a/app/Factory/TransactionTypeFactory.php b/app/Factory/TransactionTypeFactory.php index db64162827..178dc21d6c 100644 --- a/app/Factory/TransactionTypeFactory.php +++ b/app/Factory/TransactionTypeFactory.php @@ -26,6 +26,7 @@ namespace FireflyIII\Factory; use FireflyIII\Models\TransactionType; /** + * @codeCoverageIgnore * Class TransactionTypeFactory */ class TransactionTypeFactory diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php index 368ee78f1f..62513a643c 100644 --- a/app/Repositories/Bill/BillRepository.php +++ b/app/Repositories/Bill/BillRepository.php @@ -552,7 +552,7 @@ class BillRepository implements BillRepositoryInterface /** @var BillFactory $factory */ $factory = app(BillFactory::class); $factory->setUser($this->user); - $bill = $factory->store($data); + $bill = $factory->create($data); return $bill; diff --git a/app/Services/Internal/Support/AccountServiceTrait.php b/app/Services/Internal/Support/AccountServiceTrait.php index 251f114757..5a4dc690c2 100644 --- a/app/Services/Internal/Support/AccountServiceTrait.php +++ b/app/Services/Internal/Support/AccountServiceTrait.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Services\Internal\Support; -use FireflyIII\Exceptions\FireflyException; +use Exception; use FireflyIII\Factory\AccountFactory; use FireflyIII\Factory\AccountMetaFactory; use FireflyIII\Factory\TransactionFactory; @@ -57,7 +57,6 @@ trait AccountServiceTrait * @param Account $account * * @return bool - * @throws \Exception */ public function deleteIB(Account $account): bool { @@ -67,7 +66,11 @@ trait AccountServiceTrait // opening balance data? update it! if (null !== $openingBalance) { Log::debug('Opening balance journal found, delete journal.'); - $openingBalance->delete(); + try { + $openingBalance->delete(); + } catch (Exception $e) { + Log::error(sprintf('Could not delete opening balance: %s', $e->getMessage())); + } return true; } @@ -126,7 +129,6 @@ trait AccountServiceTrait * @param array $data * * @return TransactionJournal|null - * @throws \FireflyIII\Exceptions\FireflyException */ public function storeIBJournal(Account $account, array $data): ?TransactionJournal { @@ -233,8 +235,6 @@ trait AccountServiceTrait * @param array $data * * @return bool - * @throws FireflyException - * @throws \Exception */ public function updateIB(Account $account, array $data): bool { @@ -266,8 +266,6 @@ trait AccountServiceTrait * @param array $data * * @return bool - * - * @throws \Exception */ public function updateIBJournal(Account $account, TransactionJournal $journal, array $data): bool { @@ -279,7 +277,12 @@ trait AccountServiceTrait Log::debug(sprintf('Submitted amount for opening balance to update is "%s"', $amount)); if (0 === bccomp($amount, '0')) { Log::notice(sprintf('Amount "%s" is zero, delete opening balance.', $amount)); - $journal->delete(); + try { + $journal->delete(); + } catch (Exception $e) { + Log::error(sprintf('Could not delete opening balance: %s', $e->getMessage())); + } + return true; } diff --git a/app/Services/Internal/Support/BillServiceTrait.php b/app/Services/Internal/Support/BillServiceTrait.php index 7269c82828..4ae1c624c9 100644 --- a/app/Services/Internal/Support/BillServiceTrait.php +++ b/app/Services/Internal/Support/BillServiceTrait.php @@ -32,6 +32,8 @@ use FireflyIII\Models\Note; */ trait BillServiceTrait { + + /** * @param Bill $bill * @param string $note diff --git a/app/Services/Internal/Support/JournalServiceTrait.php b/app/Services/Internal/Support/JournalServiceTrait.php index 8078f77d86..d015c5d22b 100644 --- a/app/Services/Internal/Support/JournalServiceTrait.php +++ b/app/Services/Internal/Support/JournalServiceTrait.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace FireflyIII\Services\Internal\Support; -use Exception; use FireflyIII\Factory\BillFactory; use FireflyIII\Factory\TagFactory; use FireflyIII\Factory\TransactionJournalMetaFactory; @@ -74,7 +73,7 @@ trait JournalServiceTrait $factory->setUser($journal->user); $set = []; if (!is_array($data['tags'])) { - return; + return; // @codeCoverageIgnore } foreach ($data['tags'] as $string) { if (strlen($string) > 0) { @@ -102,11 +101,7 @@ trait JournalServiceTrait ]; /** @var TransactionJournalMetaFactory $factory */ $factory = app(TransactionJournalMetaFactory::class); - try { - $factory->updateOrCreate($set); - } catch (Exception $e) { - // don't care - } + $factory->updateOrCreate($set); } /** diff --git a/app/Services/Internal/Support/TransactionServiceTrait.php b/app/Services/Internal/Support/TransactionServiceTrait.php index cc92aa09df..d87f3731d2 100644 --- a/app/Services/Internal/Support/TransactionServiceTrait.php +++ b/app/Services/Internal/Support/TransactionServiceTrait.php @@ -24,8 +24,6 @@ declare(strict_types=1); namespace FireflyIII\Services\Internal\Support; -use Exception; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\AccountFactory; use FireflyIII\Factory\BudgetFactory; use FireflyIII\Factory\CategoryFactory; @@ -39,6 +37,7 @@ use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use Log; /** * Trait TransactionServiceTrait @@ -53,7 +52,6 @@ trait TransactionServiceTrait * @param string $direction * * @return string|null - * @throws FireflyException */ public function accountType(TransactionJournal $journal, string $direction): ?string { @@ -61,7 +59,11 @@ trait TransactionServiceTrait $type = $journal->transactionType->type; switch ($type) { default: - throw new FireflyException(sprintf('Cannot handle type "%s" in accountType()', $type)); + // @codeCoverageIgnoreStart + Log::error(sprintf('Cannot handle type "%s" in accountType()', $type)); + + return null; + // @codeCoverageIgnoreEnd case TransactionType::WITHDRAWAL: $types['source'] = AccountType::ASSET; $types['destination'] = AccountType::EXPENSE; @@ -83,20 +85,22 @@ trait TransactionServiceTrait return $types[$direction]; } if (!isset($types[$direction])) { - throw new FireflyException(sprintf('No type set for direction "%s" and type "%s"', $type, $direction)); + // @codeCoverageIgnoreStart + Log::error(sprintf('No type set for direction "%s" and type "%s"', $type, $direction)); + + return null; + // @codeCoverageIgnoreEnd } return $types[$direction]; } /** - * @param string|null $expectedType + * @param string|null $expectedType * @param int|null $accountId * @param string|null $accountName * * @return Account - * @throws FireflyException - * @throws Exception */ public function findAccount(?string $expectedType, ?int $accountId, ?string $accountName): Account { @@ -105,7 +109,7 @@ trait TransactionServiceTrait $repository = app(AccountRepositoryInterface::class); $repository->setUser($this->user); - if(is_null($expectedType)) { + if (is_null($expectedType)) { return $repository->findNull($accountId); } @@ -153,7 +157,11 @@ trait TransactionServiceTrait return $repository->getCashAccount(); default: - throw new FireflyException(sprintf('Cannot find account of type "%s".', $expectedType)); + // @codeCoverageIgnoreStart + Log::error(sprintf('Cannot find account of type "%s".', $expectedType)); + + return null; + // @codeCoverageIgnoreEnd } } @@ -233,7 +241,7 @@ trait TransactionServiceTrait /** * @param Transaction $transaction - * @param string|null $amount + * @param string|null $amount */ protected function setForeignAmount(Transaction $transaction, ?string $amount): void { diff --git a/tests/Unit/Factory/AccountFactoryTest.php b/tests/Unit/Factory/AccountFactoryTest.php new file mode 100644 index 0000000000..79e031fb61 --- /dev/null +++ b/tests/Unit/Factory/AccountFactoryTest.php @@ -0,0 +1,396 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + + +use Carbon\Carbon; +use FireflyIII\Factory\AccountFactory; +use FireflyIII\Models\AccountType; +use Tests\TestCase; + +/** + * Class AccountFactoryTest + */ +class AccountFactoryTest extends TestCase +{ + /** + * Test minimal set of data to make factory work (asset account). + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Factory\AccountMetaFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateBasic() + { + + $data = [ + 'account_type_id' => null, + 'accountType' => 'asset', + 'iban' => null, + 'name' => 'Basic asset account #' . rand(1, 1000), + 'virtualBalance' => null, + 'active' => true, + 'accountRole' => 'defaultAsset', + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + $account = $factory->create($data); + + // assert stuff about account: + $this->assertEquals($account->name, $data['name']); + $this->assertEquals(AccountType::ASSET, $account->accountType->type); + $this->assertEquals('', $account->iban); + $this->assertTrue($account->active); + $this->assertEquals('0', $account->virtual_balance); + $this->assertEquals('defaultAsset', $account->getMeta('accountRole')); + } + + /** + * Test creation of CC asset. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Factory\AccountMetaFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateBasicCC() + { + + $data = [ + 'account_type_id' => null, + 'accountType' => 'asset', + 'iban' => null, + 'name' => 'Basic CC account #' . rand(1, 1000), + 'virtualBalance' => null, + 'active' => true, + 'accountRole' => 'ccAsset', + 'ccMonthlyPaymentDate' => '2018-01-01', + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + $account = $factory->create($data); + + // assert stuff about account: + $this->assertEquals($account->name, $data['name']); + $this->assertEquals(AccountType::ASSET, $account->accountType->type); + $this->assertEquals('', $account->iban); + $this->assertTrue($account->active); + $this->assertEquals('0', $account->virtual_balance); + $this->assertEquals('ccAsset', $account->getMeta('accountRole')); + $this->assertEquals('2018-01-01', $account->getMeta('ccMonthlyPaymentDate')); + } + + /** + * Create an expense account. This overrules the virtual balance. + * Role should not be set. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Factory\AccountMetaFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateBasicExpense() + { + + $data = [ + 'account_type_id' => null, + 'accountType' => 'expense', + 'iban' => null, + 'name' => 'Basic expense account #' . rand(1, 1000), + 'virtualBalance' => '1243', + 'active' => true, + 'accountRole' => 'defaultAsset', + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + $account = $factory->create($data); + + // assert stuff about account: + $this->assertEquals($account->name, $data['name']); + $this->assertEquals(AccountType::EXPENSE, $account->accountType->type); + $this->assertEquals('', $account->iban); + $this->assertTrue($account->active); + $this->assertEquals('0', $account->virtual_balance); + $this->assertEquals('', $account->getMeta('accountRole')); + } + + /** + * Submit IB data for asset account. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Factory\AccountMetaFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateBasicIB() + { + + $data = [ + 'account_type_id' => null, + 'accountType' => 'asset', + 'iban' => null, + 'name' => 'Basic asset account #' . rand(1, 1000), + 'virtualBalance' => null, + 'active' => true, + 'accountRole' => 'defaultAsset', + 'openingBalance' => '100', + 'openingBalanceDate' => new Carbon('2018-01-01'), + 'currency_id' => 1, + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + $account = $factory->create($data); + + // assert stuff about account: + $this->assertEquals($account->name, $data['name']); + $this->assertEquals(AccountType::ASSET, $account->accountType->type); + $this->assertEquals('', $account->iban); + $this->assertTrue($account->active); + $this->assertEquals('0', $account->virtual_balance); + $this->assertEquals('defaultAsset', $account->getMeta('accountRole')); + + // find opening balance: + $this->assertEquals(1, $account->transactions()->count()); + $this->assertEquals(100, floatval($account->transactions()->first()->amount)); + } + + /** + * Submit empty (amount = 0) IB data for asset account. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Factory\AccountMetaFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateBasicIBZero() + { + + $data = [ + 'account_type_id' => null, + 'accountType' => 'asset', + 'iban' => null, + 'name' => 'Basic asset account #' . rand(1, 1000), + 'virtualBalance' => null, + 'active' => true, + 'accountRole' => 'defaultAsset', + 'openingBalance' => '0.0', + 'openingBalanceDate' => new Carbon('2018-01-01'), + 'currency_id' => 1, + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + $account = $factory->create($data); + + // assert stuff about account: + $this->assertEquals($account->name, $data['name']); + $this->assertEquals(AccountType::ASSET, $account->accountType->type); + $this->assertEquals('', $account->iban); + $this->assertTrue($account->active); + $this->assertEquals('0', $account->virtual_balance); + $this->assertEquals('defaultAsset', $account->getMeta('accountRole')); + + // find opening balance: + $this->assertEquals(0, $account->transactions()->count()); + } + + /** + * Add valid IBAN. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Factory\AccountMetaFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateBasicIban() + { + + $data = [ + 'account_type_id' => null, + 'accountType' => 'asset', + 'iban' => 'NL18RABO0326747238', + 'name' => 'Basic asset account #' . rand(1, 1000), + 'virtualBalance' => null, + 'active' => true, + 'accountRole' => 'defaultAsset', + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + $account = $factory->create($data); + + // assert stuff about account: + $this->assertEquals($account->name, $data['name']); + $this->assertEquals(AccountType::ASSET, $account->accountType->type); + $this->assertEquals('NL18RABO0326747238', $account->iban); + $this->assertTrue($account->active); + $this->assertEquals('0', $account->virtual_balance); + $this->assertEquals('defaultAsset', $account->getMeta('accountRole')); + } + + /** + * Add invalid IBAN. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Factory\AccountMetaFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateBasicInvalidIban() + { + + $data = [ + 'account_type_id' => null, + 'accountType' => 'asset', + 'iban' => 'NL1XRABO032674X238', + 'name' => 'Basic asset account #' . rand(1, 1000), + 'virtualBalance' => null, + 'active' => true, + 'accountRole' => 'defaultAsset', + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + $account = $factory->create($data); + + // assert stuff about account: + $this->assertEquals($account->name, $data['name']); + $this->assertEquals(AccountType::ASSET, $account->accountType->type); + $this->assertEquals('', $account->iban); + $this->assertTrue($account->active); + $this->assertEquals('0', $account->virtual_balance); + $this->assertEquals('defaultAsset', $account->getMeta('accountRole')); + } + + /** + * Submit IB data for asset account. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Factory\AccountMetaFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateBasicNegativeIB() + { + + $data = [ + 'account_type_id' => null, + 'accountType' => 'asset', + 'iban' => null, + 'name' => 'Basic asset account #' . rand(1, 1000), + 'virtualBalance' => null, + 'active' => true, + 'accountRole' => 'defaultAsset', + 'openingBalance' => '-100', + 'openingBalanceDate' => new Carbon('2018-01-01'), + 'currency_id' => 1, + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + $account = $factory->create($data); + + // assert stuff about account: + $this->assertEquals($account->name, $data['name']); + $this->assertEquals(AccountType::ASSET, $account->accountType->type); + $this->assertEquals('', $account->iban); + $this->assertTrue($account->active); + $this->assertEquals('0', $account->virtual_balance); + $this->assertEquals('defaultAsset', $account->getMeta('accountRole')); + + // find opening balance: + $this->assertEquals(1, $account->transactions()->count()); + $this->assertEquals(-100, floatval($account->transactions()->first()->amount)); + } + + /** + * Add some notes to asset account. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Factory\AccountMetaFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateBasicNotes() + { + + $data = [ + 'account_type_id' => null, + 'accountType' => 'asset', + 'iban' => null, + 'name' => 'Basic asset account #' . rand(1, 1000), + 'virtualBalance' => null, + 'active' => true, + 'accountRole' => 'defaultAsset', + 'notes' => 'Hello!', + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + $account = $factory->create($data); + + // assert stuff about account: + $this->assertEquals($account->name, $data['name']); + $this->assertEquals(AccountType::ASSET, $account->accountType->type); + $this->assertEquals('', $account->iban); + $this->assertTrue($account->active); + $this->assertEquals('0', $account->virtual_balance); + $this->assertEquals('defaultAsset', $account->getMeta('accountRole')); + $note = $account->notes()->first(); + $this->assertEquals('Hello!', $note->text); + } + + /** + * Should return existing account. + * + * @covers \FireflyIII\Factory\AccountFactory + */ + public function testCreateExisting() + { + $existing = $this->user()->accounts()->where('account_type_id', 3)->first(); + $data = [ + 'account_type_id' => null, + 'accountType' => 'asset', + 'name' => $existing->name, + 'virtualBalance' => null, + 'iban' => null, + 'active' => true, + 'accountRole' => 'defaultAsset', + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + $account = $factory->create($data); + + // assert stuff about account: + $this->assertEquals($account->id, $existing->id); + } + +} \ No newline at end of file diff --git a/tests/Unit/Factory/BillFactoryTest.php b/tests/Unit/Factory/BillFactoryTest.php new file mode 100644 index 0000000000..df04b26a2a --- /dev/null +++ b/tests/Unit/Factory/BillFactoryTest.php @@ -0,0 +1,134 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + + +use FireflyIII\Factory\BillFactory; +use Tests\TestCase; + +/** + * Class BillFactoryTest + */ +class BillFactoryTest extends TestCase +{ + + /** + * Create basic bill with minimum data. + * + * @covers \FireflyIII\Factory\BillFactory + * @covers \FireflyIII\Services\Internal\Support\BillServiceTrait + */ + public function testCreateBasic() + { + $data = [ + 'name' => 'Some new bill #' . rand(1, 1000), + 'match' => 'i,am,word' . rand(1, 1000), + 'amount_min' => '5', + 'amount_max' => '10', + 'date' => '2018-01-01', + 'repeat_freq' => 'monthly', + 'skip' => 0, + 'automatch' => true, + 'active' => true, + 'notes' => 'Hello!', + ]; + + /** @var BillFactory $factory */ + $factory = app(BillFactory::class); + $factory->setUser($this->user()); + $bill = $factory->create($data); + + $this->assertEquals($data['name'], $bill->name); + $this->assertEquals($data['match'], $bill->match); + $this->assertEquals($data['amount_min'], $bill->amount_min); + $this->assertEquals($data['repeat_freq'], $bill->repeat_freq); + $note = $bill->notes()->first(); + $this->assertEquals($data['notes'], $note->text); + + } + + /** + * Find by ID + * + * @covers \FireflyIII\Factory\BillFactory + * + */ + public function testFindById() + { + $existing = $this->user()->piggyBanks()->first(); + /** @var BillFactory $factory */ + $factory = app(BillFactory::class); + $factory->setUser($this->user()); + $piggy = $factory->find($existing->id, null); + $this->assertEquals($existing->id, $piggy->id); + } + + /** + * Find by name + * + * @covers \FireflyIII\Factory\BillFactory + * + */ + public function testFindByName() + { + $existing = $this->user()->bills()->first(); + /** @var BillFactory $factory */ + $factory = app(BillFactory::class); + $factory->setUser($this->user()); + $piggy = $factory->find(null, $existing->name); + + $this->assertEquals($existing->id, $piggy->id); + } + + /** + * Find by unknown name + * + * @covers \FireflyIII\Factory\BillFactory + * + */ + public function testFindByUnknownName() + { + /** @var BillFactory $factory */ + $factory = app(BillFactory::class); + $factory->setUser($this->user()); + $piggy = $factory->find(null, 'I dont exist' . rand(1, 1000)); + + $this->assertNull($piggy); + } + + /** + * Find NULL + * + * @covers \FireflyIII\Factory\BillFactory + * + */ + public function testFindNull() + { + /** @var BillFactory $factory */ + $factory = app(BillFactory::class); + $factory->setUser($this->user()); + $this->assertNull($factory->find(null, null)); + } + +} \ No newline at end of file diff --git a/tests/Unit/Factory/BudgetFactoryTest.php b/tests/Unit/Factory/BudgetFactoryTest.php new file mode 100644 index 0000000000..a55a6e6e14 --- /dev/null +++ b/tests/Unit/Factory/BudgetFactoryTest.php @@ -0,0 +1,97 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + + +use FireflyIII\Factory\BudgetFactory; +use Tests\TestCase; + +/** + * Class BudgetFactoryTest + */ +class BudgetFactoryTest extends TestCase +{ + /** + * Put in ID, return it. + * + * @covers \FireflyIII\Factory\BudgetFactory + */ + public function testFindById() + { + $existing = $this->user()->budgets()->first(); + /** @var BudgetFactory $factory */ + $factory = app(BudgetFactory::class); + $factory->setUser($this->user()); + + $budget = $factory->find($existing->id, null); + $this->assertEquals($existing->id, $budget->id); + + } + + /** + * Put in name, return it. + * + * @covers \FireflyIII\Factory\BudgetFactory + */ + public function testFindByName() + { + $existing = $this->user()->budgets()->first(); + /** @var BudgetFactory $factory */ + $factory = app(BudgetFactory::class); + $factory->setUser($this->user()); + + $budget = $factory->find(null, $existing->name); + $this->assertEquals($existing->id, $budget->id); + + } + + /** + * Put in unknown, get NULL + * + * @covers \FireflyIII\Factory\BudgetFactory + */ + public function testFindUnknown() + { + /** @var BudgetFactory $factory */ + $factory = app(BudgetFactory::class); + $factory->setUser($this->user()); + $this->assertNull($factory->find(null, 'I dont exist.'.rand(1,000))); + } + + /** + * Put in NULL, will find NULL. + * + * @covers \FireflyIII\Factory\BudgetFactory + */ + public function testFindNull() + { + /** @var BudgetFactory $factory */ + $factory = app(BudgetFactory::class); + $factory->setUser($this->user()); + + $this->assertNull($factory->find(null, null)); + + } + +} \ No newline at end of file diff --git a/tests/Unit/Factory/CategoryFactoryTest.php b/tests/Unit/Factory/CategoryFactoryTest.php new file mode 100644 index 0000000000..185de567da --- /dev/null +++ b/tests/Unit/Factory/CategoryFactoryTest.php @@ -0,0 +1,103 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + +use FireflyIII\Factory\CategoryFactory; +use Tests\TestCase; + +/** + * Class CategoryFactoryTest + */ +class CategoryFactoryTest extends TestCase +{ + /** + * @covers \FireflyIII\Factory\CategoryFactory + */ + public function testFindOrCreateExistingID() + { + $existing = $this->user()->categories()->first(); + + /** @var CategoryFactory $factory */ + $factory = app(CategoryFactory::class); + $factory->setUser($this->user()); + $category = $factory->findOrCreate($existing->id, null); + $this->assertEquals($existing->id, $category->id); + } + + /** + * @covers \FireflyIII\Factory\CategoryFactory + */ + public function testFindOrCreateExistingName() + { + $existing = $this->user()->categories()->first(); + + /** @var CategoryFactory $factory */ + $factory = app(CategoryFactory::class); + $factory->setUser($this->user()); + $category = $factory->findOrCreate(null, $existing->name); + $this->assertEquals($existing->id, $category->id); + } + + /** + * You can force a NULL result by presenting an invalid ID and no valid name. + * + * @covers \FireflyIII\Factory\CategoryFactory + */ + public function testFindOrCreateInvalidID() + { + $existing = $this->user()->categories()->max('id'); + $existing = $existing + 4; + + /** @var CategoryFactory $factory */ + $factory = app(CategoryFactory::class); + $factory->setUser($this->user()); + $this->assertNull($factory->findOrCreate($existing, '')); + } + + /** + * @covers \FireflyIII\Factory\CategoryFactory + */ + public function testFindOrCreateNewName() + { + $name = 'Some new category #' . rand(1, 1000); + + /** @var CategoryFactory $factory */ + $factory = app(CategoryFactory::class); + $factory->setUser($this->user()); + $category = $factory->findOrCreate(null, $name); + $this->assertEquals($name, $category->name); + } + + /** + * @covers \FireflyIII\Factory\CategoryFactory + */ + public function testFindOrCreateNull() + { + /** @var CategoryFactory $factory */ + $factory = app(CategoryFactory::class); + $factory->setUser($this->user()); + $this->assertNull($factory->findOrCreate(null, null)); + } + +} \ No newline at end of file diff --git a/tests/Unit/Factory/PiggyBankEventFactoryTest.php b/tests/Unit/Factory/PiggyBankEventFactoryTest.php new file mode 100644 index 0000000000..06ecd5afea --- /dev/null +++ b/tests/Unit/Factory/PiggyBankEventFactoryTest.php @@ -0,0 +1,135 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + + +use FireflyIII\Factory\PiggyBankEventFactory; +use FireflyIII\Models\PiggyBankEvent; +use FireflyIII\Models\PiggyBankRepetition; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; +use Tests\TestCase; + +/** + * Class PiggyBankEventFactoryTest + */ +class PiggyBankEventFactoryTest extends TestCase +{ + /** + * @covers \FireflyIII\Factory\PiggyBankEventFactory + */ + public function testCreateAmountZero() + { + /** @var TransactionJournal $transfer */ + $transfer = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); + $piggy = $this->user()->piggyBanks()->first(); + $repetition = PiggyBankRepetition::first(); + $repos = $this->mock(PiggyBankRepositoryInterface::class); + /** @var PiggyBankEventFactory $factory */ + $factory = app(PiggyBankEventFactory::class); + + // mock: + $repos->shouldReceive('setUser'); + $repos->shouldReceive('getRepetition')->andReturn($repetition); + $repos->shouldReceive('getExactAmount')->andReturn('0'); + + $this->assertNull($factory->create($transfer, $piggy)); + } + + /** + * @covers \FireflyIII\Factory\PiggyBankEventFactory + */ + public function testCreateNoPiggy() + { + /** @var TransactionJournal $transfer */ + $transfer = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); + + /** @var PiggyBankEventFactory $factory */ + $factory = app(PiggyBankEventFactory::class); + + $this->assertNull($factory->create($transfer, null)); + } + + /** + * @covers \FireflyIII\Factory\PiggyBankEventFactory + */ + public function testCreateNoRep() + { + /** @var TransactionJournal $transfer */ + $transfer = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); + $piggy = $this->user()->piggyBanks()->first(); + $repetition = new PiggyBankRepetition; + $repos = $this->mock(PiggyBankRepositoryInterface::class); + /** @var PiggyBankEventFactory $factory */ + $factory = app(PiggyBankEventFactory::class); + + // mock: + $repos->shouldReceive('setUser'); + $repos->shouldReceive('getRepetition')->andReturn($repetition); + $repos->shouldReceive('getExactAmount')->andReturn('0'); + + $this->assertNull($factory->create($transfer, $piggy)); + } + + /** + * @covers \FireflyIII\Factory\PiggyBankEventFactory + */ + public function testCreateNotTransfer() + { + /** @var TransactionJournal $deposit */ + $deposit = $this->user()->transactionJournals()->where('transaction_type_id', 2)->first(); + $piggy = $this->user()->piggyBanks()->first(); + /** @var PiggyBankEventFactory $factory */ + $factory = app(PiggyBankEventFactory::class); + + $this->assertNull($factory->create($deposit, $piggy)); + } + + /** + * @covers \FireflyIII\Factory\PiggyBankEventFactory + */ + public function testCreateSuccess() + { + /** @var TransactionJournal $transfer */ + $transfer = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); + $piggy = $this->user()->piggyBanks()->first(); + $repetition = PiggyBankRepetition::first(); + $event = PiggyBankEvent::first(); + $repos = $this->mock(PiggyBankRepositoryInterface::class); + /** @var PiggyBankEventFactory $factory */ + $factory = app(PiggyBankEventFactory::class); + + // mock: + $repos->shouldReceive('setUser'); + $repos->shouldReceive('getRepetition')->andReturn($repetition); + $repos->shouldReceive('getExactAmount')->andReturn('5'); + $repos->shouldReceive('addAmountToRepetition')->once(); + $repos->shouldReceive('createEventWithJournal')->once()->andReturn($event); + + $result = $factory->create($transfer, $piggy); + $this->assertEquals($result->id, $event->id); + + } + +} \ No newline at end of file diff --git a/tests/Unit/Factory/PiggyBankFactoryTest.php b/tests/Unit/Factory/PiggyBankFactoryTest.php new file mode 100644 index 0000000000..68e6768808 --- /dev/null +++ b/tests/Unit/Factory/PiggyBankFactoryTest.php @@ -0,0 +1,96 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + + +use FireflyIII\Factory\PiggyBankFactory; +use Tests\TestCase; + +/** + * Class PiggyBankFactoryTest + */ +class PiggyBankFactoryTest extends TestCase +{ + /** + * Put in ID, return it. + * + * @covers \FireflyIII\Factory\PiggyBankFactory + */ + public function testFindById() + { + $existing = $this->user()->piggyBanks()->first(); + /** @var PiggyBankFactory $factory */ + $factory = app(PiggyBankFactory::class); + $factory->setUser($this->user()); + + $piggyBank = $factory->find($existing->id, null); + $this->assertEquals($existing->id, $piggyBank->id); + + } + + /** + * Put in name, return it. + * + * @covers \FireflyIII\Factory\PiggyBankFactory + */ + public function testFindByName() + { + $existing = $this->user()->piggyBanks()->first(); + /** @var PiggyBankFactory $factory */ + $factory = app(PiggyBankFactory::class); + $factory->setUser($this->user()); + + $piggyBank = $factory->find(null, $existing->name); + $this->assertEquals($existing->id, $piggyBank->id); + + } + + /** + * Put in NULL, will find NULL. + * + * @covers \FireflyIII\Factory\PiggyBankFactory + */ + public function testFindNull() + { + /** @var PiggyBankFactory $factory */ + $factory = app(PiggyBankFactory::class); + $factory->setUser($this->user()); + + $this->assertNull($factory->find(null, null)); + + } + + /** + * Put in unknown, get NULL + * + * @covers \FireflyIII\Factory\PiggyBankFactory + */ + public function testFindUnknown() + { + /** @var PiggyBankFactory $factory */ + $factory = app(PiggyBankFactory::class); + $factory->setUser($this->user()); + $this->assertNull($factory->find(null, 'I dont exist.' . rand(1, 000))); + } +} \ No newline at end of file diff --git a/tests/Unit/Factory/TagFactoryTest.php b/tests/Unit/Factory/TagFactoryTest.php new file mode 100644 index 0000000000..4c1590bd34 --- /dev/null +++ b/tests/Unit/Factory/TagFactoryTest.php @@ -0,0 +1,63 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + + +use FireflyIII\Factory\TagFactory; +use Tests\TestCase; + +/** + * Class TagFactoryTest + */ +class TagFactoryTest extends TestCase +{ + /** + * @covers \FireflyIII\Factory\TagFactory + */ + public function testFindOrCreateExisting() + { + $tag = $this->user()->tags()->first(); + /** @var TagFactory $factory */ + $factory = app(TagFactory::class); + $factory->setUser($this->user()); + + $result = $factory->findOrCreate($tag->tag); + $this->assertEquals($tag->id, $result->id); + } + + /** + * @covers \FireflyIII\Factory\TagFactory + */ + public function testFindOrCreateNew() + { + $tag = 'Some new tag#' . rand(1, 1000); + /** @var TagFactory $factory */ + $factory = app(TagFactory::class); + $factory->setUser($this->user()); + + $result = $factory->findOrCreate($tag); + $this->assertEquals($tag, $result->tag); + } + +} \ No newline at end of file diff --git a/tests/Unit/Factory/TransactionCurrencyFactoryTest.php b/tests/Unit/Factory/TransactionCurrencyFactoryTest.php new file mode 100644 index 0000000000..fa061071b0 --- /dev/null +++ b/tests/Unit/Factory/TransactionCurrencyFactoryTest.php @@ -0,0 +1,81 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + + +use FireflyIII\Factory\TransactionCurrencyFactory; +use FireflyIII\Models\TransactionCurrency; +use Tests\TestCase; + +/** + * Class TransactionCurrencyFactoryTest + */ +class TransactionCurrencyFactoryTest extends TestCase +{ + /** + * @covers \FireflyIII\Factory\TransactionCurrencyFactory + */ + public function testFindByBadCode() + { + /** @var TransactionCurrencyFactory $factory */ + $factory = app(TransactionCurrencyFactory::class); + $this->assertNull($factory->find(null, 'BAD CODE')); + + } + + /** + * @covers \FireflyIII\Factory\TransactionCurrencyFactory + */ + public function testFindByCode() + { + $currency = TransactionCurrency::find(1); + /** @var TransactionCurrencyFactory $factory */ + $factory = app(TransactionCurrencyFactory::class); + $result = $factory->find(null, $currency->code); + $this->assertEquals($currency->id, $result->id); + } + + /** + * @covers \FireflyIII\Factory\TransactionCurrencyFactory + */ + public function testFindByID() + { + $currency = TransactionCurrency::find(1); + /** @var TransactionCurrencyFactory $factory */ + $factory = app(TransactionCurrencyFactory::class); + $result = $factory->find($currency->id, null); + $this->assertEquals($currency->id, $result->id); + } + + /** + * @covers \FireflyIII\Factory\TransactionCurrencyFactory + */ + public function testFindNull() + { + /** @var TransactionCurrencyFactory $factory */ + $factory = app(TransactionCurrencyFactory::class); + $this->assertNull($factory->find(null, null)); + } + +} \ No newline at end of file diff --git a/tests/Unit/Factory/TransactionFactoryTest.php b/tests/Unit/Factory/TransactionFactoryTest.php new file mode 100644 index 0000000000..b88b5ee005 --- /dev/null +++ b/tests/Unit/Factory/TransactionFactoryTest.php @@ -0,0 +1,823 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + + +use FireflyIII\Factory\AccountFactory; +use FireflyIII\Factory\BudgetFactory; +use FireflyIII\Factory\CategoryFactory; +use FireflyIII\Factory\TransactionCurrencyFactory; +use FireflyIII\Factory\TransactionFactory; +use FireflyIII\Models\AccountType; +use FireflyIII\Models\Transaction; +use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use Tests\TestCase; + +/** + * Class TransactionFactoryTest + */ +class TransactionFactoryTest extends TestCase +{ + /** + * @covers \FireflyIII\Factory\TransactionFactory + * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait + */ + public function testCreatePairBasic() + { + // objects: + $asset = $this->user()->accounts()->where('account_type_id', 3)->first(); + $expense = $this->user()->accounts()->where('account_type_id', 4)->first(); + $euro = TransactionCurrency::first(); + + // mocked classes + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + + $data = [ + 'currency_id' => 1, + 'currency_code' => null, + 'description' => null, + 'source_id' => $asset->id, + 'source_name' => null, + 'destination_id' => $expense->id, + 'destination_name' => null, + 'amount' => '10', + 'reconciled' => false, + 'identifier' => 0, + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'budget_id' => null, + 'budget_name' => null, + 'category_id' => null, + 'category_name' => null, + ]; + + // mock: + $accountRepos->shouldReceive('setUser'); + $budgetFactory->shouldReceive('setUser'); + $categoryFactory->shouldReceive('setUser'); + // first search action is for the asset account, second is for expense account. + $accountRepos->shouldReceive('findNull')->andReturn($asset, $expense); + + // factories return various stuff: + $budgetFactory->shouldReceive('find')->andReturn(null); + $categoryFactory->shouldReceive('findOrCreate')->andReturn(null); + $currencyFactory->shouldReceive('find')->andReturn($euro, null); + + /** @var TransactionJournal $withdrawal */ + $withdrawal = $this->user()->transactionJournals()->where('transaction_type_id', 1)->first(); + $count = $withdrawal->transactions()->count(); + + /** @var TransactionFactory $factory */ + $factory = app(TransactionFactory::class); + $factory->setUser($this->user()); + $collection = $factory->createPair($withdrawal, $data); + + $newCount = $withdrawal->transactions()->count(); + + $this->assertCount(2, $collection); + $this->assertEquals($count + 2, $newCount); + // find stuff in transaction #1 (should suffice): + /** @var Transaction $first */ + $first = $collection->first(); + $this->assertEquals($withdrawal->id, $first->transaction_journal_id); + $this->assertEquals(-10, $first->amount); + $this->assertEquals(false, $first->reconciled); + $this->assertEquals(0, $first->identifier); + $this->assertEquals($euro->id, $first->transaction_currency_id); + $this->assertNull($first->foreign_amount); + $this->assertNull($first->foreign_currency_id); + } + + /** + * @covers \FireflyIII\Factory\TransactionFactory + * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait + */ + public function testCreatePairBasicByName() + { + // objects: + $asset = $this->user()->accounts()->where('account_type_id', 3)->first(); + $expense = $this->user()->accounts()->where('account_type_id', 4)->first(); + $euro = TransactionCurrency::first(); + + // mocked classes + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + + $data = [ + 'currency_id' => 1, + 'currency_code' => null, + 'description' => null, + 'source_id' => null, + 'source_name' => $asset->name, + 'destination_id' => null, + 'destination_name' => $expense->name, + 'amount' => '10', + 'reconciled' => false, + 'identifier' => 0, + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'budget_id' => null, + 'budget_name' => null, + 'category_id' => null, + 'category_name' => null, + ]; + + // mock: + $accountRepos->shouldReceive('setUser'); + $budgetFactory->shouldReceive('setUser'); + $categoryFactory->shouldReceive('setUser'); + $accountFactory->shouldReceive('setUser'); + // first search action is for the asset account + $accountRepos->shouldReceive('findByName')->withArgs([$asset->name, [AccountType::ASSET]])->andReturn($asset); + // second is for expense account. + $accountFactory->shouldReceive('findOrCreate')->andReturn($expense); + + // factories return various stuff: + $budgetFactory->shouldReceive('find')->andReturn(null); + $categoryFactory->shouldReceive('findOrCreate')->andReturn(null); + $currencyFactory->shouldReceive('find')->andReturn($euro, null); + + /** @var TransactionJournal $withdrawal */ + $withdrawal = $this->user()->transactionJournals()->where('transaction_type_id', 1)->first(); + $count = $withdrawal->transactions()->count(); + + /** @var TransactionFactory $factory */ + $factory = app(TransactionFactory::class); + $factory->setUser($this->user()); + $collection = $factory->createPair($withdrawal, $data); + + $newCount = $withdrawal->transactions()->count(); + + $this->assertCount(2, $collection); + $this->assertEquals($count + 2, $newCount); + // find stuff in transaction #1 (should suffice): + /** @var Transaction $first */ + $first = $collection->first(); + $this->assertEquals($withdrawal->id, $first->transaction_journal_id); + $this->assertEquals(-10, $first->amount); + $this->assertEquals(false, $first->reconciled); + $this->assertEquals(0, $first->identifier); + $this->assertEquals($euro->id, $first->transaction_currency_id); + $this->assertNull($first->foreign_amount); + $this->assertNull($first->foreign_currency_id); + } + + /** + * @covers \FireflyIII\Factory\TransactionFactory + * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait + */ + public function testCreatePairBasicIntoCash() + { + // objects: + $asset = $this->user()->accounts()->where('account_type_id', 3)->first(); + $expense = $this->user()->accounts()->where('account_type_id', 4)->first(); + $euro = TransactionCurrency::first(); + + // mocked classes + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + + $data = [ + 'currency_id' => 1, + 'currency_code' => null, + 'description' => null, + 'source_id' => null, + 'source_name' => $asset->name, + 'destination_id' => null, + 'destination_name' => '', + 'amount' => '10', + 'reconciled' => false, + 'identifier' => 0, + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'budget_id' => null, + 'budget_name' => null, + 'category_id' => null, + 'category_name' => null, + ]; + + // mock: + $accountRepos->shouldReceive('setUser'); + $budgetFactory->shouldReceive('setUser'); + $categoryFactory->shouldReceive('setUser'); + $accountFactory->shouldReceive('setUser'); + // first search action is for the asset account + $accountRepos->shouldReceive('findByName')->withArgs([$asset->name, [AccountType::ASSET]])->andReturn($asset); + // second is for expense account (cash) + $accountRepos->shouldReceive('getCashAccount')->andReturn($expense); + + // factories return various stuff: + $budgetFactory->shouldReceive('find')->andReturn(null); + $categoryFactory->shouldReceive('findOrCreate')->andReturn(null); + $currencyFactory->shouldReceive('find')->andReturn($euro, null); + + /** @var TransactionJournal $withdrawal */ + $withdrawal = $this->user()->transactionJournals()->where('transaction_type_id', 1)->first(); + $count = $withdrawal->transactions()->count(); + + /** @var TransactionFactory $factory */ + $factory = app(TransactionFactory::class); + $factory->setUser($this->user()); + $collection = $factory->createPair($withdrawal, $data); + + $newCount = $withdrawal->transactions()->count(); + + $this->assertCount(2, $collection); + $this->assertEquals($count + 2, $newCount); + // find stuff in transaction #1 (should suffice): + /** @var Transaction $first */ + $first = $collection->first(); + $this->assertEquals($withdrawal->id, $first->transaction_journal_id); + $this->assertEquals(-10, $first->amount); + $this->assertEquals(false, $first->reconciled); + $this->assertEquals(0, $first->identifier); + $this->assertEquals($euro->id, $first->transaction_currency_id); + $this->assertNull($first->foreign_amount); + $this->assertNull($first->foreign_currency_id); + } + + /** + * Add budget and category data. + * + * @covers \FireflyIII\Factory\TransactionFactory + * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait + */ + public function testCreatePairBasicMeta() + { + // objects: + $asset = $this->user()->accounts()->where('account_type_id', 3)->first(); + $expense = $this->user()->accounts()->where('account_type_id', 4)->first(); + $budget = $this->user()->budgets()->first(); + $category = $this->user()->categories()->first(); + $euro = TransactionCurrency::first(); + + // mocked classes + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + + $data = [ + 'currency_id' => 1, + 'currency_code' => null, + 'description' => null, + 'source_id' => $asset->id, + 'source_name' => null, + 'destination_id' => $expense->id, + 'destination_name' => null, + 'amount' => '10', + 'reconciled' => false, + 'identifier' => 0, + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'budget_id' => $budget->id, + 'budget_name' => null, + 'category_id' => $category->id, + 'category_name' => null, + ]; + + // mock: + $accountRepos->shouldReceive('setUser'); + $budgetFactory->shouldReceive('setUser'); + $categoryFactory->shouldReceive('setUser'); + // first search action is for the asset account, second is for expense account. + $accountRepos->shouldReceive('findNull')->andReturn($asset, $expense); + + // factories return various stuff: + $budgetFactory->shouldReceive('find')->andReturn($budget); + $categoryFactory->shouldReceive('findOrCreate')->andReturn($category); + $currencyFactory->shouldReceive('find')->andReturn($euro, null); + + /** @var TransactionJournal $withdrawal */ + $withdrawal = $this->user()->transactionJournals()->where('transaction_type_id', 1)->first(); + $count = $withdrawal->transactions()->count(); + + /** @var TransactionFactory $factory */ + $factory = app(TransactionFactory::class); + $factory->setUser($this->user()); + $collection = $factory->createPair($withdrawal, $data); + + $newCount = $withdrawal->transactions()->count(); + + $this->assertCount(2, $collection); + $this->assertEquals($count + 2, $newCount); + // find stuff in transaction #1 (should suffice): + /** @var Transaction $first */ + $first = $collection->first(); + $this->assertEquals($withdrawal->id, $first->transaction_journal_id); + $this->assertEquals(-10, $first->amount); + $this->assertEquals(false, $first->reconciled); + $this->assertEquals(0, $first->identifier); + $this->assertEquals($euro->id, $first->transaction_currency_id); + $this->assertNull($first->foreign_amount); + $this->assertNull($first->foreign_currency_id); + $this->assertEquals($budget->name, $first->budgets()->first()->name); + $this->assertEquals($category->name, $first->categories()->first()->name); + } + + /** + * Create deposit using minimal data. + * + * @covers \FireflyIII\Factory\TransactionFactory + * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait + */ + public function testCreatePairDeposit() + { + // objects: + $asset = $this->user()->accounts()->where('account_type_id', 3)->first(); + $revenue = $this->user()->accounts()->where('account_type_id', 5)->first(); + $euro = TransactionCurrency::first(); + $foreign = TransactionCurrency::where('id', '!=', $euro->id)->first(); + + // mocked classes + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + + $data = [ + 'currency_id' => 1, + 'currency_code' => null, + 'description' => null, + 'source_id' => $revenue->id, + 'source_name' => null, + 'destination_id' => $asset->id, + 'destination_name' => null, + 'amount' => '10', + 'reconciled' => false, + 'identifier' => 0, + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'budget_id' => null, + 'budget_name' => null, + 'category_id' => null, + 'category_name' => null, + ]; + + // mock: + $accountRepos->shouldReceive('setUser'); + $budgetFactory->shouldReceive('setUser'); + $categoryFactory->shouldReceive('setUser'); + // first search action is for the asset account, second is for expense account. + $accountRepos->shouldReceive('findNull')->andReturn($revenue, $asset); + + // factories return various stuff: + $budgetFactory->shouldReceive('find')->andReturn(null); + $categoryFactory->shouldReceive('findOrCreate')->andReturn(null); + $currencyFactory->shouldReceive('find')->andReturn($euro, null); + + /** @var TransactionJournal $deposit */ + $deposit = $this->user()->transactionJournals()->where('transaction_type_id', 2)->first(); + $count = $deposit->transactions()->count(); + + /** @var TransactionFactory $factory */ + $factory = app(TransactionFactory::class); + $factory->setUser($this->user()); + $collection = $factory->createPair($deposit, $data); + + $newCount = $deposit->transactions()->count(); + + $this->assertCount(2, $collection); + $this->assertEquals($count + 2, $newCount); + // find stuff in transaction #1 (should suffice): + /** @var Transaction $first */ + $first = $collection->first(); + $this->assertEquals($deposit->id, $first->transaction_journal_id); + $this->assertEquals(-10, $first->amount); + $this->assertEquals(false, $first->reconciled); + $this->assertEquals(0, $first->identifier); + $this->assertEquals($euro->id, $first->transaction_currency_id); + $this->assertNull($first->foreign_amount); + $this->assertNull($first->foreign_currency_id); + } + + /** + * Create deposit using minimal data. + * + * @covers \FireflyIII\Factory\TransactionFactory + * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait + */ + public function testCreatePairDepositByName() + { + // objects: + $asset = $this->user()->accounts()->where('account_type_id', 3)->first(); + $revenue = $this->user()->accounts()->where('account_type_id', 5)->first(); + $euro = TransactionCurrency::first(); + $foreign = TransactionCurrency::where('id', '!=', $euro->id)->first(); + + // mocked classes + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + + $data = [ + 'currency_id' => 1, + 'currency_code' => null, + 'description' => null, + 'source_id' => null, + 'source_name' => $revenue->name, + 'destination_id' => $asset->id, + 'destination_name' => null, + 'amount' => '10', + 'reconciled' => false, + 'identifier' => 0, + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'budget_id' => null, + 'budget_name' => null, + 'category_id' => null, + 'category_name' => null, + ]; + + // mock: + $accountRepos->shouldReceive('setUser'); + $budgetFactory->shouldReceive('setUser'); + $categoryFactory->shouldReceive('setUser'); + $accountFactory->shouldReceive('setUser'); + // first search action is for the asset account + $accountRepos->shouldReceive('findNull')->andReturn($asset); + // second is for revenue account. + $accountFactory->shouldReceive('findOrCreate')->andReturn($revenue); + + // factories return various stuff: + $budgetFactory->shouldReceive('find')->andReturn(null); + $categoryFactory->shouldReceive('findOrCreate')->andReturn(null); + $currencyFactory->shouldReceive('find')->andReturn($euro, null); + + /** @var TransactionJournal $deposit */ + $deposit = $this->user()->transactionJournals()->where('transaction_type_id', 2)->first(); + $count = $deposit->transactions()->count(); + + /** @var TransactionFactory $factory */ + $factory = app(TransactionFactory::class); + $factory->setUser($this->user()); + $collection = $factory->createPair($deposit, $data); + + $newCount = $deposit->transactions()->count(); + + $this->assertCount(2, $collection); + $this->assertEquals($count + 2, $newCount); + // find stuff in transaction #1 (should suffice): + /** @var Transaction $first */ + $first = $collection->first(); + $this->assertEquals($deposit->id, $first->transaction_journal_id); + $this->assertEquals(-10, $first->amount); + $this->assertEquals(false, $first->reconciled); + $this->assertEquals(0, $first->identifier); + $this->assertEquals($euro->id, $first->transaction_currency_id); + $this->assertNull($first->foreign_amount); + $this->assertNull($first->foreign_currency_id); + } + + /** + * Create deposit using minimal data. + * + * @covers \FireflyIII\Factory\TransactionFactory + * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait + */ + public function testCreatePairDepositCash() + { + // objects: + $asset = $this->user()->accounts()->where('account_type_id', 3)->first(); + $revenue = $this->user()->accounts()->where('account_type_id', 5)->first(); + $euro = TransactionCurrency::first(); + $foreign = TransactionCurrency::where('id', '!=', $euro->id)->first(); + + // mocked classes + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + + $data = [ + 'currency_id' => 1, + 'currency_code' => null, + 'description' => null, + 'source_id' => null, + 'source_name' => '', + 'destination_id' => $asset->id, + 'destination_name' => null, + 'amount' => '10', + 'reconciled' => false, + 'identifier' => 0, + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'budget_id' => null, + 'budget_name' => null, + 'category_id' => null, + 'category_name' => null, + ]; + + // mock: + $accountRepos->shouldReceive('setUser'); + $budgetFactory->shouldReceive('setUser'); + $categoryFactory->shouldReceive('setUser'); + $accountFactory->shouldReceive('setUser'); + // first search action is for the asset account + $accountRepos->shouldReceive('findNull')->andReturn($asset); + + // second is for revenue account. + $accountRepos->shouldReceive('getCashAccount')->andReturn($revenue)->once(); + + // factories return various stuff: + $budgetFactory->shouldReceive('find')->andReturn(null); + $categoryFactory->shouldReceive('findOrCreate')->andReturn(null); + $currencyFactory->shouldReceive('find')->andReturn($euro, null); + + /** @var TransactionJournal $deposit */ + $deposit = $this->user()->transactionJournals()->where('transaction_type_id', 2)->first(); + $count = $deposit->transactions()->count(); + + /** @var TransactionFactory $factory */ + $factory = app(TransactionFactory::class); + $factory->setUser($this->user()); + $collection = $factory->createPair($deposit, $data); + + $newCount = $deposit->transactions()->count(); + + $this->assertCount(2, $collection); + $this->assertEquals($count + 2, $newCount); + // find stuff in transaction #1 (should suffice): + /** @var Transaction $first */ + $first = $collection->first(); + $this->assertEquals($deposit->id, $first->transaction_journal_id); + $this->assertEquals(-10, $first->amount); + $this->assertEquals(false, $first->reconciled); + $this->assertEquals(0, $first->identifier); + $this->assertEquals($euro->id, $first->transaction_currency_id); + $this->assertNull($first->foreign_amount); + $this->assertNull($first->foreign_currency_id); + } + + /** + * @covers \FireflyIII\Factory\TransactionFactory + * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait + */ + public function testCreatePairForeign() + { + // objects: + $asset = $this->user()->accounts()->where('account_type_id', 3)->first(); + $expense = $this->user()->accounts()->where('account_type_id', 4)->first(); + $euro = TransactionCurrency::first(); + $foreign = TransactionCurrency::where('id', '!=', $euro->id)->first(); + + // mocked classes + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + + $data = [ + 'currency_id' => $euro->id, + 'currency_code' => null, + 'description' => null, + 'source_id' => $asset->id, + 'source_name' => null, + 'destination_id' => $expense->id, + 'destination_name' => null, + 'amount' => '10', + 'reconciled' => false, + 'identifier' => 0, + 'foreign_currency_id' => $foreign->id, + 'foreign_currency_code' => null, + 'foreign_amount' => '10', + 'budget_id' => null, + 'budget_name' => null, + 'category_id' => null, + 'category_name' => null, + ]; + + // mock: + $accountRepos->shouldReceive('setUser'); + $budgetFactory->shouldReceive('setUser'); + $categoryFactory->shouldReceive('setUser'); + // first search action is for the asset account, second is for expense account. + $accountRepos->shouldReceive('findNull')->andReturn($asset, $expense); + + // factories return various stuff: + $budgetFactory->shouldReceive('find')->andReturn(null); + $categoryFactory->shouldReceive('findOrCreate')->andReturn(null); + $currencyFactory->shouldReceive('find')->andReturn($euro, $foreign); + + /** @var TransactionJournal $withdrawal */ + $withdrawal = $this->user()->transactionJournals()->where('transaction_type_id', 1)->first(); + $count = $withdrawal->transactions()->count(); + + /** @var TransactionFactory $factory */ + $factory = app(TransactionFactory::class); + $factory->setUser($this->user()); + $collection = $factory->createPair($withdrawal, $data); + + $newCount = $withdrawal->transactions()->count(); + + $this->assertCount(2, $collection); + $this->assertEquals($count + 2, $newCount); + // find stuff in transaction #1 (should suffice): + /** @var Transaction $first */ + $first = $collection->first(); + $this->assertEquals($withdrawal->id, $first->transaction_journal_id); + $this->assertEquals(-10, $first->amount); + $this->assertEquals(-10, $first->foreign_amount); + $this->assertEquals(false, $first->reconciled); + $this->assertEquals(0, $first->identifier); + $this->assertEquals($euro->id, $first->transaction_currency_id); + $this->assertEquals($foreign->id, $first->foreign_currency_id); + } + + /** + * Create transfer using minimal data. + * + * @covers \FireflyIII\Factory\TransactionFactory + * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait + */ + public function testCreatePairReconciliation() + { + // objects: + $asset = $this->user()->accounts()->where('account_type_id', 3)->first(); + $opposing = $this->user()->accounts()->where('id', '!=', $asset->id)->where('account_type_id', 3)->first(); + $euro = TransactionCurrency::first(); + $foreign = TransactionCurrency::where('id', '!=', $euro->id)->first(); + + // mocked classes + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + + $data = [ + 'currency_id' => 1, + 'currency_code' => null, + 'description' => null, + 'source_id' => $asset->id, + 'source_name' => null, + 'destination_id' => $opposing->id, + 'destination_name' => null, + 'amount' => '10', + 'reconciled' => false, + 'identifier' => 0, + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'budget_id' => null, + 'budget_name' => null, + 'category_id' => null, + 'category_name' => null, + ]; + + // mock: + $accountRepos->shouldReceive('setUser'); + $budgetFactory->shouldReceive('setUser'); + $categoryFactory->shouldReceive('setUser'); + // first search action is for the asset account, second is for expense account. + $accountRepos->shouldReceive('findNull')->andReturn($asset, $opposing); + + // factories return various stuff: + $budgetFactory->shouldReceive('find')->andReturn(null); + $categoryFactory->shouldReceive('findOrCreate')->andReturn(null); + $currencyFactory->shouldReceive('find')->andReturn($euro, null); + + /** @var TransactionJournal $recon */ + $recon = $this->user()->transactionJournals()->where('transaction_type_id', 5)->first(); + $count = $recon->transactions()->count(); + + /** @var TransactionFactory $factory */ + $factory = app(TransactionFactory::class); + $factory->setUser($this->user()); + $collection = $factory->createPair($recon, $data); + + $newCount = $recon->transactions()->count(); + + $this->assertCount(2, $collection); + $this->assertEquals($count + 2, $newCount); + // find stuff in transaction #1 (should suffice): + /** @var Transaction $first */ + $first = $collection->first(); + $this->assertEquals($recon->id, $first->transaction_journal_id); + $this->assertEquals(-10, $first->amount); + $this->assertEquals(false, $first->reconciled); + $this->assertEquals(0, $first->identifier); + $this->assertEquals($euro->id, $first->transaction_currency_id); + $this->assertNull($first->foreign_amount); + $this->assertNull($first->foreign_currency_id); + } + + /** + * Create reconciliation using minimal (bad) data. + * + * @covers \FireflyIII\Factory\TransactionFactory + * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait + */ + public function testCreatePairTransfer() + { + // objects: + $asset = $this->user()->accounts()->where('account_type_id', 3)->first(); + $opposing = $this->user()->accounts()->where('id', '!=', $asset->id)->where('account_type_id', 3)->first(); + $euro = TransactionCurrency::first(); + $foreign = TransactionCurrency::where('id', '!=', $euro->id)->first(); + + // mocked classes + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + + $data = [ + 'currency_id' => 1, + 'currency_code' => null, + 'description' => null, + 'source_id' => $asset->id, + 'source_name' => null, + 'destination_id' => $opposing->id, + 'destination_name' => null, + 'amount' => '10', + 'reconciled' => false, + 'identifier' => 0, + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'budget_id' => null, + 'budget_name' => null, + 'category_id' => null, + 'category_name' => null, + ]; + + // mock: + $accountRepos->shouldReceive('setUser'); + $budgetFactory->shouldReceive('setUser'); + $categoryFactory->shouldReceive('setUser'); + // first search action is for the asset account, second is for expense account. + $accountRepos->shouldReceive('findNull')->andReturn($asset, $opposing); + + // factories return various stuff: + $budgetFactory->shouldReceive('find')->andReturn(null); + $categoryFactory->shouldReceive('findOrCreate')->andReturn(null); + $currencyFactory->shouldReceive('find')->andReturn($euro, null); + + /** @var TransactionJournal $transfer */ + $transfer = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); + $count = $transfer->transactions()->count(); + + /** @var TransactionFactory $factory */ + $factory = app(TransactionFactory::class); + $factory->setUser($this->user()); + $collection = $factory->createPair($transfer, $data); + + $newCount = $transfer->transactions()->count(); + + $this->assertCount(2, $collection); + $this->assertEquals($count + 2, $newCount); + // find stuff in transaction #1 (should suffice): + /** @var Transaction $first */ + $first = $collection->first(); + $this->assertEquals($transfer->id, $first->transaction_journal_id); + $this->assertEquals(-10, $first->amount); + $this->assertEquals(false, $first->reconciled); + $this->assertEquals(0, $first->identifier); + $this->assertEquals($euro->id, $first->transaction_currency_id); + $this->assertNull($first->foreign_amount); + $this->assertNull($first->foreign_currency_id); + } + +} \ No newline at end of file diff --git a/tests/Unit/Factory/TransactionJournalFactoryTest.php b/tests/Unit/Factory/TransactionJournalFactoryTest.php new file mode 100644 index 0000000000..ba9358d108 --- /dev/null +++ b/tests/Unit/Factory/TransactionJournalFactoryTest.php @@ -0,0 +1,177 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + + +use Carbon\Carbon; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Factory\BillFactory; +use FireflyIII\Factory\PiggyBankEventFactory; +use FireflyIII\Factory\PiggyBankFactory; +use FireflyIII\Factory\TagFactory; +use FireflyIII\Factory\TransactionFactory; +use FireflyIII\Factory\TransactionJournalFactory; +use FireflyIII\Factory\TransactionJournalMetaFactory; +use FireflyIII\Factory\TransactionTypeFactory; +use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Models\TransactionType; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use Tests\TestCase; + +/** + * Class TransactionJournalFactoryTest + */ +class TransactionJournalFactoryTest extends TestCase +{ + + /** + * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait + */ + public function testCreateBasic() + { + // mock used classes: + $type = TransactionType::find(1); + $euro = TransactionCurrency::find(1); + $billFactory = $this->mock(BillFactory::class); + $tagFactory = $this->mock(TagFactory::class); + $metaFactory = $this->mock(TransactionJournalMetaFactory::class); + $typeFactory = $this->mock(TransactionTypeFactory::class); + $transactionFactory = $this->mock(TransactionFactory::class); + $piggyFactory = $this->mock(PiggyBankFactory::class); + $eventFactory = $this->mock(PiggyBankEventFactory::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + + // mock stuff: + $typeFactory->shouldReceive('find')->andReturn($type); + $currencyRepos->shouldReceive('find')->andReturn($euro); + + // mock factories: + $transactionFactory->shouldReceive('setUser')->once(); + $billFactory->shouldReceive('setUser')->once(); + $piggyFactory->shouldReceive('setUser')->once(); + $tagFactory->shouldReceive('setUser')->once(); + + $transactionFactory->shouldReceive('createPair')->once(); + $billFactory->shouldReceive('find')->andReturn(null); + $piggyFactory->shouldReceive('find')->andReturn(null); + $data = [ + 'type' => 'withdrawal', + 'user' => $this->user()->id, + 'description' => 'I are journal', + 'date' => new Carbon('2018-01-01'), + 'bill_id' => null, + 'bill_name' => null, + 'piggy_bank_id' => null, + 'piggy_bank_name' => null, + 'notes' => 'Hello', + 'tags' => [], + 'transactions' => [[]], + ]; + + /** @var TransactionJournalFactory $factory */ + $factory = app(TransactionJournalFactory::class); + $factory->setUser($this->user()); + try { + $journal = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + $this->assertEquals($data['description'], $journal->description); + $this->assertEquals('2018-01-01', $journal->date->format('Y-m-d')); + $this->assertEquals(1, $journal->notes()->count()); + + } + + + /** + * Same but with added meta data + * + * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait + */ + public function testCreateBasicMeta() + { + // mock used classes: + $type = TransactionType::find(1); + $euro = TransactionCurrency::find(1); + $piggy = $this->user()->piggyBanks()->first(); + $bill = $this->user()->bills()->first(); + $tag = $this->user()->tags()->first(); + $billFactory = $this->mock(BillFactory::class); + $tagFactory = $this->mock(TagFactory::class); + $metaFactory = $this->mock(TransactionJournalMetaFactory::class); + $typeFactory = $this->mock(TransactionTypeFactory::class); + $transactionFactory = $this->mock(TransactionFactory::class); + $piggyFactory = $this->mock(PiggyBankFactory::class); + $eventFactory = $this->mock(PiggyBankEventFactory::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + + // mock stuff: + $typeFactory->shouldReceive('find')->andReturn($type); + $currencyRepos->shouldReceive('find')->andReturn($euro); + + // mock factories: + $transactionFactory->shouldReceive('setUser')->once(); + $billFactory->shouldReceive('setUser')->once(); + $piggyFactory->shouldReceive('setUser')->once(); + $tagFactory->shouldReceive('setUser')->once(); + + $transactionFactory->shouldReceive('createPair')->once(); + $billFactory->shouldReceive('find')->andReturn($bill); + $piggyFactory->shouldReceive('find')->andReturn($piggy); + $eventFactory->shouldReceive('create')->once(); + $tagFactory->shouldReceive('findOrCreate')->andReturn($tag); + $metaFactory->shouldReceive('updateOrCreate'); + + $data = [ + 'type' => 'withdrawal', + 'user' => $this->user()->id, + 'description' => 'I are journal', + 'date' => new Carbon('2018-01-01'), + 'bill_id' => $bill->id, + 'bill_name' => null, + 'piggy_bank_id' => $piggy->id, + 'piggy_bank_name' => null, + 'notes' => '', + 'tags' => ['a', 'b', 'c'], + 'transactions' => [[]], + 'interest_date' => '2018-01-01', + ]; + + /** @var TransactionJournalFactory $factory */ + $factory = app(TransactionJournalFactory::class); + $factory->setUser($this->user()); + try { + $journal = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + $this->assertEquals($data['description'], $journal->description); + $this->assertEquals('2018-01-01', $journal->date->format('Y-m-d')); + $this->assertEquals(0, $journal->notes()->count()); + + } + +} \ No newline at end of file diff --git a/tests/Unit/Factory/TransactionJournalMetaFactoryTest.php b/tests/Unit/Factory/TransactionJournalMetaFactoryTest.php new file mode 100644 index 0000000000..62f53215c3 --- /dev/null +++ b/tests/Unit/Factory/TransactionJournalMetaFactoryTest.php @@ -0,0 +1,105 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Factory; + +use Carbon\Carbon; +use FireflyIII\Factory\TransactionJournalMetaFactory; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Models\TransactionJournalMeta; +use Tests\TestCase; + +/** + * Class TransactionJournalMetaFactoryTest + */ +class TransactionJournalMetaFactoryTest extends TestCase +{ + /** + * @covers \FireflyIII\Factory\TransactionJournalMetaFactory + */ + public function testUpdateOrCreateBasic() + { + /** @var TransactionJournal $journal */ + $journal = $this->user()->transactionJournals()->where('transaction_type_id', 1)->first(); + $set = [ + 'journal' => $journal, + 'name' => 'hello', + 'data' => 'bye!', + ]; + /** @var TransactionJournalMetaFactory $factory */ + $factory = app(TransactionJournalMetaFactory::class); + $result = $factory->updateOrCreate($set); + + $this->assertEquals(1, $journal->transactionJournalMeta()->count()); + $this->assertEquals($set['data'], $result->data); + } + + /** + * @covers \FireflyIII\Factory\TransactionJournalMetaFactory + */ + public function testUpdateOrCreateDate() + { + /** @var TransactionJournal $journal */ + $journal = $this->user()->transactionJournals()->where('transaction_type_id', 2)->first(); + $set = [ + 'journal' => $journal, + 'name' => 'hello', + 'data' => new Carbon('2012-01-01'), + ]; + /** @var TransactionJournalMetaFactory $factory */ + $factory = app(TransactionJournalMetaFactory::class); + $result = $factory->updateOrCreate($set); + + $this->assertEquals(1, $journal->transactionJournalMeta()->count()); + $this->assertEquals($set['data']->toW3cString(), $result->data); + } + + /** + * @covers \FireflyIII\Factory\TransactionJournalMetaFactory + */ + public function testUpdateOrCreateDeleteExisting() + { + /** @var TransactionJournal $journal */ + $journal = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); + $meta = TransactionJournalMeta::create( + [ + 'transaction_journal_id' => $journal->id, + 'name' => 'hello', + 'data' => 'bye!', + ] + ); + + $set = [ + 'journal' => $journal, + 'name' => 'hello', + 'data' => null, + ]; + /** @var TransactionJournalMetaFactory $factory */ + $factory = app(TransactionJournalMetaFactory::class); + $factory->updateOrCreate($set); + + $this->assertEquals(0, $journal->transactionJournalMeta()->count()); + } + + +} \ No newline at end of file