Start testing new rule actions.

This commit is contained in:
James Cole
2020-08-23 07:42:14 +02:00
parent d89a4d8a54
commit 6e074d9b8b
34 changed files with 608 additions and 246 deletions

View File

@@ -37,18 +37,6 @@ use Log;
*/ */
class TransactionCurrencyFactory class TransactionCurrencyFactory
{ {
/**
* TransactionCurrencyFactory constructor.
*
* @codeCoverageIgnore
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/** /**
* @param array $data * @param array $data
* *

View File

@@ -49,6 +49,7 @@ class AddTag implements ActionInterface
/** /**
* @inheritDoc * @inheritDoc
* @deprecated * @deprecated
* @codeCoverageIgnore
*/ */
public function act(TransactionJournal $journal): bool public function act(TransactionJournal $journal): bool
{ {
@@ -57,6 +58,7 @@ class AddTag implements ActionInterface
$factory = app(TagFactory::class); $factory = app(TagFactory::class);
$factory->setUser($journal->user); $factory->setUser($journal->user);
$tag = $factory->findOrCreate($this->action->action_value); $tag = $factory->findOrCreate($this->action->action_value);
if (null === $tag) { if (null === $tag) {
// could not find, could not create tag. // could not find, could not create tag.
Log::error(sprintf('RuleAction AddTag. Could not find or create tag "%s"', $this->action->action_value)); Log::error(sprintf('RuleAction AddTag. Could not find or create tag "%s"', $this->action->action_value));
@@ -86,12 +88,14 @@ class AddTag implements ActionInterface
$factory = app(TagFactory::class); $factory = app(TagFactory::class);
$factory->setUser(User::find($journal['user_id'])); $factory->setUser(User::find($journal['user_id']));
$tag = $factory->findOrCreate($this->action->action_value); $tag = $factory->findOrCreate($this->action->action_value);
// @codeCoverageIgnoreStart
if (null === $tag) { if (null === $tag) {
// could not find, could not create tag. // could not find, could not create tag.
Log::error(sprintf('RuleAction AddTag. Could not find or create tag "%s"', $this->action->action_value)); Log::error(sprintf('RuleAction AddTag. Could not find or create tag "%s"', $this->action->action_value));
return false; return false;
} }
// @codeCoverageIgnoreEnd
$count = DB::table('tag_transaction_journal') $count = DB::table('tag_transaction_journal')
->where('tag_id', $tag->id) ->where('tag_id', $tag->id)
->where('transaction_journal_id', $journal['transaction_journal_id']) ->where('transaction_journal_id', $journal['transaction_journal_id'])

View File

@@ -48,7 +48,8 @@ class AppendDescription implements ActionInterface
* Append description with X * Append description with X
* *
* @param TransactionJournal $journal * @param TransactionJournal $journal
* * @codeCoverageIgnore
* @deprecated
* @return bool * @return bool
*/ */
public function act(TransactionJournal $journal): bool public function act(TransactionJournal $journal): bool

View File

@@ -46,9 +46,9 @@ class AppendNotes implements ActionInterface
} }
/** /**
* Append notes with X
*
* @param TransactionJournal $journal * @param TransactionJournal $journal
* @deprecated
* @codeCoverageIgnore
* *
* @return bool * @return bool
*/ */
@@ -84,8 +84,6 @@ class AppendNotes implements ActionInterface
$dbNote->noteable_id = (int) $journal['transaction_journal_id']; $dbNote->noteable_id = (int) $journal['transaction_journal_id'];
$dbNote->noteable_type = TransactionJournal::class; $dbNote->noteable_type = TransactionJournal::class;
$dbNote->text = ''; $dbNote->text = '';
} }
Log::debug(sprintf('RuleAction AppendNotes appended "%s" to "%s".', $this->action->action_value, $dbNote->text)); Log::debug(sprintf('RuleAction AppendNotes appended "%s" to "%s".', $this->action->action_value, $dbNote->text));
$text = sprintf('%s%s', $dbNote->text, $this->action->action_value); $text = sprintf('%s%s', $dbNote->text, $this->action->action_value);

View File

@@ -26,7 +26,7 @@ use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use Log; use Log;
use DB;
/** /**
* Class ClearBudget. * Class ClearBudget.
*/ */
@@ -45,8 +45,9 @@ class ClearBudget implements ActionInterface
* Clear all budgets * Clear all budgets
* *
* @param TransactionJournal $journal * @param TransactionJournal $journal
* * @codeCoverageIgnore
* @return bool * @return bool
* @deprecated
*/ */
public function act(TransactionJournal $journal): bool public function act(TransactionJournal $journal): bool
{ {
@@ -63,4 +64,16 @@ class ClearBudget implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
DB::table('budget_transaction_journal')->where('transaction_journal_id', '=', $journal['transaction_journal_id'])->delete();
Log::debug(sprintf('RuleAction ClearBudget removed all budgets from journal %d.', $journal['transaction_journal_id']));
return true;
}
} }

View File

@@ -21,7 +21,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions; namespace FireflyIII\TransactionRules\Actions;
use DB;
use FireflyIII\Models\RuleAction; use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
@@ -45,6 +45,8 @@ class ClearCategory implements ActionInterface
* Clear all categories * Clear all categories
* *
* @param TransactionJournal $journal * @param TransactionJournal $journal
* @codeCoverageIgnore
* @deprecated
* *
* @return bool * @return bool
*/ */
@@ -63,4 +65,16 @@ class ClearCategory implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
DB::table('category_transaction_journal')->where('transaction_journal_id', '=', $journal['transaction_journal_id'])->delete();
Log::debug(sprintf('RuleAction ClearCategory removed all categories from journal %d.', $journal['transaction_journal_id']));
return true;
}
} }

View File

@@ -27,7 +27,7 @@ use FireflyIII\Models\Note;
use FireflyIII\Models\RuleAction; use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use Log; use Log;
use DB;
/** /**
* Class ClearNotes. * Class ClearNotes.
*/ */
@@ -46,7 +46,8 @@ class ClearNotes implements ActionInterface
* Remove notes * Remove notes
* *
* @param TransactionJournal $journal * @param TransactionJournal $journal
* * @codeCoverageIgnore
* @deprecated
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
@@ -62,4 +63,17 @@ class ClearNotes implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
DB::table('notes')
->where('noteable_id', $journal['transaction_journal_id'])
->where('noteable_type', TransactionJournal::class)
->delete();
Log::debug(sprintf('RuleAction ClearNotes removed all notes.'));
return true;
}
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions; namespace FireflyIII\TransactionRules\Actions;
use DB;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\AccountFactory; use FireflyIII\Factory\AccountFactory;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
@@ -31,6 +32,7 @@ use FireflyIII\Models\AccountType;
use FireflyIII\Models\RuleAction; use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType; use FireflyIII\Models\TransactionType;
use FireflyIII\User;
use Log; use Log;
/** /**
@@ -39,8 +41,7 @@ use Log;
*/ */
class ConvertToDeposit implements ActionInterface class ConvertToDeposit implements ActionInterface
{ {
/** @var RuleAction The rule action */ private RuleAction $action;
private $action;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -56,7 +57,7 @@ class ConvertToDeposit implements ActionInterface
* Execute the action. * Execute the action.
* *
* @param TransactionJournal $journal * @param TransactionJournal $journal
* * @deprecated
* @return bool * @return bool
* @throws FireflyException * @throws FireflyException
*/ */
@@ -120,9 +121,9 @@ class ConvertToDeposit implements ActionInterface
* Output is a deposit from C to B. * Output is a deposit from C to B.
* *
* @param TransactionJournal $journal * @param TransactionJournal $journal
*
* @return bool * @return bool
* @throws FireflyException * @throws FireflyException
* @deprecated
*/ */
private function convertTransfer(TransactionJournal $journal): bool private function convertTransfer(TransactionJournal $journal): bool
{ {
@@ -157,12 +158,55 @@ class ConvertToDeposit implements ActionInterface
return true; return true;
} }
/**
* Input is a transfer from A to B.
* Output is a deposit from C to B.
*
* @param array $journal
*
* @return bool
* @throws FireflyException
*/
private function convertTransferArray(array $journal): bool
{
$user = User::find($journal['user_id']);
// find or create revenue account.
/** @var AccountFactory $factory */
$factory = app(AccountFactory::class);
$factory->setUser($user);
// get the action value, or use the original source name in case the action value is empty:
// this becomes a new or existing revenue account.
$revenueName = '' === $this->action->action_value ? $journal['source_account_name'] : $this->action->action_value;
$revenue = $factory->findOrCreate($revenueName, AccountType::REVENUE);
Log::debug(sprintf('ConvertToDeposit. Action value is "%s", revenue name is "%s"', $this->action->action_value, $journal['source_account_name']));
unset($source);
// update source transaction(s) to be revenue account
DB::table('transactions')
->where('transaction_journal_id', '=', $journal['transaction_journal_id'])
->where('amount', '<', 0)
->update(['account_id' => $revenue->id]);
// change transaction type of journal:
$newType = TransactionType::whereType(TransactionType::DEPOSIT)->first();
DB::table('transaction_journals')
->where('id', '=', $journal['transaction_journal_id'])
->update(['transaction_type_id' => $newType->id]);
Log::debug('Converted transfer to deposit.');
return true;
}
/** /**
* Input is a withdrawal from A to B * Input is a withdrawal from A to B
* Is converted to a deposit from C to A. * Is converted to a deposit from C to A.
* *
* @param TransactionJournal $journal * @param TransactionJournal $journal
* * @deprecated
* @return bool * @return bool
* @throws FireflyException * @throws FireflyException
*/ */
@@ -209,4 +253,79 @@ class ConvertToDeposit implements ActionInterface
return true; return true;
} }
/**
* Input is a withdrawal from A to B
* Is converted to a deposit from C to A.
*
* @param array $journal
*
* @return bool
* @throws FireflyException
*/
private function convertWithdrawalArray(array $journal): bool
{
$user = User::find($journal['user_id']);
// find or create revenue account.
/** @var AccountFactory $factory */
$factory = app(AccountFactory::class);
$factory->setUser($user);
// get the action value, or use the original destination name in case the action value is empty:
// this becomes a new or existing revenue account.
$revenueName = '' === $this->action->action_value ? $journal['destination_account_name'] : $this->action->action_value;
$revenue = $factory->findOrCreate($revenueName, AccountType::REVENUE);
Log::debug(sprintf('ConvertToDeposit. Action value is "%s", revenue name is "%s"', $this->action->action_value, $journal['destination_account_name']));
// update the source transaction and put in the new revenue ID.
DB::table('transactions')
->where('transaction_journal_id', '=', $journal['transaction_journal_id'])
->where('amount', '<', 0)
->update(['account_id' => $revenue->id]);
// update the destination transaction and put in the original source account ID.
DB::table('transactions')
->where('transaction_journal_id', '=', $journal['transaction_journal_id'])
->where('amount', '>', 0)
->update(['account_id' => $journal['source_account_id']]);
// change transaction type of journal:
$newType = TransactionType::whereType(TransactionType::DEPOSIT)->first();
DB::table('transaction_journals')
->where('id', '=', $journal['transaction_journal_id'])
->update(['transaction_type_id' => $newType->id]);
Log::debug('Converted withdrawal to deposit.');
return true;
}
/**
* @inheritDoc
* @throws FireflyException
*/
public function actOnArray(array $journal): bool
{
Log::debug(sprintf('Convert journal #%d to deposit.', $journal['transaction_journal_id']));
$type = $journal['transaction_type_type'];
if (TransactionType::DEPOSIT === $type) {
Log::error(sprintf('Journal #%d is already a deposit (rule #%d).', $journal['transaction_journal_id'], $this->action->rule_id));
return false;
}
if (TransactionType::WITHDRAWAL === $type) {
Log::debug('Going to transform a withdrawal to a deposit.');
return $this->convertWithdrawalArray($journal);
}
if (TransactionType::TRANSFER === $type) {
Log::debug('Going to transform a transfer to a deposit.');
return $this->convertTransferArray($journal);
}
return false;
}
} }

View File

@@ -30,7 +30,9 @@ use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType; use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\User;
use Log; use Log;
use DB;
/** /**
* *
@@ -38,8 +40,7 @@ use Log;
*/ */
class ConvertToTransfer implements ActionInterface class ConvertToTransfer implements ActionInterface
{ {
/** @var RuleAction The rule action */ private RuleAction $action;
private $action;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -53,7 +54,8 @@ class ConvertToTransfer implements ActionInterface
/** /**
* Execute the action. * Execute the action.
* * @deprecated
* @codeCoverageIgnore
* @param TransactionJournal $journal * @param TransactionJournal $journal
* *
* @return bool * @return bool
@@ -135,7 +137,8 @@ class ConvertToTransfer implements ActionInterface
/** /**
* A deposit is from Revenue to Asset. * A deposit is from Revenue to Asset.
* We replace the Revenue with another asset. * We replace the Revenue with another asset.
* * @deprecated
* @codeCoverageIgnore
* @param TransactionJournal $journal * @param TransactionJournal $journal
* @param Account $assetAccount * @param Account $assetAccount
* *
@@ -173,7 +176,8 @@ class ConvertToTransfer implements ActionInterface
/** /**
* A withdrawal is from Asset to Expense. * A withdrawal is from Asset to Expense.
* We replace the Expense with another asset. * We replace the Expense with another asset.
* * @deprecated
* @codeCoverageIgnore
* @param TransactionJournal $journal * @param TransactionJournal $journal
* @param Account $assetAccount * @param Account $assetAccount
* *
@@ -207,4 +211,106 @@ class ConvertToTransfer implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
$type = $journal['transaction_type_type'];
$user = User::find($journal['user_id']);
if (TransactionType::TRANSFER === $type) {
Log::error(sprintf('Journal #%d is already a transfer so cannot be converted (rule #%d).', $journal['transaction_journal_id'], $this->action->rule_id));
return false;
}
// find the asset account in the action value.
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($user);
$asset = $repository->findByName($this->action->action_value, [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
if (null === $asset) {
Log::error(sprintf('Journal #%d cannot be converted because no asset with name "%s" exists (rule #%d).', $journal['transaction_journal_id'], $this->action->action_value, $this->action->rule_id));
return false;
}
if (TransactionType::WITHDRAWAL === $type) {
Log::debug('Going to transform a withdrawal to a transfer.');
return $this->convertWithdrawalArray($journal, $asset);
}
if (TransactionType::DEPOSIT === $type) {
Log::debug('Going to transform a deposit to a transfer.');
return $this->convertDepositArray($journal, $asset);
}
return false; // @codeCoverageIgnore
}
/**
* A deposit is from Revenue to Asset.
* We replace the Revenue with another asset.
* @param array $journal
* @param Account $asset
* @return bool
*/
private function convertDepositArray(array $journal, Account $asset): bool
{
if ($journal['destination_account_id'] === $asset->id) {
Log::error(vsprintf('Journal #%d has already has "%s" as a destination asset. ConvertToTransfer failed. (rule #%d).', [$journal['transaction_journal_id'], $asset->name, $this->action->rule_id]));
return false;
}
// update source transaction:
DB::table('transactions')
->where('transaction_journal_id', '=', $journal['transaction_journal_id'])
->where('amount', '<', 0)
->update(['account_id' => $asset->id]);
// change transaction type of journal:
$newType = TransactionType::whereType(TransactionType::TRANSFER)->first();
DB::table('transaction_journals')
->where('id', '=', $journal['transaction_journal_id'])
->update(['transaction_type_id' => $newType->id]);
Log::debug('Converted deposit to transfer.');
return true;
}
/**
* A withdrawal is from Asset to Expense.
* We replace the Expense with another asset.
* @param array $journal
* @param Account $asset
* @return bool
*/
private function convertWithdrawalArray(array $journal, Account $asset): bool
{
if ($journal['source_account_id'] === $asset->id) {
Log::error(vsprintf('Journal #%d has already has "%s" as a source asset. ConvertToTransfer failed. (rule #%d).', [$journal['transaction_journal_id'], $asset->name, $this->action->rule_id]));
return false;
}
// update destination transaction:
DB::table('transactions')
->where('transaction_journal_id', '=', $journal['transaction_journal_id'])
->where('amount', '>', 0)
->update(['account_id' => $asset->id]);
// change transaction type of journal:
$newType = TransactionType::whereType(TransactionType::TRANSFER)->first();
DB::table('transaction_journals')
->where('id', '=', $journal['transaction_journal_id'])
->update(['transaction_type_id' => $newType->id]);
Log::debug('Converted withdrawal to transfer.');
return true;
}
} }

View File

@@ -210,4 +210,12 @@ class ConvertToWithdrawal implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -78,4 +78,12 @@ class DeleteTransaction implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -76,4 +76,12 @@ class LinkToBill implements ActionInterface
return false; return false;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -59,4 +59,12 @@ class PrependDescription implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -68,4 +68,12 @@ class PrependNotes implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -55,4 +55,12 @@ class RemoveAllTags implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -68,4 +68,12 @@ class RemoveTag implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -83,4 +83,12 @@ class SetBudget implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -72,4 +72,12 @@ class SetCategory implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -69,4 +69,12 @@ class SetDescription implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -168,4 +168,12 @@ class SetDestinationAccount implements ActionInterface
Log::debug(sprintf('Found or created expense account #%d ("%s")', $account->id, $account->name)); Log::debug(sprintf('Found or created expense account #%d ("%s")', $account->id, $account->name));
$this->newDestinationAccount = $account; $this->newDestinationAccount = $account;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -68,4 +68,12 @@ class SetNotes implements ActionInterface
return true; return true;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -158,4 +158,12 @@ class SetSourceAccount implements ActionInterface
Log::debug(sprintf('Found or created revenue account #%d ("%s")', $account->id, $account->name)); Log::debug(sprintf('Found or created revenue account #%d ("%s")', $account->id, $account->name));
$this->newSourceAccount = $account; $this->newSourceAccount = $account;
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -184,4 +184,12 @@ class UpdatePiggybank implements ActionInterface
$repository->removeAmount($piggyBank, $amount); $repository->removeAmount($piggyBank, $amount);
$repository->createEventWithJournal($piggyBank, app('steam')->negative($amount), $journal); $repository->createEventWithJournal($piggyBank, app('steam')->negative($amount), $journal);
} }
/**
* @inheritDoc
*/
public function actOnArray(array $journal): bool
{
// TODO: Implement actOnArray() method.
}
} }

View File

@@ -36,6 +36,7 @@ use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\Preference; use FireflyIII\Models\Preference;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\AccountDestroyService;
use Log; use Log;
use Mockery; use Mockery;
use Preferences; use Preferences;
@@ -95,7 +96,10 @@ class AccountFactoryTest extends TestCase
$this->assertEquals(0, $account->order); $this->assertEquals(0, $account->order);
$this->assertNull($account->virtual_balance); $this->assertNull($account->virtual_balance);
$account->forceDelete(); // use delete service:
$service = app(AccountDestroyService::class);
$service->destroy($account, null);
} }
@@ -141,7 +145,9 @@ class AccountFactoryTest extends TestCase
$this->assertNull($account->virtual_balance); $this->assertNull($account->virtual_balance);
$this->assertCount(1, $account->locations()->get()); $this->assertCount(1, $account->locations()->get());
$account->forceDelete(); // use delete service:
$service = app(AccountDestroyService::class);
$service->destroy($account, null);
} }
/** /**
@@ -184,7 +190,9 @@ class AccountFactoryTest extends TestCase
$this->assertNull($account->virtual_balance); $this->assertNull($account->virtual_balance);
$this->assertNull($account->iban); $this->assertNull($account->iban);
$account->forceDelete(); // use delete service:
$service = app(AccountDestroyService::class);
$service->destroy($account, null);
} }
/** /**
@@ -227,7 +235,9 @@ class AccountFactoryTest extends TestCase
$this->assertNull($account->virtual_balance); $this->assertNull($account->virtual_balance);
$this->assertEquals($data['iban'], $account->iban); $this->assertEquals($data['iban'], $account->iban);
$account->forceDelete(); // use delete service:
$service = app(AccountDestroyService::class);
$service->destroy($account, null);
} }
/** /**
@@ -273,7 +283,9 @@ class AccountFactoryTest extends TestCase
$this->assertNull($account->virtual_balance); $this->assertNull($account->virtual_balance);
$this->assertCount(1, $account->transactions()->get()); $this->assertCount(1, $account->transactions()->get());
$account->forceDelete(); // use delete service:
$service = app(AccountDestroyService::class);
$service->destroy($account, null);
} }
/** /**
* Create asset, include opening balance. * Create asset, include opening balance.
@@ -318,7 +330,9 @@ class AccountFactoryTest extends TestCase
$this->assertNull($account->virtual_balance); $this->assertNull($account->virtual_balance);
$this->assertCount(1, $account->transactions()->get()); $this->assertCount(1, $account->transactions()->get());
$account->forceDelete(); // use delete service:
$service = app(AccountDestroyService::class);
$service->destroy($account, null);
} }
/** /**
@@ -364,7 +378,9 @@ class AccountFactoryTest extends TestCase
$this->assertNull($account->virtual_balance); $this->assertNull($account->virtual_balance);
$this->assertCount(0, $account->transactions()->get()); $this->assertCount(0, $account->transactions()->get());
$account->forceDelete(); // use delete service:
$service = app(AccountDestroyService::class);
$service->destroy($account, null);
} }
@@ -410,7 +426,9 @@ class AccountFactoryTest extends TestCase
$this->assertEquals(0, $account->order); $this->assertEquals(0, $account->order);
$this->assertNull($account->virtual_balance); $this->assertNull($account->virtual_balance);
$account->forceDelete(); // use delete service:
$service = app(AccountDestroyService::class);
$service->destroy($account, null);
} }

View File

@@ -73,6 +73,7 @@ class AttachmentFactoryTest extends TestCase
$this->assertEquals($data['title'], $result->title); $this->assertEquals($data['title'], $result->title);
$this->assertEquals(1, $result->notes()->count()); $this->assertEquals(1, $result->notes()->count());
$result->forceDelete();
} }
@@ -104,6 +105,8 @@ class AttachmentFactoryTest extends TestCase
$this->assertEquals(1, $result->notes()->count()); $this->assertEquals(1, $result->notes()->count());
$this->assertEquals($journal->id, $result->attachable_id); $this->assertEquals($journal->id, $result->attachable_id);
$result->forceDelete();
} }
} }

View File

@@ -955,10 +955,7 @@ class OperatorQuerySearchTest extends TestCase
// many results, tricky to verify. // many results, tricky to verify.
$this->assertTrue(count($result) > 2); $this->assertTrue(count($result) > 2);
// TODO better verification.
// the first one should say "Groceries".
$transaction = array_shift($result->first()['transactions']);
$this->assertEquals('Groceries', $transaction['description'] ?? '');
} }
/** /**
@@ -1033,10 +1030,7 @@ class OperatorQuerySearchTest extends TestCase
// many results, tricky to verify. // many results, tricky to verify.
$this->assertTrue(count($result) > 2); $this->assertTrue(count($result) > 2);
// todo verify
// the first one should say "Groceries".
$transaction = array_shift($result->first()['transactions']);
$this->assertEquals('Groceries', $transaction['description'] ?? '');
} }
@@ -1304,10 +1298,8 @@ class OperatorQuerySearchTest extends TestCase
// could have many results, grab first transaction: // could have many results, grab first transaction:
$this->assertTrue( count($result) > 1); $this->assertTrue( count($result) > 1);
$transaction = array_shift($result->first()['transactions']);
// check if result is as expected. // todo better verification
$this->assertEquals('Groceries', $transaction['description'] ?? '');
} }
/** /**

View File

@@ -22,18 +22,15 @@ declare(strict_types=1);
namespace Tests\Unit\TransactionRules\Actions; namespace Tests\Unit\TransactionRules\Actions;
use FireflyIII\Factory\TagFactory;
use FireflyIII\Models\RuleAction; use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\TransactionRules\Actions\AddTag; use FireflyIII\TransactionRules\Actions\AddTag;
use Log; use Log;
use Tests\TestCase; use Tests\TestCase;
/** /**
* Class AddTagTest * Class AddTagTest
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
*/ */
class AddTagTest extends TestCase class AddTagTest extends TestCase
{ {
@@ -42,9 +39,6 @@ class AddTagTest extends TestCase
*/ */
public function setUp(): void public function setUp(): void
{ {
self::markTestIncomplete('Incomplete for refactor.');
return;
parent::setUp(); parent::setUp();
Log::info(sprintf('Now in %s.', get_class($this))); Log::info(sprintf('Now in %s.', get_class($this)));
} }
@@ -54,9 +48,11 @@ class AddTagTest extends TestCase
*/ */
public function testActExistingTag(): void public function testActExistingTag(): void
{ {
$tagFactory = $this->mock(TagFactory::class); /** @var Tag $tag */
$tag = $this->getRandomTag(); $tag = $this->user()->tags()->where('tag', 'RuleActionTag')->first();
$journal = $this->getRandomWithdrawal();
/** @var TransactionJournal $journal */
$journal = $this->user()->transactionJournals()->where('description', 'Rule action test transaction.')->first();
// make sure journal has no tags: // make sure journal has no tags:
$journal->tags()->sync([]); $journal->tags()->sync([]);
@@ -65,18 +61,20 @@ class AddTagTest extends TestCase
// add single existing tag: // add single existing tag:
$journal->tags()->sync([$tag->id]); $journal->tags()->sync([$tag->id]);
$tagFactory->shouldReceive('setUser')->once();
$tagFactory->shouldReceive('findOrCreate')->once()->withArgs([$tag->tag])->andReturn($tag);
// assert connection exists. // assert connection exists.
$this->assertDatabaseHas('tag_transaction_journal', ['tag_id' => $tag->id, 'transaction_journal_id' => $journal->id]); $this->assertDatabaseHas('tag_transaction_journal', ['tag_id' => $tag->id, 'transaction_journal_id' => $journal->id]);
// file action // array with data required:
$array = [
'user_id' => $this->user()->id,
'transaction_journal_id' => $journal->id,
];
// run the action:
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = $tag->tag; $ruleAction->action_value = $tag->tag;
$action = new AddTag($ruleAction); $action = new AddTag($ruleAction);
$result = $action->act($journal); $result = $action->actOnArray($array);
$this->assertFalse($result); $this->assertFalse($result);
// assert DB is unchanged. // assert DB is unchanged.
@@ -89,28 +87,30 @@ class AddTagTest extends TestCase
*/ */
public function testActNewTag(): void public function testActNewTag(): void
{ {
$tagFactory = $this->mock(TagFactory::class); /** @var Tag $tag */
$tag = $this->getRandomTag(); $tag = $this->user()->tags()->where('tag', 'RuleActionTag')->first();
$journal = $this->getRandomWithdrawal();
/** @var TransactionJournal $journal */
$journal = $this->user()->transactionJournals()->where('description', 'Rule action test transaction.')->first();
// make sure journal has no tags: // make sure journal has no tags:
$journal->tags()->sync([]); $journal->tags()->sync([]);
$journal->save(); $journal->save();
$tagFactory->shouldReceive('setUser')->once(); // array with data required:
$tagFactory->shouldReceive('findOrCreate')->once()->withArgs([$tag->tag])->andReturn($tag); $array = [
'user_id' => $this->user()->id,
'transaction_journal_id' => $journal->id,
];
// assert connection does not exist. // run the action:
$this->assertDatabaseMissing('tag_transaction_journal', ['tag_id' => $tag->id, 'transaction_journal_id' => $journal->id]);
// file action
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = $tag->tag; $ruleAction->action_value = $tag->tag;
$action = new AddTag($ruleAction); $action = new AddTag($ruleAction);
$result = $action->act($journal); $result = $action->actOnArray($array);
$this->assertTrue($result); $this->assertTrue($result);
// assert DB is unchanged. // assert DB is updated! Yay!
$this->assertDatabaseHas('tag_transaction_journal', ['tag_id' => $tag->id, 'transaction_journal_id' => $journal->id]); $this->assertDatabaseHas('tag_transaction_journal', ['tag_id' => $tag->id, 'transaction_journal_id' => $journal->id]);
} }
@@ -119,19 +119,34 @@ class AddTagTest extends TestCase
*/ */
public function testActNullTag(): void public function testActNullTag(): void
{ {
// try to add non-existing tag $newTagName = sprintf('TestTag-%d', $this->randomInt());
$tagFactory = $this->mock(TagFactory::class);
$newTagName = 'TestTag-' . $this->randomInt();
// should return null: /** @var TransactionJournal $journal */
$tagFactory->shouldReceive('setUser')->once(); $journal = $this->user()->transactionJournals()->where('description', 'Rule action test transaction.')->first();
$tagFactory->shouldReceive('findOrCreate')->once()->withArgs([$newTagName])->andReturnNull();
$journal = $this->getRandomWithdrawal(); // make sure journal has no tags:
$journal->tags()->sync([]);
$journal->save();
// array with data required:
$array = [
'user_id' => $this->user()->id,
'transaction_journal_id' => $journal->id,
];
// run the action:
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = $newTagName; $ruleAction->action_value = $newTagName;
$action = new AddTag($ruleAction); $action = new AddTag($ruleAction);
$result = $action->act($journal); $result = $action->actOnArray($array);
$this->assertFalse($result); $this->assertTrue($result);
// find the tag in the DB:
$this->assertDatabaseHas('tags', ['tag' => $newTagName]);
$tag = Tag::whereTag($newTagName)->first();
// assert DB is updated! Yay!
$this->assertDatabaseHas('tag_transaction_journal', ['tag_id' => $tag->id, 'transaction_journal_id' => $journal->id]);
} }
} }

View File

@@ -30,9 +30,6 @@ use Tests\TestCase;
/** /**
* Class AppendDescriptionTest * Class AppendDescriptionTest
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
*/ */
class AppendDescriptionTest extends TestCase class AppendDescriptionTest extends TestCase
{ {
@@ -41,9 +38,6 @@ class AppendDescriptionTest extends TestCase
*/ */
public function setUp(): void public function setUp(): void
{ {
self::markTestIncomplete('Incomplete for refactor.');
return;
parent::setUp(); parent::setUp();
Log::info(sprintf('Now in %s.', get_class($this))); Log::info(sprintf('Now in %s.', get_class($this)));
} }
@@ -53,15 +47,26 @@ class AppendDescriptionTest extends TestCase
*/ */
public function testActExistingTag(): void public function testActExistingTag(): void
{ {
/** @var TransactionJournal $journal */
$journal = $this->user()->transactionJournals()->where('description', 'Rule action test transaction.')->first();
$original = $journal->description;
$array = [
'transaction_journal_id' => $journal->id,
'description' => $original,
];
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = 'APPEND'; $ruleAction->action_value = 'APPEND';
$journal = $this->getRandomWithdrawal();
$oldDescription = $journal->description;
$action = new AppendDescription($ruleAction); $action = new AppendDescription($ruleAction);
$result = $action->act($journal); $result = $action->actOnArray($array);
$this->assertTrue($result); $this->assertTrue($result);
$journal = TransactionJournal::find($journal->id); $journal = TransactionJournal::find($journal->id);
$this->assertEquals($oldDescription . 'APPEND', $journal->description); $this->assertEquals(sprintf('%s%s', $original, $ruleAction->action_value), $journal->description);
$journal->description = $original;
$journal->save();
} }
} }

View File

@@ -28,12 +28,9 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\TransactionRules\Actions\AppendNotes; use FireflyIII\TransactionRules\Actions\AppendNotes;
use Log; use Log;
use Tests\TestCase; use Tests\TestCase;
use DB;
/** /**
* Class AppendNotesTest * Class AppendNotesTest
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
*/ */
class AppendNotesTest extends TestCase class AppendNotesTest extends TestCase
{ {
@@ -42,9 +39,6 @@ class AppendNotesTest extends TestCase
*/ */
public function setUp(): void public function setUp(): void
{ {
self::markTestIncomplete('Incomplete for refactor.');
return;
parent::setUp(); parent::setUp();
Log::info(sprintf('Now in %s.', get_class($this))); Log::info(sprintf('Now in %s.', get_class($this)));
} }
@@ -52,52 +46,29 @@ class AppendNotesTest extends TestCase
/** /**
* @covers \FireflyIII\TransactionRules\Actions\AppendNotes * @covers \FireflyIII\TransactionRules\Actions\AppendNotes
*/ */
public function testAct(): void public function testActOnArray(): void
{ {
// give journal some notes. // give journal some notes.
$journal = $this->getRandomWithdrawal(); $journal = $this->user()->transactionJournals()->where('description','Rule action note test transaction.')->first();
$note = $journal->notes()->first();
$start = 'Default note text'; // make sure all notes deleted:
$toAppend = 'This is appended'; DB::table('notes')->where('noteable_id', $journal->id)->where('noteable_type', TransactionJournal::class)->delete();
if (null === $note) {
$note = new Note(); // array for action:
$note->noteable()->associate($journal); $array = [
} 'transaction_journal_id' => $journal->id
$note->text = $start; ];
$note->save(); $toAppend = 'Text to append to note.';
// fire the action: // fire the action:
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = $toAppend; $ruleAction->action_value = $toAppend;
$action = new AppendNotes($ruleAction); $action = new AppendNotes($ruleAction);
$result = $action->act($journal); $result = $action->actOnArray($array);
$this->assertTrue($result);
$newNote = $journal->notes()->first();
$this->assertEquals($start . $toAppend, $newNote->text);
}
/**
* @covers \FireflyIII\TransactionRules\Actions\AppendNotes
*/
public function testActNewNote(): void
{
// give journal some notes.
$journal = TransactionJournal::find(4);
$note = $journal->notes()->first();
if (null !== $note) {
$note->forceDelete();
}
$toAppend = 'This is appended';
// fire the action:
$ruleAction = new RuleAction;
$ruleAction->action_value = $toAppend;
$action = new AppendNotes($ruleAction);
$result = $action->act($journal);
$this->assertTrue($result); $this->assertTrue($result);
$newNote = $journal->notes()->first(); $newNote = $journal->notes()->first();
$this->assertEquals($toAppend, $newNote->text); $this->assertEquals($toAppend, $newNote->text);
} }
} }

View File

@@ -30,9 +30,6 @@ use Tests\TestCase;
/** /**
* Class ClearBudgetTest * Class ClearBudgetTest
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
*/ */
class ClearBudgetTest extends TestCase class ClearBudgetTest extends TestCase
{ {
@@ -41,9 +38,6 @@ class ClearBudgetTest extends TestCase
*/ */
public function setUp(): void public function setUp(): void
{ {
self::markTestIncomplete('Incomplete for refactor.');
return;
parent::setUp(); parent::setUp();
Log::info(sprintf('Now in %s.', get_class($this))); Log::info(sprintf('Now in %s.', get_class($this)));
} }
@@ -54,26 +48,25 @@ class ClearBudgetTest extends TestCase
public function testAct(): void public function testAct(): void
{ {
// associate budget with journal: // associate budget with journal:
$journal = $this->getRandomWithdrawal(); $journal = $this->user()->transactionJournals()->where('description','Rule action test transaction.')->first();
$budget = $this->getRandomBudget(); $budget = $this->user()->budgets()->inRandomOrder()->first();
// link a budget.
$journal->budgets()->save($budget); $journal->budgets()->save($budget);
$this->assertGreaterThan(0, $journal->budgets()->count()); $this->assertGreaterThan(0, $journal->budgets()->count());
$array = [
'transaction_journal_id' => $journal->id
];
// fire the action: // fire the action:
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = null; $ruleAction->action_value = null;
$action = new ClearBudget($ruleAction); $action = new ClearBudget($ruleAction);
$result = $action->act($journal); $result = $action->actOnArray($array);
$this->assertTrue($result); $this->assertTrue($result);
// assert result // assert result
$this->assertEquals(0, $journal->budgets()->count()); $this->assertEquals(0, $journal->budgets()->count());
/** @var Transaction $transaction */
foreach ($journal->transactions as $transaction) {
$this->assertEquals(0, $transaction->budgets()->count());
}
} }
} }

View File

@@ -23,16 +23,12 @@ declare(strict_types=1);
namespace Tests\Unit\TransactionRules\Actions; namespace Tests\Unit\TransactionRules\Actions;
use FireflyIII\Models\RuleAction; use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction;
use FireflyIII\TransactionRules\Actions\ClearCategory; use FireflyIII\TransactionRules\Actions\ClearCategory;
use Log; use Log;
use Tests\TestCase; use Tests\TestCase;
/** /**
* Class ClearCategoryTest * Class ClearCategoryTest
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
*/ */
class ClearCategoryTest extends TestCase class ClearCategoryTest extends TestCase
{ {
@@ -41,9 +37,6 @@ class ClearCategoryTest extends TestCase
*/ */
public function setUp(): void public function setUp(): void
{ {
self::markTestIncomplete('Incomplete for refactor.');
return;
parent::setUp(); parent::setUp();
Log::info(sprintf('Now in %s.', get_class($this))); Log::info(sprintf('Now in %s.', get_class($this)));
} }
@@ -54,24 +47,25 @@ class ClearCategoryTest extends TestCase
public function testAct(): void public function testAct(): void
{ {
// associate budget with journal: // associate budget with journal:
$journal = $this->getRandomWithdrawal(); $journal = $this->user()->transactionJournals()->where('description', 'Rule action test transaction.')->first();
$category = $this->getRandomCategory();; $category = $this->user()->categories()->inRandomOrder()->first();
// link a budget.
$journal->categories()->save($category); $journal->categories()->save($category);
$this->assertGreaterThan(0, $journal->categories()->count()); $this->assertGreaterThan(0, $journal->categories()->count());
$array = [
'transaction_journal_id' => $journal->id,
];
// fire the action: // fire the action:
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = null; $ruleAction->action_value = null;
$action = new ClearCategory($ruleAction); $action = new ClearCategory($ruleAction);
$result = $action->act($journal); $result = $action->actOnArray($array);
$this->assertTrue($result); $this->assertTrue($result);
// assert result // assert result
$this->assertEquals(0, $journal->categories()->count()); $this->assertEquals(0, $journal->categories()->count());
/** @var Transaction $transaction */
foreach ($journal->transactions as $transaction) {
$this->assertEquals(0, $transaction->categories()->count());
}
} }
} }

View File

@@ -32,9 +32,6 @@ use Tests\TestCase;
/** /**
* Class ClearNotesTest * Class ClearNotesTest
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
*/ */
class ClearNotesTest extends TestCase class ClearNotesTest extends TestCase
{ {
@@ -43,9 +40,6 @@ class ClearNotesTest extends TestCase
*/ */
public function setUp(): void public function setUp(): void
{ {
self::markTestIncomplete('Incomplete for refactor.');
return;
parent::setUp(); parent::setUp();
Log::info(sprintf('Now in %s.', get_class($this))); Log::info(sprintf('Now in %s.', get_class($this)));
} }
@@ -56,7 +50,7 @@ class ClearNotesTest extends TestCase
public function testAct(): void public function testAct(): void
{ {
// give journal a note: // give journal a note:
$journal = $this->getRandomWithdrawal(); $journal = $this->user()->transactionJournals()->where('description', 'Rule action test transaction.')->first();
$note = $journal->notes()->first(); $note = $journal->notes()->first();
if (null === $note) { if (null === $note) {
$note = new Note; $note = new Note;
@@ -70,8 +64,13 @@ class ClearNotesTest extends TestCase
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = null; $ruleAction->action_value = null;
$action = new ClearNotes($ruleAction); $action = new ClearNotes($ruleAction);
$array = [
'transaction_journal_id' => $journal->id
];
try { try {
$result = $action->act($journal); $result = $action->actOnArray($array);
} catch (Exception $e) { } catch (Exception $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
Log::error($e->getTraceAsString()); Log::error($e->getTraceAsString());

View File

@@ -26,8 +26,10 @@ namespace Tests\Unit\TransactionRules\Actions;
use Exception; use Exception;
use FireflyIII\Factory\AccountFactory; use FireflyIII\Factory\AccountFactory;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\RuleAction; use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType; use FireflyIII\Models\TransactionType;
use FireflyIII\TransactionRules\Actions\ConvertToDeposit; use FireflyIII\TransactionRules\Actions\ConvertToDeposit;
use Log; use Log;
@@ -36,9 +38,6 @@ use Tests\TestCase;
/** /**
* *
* Class ConvertToDepositTest * Class ConvertToDepositTest
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
*/ */
class ConvertToDepositTest extends TestCase class ConvertToDepositTest extends TestCase
{ {
@@ -47,9 +46,6 @@ class ConvertToDepositTest extends TestCase
*/ */
public function setUp(): void public function setUp(): void
{ {
self::markTestIncomplete('Incomplete for refactor.');
return;
parent::setUp(); parent::setUp();
Log::info(sprintf('Now in %s.', get_class($this))); Log::info(sprintf('Now in %s.', get_class($this)));
} }
@@ -61,35 +57,36 @@ class ConvertToDepositTest extends TestCase
*/ */
public function testActTransfer(): void public function testActTransfer(): void
{ {
$revenue = $this->getRandomRevenue(); /** @var TransactionJournal $transfer */
$name = 'Random revenue #' . $this->randomInt(); $transfer = $this->user()->transactionJournals()->where('description', 'Transfer for convertToDeposit.')->first();
$journal = $this->getRandomTransfer(); $name = sprintf('Random revenue #%d', $this->randomInt());
// journal is a transfer: // journal is a transfer:
$this->assertEquals(TransactionType::TRANSFER, $journal->transactionType->type); $this->assertEquals(TransactionType::TRANSFER, $transfer->transactionType->type);
// mock used stuff:
$factory = $this->mock(AccountFactory::class);
$factory->shouldReceive('setUser')->once();
$factory->shouldReceive('findOrCreate')->once()->withArgs([$name, AccountType::REVENUE])->andReturn($revenue);
// make array for action:
$array = [
'transaction_journal_id' => $transfer->id,
'transaction_type_type' => $transfer->transactionType->type,
'user_id' => $this->user()->id,
'source_account_name' => 'Checking Account',
];
// fire the action: // fire the action:
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = $name; $ruleAction->action_value = $name;
$action = new ConvertToDeposit($ruleAction); $action = new ConvertToDeposit($ruleAction);
try { try {
$result = $action->act($journal); $result = $action->actOnArray($array);
} catch (Exception $e) { } catch (Exception $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
Log::error($e->getTraceAsString()); Log::error($e->getTraceAsString());
$this->assertTrue(false, $e->getMessage()); $this->assertTrue(false, $e->getMessage());
} }
$this->assertTrue($result); $this->assertTrue($result);
// get journal:
// journal is now a deposit. $transfer->refresh();
$journal->refresh(); $this->assertEquals(TransactionType::DEPOSIT, $transfer->transactionType->type);
$this->assertEquals(TransactionType::DEPOSIT, $journal->transactionType->type);
} }
/** /**
@@ -99,36 +96,39 @@ class ConvertToDepositTest extends TestCase
*/ */
public function testActWithdrawal(): void public function testActWithdrawal(): void
{ {
$revenue = $this->getRandomRevenue(); /** @var TransactionJournal $withdrawal */
$name = 'Random revenue #' . $this->randomInt(); $withdrawal = $this->user()->transactionJournals()->where('description', 'Withdrawal for convertToDeposit.')->first();
$journal = $this->getRandomWithdrawal(); $name = sprintf('Random revenue #%d', $this->randomInt());
// journal is a withdrawal: // journal is a withdrawal:
$this->assertEquals(TransactionType::WITHDRAWAL, $journal->transactionType->type); $this->assertEquals(TransactionType::WITHDRAWAL, $withdrawal->transactionType->type);
// mock used stuff: // quick DB search for original source:
$factory = $this->mock(AccountFactory::class); $source = Account::where('name', 'Checking Account')->first();
$factory->shouldReceive('setUser')->once();
$factory->shouldReceive('findOrCreate')->once()->withArgs([$name, AccountType::REVENUE])->andReturn($revenue);
// make array for action:
$array = [
'transaction_journal_id' => $withdrawal->id,
'transaction_type_type' => $withdrawal->transactionType->type,
'user_id' => $this->user()->id,
'destination_account_name' => 'SuperMarket',
'source_account_id' => $source->id,
];
// fire the action: // fire the action:
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = $name; $ruleAction->action_value = $name;
$action = new ConvertToDeposit($ruleAction); $action = new ConvertToDeposit($ruleAction);
try { try {
$result = $action->act($journal); $result = $action->actOnArray($array);
} catch (Exception $e) { } catch (Exception $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
Log::error($e->getTraceAsString()); Log::error($e->getTraceAsString());
$this->assertTrue(false, $e->getMessage()); $this->assertTrue(false, $e->getMessage());
} }
$this->assertTrue($result); $this->assertTrue($result);
// get journal:
// journal is now a deposit. $withdrawal->refresh();
$journal->refresh(); $this->assertEquals(TransactionType::DEPOSIT, $withdrawal->transactionType->type);
$this->assertEquals(TransactionType::DEPOSIT, $journal->transactionType->type);
} }
} }

View File

@@ -25,11 +25,11 @@ namespace Tests\Unit\TransactionRules\Actions;
use Exception; use Exception;
use FireflyIII\Models\AccountType; use FireflyIII\Models\Account;
use FireflyIII\Models\Rule; use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleAction; use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType; use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\TransactionRules\Actions\ConvertToTransfer; use FireflyIII\TransactionRules\Actions\ConvertToTransfer;
use Log; use Log;
use Tests\TestCase; use Tests\TestCase;
@@ -48,9 +48,6 @@ class ConvertToTransferTest extends TestCase
*/ */
public function setUp(): void public function setUp(): void
{ {
self::markTestIncomplete('Incomplete for refactor.');
return;
parent::setUp(); parent::setUp();
Log::info(sprintf('Now in %s.', get_class($this))); Log::info(sprintf('Now in %s.', get_class($this)));
} }
@@ -62,30 +59,33 @@ class ConvertToTransferTest extends TestCase
*/ */
public function testActDeposit(): void public function testActDeposit(): void
{ {
$deposit = $this->getRandomDeposit(); /** @var TransactionJournal $deposit */
$deposit = $this->user()->transactionJournals()->where('description', 'Deposit for ConvertToTransferTest.')->first();
// make sure that $asset is not the destination account of $deposit: // get new source account (replaces the revenue account):
$forbiddenId = (int)$deposit->transactions()->where('amount', '>', 0)->first()->account_id; $newSource = Account::whereName('Savings Account')->first();
$asset = $this->getRandomAsset($forbiddenId); $destination = Account::whereName('Checking Account')->first();
// journal is a withdrawal:
$this->assertEquals(TransactionType::DEPOSIT, $deposit->transactionType->type);
// mock used stuff: // make the required array:
$accountRepos = $this->mock(AccountRepositoryInterface::class); $array = [
$accountRepos->shouldReceive('setUser')->once(); 'transaction_journal_id' => $deposit->id,
$accountRepos->shouldReceive('findByName')->withArgs( 'transaction_type_type' => $deposit->transactionType->type,
[$asset->name, 'user_id' => 1,
[AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]] 'destination_account_id' => $destination->id,
)->andReturn($asset); ];
// fire the action: // fire the action:
$rule = new Rule; $rule = new Rule;
$rule->title = 'OK'; $rule->title = 'OK';
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = $asset->name; $ruleAction->action_value = 'Savings Account';
$ruleAction->rule = $rule; $ruleAction->rule = $rule;
$action = new ConvertToTransfer($ruleAction); $action = new ConvertToTransfer($ruleAction);
try { try {
$result = $action->act($deposit); $result = $action->actOnArray($array);
} catch (Exception $e) { } catch (Exception $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
Log::error($e->getTraceAsString()); Log::error($e->getTraceAsString());
@@ -105,27 +105,30 @@ class ConvertToTransferTest extends TestCase
*/ */
public function testActWithdrawal(): void public function testActWithdrawal(): void
{ {
$withdrawal = $this->getRandomWithdrawal(); /** @var TransactionJournal $withdrawal */
$withdrawal = $this->user()->transactionJournals()->where('description', 'Withdrawal for ConvertToTransferTest.')->first();
// make sure that $asset is not the source account of $withdrawal: // new asset to link to destination of withdrawal:
$forbiddenId = (int)$withdrawal->transactions()->where('amount', '<', 0)->first()->account_id; $newDestination = Account::whereName('Savings Account')->first();
$asset = $this->getRandomAsset($forbiddenId); $source = Account::whereName('Checking Account')->first();
// array with necessary data:
// mock used stuff: $array = [
$accountRepos = $this->mock(AccountRepositoryInterface::class); 'transaction_journal_id' => $withdrawal->id,
$accountRepos->shouldReceive('setUser')->once(); 'transaction_type_type' => $withdrawal->transactionType->type,
$accountRepos->shouldReceive('findByName')->withArgs([$asset->name, [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]])->andReturn($asset); 'user_id' => 1,
'source_account_id' => $source->id,
];
// fire the action: // fire the action:
$rule = new Rule; $rule = new Rule;
$rule->title = 'OK'; $rule->title = 'OK';
$ruleAction = new RuleAction; $ruleAction = new RuleAction;
$ruleAction->action_value = $asset->name; $ruleAction->action_value = $newDestination->name;
$ruleAction->rule = $rule; $ruleAction->rule = $rule;
$action = new ConvertToTransfer($ruleAction); $action = new ConvertToTransfer($ruleAction);
try { try {
$result = $action->act($withdrawal); $result = $action->actOnArray($array);
} catch (Exception $e) { } catch (Exception $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
Log::error($e->getTraceAsString()); Log::error($e->getTraceAsString());