From 72c0d7a8749d93011e9eef7ad7c7964c96c666c9 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 16 Jun 2019 13:16:46 +0200 Subject: [PATCH] Improve test coverage and quality --- .../V1/Controllers/AccountControllerTest.php | 12 +- .../Controllers/AttachmentControllerTest.php | 4 +- .../Api/V1/Controllers/BillControllerTest.php | 12 +- .../V1/Controllers/LinkTypeControllerTest.php | 48 +- .../Controllers/PiggyBankControllerTest.php | 6 +- .../Controllers/RuleGroupControllerTest.php | 4 +- .../Api/V1/Controllers/TagControllerTest.php | 4 +- .../Api/V1/Controllers/UserControllerTest.php | 12 +- .../Account/CreateControllerTest.php | 6 +- .../Account/EditControllerTest.php | 4 +- .../Controllers/AttachmentControllerTest.php | 2 +- .../Controllers/BillControllerTest.php | 10 +- .../Budget/CreateControllerTest.php | 2 +- .../Controllers/Budget/EditControllerTest.php | 2 +- .../Controllers/CategoryControllerTest.php | 4 +- tests/TestCase.php | 15 + .../Commands/Import/CreateCSVImportTest.php | 4 +- .../Commands/Upgrade/MigrateToRulesTest.php | 12 +- tests/Unit/Factory/AccountFactoryTest.php | 878 +++--- tests/Unit/Factory/AccountMetaFactoryTest.php | 30 +- tests/Unit/Factory/AttachmentFactoryTest.php | 76 +- tests/Unit/Factory/BillFactoryTest.php | 37 +- tests/Unit/Factory/BudgetFactoryTest.php | 2 +- tests/Unit/Factory/CategoryFactoryTest.php | 2 +- .../Factory/PiggyBankEventFactoryTest.php | 39 +- tests/Unit/Factory/RecurrenceFactoryTest.php | 753 +++-- tests/Unit/Factory/TagFactoryTest.php | 2 +- tests/Unit/Factory/TransactionFactoryTest.php | 768 +---- .../Factory/TransactionJournalFactoryTest.php | 2474 +++++++++++------ .../TransactionJournalMetaFactoryTest.php | 69 +- .../BunqJobConfigurationTest.php | 4 +- .../YnabJobConfigurationTest.php | 4 +- .../Update/TransactionUpdateServiceTest.php | 432 +-- .../Spectre/StageImportDataHandlerTest.php | 2 +- 34 files changed, 3211 insertions(+), 2524 deletions(-) diff --git a/tests/Api/V1/Controllers/AccountControllerTest.php b/tests/Api/V1/Controllers/AccountControllerTest.php index 638759e365..1857e7596b 100644 --- a/tests/Api/V1/Controllers/AccountControllerTest.php +++ b/tests/Api/V1/Controllers/AccountControllerTest.php @@ -67,7 +67,7 @@ class AccountControllerTest extends TestCase // data to submit $data = [ - 'name' => 'Some new asset account #' . random_int(1, 10000), + 'name' => 'Some new asset account #' . $this->randomInt(), 'type' => 'asset', 'account_role' => 'defaultAsset', 'opening_balance' => '123.45', @@ -146,7 +146,7 @@ class AccountControllerTest extends TestCase // data to submit $data = [ - 'name' => 'Some new liability account #' . random_int(1, 10000), + 'name' => 'Some new liability account #' . $this->randomInt(), 'type' => 'liability', 'liability_amount' => '10000', 'liability_start_date' => '2016-01-01', @@ -185,7 +185,7 @@ class AccountControllerTest extends TestCase // data to submit $data = [ - 'name' => 'Some new asset account #' . random_int(1, 10000), + 'name' => 'Some new asset account #' . $this->randomInt(), 'type' => 'asset', 'account_role' => 'ccAsset', ]; @@ -233,7 +233,7 @@ class AccountControllerTest extends TestCase // data to submit $data = [ - 'name' => 'Some new asset account #' . random_int(1, 10000), + 'name' => 'Some new asset account #' . $this->randomInt(), 'type' => 'asset', 'account_role' => 'defaultAsset', 'include_net_worth' => false, @@ -314,7 +314,7 @@ class AccountControllerTest extends TestCase // data to submit $data = [ - 'name' => 'Some new asset account #' . random_int(1, 10000), + 'name' => 'Some new asset account #' . $this->randomInt(), 'type' => 'asset', 'account_role' => 'defaultAsset', ]; @@ -355,7 +355,7 @@ class AccountControllerTest extends TestCase // data to submit $data = [ - 'name' => 'Some new asset account #' . random_int(1, 10000), + 'name' => 'Some new asset account #' . $this->randomInt(), 'currency_code' => 'EUR', 'type' => 'asset', 'account_role' => 'defaultAsset', diff --git a/tests/Api/V1/Controllers/AttachmentControllerTest.php b/tests/Api/V1/Controllers/AttachmentControllerTest.php index 5b5705808b..8b5014f928 100644 --- a/tests/Api/V1/Controllers/AttachmentControllerTest.php +++ b/tests/Api/V1/Controllers/AttachmentControllerTest.php @@ -115,7 +115,7 @@ class AttachmentControllerTest extends TestCase // data to submit $data = [ 'filename' => 'Some new att', - 'description' => sprintf('Attempt #%d', random_int(1, 10000)), + 'description' => sprintf('Attempt #%d', $this->randomInt()), 'model' => 'TransactionJournal', 'model_id' => $journal->id, ]; @@ -159,7 +159,7 @@ class AttachmentControllerTest extends TestCase // data to submit $data = [ 'filename' => $attachment->filename, - 'description' => sprintf('Attempt #%d', random_int(1, 10000)), + 'description' => sprintf('Attempt #%d', $this->randomInt()), 'model' => 'TransactionJournal', 'model_id' => 1, ]; diff --git a/tests/Api/V1/Controllers/BillControllerTest.php b/tests/Api/V1/Controllers/BillControllerTest.php index 088064cf0c..edcb574caf 100644 --- a/tests/Api/V1/Controllers/BillControllerTest.php +++ b/tests/Api/V1/Controllers/BillControllerTest.php @@ -68,8 +68,8 @@ class BillControllerTest extends TestCase // data to submit: $data = [ - 'name' => 'New bill #' . random_int(1, 10000), - 'match' => 'some,words,' . random_int(1, 10000), + 'name' => 'New bill #' . $this->randomInt(), + 'match' => 'some,words,' . $this->randomInt(), 'amount_min' => '66.34', 'amount_max' => '45.67', 'date' => '2018-01-01', @@ -121,8 +121,8 @@ class BillControllerTest extends TestCase // data to submit: $data = [ - 'name' => 'New bill #' . random_int(1, 10000), - 'match' => 'some,words,' . random_int(1, 10000), + 'name' => 'New bill #' . $this->randomInt(), + 'match' => 'some,words,' . $this->randomInt(), 'amount_min' => '12.34', 'amount_max' => '45.67', 'date' => '2018-01-01', @@ -160,8 +160,8 @@ class BillControllerTest extends TestCase $repository->shouldReceive('update')->andReturn($bill); // data to submit: $data = [ - 'name' => 'New bill #' . random_int(1, 10000), - 'match' => 'some,words,' . random_int(1, 10000), + 'name' => 'New bill #' . $this->randomInt(), + 'match' => 'some,words,' . $this->randomInt(), 'amount_min' => '12.34', 'amount_max' => '45.67', 'date' => '2018-01-01', diff --git a/tests/Api/V1/Controllers/LinkTypeControllerTest.php b/tests/Api/V1/Controllers/LinkTypeControllerTest.php index f3cbec6e10..53816a9645 100644 --- a/tests/Api/V1/Controllers/LinkTypeControllerTest.php +++ b/tests/Api/V1/Controllers/LinkTypeControllerTest.php @@ -80,9 +80,9 @@ class LinkTypeControllerTest extends TestCase // data to submit $data = [ - 'name' => 'random' . random_int(1, 100000), - 'outward' => 'outward' . random_int(1, 100000), - 'inward' => 'inward ' . random_int(1, 100000), + 'name' => 'random' . $this->randomInt(), + 'outward' => 'outward' . $this->randomInt(), + 'inward' => 'inward ' . $this->randomInt(), 'editable' => true, ]; @@ -110,9 +110,9 @@ class LinkTypeControllerTest extends TestCase // data to submit $data = [ - 'name' => 'random' . random_int(1, 100000), - 'outward' => 'outward' . random_int(1, 100000), - 'inward' => 'inward ' . random_int(1, 100000), + 'name' => 'random' . $this->randomInt(), + 'outward' => 'outward' . $this->randomInt(), + 'inward' => 'inward ' . $this->randomInt(), 'editable' => true, ]; @@ -146,9 +146,9 @@ class LinkTypeControllerTest extends TestCase // create editable link type: $linkType = LinkType::create( [ - 'name' => 'random' . random_int(1, 100000), - 'outward' => 'outward' . random_int(1, 100000), - 'inward' => 'inward ' . random_int(1, 100000), + 'name' => 'random' . $this->randomInt(), + 'outward' => 'outward' . $this->randomInt(), + 'inward' => 'inward ' . $this->randomInt(), 'editable' => true, ] @@ -160,9 +160,9 @@ class LinkTypeControllerTest extends TestCase // data to submit $data = [ - 'name' => 'random' . random_int(1, 100000), - 'outward' => 'outward' . random_int(1, 100000), - 'inward' => 'inward ' . random_int(1, 100000), + 'name' => 'random' . $this->randomInt(), + 'outward' => 'outward' . $this->randomInt(), + 'inward' => 'inward ' . $this->randomInt(), 'editable' => true, ]; @@ -186,9 +186,9 @@ class LinkTypeControllerTest extends TestCase // create editable link type: $linkType = LinkType::create( [ - 'name' => 'random' . random_int(1, 100000), - 'outward' => 'outward' . random_int(1, 100000), - 'inward' => 'inward ' . random_int(1, 100000), + 'name' => 'random' . $this->randomInt(), + 'outward' => 'outward' . $this->randomInt(), + 'inward' => 'inward ' . $this->randomInt(), 'editable' => false, ] @@ -199,9 +199,9 @@ class LinkTypeControllerTest extends TestCase // data to submit $data = [ - 'name' => 'random' . random_int(1, 100000), - 'outward' => 'outward' . random_int(1, 100000), - 'inward' => 'inward ' . random_int(1, 100000), + 'name' => 'random' . $this->randomInt(), + 'outward' => 'outward' . $this->randomInt(), + 'inward' => 'inward ' . $this->randomInt(), 'editable' => true, ]; @@ -227,9 +227,9 @@ class LinkTypeControllerTest extends TestCase // create editable link type: $linkType = LinkType::create( [ - 'name' => 'random' . random_int(1, 100000), - 'outward' => 'outward' . random_int(1, 100000), - 'inward' => 'inward ' . random_int(1, 100000), + 'name' => 'random' . $this->randomInt(), + 'outward' => 'outward' . $this->randomInt(), + 'inward' => 'inward ' . $this->randomInt(), 'editable' => true, ] @@ -240,9 +240,9 @@ class LinkTypeControllerTest extends TestCase // data to submit $data = [ - 'name' => 'random' . random_int(1, 100000), - 'outward' => 'outward' . random_int(1, 100000), - 'inward' => 'inward ' . random_int(1, 100000), + 'name' => 'random' . $this->randomInt(), + 'outward' => 'outward' . $this->randomInt(), + 'inward' => 'inward ' . $this->randomInt(), 'editable' => true, ]; diff --git a/tests/Api/V1/Controllers/PiggyBankControllerTest.php b/tests/Api/V1/Controllers/PiggyBankControllerTest.php index 8d76ad3286..555c8ffe3a 100644 --- a/tests/Api/V1/Controllers/PiggyBankControllerTest.php +++ b/tests/Api/V1/Controllers/PiggyBankControllerTest.php @@ -78,7 +78,7 @@ class PiggyBankControllerTest extends TestCase $repository->shouldReceive('store')->once()->andReturn($piggy); $data = [ - 'name' => 'New piggy #' . random_int(1, 100000), + 'name' => 'New piggy #' . $this->randomInt(), 'account_id' => 1, 'target_amount' => '100', ]; @@ -106,7 +106,7 @@ class PiggyBankControllerTest extends TestCase $data = [ - 'name' => 'New piggy #' . random_int(1, 100000), + 'name' => 'New piggy #' . $this->randomInt(), 'account_id' => 1, 'target_amount' => '100', ]; @@ -157,7 +157,7 @@ class PiggyBankControllerTest extends TestCase $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::first()); $data = [ - 'name' => 'new pigy bank ' . random_int(1, 10000), + 'name' => 'new pigy bank ' . $this->randomInt(), 'account_id' => 1, 'target_amount' => '100', ]; diff --git a/tests/Api/V1/Controllers/RuleGroupControllerTest.php b/tests/Api/V1/Controllers/RuleGroupControllerTest.php index cbb0512781..03e34fcb51 100644 --- a/tests/Api/V1/Controllers/RuleGroupControllerTest.php +++ b/tests/Api/V1/Controllers/RuleGroupControllerTest.php @@ -80,7 +80,7 @@ class RuleGroupControllerTest extends TestCase $ruleGroupRepos->shouldReceive('setUser')->once(); $ruleGroup = $this->user()->ruleGroups()->first(); $data = [ - 'title' => 'Store new rule group ' . random_int(1, 100000), + 'title' => 'Store new rule group ' . $this->randomInt(), 'active' => 1, 'description' => 'Hello', ]; @@ -214,7 +214,7 @@ class RuleGroupControllerTest extends TestCase $ruleGroupRepos->shouldReceive('setUser')->once(); $ruleGroup = $this->user()->ruleGroups()->first(); $data = [ - 'title' => 'Store new rule ' . random_int(1, 100000), + 'title' => 'Store new rule ' . $this->randomInt(), 'active' => 1, 'description' => 'Hello', ]; diff --git a/tests/Api/V1/Controllers/TagControllerTest.php b/tests/Api/V1/Controllers/TagControllerTest.php index 94ce599b60..1a7513c1c6 100644 --- a/tests/Api/V1/Controllers/TagControllerTest.php +++ b/tests/Api/V1/Controllers/TagControllerTest.php @@ -57,7 +57,7 @@ class TagControllerTest extends TestCase { $tagRepos = $this->mock(TagRepositoryInterface::class); $tag = $this->user()->tags()->inRandomOrder()->first(); - $data = ['tag' => 'Some tag' . random_int(1, 10000),]; + $data = ['tag' => 'Some tag' . $this->randomInt(),]; $transformer = $this->mock(TagTransformer::class); // mock transformer @@ -126,7 +126,7 @@ class TagControllerTest extends TestCase { $tagRepos = $this->mock(TagRepositoryInterface::class); $tag = $this->user()->tags()->inRandomOrder()->first(); - $data = ['tag' => 'Some tag' . random_int(1, 10000),]; + $data = ['tag' => 'Some tag' . $this->randomInt(),]; $transformer = $this->mock(TagTransformer::class); // mock transformer diff --git a/tests/Api/V1/Controllers/UserControllerTest.php b/tests/Api/V1/Controllers/UserControllerTest.php index d55eef6413..f56f7bff84 100644 --- a/tests/Api/V1/Controllers/UserControllerTest.php +++ b/tests/Api/V1/Controllers/UserControllerTest.php @@ -61,7 +61,7 @@ class UserControllerTest extends TestCase public function testStoreBasic(): void { $data = [ - 'email' => 'some_new@user' . random_int(1, 10000) . '.com', + 'email' => 'some_new@user' . $this->randomInt() . '.com', ]; // mock @@ -91,7 +91,7 @@ class UserControllerTest extends TestCase public function testStoreBasicJson(): void { $data = [ - 'email' => 'some_new@user' . random_int(1, 10000) . '.com', + 'email' => 'some_new@user' . $this->randomInt() . '.com', 'blocked' => true, 'blocked_code' => 'email_changed', ]; @@ -185,11 +185,11 @@ class UserControllerTest extends TestCase public function testUpdate(): void { // create a user first: - $user = User::create(['email' => 'some@newu' . random_int(1, 10000) . 'ser.nl', 'password' => 'hello', 'blocked' => 0]); + $user = User::create(['email' => 'some@newu' . $this->randomInt() . 'ser.nl', 'password' => 'hello', 'blocked' => 0]); // data: $data = [ - 'email' => 'some-new@email' . random_int(1, 10000) . '.com', + 'email' => 'some-new@email' . $this->randomInt() . '.com', 'blocked' => 0, ]; @@ -220,11 +220,11 @@ class UserControllerTest extends TestCase public function testUpdateJson(): void { // create a user first: - $user = User::create(['email' => 'some@newu' . random_int(1, 10000) . 'ser.nl', 'password' => 'hello', 'blocked' => 0]); + $user = User::create(['email' => 'some@newu' . $this->randomInt() . 'ser.nl', 'password' => 'hello', 'blocked' => 0]); // data: $data = [ - 'email' => 'some-new@email' . random_int(1, 10000) . '.com', + 'email' => 'some-new@email' . $this->randomInt() . '.com', 'blocked' => 0, ]; diff --git a/tests/Feature/Controllers/Account/CreateControllerTest.php b/tests/Feature/Controllers/Account/CreateControllerTest.php index 11b93c0d6c..c2f4ccbebc 100644 --- a/tests/Feature/Controllers/Account/CreateControllerTest.php +++ b/tests/Feature/Controllers/Account/CreateControllerTest.php @@ -101,7 +101,7 @@ class CreateControllerTest extends TestCase $this->session(['accounts.create.uri' => 'http://localhost']); $this->be($this->user()); $data = [ - 'name' => 'new account ' . random_int(1000, 9999), + 'name' => 'new account ' . $this->randomInt(), 'what' => 'asset', ]; @@ -127,7 +127,7 @@ class CreateControllerTest extends TestCase $this->session(['accounts.create.uri' => 'http://localhost']); $this->be($this->user()); $data = [ - 'name' => 'new account ' . random_int(1000, 9999), + 'name' => 'new account ' . $this->randomInt(), 'what' => 'asset', 'create_another' => 1, ]; @@ -157,7 +157,7 @@ class CreateControllerTest extends TestCase $this->session(['accounts.create.uri' => 'http://localhost']); $this->be($this->user()); $data = [ - 'name' => 'new liability account ' . random_int(1000, 9999), + 'name' => 'new liability account ' . $this->randomInt(), 'what' => 'liabilities', 'liability_type_id' => AccountType::where('type', AccountType::LOAN)->first()->id, 'openingBalance' => '100', diff --git a/tests/Feature/Controllers/Account/EditControllerTest.php b/tests/Feature/Controllers/Account/EditControllerTest.php index d3be9ca3c1..9282b583ec 100644 --- a/tests/Feature/Controllers/Account/EditControllerTest.php +++ b/tests/Feature/Controllers/Account/EditControllerTest.php @@ -205,7 +205,7 @@ class EditControllerTest extends TestCase $this->session(['accounts.edit.uri' => 'http://localhost/javascript/account']); $this->be($this->user()); $data = [ - 'name' => 'updated account ' . random_int(1000, 9999), + 'name' => 'updated account ' . $this->randomInt(), 'active' => 1, 'what' => 'asset', ]; @@ -232,7 +232,7 @@ class EditControllerTest extends TestCase $this->session(['accounts.edit.uri' => 'http://localhost']); $this->be($this->user()); $data = [ - 'name' => 'updated account ' . random_int(1000, 9999), + 'name' => 'updated account ' . $this->randomInt(), 'active' => 1, 'what' => 'asset', 'return_to_edit' => '1', diff --git a/tests/Feature/Controllers/AttachmentControllerTest.php b/tests/Feature/Controllers/AttachmentControllerTest.php index 1e4a2262f3..f1c86197d1 100644 --- a/tests/Feature/Controllers/AttachmentControllerTest.php +++ b/tests/Feature/Controllers/AttachmentControllerTest.php @@ -190,7 +190,7 @@ class AttachmentControllerTest extends TestCase $this->session(['attachments.edit.uri' => 'http://localhost']); $data = [ - 'title' => 'Some updated title ' . random_int(1000, 9999), + 'title' => 'Some updated title ' . $this->randomInt(), 'notes' => 'A', 'description' => 'B', ]; diff --git a/tests/Feature/Controllers/BillControllerTest.php b/tests/Feature/Controllers/BillControllerTest.php index f7348ab012..4209f30fb9 100644 --- a/tests/Feature/Controllers/BillControllerTest.php +++ b/tests/Feature/Controllers/BillControllerTest.php @@ -326,7 +326,7 @@ class BillControllerTest extends TestCase $attachHelper->shouldReceive('getMessages')->andReturn(new MessageBag); $data = [ - 'name' => 'New Bill ' . random_int(1000, 9999), + 'name' => 'New Bill ' . $this->randomInt(), 'amount_min' => '100', 'transaction_currency_id' => 1, 'skip' => 0, @@ -364,7 +364,7 @@ class BillControllerTest extends TestCase $attachHelper->shouldReceive('getMessages')->andReturn(new MessageBag); $data = [ - 'name' => 'New Bill ' . random_int(1000, 9999), + 'name' => 'New Bill ' . $this->randomInt(), 'amount_min' => '100', 'transaction_currency_id' => 1, 'skip' => 0, @@ -400,7 +400,7 @@ class BillControllerTest extends TestCase $repository->shouldReceive('store')->andReturn(null); $data = [ - 'name' => 'New Bill ' . random_int(1000, 9999), + 'name' => 'New Bill ' . $this->randomInt(), 'amount_min' => '100', 'transaction_currency_id' => 1, 'skip' => 0, @@ -437,7 +437,7 @@ class BillControllerTest extends TestCase $attachHelper->shouldReceive('getMessages')->andReturn(new MessageBag); $data = [ - 'name' => 'New Bill ' . random_int(1000, 9999), + 'name' => 'New Bill ' . $this->randomInt(), 'amount_min' => '100', 'transaction_currency_id' => 1, 'skip' => 0, @@ -476,7 +476,7 @@ class BillControllerTest extends TestCase $data = [ 'id' => 1, - 'name' => 'Updated Bill ' . random_int(1000, 9999), + 'name' => 'Updated Bill ' . $this->randomInt(), 'amount_min' => '100', 'transaction_currency_id' => 1, 'skip' => 0, diff --git a/tests/Feature/Controllers/Budget/CreateControllerTest.php b/tests/Feature/Controllers/Budget/CreateControllerTest.php index 2c8e240a62..4872d8ef48 100644 --- a/tests/Feature/Controllers/Budget/CreateControllerTest.php +++ b/tests/Feature/Controllers/Budget/CreateControllerTest.php @@ -91,7 +91,7 @@ class CreateControllerTest extends TestCase $this->session(['budgets.create.uri' => 'http://localhost']); $data = [ - 'name' => 'New Budget ' . random_int(1000, 9999), + 'name' => 'New Budget ' . $this->randomInt(), ]; $this->be($this->user()); $response = $this->post(route('budgets.store'), $data); diff --git a/tests/Feature/Controllers/Budget/EditControllerTest.php b/tests/Feature/Controllers/Budget/EditControllerTest.php index 4bc03f6646..2bb56e660d 100644 --- a/tests/Feature/Controllers/Budget/EditControllerTest.php +++ b/tests/Feature/Controllers/Budget/EditControllerTest.php @@ -90,7 +90,7 @@ class EditControllerTest extends TestCase $this->session(['budgets.edit.uri' => 'http://localhost']); $data = [ - 'name' => 'Updated Budget ' . random_int(1000, 9999), + 'name' => 'Updated Budget ' . $this->randomInt(), 'active' => 1, ]; $this->be($this->user()); diff --git a/tests/Feature/Controllers/CategoryControllerTest.php b/tests/Feature/Controllers/CategoryControllerTest.php index 7e40020bb6..d1f8081433 100644 --- a/tests/Feature/Controllers/CategoryControllerTest.php +++ b/tests/Feature/Controllers/CategoryControllerTest.php @@ -184,7 +184,7 @@ class CategoryControllerTest extends TestCase $this->session(['categories.create.uri' => 'http://localhost']); $data = [ - 'name' => 'New Category ' . random_int(1000, 9999), + 'name' => 'New Category ' . $this->randomInt(), ]; $this->be($this->user()); $response = $this->post(route('categories.store'), $data); @@ -212,7 +212,7 @@ class CategoryControllerTest extends TestCase $this->session(['categories.edit.uri' => 'http://localhost']); $data = [ - 'name' => 'Updated Category ' . random_int(1000, 9999), + 'name' => 'Updated Category ' . $this->randomInt(), 'active' => 1, ]; $this->be($this->user()); diff --git a/tests/TestCase.php b/tests/TestCase.php index 11ad4115c0..6a6e78998f 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -51,6 +51,21 @@ use RuntimeException; */ abstract class TestCase extends BaseTestCase { + /** + * @return int + */ + public function randomInt(): int + { + $result = 4; + try { + $result = random_int(1, 100000); + } catch (Exception $e) { + Log::debug(sprintf('Could not generate random number: %s', $e->getMessage())); + } + + return $result; + } + /** * @param User $user * @param string $range diff --git a/tests/Unit/Console/Commands/Import/CreateCSVImportTest.php b/tests/Unit/Console/Commands/Import/CreateCSVImportTest.php index 94e31c68c3..5069ae66d0 100644 --- a/tests/Unit/Console/Commands/Import/CreateCSVImportTest.php +++ b/tests/Unit/Console/Commands/Import/CreateCSVImportTest.php @@ -129,7 +129,7 @@ class CreateCSVImportTest extends TestCase $importJob = ImportJob::create( [ - 'key' => 'key-' . random_int(1, 100000), + 'key' => 'key-' . $this->randomInt(), 'user_id' => 1, 'file_type' => 'csv', 'status' => 'new', @@ -203,7 +203,7 @@ class CreateCSVImportTest extends TestCase $importJob = ImportJob::create( [ - 'key' => 'key-' . random_int(1, 100000), + 'key' => 'key-' . $this->randomInt(), 'user_id' => 1, 'file_type' => 'csv', 'status' => 'new', diff --git a/tests/Unit/Console/Commands/Upgrade/MigrateToRulesTest.php b/tests/Unit/Console/Commands/Upgrade/MigrateToRulesTest.php index d0df3f9b0a..b84a82c24b 100644 --- a/tests/Unit/Console/Commands/Upgrade/MigrateToRulesTest.php +++ b/tests/Unit/Console/Commands/Upgrade/MigrateToRulesTest.php @@ -151,8 +151,10 @@ class MigrateToRulesTest extends TestCase ], ], 'actions' => [ - 'type' => 'link_to_bill', - 'value' => $bill->name, + [ + 'type' => 'link_to_bill', + 'value' => $bill->name, + ], ], ]; @@ -260,8 +262,10 @@ class MigrateToRulesTest extends TestCase ], ], 'actions' => [ - 'type' => 'link_to_bill', - 'value' => $bill->name, + [ + 'type' => 'link_to_bill', + 'value' => $bill->name, + ], ], ]; diff --git a/tests/Unit/Factory/AccountFactoryTest.php b/tests/Unit/Factory/AccountFactoryTest.php index e72169e715..80f26c088d 100644 --- a/tests/Unit/Factory/AccountFactoryTest.php +++ b/tests/Unit/Factory/AccountFactoryTest.php @@ -27,15 +27,19 @@ namespace Tests\Unit\Factory; use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\AccountFactory; +use FireflyIII\Factory\AccountMetaFactory; +use FireflyIII\Factory\TransactionGroupFactory; use FireflyIII\Models\Account; use FireflyIII\Models\AccountMeta; use FireflyIII\Models\AccountType; -use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; use Log; +use Mockery; use Tests\TestCase; /** * Class AccountFactoryTest + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ class AccountFactoryTest extends TestCase { @@ -52,27 +56,41 @@ 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(): void + public function testCreate(): void { - + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $this->mock(TransactionGroupFactory::class); $data = [ 'account_type_id' => null, - 'accountType' => 'asset', + 'account_type' => 'asset', 'iban' => null, - 'name' => 'Basic asset account #' . random_int(1, 10000), - 'virtualBalance' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => null, 'active' => true, - 'accountRole' => 'defaultAsset', + 'account_role' => 'defaultAsset', ]; + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'defaultAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); - $account = $factory->create($data); + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } // assert stuff about account: $this->assertEquals($account->name, $data['name']); @@ -81,44 +99,267 @@ class AccountFactoryTest extends TestCase $this->assertTrue($account->active); $this->assertEquals('0', $account->virtual_balance); - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('defaultAsset', $meta->data); - - // get the currency ID: - /** @var AccountMeta $meta */ - $currencyId = $account->accountMeta()->where('name', 'currency_id')->first(); - $this->assertNotNull($currencyId); - $this->assertEquals('1', $currencyId->data); + $account->forceDelete(); } /** * Test creation of CC asset. * * @covers \FireflyIII\Factory\AccountFactory - * @covers \FireflyIII\Factory\AccountMetaFactory * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait */ - public function testCreateBasicCC(): void + public function testCreateCC(): void { - + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $this->mock(TransactionGroupFactory::class); $data = [ + 'account_type_id' => null, + 'account_type' => 'asset', + 'iban' => null, + 'name' => sprintf('Basic CC account #%d', $this->randomInt()), + 'virtual_balance' => null, + 'active' => true, + 'account_role' => 'ccAsset', + 'cc_monthly_payment_date' => '2018-01-01', + ]; + + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'ccAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'cc_monthly_payment_date', '2018-01-01'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'cc_type', ''])->atLeast()->once()->andReturnNull(); + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + + // 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); + + $account->forceDelete(); + } + + /** + * Leave virtual balance empty. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateEmptyVb(): void + { + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $this->mock(TransactionGroupFactory::class); + $data = [ + 'account_type_id' => null, + 'account_type' => 'asset', + 'iban' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => '', + 'active' => true, + 'account_role' => 'defaultAsset', + ]; + + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'defaultAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + + // 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); + + $account->forceDelete(); + } + + /** + * Create an expense account. This overrules the virtual balance. + * Role should not be set. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateExpense(): void + { + $this->mock(AccountRepositoryInterface::class); + $this->mock(TransactionGroupFactory::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $data = [ + 'account_type_id' => null, + 'account_type' => 'expense', + 'iban' => null, + 'name' => sprintf('Basic expense account #%d', $this->randomInt()), + 'virtual_balance' => '1243', + 'active' => true, + 'account_role' => 'defaultAsset', + ]; + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'interest', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'interest_period', ''])->atLeast()->once()->andReturnNull(); + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + + // 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); + + // get the role: + /** @var AccountMeta $meta */ + $meta = $account->accountMeta()->where('name', 'accountRole')->first(); + $this->assertNull($meta); + $account->forceDelete(); + } + + /** + * Create an expense account. This overrules the virtual balance. + * Role should not be set. This time set type name, not ID. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateExpenseFullType(): void + { + $this->mock(AccountRepositoryInterface::class); + $this->mock(TransactionGroupFactory::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $data = [ + 'account_type_id' => null, + 'account_type' => 'Expense account', + 'iban' => null, + 'name' => sprintf('Basic expense account #%d', $this->randomInt()), + 'virtual_balance' => '1243', + 'active' => true, + 'account_role' => 'defaultAsset', + ]; + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'interest', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'interest_period', ''])->atLeast()->once()->andReturnNull(); + + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + + // 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); + + // get the role: + /** @var AccountMeta $meta */ + $meta = $account->accountMeta()->where('name', 'accountRole')->first(); + $this->assertNull($meta); + $account->forceDelete(); + } + + /** + * Submit valid opening balance data for asset account. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testCreateOB(): void + { + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $groupFactory = $this->mock(TransactionGroupFactory::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $data = [ 'account_type_id' => null, - 'accountType' => 'asset', + 'account_type' => 'asset', 'iban' => null, - 'name' => 'Basic CC account #' . random_int(1, 10000), - 'virtualBalance' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => null, 'active' => true, - 'accountRole' => 'ccAsset', - 'ccMonthlyPaymentDate' => '2018-01-01', + 'account_role' => 'defaultAsset', + 'opening_balance' => '100', + 'opening_balance_date' => new Carbon('2018-01-01'), + 'currency_id' => 1, ]; + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + $groupFactory->shouldReceive('setUser')->atLeast()->once(); + $groupFactory->shouldReceive('create')->atLeast()->once(); + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'defaultAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); - $account = $factory->create($data); + + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } // assert stuff about account: $this->assertEquals($account->name, $data['name']); @@ -126,212 +367,56 @@ class AccountFactoryTest extends TestCase $this->assertEquals('', $account->iban); $this->assertTrue($account->active); $this->assertEquals('0', $account->virtual_balance); - - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('ccAsset', $meta->data); - - // get the date: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'ccMonthlyPaymentDate')->first(); - $this->assertNotNull($meta); - $this->assertEquals('2018-01-01', $meta->data); - } - - /** - * 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 testCreateBasicEmptyVb(): void - { - - $data = [ - 'account_type_id' => null, - 'accountType' => 'asset', - 'iban' => null, - 'name' => 'Basic asset account #' . random_int(1, 10000), - 'virtualBalance' => '', - '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); - - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('defaultAsset', $meta->data); - } - - /** - * 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(): void - { - - $data = [ - 'account_type_id' => null, - 'accountType' => 'expense', - 'iban' => null, - 'name' => 'Basic expense account #' . random_int(1, 10000), - '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); - - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNull($meta); - } - - /** - * 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 testCreateBasicExpenseFullType(): void - { - - $data = [ - 'account_type_id' => null, - 'accountType' => 'Expense account', - 'iban' => null, - 'name' => 'Basic expense account #' . random_int(1, 10000), - '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); - - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNull($meta); - } - - /** - * Submit IB data for asset account. - * - * @covers \FireflyIII\Factory\AccountFactory - * @covers \FireflyIII\Factory\AccountMetaFactory - * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait - */ - public function testCreateBasicIB(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - $data = [ - 'account_type_id' => null, - 'accountType' => 'asset', - 'iban' => null, - 'name' => 'Basic asset account #' . random_int(1, 10000), - '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); - - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('defaultAsset', $meta->data); - - // find opening balance: - $this->assertEquals(1, $account->transactions()->count()); - $this->assertEquals(100, (float)$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(): void + public function testCreateOBZero(): void { - - $data = [ - 'account_type_id' => null, - 'accountType' => 'asset', - 'iban' => null, - 'name' => 'Basic asset account #' . random_int(1, 10000), - 'virtualBalance' => null, - 'active' => true, - 'accountRole' => 'defaultAsset', - 'openingBalance' => '0.0', - 'openingBalanceDate' => new Carbon('2018-01-01'), - 'currency_id' => 1, + // mock repositories: + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $groupFactory = $this->mock(TransactionGroupFactory::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $data = [ + 'account_type_id' => null, + 'account_type' => 'asset', + 'iban' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => null, + 'active' => true, + 'account_role' => 'defaultAsset', + 'opening_balance' => '0.0', + 'opening_balance_date' => new Carbon('2018-01-01'), + 'currency_id' => 1, ]; + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + $groupFactory->shouldReceive('setUser')->atLeast()->once(); + $groupFactory->shouldReceive('create')->atLeast()->once(); + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'defaultAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); - $account = $factory->create($data); + + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + // assert stuff about account: $this->assertEquals($account->name, $data['name']); @@ -340,40 +425,50 @@ class AccountFactoryTest extends TestCase $this->assertTrue($account->active); $this->assertEquals('0', $account->virtual_balance); - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('defaultAsset', $meta->data); - - // find opening balance: - $this->assertEquals(0, $account->transactions()->count()); + $account->forceDelete(); } /** * Add valid IBAN. * * @covers \FireflyIII\Factory\AccountFactory - * @covers \FireflyIII\Factory\AccountMetaFactory * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait */ - public function testCreateBasicIban(): void + public function testCreateIban(): void { - + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $this->mock(TransactionGroupFactory::class); $data = [ 'account_type_id' => null, - 'accountType' => 'asset', + 'account_type' => 'asset', 'iban' => 'NL02ABNA0870809585', - 'name' => 'Basic asset account #' . random_int(1, 10000), - 'virtualBalance' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => null, 'active' => true, - 'accountRole' => 'defaultAsset', + 'account_role' => 'defaultAsset', ]; + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'defaultAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); - $account = $factory->create($data); + + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } // assert stuff about account: $this->assertEquals($account->name, $data['name']); @@ -382,37 +477,51 @@ class AccountFactoryTest extends TestCase $this->assertTrue($account->active); $this->assertEquals('0', $account->virtual_balance); - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('defaultAsset', $meta->data); + $account->forceDelete(); } /** * Add invalid IBAN. * * @covers \FireflyIII\Factory\AccountFactory - * @covers \FireflyIII\Factory\AccountMetaFactory * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait */ - public function testCreateBasicInvalidIban(): void + public function testCreateInvalidIban(): void { - + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $this->mock(TransactionGroupFactory::class); $data = [ 'account_type_id' => null, - 'accountType' => 'asset', + 'account_type' => 'asset', 'iban' => 'NL1XRABO032674X238', - 'name' => 'Basic asset account #' . random_int(1, 10000), - 'virtualBalance' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => null, 'active' => true, - 'accountRole' => 'defaultAsset', + 'account_role' => 'defaultAsset', ]; + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'defaultAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + + /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); - $account = $factory->create($data); + + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } // assert stuff about account: $this->assertEquals($account->name, $data['name']); @@ -421,42 +530,55 @@ class AccountFactoryTest extends TestCase $this->assertTrue($account->active); $this->assertEquals('0', $account->virtual_balance); - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('defaultAsset', $meta->data); } /** * Submit IB data for asset account. * * @covers \FireflyIII\Factory\AccountFactory - * @covers \FireflyIII\Factory\AccountMetaFactory * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait */ - public function testCreateBasicNegativeIB(): void + public function testCreateNegativeIB(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - $data = [ - 'account_type_id' => null, - 'accountType' => 'asset', - 'iban' => null, - 'name' => 'Basic asset account #' . random_int(1, 10000), - 'virtualBalance' => null, - 'active' => true, - 'accountRole' => 'defaultAsset', - 'openingBalance' => '-100', - 'openingBalanceDate' => new Carbon('2018-01-01'), - 'currency_id' => 1, + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $groupFactory = $this->mock(TransactionGroupFactory::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $data = [ + 'account_type_id' => null, + 'account_type' => 'asset', + 'iban' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => null, + 'active' => true, + 'account_role' => 'defaultAsset', + 'opening_balance' => '-100', + 'opening_balance_date' => new Carbon('2018-01-01'), + 'currency_id' => 1, ]; + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + $groupFactory->shouldReceive('setUser')->atLeast()->once(); + $groupFactory->shouldReceive('create')->atLeast()->once(); + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'defaultAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + + /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); - $account = $factory->create($data); + + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } // assert stuff about account: $this->assertEquals($account->name, $data['name']); @@ -465,42 +587,52 @@ class AccountFactoryTest extends TestCase $this->assertTrue($account->active); $this->assertEquals('0', $account->virtual_balance); - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('defaultAsset', $meta->data); - - // find opening balance: - $this->assertEquals(1, $account->transactions()->count()); - $this->assertEquals(-100, (float)$account->transactions()->first()->amount); + $account->forceDelete(); } /** * Add some notes to asset account. * * @covers \FireflyIII\Factory\AccountFactory - * @covers \FireflyIII\Factory\AccountMetaFactory * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait */ - public function testCreateBasicNotes(): void + public function testCreateNotes(): void { - + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $this->mock(TransactionGroupFactory::class); $data = [ 'account_type_id' => null, - 'accountType' => 'asset', + 'account_type' => 'asset', 'iban' => null, - 'name' => 'Basic asset account #' . random_int(1, 10000), - 'virtualBalance' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => null, 'active' => true, - 'accountRole' => 'defaultAsset', + 'account_role' => 'defaultAsset', 'notes' => 'Hello!', ]; /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); - $account = $factory->create($data); + + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'defaultAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + + + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } // assert stuff about account: $this->assertEquals($account->name, $data['name']); @@ -509,12 +641,6 @@ class AccountFactoryTest extends TestCase $this->assertTrue($account->active); $this->assertEquals('0', $account->virtual_balance); - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('defaultAsset', $meta->data); - $note = $account->notes()->first(); $this->assertEquals('Hello!', $note->text); } @@ -523,28 +649,46 @@ 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 testCreateCurrencyCode(): void { - $currency = TransactionCurrency::where('code', 'CAD')->first(); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $this->mock(TransactionGroupFactory::class); + $currency = $this->getDollar(); $data = [ 'account_type_id' => null, - 'accountType' => 'asset', + 'account_type' => 'asset', 'iban' => null, 'currency_code' => $currency->code, - 'name' => 'Basic asset account #' . random_int(1, 10000), - 'virtualBalance' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => null, 'active' => true, - 'accountRole' => 'defaultAsset', + 'account_role' => 'defaultAsset', ]; + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'defaultAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', $currency->id])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); - $account = $factory->create($data); + + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } // assert stuff about account: $this->assertEquals($account->name, $data['name']); @@ -553,45 +697,53 @@ class AccountFactoryTest extends TestCase $this->assertTrue($account->active); $this->assertEquals('0', $account->virtual_balance); - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('defaultAsset', $meta->data); - // get the currency ID: - /** @var AccountMeta $meta */ - $currencyId = $account->accountMeta()->where('name', 'currency_id')->first(); - $this->assertNotNull($currencyId); - $this->assertEquals((int)$currency->id, (int)$currencyId->data); } /** * 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 testCreateCurrencyId(): void { - $currency = TransactionCurrency::where('code', 'USD')->first(); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + $this->mock(TransactionGroupFactory::class); + $currency = $this->getDollar(); $data = [ 'account_type_id' => null, - 'accountType' => 'asset', + 'account_type' => 'asset', 'iban' => null, 'currency_id' => $currency->id, - 'name' => 'Basic asset account #' . random_int(1, 10000), - 'virtualBalance' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => null, 'active' => true, - 'accountRole' => 'defaultAsset', + 'account_role' => 'defaultAsset', ]; + // mock calls to the repository: + $accountRepos->shouldReceive('getOpeningBalanceGroup')->atLeast()->once()->andReturn(null); + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_role', 'defaultAsset'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', $currency->id])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); - $account = $factory->create($data); + + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } // assert stuff about account: $this->assertEquals($account->name, $data['name']); @@ -600,17 +752,6 @@ class AccountFactoryTest extends TestCase $this->assertTrue($account->active); $this->assertEquals('0', $account->virtual_balance); - // get the role: - /** @var AccountMeta $meta */ - $meta = $account->accountMeta()->where('name', 'accountRole')->first(); - $this->assertNotNull($meta); - $this->assertEquals('defaultAsset', $meta->data); - - // get the currency ID: - /** @var AccountMeta $meta */ - $currencyId = $account->accountMeta()->where('name', 'currency_id')->first(); - $this->assertNotNull($currencyId); - $this->assertEquals($currency->id, $currencyId->data); } /** @@ -620,21 +761,32 @@ class AccountFactoryTest extends TestCase */ public function testCreateExisting(): void { - $existing = $this->user()->accounts()->where('account_type_id', 3)->first(); + $this->mock(AccountRepositoryInterface::class); + $this->mock(TransactionGroupFactory::class); + $this->mock(AccountMetaFactory::class); + $existing = $this->getRandomAsset(); $data = [ 'account_type_id' => null, - 'accountType' => 'asset', + 'account_type' => 'asset', 'name' => $existing->name, - 'virtualBalance' => null, + 'virtual_balance' => null, 'iban' => null, 'active' => true, - 'accountRole' => 'defaultAsset', + 'account_role' => 'defaultAsset', ]; + /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); - $account = $factory->create($data); + + try { + $account = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } // assert stuff about account: $this->assertEquals($account->id, $existing->id); @@ -644,20 +796,21 @@ class AccountFactoryTest extends TestCase * Can't find account type. * * @covers \FireflyIII\Factory\AccountFactory - * @covers \FireflyIII\Factory\AccountMetaFactory * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait */ public function testCreateNoType(): void { - + $this->mock(AccountRepositoryInterface::class); + $this->mock(TransactionGroupFactory::class); + $this->mock(AccountMetaFactory::class); $data = [ 'account_type_id' => null, - 'accountType' => 'bla-bla', + 'account_type' => 'bla-bla', 'iban' => null, - 'name' => 'Basic asset account #' . random_int(1, 10000), - 'virtualBalance' => null, + 'name' => sprintf('Basic asset account #%d', $this->randomInt()), + 'virtual_balance' => null, 'active' => true, - 'accountRole' => 'defaultAsset', + 'account_role' => 'defaultAsset', ]; /** @var AccountFactory $factory */ @@ -671,16 +824,18 @@ class AccountFactoryTest extends TestCase } /** - * Test only for existing account because the rest has been covered by other tests. - * * @covers \FireflyIII\Factory\AccountFactory - * @covers \FireflyIII\Factory\AccountMetaFactory * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait */ public function testFindOrCreate(): void { + $this->mock(AccountRepositoryInterface::class); + $this->mock(TransactionGroupFactory::class); + $this->mock(AccountMetaFactory::class); /** @var Account $account */ $account = $this->getRandomRevenue(); + + /** @var AccountFactory $factory */ $factory = app(AccountFactory::class); $factory->setUser($this->user()); @@ -690,4 +845,39 @@ class AccountFactoryTest extends TestCase $this->assertEquals($result->id, $account->id); } + /** + * Test only for existing account because the rest has been covered by other tests. + * + * @covers \FireflyIII\Factory\AccountFactory + * @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait + */ + public function testFindOrCreateNew(): void + { + $this->mock(AccountRepositoryInterface::class); + $this->mock(TransactionGroupFactory::class); + $metaFactory = $this->mock(AccountMetaFactory::class); + /** @var Account $account */ + $account = $this->getRandomRevenue(); + + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'account_number', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'currency_id', '1'])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'BIC', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'include_net_worth', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'interest', ''])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('crud')->withArgs([Mockery::any(), 'interest_period', ''])->atLeast()->once()->andReturnNull(); + + $name = sprintf('New %s', $account->name); + + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user()); + Log::debug(sprintf('Searching for account #%d with name "%s"', $account->id, $account->name)); + + $result = $factory->findOrCreate($name, $account->accountType->type); + $this->assertNotEquals($result->id, $account->id); + + $result->forceDelete(); + + } + } diff --git a/tests/Unit/Factory/AccountMetaFactoryTest.php b/tests/Unit/Factory/AccountMetaFactoryTest.php index ac145393d0..618597d929 100644 --- a/tests/Unit/Factory/AccountMetaFactoryTest.php +++ b/tests/Unit/Factory/AccountMetaFactoryTest.php @@ -25,6 +25,7 @@ namespace Tests\Unit\Factory; use FireflyIII\Factory\AccountMetaFactory; +use FireflyIII\Models\AccountMeta; use Log; use Tests\TestCase; @@ -34,8 +35,6 @@ use Tests\TestCase; */ class AccountMetaFactoryTest extends TestCase { - - /** * */ @@ -50,16 +49,17 @@ class AccountMetaFactoryTest extends TestCase */ public function testCreate(): void { - $account = $this->user()->accounts()->inRandomOrder()->first(); + $account = $this->getRandomAsset(); $data = [ 'account_id' => $account->id, 'name' => 'Some name', 'data' => 'Some value', ]; - $factory = new AccountMetaFactory; + $factory = app(AccountMetaFactory::class); $result = $factory->create($data); $this->assertEquals($data['name'], $result->name); + $result->forceDelete(); } /** @@ -67,19 +67,20 @@ class AccountMetaFactoryTest extends TestCase */ public function testCrudDelete(): void { - $factory = new AccountMetaFactory; - $account = $this->user()->accounts()->inRandomOrder()->first(); + $factory = app(AccountMetaFactory::class); + $account = $this->getRandomAsset(); $data = [ 'account_id' => $account->id, - 'name' => 'Some name ' . random_int(1, 100000), + 'name' => sprintf('Some name %d', $this->randomInt()), 'data' => 'Some value', ]; - $factory->create($data); + $new = $factory->create($data); // update existing one $result = $factory->crud($account, $data['name'], ''); $this->assertNull($result); + $this->assertCount(0, AccountMeta::where('id', $new->id)->get()); } /** @@ -87,11 +88,11 @@ class AccountMetaFactoryTest extends TestCase */ public function testCrudExisting(): void { - $factory = new AccountMetaFactory; - $account = $this->user()->accounts()->inRandomOrder()->first(); + $factory = app(AccountMetaFactory::class); + $account = $this->getRandomAsset(); $data = [ 'account_id' => $account->id, - 'name' => 'Some name ' . random_int(1, 100000), + 'name' => sprintf('Some name %d', $this->randomInt()), 'data' => 'Some value', ]; @@ -103,7 +104,6 @@ class AccountMetaFactoryTest extends TestCase $this->assertEquals($result->account_id, $account->id); $this->assertEquals($existing->name, $result->name); $this->assertEquals('Some NEW value', $result->data); - } /** @@ -111,9 +111,9 @@ class AccountMetaFactoryTest extends TestCase */ public function testCrudNew(): void { - $account = $this->user()->accounts()->inRandomOrder()->first(); - $factory = new AccountMetaFactory; - $result = $factory->crud($account, 'random name ' . random_int(1, 100000), 'Some value'); + $factory = app(AccountMetaFactory::class); + $account = $this->getRandomAsset(); + $result = $factory->crud($account, 'random name ' . $this->randomInt(), 'Some value'); $this->assertNotNull($result); $this->assertEquals($result->account_id, $account->id); diff --git a/tests/Unit/Factory/AttachmentFactoryTest.php b/tests/Unit/Factory/AttachmentFactoryTest.php index 612de8dddf..548019536d 100644 --- a/tests/Unit/Factory/AttachmentFactoryTest.php +++ b/tests/Unit/Factory/AttachmentFactoryTest.php @@ -24,7 +24,9 @@ declare(strict_types=1); namespace Tests\Unit\Factory; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\AttachmentFactory; +use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use Log; use Tests\TestCase; @@ -51,7 +53,7 @@ class AttachmentFactoryTest extends TestCase public function testCreate(): void { - $journal = $this->user()->transactionJournals()->inRandomOrder()->first(); + $journal = $this->getRandomWithdrawal(); $data = [ 'model_id' => $journal->id, 'model' => TransactionJournal::class, @@ -60,12 +62,80 @@ class AttachmentFactoryTest extends TestCase 'notes' => 'Some notes', ]; - $factory = new AttachmentFactory; + /** @var AttachmentFactory $factory */ + $factory = app(AttachmentFactory::class); $factory->setUser($this->user()); - $result = $factory->create($data); + try { + $result = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } $this->assertEquals($data['title'], $result->title); $this->assertEquals(1, $result->notes()->count()); + } + + /** + * @covers \FireflyIII\Factory\AttachmentFactory + */ + public function testCreateTransaction(): void + { + + $journal = $this->getRandomWithdrawal(); + $transaction = $journal->transactions()->first(); + $data = [ + 'model_id' => $transaction->id, + 'model' => Transaction::class, + 'filename' => 'testfile.pdf', + 'title' => 'File name', + 'notes' => 'Some notes', + ]; + + /** @var AttachmentFactory $factory */ + $factory = app(AttachmentFactory::class); + $factory->setUser($this->user()); + try { + $result = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + $this->assertEquals($data['title'], $result->title); + $this->assertEquals($result->attachable_id, $journal->id); + $this->assertEquals(1, $result->notes()->count()); + + + } + + + /** + * @covers \FireflyIII\Factory\AttachmentFactory + */ + public function testCreateTransactionAppendModel(): void + { + + $journal = $this->getRandomWithdrawal(); + $transaction = $journal->transactions()->first(); + $data = [ + 'model_id' => $transaction->id, + 'model' => 'Transaction', + 'filename' => 'testfile.pdf', + 'title' => 'File name', + 'notes' => 'Some notes', + ]; + + /** @var AttachmentFactory $factory */ + $factory = app(AttachmentFactory::class); + $factory->setUser($this->user()); + try { + $result = $factory->create($data); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + $this->assertEquals($data['title'], $result->title); + $this->assertEquals($result->attachable_id, $journal->id); + $this->assertEquals(1, $result->notes()->count()); + + } } diff --git a/tests/Unit/Factory/BillFactoryTest.php b/tests/Unit/Factory/BillFactoryTest.php index 3a52ed7f5e..41a9e66678 100644 --- a/tests/Unit/Factory/BillFactoryTest.php +++ b/tests/Unit/Factory/BillFactoryTest.php @@ -27,7 +27,6 @@ namespace Tests\Unit\Factory; use Amount; use FireflyIII\Factory\BillFactory; use FireflyIII\Factory\TransactionCurrencyFactory; -use FireflyIII\Models\TransactionCurrency; use Log; use Tests\TestCase; @@ -36,8 +35,6 @@ use Tests\TestCase; */ class BillFactoryTest extends TestCase { - - /** * */ @@ -56,8 +53,9 @@ class BillFactoryTest extends TestCase public function testCreateBasic(): void { $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $euro = $this->getEuro(); $data = [ - 'name' => 'Some new bill #' . random_int(1, 10000), + 'name' => sprintf('Some new bill #%d', $this->randomInt()), 'amount_min' => '5', 'currency_id' => 1, 'currency_code' => '', @@ -71,8 +69,7 @@ class BillFactoryTest extends TestCase ]; $currencyFactory->shouldReceive('find')->atLeast()->once() - ->withArgs([1, ''])->andReturn(TransactionCurrency::find(1)); - + ->withArgs([1, ''])->andReturn($euro); /** @var BillFactory $factory */ $factory = app(BillFactory::class); @@ -97,10 +94,11 @@ class BillFactoryTest extends TestCase public function testCreateDifferentCurrency(): void { $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $dollar = $this->getDollar(); $data = [ - 'name' => 'Some new bill #' . random_int(1, 10000), + 'name' => sprintf('Some new bill #%d', $this->randomInt()), 'amount_min' => '5', - 'currency_code' => 'USD', + 'currency_code' => $dollar->code, 'amount_max' => '10', 'date' => '2018-01-01', 'repeat_freq' => 'monthly', @@ -111,8 +109,7 @@ class BillFactoryTest extends TestCase ]; $currencyFactory->shouldReceive('find')->atLeast()->once() - ->withArgs([0, 'USD'])->andReturn(TransactionCurrency::find(5)); - + ->withArgs([0, $dollar->code])->andReturn($dollar); /** @var BillFactory $factory */ $factory = app(BillFactory::class); @@ -121,7 +118,7 @@ class BillFactoryTest extends TestCase $this->assertEquals($data['name'], $bill->name); $this->assertEquals($data['amount_min'], $bill->amount_min); - $this->assertEquals(5, $bill->transaction_currency_id); + $this->assertEquals($dollar->id, $bill->transaction_currency_id); $this->assertEquals($data['repeat_freq'], $bill->repeat_freq); $note = $bill->notes()->first(); $this->assertEquals($data['notes'], $note->text); @@ -137,13 +134,14 @@ class BillFactoryTest extends TestCase public function testCreateEmptyNotes(): void { $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $euro = $this->getEuro(); $data = [ - 'name' => 'Some new bill #' . random_int(1, 10000), + 'name' => sprintf('Some new bill #%d', $this->randomInt()), 'amount_min' => '5', 'amount_max' => '10', 'date' => '2018-01-01', 'repeat_freq' => 'monthly', - 'currency_id' => 1, + 'currency_id' => $euro->id, 'currency_code' => '', 'skip' => 0, 'automatch' => true, @@ -152,7 +150,7 @@ class BillFactoryTest extends TestCase ]; $currencyFactory->shouldReceive('find')->atLeast()->once() - ->withArgs([1, ''])->andReturn(TransactionCurrency::find(1)); + ->withArgs([1, ''])->andReturn($euro); /** @var BillFactory $factory */ @@ -161,7 +159,7 @@ class BillFactoryTest extends TestCase $bill = $factory->create($data); $this->assertEquals($data['name'], $bill->name); - $this->assertEquals(1, $bill->transaction_currency_id); + $this->assertEquals($euro->id, $bill->transaction_currency_id); $this->assertEquals($data['amount_min'], $bill->amount_min); $this->assertEquals($data['repeat_freq'], $bill->repeat_freq); $this->assertEquals(0, $bill->notes()->count()); @@ -177,8 +175,9 @@ class BillFactoryTest extends TestCase public function testCreateNoCurrency(): void { $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $dollar = $this->getDollar(); $data = [ - 'name' => 'Some new bill #' . random_int(1, 10000), + 'name' => sprintf('Some new bill #%d', $this->randomInt()), 'amount_min' => '5', 'amount_max' => '10', 'date' => '2018-01-01', @@ -192,7 +191,7 @@ class BillFactoryTest extends TestCase $currencyFactory->shouldReceive('find')->atLeast()->once() ->withArgs([0, ''])->andReturnNull(); - Amount::shouldReceive('getDefaultCurrencyByUser')->atLeast()->once()->andReturn(TransactionCurrency::find(3)); + Amount::shouldReceive('getDefaultCurrencyByUser')->atLeast()->once()->andReturn($dollar); /** @var BillFactory $factory */ @@ -202,7 +201,7 @@ class BillFactoryTest extends TestCase $this->assertEquals($data['name'], $bill->name); $this->assertEquals($data['amount_min'], $bill->amount_min); - $this->assertEquals(3, $bill->transaction_currency_id); + $this->assertEquals($dollar->id, $bill->transaction_currency_id); $this->assertEquals($data['repeat_freq'], $bill->repeat_freq); $note = $bill->notes()->first(); $this->assertEquals($data['notes'], $note->text); @@ -256,7 +255,7 @@ class BillFactoryTest extends TestCase /** @var BillFactory $factory */ $factory = app(BillFactory::class); $factory->setUser($this->user()); - $piggy = $factory->find(null, 'I dont exist' . random_int(1, 10000)); + $piggy = $factory->find(null, sprintf('I dont exist #%d', $this->randomInt())); $this->assertNull($piggy); } diff --git a/tests/Unit/Factory/BudgetFactoryTest.php b/tests/Unit/Factory/BudgetFactoryTest.php index e6029938da..ccbac463e2 100644 --- a/tests/Unit/Factory/BudgetFactoryTest.php +++ b/tests/Unit/Factory/BudgetFactoryTest.php @@ -102,7 +102,7 @@ class BudgetFactoryTest extends TestCase /** @var BudgetFactory $factory */ $factory = app(BudgetFactory::class); $factory->setUser($this->user()); - $this->assertNull($factory->find(null, 'I dont exist.' . random_int(1, 10000))); + $this->assertNull($factory->find(null, sprintf('I dont exist %d', $this->randomInt()))); } } diff --git a/tests/Unit/Factory/CategoryFactoryTest.php b/tests/Unit/Factory/CategoryFactoryTest.php index 2188cacfc3..565b46cf6e 100644 --- a/tests/Unit/Factory/CategoryFactoryTest.php +++ b/tests/Unit/Factory/CategoryFactoryTest.php @@ -91,7 +91,7 @@ class CategoryFactoryTest extends TestCase */ public function testFindOrCreateNewName(): void { - $name = 'Some new category #' . random_int(1, 10000); + $name = sprintf('Some new category #%d', $this->randomInt()); /** @var CategoryFactory $factory */ $factory = app(CategoryFactory::class); diff --git a/tests/Unit/Factory/PiggyBankEventFactoryTest.php b/tests/Unit/Factory/PiggyBankEventFactoryTest.php index 347b9a1464..a0645e38ee 100644 --- a/tests/Unit/Factory/PiggyBankEventFactoryTest.php +++ b/tests/Unit/Factory/PiggyBankEventFactoryTest.php @@ -27,7 +27,6 @@ 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 Log; use Tests\TestCase; @@ -52,12 +51,8 @@ class PiggyBankEventFactoryTest extends TestCase */ public function testCreateAmountZero(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var TransactionJournal $transfer */ - $transfer = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); - $piggy = $this->user()->piggyBanks()->first(); + $transfer = $this->getRandomTransfer(); + $piggy = $this->user()->piggyBanks()->inRandomOrder()->first(); $repetition = PiggyBankRepetition::first(); $repos = $this->mock(PiggyBankRepositoryInterface::class); /** @var PiggyBankEventFactory $factory */ @@ -76,11 +71,8 @@ class PiggyBankEventFactoryTest extends TestCase */ public function testCreateNoPiggy(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var TransactionJournal $transfer */ - $transfer = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); + $this->mock(PiggyBankRepositoryInterface::class); + $transfer = $this->getRandomTransfer(); /** @var PiggyBankEventFactory $factory */ $factory = app(PiggyBankEventFactory::class); @@ -95,11 +87,7 @@ class PiggyBankEventFactoryTest extends TestCase */ public function testCreateNoRep(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var TransactionJournal $transfer */ - $transfer = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); + $transfer = $this->getRandomTransfer(); $piggy = $this->user()->piggyBanks()->first(); $repos = $this->mock(PiggyBankRepositoryInterface::class); /** @var PiggyBankEventFactory $factory */ @@ -118,12 +106,10 @@ class PiggyBankEventFactoryTest extends TestCase */ public function testCreateNotTransfer(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); + $this->mock(PiggyBankRepositoryInterface::class); + $deposit = $this->getRandomDeposit(); - return; - /** @var TransactionJournal $deposit */ - $deposit = $this->user()->transactionJournals()->where('transaction_type_id', 2)->first(); - $piggy = $this->user()->piggyBanks()->first(); + $piggy = $this->user()->piggyBanks()->first(); /** @var PiggyBankEventFactory $factory */ $factory = app(PiggyBankEventFactory::class); @@ -135,15 +121,12 @@ class PiggyBankEventFactoryTest extends TestCase */ public function testCreateSuccess(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var TransactionJournal $transfer */ - $transfer = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); + $transfer = $this->getRandomTransfer(); $piggy = $this->user()->piggyBanks()->first(); $repetition = PiggyBankRepetition::first(); $event = PiggyBankEvent::first(); $repos = $this->mock(PiggyBankRepositoryInterface::class); + /** @var PiggyBankEventFactory $factory */ $factory = app(PiggyBankEventFactory::class); @@ -155,8 +138,8 @@ class PiggyBankEventFactoryTest extends TestCase $repos->shouldReceive('createEventWithJournal')->once()->andReturn($event); $result = $factory->create($transfer, $piggy); + $this->assertNotnull($result); $this->assertEquals($result->id, $event->id); - } } diff --git a/tests/Unit/Factory/RecurrenceFactoryTest.php b/tests/Unit/Factory/RecurrenceFactoryTest.php index f8e21a5fb4..ab5e465855 100644 --- a/tests/Unit/Factory/RecurrenceFactoryTest.php +++ b/tests/Unit/Factory/RecurrenceFactoryTest.php @@ -26,6 +26,7 @@ namespace Tests\Unit\Factory; use Amount; use Carbon\Carbon; +use FireflyIII\Factory\AccountFactory; use FireflyIII\Factory\BudgetFactory; use FireflyIII\Factory\CategoryFactory; use FireflyIII\Factory\PiggyBankFactory; @@ -35,12 +36,22 @@ use FireflyIII\Factory\TransactionTypeFactory; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Validation\AccountValidator; use Log; use Tests\TestCase; /** + * + * + * Test different combinations: + * Transfer + * Withdrawal + * Deposit + * + * With the correct types. * * Class RecurrenceFactoryTest + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ class RecurrenceFactoryTest extends TestCase { @@ -55,18 +66,20 @@ class RecurrenceFactoryTest extends TestCase /** * With piggy bank. With tags. With budget. With category. + * This is a withdrawal * * @covers \FireflyIII\Factory\RecurrenceFactory * @covers \FireflyIII\Services\Internal\Support\RecurringTransactionTrait */ - public function testBasic(): void + public function testCreate(): void { // objects to return: - $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); - $accountA = $this->user()->accounts()->inRandomOrder()->first(); - $accountB = $this->user()->accounts()->inRandomOrder()->first(); - $budget = $this->user()->budgets()->inRandomOrder()->first(); - $category = $this->user()->categories()->inRandomOrder()->first(); + $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); + $source = $this->getRandomAsset(); + $destination = $this->getRandomExpense(); + $budget = $this->user()->budgets()->inRandomOrder()->first(); + $category = $this->user()->categories()->inRandomOrder()->first(); + $euro = $this->getEuro(); // mock other factories: $piggyFactory = $this->mock(PiggyBankFactory::class); @@ -74,221 +87,36 @@ class RecurrenceFactoryTest extends TestCase $categoryFactory = $this->mock(CategoryFactory::class); $accountRepos = $this->mock(AccountRepositoryInterface::class); $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $typeFactory = $this->mock(TransactionTypeFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $validator = $this->mock(AccountValidator::class); // mock calls: - Amount::shouldReceive('getDefaultCurrencyByUser')->andReturn(TransactionCurrency::find(1))->once(); - $piggyFactory->shouldReceive('setUser')->once(); - $piggyFactory->shouldReceive('find')->withArgs([1, 'Bla bla'])->andReturn($piggyBank); - + Amount::shouldReceive('getDefaultCurrencyByUser')->andReturn($euro)->once(); + $piggyFactory->shouldReceive('setUser')->atLeast()->once(); + $budgetFactory->shouldReceive('setUser')->atLeast()->once(); $accountRepos->shouldReceive('setUser')->twice(); - $accountRepos->shouldReceive('findNull')->twice()->andReturn($accountA, $accountB); + $categoryFactory->shouldReceive('setUser')->once(); + + $piggyFactory->shouldReceive('find')->atLeast()->once()->withArgs([1, 'Bla bla'])->andReturn($piggyBank); + $accountRepos->shouldReceive('findNull')->twice()->andReturn($source, $destination); $currencyFactory->shouldReceive('find')->once()->withArgs([1, 'EUR'])->andReturn(null); $currencyFactory->shouldReceive('find')->once()->withArgs([null, null])->andReturn(null); - - $budgetFactory->shouldReceive('setUser')->once(); $budgetFactory->shouldReceive('find')->withArgs([1, 'Some budget'])->once()->andReturn($budget); - - $categoryFactory->shouldReceive('setUser')->once(); - $categoryFactory->shouldReceive('findOrCreate')->withArgs([2, 'Some category'])->once()->andReturn($category); - - // data for basic recurrence. - $data = [ - 'recurrence' => [ - 'type' => 'withdrawal', - 'first_date' => Carbon::now()->addDay(), - 'repetitions' => 0, - 'title' => 'Test recurrence' . random_int(1, 100000), - 'description' => 'Description thing', - 'apply_rules' => true, - 'active' => true, - 'repeat_until' => null, - ], - 'meta' => [ - 'tags' => ['a', 'b', 'c'], - 'piggy_bank_id' => 1, - 'piggy_bank_name' => 'Bla bla', - ], - 'repetitions' => [ - [ - 'type' => 'daily', - 'moment' => '', - 'skip' => 0, - 'weekend' => 1, - ], - ], - 'transactions' => [ - [ - 'source_id' => 1, - 'source_name' => 'Some name', - 'destination_id' => 2, - 'destination_name' => 'some otjer name', - 'currency_id' => 1, - 'currency_code' => 'EUR', - 'foreign_currency_id' => null, - 'foreign_currency_code' => null, - 'foreign_amount' => null, - 'description' => 'Bla bla bla', - 'amount' => '100', - 'budget_id' => 1, - 'budget_name' => 'Some budget', - 'category_id' => 2, - 'category_name' => 'Some category', - - ], - ], - ]; - $typeFactory = $this->mock(TransactionTypeFactory::class); - $typeFactory->shouldReceive('find')->once()->withArgs([ucfirst($data['recurrence']['type'])])->andReturn(TransactionType::find(1)); - $factory = new RecurrenceFactory; - $factory->setUser($this->user()); - - $result = $factory->create($data); - $this->assertEquals($result->title, $data['recurrence']['title']); - } - - /** - * Deposit. With piggy bank. With tags. With budget. With category. - * - * @covers \FireflyIII\Factory\RecurrenceFactory - * @covers \FireflyIII\Services\Internal\Support\RecurringTransactionTrait - */ - public function testBasicDeposit(): void - { - // objects to return: - $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); - $accountA = $this->user()->accounts()->inRandomOrder()->first(); - $accountB = $this->user()->accounts()->inRandomOrder()->first(); - $budget = $this->user()->budgets()->inRandomOrder()->first(); - $category = $this->user()->categories()->inRandomOrder()->first(); - - // mock other factories: - $piggyFactory = $this->mock(PiggyBankFactory::class); - $budgetFactory = $this->mock(BudgetFactory::class); - $categoryFactory = $this->mock(CategoryFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - - // mock calls: - Amount::shouldReceive('getDefaultCurrencyByUser')->andReturn(TransactionCurrency::find(1))->once(); - $piggyFactory->shouldReceive('setUser')->once(); - $piggyFactory->shouldReceive('find')->withArgs([1, 'Bla bla'])->andReturn($piggyBank); - - $accountRepos->shouldReceive('setUser')->twice(); - $accountRepos->shouldReceive('findNull')->twice()->andReturn($accountA, $accountB); - - $currencyFactory->shouldReceive('find')->once()->withArgs([1, 'EUR'])->andReturn(null); - $currencyFactory->shouldReceive('find')->once()->withArgs([null, null])->andReturn(null); - - $budgetFactory->shouldReceive('setUser')->once(); - $budgetFactory->shouldReceive('find')->withArgs([1, 'Some budget'])->once()->andReturn($budget); - - $categoryFactory->shouldReceive('setUser')->once(); $categoryFactory->shouldReceive('findOrCreate')->withArgs([2, 'Some category'])->once()->andReturn($category); + $validator->shouldReceive('setUser')->once(); + $validator->shouldReceive('setTransactionType')->atLeast()->once(); + $validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true); // data for basic recurrence. $data = [ - 'recurrence' => [ - 'type' => 'deposit', - 'first_date' => Carbon::now()->addDay(), - 'repetitions' => 0, - 'title' => 'Test recurrence' . random_int(1, 100000), - 'description' => 'Description thing', - 'apply_rules' => true, - 'active' => true, - 'repeat_until' => null, - ], - 'meta' => [ - 'tags' => ['a', 'b', 'c'], - 'piggy_bank_id' => 1, - 'piggy_bank_name' => 'Bla bla', - ], - 'repetitions' => [ - [ - 'type' => 'daily', - 'moment' => '', - 'skip' => 0, - 'weekend' => 1, - ], - ], - 'transactions' => [ - [ - 'source_id' => 1, - 'source_name' => 'Some name', - 'destination_id' => 2, - 'destination_name' => 'some otjer name', - 'currency_id' => 1, - 'currency_code' => 'EUR', - 'foreign_currency_id' => null, - 'foreign_currency_code' => null, - 'foreign_amount' => null, - 'description' => 'Bla bla bla', - 'amount' => '100', - 'budget_id' => 1, - 'budget_name' => 'Some budget', - 'category_id' => 2, - 'category_name' => 'Some category', - - ], - ], - ]; - - $typeFactory = $this->mock(TransactionTypeFactory::class); - $typeFactory->shouldReceive('find')->once()->withArgs([ucfirst($data['recurrence']['type'])])->andReturn(TransactionType::find(2)); - - $factory = new RecurrenceFactory; - $factory->setUser($this->user()); - - $result = $factory->create($data); - $this->assertEquals($result->title, $data['recurrence']['title']); - } - - /** - * No piggy bank. With tags. With budget. With category. - * - * @covers \FireflyIII\Factory\RecurrenceFactory - * @covers \FireflyIII\Services\Internal\Support\RecurringTransactionTrait - */ - public function testBasicNoPiggybank(): void - { - // objects to return: - $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); - $accountA = $this->user()->accounts()->inRandomOrder()->first(); - $accountB = $this->user()->accounts()->inRandomOrder()->first(); - $budget = $this->user()->budgets()->inRandomOrder()->first(); - $category = $this->user()->categories()->inRandomOrder()->first(); - - // mock other factories: - $piggyFactory = $this->mock(PiggyBankFactory::class); - $budgetFactory = $this->mock(BudgetFactory::class); - $categoryFactory = $this->mock(CategoryFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - - // mock calls: - Amount::shouldReceive('getDefaultCurrencyByUser')->andReturn(TransactionCurrency::find(1))->once(); - $piggyFactory->shouldReceive('setUser')->once(); - $piggyFactory->shouldReceive('find')->withArgs([1, 'Bla bla'])->andReturn(null); - - $accountRepos->shouldReceive('setUser')->twice(); - $accountRepos->shouldReceive('findNull')->twice()->andReturn($accountA, $accountB); - - $currencyFactory->shouldReceive('find')->once()->withArgs([1, 'EUR'])->andReturn(null); - $currencyFactory->shouldReceive('find')->once()->withArgs([null, null])->andReturn(null); - - $budgetFactory->shouldReceive('setUser')->once(); - $budgetFactory->shouldReceive('find')->withArgs([1, 'Some budget'])->once()->andReturn($budget); - - $categoryFactory->shouldReceive('setUser')->once(); - $categoryFactory->shouldReceive('findOrCreate')->withArgs([2, 'Some category'])->once()->andReturn($category); - - // data for basic recurrence. - $data = [ 'recurrence' => [ 'type' => 'withdrawal', 'first_date' => Carbon::now()->addDay(), 'repetitions' => 0, - 'title' => 'Test recurrence' . random_int(1, 100000), + 'title' => 'Test recurrence' . $this->randomInt(), 'description' => 'Description thing', 'apply_rules' => true, 'active' => true, @@ -312,7 +140,7 @@ class RecurrenceFactoryTest extends TestCase 'source_id' => 1, 'source_name' => 'Some name', 'destination_id' => 2, - 'destination_name' => 'some otjer name', + 'destination_name' => 'some other name', 'currency_id' => 1, 'currency_code' => 'EUR', 'foreign_currency_id' => null, @@ -328,9 +156,9 @@ class RecurrenceFactoryTest extends TestCase ], ], ]; - $typeFactory = $this->mock(TransactionTypeFactory::class); $typeFactory->shouldReceive('find')->once()->withArgs([ucfirst($data['recurrence']['type'])])->andReturn(TransactionType::find(1)); - $factory = new RecurrenceFactory; + /** @var RecurrenceFactory $factory */ + $factory = app(RecurrenceFactory::class); $factory->setUser($this->user()); $result = $factory->create($data); @@ -339,18 +167,20 @@ class RecurrenceFactoryTest extends TestCase /** * With piggy bank. With tags. With budget. With category. + * Submit account names, not types. This is a withdrawal. * * @covers \FireflyIII\Factory\RecurrenceFactory * @covers \FireflyIII\Services\Internal\Support\RecurringTransactionTrait */ - public function testBasicNoTags(): void + public function testCreateByName(): void { // objects to return: - $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); - $accountA = $this->user()->accounts()->inRandomOrder()->first(); - $accountB = $this->user()->accounts()->inRandomOrder()->first(); - $budget = $this->user()->budgets()->inRandomOrder()->first(); - $category = $this->user()->categories()->inRandomOrder()->first(); + $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); + $source = $this->getRandomAsset(); + $destination = $this->getRandomExpense(); + $budget = $this->user()->budgets()->inRandomOrder()->first(); + $category = $this->user()->categories()->inRandomOrder()->first(); + $euro = $this->getEuro(); // mock other factories: $piggyFactory = $this->mock(PiggyBankFactory::class); @@ -358,6 +188,230 @@ class RecurrenceFactoryTest extends TestCase $categoryFactory = $this->mock(CategoryFactory::class); $accountRepos = $this->mock(AccountRepositoryInterface::class); $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $typeFactory = $this->mock(TransactionTypeFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $validator = $this->mock(AccountValidator::class); + + // mock calls: + Amount::shouldReceive('getDefaultCurrencyByUser')->andReturn($euro)->once(); + $piggyFactory->shouldReceive('setUser')->atLeast()->once(); + $budgetFactory->shouldReceive('setUser')->atLeast()->once(); + $categoryFactory->shouldReceive('setUser')->once(); + $accountRepos->shouldReceive('setUser')->twice(); + //$accountFactory->shouldReceive('setUser')->atLeast()->once(); + + $piggyFactory->shouldReceive('find')->atLeast()->once()->withArgs([1, 'Bla bla'])->andReturn($piggyBank); + + // return NULL for account ID's. + $accountRepos->shouldReceive('findNull')->twice()->andReturn(null, null); + // but find them by name: + $accountRepos->shouldReceive('findByName')->twice()->andReturn($source, $destination); + + $currencyFactory->shouldReceive('find')->once()->withArgs([1, 'EUR'])->andReturn(null); + $currencyFactory->shouldReceive('find')->once()->withArgs([null, null])->andReturn(null); + $budgetFactory->shouldReceive('find')->withArgs([1, 'Some budget'])->once()->andReturn($budget); + $categoryFactory->shouldReceive('findOrCreate')->withArgs([2, 'Some category'])->once()->andReturn($category); + + // validator: + $validator->shouldReceive('setUser')->once(); + $validator->shouldReceive('setTransactionType')->atLeast()->once(); + $validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true); + + // data for basic recurrence. + $data = [ + 'recurrence' => [ + 'type' => 'withdrawal', + 'first_date' => Carbon::now()->addDay(), + 'repetitions' => 0, + 'title' => 'Test recurrence' . $this->randomInt(), + 'description' => 'Description thing', + 'apply_rules' => true, + 'active' => true, + 'repeat_until' => null, + ], + 'meta' => [ + 'tags' => ['a', 'b', 'c'], + 'piggy_bank_id' => 1, + 'piggy_bank_name' => 'Bla bla', + ], + 'repetitions' => [ + [ + 'type' => 'daily', + 'moment' => '', + 'skip' => 0, + 'weekend' => 1, + ], + ], + 'transactions' => [ + [ + 'source_id' => 1, + 'source_name' => 'Some name', + 'destination_id' => 2, + 'destination_name' => 'some other name', + 'currency_id' => 1, + 'currency_code' => 'EUR', + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'description' => 'Bla bla bla', + 'amount' => '100', + 'budget_id' => 1, + 'budget_name' => 'Some budget', + 'category_id' => 2, + 'category_name' => 'Some category', + + ], + ], + ]; + $typeFactory->shouldReceive('find')->once()->withArgs([ucfirst($data['recurrence']['type'])])->andReturn(TransactionType::find(1)); + /** @var RecurrenceFactory $factory */ + $factory = app(RecurrenceFactory::class); + $factory->setUser($this->user()); + + $result = $factory->create($data); + $this->assertEquals($result->title, $data['recurrence']['title']); + } + + /** + * With piggy bank. With tags. With budget. With category. + * Submit account names, not types. Also a withdrawal + * + * @covers \FireflyIII\Factory\RecurrenceFactory + * @covers \FireflyIII\Services\Internal\Support\RecurringTransactionTrait + */ + public function testCreateNewByName(): void + { + // objects to return: + $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); + $source = $this->getRandomAsset(); + $destination = $this->getRandomExpense(); + $budget = $this->user()->budgets()->inRandomOrder()->first(); + $category = $this->user()->categories()->inRandomOrder()->first(); + $euro = $this->getEuro(); + + // mock other factories: + $piggyFactory = $this->mock(PiggyBankFactory::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $typeFactory = $this->mock(TransactionTypeFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $validator = $this->mock(AccountValidator::class); + + // mock calls: + Amount::shouldReceive('getDefaultCurrencyByUser')->andReturn($euro)->once(); + $piggyFactory->shouldReceive('setUser')->atLeast()->once(); + $budgetFactory->shouldReceive('setUser')->atLeast()->once(); + $categoryFactory->shouldReceive('setUser')->once(); + + $accountRepos->shouldReceive('setUser')->twice(); + $piggyFactory->shouldReceive('find')->atLeast()->once()->withArgs([1, 'Bla bla'])->andReturn($piggyBank); + + // return NULL for account ID's. + $accountRepos->shouldReceive('findNull')->twice()->andReturn(null, null); + // but find them by name (at least the first one): + $accountRepos->shouldReceive('findByName')->twice()->andReturn($source, null); + + // this activates the "create by name" routine (account factory): + $accountFactory->shouldReceive('setUser')->atLeast()->once(); + $accountFactory->shouldReceive('findOrCreate')->atLeast()->once() + ->andReturn($destination); + + $currencyFactory->shouldReceive('find')->once()->withArgs([1, 'EUR'])->andReturn(null); + $currencyFactory->shouldReceive('find')->once()->withArgs([null, null])->andReturn(null); + + + $budgetFactory->shouldReceive('find')->withArgs([1, 'Some budget'])->once()->andReturn($budget); + $categoryFactory->shouldReceive('findOrCreate')->withArgs([2, 'Some category'])->once()->andReturn($category); + + // validator: + $validator->shouldReceive('setUser')->once(); + $validator->shouldReceive('setTransactionType')->atLeast()->once(); + $validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true); + + // data for basic recurrence. + $data = [ + 'recurrence' => [ + 'type' => 'withdrawal', + 'first_date' => Carbon::now()->addDay(), + 'repetitions' => 0, + 'title' => 'Test recurrence' . $this->randomInt(), + 'description' => 'Description thing', + 'apply_rules' => true, + 'active' => true, + 'repeat_until' => null, + ], + 'meta' => [ + 'tags' => ['a', 'b', 'c'], + 'piggy_bank_id' => 1, + 'piggy_bank_name' => 'Bla bla', + ], + 'repetitions' => [ + [ + 'type' => 'daily', + 'moment' => '', + 'skip' => 0, + 'weekend' => 1, + ], + ], + 'transactions' => [ + [ + 'source_id' => 1, + 'source_name' => 'Some name', + 'destination_id' => 2, + 'destination_name' => 'some other name', + 'currency_id' => 1, + 'currency_code' => 'EUR', + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'description' => 'Bla bla bla', + 'amount' => '100', + 'budget_id' => 1, + 'budget_name' => 'Some budget', + 'category_id' => 2, + 'category_name' => 'Some category', + + ], + ], + ]; + $typeFactory->shouldReceive('find')->once()->withArgs([ucfirst($data['recurrence']['type'])])->andReturn(TransactionType::find(1)); + /** @var RecurrenceFactory $factory */ + $factory = app(RecurrenceFactory::class); + $factory->setUser($this->user()); + + $result = $factory->create($data); + $this->assertEquals($result->title, $data['recurrence']['title']); + } + + + /** + * Deposit. With piggy bank. With tags. With budget. With category. + * + * @covers \FireflyIII\Factory\RecurrenceFactory + * @covers \FireflyIII\Services\Internal\Support\RecurringTransactionTrait + */ + public function testCreateDeposit(): void + { + // objects to return: + $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); + $source = $this->getRandomRevenue(); + $destination = $this->getRandomAsset(); + $budget = $this->user()->budgets()->inRandomOrder()->first(); + $category = $this->user()->categories()->inRandomOrder()->first(); + + // mock other factories: + $piggyFactory = $this->mock(PiggyBankFactory::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $typeFactory = $this->mock(TransactionTypeFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $validator = $this->mock(AccountValidator::class); // mock calls: Amount::shouldReceive('getDefaultCurrencyByUser')->andReturn(TransactionCurrency::find(1))->once(); @@ -365,7 +419,7 @@ class RecurrenceFactoryTest extends TestCase $piggyFactory->shouldReceive('find')->withArgs([1, 'Bla bla'])->andReturn($piggyBank); $accountRepos->shouldReceive('setUser')->twice(); - $accountRepos->shouldReceive('findNull')->twice()->andReturn($accountA, $accountB); + $accountRepos->shouldReceive('findNull')->twice()->andReturn($source, $destination); $currencyFactory->shouldReceive('find')->once()->withArgs([1, 'EUR'])->andReturn(null); $currencyFactory->shouldReceive('find')->once()->withArgs([null, null])->andReturn(null); @@ -376,13 +430,230 @@ class RecurrenceFactoryTest extends TestCase $categoryFactory->shouldReceive('setUser')->once(); $categoryFactory->shouldReceive('findOrCreate')->withArgs([2, 'Some category'])->once()->andReturn($category); + // validator: + $validator->shouldReceive('setUser')->once(); + $validator->shouldReceive('setTransactionType')->atLeast()->once(); + $validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true); + // data for basic recurrence. - $data = [ + $data = [ + 'recurrence' => [ + 'type' => 'deposit', + 'first_date' => Carbon::now()->addDay(), + 'repetitions' => 0, + 'title' => 'Test recurrence' . $this->randomInt(), + 'description' => 'Description thing', + 'apply_rules' => true, + 'active' => true, + 'repeat_until' => null, + ], + 'meta' => [ + 'tags' => ['a', 'b', 'c'], + 'piggy_bank_id' => 1, + 'piggy_bank_name' => 'Bla bla', + ], + 'repetitions' => [ + [ + 'type' => 'daily', + 'moment' => '', + 'skip' => 0, + 'weekend' => 1, + ], + ], + 'transactions' => [ + [ + 'source_id' => 1, + 'source_name' => 'Some name', + 'destination_id' => 2, + 'destination_name' => 'some otjer name', + 'currency_id' => 1, + 'currency_code' => 'EUR', + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'description' => 'Bla bla bla', + 'amount' => '100', + 'budget_id' => 1, + 'budget_name' => 'Some budget', + 'category_id' => 2, + 'category_name' => 'Some category', + + ], + ], + ]; + + + $typeFactory->shouldReceive('find')->once()->withArgs([ucfirst($data['recurrence']['type'])])->andReturn(TransactionType::find(2)); + + /** @var RecurrenceFactory $factory */ + $factory = app(RecurrenceFactory::class); + $factory->setUser($this->user()); + + $result = $factory->create($data); + $this->assertEquals($result->title, $data['recurrence']['title']); + } + + /** + * No piggy bank. With tags. With budget. With category. Withdrawal. + * + * @covers \FireflyIII\Factory\RecurrenceFactory + * @covers \FireflyIII\Services\Internal\Support\RecurringTransactionTrait + */ + public function testCreateNoPiggybank(): void + { + // objects to return: + $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); + $source = $this->getRandomAsset(); + $destination = $this->getRandomExpense(); + $budget = $this->user()->budgets()->inRandomOrder()->first(); + $category = $this->user()->categories()->inRandomOrder()->first(); + + // mock other factories: + $piggyFactory = $this->mock(PiggyBankFactory::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $typeFactory = $this->mock(TransactionTypeFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $validator = $this->mock(AccountValidator::class); + + // mock calls: + Amount::shouldReceive('getDefaultCurrencyByUser')->andReturn(TransactionCurrency::find(1))->once(); + $piggyFactory->shouldReceive('setUser')->once(); + $piggyFactory->shouldReceive('find')->withArgs([1, 'Bla bla'])->andReturn(null); + + $accountRepos->shouldReceive('setUser')->twice(); + $accountRepos->shouldReceive('findNull')->twice()->andReturn($source, $destination); + + $currencyFactory->shouldReceive('find')->once()->withArgs([1, 'EUR'])->andReturn(null); + $currencyFactory->shouldReceive('find')->once()->withArgs([null, null])->andReturn(null); + + $budgetFactory->shouldReceive('setUser')->once(); + $budgetFactory->shouldReceive('find')->withArgs([1, 'Some budget'])->once()->andReturn($budget); + + $categoryFactory->shouldReceive('setUser')->once(); + $categoryFactory->shouldReceive('findOrCreate')->withArgs([2, 'Some category'])->once()->andReturn($category); + + // validator: + $validator->shouldReceive('setUser')->once(); + $validator->shouldReceive('setTransactionType')->atLeast()->once(); + $validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true); + + // data for basic recurrence. + $data = [ 'recurrence' => [ 'type' => 'withdrawal', 'first_date' => Carbon::now()->addDay(), 'repetitions' => 0, - 'title' => 'Test recurrence' . random_int(1, 100000), + 'title' => 'Test recurrence' . $this->randomInt(), + 'description' => 'Description thing', + 'apply_rules' => true, + 'active' => true, + 'repeat_until' => null, + ], + 'meta' => [ + 'tags' => ['a', 'b', 'c'], + 'piggy_bank_id' => 1, + 'piggy_bank_name' => 'Bla bla', + ], + 'repetitions' => [ + [ + 'type' => 'daily', + 'moment' => '', + 'skip' => 0, + 'weekend' => 1, + ], + ], + 'transactions' => [ + [ + 'source_id' => 1, + 'source_name' => 'Some name', + 'destination_id' => 2, + 'destination_name' => 'some otjer name', + 'currency_id' => 1, + 'currency_code' => 'EUR', + 'foreign_currency_id' => null, + 'foreign_currency_code' => null, + 'foreign_amount' => null, + 'description' => 'Bla bla bla', + 'amount' => '100', + 'budget_id' => 1, + 'budget_name' => 'Some budget', + 'category_id' => 2, + 'category_name' => 'Some category', + + ], + ], + ]; + + $typeFactory->shouldReceive('find')->once()->withArgs([ucfirst($data['recurrence']['type'])])->andReturn(TransactionType::find(1)); + /** @var RecurrenceFactory $factory */ + $factory = app(RecurrenceFactory::class); + $factory->setUser($this->user()); + + $result = $factory->create($data); + $this->assertEquals($result->title, $data['recurrence']['title']); + } + + /** + * With piggy bank. With tags. With budget. With category. Withdrawal + * + * @covers \FireflyIII\Factory\RecurrenceFactory + * @covers \FireflyIII\Services\Internal\Support\RecurringTransactionTrait + */ + public function testCreateNoTags(): void + { + // objects to return: + $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); + $source = $this->getRandomAsset(); + $destination = $this->getRandomExpense(); + $budget = $this->user()->budgets()->inRandomOrder()->first(); + $category = $this->user()->categories()->inRandomOrder()->first(); + + // mock other factories: + $piggyFactory = $this->mock(PiggyBankFactory::class); + $budgetFactory = $this->mock(BudgetFactory::class); + $categoryFactory = $this->mock(CategoryFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $typeFactory = $this->mock(TransactionTypeFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $validator = $this->mock(AccountValidator::class); + + // mock calls: + Amount::shouldReceive('getDefaultCurrencyByUser')->andReturn(TransactionCurrency::find(1))->once(); + $piggyFactory->shouldReceive('setUser')->once(); + $piggyFactory->shouldReceive('find')->withArgs([1, 'Bla bla'])->andReturn($piggyBank); + + $accountRepos->shouldReceive('setUser')->twice(); + $accountRepos->shouldReceive('findNull')->twice()->andReturn($source, $destination); + + $currencyFactory->shouldReceive('find')->once()->withArgs([1, 'EUR'])->andReturn(null); + $currencyFactory->shouldReceive('find')->once()->withArgs([null, null])->andReturn(null); + + $budgetFactory->shouldReceive('setUser')->once(); + $budgetFactory->shouldReceive('find')->withArgs([1, 'Some budget'])->once()->andReturn($budget); + + $categoryFactory->shouldReceive('setUser')->once(); + $categoryFactory->shouldReceive('findOrCreate')->withArgs([2, 'Some category'])->once()->andReturn($category); + + + // validator: + $validator->shouldReceive('setUser')->once(); + $validator->shouldReceive('setTransactionType')->atLeast()->once(); + $validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true); + + // data for basic recurrence. + $data = [ + 'recurrence' => [ + 'type' => 'withdrawal', + 'first_date' => Carbon::now()->addDay(), + 'repetitions' => 0, + 'title' => 'Test recurrence' . $this->randomInt(), 'description' => 'Description thing', 'apply_rules' => true, 'active' => true, @@ -422,9 +693,10 @@ class RecurrenceFactoryTest extends TestCase ], ], ]; - $typeFactory = $this->mock(TransactionTypeFactory::class); + $typeFactory->shouldReceive('find')->once()->withArgs([ucfirst($data['recurrence']['type'])])->andReturn(TransactionType::find(1)); - $factory = new RecurrenceFactory; + /** @var RecurrenceFactory $factory */ + $factory = app(RecurrenceFactory::class); $factory->setUser($this->user()); $result = $factory->create($data); @@ -437,14 +709,15 @@ class RecurrenceFactoryTest extends TestCase * @covers \FireflyIII\Factory\RecurrenceFactory * @covers \FireflyIII\Services\Internal\Support\RecurringTransactionTrait */ - public function testBasicTransfer(): void + public function testCreateTransfer(): void { // objects to return: - $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); - $accountA = $this->user()->accounts()->inRandomOrder()->first(); - $accountB = $this->user()->accounts()->inRandomOrder()->first(); - $budget = $this->user()->budgets()->inRandomOrder()->first(); - $category = $this->user()->categories()->inRandomOrder()->first(); + $piggyBank = $this->user()->piggyBanks()->inRandomOrder()->first(); + $source = $this->getRandomAsset(); + $destination = $this->getRandomAsset($source->id); + $budget = $this->user()->budgets()->inRandomOrder()->first(); + $category = $this->user()->categories()->inRandomOrder()->first(); + $validator = $this->mock(AccountValidator::class); // mock other factories: $piggyFactory = $this->mock(PiggyBankFactory::class); @@ -452,6 +725,8 @@ class RecurrenceFactoryTest extends TestCase $categoryFactory = $this->mock(CategoryFactory::class); $accountRepos = $this->mock(AccountRepositoryInterface::class); $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $typeFactory = $this->mock(TransactionTypeFactory::class); + $accountFactory = $this->mock(AccountFactory::class); // mock calls: Amount::shouldReceive('getDefaultCurrencyByUser')->andReturn(TransactionCurrency::find(1))->once(); @@ -459,7 +734,7 @@ class RecurrenceFactoryTest extends TestCase $piggyFactory->shouldReceive('find')->withArgs([1, 'Bla bla'])->andReturn($piggyBank); $accountRepos->shouldReceive('setUser')->twice(); - $accountRepos->shouldReceive('findNull')->twice()->andReturn($accountA, $accountB); + $accountRepos->shouldReceive('findNull')->twice()->andReturn($source, $destination); $currencyFactory->shouldReceive('find')->once()->withArgs([1, 'EUR'])->andReturn(null); $currencyFactory->shouldReceive('find')->once()->withArgs([null, null])->andReturn(null); @@ -470,13 +745,19 @@ class RecurrenceFactoryTest extends TestCase $categoryFactory->shouldReceive('setUser')->once(); $categoryFactory->shouldReceive('findOrCreate')->withArgs([2, 'Some category'])->once()->andReturn($category); + // validator: + $validator->shouldReceive('setUser')->once(); + $validator->shouldReceive('setTransactionType')->atLeast()->once(); + $validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true); + // data for basic recurrence. $data = [ 'recurrence' => [ 'type' => 'transfer', 'first_date' => Carbon::now()->addDay(), 'repetitions' => 0, - 'title' => 'Test recurrence' . random_int(1, 100000), + 'title' => 'Test recurrence' . $this->randomInt(), 'description' => 'Description thing', 'apply_rules' => true, 'active' => true, @@ -517,10 +798,12 @@ class RecurrenceFactoryTest extends TestCase ], ]; - $typeFactory = $this->mock(TransactionTypeFactory::class); + $typeFactory->shouldReceive('find')->once()->withArgs([ucfirst($data['recurrence']['type'])])->andReturn(TransactionType::find(3)); - $factory = new RecurrenceFactory; + /** @var RecurrenceFactory $factory */ + $factory = app(RecurrenceFactory::class); + $factory->setUser($this->user()); $result = $factory->create($data); @@ -532,17 +815,21 @@ class RecurrenceFactoryTest extends TestCase */ public function testCreateBadTransactionType(): void { - $data = [ + $accountFactory = $this->mock(AccountFactory::class); + $validator = $this->mock(AccountValidator::class); + $typeFactory = $this->mock(TransactionTypeFactory::class); + $data = [ 'recurrence' => [ 'type' => 'bad type', ], ]; - $typeFactory = $this->mock(TransactionTypeFactory::class); + $typeFactory->shouldReceive('find')->once()->withArgs([ucfirst($data['recurrence']['type'])])->andReturn(null); - $factory = new RecurrenceFactory; + /** @var RecurrenceFactory $factory */ + $factory = app(RecurrenceFactory::class); $factory->setUser($this->user()); $result = $factory->create($data); diff --git a/tests/Unit/Factory/TagFactoryTest.php b/tests/Unit/Factory/TagFactoryTest.php index 76985d5468..8b5e61e437 100644 --- a/tests/Unit/Factory/TagFactoryTest.php +++ b/tests/Unit/Factory/TagFactoryTest.php @@ -62,7 +62,7 @@ class TagFactoryTest extends TestCase */ public function testFindOrCreateNew(): void { - $tag = 'Some new tag#' . random_int(1, 10000); + $tag = sprintf('Some new tag #%d', $this->randomInt()); /** @var TagFactory $factory */ $factory = app(TagFactory::class); $factory->setUser($this->user()); diff --git a/tests/Unit/Factory/TransactionFactoryTest.php b/tests/Unit/Factory/TransactionFactoryTest.php index 9e426e3ecc..2bd9947045 100644 --- a/tests/Unit/Factory/TransactionFactoryTest.php +++ b/tests/Unit/Factory/TransactionFactoryTest.php @@ -24,13 +24,7 @@ declare(strict_types=1); namespace Tests\Unit\Factory; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\TransactionFactory; -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Support\NullArrayObject; use Log; use Tests\TestCase; @@ -52,752 +46,130 @@ class TransactionFactoryTest extends TestCase /** * @covers \FireflyIII\Factory\TransactionFactory */ - public function testCreateBasic(): void + public function testCreateNegative(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - // data used in calls. $journal = $this->getRandomWithdrawal(); $account = $this->getRandomAsset(); - $euro = TransactionCurrency::whereCode('EUR')->first(); + $euro = $this->getEuro(); $amount = '10'; - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - /** @var TransactionFactory $factory */ $factory = app(TransactionFactory::class); + + + // set details: $factory->setUser($this->user()); $factory->setJournal($journal); - $transaction = $factory->create($account, $euro, $amount); + $factory->setAccount($account); + $factory->setCurrency($euro); + $factory->setReconciled(false); + + // create negative + $transaction = $factory->createNegative($amount, null); $this->assertEquals($transaction->account_id, $account->id); + $this->assertEquals('-10', $transaction->amount); + $transaction->forceDelete(); } /** * @covers \FireflyIII\Factory\TransactionFactory */ - public function testCreateNull(): void + public function testCreatePositive(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - // data used in calls. $journal = $this->getRandomWithdrawal(); - $account = new Account; - $euro = TransactionCurrency::whereCode('EUR')->first(); + $account = $this->getRandomAsset(); + $euro = $this->getEuro(); $amount = '10'; - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - /** @var TransactionFactory $factory */ $factory = app(TransactionFactory::class); + + + // set details: $factory->setUser($this->user()); $factory->setJournal($journal); - $transaction = $factory->create($account, $euro, $amount); + $factory->setAccount($account); + $factory->setCurrency($euro); + $factory->setReconciled(false); - $this->assertNull($transaction); + // create positive + $transaction = $factory->createPositive($amount, null); + + $this->assertEquals($transaction->account_id, $account->id); + $this->assertEquals('10', $transaction->amount); + $transaction->forceDelete(); } /** * @covers \FireflyIII\Factory\TransactionFactory */ - public function testCreatePair(): void + public function testCreateNegativeForeign(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // used objects - $withdrawal = $this->getRandomWithdrawal(); - $asset = $this->getRandomAsset(); - $expense = $this->getRandomExpense(); - $currency = TransactionCurrency::whereCode('EUR')->first(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('findNull')->withArgs([1])->once()->andReturn($asset); - $accountRepos->shouldReceive('findByName')->withArgs(['Some destination', [AccountType::EXPENSE]])->once()->andReturn($expense); - - - $data = new NullArrayObject( - [ - 'source_id' => 1, - 'destination_name' => 'Some destination', - 'amount' => '20', - ] - ); - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - $pairs = $factory->createPair($data, $currency, null); - $first = $pairs->first(); - $this->assertCount(2, $pairs); - $this->assertEquals('-20', $first->amount); - $this->assertEquals($currency->id, $first->transaction_currency_id); - } - - /** - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testCreatePairForeign(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // used objects: - $withdrawal = $this->getRandomWithdrawal(); - $expense = $this->getRandomExpense(); - $asset = $this->getRandomAsset(); - $currency = TransactionCurrency::whereCode('EUR')->first(); - $foreign = TransactionCurrency::whereCode('USD')->first(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('findNull')->withArgs([1])->once()->andReturn($asset); - $accountRepos->shouldReceive('findByName')->withArgs(['Some destination', [AccountType::EXPENSE]])->once()->andReturn($expense); - - - $data = new NullArrayObject( - [ - 'source_id' => 1, - 'destination_name' => 'Some destination', - 'amount' => '20', - 'foreign_amount' => '20', - ] - ); - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - $pairs = $factory->createPair($data, $currency, $foreign); - $first = $pairs->first(); - $this->assertCount(2, $pairs); - $this->assertEquals('-20', $first->amount); - $this->assertEquals($currency->id, $first->transaction_currency_id); - $this->assertEquals($foreign->id, $first->foreign_currency_id); - } - - /** - * To cover everything, test several combinations. - * - * For the source account, submit a Deposit and an Revenue account ID (this is OK). - * Expected result: the same revenue account. - * - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testDepositSourceAsseRevenueId(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data used in calls. - $deposit = $this->getRandomDeposit(); - $revenue = $this->getRandomRevenue(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('findNull')->once()->withArgs([$revenue->id])->andReturn($revenue); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($deposit); - - $result = $factory->getAccount('source', null, $revenue->id, null); - $this->assertEquals($revenue->id, $result->id); - } - - /** - * To cover everything, test several combinations. - * - * For the source account, submit a Deposit and nothing else (this is OK). - * Expected result: a cash account - * - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testDepositSourceRevenueCash(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data used in calls. - $deposit = $this->getRandomDeposit(); - $revenue = $this->getRandomRevenue(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($revenue); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($deposit); - - $result = $factory->getAccount('source', null, null, null); - $this->assertEquals($revenue->name, $result->name); - } - - /** - * To cover everything, test several combinations. - * - * For the source account, submit a Deposit and an Revenue account name (this is OK). - * Expected result: a new revenue account. - * - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testDepositSourceRevenueNameNew(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data used in calls. - $deposit = $this->getRandomDeposit(); - $name = 'random rev name ' . random_int(1, 100000); - $revenue = $this->getRandomRevenue(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('findByName')->once()->withArgs([$name, [AccountType::REVENUE]])->andReturnNull(); - // system will automatically expand search: - $accountRepos->shouldReceive('findByName')->once()->withArgs( - [$name, [AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE, AccountType::INITIAL_BALANCE, - AccountType::RECONCILIATION]] - )->andReturnNull(); - - // then store new account: - $accountRepos->shouldReceive('store')->once()->withArgs( - [[ - 'account_type_id' => null, - 'accountType' => AccountType::REVENUE, - 'name' => $name, - 'active' => true, - 'iban' => null, - ]] - )->andReturn($revenue); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($deposit); - - $result = $factory->getAccount('source', null, null, $name); - $this->assertEquals($revenue->name, $result->name); - } - - /** - * @throws FireflyException - */ - public function testDramaBasic(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - $withdrawal = $this->getRandomWithdrawal(); - $source = $withdrawal->transactions()->where('amount', '<', 0)->first(); - $dest = $withdrawal->transactions()->where('amount', '>', 0)->first(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - $factory->makeDramaOverAccountTypes($source->account, $dest->account); - } - - /** - * @throws FireflyException - */ - public function testDramaNotAllowed(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - $withdrawal = $this->getRandomWithdrawal(); - - // this is an asset account. - $source = $withdrawal->transactions()->where('amount', '<', 0)->first(); - // so destiny cannot be also asset account - $dest = $this->getRandomAsset(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - try { - $factory->makeDramaOverAccountTypes($source->account, $dest); - } catch (FireflyException $e) { - $this->assertEquals( - 'Journal of type "Withdrawal" has a source account of type "Asset account" and cannot accept a "Asset account"-account as destination, but only accounts of: Expense account, Loan, Debt, Mortgage', - $e->getMessage() - ); - } - } - - /** - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testGetAmountBasic(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - $amount = '10'; // data used in calls. $journal = $this->getRandomWithdrawal(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); + $account = $this->getRandomAsset(); + $euro = $this->getEuro(); + $dollar = $this->getDollar(); + $amount = '10'; /** @var TransactionFactory $factory */ $factory = app(TransactionFactory::class); + + + // set details: $factory->setUser($this->user()); $factory->setJournal($journal); + $factory->setAccount($account); + $factory->setCurrency($euro); + $factory->setForeignCurrency($dollar); + $factory->setReconciled(false); - $result = $factory->getAmount($amount); - $this->assertEquals($amount, $result); + // create negative + $transaction = $factory->createNegative($amount, $amount); + + $this->assertEquals($transaction->account_id, $account->id); + $this->assertEquals('-10', $transaction->amount); + $this->assertEquals('-10', $transaction->foreign_amount); + $this->assertEquals($euro->id, $transaction->transaction_currency_id); + $this->assertEquals($dollar->id, $transaction->foreign_currency_id); + $transaction->forceDelete(); } /** * @covers \FireflyIII\Factory\TransactionFactory */ - public function testGetAmountNull(): void + public function testCreatePositiveForeign(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $amount = ''; // data used in calls. $journal = $this->getRandomWithdrawal(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); + $account = $this->getRandomAsset(); + $euro = $this->getEuro(); + $dollar = $this->getDollar(); + $amount = '10'; /** @var TransactionFactory $factory */ $factory = app(TransactionFactory::class); + + + // set details: $factory->setUser($this->user()); $factory->setJournal($journal); + $factory->setAccount($account); + $factory->setCurrency($euro); + $factory->setForeignCurrency($dollar); + $factory->setReconciled(false); - try { - $factory->getAmount($amount); - } catch (FireflyException $e) { - $this->assertEquals('The amount cannot be an empty string: ""', $e->getMessage()); - } + // create positive + $transaction = $factory->createPositive($amount, $amount); + $this->assertEquals($transaction->account_id, $account->id); + $this->assertEquals('10', $transaction->amount); + $this->assertEquals('10', $transaction->foreign_amount); + $this->assertEquals($euro->id, $transaction->transaction_currency_id); + $this->assertEquals($dollar->id, $transaction->foreign_currency_id); + + $transaction->forceDelete(); } - - /** - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testGetAmountZero(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $amount = '0.0'; - // data used in calls. - $journal = $this->getRandomWithdrawal(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($journal); - - try { - $factory->getAmount($amount); - } catch (FireflyException $e) { - $this->assertEquals('The amount seems to be zero: "0.0"', $e->getMessage()); - } - } - - /** - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testGetForeignAmountBasic(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $amount = '10'; - // data used in calls. - $journal = $this->getRandomWithdrawal(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($journal); - - $result = $factory->getForeignAmount($amount); - $this->assertEquals($amount, $result); - } - - /** - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testGetForeignAmountEmpty(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $amount = ''; - // data used in calls. - $journal = $this->getRandomWithdrawal(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($journal); - - $result = $factory->getForeignAmount($amount); - $this->assertNull($result); - } - - /** - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testGetForeignAmountNull(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $amount = null; - // data used in calls. - $journal = $this->getRandomWithdrawal(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($journal); - - $result = $factory->getForeignAmount($amount); - $this->assertNull($result); - } - - /** - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testGetForeignAmountZero(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $amount = '0.0'; - // data used in calls. - $journal = $this->getRandomWithdrawal(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($journal); - - $result = $factory->getForeignAmount($amount); - $this->assertNull($result); - } - - /** - * To cover everything, test several combinations. - * - * For the source account, submit a Withdrawal and an Asset account ID (this is OK). - * Expected result: the same asset account. - * - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testWithdrawalSourceAssetId(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data used in calls. - $withdrawal = $this->getRandomWithdrawal(); - $asset = $this->getRandomAsset(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('findNull')->once()->withArgs([$asset->id])->andReturn($asset); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - - $result = $factory->getAccount('source', null, $asset->id, null); - $this->assertEquals($asset->id, $result->id); - } - - /** - * To cover everything, test several combinations. - * - * For the source account, submit a Withdrawal and an Asset account ID (this is OK). - * Expected result: find won't return anything so we expect a big fat error. - * - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testWithdrawalSourceAssetIdNOK(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data used in calls. - $withdrawal = $this->getRandomWithdrawal(); - $asset = $this->getRandomAsset(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('findNull')->once()->withArgs([$asset->id])->andReturn($asset); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - - try { - $factory->getAccount('source', null, $asset->id, null); - } catch (FireflyException $e) { - $this->assertEquals('TransactionFactory: Cannot create asset account with ID #0 or name "(no name)".', $e->getMessage()); - } - } - - /** - * To cover everything, test several combinations. - * - * For the source account, submit a Withdrawal and an Asset account name (this is OK). - * Expected result: the same asset account. - * - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testWithdrawalSourceAssetName(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data used in calls. - $withdrawal = $this->getRandomWithdrawal(); - $asset = $this->getRandomAsset(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('findByName')->once()->withArgs([$asset->name, [AccountType::ASSET]])->andReturn($asset); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - - $result = $factory->getAccount('source', null, null, $asset->name); - $this->assertEquals($asset->id, $result->id); - } - - /** - * To cover everything, test several combinations. - * - * For the source account, submit a Withdrawal and an Asset account name (this is OK). - * Expected result: the same asset account. - * - * This will initially return NULL and then search again with all possible types. - * - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testWithdrawalSourceAssetName2(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data used in calls. - $withdrawal = $this->getRandomWithdrawal(); - $asset = $this->getRandomAsset(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('findByName')->once()->withArgs([$asset->name, [AccountType::ASSET]])->andReturnNull(); - $accountRepos->shouldReceive('findByName')->once()->withArgs( - [$asset->name, [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]] - )->andReturn($asset); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - - $result = $factory->getAccount('source', null, null, $asset->name); - $this->assertEquals($asset->id, $result->id); - } - - /** - * To cover everything, test several combinations. - * - * For the source account, submit a Withdrawal and an Asset account object (this is OK). - * Expected result: the same asset account. - * - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testWithdrawalSourceAssetObj(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data used in calls. - $withdrawal = $this->getRandomWithdrawal(); - $asset = $this->getRandomAsset(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - - $result = $factory->getAccount('source', $asset, null, null); - $this->assertEquals($asset->id, $result->id); - } - - /** - * To cover everything, test several combinations. - * - * For the source account, submit a Withdrawal and an Expense account object (this is not OK). - * Expected result: big fat error because of missing data. - * - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testWithdrawalSourceAssetObjNOK(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data used in calls. - $withdrawal = $this->getRandomWithdrawal(); - $expense = $this->getRandomExpense(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - try { - $factory->getAccount('source', $expense, null, null); - } catch (FireflyException $e) { - $this->assertEquals('TransactionFactory: Cannot create asset account with ID #0 or name "(no name)".', $e->getMessage()); - } - } - - /** - * To cover everything, test several combinations. - * - * For the source account, submit a Withdrawal and Loan account object (this is OK). - * Expected result: the same loan account. - * - * @covers \FireflyIII\Factory\TransactionFactory - */ - public function testWithdrawalSourceLoanObj(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock classes - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data used in calls. - $withdrawal = $this->getRandomWithdrawal(); - $loan = $this->getRandomLoan(); - - // mock calls. - $accountRepos->shouldReceive('setUser')->once(); - - /** @var TransactionFactory $factory */ - $factory = app(TransactionFactory::class); - $factory->setUser($this->user()); - $factory->setJournal($withdrawal); - - $result = $factory->getAccount('source', $loan, null, null); - $this->assertEquals($loan->id, $result->id); - } - - } diff --git a/tests/Unit/Factory/TransactionJournalFactoryTest.php b/tests/Unit/Factory/TransactionJournalFactoryTest.php index 76af2dc139..77c66be79a 100644 --- a/tests/Unit/Factory/TransactionJournalFactoryTest.php +++ b/tests/Unit/Factory/TransactionJournalFactoryTest.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace Tests\Unit\Factory; +use Amount; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\AccountFactory; use FireflyIII\Factory\PiggyBankEventFactory; use FireflyIII\Factory\TagFactory; @@ -31,14 +33,8 @@ use FireflyIII\Factory\TransactionCurrencyFactory; use FireflyIII\Factory\TransactionFactory; use FireflyIII\Factory\TransactionJournalFactory; use FireflyIII\Factory\TransactionJournalMetaFactory; -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\Budget; -use FireflyIII\Models\Category; -use FireflyIII\Models\PiggyBank; -use FireflyIII\Models\Tag; -use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Models\TransactionGroup; +use FireflyIII\Models\PiggyBankEvent; +use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; @@ -67,920 +63,1712 @@ class TransactionJournalFactoryTest extends TestCase } /** + * Submit empty array. * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait */ - public function testBudget(): void + public function testCreate(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock used repositories. - $billRepos = $this->mock(BillRepositoryInterface::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $catRepos = $this->mock(CategoryRepositoryInterface::class); - $curRepos = $this->mock(CurrencyRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); - $eventFactory = $this->mock(PiggyBankEventFactory::class); - $tagFactory = $this->mock(TagFactory::class); - $accountFactory = $this->mock(AccountFactory::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - $metaFactory = $this->mock(TransactionJournalMetaFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data to return from various calls: - $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); - $euro = TransactionCurrency::whereCode('EUR')->first(); - $usd = TransactionCurrency::whereCode('USD')->first(); - $asset = $this->getRandomAsset(); - $expense = $this->getRandomExpense(); - $budget = Budget::first(); - - // data to submit. - $data = [ - 'transactions' => [ - // first transaction: - [ - 'source_id' => $asset->id, - 'amount' => '1', - 'foreign_currency_code' => 'USD', - 'foreign_amount' => '2', - 'notes' => 'I am some notes', - 'budget_id' => $budget->id, - ], - ], - ]; - - // calls to setUser: - $curRepos->shouldReceive('setUser')->once(); - $billRepos->shouldReceive('setUser')->once(); - $budgetRepos->shouldReceive('setUser')->once(); - $catRepos->shouldReceive('setUser')->once(); - $piggyRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('setUser')->once(); - $tagFactory->shouldReceive('setUser')->once(); - - // calls to transaction type repository. - $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); - - // calls to the currency repository: - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, 'USD'])->once()->andReturn($usd); - - // calls to the bill repository: - $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the budget repository - $budgetRepos->shouldReceive('findBudget')->withArgs([null, $budget->id, null])->once()->andReturn($budget); - - // calls to the category repository - $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the account repository - $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); - $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); - - // calls to the meta factory: - $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); - - - /** @var TransactionJournalFactory $factory */ - $factory = app(TransactionJournalFactory::class); - $factory->setUser($this->user()); - $collection = $factory->create($data); - - /** @var TransactionJournal $journal */ - $journal = $collection->first(); - // collection should have one journal. - $this->assertCount(1, $collection); - $this->assertInstanceOf(TransactionJournal::class, $journal); - $this->assertEquals('(empty description)', $journal->description); - $this->assertCount(1, $journal->budgets); - $this->assertCount(0, $journal->categories); - $this->assertCount(2, $journal->transactions); - $this->assertEquals('I am some notes', $journal->notes->first()->text); - $this->assertEquals('EUR', $journal->transactions->first()->transactionCurrency->code); - $this->assertEquals('USD', $journal->transactions->first()->foreignCurrency->code); - } - - /** - * @covers \FireflyIII\Factory\TransactionJournalFactory - */ - public function testCategory(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock used repositories. - $billRepos = $this->mock(BillRepositoryInterface::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $catRepos = $this->mock(CategoryRepositoryInterface::class); - $curRepos = $this->mock(CurrencyRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); - $eventFactory = $this->mock(PiggyBankEventFactory::class); - $tagFactory = $this->mock(TagFactory::class); - $accountFactory = $this->mock(AccountFactory::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - $metaFactory = $this->mock(TransactionJournalMetaFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data to return from various calls: - $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); - $euro = TransactionCurrency::whereCode('EUR')->first(); - $usd = TransactionCurrency::whereCode('USD')->first(); - $asset = $this->getRandomAsset(); - $category = Category::first(); - $expense = $this->getRandomExpense(); - $budget = Budget::first(); - - // data to submit. - $data = [ - 'transactions' => [ - // first transaction: - [ - 'source_id' => $asset->id, - 'amount' => '1', - 'foreign_currency_code' => 'USD', - 'foreign_amount' => '2', - 'notes' => 'I am some notes', - 'budget_id' => $budget->id, - 'category_name' => $category->name, - ], - ], - ]; - - // calls to setUser: - $curRepos->shouldReceive('setUser')->once(); - $billRepos->shouldReceive('setUser')->once(); - $budgetRepos->shouldReceive('setUser')->once(); - $catRepos->shouldReceive('setUser')->once(); - $piggyRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('setUser')->once(); - $tagFactory->shouldReceive('setUser')->once(); - - // calls to transaction type repository. - $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); - - // calls to the currency repository: - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, 'USD'])->once()->andReturn($usd); - - // calls to the bill repository: - $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the budget repository - $budgetRepos->shouldReceive('findBudget')->withArgs([null, $budget->id, null])->once()->andReturn($budget); - - // calls to the category repository - $catRepos->shouldReceive('findCategory')->withArgs([null, null, $category->name])->once()->andReturn($category); - - // calls to the account repository - $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); - $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); - - // calls to the meta factory: - $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); - - - /** @var TransactionJournalFactory $factory */ - $factory = app(TransactionJournalFactory::class); - $factory->setUser($this->user()); - $collection = $factory->create($data); - - /** @var TransactionJournal $journal */ - $journal = $collection->first(); - // collection should have one journal. - $this->assertCount(1, $collection); - $this->assertInstanceOf(TransactionJournal::class, $journal); - $this->assertEquals('(empty description)', $journal->description); - $this->assertCount(1, $journal->budgets); - $this->assertCount(1, $journal->categories); - $this->assertCount(2, $journal->transactions); - $this->assertEquals('I am some notes', $journal->notes->first()->text); - $this->assertEquals('EUR', $journal->transactions->first()->transactionCurrency->code); - $this->assertEquals('USD', $journal->transactions->first()->foreignCurrency->code); - } - - /** - * @covers \FireflyIII\Factory\TransactionJournalFactory - */ - public function testCreateAlmostEmpty(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock used repositories. - $billRepos = $this->mock(BillRepositoryInterface::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $catRepos = $this->mock(CategoryRepositoryInterface::class); - $curRepos = $this->mock(CurrencyRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); - $eventFactory = $this->mock(PiggyBankEventFactory::class); - $tagFactory = $this->mock(TagFactory::class); - $accountFactory = $this->mock(AccountFactory::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - $metaFactory = $this->mock(TransactionJournalMetaFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data to return from various calls: - $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); - $euro = TransactionCurrency::whereCode('EUR')->first(); - $asset = $this->getRandomAsset(); - $expense = $this->getRandomExpense(); - - // data to submit. - $data = [ - 'transactions' => [ - // first transaction: - [ - 'source_id' => $asset->id, - 'amount' => '1', - ], - ], - ]; - - // calls to setUser: - $curRepos->shouldReceive('setUser')->once(); - $billRepos->shouldReceive('setUser')->once(); - $budgetRepos->shouldReceive('setUser')->once(); - $catRepos->shouldReceive('setUser')->once(); - $piggyRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('setUser')->once(); - $tagFactory->shouldReceive('setUser')->once(); - - // calls to transaction type repository. - $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); - - // calls to the currency repository: - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); - - // calls to the bill repository: - $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the budget repository - $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the category repository - $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the account repository - $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); - $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); - - // calls to the meta factory: - $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); - - - /** @var TransactionJournalFactory $factory */ - $factory = app(TransactionJournalFactory::class); - $factory->setUser($this->user()); - $collection = $factory->create($data); - - /** @var TransactionJournal $journal */ - $journal = $collection->first(); - // collection should have one journal. - $this->assertCount(1, $collection); - $this->assertInstanceOf(TransactionJournal::class, $journal); - $this->assertEquals('(empty description)', $journal->description); - $this->assertCount(0, $journal->budgets); - $this->assertCount(0, $journal->categories); - $this->assertCount(2, $journal->transactions); - } - - /** - * @covers \FireflyIII\Factory\TransactionJournalFactory - */ - public function testCreateAlmostEmptyTransfer(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock used repositories. - $billRepos = $this->mock(BillRepositoryInterface::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $catRepos = $this->mock(CategoryRepositoryInterface::class); - $curRepos = $this->mock(CurrencyRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); - $eventFactory = $this->mock(PiggyBankEventFactory::class); - $tagFactory = $this->mock(TagFactory::class); - $accountFactory = $this->mock(AccountFactory::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - $metaFactory = $this->mock(TransactionJournalMetaFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data to return from various calls: - $type = TransactionType::whereType(TransactionType::TRANSFER)->first(); - $euro = TransactionCurrency::whereCode('EUR')->first(); - $source = $this->getRandomAsset(); - $destination = $this->getAnotherRandomAsset($source->id); - - // data to submit. - $data = [ - 'type' => 'transfer', - 'transactions' => [ - // first transaction: - [ - 'source_id' => $source->id, - 'destination_id' => $destination->id, - 'amount' => '1', - ], - ], - ]; - - // calls to setUser: - $curRepos->shouldReceive('setUser')->once(); - $billRepos->shouldReceive('setUser')->once(); - $budgetRepos->shouldReceive('setUser')->once(); - $catRepos->shouldReceive('setUser')->once(); - $piggyRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('setUser')->once(); - $tagFactory->shouldReceive('setUser')->once(); - - // calls to transaction type repository. - $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'transfer'])->once()->andReturn($type); - - // calls to the currency repository: - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); - - // calls to the bill repository: - $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the budget repository - $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the category repository - $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the piggy bank repository: - $piggyRepos->shouldReceive('findPiggyBank')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the account repository - $accountRepos->shouldReceive('findNull')->withArgs([$source->id])->once()->andReturn($source); - $accountRepos->shouldReceive('findNull')->withArgs([$destination->id])->once()->andReturn($destination); - - // calls to the meta factory: - $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); - - /** @var TransactionJournalFactory $factory */ - $factory = app(TransactionJournalFactory::class); - $factory->setUser($this->user()); - $collection = $factory->create($data); - - /** @var TransactionJournal $journal */ - $journal = $collection->first(); - // collection should have one journal. - $this->assertCount(1, $collection); - $this->assertInstanceOf(TransactionJournal::class, $journal); - $this->assertEquals('(empty description)', $journal->description); - $this->assertCount(0, $journal->budgets); - $this->assertCount(0, $journal->categories); - $this->assertCount(2, $journal->transactions); - } - - /** - * @covers \FireflyIII\Factory\TransactionJournalFactory - */ - public function testCreateBasicGroup(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock used repositories. - $billRepos = $this->mock(BillRepositoryInterface::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $catRepos = $this->mock(CategoryRepositoryInterface::class); - $curRepos = $this->mock(CurrencyRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); - $eventFactory = $this->mock(PiggyBankEventFactory::class); - $tagFactory = $this->mock(TagFactory::class); - $accountFactory = $this->mock(AccountFactory::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - $metaFactory = $this->mock(TransactionJournalMetaFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data to return from various calls: - $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); - $euro = TransactionCurrency::whereCode('EUR')->first(); - $asset = $this->getRandomAsset(); - $expense = $this->getRandomExpense(); - - // data to submit. - $data = [ - 'transactions' => [ - // first transaction: - [ - 'source_id' => $asset->id, - 'amount' => '1', - ], - // second transaction: - [ - 'source_id' => $asset->id, - 'amount' => '1', - ], - ], - ]; - - // calls to setUser: - $curRepos->shouldReceive('setUser')->once(); - $billRepos->shouldReceive('setUser')->once(); - $budgetRepos->shouldReceive('setUser')->once(); - $catRepos->shouldReceive('setUser')->once(); - $piggyRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('setUser')->once(); - $tagFactory->shouldReceive('setUser')->times(2); - - // calls to transaction type repository. - $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); - - // calls to the currency repository: - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->times(2)->andReturn($euro); - - // calls to the bill repository: - $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->times(2)->andReturnNull(); - - // calls to the budget repository - $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->times(2)->andReturnNull(); - - // calls to the category repository - $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->times(2)->andReturnNull(); - - // calls to the account repository - $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->times(2)->andReturn($asset); - $accountRepos->shouldReceive('getCashAccount')->times(2)->andReturn($expense); - - // calls to the meta factory: - $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); - - /** @var TransactionJournalFactory $factory */ - $factory = app(TransactionJournalFactory::class); - $factory->setUser($this->user()); - $collection = $factory->create($data); - - /** @var TransactionJournal $journal */ - $journal = $collection->first(); - - // collection should have two journals. - $this->assertCount(2, $collection); - - // journal should have some props. - $this->assertInstanceOf(TransactionJournal::class, $journal); - $this->assertEquals('(empty description)', $journal->description); - $this->assertCount(0, $journal->budgets); - $this->assertCount(0, $journal->categories); - $this->assertCount(2, $journal->transactions); - - // group of journal should also have some props. - /** @var TransactionGroup $group */ - $group = $journal->transactionGroups()->first(); - $this->assertCount(2, $group->transactionJournals); - $this->assertEquals($journal->description, $group->title); - } - - /** - * @covers \FireflyIII\Factory\TransactionJournalFactory - */ - public function testCreateEmpty(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock used repositories. $billRepos = $this->mock(BillRepositoryInterface::class); $budgetRepos = $this->mock(BudgetRepositoryInterface::class); $catRepos = $this->mock(CategoryRepositoryInterface::class); $curRepos = $this->mock(CurrencyRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + $tagFactory = $this->mock(TagFactory::class); $transactionFactory = $this->mock(TransactionFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); $eventFactory = $this->mock(PiggyBankEventFactory::class); - $tagFactory = $this->mock(TagFactory::class); $accountFactory = $this->mock(AccountFactory::class); $currencyFactory = $this->mock(TransactionCurrencyFactory::class); $metaFactory = $this->mock(TransactionJournalMetaFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); + $submission = []; - // data to return from various calls: - $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); - - // data to submit. - $data = []; - - // calls to setUser: - $curRepos->shouldReceive('setUser')->once(); - $transactionFactory->shouldReceive('setUser')->once(); - $billRepos->shouldReceive('setUser')->once(); - $budgetRepos->shouldReceive('setUser')->once(); - $catRepos->shouldReceive('setUser')->once(); - $piggyRepos->shouldReceive('setUser')->once(); - - // calls to transaction type repository. - $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); + // mock calls to all repositories + $curRepos->shouldReceive('setUser')->atLeast()->once(); + $billRepos->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $catRepos->shouldReceive('setUser')->atLeast()->once(); + $piggyRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); + $tagFactory->shouldReceive('setUser')->atLeast()->once(); + $transactionFactory->shouldReceive('setUser')->atLeast()->once(); /** @var TransactionJournalFactory $factory */ $factory = app(TransactionJournalFactory::class); $factory->setUser($this->user()); - $collection = $factory->create($data); + try { + $collection = $factory->create($submission); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } $this->assertCount(0, $collection); } /** + * Submit minimal array for a withdrawal. * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait */ - public function testCreatePiggyEvent(): void + public function testCreateWithdrawal(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $catRepos = $this->mock(CategoryRepositoryInterface::class); + $curRepos = $this->mock(CurrencyRepositoryInterface::class); + $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + $tagFactory = $this->mock(TagFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); + $eventFactory = $this->mock(PiggyBankEventFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $metaFactory = $this->mock(TransactionJournalMetaFactory::class); + $transactionFactory = $this->mock(TransactionFactory::class); - return; - // mock used repositories. - $billRepos = $this->mock(BillRepositoryInterface::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $catRepos = $this->mock(CategoryRepositoryInterface::class); - $curRepos = $this->mock(CurrencyRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); - $eventFactory = $this->mock(PiggyBankEventFactory::class); - $tagFactory = $this->mock(TagFactory::class); - $accountFactory = $this->mock(AccountFactory::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - $metaFactory = $this->mock(TransactionJournalMetaFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - // data to return from various calls: - $type = TransactionType::whereType(TransactionType::TRANSFER)->first(); - $euro = TransactionCurrency::whereCode('EUR')->first(); - $piggyBank = PiggyBank::first(); - $source = $this->getRandomAsset(); - $destination = $this->getAnotherRandomAsset($source->id); - - // data to submit. - $data = [ - 'type' => 'transfer', + // data + $withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first(); + $asset = $this->getRandomAsset(); + $expense = $this->getRandomExpense(); + $euro = $this->getEuro(); + $submission = [ 'transactions' => [ - // first transaction: [ - 'source_id' => $source->id, - 'destination_id' => $destination->id, - 'amount' => '1', - 'piggy_bank_id' => '1', - 'piggy_bank_name' => 'Some name', + 'type' => 'withdrawal', + 'amount' => '10', + 'description' => sprintf('I am a test #%d', $this->randomInt()), + 'source_id' => $asset->id, + 'destination_id' => $expense->id, ], ], ]; - // calls to setUser: - $curRepos->shouldReceive('setUser')->once(); - $billRepos->shouldReceive('setUser')->once(); - $budgetRepos->shouldReceive('setUser')->once(); - $catRepos->shouldReceive('setUser')->once(); - $piggyRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('setUser')->once(); - $tagFactory->shouldReceive('setUser')->once(); - // calls to transaction type repository. - $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'transfer'])->once()->andReturn($type); + // mock calls to all repositories + $curRepos->shouldReceive('setUser')->atLeast()->once(); + $billRepos->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $catRepos->shouldReceive('setUser')->atLeast()->once(); + $piggyRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); + $tagFactory->shouldReceive('setUser')->atLeast()->once(); + $transactionFactory->shouldReceive('setUser')->atLeast()->once(); - // calls to the currency repository: - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); + $transactionFactory->shouldReceive('setJournal')->atLeast()->once(); + $transactionFactory->shouldReceive('setAccount')->atLeast()->once(); + $transactionFactory->shouldReceive('setCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setForeignCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setReconciled')->atLeast()->once(); + $transactionFactory->shouldReceive('createNegative')->atLeast()->once()->andReturn(new Transaction); + $transactionFactory->shouldReceive('createPositive')->atLeast()->once()->andReturn(new Transaction); - // calls to the bill repository: - $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the budget repository - $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the category repository - $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the piggy bank repository: - $piggyRepos->shouldReceive('findPiggyBank')->withArgs([null, 1, 'Some name'])->once()->andReturn($piggyBank); - - // calls to the piggy factory - $eventFactory->shouldReceive('create')->once()->andReturnNull(); - - // calls to the account repository - $accountRepos->shouldReceive('findNull')->withArgs([$source->id])->once()->andReturn($source); - $accountRepos->shouldReceive('findNull')->withArgs([$destination->id])->once()->andReturn($destination); - - // calls to the meta factory: - $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); - - /** @var TransactionJournalFactory $factory */ - $factory = app(TransactionJournalFactory::class); - $factory->setUser($this->user()); - $collection = $factory->create($data); - - /** @var TransactionJournal $journal */ - $journal = $collection->first(); - // collection should have one journal. - $this->assertCount(1, $collection); - $this->assertInstanceOf(TransactionJournal::class, $journal); - $this->assertEquals('(empty description)', $journal->description); - $this->assertCount(0, $journal->budgets); - $this->assertCount(0, $journal->categories); - $this->assertCount(2, $journal->transactions); - } - - /** - * @covers \FireflyIII\Factory\TransactionJournalFactory - */ - public function testForeignCurrency(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock used repositories. - $billRepos = $this->mock(BillRepositoryInterface::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $catRepos = $this->mock(CategoryRepositoryInterface::class); - $curRepos = $this->mock(CurrencyRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); - $eventFactory = $this->mock(PiggyBankEventFactory::class); - $tagFactory = $this->mock(TagFactory::class); - $accountFactory = $this->mock(AccountFactory::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - $metaFactory = $this->mock(TransactionJournalMetaFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data to return from various calls: - $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); - $euro = TransactionCurrency::whereCode('EUR')->first(); - $usd = TransactionCurrency::whereCode('USD')->first(); - $asset = $this->getRandomAsset(); - $expense = $this->getRandomExpense(); - - // data to submit. - $data = [ - 'transactions' => [ - // first transaction: - [ - 'source_id' => $asset->id, - 'amount' => '1', - 'foreign_currency_code' => 'USD', - 'foreign_amount' => '2', - 'notes' => 'I am some notes', - ], - ], - ]; - - // calls to setUser: - $curRepos->shouldReceive('setUser')->once(); - $billRepos->shouldReceive('setUser')->once(); - $budgetRepos->shouldReceive('setUser')->once(); - $catRepos->shouldReceive('setUser')->once(); - $piggyRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('setUser')->once(); - $tagFactory->shouldReceive('setUser')->once(); - - // calls to transaction type repository. - $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); - - // calls to the currency repository: - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, 'USD'])->once()->andReturn($usd); - - // calls to the bill repository: - $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the budget repository - $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the category repository - $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the account repository - $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); - $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); - - // calls to the meta factory: - $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); + $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'withdrawal'])->atLeast()->once()->andReturn($withdrawal); + $curRepos->shouldReceive('findCurrency')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $curRepos->shouldReceive('findCurrencyNull')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $billRepos->shouldReceive('findBill')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->atLeast()->once()->andReturn($asset); + $accountRepos->shouldReceive('findNull')->withArgs([$expense->id])->atLeast()->once()->andReturn($expense); + $accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro); + $budgetRepos->shouldReceive('findBudget')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $catRepos->shouldReceive('findCategory')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once(); /** @var TransactionJournalFactory $factory */ $factory = app(TransactionJournalFactory::class); $factory->setUser($this->user()); - $collection = $factory->create($data); - /** @var TransactionJournal $journal */ - $journal = $collection->first(); - // collection should have one journal. + try { + $collection = $factory->create($submission); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } $this->assertCount(1, $collection); - $this->assertInstanceOf(TransactionJournal::class, $journal); - $this->assertEquals('(empty description)', $journal->description); - $this->assertCount(0, $journal->budgets); - $this->assertCount(0, $journal->categories); - $this->assertCount(2, $journal->transactions); - $this->assertEquals('I am some notes', $journal->notes->first()->text); - $this->assertEquals('EUR', $journal->transactions->first()->transactionCurrency->code); - $this->assertEquals('USD', $journal->transactions->first()->foreignCurrency->code); + /** @var TransactionJournal $first */ + $first = $collection->first(); + $this->assertEquals($first->description, $submission['transactions'][0]['description']); + $first->forceDelete(); } + /** + * Submit minimal array for a deposit. * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait */ - public function testNotes(): void + public function testCreateDeposit(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $catRepos = $this->mock(CategoryRepositoryInterface::class); + $curRepos = $this->mock(CurrencyRepositoryInterface::class); + $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + $tagFactory = $this->mock(TagFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); + $eventFactory = $this->mock(PiggyBankEventFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $metaFactory = $this->mock(TransactionJournalMetaFactory::class); + $transactionFactory = $this->mock(TransactionFactory::class); - return; - // mock used repositories. - $billRepos = $this->mock(BillRepositoryInterface::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $catRepos = $this->mock(CategoryRepositoryInterface::class); - $curRepos = $this->mock(CurrencyRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); - $eventFactory = $this->mock(PiggyBankEventFactory::class); - $tagFactory = $this->mock(TagFactory::class); - $accountFactory = $this->mock(AccountFactory::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - $metaFactory = $this->mock(TransactionJournalMetaFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - // data to return from various calls: - $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); - $euro = TransactionCurrency::whereCode('EUR')->first(); - $asset = $this->getRandomAsset(); - $expense = $this->getRandomExpense(); - - // data to submit. - $data = [ + // data + $withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first(); + $deposit = TransactionType::where('type', TransactionType::DEPOSIT)->first(); + $asset = $this->getRandomAsset(); + $expense = $this->getRandomExpense(); + $revenue = $this->getRandomRevenue(); + $euro = $this->getEuro(); + $submission = [ 'transactions' => [ - // first transaction: [ - 'source_id' => $asset->id, - 'amount' => '1', - 'notes' => 'I am some notes', + 'type' => 'deposit', + 'amount' => '10', + 'description' => sprintf('I am a test #%d', $this->randomInt()), + 'source_id' => $revenue->id, + 'destination_id' => $asset->id, ], ], ]; - // calls to setUser: - $curRepos->shouldReceive('setUser')->once(); - $billRepos->shouldReceive('setUser')->once(); - $budgetRepos->shouldReceive('setUser')->once(); - $catRepos->shouldReceive('setUser')->once(); - $piggyRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('setUser')->once(); - $tagFactory->shouldReceive('setUser')->once(); - // calls to transaction type repository. - $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); + // mock calls to all repositories + $curRepos->shouldReceive('setUser')->atLeast()->once(); + $billRepos->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $catRepos->shouldReceive('setUser')->atLeast()->once(); + $piggyRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); + $tagFactory->shouldReceive('setUser')->atLeast()->once(); + $transactionFactory->shouldReceive('setUser')->atLeast()->once(); - // calls to the currency repository: - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); + $transactionFactory->shouldReceive('setJournal')->atLeast()->once(); + $transactionFactory->shouldReceive('setAccount')->atLeast()->once(); + $transactionFactory->shouldReceive('setCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setForeignCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setReconciled')->atLeast()->once(); + $transactionFactory->shouldReceive('createNegative')->atLeast()->once()->andReturn(new Transaction); + $transactionFactory->shouldReceive('createPositive')->atLeast()->once()->andReturn(new Transaction); - // calls to the bill repository: - $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the budget repository - $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the category repository - $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the account repository - $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); - $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); - - // calls to the meta factory: - $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); + $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'deposit'])->atLeast()->once()->andReturn($deposit); + $curRepos->shouldReceive('findCurrency')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $curRepos->shouldReceive('findCurrencyNull')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $billRepos->shouldReceive('findBill')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $accountRepos->shouldReceive('findNull')->withArgs([$revenue->id])->atLeast()->once()->andReturn($revenue); + $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->atLeast()->once()->andReturn($asset); + $accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro); + $catRepos->shouldReceive('findCategory')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once(); /** @var TransactionJournalFactory $factory */ $factory = app(TransactionJournalFactory::class); $factory->setUser($this->user()); - $collection = $factory->create($data); - /** @var TransactionJournal $journal */ - $journal = $collection->first(); - // collection should have one journal. + try { + $collection = $factory->create($submission); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } $this->assertCount(1, $collection); - $this->assertInstanceOf(TransactionJournal::class, $journal); - $this->assertEquals('(empty description)', $journal->description); - $this->assertCount(0, $journal->budgets); - $this->assertCount(0, $journal->categories); - $this->assertCount(2, $journal->transactions); - $this->assertEquals('I am some notes', $journal->notes->first()->text); + /** @var TransactionJournal $first */ + $first = $collection->first(); + $this->assertEquals($first->description, $submission['transactions'][0]['description']); + $first->forceDelete(); } - /** - * @covers \FireflyIII\Factory\TransactionJournalFactory - */ - public function testTags(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock used repositories. - $billRepos = $this->mock(BillRepositoryInterface::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $catRepos = $this->mock(CategoryRepositoryInterface::class); - $curRepos = $this->mock(CurrencyRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); - $eventFactory = $this->mock(PiggyBankEventFactory::class); - $tagFactory = $this->mock(TagFactory::class); - $accountFactory = $this->mock(AccountFactory::class); - $currencyFactory = $this->mock(TransactionCurrencyFactory::class); - $metaFactory = $this->mock(TransactionJournalMetaFactory::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // data to return from various calls: - $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); - $euro = TransactionCurrency::whereCode('EUR')->first(); - $asset = $this->getRandomAsset(); - $expense = $this->getRandomExpense(); - $tag = Tag::first(); - - // data to submit. - $data = [ - 'transactions' => [ - // first transaction: - [ - 'source_id' => $asset->id, - 'amount' => '1', - 'tags' => ['tagA', 'B', '', 'C'], - ], - ], - ]; - - // calls to setUser: - $curRepos->shouldReceive('setUser')->once(); - $billRepos->shouldReceive('setUser')->once(); - $budgetRepos->shouldReceive('setUser')->once(); - $catRepos->shouldReceive('setUser')->once(); - $piggyRepos->shouldReceive('setUser')->once(); - $accountRepos->shouldReceive('setUser')->once(); - $tagFactory->shouldReceive('setUser')->once(); - - // calls to transaction type repository. - $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); - - // calls to the currency repository: - $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); - - // calls to the bill repository: - $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the budget repository - $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the category repository - $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); - - // calls to the account repository - $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); - $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); - - // calls to tag factory - $tagFactory->shouldReceive('findOrCreate')->once()->withArgs(['tagA'])->andReturn($tag); - $tagFactory->shouldReceive('findOrCreate')->once()->withArgs(['B'])->andReturn($tag); - $tagFactory->shouldReceive('findOrCreate')->once()->withArgs(['C'])->andReturnNull(); - - // calls to the meta factory: - $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); - - /** @var TransactionJournalFactory $factory */ - $factory = app(TransactionJournalFactory::class); - $factory->setUser($this->user()); - $collection = $factory->create($data); - - /** @var TransactionJournal $journal */ - $journal = $collection->first(); - // collection should have one journal. - $this->assertCount(1, $collection); - $this->assertInstanceOf(TransactionJournal::class, $journal); - $this->assertEquals('(empty description)', $journal->description); - $this->assertCount(0, $journal->budgets); - $this->assertCount(0, $journal->categories); - $this->assertCount(2, $journal->transactions); - $this->assertCount(1, $journal->tags); // we return the same tag every time. - } /** - * @param int $id + * Submit array for a withdrawal. Include tag info. * - * @return Account + * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait */ - private function getAnotherRandomAsset(int $id): Account + public function testCreateWithdrawalTags(): void { + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $catRepos = $this->mock(CategoryRepositoryInterface::class); + $curRepos = $this->mock(CurrencyRepositoryInterface::class); + $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + $tagFactory = $this->mock(TagFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); + $eventFactory = $this->mock(PiggyBankEventFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $metaFactory = $this->mock(TransactionJournalMetaFactory::class); + $transactionFactory = $this->mock(TransactionFactory::class); - $query = Account:: - leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') - ->whereNull('accounts.deleted_at') - ->where('accounts.user_id', $this->user()->id) - ->where('account_types.type', AccountType::ASSET) - ->where('accounts.id', '!=', $id) - ->inRandomOrder()->take(1); - return $query->first(['accounts.*']); + // data + $withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first(); + $asset = $this->getRandomAsset(); + $tag = $this->user()->tags()->inRandomOrder()->first(); + $expense = $this->getRandomExpense(); + $euro = $this->getEuro(); + $submission = [ + 'transactions' => [ + [ + 'type' => 'withdrawal', + 'amount' => '10', + 'description' => sprintf('I am a test #%d', $this->randomInt()), + 'source_id' => $asset->id, + 'destination_id' => $expense->id, + 'tags' => ['a'], + ], + ], + ]; + + + // mock calls to all repositories + $curRepos->shouldReceive('setUser')->atLeast()->once(); + $billRepos->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $catRepos->shouldReceive('setUser')->atLeast()->once(); + $piggyRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); + $tagFactory->shouldReceive('setUser')->atLeast()->once(); + $transactionFactory->shouldReceive('setUser')->atLeast()->once(); + + $transactionFactory->shouldReceive('setJournal')->atLeast()->once(); + $transactionFactory->shouldReceive('setAccount')->atLeast()->once(); + $transactionFactory->shouldReceive('setCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setForeignCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setReconciled')->atLeast()->once(); + $transactionFactory->shouldReceive('createNegative')->atLeast()->once()->andReturn(new Transaction); + $transactionFactory->shouldReceive('createPositive')->atLeast()->once()->andReturn(new Transaction); + + $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'withdrawal'])->atLeast()->once()->andReturn($withdrawal); + $curRepos->shouldReceive('findCurrency')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $curRepos->shouldReceive('findCurrencyNull')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $billRepos->shouldReceive('findBill')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->atLeast()->once()->andReturn($asset); + $accountRepos->shouldReceive('findNull')->withArgs([$expense->id])->atLeast()->once()->andReturn($expense); + $accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro); + $budgetRepos->shouldReceive('findBudget')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $catRepos->shouldReceive('findCategory')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once(); + $tagFactory->shouldReceive('findOrCreate')->atLeast()->once()->andReturn($tag); + + + /** @var TransactionJournalFactory $factory */ + $factory = app(TransactionJournalFactory::class); + $factory->setUser($this->user()); + + try { + $collection = $factory->create($submission); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + $this->assertCount(1, $collection); + /** @var TransactionJournal $first */ + $first = $collection->first(); + $this->assertEquals($first->description, $submission['transactions'][0]['description']); + $first->forceDelete(); } + + /** + * Submit minimal array for a withdrawal. + * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait + */ + public function testCreateWithdrawalNote(): void + { + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $catRepos = $this->mock(CategoryRepositoryInterface::class); + $curRepos = $this->mock(CurrencyRepositoryInterface::class); + $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + $tagFactory = $this->mock(TagFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); + $eventFactory = $this->mock(PiggyBankEventFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $metaFactory = $this->mock(TransactionJournalMetaFactory::class); + $transactionFactory = $this->mock(TransactionFactory::class); + + + // data + $withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first(); + $asset = $this->getRandomAsset(); + $expense = $this->getRandomExpense(); + $euro = $this->getEuro(); + $submission = [ + 'transactions' => [ + [ + 'type' => 'withdrawal', + 'amount' => '10', + 'description' => sprintf('I am a test #%d', $this->randomInt()), + 'source_id' => $asset->id, + 'destination_id' => $expense->id, + 'notes' => 'I am a note', + ], + ], + ]; + + + // mock calls to all repositories + $curRepos->shouldReceive('setUser')->atLeast()->once(); + $billRepos->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $catRepos->shouldReceive('setUser')->atLeast()->once(); + $piggyRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); + $tagFactory->shouldReceive('setUser')->atLeast()->once(); + $transactionFactory->shouldReceive('setUser')->atLeast()->once(); + + $transactionFactory->shouldReceive('setJournal')->atLeast()->once(); + $transactionFactory->shouldReceive('setAccount')->atLeast()->once(); + $transactionFactory->shouldReceive('setCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setForeignCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setReconciled')->atLeast()->once(); + $transactionFactory->shouldReceive('createNegative')->atLeast()->once()->andReturn(new Transaction); + $transactionFactory->shouldReceive('createPositive')->atLeast()->once()->andReturn(new Transaction); + + $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'withdrawal'])->atLeast()->once()->andReturn($withdrawal); + $curRepos->shouldReceive('findCurrency')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $curRepos->shouldReceive('findCurrencyNull')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $billRepos->shouldReceive('findBill')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->atLeast()->once()->andReturn($asset); + $accountRepos->shouldReceive('findNull')->withArgs([$expense->id])->atLeast()->once()->andReturn($expense); + $accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro); + $budgetRepos->shouldReceive('findBudget')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $catRepos->shouldReceive('findCategory')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once(); + + + /** @var TransactionJournalFactory $factory */ + $factory = app(TransactionJournalFactory::class); + $factory->setUser($this->user()); + + try { + $collection = $factory->create($submission); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + $this->assertCount(1, $collection); + /** @var TransactionJournal $first */ + $first = $collection->first(); + $this->assertEquals($first->description, $submission['transactions'][0]['description']); + $this->assertCount(1, $first->notes()->get()); + $first->forceDelete(); + } + + /** + * Submit array for a withdrawal. + * + * Include budget, category. + * + * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait + */ + public function testCreateWithdrawalMeta(): void + { + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $catRepos = $this->mock(CategoryRepositoryInterface::class); + $curRepos = $this->mock(CurrencyRepositoryInterface::class); + $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + $tagFactory = $this->mock(TagFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); + $eventFactory = $this->mock(PiggyBankEventFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $metaFactory = $this->mock(TransactionJournalMetaFactory::class); + $transactionFactory = $this->mock(TransactionFactory::class); + + + // data + $withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first(); + $asset = $this->getRandomAsset(); + $expense = $this->getRandomExpense(); + $budget = $this->user()->budgets()->inRandomOrder()->first(); + $category = $this->user()->categories()->inRandomOrder()->first(); + $euro = $this->getEuro(); + $submission = [ + 'transactions' => [ + [ + 'type' => 'withdrawal', + 'amount' => '10', + 'description' => sprintf('I am a test #%d', $this->randomInt()), + 'source_id' => $asset->id, + 'budget_id' => $budget->id, + 'category_id' => $category->id, + 'destination_id' => $expense->id, + ], + ], + ]; + + + // mock calls to all repositories + $curRepos->shouldReceive('setUser')->atLeast()->once(); + $billRepos->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $catRepos->shouldReceive('setUser')->atLeast()->once(); + $piggyRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); + $tagFactory->shouldReceive('setUser')->atLeast()->once(); + $transactionFactory->shouldReceive('setUser')->atLeast()->once(); + + $transactionFactory->shouldReceive('setJournal')->atLeast()->once(); + $transactionFactory->shouldReceive('setAccount')->atLeast()->once(); + $transactionFactory->shouldReceive('setCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setForeignCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setReconciled')->atLeast()->once(); + $transactionFactory->shouldReceive('createNegative')->atLeast()->once()->andReturn(new Transaction); + $transactionFactory->shouldReceive('createPositive')->atLeast()->once()->andReturn(new Transaction); + + $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'withdrawal'])->atLeast()->once()->andReturn($withdrawal); + $curRepos->shouldReceive('findCurrency')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $curRepos->shouldReceive('findCurrencyNull')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $billRepos->shouldReceive('findBill')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->atLeast()->once()->andReturn($asset); + $accountRepos->shouldReceive('findNull')->withArgs([$expense->id])->atLeast()->once()->andReturn($expense); + $accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro); + $budgetRepos->shouldReceive('findBudget')->withArgs([$budget->id, null])->atLeast()->once()->andReturn($budget); + $catRepos->shouldReceive('findCategory')->withArgs([$category->id, null])->atLeast()->once()->andReturn($category); + $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once(); + + + /** @var TransactionJournalFactory $factory */ + $factory = app(TransactionJournalFactory::class); + $factory->setUser($this->user()); + + try { + $collection = $factory->create($submission); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + $this->assertCount(1, $collection); + /** @var TransactionJournal $first */ + $first = $collection->first(); + $this->assertEquals($first->description, $submission['transactions'][0]['description']); + $first->forceDelete(); + } + + /** + * Submit minimal array for a withdrawal. + * Includes piggy bank data, but the piggy bank is invalid. + * + * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait + */ + public function testCreateTransferInvalidPiggie(): void + { + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $catRepos = $this->mock(CategoryRepositoryInterface::class); + $curRepos = $this->mock(CurrencyRepositoryInterface::class); + $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + $tagFactory = $this->mock(TagFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); + $eventFactory = $this->mock(PiggyBankEventFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $metaFactory = $this->mock(TransactionJournalMetaFactory::class); + $transactionFactory = $this->mock(TransactionFactory::class); + + + // data + $transfer = TransactionType::where('type', TransactionType::TRANSFER)->first(); + $asset = $this->getRandomAsset(); + $otherAsset = $this->getRandomAsset($asset->id); + $euro = $this->getEuro(); + $piggy = $this->user()->piggyBanks()->inRandomOrder()->first(); + $submission = [ + 'transactions' => [ + [ + 'type' => 'transfer', + 'amount' => '10', + 'description' => sprintf('I am a test #%d', $this->randomInt()), + 'source_id' => $asset->id, + 'destination_id' => $otherAsset->id, + 'piggy_bank_id' => $piggy->id, + ], + ], + ]; + + + // mock calls to all repositories + $curRepos->shouldReceive('setUser')->atLeast()->once(); + $billRepos->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $catRepos->shouldReceive('setUser')->atLeast()->once(); + $piggyRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); + $tagFactory->shouldReceive('setUser')->atLeast()->once(); + $transactionFactory->shouldReceive('setUser')->atLeast()->once(); + + $transactionFactory->shouldReceive('setJournal')->atLeast()->once(); + $transactionFactory->shouldReceive('setAccount')->atLeast()->once(); + $transactionFactory->shouldReceive('setCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setForeignCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setReconciled')->atLeast()->once(); + $transactionFactory->shouldReceive('createNegative')->atLeast()->once()->andReturn(new Transaction); + $transactionFactory->shouldReceive('createPositive')->atLeast()->once()->andReturn(new Transaction); + + $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'transfer'])->atLeast()->once()->andReturn($transfer); + $curRepos->shouldReceive('findCurrency')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $curRepos->shouldReceive('findCurrencyNull')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $billRepos->shouldReceive('findBill')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->atLeast()->once()->andReturn($asset); + $accountRepos->shouldReceive('findNull')->withArgs([$otherAsset->id])->atLeast()->once()->andReturn($otherAsset); + $accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro); + $catRepos->shouldReceive('findCategory')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once(); + $piggyRepos->shouldReceive('findPiggyBank')->withArgs([$piggy->id, null])->atLeast()->once()->andReturn(null); + + + /** @var TransactionJournalFactory $factory */ + $factory = app(TransactionJournalFactory::class); + $factory->setUser($this->user()); + + try { + $collection = $factory->create($submission); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + $this->assertCount(1, $collection); + /** @var TransactionJournal $first */ + $first = $collection->first(); + $this->assertEquals($first->description, $submission['transactions'][0]['description']); + $first->forceDelete(); + } + + + /** + * Submit minimal array for a withdrawal. + * Includes piggy bank data. + * + * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait + */ + public function testCreateTransfer(): void + { + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $catRepos = $this->mock(CategoryRepositoryInterface::class); + $curRepos = $this->mock(CurrencyRepositoryInterface::class); + $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + $tagFactory = $this->mock(TagFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); + $eventFactory = $this->mock(PiggyBankEventFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $metaFactory = $this->mock(TransactionJournalMetaFactory::class); + $transactionFactory = $this->mock(TransactionFactory::class); + + + // data + $transfer = TransactionType::where('type', TransactionType::TRANSFER)->first(); + $asset = $this->getRandomAsset(); + $otherAsset = $this->getRandomAsset($asset->id); + $euro = $this->getEuro(); + $piggy = $this->user()->piggyBanks()->inRandomOrder()->first(); + $submission = [ + 'transactions' => [ + [ + 'type' => 'transfer', + 'amount' => '10', + 'description' => sprintf('I am a test #%d', $this->randomInt()), + 'source_id' => $asset->id, + 'destination_id' => $otherAsset->id, + 'piggy_bank_id' => $piggy->id, + ], + ], + ]; + + + // mock calls to all repositories + $curRepos->shouldReceive('setUser')->atLeast()->once(); + $billRepos->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $catRepos->shouldReceive('setUser')->atLeast()->once(); + $piggyRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); + $tagFactory->shouldReceive('setUser')->atLeast()->once(); + $transactionFactory->shouldReceive('setUser')->atLeast()->once(); + + $transactionFactory->shouldReceive('setJournal')->atLeast()->once(); + $transactionFactory->shouldReceive('setAccount')->atLeast()->once(); + $transactionFactory->shouldReceive('setCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setForeignCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setReconciled')->atLeast()->once(); + $transactionFactory->shouldReceive('createNegative')->atLeast()->once()->andReturn(new Transaction); + $transactionFactory->shouldReceive('createPositive')->atLeast()->once()->andReturn(new Transaction); + + $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'transfer'])->atLeast()->once()->andReturn($transfer); + $curRepos->shouldReceive('findCurrency')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $curRepos->shouldReceive('findCurrencyNull')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $billRepos->shouldReceive('findBill')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->atLeast()->once()->andReturn($asset); + $accountRepos->shouldReceive('findNull')->withArgs([$otherAsset->id])->atLeast()->once()->andReturn($otherAsset); + $accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro); + $catRepos->shouldReceive('findCategory')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once(); + $piggyRepos->shouldReceive('findPiggyBank')->withArgs([$piggy->id, null])->atLeast()->once()->andReturn($piggy); + $eventFactory->shouldReceive('create')->atLeast()->once()->andReturn(new PiggyBankEvent); + + + /** @var TransactionJournalFactory $factory */ + $factory = app(TransactionJournalFactory::class); + $factory->setUser($this->user()); + + try { + $collection = $factory->create($submission); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + $this->assertCount(1, $collection); + /** @var TransactionJournal $first */ + $first = $collection->first(); + $this->assertEquals($first->description, $submission['transactions'][0]['description']); + $first->forceDelete(); + } + + + /** + * Submit minimal array for a withdrawal. + * Includes piggy bank data. + * Includes foreign amounts but foreign currency is missing or invalid. + * Will be solved by getting users default currency. + * + * @covers \FireflyIII\Factory\TransactionJournalFactory + * @covers \FireflyIII\Services\Internal\Support\JournalServiceTrait + */ + public function testCreateTransferForeign(): void + { + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $catRepos = $this->mock(CategoryRepositoryInterface::class); + $curRepos = $this->mock(CurrencyRepositoryInterface::class); + $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + $tagFactory = $this->mock(TagFactory::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); + $eventFactory = $this->mock(PiggyBankEventFactory::class); + $accountFactory = $this->mock(AccountFactory::class); + $currencyFactory = $this->mock(TransactionCurrencyFactory::class); + $metaFactory = $this->mock(TransactionJournalMetaFactory::class); + $transactionFactory = $this->mock(TransactionFactory::class); + + + // data + $transfer = TransactionType::where('type', TransactionType::TRANSFER)->first(); + $asset = $this->getRandomAsset(); + $otherAsset = $this->getRandomAsset($asset->id); + $euro = $this->getEuro(); + $piggy = $this->user()->piggyBanks()->inRandomOrder()->first(); + $submission = [ + 'transactions' => [ + [ + 'type' => 'transfer', + 'amount' => '10', + 'foreign_amount' => '10', + 'description' => sprintf('I am a test #%d', $this->randomInt()), + 'source_id' => $asset->id, + 'destination_id' => $otherAsset->id, + 'piggy_bank_id' => $piggy->id, + ], + ], + ]; + + + // mock calls to all repositories + $curRepos->shouldReceive('setUser')->atLeast()->once(); + $billRepos->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $catRepos->shouldReceive('setUser')->atLeast()->once(); + $piggyRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); + $tagFactory->shouldReceive('setUser')->atLeast()->once(); + $transactionFactory->shouldReceive('setUser')->atLeast()->once(); + + Amount::shouldReceive('getDefaultCurrencyByUser')->atLeast()->once()->andReturn($euro); + + $transactionFactory->shouldReceive('setJournal')->atLeast()->once(); + $transactionFactory->shouldReceive('setAccount')->atLeast()->once(); + $transactionFactory->shouldReceive('setCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setForeignCurrency')->atLeast()->once(); + $transactionFactory->shouldReceive('setReconciled')->atLeast()->once(); + $transactionFactory->shouldReceive('createNegative')->atLeast()->once()->andReturn(new Transaction); + $transactionFactory->shouldReceive('createPositive')->atLeast()->once()->andReturn(new Transaction); + + $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'transfer'])->atLeast()->once()->andReturn($transfer); + $curRepos->shouldReceive('findCurrency')->atLeast()->once()->withArgs([0, null])->andReturn($euro); + $curRepos->shouldReceive('findCurrencyNull')->atLeast()->once()->withArgs([0, null])->andReturnNull(); + $billRepos->shouldReceive('findBill')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->atLeast()->once()->andReturn($asset); + $accountRepos->shouldReceive('findNull')->withArgs([$otherAsset->id])->atLeast()->once()->andReturn($otherAsset); + $accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro, null); + $catRepos->shouldReceive('findCategory')->withArgs([0, null])->atLeast()->once()->andReturnNull(); + $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once(); + $piggyRepos->shouldReceive('findPiggyBank')->withArgs([$piggy->id, null])->atLeast()->once()->andReturn($piggy); + $eventFactory->shouldReceive('create')->atLeast()->once()->andReturn(new PiggyBankEvent); + + + /** @var TransactionJournalFactory $factory */ + $factory = app(TransactionJournalFactory::class); + $factory->setUser($this->user()); + + try { + $collection = $factory->create($submission); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + + return; + } + $this->assertCount(1, $collection); + /** @var TransactionJournal $first */ + $first = $collection->first(); + $this->assertEquals($first->description, $submission['transactions'][0]['description']); + $first->forceDelete(); + } + + + +// +// /** +// * @covers \FireflyIII\Factory\TransactionJournalFactory +// */ +// public function testBudget(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// // mock used repositories. +// $billRepos = $this->mock(BillRepositoryInterface::class); +// $budgetRepos = $this->mock(BudgetRepositoryInterface::class); +// $catRepos = $this->mock(CategoryRepositoryInterface::class); +// $curRepos = $this->mock(CurrencyRepositoryInterface::class); +// $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); +// $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); +// $eventFactory = $this->mock(PiggyBankEventFactory::class); +// $tagFactory = $this->mock(TagFactory::class); +// $accountFactory = $this->mock(AccountFactory::class); +// $currencyFactory = $this->mock(TransactionCurrencyFactory::class); +// $metaFactory = $this->mock(TransactionJournalMetaFactory::class); +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// +// // data to return from various calls: +// $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); +// $euro = TransactionCurrency::whereCode('EUR')->first(); +// $usd = TransactionCurrency::whereCode('USD')->first(); +// $asset = $this->getRandomAsset(); +// $expense = $this->getRandomExpense(); +// $budget = Budget::first(); +// +// // data to submit. +// $data = [ +// 'transactions' => [ +// // first transaction: +// [ +// 'source_id' => $asset->id, +// 'amount' => '1', +// 'foreign_currency_code' => 'USD', +// 'foreign_amount' => '2', +// 'notes' => 'I am some notes', +// 'budget_id' => $budget->id, +// ], +// ], +// ]; +// +// // calls to setUser: +// $curRepos->shouldReceive('setUser')->once(); +// $billRepos->shouldReceive('setUser')->once(); +// $budgetRepos->shouldReceive('setUser')->once(); +// $catRepos->shouldReceive('setUser')->once(); +// $piggyRepos->shouldReceive('setUser')->once(); +// $accountRepos->shouldReceive('setUser')->once(); +// $tagFactory->shouldReceive('setUser')->once(); +// +// // calls to transaction type repository. +// $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); +// +// // calls to the currency repository: +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, 'USD'])->once()->andReturn($usd); +// +// // calls to the bill repository: +// $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the budget repository +// $budgetRepos->shouldReceive('findBudget')->withArgs([null, $budget->id, null])->once()->andReturn($budget); +// +// // calls to the category repository +// $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the account repository +// $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); +// $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); +// +// // calls to the meta factory: +// $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); +// +// +// /** @var TransactionJournalFactory $factory */ +// $factory = app(TransactionJournalFactory::class); +// $factory->setUser($this->user()); +// $collection = $factory->create($data); +// +// /** @var TransactionJournal $journal */ +// $journal = $collection->first(); +// // collection should have one journal. +// $this->assertCount(1, $collection); +// $this->assertInstanceOf(TransactionJournal::class, $journal); +// $this->assertEquals('(empty description)', $journal->description); +// $this->assertCount(1, $journal->budgets); +// $this->assertCount(0, $journal->categories); +// $this->assertCount(2, $journal->transactions); +// $this->assertEquals('I am some notes', $journal->notes->first()->text); +// $this->assertEquals('EUR', $journal->transactions->first()->transactionCurrency->code); +// $this->assertEquals('USD', $journal->transactions->first()->foreignCurrency->code); +// } +// +// /** +// * @covers \FireflyIII\Factory\TransactionJournalFactory +// */ +// public function testCategory(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// // mock used repositories. +// $billRepos = $this->mock(BillRepositoryInterface::class); +// $budgetRepos = $this->mock(BudgetRepositoryInterface::class); +// $catRepos = $this->mock(CategoryRepositoryInterface::class); +// $curRepos = $this->mock(CurrencyRepositoryInterface::class); +// $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); +// $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); +// $eventFactory = $this->mock(PiggyBankEventFactory::class); +// $tagFactory = $this->mock(TagFactory::class); +// $accountFactory = $this->mock(AccountFactory::class); +// $currencyFactory = $this->mock(TransactionCurrencyFactory::class); +// $metaFactory = $this->mock(TransactionJournalMetaFactory::class); +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// +// // data to return from various calls: +// $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); +// $euro = TransactionCurrency::whereCode('EUR')->first(); +// $usd = TransactionCurrency::whereCode('USD')->first(); +// $asset = $this->getRandomAsset(); +// $category = Category::first(); +// $expense = $this->getRandomExpense(); +// $budget = Budget::first(); +// +// // data to submit. +// $data = [ +// 'transactions' => [ +// // first transaction: +// [ +// 'source_id' => $asset->id, +// 'amount' => '1', +// 'foreign_currency_code' => 'USD', +// 'foreign_amount' => '2', +// 'notes' => 'I am some notes', +// 'budget_id' => $budget->id, +// 'category_name' => $category->name, +// ], +// ], +// ]; +// +// // calls to setUser: +// $curRepos->shouldReceive('setUser')->once(); +// $billRepos->shouldReceive('setUser')->once(); +// $budgetRepos->shouldReceive('setUser')->once(); +// $catRepos->shouldReceive('setUser')->once(); +// $piggyRepos->shouldReceive('setUser')->once(); +// $accountRepos->shouldReceive('setUser')->once(); +// $tagFactory->shouldReceive('setUser')->once(); +// +// // calls to transaction type repository. +// $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); +// +// // calls to the currency repository: +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, 'USD'])->once()->andReturn($usd); +// +// // calls to the bill repository: +// $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the budget repository +// $budgetRepos->shouldReceive('findBudget')->withArgs([null, $budget->id, null])->once()->andReturn($budget); +// +// // calls to the category repository +// $catRepos->shouldReceive('findCategory')->withArgs([null, null, $category->name])->once()->andReturn($category); +// +// // calls to the account repository +// $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); +// $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); +// +// // calls to the meta factory: +// $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); +// +// +// /** @var TransactionJournalFactory $factory */ +// $factory = app(TransactionJournalFactory::class); +// $factory->setUser($this->user()); +// $collection = $factory->create($data); +// +// /** @var TransactionJournal $journal */ +// $journal = $collection->first(); +// // collection should have one journal. +// $this->assertCount(1, $collection); +// $this->assertInstanceOf(TransactionJournal::class, $journal); +// $this->assertEquals('(empty description)', $journal->description); +// $this->assertCount(1, $journal->budgets); +// $this->assertCount(1, $journal->categories); +// $this->assertCount(2, $journal->transactions); +// $this->assertEquals('I am some notes', $journal->notes->first()->text); +// $this->assertEquals('EUR', $journal->transactions->first()->transactionCurrency->code); +// $this->assertEquals('USD', $journal->transactions->first()->foreignCurrency->code); +// } +// +// /** +// * @covers \FireflyIII\Factory\TransactionJournalFactory +// */ +// public function testCreateAlmostEmpty(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// // mock used repositories. +// $billRepos = $this->mock(BillRepositoryInterface::class); +// $budgetRepos = $this->mock(BudgetRepositoryInterface::class); +// $catRepos = $this->mock(CategoryRepositoryInterface::class); +// $curRepos = $this->mock(CurrencyRepositoryInterface::class); +// $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); +// $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); +// $eventFactory = $this->mock(PiggyBankEventFactory::class); +// $tagFactory = $this->mock(TagFactory::class); +// $accountFactory = $this->mock(AccountFactory::class); +// $currencyFactory = $this->mock(TransactionCurrencyFactory::class); +// $metaFactory = $this->mock(TransactionJournalMetaFactory::class); +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// +// // data to return from various calls: +// $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); +// $euro = TransactionCurrency::whereCode('EUR')->first(); +// $asset = $this->getRandomAsset(); +// $expense = $this->getRandomExpense(); +// +// // data to submit. +// $data = [ +// 'transactions' => [ +// // first transaction: +// [ +// 'source_id' => $asset->id, +// 'amount' => '1', +// ], +// ], +// ]; +// +// // calls to setUser: +// $curRepos->shouldReceive('setUser')->once(); +// $billRepos->shouldReceive('setUser')->once(); +// $budgetRepos->shouldReceive('setUser')->once(); +// $catRepos->shouldReceive('setUser')->once(); +// $piggyRepos->shouldReceive('setUser')->once(); +// $accountRepos->shouldReceive('setUser')->once(); +// $tagFactory->shouldReceive('setUser')->once(); +// +// // calls to transaction type repository. +// $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); +// +// // calls to the currency repository: +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); +// +// // calls to the bill repository: +// $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the budget repository +// $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the category repository +// $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the account repository +// $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); +// $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); +// +// // calls to the meta factory: +// $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); +// +// +// /** @var TransactionJournalFactory $factory */ +// $factory = app(TransactionJournalFactory::class); +// $factory->setUser($this->user()); +// $collection = $factory->create($data); +// +// /** @var TransactionJournal $journal */ +// $journal = $collection->first(); +// // collection should have one journal. +// $this->assertCount(1, $collection); +// $this->assertInstanceOf(TransactionJournal::class, $journal); +// $this->assertEquals('(empty description)', $journal->description); +// $this->assertCount(0, $journal->budgets); +// $this->assertCount(0, $journal->categories); +// $this->assertCount(2, $journal->transactions); +// } +// +// /** +// * @covers \FireflyIII\Factory\TransactionJournalFactory +// */ +// public function testCreateAlmostEmptyTransfer(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// // mock used repositories. +// $billRepos = $this->mock(BillRepositoryInterface::class); +// $budgetRepos = $this->mock(BudgetRepositoryInterface::class); +// $catRepos = $this->mock(CategoryRepositoryInterface::class); +// $curRepos = $this->mock(CurrencyRepositoryInterface::class); +// $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); +// $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); +// $eventFactory = $this->mock(PiggyBankEventFactory::class); +// $tagFactory = $this->mock(TagFactory::class); +// $accountFactory = $this->mock(AccountFactory::class); +// $currencyFactory = $this->mock(TransactionCurrencyFactory::class); +// $metaFactory = $this->mock(TransactionJournalMetaFactory::class); +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// +// // data to return from various calls: +// $type = TransactionType::whereType(TransactionType::TRANSFER)->first(); +// $euro = TransactionCurrency::whereCode('EUR')->first(); +// $source = $this->getRandomAsset(); +// $destination = $this->getAnotherRandomAsset($source->id); +// +// // data to submit. +// $data = [ +// 'type' => 'transfer', +// 'transactions' => [ +// // first transaction: +// [ +// 'source_id' => $source->id, +// 'destination_id' => $destination->id, +// 'amount' => '1', +// ], +// ], +// ]; +// +// // calls to setUser: +// $curRepos->shouldReceive('setUser')->once(); +// $billRepos->shouldReceive('setUser')->once(); +// $budgetRepos->shouldReceive('setUser')->once(); +// $catRepos->shouldReceive('setUser')->once(); +// $piggyRepos->shouldReceive('setUser')->once(); +// $accountRepos->shouldReceive('setUser')->once(); +// $tagFactory->shouldReceive('setUser')->once(); +// +// // calls to transaction type repository. +// $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'transfer'])->once()->andReturn($type); +// +// // calls to the currency repository: +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); +// +// // calls to the bill repository: +// $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the budget repository +// $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the category repository +// $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the piggy bank repository: +// $piggyRepos->shouldReceive('findPiggyBank')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the account repository +// $accountRepos->shouldReceive('findNull')->withArgs([$source->id])->once()->andReturn($source); +// $accountRepos->shouldReceive('findNull')->withArgs([$destination->id])->once()->andReturn($destination); +// +// // calls to the meta factory: +// $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); +// +// /** @var TransactionJournalFactory $factory */ +// $factory = app(TransactionJournalFactory::class); +// $factory->setUser($this->user()); +// $collection = $factory->create($data); +// +// /** @var TransactionJournal $journal */ +// $journal = $collection->first(); +// // collection should have one journal. +// $this->assertCount(1, $collection); +// $this->assertInstanceOf(TransactionJournal::class, $journal); +// $this->assertEquals('(empty description)', $journal->description); +// $this->assertCount(0, $journal->budgets); +// $this->assertCount(0, $journal->categories); +// $this->assertCount(2, $journal->transactions); +// } +// +// /** +// * @covers \FireflyIII\Factory\TransactionJournalFactory +// */ +// public function testCreateBasicGroup(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// // mock used repositories. +// $billRepos = $this->mock(BillRepositoryInterface::class); +// $budgetRepos = $this->mock(BudgetRepositoryInterface::class); +// $catRepos = $this->mock(CategoryRepositoryInterface::class); +// $curRepos = $this->mock(CurrencyRepositoryInterface::class); +// $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); +// $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); +// $eventFactory = $this->mock(PiggyBankEventFactory::class); +// $tagFactory = $this->mock(TagFactory::class); +// $accountFactory = $this->mock(AccountFactory::class); +// $currencyFactory = $this->mock(TransactionCurrencyFactory::class); +// $metaFactory = $this->mock(TransactionJournalMetaFactory::class); +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// +// // data to return from various calls: +// $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); +// $euro = TransactionCurrency::whereCode('EUR')->first(); +// $asset = $this->getRandomAsset(); +// $expense = $this->getRandomExpense(); +// +// // data to submit. +// $data = [ +// 'transactions' => [ +// // first transaction: +// [ +// 'source_id' => $asset->id, +// 'amount' => '1', +// ], +// // second transaction: +// [ +// 'source_id' => $asset->id, +// 'amount' => '1', +// ], +// ], +// ]; +// +// // calls to setUser: +// $curRepos->shouldReceive('setUser')->once(); +// $billRepos->shouldReceive('setUser')->once(); +// $budgetRepos->shouldReceive('setUser')->once(); +// $catRepos->shouldReceive('setUser')->once(); +// $piggyRepos->shouldReceive('setUser')->once(); +// $accountRepos->shouldReceive('setUser')->once(); +// $tagFactory->shouldReceive('setUser')->times(2); +// +// // calls to transaction type repository. +// $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); +// +// // calls to the currency repository: +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->times(2)->andReturn($euro); +// +// // calls to the bill repository: +// $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->times(2)->andReturnNull(); +// +// // calls to the budget repository +// $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->times(2)->andReturnNull(); +// +// // calls to the category repository +// $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->times(2)->andReturnNull(); +// +// // calls to the account repository +// $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->times(2)->andReturn($asset); +// $accountRepos->shouldReceive('getCashAccount')->times(2)->andReturn($expense); +// +// // calls to the meta factory: +// $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); +// +// /** @var TransactionJournalFactory $factory */ +// $factory = app(TransactionJournalFactory::class); +// $factory->setUser($this->user()); +// $collection = $factory->create($data); +// +// /** @var TransactionJournal $journal */ +// $journal = $collection->first(); +// +// // collection should have two journals. +// $this->assertCount(2, $collection); +// +// // journal should have some props. +// $this->assertInstanceOf(TransactionJournal::class, $journal); +// $this->assertEquals('(empty description)', $journal->description); +// $this->assertCount(0, $journal->budgets); +// $this->assertCount(0, $journal->categories); +// $this->assertCount(2, $journal->transactions); +// +// // group of journal should also have some props. +// /** @var TransactionGroup $group */ +// $group = $journal->transactionGroups()->first(); +// $this->assertCount(2, $group->transactionJournals); +// $this->assertEquals($journal->description, $group->title); +// } +// +// /** +// * @covers \FireflyIII\Factory\TransactionJournalFactory +// */ +// public function testCreateEmpty(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// // mock used repositories. +// $billRepos = $this->mock(BillRepositoryInterface::class); +// $budgetRepos = $this->mock(BudgetRepositoryInterface::class); +// $catRepos = $this->mock(CategoryRepositoryInterface::class); +// $curRepos = $this->mock(CurrencyRepositoryInterface::class); +// $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); +// $transactionFactory = $this->mock(TransactionFactory::class); +// $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); +// $eventFactory = $this->mock(PiggyBankEventFactory::class); +// $tagFactory = $this->mock(TagFactory::class); +// $accountFactory = $this->mock(AccountFactory::class); +// $currencyFactory = $this->mock(TransactionCurrencyFactory::class); +// $metaFactory = $this->mock(TransactionJournalMetaFactory::class); +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// +// // data to return from various calls: +// $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); +// +// // data to submit. +// $data = []; +// +// // calls to setUser: +// $curRepos->shouldReceive('setUser')->once(); +// $transactionFactory->shouldReceive('setUser')->once(); +// $billRepos->shouldReceive('setUser')->once(); +// $budgetRepos->shouldReceive('setUser')->once(); +// $catRepos->shouldReceive('setUser')->once(); +// $piggyRepos->shouldReceive('setUser')->once(); +// +// // calls to transaction type repository. +// $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); +// +// +// /** @var TransactionJournalFactory $factory */ +// $factory = app(TransactionJournalFactory::class); +// $factory->setUser($this->user()); +// $collection = $factory->create($data); +// +// $this->assertCount(0, $collection); +// } +// +// /** +// * @covers \FireflyIII\Factory\TransactionJournalFactory +// */ +// public function testCreatePiggyEvent(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// // mock used repositories. +// $billRepos = $this->mock(BillRepositoryInterface::class); +// $budgetRepos = $this->mock(BudgetRepositoryInterface::class); +// $catRepos = $this->mock(CategoryRepositoryInterface::class); +// $curRepos = $this->mock(CurrencyRepositoryInterface::class); +// $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); +// $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); +// $eventFactory = $this->mock(PiggyBankEventFactory::class); +// $tagFactory = $this->mock(TagFactory::class); +// $accountFactory = $this->mock(AccountFactory::class); +// $currencyFactory = $this->mock(TransactionCurrencyFactory::class); +// $metaFactory = $this->mock(TransactionJournalMetaFactory::class); +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// +// // data to return from various calls: +// $type = TransactionType::whereType(TransactionType::TRANSFER)->first(); +// $euro = TransactionCurrency::whereCode('EUR')->first(); +// $piggyBank = PiggyBank::first(); +// $source = $this->getRandomAsset(); +// $destination = $this->getAnotherRandomAsset($source->id); +// +// // data to submit. +// $data = [ +// 'type' => 'transfer', +// 'transactions' => [ +// // first transaction: +// [ +// 'source_id' => $source->id, +// 'destination_id' => $destination->id, +// 'amount' => '1', +// 'piggy_bank_id' => '1', +// 'piggy_bank_name' => 'Some name', +// ], +// ], +// ]; +// +// // calls to setUser: +// $curRepos->shouldReceive('setUser')->once(); +// $billRepos->shouldReceive('setUser')->once(); +// $budgetRepos->shouldReceive('setUser')->once(); +// $catRepos->shouldReceive('setUser')->once(); +// $piggyRepos->shouldReceive('setUser')->once(); +// $accountRepos->shouldReceive('setUser')->once(); +// $tagFactory->shouldReceive('setUser')->once(); +// +// // calls to transaction type repository. +// $typeRepos->shouldReceive('findTransactionType')->withArgs([null, 'transfer'])->once()->andReturn($type); +// +// // calls to the currency repository: +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); +// +// // calls to the bill repository: +// $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the budget repository +// $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the category repository +// $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the piggy bank repository: +// $piggyRepos->shouldReceive('findPiggyBank')->withArgs([null, 1, 'Some name'])->once()->andReturn($piggyBank); +// +// // calls to the piggy factory +// $eventFactory->shouldReceive('create')->once()->andReturnNull(); +// +// // calls to the account repository +// $accountRepos->shouldReceive('findNull')->withArgs([$source->id])->once()->andReturn($source); +// $accountRepos->shouldReceive('findNull')->withArgs([$destination->id])->once()->andReturn($destination); +// +// // calls to the meta factory: +// $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); +// +// /** @var TransactionJournalFactory $factory */ +// $factory = app(TransactionJournalFactory::class); +// $factory->setUser($this->user()); +// $collection = $factory->create($data); +// +// /** @var TransactionJournal $journal */ +// $journal = $collection->first(); +// // collection should have one journal. +// $this->assertCount(1, $collection); +// $this->assertInstanceOf(TransactionJournal::class, $journal); +// $this->assertEquals('(empty description)', $journal->description); +// $this->assertCount(0, $journal->budgets); +// $this->assertCount(0, $journal->categories); +// $this->assertCount(2, $journal->transactions); +// } +// +// /** +// * @covers \FireflyIII\Factory\TransactionJournalFactory +// */ +// public function testForeignCurrency(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// // mock used repositories. +// $billRepos = $this->mock(BillRepositoryInterface::class); +// $budgetRepos = $this->mock(BudgetRepositoryInterface::class); +// $catRepos = $this->mock(CategoryRepositoryInterface::class); +// $curRepos = $this->mock(CurrencyRepositoryInterface::class); +// $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); +// $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); +// $eventFactory = $this->mock(PiggyBankEventFactory::class); +// $tagFactory = $this->mock(TagFactory::class); +// $accountFactory = $this->mock(AccountFactory::class); +// $currencyFactory = $this->mock(TransactionCurrencyFactory::class); +// $metaFactory = $this->mock(TransactionJournalMetaFactory::class); +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// +// // data to return from various calls: +// $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); +// $euro = TransactionCurrency::whereCode('EUR')->first(); +// $usd = TransactionCurrency::whereCode('USD')->first(); +// $asset = $this->getRandomAsset(); +// $expense = $this->getRandomExpense(); +// +// // data to submit. +// $data = [ +// 'transactions' => [ +// // first transaction: +// [ +// 'source_id' => $asset->id, +// 'amount' => '1', +// 'foreign_currency_code' => 'USD', +// 'foreign_amount' => '2', +// 'notes' => 'I am some notes', +// ], +// ], +// ]; +// +// // calls to setUser: +// $curRepos->shouldReceive('setUser')->once(); +// $billRepos->shouldReceive('setUser')->once(); +// $budgetRepos->shouldReceive('setUser')->once(); +// $catRepos->shouldReceive('setUser')->once(); +// $piggyRepos->shouldReceive('setUser')->once(); +// $accountRepos->shouldReceive('setUser')->once(); +// $tagFactory->shouldReceive('setUser')->once(); +// +// // calls to transaction type repository. +// $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); +// +// // calls to the currency repository: +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, 'USD'])->once()->andReturn($usd); +// +// // calls to the bill repository: +// $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the budget repository +// $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the category repository +// $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the account repository +// $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); +// $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); +// +// // calls to the meta factory: +// $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); +// +// +// /** @var TransactionJournalFactory $factory */ +// $factory = app(TransactionJournalFactory::class); +// $factory->setUser($this->user()); +// $collection = $factory->create($data); +// +// /** @var TransactionJournal $journal */ +// $journal = $collection->first(); +// // collection should have one journal. +// $this->assertCount(1, $collection); +// $this->assertInstanceOf(TransactionJournal::class, $journal); +// $this->assertEquals('(empty description)', $journal->description); +// $this->assertCount(0, $journal->budgets); +// $this->assertCount(0, $journal->categories); +// $this->assertCount(2, $journal->transactions); +// $this->assertEquals('I am some notes', $journal->notes->first()->text); +// $this->assertEquals('EUR', $journal->transactions->first()->transactionCurrency->code); +// $this->assertEquals('USD', $journal->transactions->first()->foreignCurrency->code); +// } +// +// /** +// * @covers \FireflyIII\Factory\TransactionJournalFactory +// */ +// public function testNotes(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// // mock used repositories. +// $billRepos = $this->mock(BillRepositoryInterface::class); +// $budgetRepos = $this->mock(BudgetRepositoryInterface::class); +// $catRepos = $this->mock(CategoryRepositoryInterface::class); +// $curRepos = $this->mock(CurrencyRepositoryInterface::class); +// $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); +// $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); +// $eventFactory = $this->mock(PiggyBankEventFactory::class); +// $tagFactory = $this->mock(TagFactory::class); +// $accountFactory = $this->mock(AccountFactory::class); +// $currencyFactory = $this->mock(TransactionCurrencyFactory::class); +// $metaFactory = $this->mock(TransactionJournalMetaFactory::class); +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// +// // data to return from various calls: +// $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); +// $euro = TransactionCurrency::whereCode('EUR')->first(); +// $asset = $this->getRandomAsset(); +// $expense = $this->getRandomExpense(); +// +// // data to submit. +// $data = [ +// 'transactions' => [ +// // first transaction: +// [ +// 'source_id' => $asset->id, +// 'amount' => '1', +// 'notes' => 'I am some notes', +// ], +// ], +// ]; +// +// // calls to setUser: +// $curRepos->shouldReceive('setUser')->once(); +// $billRepos->shouldReceive('setUser')->once(); +// $budgetRepos->shouldReceive('setUser')->once(); +// $catRepos->shouldReceive('setUser')->once(); +// $piggyRepos->shouldReceive('setUser')->once(); +// $accountRepos->shouldReceive('setUser')->once(); +// $tagFactory->shouldReceive('setUser')->once(); +// +// // calls to transaction type repository. +// $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); +// +// // calls to the currency repository: +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); +// +// // calls to the bill repository: +// $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the budget repository +// $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the category repository +// $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the account repository +// $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); +// $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); +// +// // calls to the meta factory: +// $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); +// +// +// /** @var TransactionJournalFactory $factory */ +// $factory = app(TransactionJournalFactory::class); +// $factory->setUser($this->user()); +// $collection = $factory->create($data); +// +// /** @var TransactionJournal $journal */ +// $journal = $collection->first(); +// // collection should have one journal. +// $this->assertCount(1, $collection); +// $this->assertInstanceOf(TransactionJournal::class, $journal); +// $this->assertEquals('(empty description)', $journal->description); +// $this->assertCount(0, $journal->budgets); +// $this->assertCount(0, $journal->categories); +// $this->assertCount(2, $journal->transactions); +// $this->assertEquals('I am some notes', $journal->notes->first()->text); +// } +// +// /** +// * @covers \FireflyIII\Factory\TransactionJournalFactory +// */ +// public function testTags(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// // mock used repositories. +// $billRepos = $this->mock(BillRepositoryInterface::class); +// $budgetRepos = $this->mock(BudgetRepositoryInterface::class); +// $catRepos = $this->mock(CategoryRepositoryInterface::class); +// $curRepos = $this->mock(CurrencyRepositoryInterface::class); +// $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); +// $typeRepos = $this->mock(TransactionTypeRepositoryInterface::class); +// $eventFactory = $this->mock(PiggyBankEventFactory::class); +// $tagFactory = $this->mock(TagFactory::class); +// $accountFactory = $this->mock(AccountFactory::class); +// $currencyFactory = $this->mock(TransactionCurrencyFactory::class); +// $metaFactory = $this->mock(TransactionJournalMetaFactory::class); +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// +// // data to return from various calls: +// $type = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); +// $euro = TransactionCurrency::whereCode('EUR')->first(); +// $asset = $this->getRandomAsset(); +// $expense = $this->getRandomExpense(); +// $tag = Tag::first(); +// +// // data to submit. +// $data = [ +// 'transactions' => [ +// // first transaction: +// [ +// 'source_id' => $asset->id, +// 'amount' => '1', +// 'tags' => ['tagA', 'B', '', 'C'], +// ], +// ], +// ]; +// +// // calls to setUser: +// $curRepos->shouldReceive('setUser')->once(); +// $billRepos->shouldReceive('setUser')->once(); +// $budgetRepos->shouldReceive('setUser')->once(); +// $catRepos->shouldReceive('setUser')->once(); +// $piggyRepos->shouldReceive('setUser')->once(); +// $accountRepos->shouldReceive('setUser')->once(); +// $tagFactory->shouldReceive('setUser')->once(); +// +// // calls to transaction type repository. +// $typeRepos->shouldReceive('findTransactionType')->withArgs([null, null])->once()->andReturn($type); +// +// // calls to the currency repository: +// $curRepos->shouldReceive('findCurrency')->withArgs([null, null, null])->once()->andReturn($euro); +// +// // calls to the bill repository: +// $billRepos->shouldReceive('findBill')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the budget repository +// $budgetRepos->shouldReceive('findBudget')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the category repository +// $catRepos->shouldReceive('findCategory')->withArgs([null, null, null])->once()->andReturnNull(); +// +// // calls to the account repository +// $accountRepos->shouldReceive('findNull')->withArgs([$asset->id])->once()->andReturn($asset); +// $accountRepos->shouldReceive('getCashAccount')->once()->andReturn($expense); +// +// // calls to tag factory +// $tagFactory->shouldReceive('findOrCreate')->once()->withArgs(['tagA'])->andReturn($tag); +// $tagFactory->shouldReceive('findOrCreate')->once()->withArgs(['B'])->andReturn($tag); +// $tagFactory->shouldReceive('findOrCreate')->once()->withArgs(['C'])->andReturnNull(); +// +// // calls to the meta factory: +// $metaFactory->shouldReceive('updateOrCreate')->atLeast()->once()->andReturnNull(); +// +// /** @var TransactionJournalFactory $factory */ +// $factory = app(TransactionJournalFactory::class); +// $factory->setUser($this->user()); +// $collection = $factory->create($data); +// +// /** @var TransactionJournal $journal */ +// $journal = $collection->first(); +// // collection should have one journal. +// $this->assertCount(1, $collection); +// $this->assertInstanceOf(TransactionJournal::class, $journal); +// $this->assertEquals('(empty description)', $journal->description); +// $this->assertCount(0, $journal->budgets); +// $this->assertCount(0, $journal->categories); +// $this->assertCount(2, $journal->transactions); +// $this->assertCount(1, $journal->tags); // we return the same tag every time. +// } +// +// /** +// * @param int $id +// * +// * @return Account +// */ +// private function getAnotherRandomAsset(int $id): Account +// { +// +// $query = Account:: +// leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') +// ->whereNull('accounts.deleted_at') +// ->where('accounts.user_id', $this->user()->id) +// ->where('account_types.type', AccountType::ASSET) +// ->where('accounts.id', '!=', $id) +// ->inRandomOrder()->take(1); +// +// return $query->first(['accounts.*']); +// } + } diff --git a/tests/Unit/Factory/TransactionJournalMetaFactoryTest.php b/tests/Unit/Factory/TransactionJournalMetaFactoryTest.php index f0dcf19fd3..025adb868e 100644 --- a/tests/Unit/Factory/TransactionJournalMetaFactoryTest.php +++ b/tests/Unit/Factory/TransactionJournalMetaFactoryTest.php @@ -25,7 +25,6 @@ namespace Tests\Unit\Factory; use Carbon\Carbon; use FireflyIII\Factory\TransactionJournalMetaFactory; -use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournalMeta; use Log; use Tests\TestCase; @@ -50,14 +49,10 @@ class TransactionJournalMetaFactoryTest extends TestCase */ public function testUpdateOrCreateBasic(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var TransactionJournal $journal */ - $journal = $this->user()->transactionJournals()->inRandomOrder()->first(); - $journal->transactionJournalMeta()->delete(); + $withdrawal = $this->getRandomWithdrawal(); + $withdrawal->transactionJournalMeta()->delete(); $set = [ - 'journal' => $journal, + 'journal' => $withdrawal, 'name' => 'hello', 'data' => 'bye!', ]; @@ -65,7 +60,7 @@ class TransactionJournalMetaFactoryTest extends TestCase $factory = app(TransactionJournalMetaFactory::class); $result = $factory->updateOrCreate($set); - $this->assertEquals(1, $journal->transactionJournalMeta()->count()); + $this->assertEquals(1, $withdrawal->transactionJournalMeta()->count()); $this->assertEquals($set['data'], $result->data); } @@ -74,14 +69,10 @@ class TransactionJournalMetaFactoryTest extends TestCase */ public function testUpdateOrCreateDate(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var TransactionJournal $journal */ - $journal = $this->user()->transactionJournals()->inRandomOrder()->first(); - $journal->transactionJournalMeta()->delete(); + $withdrawal = $this->getRandomWithdrawal(); + $withdrawal->transactionJournalMeta()->delete(); $set = [ - 'journal' => $journal, + 'journal' => $withdrawal, 'name' => 'hello', 'data' => new Carbon('2012-01-01'), ]; @@ -89,7 +80,7 @@ class TransactionJournalMetaFactoryTest extends TestCase $factory = app(TransactionJournalMetaFactory::class); $result = $factory->updateOrCreate($set); - $this->assertEquals(1, $journal->transactionJournalMeta()->count()); + $this->assertEquals(1, $withdrawal->transactionJournalMeta()->count()); $this->assertEquals($set['data']->toW3cString(), $result->data); } @@ -98,22 +89,18 @@ class TransactionJournalMetaFactoryTest extends TestCase */ public function testUpdateOrCreateDeleteExisting(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var TransactionJournal $journal */ - $journal = $this->user()->transactionJournals()->where('transaction_type_id', 3)->first(); - $meta = TransactionJournalMeta::create( + $withdrawal = $this->getRandomWithdrawal(); + TransactionJournalMeta::create( [ - 'transaction_journal_id' => $journal->id, + 'transaction_journal_id' => $withdrawal->id, 'name' => 'hello', 'data' => 'bye!', ] ); - $count = $journal->transactionJournalMeta()->count(); + $count = $withdrawal->transactionJournalMeta()->count(); $set = [ - 'journal' => $journal, + 'journal' => $withdrawal, 'name' => 'hello', 'data' => null, ]; @@ -121,7 +108,7 @@ class TransactionJournalMetaFactoryTest extends TestCase $factory = app(TransactionJournalMetaFactory::class); $factory->updateOrCreate($set); - $this->assertEquals($count - 1, $journal->transactionJournalMeta()->count()); + $this->assertEquals($count - 1, $withdrawal->transactionJournalMeta()->count()); } /** @@ -129,14 +116,10 @@ class TransactionJournalMetaFactoryTest extends TestCase */ public function testUpdateOrCreateEmpty(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var TransactionJournal $journal */ - $journal = $this->user()->transactionJournals()->inRandomOrder()->first(); - $journal->transactionJournalMeta()->delete(); + $withdrawal = $this->getRandomWithdrawal(); + $withdrawal->transactionJournalMeta()->delete(); $set = [ - 'journal' => $journal, + 'journal' => $withdrawal, 'name' => 'hello', 'data' => '', ]; @@ -144,7 +127,7 @@ class TransactionJournalMetaFactoryTest extends TestCase $factory = app(TransactionJournalMetaFactory::class); $result = $factory->updateOrCreate($set); - $this->assertEquals(0, $journal->transactionJournalMeta()->count()); + $this->assertEquals(0, $withdrawal->transactionJournalMeta()->count()); $this->assertNull($result); } @@ -153,14 +136,10 @@ class TransactionJournalMetaFactoryTest extends TestCase */ public function testUpdateOrCreateExistingEmpty(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var TransactionJournal $journal */ - $journal = $this->user()->transactionJournals()->inRandomOrder()->first(); - $journal->transactionJournalMeta()->delete(); + $withdrawal = $this->getRandomWithdrawal(); + $withdrawal->transactionJournalMeta()->delete(); $set = [ - 'journal' => $journal, + 'journal' => $withdrawal, 'name' => 'hello', 'data' => 'SomeData', ]; @@ -168,12 +147,12 @@ class TransactionJournalMetaFactoryTest extends TestCase $factory = app(TransactionJournalMetaFactory::class); $result = $factory->updateOrCreate($set); - $this->assertEquals(1, $journal->transactionJournalMeta()->count()); + $this->assertEquals(1, $withdrawal->transactionJournalMeta()->count()); $this->assertNotNull($result); // overrule with empty entry: $set = [ - 'journal' => $journal, + 'journal' => $withdrawal, 'name' => 'hello', 'data' => '', ]; @@ -181,7 +160,7 @@ class TransactionJournalMetaFactoryTest extends TestCase $factory = app(TransactionJournalMetaFactory::class); $result = $factory->updateOrCreate($set); - $this->assertEquals(0, $journal->transactionJournalMeta()->count()); + $this->assertEquals(0, $withdrawal->transactionJournalMeta()->count()); $this->assertNull($result); } diff --git a/tests/Unit/Import/JobConfiguration/BunqJobConfigurationTest.php b/tests/Unit/Import/JobConfiguration/BunqJobConfigurationTest.php index cdedf32d3e..9fbad94aa3 100644 --- a/tests/Unit/Import/JobConfiguration/BunqJobConfigurationTest.php +++ b/tests/Unit/Import/JobConfiguration/BunqJobConfigurationTest.php @@ -57,7 +57,7 @@ class BunqJobConfigurationTest extends TestCase $jobRepos->shouldReceive('setUser')->once(); $job = new ImportJob; $job->user_id = $this->user()->id; - $job->key = 'bunq_jc_A' . random_int(1, 100000); + $job->key = 'bunq_jc_A' . $this->randomInt(); $job->status = 'new'; $job->stage = 'new'; $job->provider = 'bunq'; @@ -154,7 +154,7 @@ class BunqJobConfigurationTest extends TestCase $jobRepos->shouldReceive('setUser')->once(); $job = new ImportJob; $job->user_id = $this->user()->id; - $job->key = 'bunq_jc_E' . random_int(1, 100000); + $job->key = 'bunq_jc_E' . $this->randomInt(); $job->status = 'new'; $job->stage = 'choose-accounts'; $job->provider = 'bunq'; diff --git a/tests/Unit/Import/JobConfiguration/YnabJobConfigurationTest.php b/tests/Unit/Import/JobConfiguration/YnabJobConfigurationTest.php index c4ced8c377..a8e90d40b4 100644 --- a/tests/Unit/Import/JobConfiguration/YnabJobConfigurationTest.php +++ b/tests/Unit/Import/JobConfiguration/YnabJobConfigurationTest.php @@ -58,7 +58,7 @@ class YnabJobConfigurationTest extends TestCase $jobRepos->shouldReceive('setUser')->once(); $job = new ImportJob; $job->user_id = $this->user()->id; - $job->key = 'ynab_jc_A' . random_int(1, 100000); + $job->key = 'ynab_jc_A' . $this->randomInt(); $job->status = 'new'; $job->stage = 'new'; $job->provider = 'ynab'; @@ -155,7 +155,7 @@ class YnabJobConfigurationTest extends TestCase $jobRepos->shouldReceive('setUser')->once(); $job = new ImportJob; $job->user_id = $this->user()->id; - $job->key = 'ynab_jc_E' . random_int(1, 100000); + $job->key = 'ynab_jc_E' . $this->randomInt(); $job->status = 'new'; $job->stage = 'new'; $job->provider = 'ynab'; diff --git a/tests/Unit/Services/Internal/Update/TransactionUpdateServiceTest.php b/tests/Unit/Services/Internal/Update/TransactionUpdateServiceTest.php index fad9159a96..67932a3480 100644 --- a/tests/Unit/Services/Internal/Update/TransactionUpdateServiceTest.php +++ b/tests/Unit/Services/Internal/Update/TransactionUpdateServiceTest.php @@ -46,220 +46,220 @@ class TransactionUpdateServiceTest extends TestCase Log::info(sprintf('Now in %s.', get_class($this))); } - /** - * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService - */ - public function testReconcile(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - $transaction = $this->user()->transactions()->inRandomOrder()->first(); - - /** @var TransactionUpdateService $service */ - $service = app(TransactionUpdateService::class); - $service->setUser($this->user()); - $result = $service->reconcile($transaction->id); - $this->assertEquals($result->id, $transaction->id); - $this->assertEquals(true, $result->reconciled); - } - - /** - * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService - * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait - */ - public function testReconcileNull(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var TransactionUpdateService $service */ - $service = app(TransactionUpdateService::class); - $service->setUser($this->user()); - $result = $service->reconcile(-1); - $this->assertNull($result); - } - - /** - * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService - * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait - */ - public function testUpdateBudget(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var Transaction $source */ - $source = $this->user()->transactions()->where('amount', '>', 0)->inRandomOrder()->first(); - $budget = $this->user()->budgets()->inRandomOrder()->first(); - - $factory = $this->mock(BudgetFactory::class); - $factory->shouldReceive('setUser'); - $factory->shouldReceive('find')->andReturn($budget); - - /** @var TransactionUpdateService $service */ - $service = app(TransactionUpdateService::class); - $service->setUser($this->user()); - $result = $service->updateBudget($source, $budget->id); - - $this->assertEquals(1, $result->budgets()->count()); - $this->assertEquals($budget->name, $result->budgets()->first()->name); - } - - /** - * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService - * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait - */ - public function testUpdateCategory(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var Transaction $source */ - $source = $this->user()->transactions()->where('amount', '>', 0)->inRandomOrder()->first(); - $category = $this->user()->categories()->inRandomOrder()->first(); - - $factory = $this->mock(CategoryFactory::class); - $factory->shouldReceive('setUser'); - $factory->shouldReceive('findOrCreate')->andReturn($category); - - /** @var TransactionUpdateService $service */ - $service = app(TransactionUpdateService::class); - $service->setUser($this->user()); - $result = $service->updateCategory($source, $category->name); - - $this->assertEquals(1, $result->categories()->count()); - $this->assertEquals($category->name, $result->categories()->first()->name); - } - - /** - * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService - * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait - */ - public function testUpdateDestinationBasic(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var Transaction $source */ - $source = $this->user()->transactions()->where('amount', '>', 0)->inRandomOrder()->first(); - $data = [ - 'currency_id' => 1, - 'currency_code' => null, - 'description' => 'Some new description', - 'reconciled' => false, - 'foreign_amount' => null, - 'budget_id' => null, - 'budget_name' => null, - 'destination_id' => (int)$source->account_id, - 'destination_name' => null, - 'category_id' => null, - 'category_name' => null, - 'amount' => $source->amount, - 'foreign_currency_id' => null, - 'foreign_currency_code' => null, - ]; - - // mock repository: - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $accountRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('findNull')->andReturn($source->account); - - /** @var TransactionUpdateService $service */ - $service = app(TransactionUpdateService::class); - $service->setUser($this->user()); - $result = $service->update($source, $data); - - $this->assertEquals($source->id, $result->id); - $this->assertEquals($result->description, $data['description']); - } - - /** - * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService - * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait - */ - public function testUpdateDestinationForeign(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var Transaction $source */ - $source = $this->user()->transactions()->where('amount', '>', 0)->inRandomOrder()->first(); - $data = [ - 'currency_id' => 1, - 'currency_code' => null, - 'description' => 'Some new description', - 'reconciled' => false, - 'foreign_amount' => '12.34', - 'budget_id' => null, - 'budget_name' => null, - 'destination_id' => (int)$source->account_id, - 'destination_name' => null, - 'category_id' => null, - 'category_name' => null, - 'amount' => $source->amount, - 'foreign_currency_id' => 2, - 'foreign_currency_code' => null, - ]; - - // mock repository: - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $accountRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('findNull')->andReturn($source->account); - - /** @var TransactionUpdateService $service */ - $service = app(TransactionUpdateService::class); - $service->setUser($this->user()); - $result = $service->update($source, $data); - - - $this->assertEquals($source->id, $result->id); - $this->assertEquals($result->description, $data['description']); - $this->assertEquals($data['foreign_amount'], $result->foreign_amount); - $this->assertEquals($data['foreign_currency_id'], $result->foreign_currency_id); - } - - /** - * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService - * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait - */ - public function testUpdateSourceBasic(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var Transaction $source */ - $source = $this->user()->transactions()->where('amount', '<', 0)->inRandomOrder()->first(); - $data = [ - 'currency_id' => 1, - 'currency_code' => null, - 'description' => 'Some new description', - 'reconciled' => false, - 'foreign_amount' => null, - 'budget_id' => null, - 'budget_name' => null, - 'source_id' => (int)$source->account_id, - 'source_name' => null, - 'category_id' => null, - 'category_name' => null, - 'amount' => $source->amount, - 'foreign_currency_id' => null, - 'foreign_currency_code' => null, - ]; - - // mock repository: - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $accountRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('findNull')->andReturn($source->account); - - /** @var TransactionUpdateService $service */ - $service = app(TransactionUpdateService::class); - $service->setUser($this->user()); - $result = $service->update($source, $data); - - $this->assertEquals($source->id, $result->id); - $this->assertEquals($result->description, $data['description']); - - - } +// /** +// * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService +// */ +// public function testReconcile(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// $transaction = $this->user()->transactions()->inRandomOrder()->first(); +// +// /** @var TransactionUpdateService $service */ +// $service = app(TransactionUpdateService::class); +// $service->setUser($this->user()); +// $result = $service->reconcile($transaction->id); +// $this->assertEquals($result->id, $transaction->id); +// $this->assertEquals(true, $result->reconciled); +// } +// +// /** +// * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService +// * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait +// */ +// public function testReconcileNull(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// /** @var TransactionUpdateService $service */ +// $service = app(TransactionUpdateService::class); +// $service->setUser($this->user()); +// $result = $service->reconcile(-1); +// $this->assertNull($result); +// } +// +// /** +// * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService +// * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait +// */ +// public function testUpdateBudget(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// /** @var Transaction $source */ +// $source = $this->user()->transactions()->where('amount', '>', 0)->inRandomOrder()->first(); +// $budget = $this->user()->budgets()->inRandomOrder()->first(); +// +// $factory = $this->mock(BudgetFactory::class); +// $factory->shouldReceive('setUser'); +// $factory->shouldReceive('find')->andReturn($budget); +// +// /** @var TransactionUpdateService $service */ +// $service = app(TransactionUpdateService::class); +// $service->setUser($this->user()); +// $result = $service->updateBudget($source, $budget->id); +// +// $this->assertEquals(1, $result->budgets()->count()); +// $this->assertEquals($budget->name, $result->budgets()->first()->name); +// } +// +// /** +// * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService +// * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait +// */ +// public function testUpdateCategory(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// /** @var Transaction $source */ +// $source = $this->user()->transactions()->where('amount', '>', 0)->inRandomOrder()->first(); +// $category = $this->user()->categories()->inRandomOrder()->first(); +// +// $factory = $this->mock(CategoryFactory::class); +// $factory->shouldReceive('setUser'); +// $factory->shouldReceive('findOrCreate')->andReturn($category); +// +// /** @var TransactionUpdateService $service */ +// $service = app(TransactionUpdateService::class); +// $service->setUser($this->user()); +// $result = $service->updateCategory($source, $category->name); +// +// $this->assertEquals(1, $result->categories()->count()); +// $this->assertEquals($category->name, $result->categories()->first()->name); +// } +// +// /** +// * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService +// * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait +// */ +// public function testUpdateDestinationBasic(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// /** @var Transaction $source */ +// $source = $this->user()->transactions()->where('amount', '>', 0)->inRandomOrder()->first(); +// $data = [ +// 'currency_id' => 1, +// 'currency_code' => null, +// 'description' => 'Some new description', +// 'reconciled' => false, +// 'foreign_amount' => null, +// 'budget_id' => null, +// 'budget_name' => null, +// 'destination_id' => (int)$source->account_id, +// 'destination_name' => null, +// 'category_id' => null, +// 'category_name' => null, +// 'amount' => $source->amount, +// 'foreign_currency_id' => null, +// 'foreign_currency_code' => null, +// ]; +// +// // mock repository: +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// $accountRepos->shouldReceive('setUser'); +// $accountRepos->shouldReceive('findNull')->andReturn($source->account); +// +// /** @var TransactionUpdateService $service */ +// $service = app(TransactionUpdateService::class); +// $service->setUser($this->user()); +// $result = $service->update($source, $data); +// +// $this->assertEquals($source->id, $result->id); +// $this->assertEquals($result->description, $data['description']); +// } +// +// /** +// * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService +// * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait +// */ +// public function testUpdateDestinationForeign(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// /** @var Transaction $source */ +// $source = $this->user()->transactions()->where('amount', '>', 0)->inRandomOrder()->first(); +// $data = [ +// 'currency_id' => 1, +// 'currency_code' => null, +// 'description' => 'Some new description', +// 'reconciled' => false, +// 'foreign_amount' => '12.34', +// 'budget_id' => null, +// 'budget_name' => null, +// 'destination_id' => (int)$source->account_id, +// 'destination_name' => null, +// 'category_id' => null, +// 'category_name' => null, +// 'amount' => $source->amount, +// 'foreign_currency_id' => 2, +// 'foreign_currency_code' => null, +// ]; +// +// // mock repository: +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// $accountRepos->shouldReceive('setUser'); +// $accountRepos->shouldReceive('findNull')->andReturn($source->account); +// +// /** @var TransactionUpdateService $service */ +// $service = app(TransactionUpdateService::class); +// $service->setUser($this->user()); +// $result = $service->update($source, $data); +// +// +// $this->assertEquals($source->id, $result->id); +// $this->assertEquals($result->description, $data['description']); +// $this->assertEquals($data['foreign_amount'], $result->foreign_amount); +// $this->assertEquals($data['foreign_currency_id'], $result->foreign_currency_id); +// } +// +// /** +// * @covers \FireflyIII\Services\Internal\Update\TransactionUpdateService +// * @covers \FireflyIII\Services\Internal\Support\TransactionServiceTrait +// */ +// public function testUpdateSourceBasic(): void +// { +// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); +// +// return; +// /** @var Transaction $source */ +// $source = $this->user()->transactions()->where('amount', '<', 0)->inRandomOrder()->first(); +// $data = [ +// 'currency_id' => 1, +// 'currency_code' => null, +// 'description' => 'Some new description', +// 'reconciled' => false, +// 'foreign_amount' => null, +// 'budget_id' => null, +// 'budget_name' => null, +// 'source_id' => (int)$source->account_id, +// 'source_name' => null, +// 'category_id' => null, +// 'category_name' => null, +// 'amount' => $source->amount, +// 'foreign_currency_id' => null, +// 'foreign_currency_code' => null, +// ]; +// +// // mock repository: +// $accountRepos = $this->mock(AccountRepositoryInterface::class); +// $accountRepos->shouldReceive('setUser'); +// $accountRepos->shouldReceive('findNull')->andReturn($source->account); +// +// /** @var TransactionUpdateService $service */ +// $service = app(TransactionUpdateService::class); +// $service->setUser($this->user()); +// $result = $service->update($source, $data); +// +// $this->assertEquals($source->id, $result->id); +// $this->assertEquals($result->description, $data['description']); +// +// +// } } diff --git a/tests/Unit/Support/Import/Routine/Spectre/StageImportDataHandlerTest.php b/tests/Unit/Support/Import/Routine/Spectre/StageImportDataHandlerTest.php index a3d0297fb3..d1f3375476 100644 --- a/tests/Unit/Support/Import/Routine/Spectre/StageImportDataHandlerTest.php +++ b/tests/Unit/Support/Import/Routine/Spectre/StageImportDataHandlerTest.php @@ -123,7 +123,7 @@ class StageImportDataHandlerTest extends TestCase $revenue = $this->user()->accounts()->where('account_type_id', 5)->first(); $job = new ImportJob; $job->user_id = $this->user()->id; - $job->key = 'sid_a__' . random_int(1, 100000); + $job->key = 'sid_a__' . $this->randomInt(); $job->status = 'new'; $job->stage = 'new'; $job->provider = 'spectre';