From 3d54a7857334b6b8e58c8e56ed53129510f3dc6a Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 10 May 2015 07:48:33 +0200 Subject: [PATCH] Tag repository tests --- app/Repositories/Tag/TagRepository.php | 41 ++- tests/repositories/TagRepositoryTest.php | 359 +++++++++++++++++++++-- 2 files changed, 359 insertions(+), 41 deletions(-) diff --git a/app/Repositories/Tag/TagRepository.php b/app/Repositories/Tag/TagRepository.php index 0fc8c4b42b..4f27c7f9d9 100644 --- a/app/Repositories/Tag/TagRepository.php +++ b/app/Repositories/Tag/TagRepository.php @@ -52,6 +52,7 @@ class TagRepository implements TagRepositoryInterface $withdrawals = $tag->transactionjournals()->where('transaction_type_id', $withdrawal->id)->count(); $transfers = $tag->transactionjournals()->where('transaction_type_id', $transfer->id)->count(); + $deposits = $tag->transactionjournals()->where('transaction_type_id', $deposit->id)->count(); if ($tag->tagMode == 'balancingAct') { @@ -73,39 +74,47 @@ class TagRepository implements TagRepositoryInterface } if ($tag->tagMode == 'advancePayment') { + // advance payments cannot accept transfers: + if ($journal->transaction_type_id == $transfer->id) { + return false; + } - // only if this is the only withdrawal - if ($journal->transaction_type_id == $withdrawal->id && $withdrawals < 1) { + // the first transaction to be attached to this + // tag is attached just like that: + if ($withdrawals < 1 && $deposits < 1) { $journal->tags()->save($tag); return true; } - // only if this is a deposit. - if ($journal->transaction_type_id == $deposit->id) { + // if withdrawal and already has a withdrawal, return false: + if ($journal->transaction_type_id == $withdrawal->id && $withdrawals == 1) { + return false; + } - // if this is a deposit, account must match the current only journal - // (if already present): - $currentWithdrawal = $tag->transactionjournals()->where('transaction_type_id', $withdrawal->id)->first(); - - if ($currentWithdrawal && $currentWithdrawal->assetAccount->id == $journal->assetAccount->id) { + // if already has transaction journals, must match ALL asset account id's: + if ($deposits > 0 || $withdrawals == 1) { + $match = true; + /** @var TransactionJournal $check */ + foreach ($tag->transactionjournals as $check) { + if ($check->assetAccount->id != $journal->assetAccount->id) { + $match = false; + } + } + if ($match) { $journal->tags()->save($tag); return true; - } else { - if (is_null($currentWithdrawal)) { - $journal->tags()->save($tag); - - return true; - } } + } return false; } - + // @codeCoverageIgnoreStart return false; } + // @codeCoverageIgnoreEnd /** * @param Tag $tag diff --git a/tests/repositories/TagRepositoryTest.php b/tests/repositories/TagRepositoryTest.php index fb1b57cd0c..855ec366d5 100644 --- a/tests/repositories/TagRepositoryTest.php +++ b/tests/repositories/TagRepositoryTest.php @@ -1,5 +1,8 @@ markTestIncomplete( - 'This test has not been implemented yet.' - ); + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + $journal->tags()->save($tag); + + $result = $this->object->connect($journal, $tag); + $this->assertFalse($result); + + } + + /** + * A deposit cannot be connected to a balancing act. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::connect + */ + public function testConnectBalancingOneDeposit() + { + $withdrawal = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $deposit = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $transfer = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + + $journal->transaction_type_id = $deposit->id; + $tag->tagMode = 'balancingAct'; + + $tag->save(); + $journal->save(); + + $result = $this->object->connect($journal, $tag); + $this->assertFalse($result); + + } + + /** + * Connecting a single transfer to a balancing act is possible if there are no + * other transfers already connected. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::connect + */ + public function testConnectBalancingOneTransfer() + { + $withdrawal = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $deposit = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $transfer = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + + $journal->transaction_type_id = $transfer->id; + $tag->tagMode = 'balancingAct'; + + $tag->save(); + $journal->save(); + + $result = $this->object->connect($journal, $tag); + $this->assertTrue($result); + + } + + /** + * Connecting a single withdrawal to a balancing act is possible if there are + * not other withdrawals already connected. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::connect + */ + public function testConnectBalancingOneWithdrawal() + { + $withdrawal = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $deposit = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $transfer = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + + $journal->transaction_type_id = $withdrawal->id; + $tag->tagMode = 'balancingAct'; + + $tag->save(); + $journal->save(); + + $result = $this->object->connect($journal, $tag); + $this->assertTrue($result); + + } + + /** + * @covers FireflyIII\Repositories\Tag\TagRepository::connect + */ + public function testConnectDefault() + { + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + $tag->tagMode = 'nothing'; + $tag->save(); + + $result = $this->object->connect($journal, $tag); + $this->assertTrue($result); + + } + + /** + * Once one or more journals have been accepted by the tag, others must match the asset account + * id. For this to work, we must also create an asset account, and a transaction. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::connect + */ + public function testConnectPaymentMultipleMatch() + { + $withdrawal = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $deposit = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $transfer = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + + $expense = FactoryMuffin::create('FireflyIII\Models\AccountType'); + $revenue = FactoryMuffin::create('FireflyIII\Models\AccountType'); + $asset = FactoryMuffin::create('FireflyIII\Models\AccountType'); + + $account = FactoryMuffin::create('FireflyIII\Models\Account'); + + + $journal1 = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $journal2 = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + + // transactions for both: + Transaction::create(['account_id' => $account->id, 'transaction_journal_id' => $journal1->id, 'amount' => 100]); + Transaction::create(['account_id' => $account->id, 'transaction_journal_id' => $journal2->id, 'amount' => 100]); + + + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + + $journal1->transaction_type_id = $withdrawal->id; + $journal2->transaction_type_id = $deposit->id; + $tag->tagMode = 'advancePayment'; + $account->account_type_id = $asset->id; + + $tag->save(); + $journal1->save(); + $journal2->save(); + $account->save(); + // connect journal1: + $journal1->tags()->save($tag); + + $result = $this->object->connect($journal2, $tag); + $this->assertTrue($result); + + } + + /** + * Once one or more journals have been accepted by the tag, others must match the asset account + * id. For this to work, we must also create an asset account, and a transaction. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::connect + */ + public function testConnectPaymentNoMatch() + { + $withdrawal = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $deposit = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $transfer = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + + $expense = FactoryMuffin::create('FireflyIII\Models\AccountType'); + $revenue = FactoryMuffin::create('FireflyIII\Models\AccountType'); + $asset = FactoryMuffin::create('FireflyIII\Models\AccountType'); + + $account1 = FactoryMuffin::create('FireflyIII\Models\Account'); + $account2 = FactoryMuffin::create('FireflyIII\Models\Account'); + + + $journal1 = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $journal2 = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + + // transactions for both: + Transaction::create(['account_id' => $account1->id, 'transaction_journal_id' => $journal1->id, 'amount' => 100]); + Transaction::create(['account_id' => $account2->id, 'transaction_journal_id' => $journal2->id, 'amount' => 100]); + + + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + + $journal1->transaction_type_id = $withdrawal->id; + $journal2->transaction_type_id = $deposit->id; + $tag->tagMode = 'advancePayment'; + $account1->account_type_id = $asset->id; + $account2->account_type_id = $asset->id; + + $tag->save(); + $journal1->save(); + $journal2->save(); + $account1->save(); + $account2->save(); + // connect journal1: + $journal1->tags()->save($tag); + + $result = $this->object->connect($journal2, $tag); + // account1 and account2 are different, so false: + $this->assertFalse($result); + + } + + /** + * An advance payment accepts no transfers + * + * @covers FireflyIII\Repositories\Tag\TagRepository::connect + */ + public function testConnectPaymentOneTransfer() + { + $withdrawal = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $deposit = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $transfer = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + + $journal->transaction_type_id = $transfer->id; + $tag->tagMode = 'advancePayment'; + + $tag->save(); + $journal->save(); + + $result = $this->object->connect($journal, $tag); + $this->assertFalse($result); + + } + + /** + * An advance payment accepts only one withdrawal, not two. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::connect + */ + public function testConnectPaymentOneWithdrawal() + { + $withdrawal = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $deposit = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $transfer = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + + $journal->transaction_type_id = $withdrawal->id; + $tag->tagMode = 'advancePayment'; + + $tag->save(); + $journal->save(); + + $result = $this->object->connect($journal, $tag); + $this->assertTrue($result); + + } + + /** + * An advance payment accepts only one withdrawal, not two. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::connect + */ + public function testConnectPaymentTwoWithdrawals() + { + $withdrawal = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $deposit = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $transfer = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $otherJournal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + + $journal->transaction_type_id = $withdrawal->id; + $otherJournal->transaction_type_id = $withdrawal->id; + $tag->tagMode = 'advancePayment'; + + $tag->save(); + $journal->save(); + $otherJournal->save(); + $otherJournal->tags()->save($tag); + + $result = $this->object->connect($journal, $tag); + $this->assertFalse($result); + } /** * @covers FireflyIII\Repositories\Tag\TagRepository::destroy - * @todo Implement testDestroy(). */ public function testDestroy() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + $this->object->destroy($tag); + + $this->assertCount(0, Tag::where('id', $tag->id)->whereNull('deleted_at')->get()); + } /** @@ -60,33 +334,68 @@ class TagRepositoryTest extends TestCase */ public function testGet() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); + $user = FactoryMuffin::create('FireflyIII\User'); + $tag1 = FactoryMuffin::create('FireflyIII\Models\Tag'); + $tag2 = FactoryMuffin::create('FireflyIII\Models\Tag'); + $tag1->tag = 'BBB'; + $tag2->tag = 'AAA'; + $tag1->user_id = $user->id; + $tag2->user_id = $user->id; + + $tag1->save(); + $tag2->save(); + + $this->be($user); + + $set = $this->object->get(); + + $this->assertCount(2, $set); + $this->assertEquals('AAA', $set->first()->tag); } /** * @covers FireflyIII\Repositories\Tag\TagRepository::store - * @todo Implement testStore(). */ public function testStore() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); + $user = FactoryMuffin::create('FireflyIII\User'); + + $data = [ + 'tag' => 'Hello' . rand(1, 100), + 'date' => '2012-01-01', + 'description' => 'Some', + 'latitude' => 12, + 'longitude' => 13, + 'zoomLevel' => 4, + 'tagMode' => 'nothing' + ]; + $this->be($user); + + $tag = $this->object->store($data); + $this->assertEquals($data['tag'], $tag->tag); } /** * @covers FireflyIII\Repositories\Tag\TagRepository::update - * @todo Implement testUpdate(). */ public function testUpdate() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + + + $data = [ + 'tag' => 'Hello' . rand(1, 100), + 'date' => '2012-01-01', + 'description' => 'Some', + 'latitude' => 12, + 'longitude' => 13, + 'zoomLevel' => 4, + 'tagMode' => 'nothing' + ]; + $this->be($tag->user); + + $newTag = $this->object->update($tag, $data); + $this->assertEquals($data['tag'], $newTag->tag); + $this->assertEquals($tag->id, $newTag->id); } }