From 85f9c256a1a40de4a396b167a4f5b5bb1a5dc49c Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 8 Jun 2019 06:19:21 +0200 Subject: [PATCH] Refactor some code for recurrences. --- app/Api/V1/Controllers/AccountController.php | 1 - .../V1/Controllers/AttachmentController.php | 1 - app/Api/V1/Requests/Request.php | 7 +- app/Factory/AccountFactory.php | 4 +- app/Factory/BillFactory.php | 6 +- app/Factory/TransactionJournalFactory.php | 4 + .../Chart/Basic/ChartJsGenerator.php | 6 +- .../Report/Tag/MonthReportGenerator.php | 153 +++--- .../Events/StoredGroupEventHandler.php | 4 +- .../Events/UpdatedGroupEventHandler.php | 6 +- .../Events/VersionCheckEventHandler.php | 5 +- .../Internal/Support/BillServiceTrait.php | 1 - .../Support/RecurringTransactionTrait.php | 2 +- .../Support/TransactionServiceTrait.php | 6 +- app/Validation/AccountValidator.php | 32 +- app/Validation/TransactionValidation.php | 13 +- config/app.php | 1 - resources/lang/en_US/validation.php | 1 + .../V1/Controllers/AccountControllerTest.php | 36 +- .../Controllers/AttachmentControllerTest.php | 29 + .../Controllers/RecurrenceControllerTest.php | 519 ++++++------------ 21 files changed, 369 insertions(+), 468 deletions(-) diff --git a/app/Api/V1/Controllers/AccountController.php b/app/Api/V1/Controllers/AccountController.php index b1b343d7e2..73c1ac2839 100644 --- a/app/Api/V1/Controllers/AccountController.php +++ b/app/Api/V1/Controllers/AccountController.php @@ -184,7 +184,6 @@ class AccountController extends Controller * @param Request $request * @param Account $account * - * @codeCoverageIgnore * @return JsonResponse */ public function show(Request $request, Account $account): JsonResponse diff --git a/app/Api/V1/Controllers/AttachmentController.php b/app/Api/V1/Controllers/AttachmentController.php index eaa82e0f07..7525029681 100644 --- a/app/Api/V1/Controllers/AttachmentController.php +++ b/app/Api/V1/Controllers/AttachmentController.php @@ -162,7 +162,6 @@ class AttachmentController extends Controller * * @param Request $request * @param Attachment $attachment - * @codeCoverageIgnore * @return JsonResponse */ public function show(Request $request, Attachment $attachment): JsonResponse diff --git a/app/Api/V1/Requests/Request.php b/app/Api/V1/Requests/Request.php index b1d3bb5d65..073e8b3629 100644 --- a/app/Api/V1/Requests/Request.php +++ b/app/Api/V1/Requests/Request.php @@ -41,7 +41,8 @@ class Request extends FireflyIIIRequest /** * @return array */ - public function getAllAccountData(): array { + public function getAllAccountData(): array + { $active = true; $includeNetWorth = true; if (null !== $this->get('active')) { @@ -194,7 +195,8 @@ class Request extends FireflyIIIRequest * * @return array */ - protected function getRecurrenceTransactionData(): array { + protected function getRecurrenceTransactionData(): array + { $return = []; // transaction data: /** @var array $transactions */ @@ -217,6 +219,7 @@ class Request extends FireflyIIIRequest 'destination_id' => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null, 'destination_name' => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null, 'description' => $transaction['description'], + 'type' => $this->string('type'), ]; } diff --git a/app/Factory/AccountFactory.php b/app/Factory/AccountFactory.php index 186ed37f3b..45b50bab5d 100644 --- a/app/Factory/AccountFactory.php +++ b/app/Factory/AccountFactory.php @@ -112,7 +112,7 @@ class AccountFactory $data['currency_id'] = $currency->id; // remove virtual balance when not an asset account or a liability $canHaveVirtual = [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD]; - if (!\in_array($type->type, $canHaveVirtual, true)) { + if (!in_array($type->type, $canHaveVirtual, true)) { $databaseData['virtual_balance'] = '0'; } @@ -124,7 +124,7 @@ class AccountFactory $return = Account::create($databaseData); $this->updateMetaData($return, $data); - if (\in_array($type->type, $canHaveVirtual, true)) { + if (in_array($type->type, $canHaveVirtual, true)) { if ($this->validIBData($data)) { $this->updateIB($return, $data); } diff --git a/app/Factory/BillFactory.php b/app/Factory/BillFactory.php index 0786eb2e3d..978c10caa4 100644 --- a/app/Factory/BillFactory.php +++ b/app/Factory/BillFactory.php @@ -93,7 +93,7 @@ class BillFactory } /** - * @param int|null $billId + * @param int|null $billId * @param null|string $billName * * @return Bill|null @@ -126,8 +126,10 @@ class BillFactory public function findByName(string $name): ?Bill { $query = sprintf('%%%s%%', $name); + /** @var Bill $first */ + $first = $this->user->bills()->where('name', 'LIKE', $query)->first(); - return $this->user->bills()->where('name', 'LIKE', $query)->first(); + return $first; } /** diff --git a/app/Factory/TransactionJournalFactory.php b/app/Factory/TransactionJournalFactory.php index e20acf56d8..6068e59f9a 100644 --- a/app/Factory/TransactionJournalFactory.php +++ b/app/Factory/TransactionJournalFactory.php @@ -246,6 +246,10 @@ class TransactionJournalFactory $destinationAccount = $this->getAccount($type->type, 'destination', (int)$row['destination_id'], $row['destination_name']); /** double check currencies. */ + $sourceCurrency = $currency; + $destCurrency = $currency; + $sourceForeignCurrency = $foreignCurrency; + $destForeignCurrency = $foreignCurrency; if ($type->type === 'Withdrawal') { // make sure currency is correct. diff --git a/app/Generator/Chart/Basic/ChartJsGenerator.php b/app/Generator/Chart/Basic/ChartJsGenerator.php index f46bd9c211..e146ea8059 100644 --- a/app/Generator/Chart/Basic/ChartJsGenerator.php +++ b/app/Generator/Chart/Basic/ChartJsGenerator.php @@ -61,7 +61,7 @@ class ChartJsGenerator implements GeneratorInterface $amounts = array_column($data, 'amount'); $next = next($amounts); $sortFlag = SORT_ASC; - if (!\is_bool($next) && 1 === bccomp((string)$next, '0')) { + if (!is_bool($next) && 1 === bccomp((string)$next, '0')) { $sortFlag = SORT_DESC; } array_multisort($amounts, $sortFlag, $data); @@ -118,7 +118,7 @@ class ChartJsGenerator implements GeneratorInterface { reset($data); $first = current($data); - $labels = \is_array($first['entries']) ? array_keys($first['entries']) : []; + $labels = is_array($first['entries']) ? array_keys($first['entries']) : []; $chartData = [ 'count' => count($data), @@ -173,7 +173,7 @@ class ChartJsGenerator implements GeneratorInterface // different sort when values are positive and when they're negative. asort($data); $next = next($data); - if (!\is_bool($next) && 1 === bccomp((string)$next, '0')) { + if (!is_bool($next) && 1 === bccomp((string)$next, '0')) { // next is positive, sort other way around. arsort($data); } diff --git a/app/Generator/Report/Tag/MonthReportGenerator.php b/app/Generator/Report/Tag/MonthReportGenerator.php index c85b22ee9e..706bc1da69 100644 --- a/app/Generator/Report/Tag/MonthReportGenerator.php +++ b/app/Generator/Report/Tag/MonthReportGenerator.php @@ -29,7 +29,6 @@ use Carbon\Carbon; use FireflyIII\Generator\Report\ReportGeneratorInterface; use FireflyIII\Generator\Report\Support; use FireflyIII\Helpers\Collector\GroupCollectorInterface; -use FireflyIII\Models\Tag; use FireflyIII\Models\TransactionType; use Illuminate\Support\Collection; use Log; @@ -101,82 +100,6 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface return $result; } - /** - * Get expense collection for report. - * - * @return array - */ - protected function getExpenses(): array - { - if (count($this->expenses) > 0) { - Log::debug('Return previous set of expenses.'); - - return $this->expenses; - } - - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setAccounts($this->accounts)->setRange($this->start, $this->end) - ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) - ->setTags($this->tags)->withAccountInformation(); - - $journals = $collector->getExtractedJournals(); - $this->expenses = $journals; - - return $journals; - } - - /** - * Get the income for this report. - * - * @return array - */ - protected function getIncome(): array - { - if (count($this->income) > 0) { - return $this->income; - } - - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setAccounts($this->accounts)->setRange($this->start, $this->end) - ->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]) - ->setTags($this->tags)->withAccountInformation(); - - $journals = $collector->getExtractedJournals(); - $this->income = $journals; - - return $journals; - } - - /** - * Summarize by tag. - * - * @param array $array - * - * @return array - */ - protected function summarizeByTag(array $array): array - { - $tagIds = array_map('\intval', $this->tags->pluck('id')->toArray()); - $result = []; - /** @var array $journal */ - foreach ($array as $journal) { - /** - * @var int $id - * @var array $tag - */ - foreach ($journal['tags'] as $id => $tag) { - if (in_array($id, $tagIds, true)) { - $result[$id] = $result[$id] ?? '0'; - $result[$id] = bcadd($journal['amount'], $result[$id]); - } - } - } - - return $result; - } - /** * Set the accounts. * @@ -268,4 +191,80 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface return $this; } + + /** + * Get expense collection for report. + * + * @return array + */ + protected function getExpenses(): array + { + if (count($this->expenses) > 0) { + Log::debug('Return previous set of expenses.'); + + return $this->expenses; + } + + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector->setAccounts($this->accounts)->setRange($this->start, $this->end) + ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) + ->setTags($this->tags)->withAccountInformation(); + + $journals = $collector->getExtractedJournals(); + $this->expenses = $journals; + + return $journals; + } + + /** + * Get the income for this report. + * + * @return array + */ + protected function getIncome(): array + { + if (count($this->income) > 0) { + return $this->income; + } + + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector->setAccounts($this->accounts)->setRange($this->start, $this->end) + ->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]) + ->setTags($this->tags)->withAccountInformation(); + + $journals = $collector->getExtractedJournals(); + $this->income = $journals; + + return $journals; + } + + /** + * Summarize by tag. + * + * @param array $array + * + * @return array + */ + protected function summarizeByTag(array $array): array + { + $tagIds = array_map('\intval', $this->tags->pluck('id')->toArray()); + $result = []; + /** @var array $journal */ + foreach ($array as $journal) { + /** + * @var int $id + * @var array $tag + */ + foreach ($journal['tags'] as $id => $tag) { + if (in_array($id, $tagIds, true)) { + $result[$id] = $result[$id] ?? '0'; + $result[$id] = bcadd($journal['amount'], $result[$id]); + } + } + } + + return $result; + } } diff --git a/app/Handlers/Events/StoredGroupEventHandler.php b/app/Handlers/Events/StoredGroupEventHandler.php index 214c7397ee..6b94192bcf 100644 --- a/app/Handlers/Events/StoredGroupEventHandler.php +++ b/app/Handlers/Events/StoredGroupEventHandler.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Events; use FireflyIII\Events\StoredTransactionGroup; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Rule; use FireflyIII\Models\RuleGroup; use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; @@ -39,7 +40,7 @@ class StoredGroupEventHandler * @param StoredTransactionGroup $storedJournalEvent * * @return bool - * @throws \FireflyIII\Exceptions\FireflyException + * @throws FireflyException */ public function processRules(StoredTransactionGroup $storedJournalEvent): bool { @@ -47,6 +48,7 @@ class StoredGroupEventHandler if(false === $storedJournalEvent->applyRules) { return true; } + // TODO fix this die('cannot apply rules yet'); // create objects: /** @var RuleGroupRepositoryInterface $ruleGroupRepos */ diff --git a/app/Handlers/Events/UpdatedGroupEventHandler.php b/app/Handlers/Events/UpdatedGroupEventHandler.php index 8a72c8fade..32a97f2953 100644 --- a/app/Handlers/Events/UpdatedGroupEventHandler.php +++ b/app/Handlers/Events/UpdatedGroupEventHandler.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Events; use FireflyIII\Events\UpdatedTransactionGroup; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Rule; use FireflyIII\Models\RuleGroup; use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; @@ -39,13 +40,14 @@ class UpdatedGroupEventHandler * @param UpdatedTransactionGroup $updatedJournalEvent * * @return bool - * @throws \FireflyIII\Exceptions\FireflyException + * @throws FireflyException */ public function processRules(UpdatedTransactionGroup $updatedJournalEvent): bool { // get all the user's rule groups, with the rules, order by 'order'. $journals = $updatedJournalEvent->transactionGroup->transactionJournals; - + // TODO fix this + die('cannot apply rules yet'); /** @var RuleGroupRepositoryInterface $ruleGroupRepos */ $ruleGroupRepos = app(RuleGroupRepositoryInterface::class); diff --git a/app/Handlers/Events/VersionCheckEventHandler.php b/app/Handlers/Events/VersionCheckEventHandler.php index 5b7efb4e45..9a0029c74c 100644 --- a/app/Handlers/Events/VersionCheckEventHandler.php +++ b/app/Handlers/Events/VersionCheckEventHandler.php @@ -25,7 +25,6 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Events; -use FireflyConfig; use FireflyIII\Events\RequestedVersionCheckStatus; use FireflyIII\Helpers\Update\UpdateTrait; use FireflyIII\Models\Configuration; @@ -71,7 +70,7 @@ class VersionCheckEventHandler } /** @var Configuration $lastCheckTime */ - $lastCheckTime = FireflyConfig::get('last_update_check', time()); + $lastCheckTime = app('fireflyconfig')->get('last_update_check', time()); $now = time(); $diff = $now - $lastCheckTime->data; Log::debug(sprintf('Last check time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff)); @@ -90,6 +89,6 @@ class VersionCheckEventHandler // flash info session()->flash('info', $resultString); } - FireflyConfig::set('last_update_check', time()); + app('fireflyconfig')->set('last_update_check', time()); } } diff --git a/app/Services/Internal/Support/BillServiceTrait.php b/app/Services/Internal/Support/BillServiceTrait.php index a8e6b2f10f..b9ded1d789 100644 --- a/app/Services/Internal/Support/BillServiceTrait.php +++ b/app/Services/Internal/Support/BillServiceTrait.php @@ -66,7 +66,6 @@ trait BillServiceTrait * @param string $note * * @return bool - * @throws \Exception */ public function updateNote(Bill $bill, string $note): bool { diff --git a/app/Services/Internal/Support/RecurringTransactionTrait.php b/app/Services/Internal/Support/RecurringTransactionTrait.php index 4358ba8aca..2a3f14894b 100644 --- a/app/Services/Internal/Support/RecurringTransactionTrait.php +++ b/app/Services/Internal/Support/RecurringTransactionTrait.php @@ -57,7 +57,7 @@ trait RecurringTransactionTrait [ 'recurrence_id' => $recurrence->id, 'repetition_type' => $array['type'], - 'repetition_moment' => $array['moment'], + 'repetition_moment' => $array['moment'] ?? '', 'repetition_skip' => $array['skip'], 'weekend' => $array['weekend'] ?? 1, ] diff --git a/app/Services/Internal/Support/TransactionServiceTrait.php b/app/Services/Internal/Support/TransactionServiceTrait.php index 2cb72011c4..87156a2172 100644 --- a/app/Services/Internal/Support/TransactionServiceTrait.php +++ b/app/Services/Internal/Support/TransactionServiceTrait.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Services\Internal\Support; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\AccountFactory; use FireflyIII\Factory\TransactionCurrencyFactory; use FireflyIII\Models\Account; @@ -75,11 +76,12 @@ trait TransactionServiceTrait /** * @param string|null $expectedType - * @param int|null $accountId + * @param Account|null $account + * @param int|null $accountId * @param string|null $accountName * * @return Account|null - * @throws \FireflyIII\Exceptions\FireflyException + * @throws FireflyException * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function findAccount(?string $expectedType, ?Account $account, ?int $accountId, ?string $accountName): ?Account diff --git a/app/Validation/AccountValidator.php b/app/Validation/AccountValidator.php index 1a92f82da9..0fb79358a7 100644 --- a/app/Validation/AccountValidator.php +++ b/app/Validation/AccountValidator.php @@ -130,7 +130,7 @@ class AccountValidator } /** - * @param int|null $accountId + * @param int|null $accountId * @param string|null $accountName * * @return bool @@ -195,19 +195,23 @@ class AccountValidator */ private function canCreateTypes(array $accountTypes): bool { + Log::debug('Can we create any of these types?', $accountTypes); /** @var string $accountType */ foreach ($accountTypes as $accountType) { if ($this->canCreateType($accountType)) { + Log::debug(sprintf('YES, we can create a %s', $accountType)); + return true; } } + Log::debug('NO, we cant create any of those.'); return false; } /** - * @param array $validTypes - * @param int|null $accountId + * @param array $validTypes + * @param int|null $accountId * @param string|null $accountName * * @return Account|null @@ -282,7 +286,7 @@ class AccountValidator } /** - * @param int|null $accountId + * @param int|null $accountId * @param string|null $accountName * * @return bool @@ -360,7 +364,7 @@ class AccountValidator } /** - * @param int|null $accountId + * @param int|null $accountId * @param string|null $accountName * * @return bool @@ -391,7 +395,7 @@ class AccountValidator } /** - * @param int|null $accountId + * @param int|null $accountId * @param string|null $accountName * * @return bool @@ -409,6 +413,20 @@ class AccountValidator return false; } + // if there's an ID it must be of the "validTypes". + if (null !== $accountId && 0 !== $accountId) { + $found = $this->accountRepository->findNull($accountId); + if (null !== $found) { + $type = $found->accountType->type; + if (in_array($type, $validTypes)) { + return true; + } + $this->destError = (string)trans('validation.withdrawal_dest_bad_data', ['id' => $accountId, 'name' => $accountName]); + + return false; + } + } + // if the account can be created anyway don't need to search. if (true === $this->canCreateTypes($validTypes)) { @@ -420,7 +438,7 @@ class AccountValidator } /** - * @param int|null $accountId + * @param int|null $accountId * @param string|null $accountName * * @return bool diff --git a/app/Validation/TransactionValidation.php b/app/Validation/TransactionValidation.php index badae75a01..0f5b0709e2 100644 --- a/app/Validation/TransactionValidation.php +++ b/app/Validation/TransactionValidation.php @@ -26,8 +26,8 @@ namespace FireflyIII\Validation; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionJournal; -use FireflyIII\Models\TransactionType; use Illuminate\Validation\Validator; +use Log; /** * Trait TransactionValidation @@ -41,15 +41,16 @@ trait TransactionValidation */ public function validateAccountInformation(Validator $validator): void { - $data = $validator->getData(); - $transactions = $data['transactions'] ?? []; + Log::debug('Now in validateAccountInformation()'); + $data = $validator->getData(); + $transactionType = $data['type'] ?? 'invalid'; + $transactions = $data['transactions'] ?? []; /** @var AccountValidator $accountValidator */ $accountValidator = app(AccountValidator::class); - + Log::debug(sprintf('Going to loop %d transaction(s)', count($transactions))); foreach ($transactions as $index => $transaction) { - $transactionType = $transaction['type'] ?? 'invalid'; $accountValidator->setTransactionType($transactionType); // validate source account. @@ -224,7 +225,7 @@ trait TransactionValidation foreach ($transactions as $index => $transaction) { $originalType = $this->getOriginalType($transaction['transaction_journal_id'] ?? 0); - $originalData = $this->getOriginalData($transaction['transaction_journal_id'] ?? 0); + $originalData = $this->getOriginalData($transaction['transaction_journal_id'] ?? 0); $transactionType = $transaction['type'] ?? $originalType; $accountValidator->setTransactionType($transactionType); diff --git a/config/app.php b/config/app.php index a59f29e61e..b0215adb1f 100644 --- a/config/app.php +++ b/config/app.php @@ -87,7 +87,6 @@ return [ FireflyIII\Providers\BudgetServiceProvider::class, FireflyIII\Providers\CategoryServiceProvider::class, FireflyIII\Providers\CurrencyServiceProvider::class, - FireflyIII\Providers\ExportJobServiceProvider::class, FireflyIII\Providers\FireflyServiceProvider::class, FireflyIII\Providers\JournalServiceProvider::class, FireflyIII\Providers\PiggyBankServiceProvider::class, diff --git a/resources/lang/en_US/validation.php b/resources/lang/en_US/validation.php index bcecfe7bf2..6cb0195c7a 100644 --- a/resources/lang/en_US/validation.php +++ b/resources/lang/en_US/validation.php @@ -173,6 +173,7 @@ return [ 'withdrawal_source_need_data' => 'Need to get a valid source account ID and/or valid source account name to continue.', 'withdrawal_source_bad_data' => 'Could not find a valid source account when searching for ID ":id" or name ":name".', 'withdrawal_dest_need_data' => 'Need to get a valid destination account ID and/or valid destination account name to continue.', + 'withdrawal_dest_bad_data' => 'Could not find a valid destination account when searching for ID ":id" or name ":name".', 'deposit_source_need_data' => 'Need to get a valid source account ID and/or valid source account name to continue.', 'deposit_source_bad_data' => 'Could not find a valid source account when searching for ID ":id" or name ":name".', diff --git a/tests/Api/V1/Controllers/AccountControllerTest.php b/tests/Api/V1/Controllers/AccountControllerTest.php index 0c678b3b09..43983d37ed 100644 --- a/tests/Api/V1/Controllers/AccountControllerTest.php +++ b/tests/Api/V1/Controllers/AccountControllerTest.php @@ -57,11 +57,9 @@ class AccountControllerTest extends TestCase // mock repositories $repository = $this->mock(AccountRepositoryInterface::class); - // mock calls: $repository->shouldReceive('setUser')->atLeast()->once(); - // data to submit $data = [ 'name' => 'Some new asset account #' . random_int(1, 10000), @@ -84,6 +82,36 @@ class AccountControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/json'); } + /** + * @covers \FireflyIII\Api\V1\Controllers\AccountController + */ + public function testShow(): void + { + // mock repositories + $repository = $this->mock(AccountRepositoryInterface::class); + $transformer = $this->mock(AccountTransformer::class); + // mock calls: + $repository->shouldReceive('setUser')->atLeast()->once(); + $transformer->shouldReceive('setParameters')->atLeast()->once(); + $transformer->shouldReceive('transform')->atLeast()->once()->andReturn( + [ + 'id' => 1, + 'attributes' => [ + 'name' => 'Account' + ] + ]); + $transformer->shouldReceive('setCurrentScope')->atLeast()->once(); + $transformer->shouldReceive('getDefaultIncludes')->atLeast()->once()->andReturn([]); + $transformer->shouldReceive('getAvailableIncludes')->atLeast()->once()->andReturn([]); + + + // getAccountType + + $account = $this->getRandomAsset(); + $response = $this->get(route('api.v1.accounts.show', [$account->id])); + $response->assertStatus(200); + } + /** * Send correct data. Should call account repository store method. * @@ -214,7 +242,7 @@ class AccountControllerTest extends TestCase public function testStoreNotUnique(): void { // mock repositories - $repository = $this->mock(AccountRepositoryInterface::class); + $repository = $this->mock(AccountRepositoryInterface::class); // mock calls: $repository->shouldReceive('setUser')->atLeast()->once(); @@ -331,7 +359,7 @@ class AccountControllerTest extends TestCase public function testUpdate(): void { // mock repositories - $repository = $this->mock(AccountRepositoryInterface::class); + $repository = $this->mock(AccountRepositoryInterface::class); $transformer = $this->mock(AccountTransformer::class); // mock calls: diff --git a/tests/Api/V1/Controllers/AttachmentControllerTest.php b/tests/Api/V1/Controllers/AttachmentControllerTest.php index 0e93fe529b..891860e812 100644 --- a/tests/Api/V1/Controllers/AttachmentControllerTest.php +++ b/tests/Api/V1/Controllers/AttachmentControllerTest.php @@ -48,6 +48,35 @@ class AttachmentControllerTest extends TestCase Log::info(sprintf('Now in %s.', get_class($this))); } + /** + * Test show attachment. + * @covers \FireflyIII\Api\V1\Controllers\AttachmentController + */ + public function testShow(): void + { + $transformer = $this->mock(AttachmentTransformer::class); + $repository = $this->mock(AttachmentRepositoryInterface::class); + // mock calls: + $repository->shouldReceive('setUser')->atLeast()->once(); + $transformer->shouldReceive('setParameters')->atLeast()->once(); + $transformer->shouldReceive('transform')->atLeast()->once()->andReturn( + [ + 'id' => 1, + 'attributes' => [ + 'file' => 'Test.pdf', + ], + ]); + $transformer->shouldReceive('setCurrentScope')->atLeast()->once(); + $transformer->shouldReceive('getDefaultIncludes')->atLeast()->once()->andReturn([]); + $transformer->shouldReceive('getAvailableIncludes')->atLeast()->once()->andReturn([]); + + $attachment = $this->user()->attachments()->inRandomOrder()->first(); + + // test API + $response = $this->get(route('api.v1.attachments.show', [$attachment->id])); + $response->assertStatus(200); + } + /** * Store a new attachment. * diff --git a/tests/Api/V1/Controllers/RecurrenceControllerTest.php b/tests/Api/V1/Controllers/RecurrenceControllerTest.php index f840453885..3d7ee47660 100644 --- a/tests/Api/V1/Controllers/RecurrenceControllerTest.php +++ b/tests/Api/V1/Controllers/RecurrenceControllerTest.php @@ -24,20 +24,15 @@ declare(strict_types=1); namespace Tests\Api\V1\Controllers; use Carbon\Carbon; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\CategoryFactory; -use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Models\AccountType; use FireflyIII\Models\Recurrence; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; -use FireflyIII\Repositories\User\UserRepositoryInterface; -use FireflyIII\Support\Cronjobs\RecurringCronjob; use FireflyIII\Transformers\RecurrenceTransformer; -use FireflyIII\Transformers\TransactionTransformer; -use Illuminate\Pagination\LengthAwarePaginator; +use FireflyIII\Validation\AccountValidator; use Illuminate\Support\Collection; use Laravel\Passport\Passport; use Log; @@ -68,20 +63,12 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreAssetId(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; + // get a recurrence: /** @var Recurrence $recurrence */ - $recurrence = $this->user()->recurrences()->first(); - - // mock stuff: - $repository = $this->mock(RecurringRepositoryInterface::class); - $factory = $this->mock(CategoryFactory::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $transformer = $this->mock(RecurrenceTransformer::class); - $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); + $recurrence = $this->user()->recurrences()->first(); + $repository = $this->mock(RecurringRepositoryInterface::class); + $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); // mock calls to transformer: $transformer->shouldReceive('setParameters')->withAnyArgs()->atLeast()->once(); @@ -90,28 +77,15 @@ class RecurrenceControllerTest extends TestCase $transformer->shouldReceive('getAvailableIncludes')->withAnyArgs()->atLeast()->once()->andReturn([]); $transformer->shouldReceive('transform')->atLeast()->once()->andReturn(['id' => 5]); + // mock calls to validator: + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['withdrawal']); + $validator->shouldReceive('validateSource')->atLeast()->once()->withArgs([1, null])->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->withArgs([null, null])->andReturn(true); + // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); $repository->shouldReceive('store')->once()->andReturn($recurrence); - // used by the validator to find the source_id: - $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() - ->andReturn(new Collection([$assetAccount])); - - - // entries used by the transformer - $repository->shouldReceive('getNoteText')->andReturn('Note text'); - $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); - $repository->shouldReceive('getXOccurrences')->andReturn([]); - - // entries used by the transformer (the fake entry has a category + a budget): - $factory->shouldReceive('findOrCreate')->andReturn(null); - $budgetRepos->shouldReceive('findNull')->andReturn(null); - - // data to submit $firstDate = new Carbon; $firstDate->addDays(2); @@ -142,8 +116,8 @@ class RecurrenceControllerTest extends TestCase // test API $response = $this->post('/api/v1/recurrences', $data, ['Accept' => 'application/json']); - $response->assertHeader('Content-Type', 'application/vnd.api+json'); $response->assertStatus(200); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); } /** @@ -154,19 +128,13 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreAssetName(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); // mock stuff: - $repository = $this->mock(RecurringRepositoryInterface::class); - $factory = $this->mock(CategoryFactory::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $transformer = $this->mock(RecurrenceTransformer::class); + $repository = $this->mock(RecurringRepositoryInterface::class); + $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); // mock calls to transformer: $transformer->shouldReceive('setParameters')->withAnyArgs()->atLeast()->once(); @@ -175,30 +143,15 @@ class RecurrenceControllerTest extends TestCase $transformer->shouldReceive('getAvailableIncludes')->withAnyArgs()->atLeast()->once()->andReturn([]); $transformer->shouldReceive('transform')->atLeast()->once()->andReturn(['id' => 5]); - $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); + // mock calls to validator: + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['withdrawal']); + $validator->shouldReceive('validateSource')->atLeast()->once()->withArgs([0, 'Checking Account'])->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->withArgs([null, null])->andReturn(true); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); $repository->shouldReceive('store')->once()->andReturn($recurrence); - // used by the validator to find the source_id: - $accountRepos->shouldReceive('getAccountsById')->withArgs([[0]])->once()->andReturn(new Collection); - // used by the validator to find the source_name: - $accountRepos->shouldReceive('findByName')->withArgs(['Checking Account', [AccountType::ASSET]])->once()->andReturn($assetAccount); - - // entries used by the transformer - $repository->shouldReceive('getNoteText')->andReturn('Note text'); - $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); - $repository->shouldReceive('getXOccurrences')->andReturn([]); - - // entries used by the transformer (the fake entry has a category + a budget): - $factory->shouldReceive('findOrCreate')->andReturn(null); - $budgetRepos->shouldReceive('findNull')->andReturn(null); - - // data to submit $firstDate = new Carbon; $firstDate->addDays(2); @@ -230,7 +183,6 @@ class RecurrenceControllerTest extends TestCase // test API $response = $this->post('/api/v1/recurrences', $data, ['Accept' => 'application/json']); $response->assertStatus(200); - $response->assertHeader('Content-Type', 'application/vnd.api+json'); } @@ -242,20 +194,13 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreDeposit(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); // mock stuff: - $repository = $this->mock(RecurringRepositoryInterface::class); - $factory = $this->mock(CategoryFactory::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); - $transformer = $this->mock(RecurrenceTransformer::class); + $repository = $this->mock(RecurringRepositoryInterface::class); + $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); // mock calls to transformer: $transformer->shouldReceive('setParameters')->withAnyArgs()->atLeast()->once(); @@ -265,27 +210,13 @@ class RecurrenceControllerTest extends TestCase $transformer->shouldReceive('transform')->atLeast()->once()->andReturn(['id' => 5]); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); $repository->shouldReceive('store')->once()->andReturn($recurrence); - - // used by the validator to find the source_id: - $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() - ->andReturn(new Collection([$assetAccount])); - - - // entries used by the transformer - $repository->shouldReceive('getNoteText')->andReturn('Note text'); - $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); - $repository->shouldReceive('getXOccurrences')->andReturn([]); - - // entries used by the transformer (the fake entry has a category + a budget): - $factory->shouldReceive('findOrCreate')->andReturn(null); - $budgetRepos->shouldReceive('findNull')->andReturn(null); - + // mock calls to validator: + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['deposit']); + $validator->shouldReceive('validateSource')->atLeast()->once()->withArgs([null, 'Some expense account'])->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->withArgs([1, null])->andReturn(true); // data to submit $firstDate = new Carbon; @@ -331,19 +262,14 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreDestinationId(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); // mock stuff: - $repository = $this->mock(RecurringRepositoryInterface::class); - $factory = $this->mock(CategoryFactory::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $transformer = $this->mock(RecurrenceTransformer::class); + $repository = $this->mock(RecurringRepositoryInterface::class); + $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); + $expenseAccount = $this->getRandomExpense(); // mock calls to transformer: $transformer->shouldReceive('setParameters')->withAnyArgs()->atLeast()->once(); @@ -352,33 +278,14 @@ class RecurrenceControllerTest extends TestCase $transformer->shouldReceive('getAvailableIncludes')->withAnyArgs()->atLeast()->once()->andReturn([]); $transformer->shouldReceive('transform')->atLeast()->once()->andReturn(['id' => 5]); - - $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); - $expenseAccount = $this->user()->accounts()->where('account_type_id', 4)->first(); - // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); $repository->shouldReceive('store')->once()->andReturn($recurrence); - // used by the validator to find the source_id: - $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() - ->andReturn(new Collection([$assetAccount])); - $accountRepos->shouldReceive('getAccountsById')->withArgs([[$expenseAccount->id]])->once() - ->andReturn(new Collection([$expenseAccount])); - - - // entries used by the transformer - $repository->shouldReceive('getNoteText')->andReturn('Note text'); - $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); - $repository->shouldReceive('getXOccurrences')->andReturn([]); - - // entries used by the transformer (the fake entry has a category + a budget): - $factory->shouldReceive('findOrCreate')->andReturn(null); - $budgetRepos->shouldReceive('findNull')->andReturn(null); - + // mock calls to validator: + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['withdrawal']); + $validator->shouldReceive('validateSource')->atLeast()->once()->withArgs([1, null])->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->withArgs([$expenseAccount->id, null])->andReturn(true); // data to submit $firstDate = new Carbon; @@ -424,19 +331,13 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreDestinationName(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); // mock stuff: - $repository = $this->mock(RecurringRepositoryInterface::class); - $factory = $this->mock(CategoryFactory::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $transformer = $this->mock(RecurrenceTransformer::class); + $repository = $this->mock(RecurringRepositoryInterface::class); + $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); // mock calls to transformer: $transformer->shouldReceive('setParameters')->withAnyArgs()->atLeast()->once(); @@ -445,31 +346,17 @@ class RecurrenceControllerTest extends TestCase $transformer->shouldReceive('getAvailableIncludes')->withAnyArgs()->atLeast()->once()->andReturn([]); $transformer->shouldReceive('transform')->atLeast()->once()->andReturn(['id' => 5]); - $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); - $expenseAccount = $this->user()->accounts()->where('account_type_id', 4)->first(); + $expenseAccount = $this->getRandomExpense(); + + // mock calls to validator: + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['withdrawal']); + $validator->shouldReceive('validateSource')->atLeast()->once()->withArgs([1, null])->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->withArgs([null, $expenseAccount->name])->andReturn(true); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); $repository->shouldReceive('store')->once()->andReturn($recurrence); - // used by the validator to find the source_id: - $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() - ->andReturn(new Collection([$assetAccount])); - - - // entries used by the transformer - $repository->shouldReceive('getNoteText')->andReturn('Note text'); - $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); - $repository->shouldReceive('getXOccurrences')->andReturn([]); - - // entries used by the transformer (the fake entry has a category + a budget): - $factory->shouldReceive('findOrCreate')->andReturn(null); - $budgetRepos->shouldReceive('findNull')->andReturn(null); - - // data to submit $firstDate = new Carbon; $firstDate->addDays(2); @@ -501,9 +388,7 @@ class RecurrenceControllerTest extends TestCase // test API $response = $this->post('/api/v1/recurrences', $data, ['Accept' => 'application/json']); - $response->assertStatus(200); - $response->assertHeader('Content-Type', 'application/vnd.api+json'); } @@ -515,42 +400,18 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailBothRepetitions(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var Recurrence $recurrence */ - $recurrence = $this->user()->recurrences()->first(); - // mock stuff: - $repository = $this->mock(RecurringRepositoryInterface::class); - $factory = $this->mock(CategoryFactory::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $transformer = $this->mock(RecurrenceTransformer::class); + $repository = $this->mock(RecurringRepositoryInterface::class); + $validator = $this->mock(AccountValidator::class); + + // mock calls to validator: + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['withdrawal']); + $validator->shouldReceive('validateSource')->atLeast()->once()->withArgs([1, null])->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->withArgs([null, null])->andReturn(true); - $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); - - // used by the validator to find the source_id: - $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() - ->andReturn(new Collection([$assetAccount])); - - - // entries used by the transformer - $repository->shouldReceive('getNoteText')->andReturn('Note text'); - $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); - $repository->shouldReceive('getXOccurrences')->andReturn([]); - - // entries used by the transformer (the fake entry has a category + a budget): - $factory->shouldReceive('findOrCreate')->andReturn(null); - $budgetRepos->shouldReceive('findNull')->andReturn(null); - + $repository->shouldReceive('setUser')->atLeast()->once(); // data to submit $firstDate = new Carbon; @@ -611,32 +472,17 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailForeignCurrency(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var Recurrence $recurrence */ - $recurrence = $this->user()->recurrences()->first(); - // mock stuff: - $repository = $this->mock(RecurringRepositoryInterface::class); - $factory = $this->mock(CategoryFactory::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $transformer = $this->mock(RecurrenceTransformer::class); + $repository = $this->mock(RecurringRepositoryInterface::class); + $validator = $this->mock(AccountValidator::class); - $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); + // mock calls to validator: + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['withdrawal']); + $validator->shouldReceive('validateSource')->atLeast()->once()->withArgs([null, 'Checking Account'])->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->withArgs([null, null])->andReturn(true); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); - - // used by the validator to find the source_id: - $accountRepos->shouldReceive('getAccountsById')->withArgs([[0]])->once()->andReturn(new Collection); - // used by the validator to find the source_name: - $accountRepos->shouldReceive('findByName')->withArgs(['Checking Account', [AccountType::ASSET]])->once()->andReturn($assetAccount); + $repository->shouldReceive('setUser')->atLeast()->once(); // data to submit $firstDate = new Carbon; @@ -691,32 +537,18 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailInvalidDaily(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var Recurrence $recurrence */ - $recurrence = $this->user()->recurrences()->first(); - // mock stuff: - $repository = $this->mock(RecurringRepositoryInterface::class); - $factory = $this->mock(CategoryFactory::class); - $budgetRepos = $this->mock(BudgetRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); - $transformer = $this->mock(RecurrenceTransformer::class); + $repository = $this->mock(RecurringRepositoryInterface::class); + $validator = $this->mock(AccountValidator::class); + // mock calls to validator: + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['withdrawal']); + $validator->shouldReceive('validateSource')->atLeast()->once()->withArgs([1, null])->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->withArgs([null, null])->andReturn(true); - $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); - - // used by the validator to find the source_id: - $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() - ->andReturn(new Collection([$assetAccount])); + $repository->shouldReceive('setUser')->atLeast()->once(); // data to submit $firstDate = new Carbon; @@ -770,43 +602,44 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailInvalidDestinationId(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - /** @var Recurrence $recurrence */ - $recurrence = $this->user()->recurrences()->first(); - // mock stuff: - $repository = $this->mock(RecurringRepositoryInterface::class); + $repository = $this->mock(RecurringRepositoryInterface::class); $factory = $this->mock(CategoryFactory::class); $budgetRepos = $this->mock(BudgetRepositoryInterface::class); $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); + + $assetAccount = $this->getRandomAsset(); + + // mock calls to validator: + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['withdrawal']); + $validator->shouldReceive('validateSource')->atLeast()->once()->withArgs([$assetAccount->id, null])->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->withArgs([$assetAccount->id, null])->andReturn(false); - $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + //$factory->shouldReceive('setUser')->atLeast()->once(); + //$budgetRepos->shouldReceive('setUser')->atLeast()->once(); + //$accountRepos->shouldReceive('setUser')->atLeast()->once(); // used by the validator to find the source_id: - $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() - ->andReturn(new Collection([$assetAccount])); - $accountRepos->shouldReceive('getAccountsById')->withArgs([[$assetAccount->id]])->once() - ->andReturn(new Collection([$assetAccount])); - - - // entries used by the transformer - $repository->shouldReceive('getNoteText')->andReturn('Note text'); - $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); - $repository->shouldReceive('getXOccurrences')->andReturn([]); - - // entries used by the transformer (the fake entry has a category + a budget): - $factory->shouldReceive('findOrCreate')->andReturn(null); - $budgetRepos->shouldReceive('findNull')->andReturn(null); +// $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() +// ->andReturn(new Collection([$assetAccount])); +// $accountRepos->shouldReceive('getAccountsById')->withArgs([[$assetAccount->id]])->once() +// ->andReturn(new Collection([$assetAccount])); +// +// +// // entries used by the transformer +// $repository->shouldReceive('getNoteText')->andReturn('Note text')->atLeast()->once(); +// $repository->shouldReceive('repetitionDescription')->andReturn('Some description.')->atLeast()->once(); +// $repository->shouldReceive('getXOccurrences')->andReturn([])->atLeast()->once(); +// +// // entries used by the transformer (the fake entry has a category + a budget): +// $factory->shouldReceive('findOrCreate')->andReturn(null)->atLeast()->once(); +// $budgetRepos->shouldReceive('findNull')->andReturn(null)->atLeast()->once(); // data to submit @@ -823,7 +656,7 @@ class RecurrenceControllerTest extends TestCase 'amount' => '100', 'currency_id' => '1', 'description' => 'Test description', - 'source_id' => '1', + 'source_id' => $assetAccount->id, 'destination_id' => $assetAccount->id, ], ], @@ -844,8 +677,11 @@ class RecurrenceControllerTest extends TestCase [ 'message' => 'The given data was invalid.', 'errors' => [ - 'transactions.0.destination_id' => [ - 'This value is invalid for this field.', + 'transactions.0.destination_id' => [ + null + ], + 'transactions.0.destination_name' => [ + null ], ], ] @@ -862,9 +698,6 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailInvalidMonthly(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -875,14 +708,15 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $factory->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); // used by the validator to find the source_id: $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() @@ -940,9 +774,6 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailInvalidNdom(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -953,14 +784,15 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $factory->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); // used by the validator to find the source_id: $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() @@ -1018,9 +850,6 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailInvalidNdomCount(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -1031,15 +860,15 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); - + $validator = $this->mock(AccountValidator::class); $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $factory->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); // used by the validator to find the source_id: $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() @@ -1097,9 +926,7 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailInvalidNdomHigh(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -1110,14 +937,15 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $factory->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); // used by the validator to find the source_id: $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() @@ -1175,9 +1003,7 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailInvalidWeekly(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -1188,14 +1014,15 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $factory->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); // used by the validator to find the source_id: $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() @@ -1253,9 +1080,6 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailNoAsset(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -1266,10 +1090,11 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); // mock calls: - $repository->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); // data to submit $firstDate = new Carbon; @@ -1325,9 +1150,7 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailNotAsset(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -1341,10 +1164,11 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); // mock calls: - $repository->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); // used to find the source_id: $accountRepos->shouldReceive('getAccountsById')->withArgs([[$expenseAccount->id]])->once() @@ -1403,9 +1227,7 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailNotAssetName(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -1419,10 +1241,11 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); // mock calls: - $repository->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); // used to find the source_id: $accountRepos->shouldReceive('getAccountsById')->withArgs([[0]])->once() @@ -1488,9 +1311,6 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailRepetitions(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -1501,14 +1321,15 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $factory->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); // used by the validator to find the source_id: $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once() @@ -1558,9 +1379,6 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreFailTransactions(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -1571,14 +1389,15 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $factory->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); // data to submit $firstDate = new Carbon; @@ -1626,9 +1445,6 @@ class RecurrenceControllerTest extends TestCase */ public function testStoreTransfer(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -1639,6 +1455,7 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); // mock calls to transformer: $transformer->shouldReceive('setParameters')->withAnyArgs()->atLeast()->once(); @@ -1651,10 +1468,10 @@ class RecurrenceControllerTest extends TestCase $otherAssetAccount = $this->user()->accounts()->where('account_type_id', 3)->where('id', '!=', $assetAccount->id)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $factory->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); $repository->shouldReceive('store')->once()->andReturn($recurrence); @@ -1664,13 +1481,13 @@ class RecurrenceControllerTest extends TestCase // entries used by the transformer - $repository->shouldReceive('getNoteText')->andReturn('Note text'); - $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); - $repository->shouldReceive('getXOccurrences')->andReturn([]); + $repository->shouldReceive('getNoteText')->andReturn('Note text')->atLeast()->once(); + $repository->shouldReceive('repetitionDescription')->andReturn('Some description.')->atLeast()->once(); + $repository->shouldReceive('getXOccurrences')->andReturn([])->atLeast()->once(); // entries used by the transformer (the fake entry has a category + a budget): - $factory->shouldReceive('findOrCreate')->andReturn(null); - $budgetRepos->shouldReceive('findNull')->andReturn(null); + $factory->shouldReceive('findOrCreate')->andReturn(null)->atLeast()->once(); + $budgetRepos->shouldReceive('findNull')->andReturn(null)->atLeast()->once(); // data to submit @@ -1717,9 +1534,6 @@ class RecurrenceControllerTest extends TestCase */ public function testUpdate(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; /** @var Recurrence $recurrence */ $recurrence = $this->user()->recurrences()->first(); @@ -1730,6 +1544,7 @@ class RecurrenceControllerTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $transformer = $this->mock(RecurrenceTransformer::class); + $validator = $this->mock(AccountValidator::class); // mock calls to transformer: $transformer->shouldReceive('setParameters')->withAnyArgs()->atLeast()->once(); @@ -1741,10 +1556,10 @@ class RecurrenceControllerTest extends TestCase $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); // mock calls: - $repository->shouldReceive('setUser'); - $factory->shouldReceive('setUser'); - $budgetRepos->shouldReceive('setUser'); - $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser')->atLeast()->once(); + $factory->shouldReceive('setUser')->atLeast()->once(); + $budgetRepos->shouldReceive('setUser')->atLeast()->once(); + $accountRepos->shouldReceive('setUser')->atLeast()->once(); $repository->shouldReceive('update')->once()->andReturn($recurrence); @@ -1753,13 +1568,13 @@ class RecurrenceControllerTest extends TestCase // entries used by the transformer - $repository->shouldReceive('getNoteText')->andReturn('Note text'); - $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); - $repository->shouldReceive('getXOccurrences')->andReturn([]); + $repository->shouldReceive('getNoteText')->andReturn('Note text')->atLeast()->once(); + $repository->shouldReceive('repetitionDescription')->andReturn('Some description.')->atLeast()->once(); + $repository->shouldReceive('getXOccurrences')->andReturn([])->atLeast()->once(); // entries used by the transformer (the fake entry has a category + a budget): - $factory->shouldReceive('findOrCreate')->andReturn(null); - $budgetRepos->shouldReceive('findNull')->andReturn(null); + $factory->shouldReceive('findOrCreate')->andReturn(null)->atLeast()->once(); + $budgetRepos->shouldReceive('findNull')->andReturn(null)->atLeast()->once(); // data to submit