diff --git a/app/Http/Controllers/BudgetController.php b/app/Http/Controllers/BudgetController.php index 3b2bdafec1..b36a59c99d 100644 --- a/app/Http/Controllers/BudgetController.php +++ b/app/Http/Controllers/BudgetController.php @@ -276,6 +276,9 @@ class BudgetController extends Controller $cache->addProperty($end); $cache->addProperty('info-income'); + Log::debug(sprintf('infoIncome start is %s', $start->format('Y-m-d'))); + Log::debug(sprintf('infoIncome end is %s', $end->format('Y-m-d'))); + if ($cache->has()) { // @codeCoverageIgnoreStart $result = $cache->get(); @@ -292,18 +295,24 @@ class BudgetController extends Controller $range = Preferences::get('viewRange', '1M')->data; $begin = app('navigation')->subtractPeriod($start, $range, 3); + Log::debug(sprintf('Range is %s', $range)); + Log::debug(sprintf('infoIncome begin is %s', $begin->format('Y-m-d'))); + // get average amount available. $total = '0'; $count = 0; $currentStart = clone $begin; while ($currentStart < $start) { + Log::debug(sprintf('Loop: currentStart is %s', $currentStart->format('Y-m-d'))); $currentEnd = app('navigation')->endOfPeriod($currentStart, $range); $total = bcadd($total, $this->repository->getAvailableBudget($currency, $currentStart, $currentEnd)); $currentStart = app('navigation')->addPeriod($currentStart, $range, 0); ++$count; } + Log::debug('Loop end'); + if (0 === $count) { - $count = 1; // @codeCoverageIgnore + $count = 1; } $result['available'] = bcdiv($total, strval($count)); diff --git a/app/Http/Controllers/Import/IndexController.php b/app/Http/Controllers/Import/IndexController.php index 730f533ba0..b6617e189e 100644 --- a/app/Http/Controllers/Import/IndexController.php +++ b/app/Http/Controllers/Import/IndexController.php @@ -73,7 +73,7 @@ class IndexController extends Controller public function create(string $bank) { if (true === !(config(sprintf('import.enabled.%s', $bank)))) { - throw new FireflyException(sprintf('Cannot import from "%s" at this time.', $bank)); + throw new FireflyException(sprintf('Cannot import from "%s" at this time.', $bank)); // @codeCoverageIgnore } $importJob = $this->repository->create($bank); diff --git a/app/Http/Controllers/Import/PrerequisitesController.php b/app/Http/Controllers/Import/PrerequisitesController.php index 4d8ef3e5f3..9d0755fdbc 100644 --- a/app/Http/Controllers/Import/PrerequisitesController.php +++ b/app/Http/Controllers/Import/PrerequisitesController.php @@ -24,6 +24,7 @@ namespace FireflyIII\Http\Controllers\Import; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Controllers\Controller; +use FireflyIII\Http\Middleware\IsDemoUser; use FireflyIII\Import\Prerequisites\PrerequisitesInterface; use Illuminate\Http\Request; use Log; @@ -33,6 +34,25 @@ use Log; */ class PrerequisitesController extends Controller { + + /** + * + */ + public function __construct() + { + parent::__construct(); + + $this->middleware( + function ($request, $next) { + app('view')->share('mainTitleIcon', 'fa-archive'); + app('view')->share('title', trans('firefly.import_index_title')); + + return $next($request); + } + ); + $this->middleware(IsDemoUser::class); + } + /** * Once there are no prerequisites, this method will create an importjob object and * redirect the user to a view where this object can be used by a bank specific @@ -47,11 +67,11 @@ class PrerequisitesController extends Controller public function index(string $bank) { if (true === !(config(sprintf('import.enabled.%s', $bank)))) { - throw new FireflyException(sprintf('Cannot import from "%s" at this time.', $bank)); + throw new FireflyException(sprintf('Cannot import from "%s" at this time.', $bank)); // @codeCoverageIgnore } $class = strval(config(sprintf('import.prerequisites.%s', $bank))); if (!class_exists($class)) { - throw new FireflyException(sprintf('No class to handle "%s".', $bank)); + throw new FireflyException(sprintf('No class to handle "%s".', $bank)); // @codeCoverageIgnore } /** @var PrerequisitesInterface $object */ @@ -61,7 +81,7 @@ class PrerequisitesController extends Controller if ($object->hasPrerequisites()) { $view = $object->getView(); $parameters = ['title' => strval(trans('firefly.import_index_title')), 'mainTitleIcon' => 'fa-archive']; - $parameters = $object->getViewParameters() + $parameters; + $parameters = array_merge($object->getViewParameters(), $parameters); return view($view, $parameters); } @@ -88,9 +108,14 @@ class PrerequisitesController extends Controller public function post(Request $request, string $bank) { Log::debug(sprintf('Now in postPrerequisites for %s', $bank)); + + if (true === !(config(sprintf('import.enabled.%s', $bank)))) { + throw new FireflyException(sprintf('Cannot import from "%s" at this time.', $bank)); // @codeCoverageIgnore + } + $class = strval(config(sprintf('import.prerequisites.%s', $bank))); if (!class_exists($class)) { - throw new FireflyException(sprintf('Cannot find class %s', $class)); + throw new FireflyException(sprintf('Cannot find class %s', $class)); // @codeCoverageIgnore } /** @var PrerequisitesInterface $object */ $object = app($class); @@ -106,10 +131,8 @@ class PrerequisitesController extends Controller if ($result->count() > 0) { $request->session()->flash('error', $result->first()); - - return redirect(route('import.prerequisites', [$bank])); } - return redirect(route('import.create-job', [$bank])); + return redirect(route('import.prerequisites', [$bank])); } } diff --git a/app/Http/Controllers/Import/StatusController.php b/app/Http/Controllers/Import/StatusController.php index 728f3fe976..267ba7f5e4 100644 --- a/app/Http/Controllers/Import/StatusController.php +++ b/app/Http/Controllers/Import/StatusController.php @@ -56,9 +56,9 @@ class StatusController extends Controller */ public function index(ImportJob $job) { - $statuses = ['configured', 'running', 'finished', 'errored']; + $statuses = ['configured', 'running', 'finished', 'error']; if (!in_array($job->status, $statuses)) { - return redirect(route('import.file.configure', [$job->key])); + return redirect(route('import.configure', [$job->key])); } $subTitle = trans('import.status_sub_title'); $subTitleIcon = 'fa-star'; @@ -108,7 +108,7 @@ class StatusController extends Controller $result['running'] = true; } - // TODO cannot handle 'errored' + // TODO cannot handle 'error' return Response::json($result); } diff --git a/app/Http/Controllers/Json/AutoCompleteController.php b/app/Http/Controllers/Json/AutoCompleteController.php index cfa618e450..3381500649 100644 --- a/app/Http/Controllers/Json/AutoCompleteController.php +++ b/app/Http/Controllers/Json/AutoCompleteController.php @@ -29,6 +29,7 @@ use FireflyIII\Models\AccountType; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Support\CacheProperties; +use Log; use Response; /** @@ -81,7 +82,7 @@ class AutoCompleteController extends Controller $set = $repository->getAccountsByType([AccountType::EXPENSE, AccountType::BENEFICIARY]); $filtered = $set->filter( function (Account $account) { - if ($account->active) { + if ($account->active === true) { return $account; } @@ -138,7 +139,7 @@ class AutoCompleteController extends Controller $set = $repository->getAccountsByType([AccountType::REVENUE]); $filtered = $set->filter( function (Account $account) { - if ($account->active) { + if ($account->active === true) { return $account; } diff --git a/app/Http/Controllers/Json/IntroController.php b/app/Http/Controllers/Json/IntroController.php index a7c19a36a1..986a3b103e 100644 --- a/app/Http/Controllers/Json/IntroController.php +++ b/app/Http/Controllers/Json/IntroController.php @@ -32,6 +32,8 @@ use Response; class IntroController { /** + * Get the intro steps. There are currently no specific routes with an outro step. + * * @param string $route * @param string $specificPage * @@ -39,12 +41,15 @@ class IntroController */ public function getIntroSteps(string $route, string $specificPage = '') { + Log::debug(sprintf('getIntroSteps for route "%s" and page "%s"', $route, $specificPage)); $steps = $this->getBasicSteps($route); $specificSteps = $this->getSpecificSteps($route, $specificPage); if (0 === count($specificSteps)) { + Log::debug(sprintf('No specific steps for route "%s" and page "%s"', $route, $specificPage)); return Response::json($steps); } if ($this->hasOutroStep($route)) { + // @codeCoverageIgnoreStart // save last step: $lastStep = $steps[count($steps) - 1]; // remove last step: @@ -52,6 +57,7 @@ class IntroController // merge arrays and add last step again $steps = array_merge($steps, $specificSteps); $steps[] = $lastStep; + // @codeCoverageIgnoreEnd } if (!$this->hasOutroStep($route)) { $steps = array_merge($steps, $specificSteps); @@ -68,13 +74,16 @@ class IntroController public function hasOutroStep(string $route): bool { $routeKey = str_replace('.', '_', $route); + Log::debug(sprintf('Has outro step for route %s', $routeKey)); $elements = config(sprintf('intro.%s', $routeKey)); if (!is_array($elements)) { return false; } - $keys = array_keys($elements); + Log::debug('Elements is array', $elements); + Log::debug('Keys is', array_keys($elements)); + Log::debug(sprintf('Keys has "outro": %s', var_export(in_array('outro', array_keys($elements)), true))); - return in_array('outro', $keys); + return in_array('outro', array_keys($elements)); } /** @@ -135,6 +144,7 @@ class IntroController $steps[] = $currentStep; } } + Log::debug(sprintf('Total basic steps for %s is %d', $routeKey, count($steps))); return $steps; } @@ -147,7 +157,8 @@ class IntroController */ private function getSpecificSteps(string $route, string $specificPage): array { - $steps = []; + $steps = []; + $routeKey = ''; // user is on page with specific instructions: if (strlen($specificPage) > 0) { @@ -165,6 +176,7 @@ class IntroController } } } + Log::debug(sprintf('Total specific steps for route "%s" and page "%s" (routeKey is "%s") is %d', $route, $specificPage, $routeKey, count($steps))); return $steps; } diff --git a/app/Http/Controllers/Transaction/LinkController.php b/app/Http/Controllers/Transaction/LinkController.php index 584d056244..28b7b78719 100644 --- a/app/Http/Controllers/Transaction/LinkController.php +++ b/app/Http/Controllers/Transaction/LinkController.php @@ -99,13 +99,13 @@ class LinkController extends Controller JournalRepositoryInterface $journalRepository, TransactionJournal $journal ) { + Log::debug('We are here (store)'); $linkInfo = $request->getLinkInfo(); if (0 === $linkInfo['transaction_journal_id']) { Session::flash('error', trans('firefly.invalid_link_selection')); return redirect(route('transactions.show', [$journal->id])); } - $linkType = $repository->find($linkInfo['link_type_id']); $other = $journalRepository->find($linkInfo['transaction_journal_id']); $alreadyLinked = $repository->findLink($journal, $other); if ($alreadyLinked) { @@ -115,22 +115,7 @@ class LinkController extends Controller } Log::debug(sprintf('Journal is %d, opposing is %d', $journal->id, $other->id)); - $journalLink = new TransactionJournalLink; - $journalLink->linkType()->associate($linkType); - if ('inward' === $linkInfo['direction']) { - Log::debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->inward, $other->id, $journal->id)); - $journalLink->source()->associate($other); - $journalLink->destination()->associate($journal); - } - - if ('outward' === $linkInfo['direction']) { - Log::debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->outward, $journal->id, $other->id)); - $journalLink->source()->associate($journal); - $journalLink->destination()->associate($other); - } - - $journalLink->comment = $linkInfo['comments']; - $journalLink->save(); + $repository->storeLink($linkInfo, $other, $journal); Session::flash('success', trans('firefly.journals_linked')); return redirect(route('transactions.show', [$journal->id])); diff --git a/app/Http/Controllers/Transaction/SingleController.php b/app/Http/Controllers/Transaction/SingleController.php index 81af686ba3..1e208acdd9 100644 --- a/app/Http/Controllers/Transaction/SingleController.php +++ b/app/Http/Controllers/Transaction/SingleController.php @@ -143,7 +143,7 @@ class SingleController extends Controller ]; /** @var Note $note */ - $note = $journal->notes()->first(); + $note = $this->repository->getNote($journal); if (null !== $note) { $preFilled['notes'] = $note->text; } @@ -302,7 +302,7 @@ class SingleController extends Controller 'destination_currency' => $foreignCurrency, ]; /** @var Note $note */ - $note = $journal->notes()->first(); + $note = $this->repository->getNote($journal); if (null !== $note) { $preFilled['notes'] = $note->text; } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 5535a78fe0..707ceb5d7a 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -47,6 +47,7 @@ use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\View\Middleware\ShareErrorsFromSession; /** + * @CodeCoverageIgnore * Class Kernel */ class Kernel extends HttpKernel diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php index a6ffca4c70..67f34aa46d 100644 --- a/app/Http/Middleware/EncryptCookies.php +++ b/app/Http/Middleware/EncryptCookies.php @@ -25,6 +25,7 @@ namespace FireflyIII\Http\Middleware; use Illuminate\Cookie\Middleware\EncryptCookies as Middleware; /** + * @CodeCoverageIgnore * Class EncryptCookies */ class EncryptCookies extends Middleware diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index 528f5b24f2..ad5d2a13db 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -26,6 +26,7 @@ use Closure; use Illuminate\Support\Facades\Auth; /** + * @CodeCoverageIgnore * Class RedirectIfAuthenticated */ class RedirectIfAuthenticated diff --git a/app/Http/Middleware/TrimStrings.php b/app/Http/Middleware/TrimStrings.php index 28c17c0320..3ce421e223 100644 --- a/app/Http/Middleware/TrimStrings.php +++ b/app/Http/Middleware/TrimStrings.php @@ -25,6 +25,7 @@ namespace FireflyIII\Http\Middleware; use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware; /** + * @CodeCoverageIgnore * Class TrimStrings */ class TrimStrings extends Middleware diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php index 533efa4c71..698511a788 100644 --- a/app/Http/Middleware/TrustProxies.php +++ b/app/Http/Middleware/TrustProxies.php @@ -27,6 +27,7 @@ use Illuminate\Contracts\Config\Repository; use Illuminate\Http\Request; /** + * @CodeCoverageIgnore * Class TrustProxies */ class TrustProxies extends Middleware diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 83f86be647..446047813f 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -25,6 +25,7 @@ namespace FireflyIII\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; /** + * @CodeCoverageIgnore * Class VerifyCsrfToken */ class VerifyCsrfToken extends Middleware diff --git a/app/Http/Requests/AttachmentFormRequest.php b/app/Http/Requests/AttachmentFormRequest.php index 0347d6024f..fe28f9a3a8 100644 --- a/app/Http/Requests/AttachmentFormRequest.php +++ b/app/Http/Requests/AttachmentFormRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class AttachmentFormRequest. */ class AttachmentFormRequest extends Request diff --git a/app/Http/Requests/BillFormRequest.php b/app/Http/Requests/BillFormRequest.php index 2e70ed4fa8..0012197b44 100644 --- a/app/Http/Requests/BillFormRequest.php +++ b/app/Http/Requests/BillFormRequest.php @@ -64,9 +64,9 @@ class BillFormRequest extends Request { $nameRule = 'required|between:1,255|uniqueObjectForUser:bills,name'; $matchRule = 'required|between:1,255|uniqueObjectForUser:bills,match'; - if (intval($this->get('id')) > 0) { - $nameRule .= ',' . intval($this->get('id')); - $matchRule .= ',' . intval($this->get('id')); + if ($this->integer('id') > 0) { + $nameRule .= ',' . $this->integer('id'); + $matchRule .= ',' . $this->integer('id'); } // is OK $rules = [ diff --git a/app/Http/Requests/BudgetFormRequest.php b/app/Http/Requests/BudgetFormRequest.php index c4567795f5..1044e3ab4e 100644 --- a/app/Http/Requests/BudgetFormRequest.php +++ b/app/Http/Requests/BudgetFormRequest.php @@ -25,6 +25,7 @@ namespace FireflyIII\Http\Requests; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; /** + * @CodeCoverageIgnore * Class BudgetFormRequest. */ class BudgetFormRequest extends Request diff --git a/app/Http/Requests/BudgetIncomeRequest.php b/app/Http/Requests/BudgetIncomeRequest.php index a862fea05f..d27f9a76f2 100644 --- a/app/Http/Requests/BudgetIncomeRequest.php +++ b/app/Http/Requests/BudgetIncomeRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class BudgetIncomeRequest. */ class BudgetIncomeRequest extends Request diff --git a/app/Http/Requests/CategoryFormRequest.php b/app/Http/Requests/CategoryFormRequest.php index 9fb8057e0c..f48a2d7c21 100644 --- a/app/Http/Requests/CategoryFormRequest.php +++ b/app/Http/Requests/CategoryFormRequest.php @@ -56,8 +56,8 @@ class CategoryFormRequest extends Request /** @var CategoryRepositoryInterface $repository */ $repository = app(CategoryRepositoryInterface::class); $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name'; - if (null !== $repository->find(intval($this->get('id')))->id) { - $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,' . intval($this->get('id')); + if (null !== $repository->find($this->integer('id'))->id) { + $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,' . $this->integer('id'); } // fixed diff --git a/app/Http/Requests/ConfigurationRequest.php b/app/Http/Requests/ConfigurationRequest.php index db80a3a8a7..ec2831d74c 100644 --- a/app/Http/Requests/ConfigurationRequest.php +++ b/app/Http/Requests/ConfigurationRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class ConfigurationRequest. */ class ConfigurationRequest extends Request diff --git a/app/Http/Requests/CurrencyFormRequest.php b/app/Http/Requests/CurrencyFormRequest.php index 77043798dd..5e1249bddf 100644 --- a/app/Http/Requests/CurrencyFormRequest.php +++ b/app/Http/Requests/CurrencyFormRequest.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** - * Class BillFormRequest. + * Class CurrencyFormRequest. */ class CurrencyFormRequest extends Request { @@ -61,7 +61,7 @@ class CurrencyFormRequest extends Request 'symbol' => 'required|min:1|max:8|unique:transaction_currencies,symbol', 'decimal_places' => 'required|min:0|max:12|numeric', ]; - if (intval($this->get('id')) > 0) { + if ($this->integer('id') > 0) { $rules = [ 'name' => 'required|max:48|min:1', 'code' => 'required|min:3|max:3', diff --git a/app/Http/Requests/DeleteAccountFormRequest.php b/app/Http/Requests/DeleteAccountFormRequest.php index dd8065d743..5cc47f5621 100644 --- a/app/Http/Requests/DeleteAccountFormRequest.php +++ b/app/Http/Requests/DeleteAccountFormRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class DeleteAccountFormRequest. */ class DeleteAccountFormRequest extends Request diff --git a/app/Http/Requests/EmailFormRequest.php b/app/Http/Requests/EmailFormRequest.php index 5dd3cd2dd2..7bbd217b03 100644 --- a/app/Http/Requests/EmailFormRequest.php +++ b/app/Http/Requests/EmailFormRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class EmailFormRequest. */ class EmailFormRequest extends Request diff --git a/app/Http/Requests/ImportUploadRequest.php b/app/Http/Requests/ImportUploadRequest.php deleted file mode 100644 index 5bb61dcb24..0000000000 --- a/app/Http/Requests/ImportUploadRequest.php +++ /dev/null @@ -1,53 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Http\Requests; - -/** - * Class ImportUploadRequest. - */ -class ImportUploadRequest extends Request -{ - /** - * @return bool - */ - public function authorize() - { - // Only allow logged in users - return auth()->check(); - } - - /** - * @return array - */ - public function rules() - { - // fixed - $types = array_keys(config('firefly.import_formats')); - - return [ - 'import_file' => 'required|file', - 'import_file_type' => 'required|in:' . join(',', $types), - 'configuration_file' => 'file', - ]; - } -} diff --git a/app/Http/Requests/MassDeleteJournalRequest.php b/app/Http/Requests/MassDeleteJournalRequest.php index 274acff2fc..55b46997ce 100644 --- a/app/Http/Requests/MassDeleteJournalRequest.php +++ b/app/Http/Requests/MassDeleteJournalRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class MassDeleteJournalRequest. */ class MassDeleteJournalRequest extends Request diff --git a/app/Http/Requests/MassEditJournalRequest.php b/app/Http/Requests/MassEditJournalRequest.php index 9ea17f8727..2d932c47b6 100644 --- a/app/Http/Requests/MassEditJournalRequest.php +++ b/app/Http/Requests/MassEditJournalRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class MassEditJournalRequest. */ class MassEditJournalRequest extends Request diff --git a/app/Http/Requests/NewUserFormRequest.php b/app/Http/Requests/NewUserFormRequest.php index f687019ba4..5dba97d13b 100644 --- a/app/Http/Requests/NewUserFormRequest.php +++ b/app/Http/Requests/NewUserFormRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class NewUserFormRequest. */ class NewUserFormRequest extends Request diff --git a/app/Http/Requests/PiggyBankFormRequest.php b/app/Http/Requests/PiggyBankFormRequest.php index 5d1284ebe9..76cd62e376 100644 --- a/app/Http/Requests/PiggyBankFormRequest.php +++ b/app/Http/Requests/PiggyBankFormRequest.php @@ -57,8 +57,8 @@ class PiggyBankFormRequest extends Request public function rules() { $nameRule = 'required|between:1,255|uniquePiggyBankForUser'; - if (intval($this->get('id'))) { - $nameRule = 'required|between:1,255|uniquePiggyBankForUser:' . intval($this->get('id')); + if ($this->integer('id')) { + $nameRule = 'required|between:1,255|uniquePiggyBankForUser:' . $this->integer('id'); } $rules = [ diff --git a/app/Http/Requests/ProfileFormRequest.php b/app/Http/Requests/ProfileFormRequest.php index 66f82b1436..1b69865ff3 100644 --- a/app/Http/Requests/ProfileFormRequest.php +++ b/app/Http/Requests/ProfileFormRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class ProfileFormRequest. */ class ProfileFormRequest extends Request diff --git a/app/Http/Requests/ReconciliationFormRequest.php b/app/Http/Requests/ReconciliationFormRequest.php index a915420310..8e657537d6 100644 --- a/app/Http/Requests/ReconciliationFormRequest.php +++ b/app/Http/Requests/ReconciliationFormRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class ReconciliationFormRequest. */ class ReconciliationFormRequest extends Request diff --git a/app/Http/Requests/SelectTransactionsRequest.php b/app/Http/Requests/SelectTransactionsRequest.php index e0bc80f942..92fbd5d1e6 100644 --- a/app/Http/Requests/SelectTransactionsRequest.php +++ b/app/Http/Requests/SelectTransactionsRequest.php @@ -25,6 +25,7 @@ namespace FireflyIII\Http\Requests; use Carbon\Carbon; /** + * @CodeCoverageIgnore * Class ExportFormRequest. */ class SelectTransactionsRequest extends Request diff --git a/app/Http/Requests/TestRuleFormRequest.php b/app/Http/Requests/TestRuleFormRequest.php index f81cdb480b..348530c429 100644 --- a/app/Http/Requests/TestRuleFormRequest.php +++ b/app/Http/Requests/TestRuleFormRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class RuleFormRequest. */ class TestRuleFormRequest extends Request diff --git a/app/Http/Requests/TokenFormRequest.php b/app/Http/Requests/TokenFormRequest.php index 47c391f45e..5911cc5c96 100644 --- a/app/Http/Requests/TokenFormRequest.php +++ b/app/Http/Requests/TokenFormRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class TokenFormRequest. */ class TokenFormRequest extends Request diff --git a/app/Http/Requests/UserFormRequest.php b/app/Http/Requests/UserFormRequest.php index e12f8df884..0c29a0366a 100644 --- a/app/Http/Requests/UserFormRequest.php +++ b/app/Http/Requests/UserFormRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class UserFormRequest. */ class UserFormRequest extends Request diff --git a/app/Http/Requests/UserRegistrationRequest.php b/app/Http/Requests/UserRegistrationRequest.php index 7b0143473e..c0b074bae7 100644 --- a/app/Http/Requests/UserRegistrationRequest.php +++ b/app/Http/Requests/UserRegistrationRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Requests; /** + * @CodeCoverageIgnore * Class UserRegistrationRequest. */ class UserRegistrationRequest extends Request diff --git a/app/Models/ImportJob.php b/app/Models/ImportJob.php index 9cea534117..40296bb818 100644 --- a/app/Models/ImportJob.php +++ b/app/Models/ImportJob.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Models; use Crypt; +use FireflyIII\Exceptions\FireflyException; use Illuminate\Database\Eloquent\Model; use Log; use Storage; @@ -33,6 +34,18 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; */ class ImportJob extends Model { + /** + * @var array + */ + public $validStatus + = [ + 'new', + 'configuring', + 'configured', + 'running', + 'error', + 'finished', + ]; /** * The attributes that should be casted to native types. * @@ -44,30 +57,24 @@ class ImportJob extends Model 'updated_at' => 'datetime', ]; - /** - * @var array - */ - protected $validStatus - = [ - 'new', - 'initialized', - 'configured', - 'running', - 'finished', - ]; - /** * @param $value * * @return mixed * * @throws NotFoundHttpException + * @throws FireflyException */ public static function routeBinder($value) { if (auth()->check()) { + /** @var ImportJob $model */ $model = self::where('key', $value)->where('user_id', auth()->user()->id)->first(); if (null !== $model) { + // must have valid status: + if (!in_array($model->status, $model->validStatus)) { + throw new FireflyException(sprintf('Job with key "%s" has invalid status "%s"', $model->key, $model->status)); + } return $model; } } @@ -112,12 +119,20 @@ class ImportJob extends Model } /** - * @param $status + * @param string $status + * + * @throws FireflyException */ - public function change($status) + public function change(string $status): void { - $this->status = $status; - $this->save(); + if (in_array($status, $this->validStatus)) { + $this->status = $status; + $this->save(); + + return; + } + throw new FireflyException(sprintf('Status "%s" is invalid for job "%s".', $status, $this->key)); + } /** diff --git a/app/Providers/AccountServiceProvider.php b/app/Providers/AccountServiceProvider.php index 568f3c5d74..53af837ff2 100644 --- a/app/Providers/AccountServiceProvider.php +++ b/app/Providers/AccountServiceProvider.php @@ -30,6 +30,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class AccountServiceProvider. */ class AccountServiceProvider extends ServiceProvider diff --git a/app/Providers/AdminServiceProvider.php b/app/Providers/AdminServiceProvider.php index b6a04c509d..b781131e48 100644 --- a/app/Providers/AdminServiceProvider.php +++ b/app/Providers/AdminServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class AdminServiceProvider */ class AdminServiceProvider extends ServiceProvider diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 60e94fbe18..19df748bcb 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -26,6 +26,7 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class AppServiceProvider. */ class AppServiceProvider extends ServiceProvider diff --git a/app/Providers/AttachmentServiceProvider.php b/app/Providers/AttachmentServiceProvider.php index 896a486ff3..08fcbef70b 100644 --- a/app/Providers/AttachmentServiceProvider.php +++ b/app/Providers/AttachmentServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class AttachmentServiceProvider. */ class AttachmentServiceProvider extends ServiceProvider diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 45011a76cc..4f9e93b961 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -25,6 +25,7 @@ namespace FireflyIII\Providers; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; /** + * @CodeCoverageIgnore * Class AuthServiceProvider */ class AuthServiceProvider extends ServiceProvider diff --git a/app/Providers/BillServiceProvider.php b/app/Providers/BillServiceProvider.php index 27abecd872..77454619f3 100644 --- a/app/Providers/BillServiceProvider.php +++ b/app/Providers/BillServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class BillServiceProvider. */ class BillServiceProvider extends ServiceProvider diff --git a/app/Providers/BroadcastServiceProvider.php b/app/Providers/BroadcastServiceProvider.php index 5ad85e848f..b11a7aa20d 100644 --- a/app/Providers/BroadcastServiceProvider.php +++ b/app/Providers/BroadcastServiceProvider.php @@ -26,6 +26,7 @@ use Illuminate\Support\Facades\Broadcast; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class BroadcastServiceProvider */ class BroadcastServiceProvider extends ServiceProvider diff --git a/app/Providers/BudgetServiceProvider.php b/app/Providers/BudgetServiceProvider.php index 39d60607a3..33d8e6205b 100644 --- a/app/Providers/BudgetServiceProvider.php +++ b/app/Providers/BudgetServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class BudgetServiceProvider. */ class BudgetServiceProvider extends ServiceProvider diff --git a/app/Providers/CategoryServiceProvider.php b/app/Providers/CategoryServiceProvider.php index 3e5fe663b4..841dfb02d1 100644 --- a/app/Providers/CategoryServiceProvider.php +++ b/app/Providers/CategoryServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class CategoryServiceProvider. */ class CategoryServiceProvider extends ServiceProvider diff --git a/app/Providers/CurrencyServiceProvider.php b/app/Providers/CurrencyServiceProvider.php index 22659b31aa..fd5e158acf 100644 --- a/app/Providers/CurrencyServiceProvider.php +++ b/app/Providers/CurrencyServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class CurrencyServiceProvider. */ class CurrencyServiceProvider extends ServiceProvider diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 9f735945f1..dbdca29986 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -39,6 +39,7 @@ use Log; class EventServiceProvider extends ServiceProvider { /** + * @CodeCoverageIgnore * The event listener mappings for the application. * * @var array @@ -82,6 +83,7 @@ class EventServiceProvider extends ServiceProvider ]; /** + * @CodeCoverageIgnore * Register any events for your application. */ public function boot() diff --git a/app/Providers/ExportJobServiceProvider.php b/app/Providers/ExportJobServiceProvider.php index 994570f7b2..f876a2b7e6 100644 --- a/app/Providers/ExportJobServiceProvider.php +++ b/app/Providers/ExportJobServiceProvider.php @@ -30,6 +30,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class ExportJobServiceProvider. */ class ExportJobServiceProvider extends ServiceProvider diff --git a/app/Providers/FireflyServiceProvider.php b/app/Providers/FireflyServiceProvider.php index 651f7a4766..e0cb9bb460 100644 --- a/app/Providers/FireflyServiceProvider.php +++ b/app/Providers/FireflyServiceProvider.php @@ -69,6 +69,7 @@ use TwigBridge\Extension\Loader\Functions; use Validator; /** + * @CodeCoverageIgnore * Class FireflyServiceProvider. */ class FireflyServiceProvider extends ServiceProvider diff --git a/app/Providers/FireflySessionProvider.php b/app/Providers/FireflySessionProvider.php index ae86562b34..cd72eacabb 100644 --- a/app/Providers/FireflySessionProvider.php +++ b/app/Providers/FireflySessionProvider.php @@ -27,6 +27,7 @@ use Illuminate\Session\SessionManager; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class FireflySessionProvider */ class FireflySessionProvider extends ServiceProvider diff --git a/app/Providers/JournalServiceProvider.php b/app/Providers/JournalServiceProvider.php index 16b5b2e913..92948e9110 100644 --- a/app/Providers/JournalServiceProvider.php +++ b/app/Providers/JournalServiceProvider.php @@ -32,6 +32,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class JournalServiceProvider. */ class JournalServiceProvider extends ServiceProvider diff --git a/app/Providers/LogServiceProvider.php b/app/Providers/LogServiceProvider.php index 74e0be4043..46fc094a1b 100644 --- a/app/Providers/LogServiceProvider.php +++ b/app/Providers/LogServiceProvider.php @@ -26,6 +26,7 @@ use Illuminate\Log\LogServiceProvider as LaravelLogServiceProvider; use Illuminate\Log\Writer; /** + * @CodeCoverageIgnore * Class LogServiceProvider. */ class LogServiceProvider extends LaravelLogServiceProvider diff --git a/app/Providers/PiggyBankServiceProvider.php b/app/Providers/PiggyBankServiceProvider.php index 5ea1f128c6..815306fbd4 100644 --- a/app/Providers/PiggyBankServiceProvider.php +++ b/app/Providers/PiggyBankServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class PiggyBankServiceProvider. */ class PiggyBankServiceProvider extends ServiceProvider diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index ebba825244..a21e44e86d 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -26,6 +26,7 @@ use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvi use Illuminate\Support\Facades\Route; /** + * @CodeCoverageIgnore * Class RouteServiceProvider */ class RouteServiceProvider extends ServiceProvider diff --git a/app/Providers/RuleGroupServiceProvider.php b/app/Providers/RuleGroupServiceProvider.php index 7c5c50bcd0..8b85a844a7 100644 --- a/app/Providers/RuleGroupServiceProvider.php +++ b/app/Providers/RuleGroupServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class RuleGroupServiceProvider. */ class RuleGroupServiceProvider extends ServiceProvider diff --git a/app/Providers/RuleServiceProvider.php b/app/Providers/RuleServiceProvider.php index 84a1f9bf86..e924e5d208 100644 --- a/app/Providers/RuleServiceProvider.php +++ b/app/Providers/RuleServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class RuleServiceProvider. */ class RuleServiceProvider extends ServiceProvider diff --git a/app/Providers/SearchServiceProvider.php b/app/Providers/SearchServiceProvider.php index 98af902220..ec86bc7188 100644 --- a/app/Providers/SearchServiceProvider.php +++ b/app/Providers/SearchServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class SearchServiceProvider. */ class SearchServiceProvider extends ServiceProvider diff --git a/app/Providers/SessionServiceProvider.php b/app/Providers/SessionServiceProvider.php index a95fc797e2..0d1885b7bc 100644 --- a/app/Providers/SessionServiceProvider.php +++ b/app/Providers/SessionServiceProvider.php @@ -26,6 +26,7 @@ use FireflyIII\Http\Middleware\StartFireflySession; use Illuminate\Session\SessionServiceProvider as BaseSessionServiceProvider; /** + * @CodeCoverageIgnore * Class SessionServiceProvider. */ class SessionServiceProvider extends BaseSessionServiceProvider diff --git a/app/Providers/TagServiceProvider.php b/app/Providers/TagServiceProvider.php index 2fafdee4f0..8d1d141c47 100644 --- a/app/Providers/TagServiceProvider.php +++ b/app/Providers/TagServiceProvider.php @@ -28,6 +28,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; /** + * @CodeCoverageIgnore * Class TagServiceProvider. */ class TagServiceProvider extends ServiceProvider diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php index 29c2f204e4..c71afd2e20 100644 --- a/app/Repositories/Journal/JournalRepository.php +++ b/app/Repositories/Journal/JournalRepository.php @@ -24,6 +24,7 @@ namespace FireflyIII\Repositories\Journal; use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; +use FireflyIII\Models\Note; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; @@ -189,6 +190,16 @@ class JournalRepository implements JournalRepositoryInterface return null; } + /** + * @param TransactionJournal $journal + * + * @return Note|null + */ + public function getNote(TransactionJournal $journal): ?Note + { + return $journal->notes()->first(); + } + /** * @return Collection */ diff --git a/app/Repositories/Journal/JournalRepositoryInterface.php b/app/Repositories/Journal/JournalRepositoryInterface.php index c9561c9196..a136ed1784 100644 --- a/app/Repositories/Journal/JournalRepositoryInterface.php +++ b/app/Repositories/Journal/JournalRepositoryInterface.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace FireflyIII\Repositories\Journal; use FireflyIII\Models\Account; +use FireflyIII\Models\Note; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; +use FireflyIII\Models\TransactionJournalLink; use FireflyIII\Models\TransactionType; use FireflyIII\User; use Illuminate\Support\Collection; @@ -52,6 +54,13 @@ interface JournalRepositoryInterface */ public function countTransactions(TransactionJournal $journal): int; + /** + * @param TransactionJournal $journal + * + * @return Note|null + */ + public function getNote(TransactionJournal $journal): ?Note; + /** * Deletes a journal. * diff --git a/app/Repositories/Journal/UpdateJournalsTrait.php b/app/Repositories/Journal/UpdateJournalsTrait.php index 31bcaa58a1..e56b62d73a 100644 --- a/app/Repositories/Journal/UpdateJournalsTrait.php +++ b/app/Repositories/Journal/UpdateJournalsTrait.php @@ -123,7 +123,7 @@ trait UpdateJournalsTrait /** * Update tags. - * + * * @param TransactionJournal $journal * @param array $array * diff --git a/app/Repositories/LinkType/LinkTypeRepository.php b/app/Repositories/LinkType/LinkTypeRepository.php index c2b4aa51e5..0e9c7acf8e 100644 --- a/app/Repositories/LinkType/LinkTypeRepository.php +++ b/app/Repositories/LinkType/LinkTypeRepository.php @@ -22,11 +22,13 @@ declare(strict_types=1); namespace FireflyIII\Repositories\LinkType; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\LinkType; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournalLink; use FireflyIII\User; use Illuminate\Support\Collection; +use Log; /** * Class LinkTypeRepository. @@ -157,6 +159,42 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface return $linkType; } + /** + * Store link between two journals. + * + * @param array $information + * @param TransactionJournal $left + * @param TransactionJournal $right + * + * @return mixed + * @throws FireflyException + */ + public function storeLink(array $information, TransactionJournal $left, TransactionJournal $right): TransactionJournalLink + { + $linkType = $this->find(intval($information['link_type_id']) ?? 0); + if (is_null($linkType->id)) { + throw new FireflyException(sprintf('Link type #%d cannot be resolved to an actual link type', intval($information['link_type_id']) ?? 0)); + } + $link = new TransactionJournalLink; + $link->linkType()->associate($linkType); + if ('inward' === $information['direction']) { + Log::debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->inward, $left->id, $right->id)); + $link->source()->associate($left); + $link->destination()->associate($right); + } + + if ('outward' === $information['direction']) { + Log::debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->outward, $right->id, $left->id)); + $link->source()->associate($right); + $link->destination()->associate($left); + } + + $link->comment = $link['comments'] ?? null; + $link->save(); + + return $link; + } + /** * @param TransactionJournalLink $link * diff --git a/app/Repositories/LinkType/LinkTypeRepositoryInterface.php b/app/Repositories/LinkType/LinkTypeRepositoryInterface.php index b3eadb454e..a94ed251b2 100644 --- a/app/Repositories/LinkType/LinkTypeRepositoryInterface.php +++ b/app/Repositories/LinkType/LinkTypeRepositoryInterface.php @@ -92,6 +92,17 @@ interface LinkTypeRepositoryInterface */ public function store(array $data): LinkType; + /** + * Store link between two journals. + * + * @param array $information + * @param TransactionJournal $left + * @param TransactionJournal $right + * + * @return mixed + */ + public function storeLink(array $information, TransactionJournal $left, TransactionJournal $right): TransactionJournalLink; + /** * @param TransactionJournalLink $link * diff --git a/app/Support/Navigation.php b/app/Support/Navigation.php index 039790f0f3..ebc33e78bc 100644 --- a/app/Support/Navigation.php +++ b/app/Support/Navigation.php @@ -24,6 +24,7 @@ namespace FireflyIII\Support; use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; +use Log; /** * Class Navigation. @@ -438,6 +439,7 @@ class Navigation { $date = clone $theDate; // 1D 1W 1M 3M 6M 1Y + Log::debug(sprintf('subtractPeriod: date is %s', $date->format('Y-m-d'))); $functionMap = [ '1D' => 'subDays', 'daily' => 'subDays', @@ -461,13 +463,16 @@ class Navigation if (isset($functionMap[$repeatFreq])) { $function = $functionMap[$repeatFreq]; $date->$function($subtract); + Log::debug(sprintf('%s is in function map, execute %s with argument %d', $repeatFreq, $function, $subtract)); + Log::debug(sprintf('subtractPeriod: resulting date is %s', $date->format('Y-m-d'))); return $date; } if (isset($modifierMap[$repeatFreq])) { $subtract = $subtract * $modifierMap[$repeatFreq]; $date->subMonths($subtract); - + Log::debug(sprintf('%s is in modifier map with value %d, execute subMonths with argument %d', $repeatFreq, $modifierMap[$repeatFreq], $subtract)); + Log::debug(sprintf('subtractPeriod: resulting date is %s', $date->format('Y-m-d'))); return $date; } // a custom range requires the session start @@ -479,7 +484,10 @@ class Navigation /** @var Carbon $tEnd */ $tEnd = session('end', Carbon::now()->endOfMonth()); $diffInDays = $tStart->diffInDays($tEnd); + Log::debug(sprintf('repeatFreq is %s, start is %s and end is %s (session data).', $repeatFreq, $tStart->format('Y-m-d'), $tEnd->format('Y-m-d'))); + Log::debug(sprintf('Diff in days is %d', $diffInDays)); $date->subDays($diffInDays * $subtract); + Log::debug(sprintf('subtractPeriod: resulting date is %s', $date->format('Y-m-d'))); return $date; } diff --git a/config/intro.php b/config/intro.php index 29fccb7fa0..dafcb13bac 100644 --- a/config/intro.php +++ b/config/intro.php @@ -37,7 +37,7 @@ return [ ], // accounts: create 'accounts_create' => [ - 'iban' => ['element' => '#ffInput_iban'], + 'iban' => ['element' => '#ffInput_iban'], ], // extra text for asset account creation. 'accounts_create_asset' => [ diff --git a/resources/lang/en_US/import.php b/resources/lang/en_US/import.php index 5ee8ad72ee..5958cf5f42 100644 --- a/resources/lang/en_US/import.php +++ b/resources/lang/en_US/import.php @@ -33,7 +33,11 @@ return [ 'status_ready_config' => 'Download configuration', 'status_ready_start' => 'Start the import', 'status_ready_share' => 'Please consider downloading your configuration and sharing it at the import configuration center. This will allow other users of Firefly III to import their files more easily.', + 'status_job_new' => 'The job is brand new.', + 'status_job_configuring' => 'The import is being configured.', + 'status_job_configured' => 'The import is configured.', 'status_job_running' => 'The import is running.. Please wait..', + 'status_job_error' => 'The job has generated an error.', 'status_job_finished' => 'The import has finished!', 'status_running_title' => 'The import is running', 'status_running_placeholder' => 'Please hold for an update...', diff --git a/routes/web.php b/routes/web.php index 1e294fdd3c..843f3e94e8 100755 --- a/routes/web.php +++ b/routes/web.php @@ -445,7 +445,7 @@ Route::group( Route::get('json/{importJob}', ['uses' => 'Import\StatusController@json', 'as' => 'status.json']); // start a job - Route::any('start/{importJob}', ['uses' => 'Import\IndexController@start', 'as' => 'start']); + Route::post('start/{importJob}', ['uses' => 'Import\IndexController@start', 'as' => 'start']); // download config Route::get('download/{importJob}', ['uses' => 'Import\IndexController@download', 'as' => 'download']); @@ -504,8 +504,8 @@ Route::group( Route::get('rate/{fromCurrencyCode}/{toCurrencyCode}/{date}', ['uses' => 'Json\ExchangeController@getRate', 'as' => 'rate']); // intro things: - Route::any('intro/finished/{route}/{specificPage?}', ['uses' => 'Json\IntroController@postFinished', 'as' => 'intro.finished']); - Route::any('intro/enable/{route}/{specificPage?}', ['uses' => 'Json\IntroController@postEnable', 'as' => 'intro.enable']); + Route::post('intro/finished/{route}/{specificPage?}', ['uses' => 'Json\IntroController@postFinished', 'as' => 'intro.finished']); + Route::post('intro/enable/{route}/{specificPage?}', ['uses' => 'Json\IntroController@postEnable', 'as' => 'intro.enable']); Route::get('intro/{route}/{specificPage?}', ['uses' => 'Json\IntroController@getIntroSteps', 'as' => 'intro']); diff --git a/tests/Feature/Controllers/BudgetControllerTest.php b/tests/Feature/Controllers/BudgetControllerTest.php index 88fdd3200a..5b8e293f90 100644 --- a/tests/Feature/Controllers/BudgetControllerTest.php +++ b/tests/Feature/Controllers/BudgetControllerTest.php @@ -294,9 +294,25 @@ class BudgetControllerTest extends TestCase $repository = $this->mock(BudgetRepositoryInterface::class); $repository->shouldReceive('getAvailableBudget')->andReturn('100.123'); - $data = ['amount' => 200, 'start' => '2017-01-01', 'end' => '2017-01-31']; $this->be($this->user()); - $response = $this->get(route('budgets.income.info', ['20170101', '20170131']), $data); + $response = $this->get(route('budgets.income.info', ['20170101', '20170131'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\BudgetController::infoIncome + * @dataProvider dateRangeProvider + * @throws \Exception + */ + public function testInfoIncomeExpanded(string $range) + { + // mock stuff + $repository = $this->mock(BudgetRepositoryInterface::class); + $repository->shouldReceive('getAvailableBudget')->andReturn('100.123'); + + $this->be($this->user()); + $this->changeDateRange($this->user(), $range); + $response = $this->get(route('budgets.income.info', ['20170301', '20170430'])); $response->assertStatus(200); } @@ -306,6 +322,8 @@ class BudgetControllerTest extends TestCase * @dataProvider dateRangeProvider * * @param string $range + * + * @throws \Exception */ public function testNoBudget(string $range) { diff --git a/tests/Feature/Controllers/Import/ConfigurationControllerTest.php b/tests/Feature/Controllers/Import/ConfigurationControllerTest.php new file mode 100644 index 0000000000..5b6a13ffb6 --- /dev/null +++ b/tests/Feature/Controllers/Import/ConfigurationControllerTest.php @@ -0,0 +1,119 @@ +. + */ +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Import; + +use FireflyIII\Import\Configuration\FileConfigurator; +use FireflyIII\Models\ImportJob; +use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; +use Tests\TestCase; + +/** + * Class AccountControllerTest + * + * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ConfigurationControllerTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Controllers\Import\ConfigurationController::__construct + * @covers \FireflyIII\Http\Controllers\Import\ConfigurationController::index + * @covers \FireflyIII\Http\Controllers\Import\ConfigurationController::makeConfigurator + */ + public function testIndex() + { + /** @var ImportJob $job */ + $job = $this->user()->importJobs()->where('key', 'configuring')->first(); + $configurator = $this->mock(FileConfigurator::class); + $repository = $this->mock(ImportJobRepositoryInterface::class); + $configurator->shouldReceive('setJob')->once(); + $configurator->shouldReceive('isJobConfigured')->once()->andReturn(false); + $configurator->shouldReceive('getNextView')->once()->andReturn('error'); // does not matter which view is returned. + $configurator->shouldReceive('getNextData')->once()->andReturn([]); + $repository->shouldReceive('updateStatus')->once(); + + $this->be($this->user()); + $response = $this->get(route('import.configure', [$job->key])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\ConfigurationController::__construct + * @covers \FireflyIII\Http\Controllers\Import\ConfigurationController::index + * @covers \FireflyIII\Http\Controllers\Import\ConfigurationController::makeConfigurator + */ + public function testIndexConfigured() + { + /** @var ImportJob $job */ + $job = $this->user()->importJobs()->where('key', 'configured')->first(); + $configurator = $this->mock(FileConfigurator::class); + $repository = $this->mock(ImportJobRepositoryInterface::class); + $configurator->shouldReceive('setJob')->once(); + $configurator->shouldReceive('isJobConfigured')->once()->andReturn(true); + $repository->shouldReceive('updateStatus')->once(); + + $this->be($this->user()); + $response = $this->get(route('import.configure', [$job->key])); + $response->assertStatus(302); + $response->assertRedirect(route('import.status', [$job->key])); + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\ConfigurationController::post + */ + public function testPost() + { + /** @var ImportJob $job */ + $job = $this->user()->importJobs()->where('key', 'configuring')->first(); + $data = ['some' => 'config']; + $configurator = $this->mock(FileConfigurator::class); + $configurator->shouldReceive('setJob')->once(); + $configurator->shouldReceive('isJobConfigured')->once()->andReturn(false); + $configurator->shouldReceive('configureJob')->once()->withArgs([$data]); + $configurator->shouldReceive('getWarningMessage')->once()->andReturn('Some warning'); + + $this->be($this->user()); + $response = $this->post(route('import.configure.post', [$job->key]), $data); + $response->assertStatus(302); + $response->assertRedirect(route('import.configure', [$job->key])); + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\ConfigurationController::post + */ + public function testPostConfigured() + { + /** @var ImportJob $job */ + $job = $this->user()->importJobs()->where('key', 'configuring')->first(); + $data = ['some' => 'config']; + $configurator = $this->mock(FileConfigurator::class); + $configurator->shouldReceive('setJob')->once(); + $configurator->shouldReceive('isJobConfigured')->once()->andReturn(true); + + $this->be($this->user()); + $response = $this->post(route('import.configure.post', [$job->key]), $data); + $response->assertStatus(302); + $response->assertRedirect(route('import.status', [$job->key])); + } +} diff --git a/tests/Feature/Controllers/Import/IndexControllerTest.php b/tests/Feature/Controllers/Import/IndexControllerTest.php new file mode 100644 index 0000000000..7d0689f650 --- /dev/null +++ b/tests/Feature/Controllers/Import/IndexControllerTest.php @@ -0,0 +1,105 @@ +. + */ +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Import; + +use FireflyIII\Import\Routine\FileRoutine; +use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; +use Tests\TestCase; + +/** + * Class AccountControllerTest + * + * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class IndexControllerTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Controllers\Import\IndexController::create + */ + public function testCreate() + { + $job = $this->user()->importJobs()->where('key', 'new')->first(); + $repository = $this->mock(ImportJobRepositoryInterface::class); + $repository->shouldReceive('create')->withArgs(['file'])->andReturn($job); + $this->be($this->user()); + $response = $this->get(route('import.create-job', ['file'])); + $response->assertStatus(302); + $response->assertRedirect(route('import.configure', ['new'])); + + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\IndexController::download + */ + public function testDownload() + { + //$job = $this->user()->importJobs()->where('key', 'testImport')->first(); + $this->be($this->user()); + $response = $this->get(route('import.download', ['testImport'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\IndexController::__construct + * @covers \FireflyIII\Http\Controllers\Import\IndexController::index + */ + public function testIndex() + { + + $this->be($this->user()); + $response = $this->get(route('import.index')); + $response->assertStatus(200); + + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\IndexController::start + */ + public function testStart() + { + $routine = $this->mock(FileRoutine::class); + $routine->shouldReceive('setJob')->once(); + $routine->shouldReceive('run')->once()->andReturn(true); + + $this->be($this->user()); + $response = $this->post(route('import.start', ['configured'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\IndexController::start + * @expectedExceptionMessage Job did not complete successfully. + */ + public function testStartFailed() + { + $routine = $this->mock(FileRoutine::class); + $routine->shouldReceive('setJob')->once(); + $routine->shouldReceive('run')->once()->andReturn(false); + + $this->be($this->user()); + $response = $this->post(route('import.start', ['configured'])); + $response->assertStatus(500); + } +} diff --git a/tests/Feature/Controllers/Import/PrerequisitesControllerTest.php b/tests/Feature/Controllers/Import/PrerequisitesControllerTest.php new file mode 100644 index 0000000000..1a68480a2f --- /dev/null +++ b/tests/Feature/Controllers/Import/PrerequisitesControllerTest.php @@ -0,0 +1,109 @@ +. + */ +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Import; + +use FireflyIII\Import\Prerequisites\FilePrerequisites; +use Illuminate\Support\MessageBag; +use Tests\TestCase; + +/** + * Class AccountControllerTest + * + * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class PrerequisitesControllerTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Controllers\Import\PrerequisitesController::__construct + * @covers \FireflyIII\Http\Controllers\Import\PrerequisitesController::index + */ + public function testIndex() + { + $object = $this->mock(FilePrerequisites::class); + $object->shouldReceive('setUser'); + $object->shouldReceive('hasPrerequisites')->andReturn(true); + $object->shouldReceive('getView')->andReturn('error'); // does not matter which view is returned + $object->shouldReceive('getViewParameters')->andReturn([]); + $this->be($this->user()); + + $response = $this->get(route('import.prerequisites', ['file'])); + $response->assertStatus(200); + + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\PrerequisitesController::index + */ + public function testIndexRedirect() + { + $object = $this->mock(FilePrerequisites::class); + $object->shouldReceive('setUser'); + $object->shouldReceive('hasPrerequisites')->andReturn(false); + $this->be($this->user()); + + $response = $this->get(route('import.prerequisites', ['file'])); + $response->assertStatus(302); + $response->assertRedirect(route('import.create-job', ['file'])); + + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\PrerequisitesController::post + */ + public function testPost() + { + $messageBag = new MessageBag; + $messageBag->add('nomessage', 'nothing'); + $object = $this->mock(FilePrerequisites::class); + $object->shouldReceive('setUser'); + $object->shouldReceive('hasPrerequisites')->andReturn(true); + $object->shouldReceive('storePrerequisites')->andReturn($messageBag); + $this->be($this->user()); + + $response = $this->post(route('import.prerequisites.post', ['file']), []); + $response->assertStatus(302); + $response->assertSessionHas('error'); + $response->assertRedirect(route('import.prerequisites', ['file'])); + + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\PrerequisitesController::post + */ + public function testPostDone() + { + $messageBag = new MessageBag; + $messageBag->add('nomessage', 'nothing'); + $object = $this->mock(FilePrerequisites::class); + $object->shouldReceive('setUser'); + $object->shouldReceive('hasPrerequisites')->andReturn(false); + $this->be($this->user()); + + $response = $this->post(route('import.prerequisites.post', ['file']), []); + $response->assertStatus(302); + $response->assertRedirect(route('import.create-job', ['file'])); + + } +} diff --git a/tests/Feature/Controllers/Import/StatusControllerTest.php b/tests/Feature/Controllers/Import/StatusControllerTest.php new file mode 100644 index 0000000000..203f5e6cdc --- /dev/null +++ b/tests/Feature/Controllers/Import/StatusControllerTest.php @@ -0,0 +1,86 @@ +. + */ +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Import; + +use FireflyIII\Repositories\Tag\TagRepositoryInterface; +use Tests\TestCase; + +/** + * Class AccountControllerTest + * + * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class StatusControllerTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Controllers\Import\StatusController::__construct + * @covers \FireflyIII\Http\Controllers\Import\StatusController::index + */ + public function testIndex() + { + $this->be($this->user()); + $response = $this->get(route('import.status', ['configured'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\StatusController::__construct + * @covers \FireflyIII\Http\Controllers\Import\StatusController::index + */ + public function testIndexRedirect() + { + $this->be($this->user()); + $response = $this->get(route('import.status', ['new'])); + $response->assertStatus(302); + $response->assertRedirect(route('import.configure', ['new'])); + + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\StatusController::__construct + * @covers \FireflyIII\Http\Controllers\Import\StatusController::json + */ + public function testStatusFinished() + { + $tag = $this->user()->tags()->first(); + $repository = $this->mock(TagRepositoryInterface::class); + $repository->shouldReceive('find')->andReturn($tag); + $this->be($this->user()); + $response = $this->get(route('import.status.json', ['finished'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Import\StatusController::__construct + * @covers \FireflyIII\Http\Controllers\Import\StatusController::json + */ + public function testStatusRunning() + { + $this->be($this->user()); + $response = $this->get(route('import.status.json', ['running'])); + $response->assertStatus(200); + } + +} diff --git a/tests/Feature/Controllers/Json/AutoCompleteControllerTest.php b/tests/Feature/Controllers/Json/AutoCompleteControllerTest.php index 2627fcea3b..40fc577877 100644 --- a/tests/Feature/Controllers/Json/AutoCompleteControllerTest.php +++ b/tests/Feature/Controllers/Json/AutoCompleteControllerTest.php @@ -41,14 +41,19 @@ class AutoCompleteControllerTest extends TestCase */ public function testAllAccounts() { + // mock stuff + $accountA = factory(Account::class)->make(); + $collection = new Collection([$accountA]); $accountRepos = $this->mock(AccountRepositoryInterface::class); $accountRepos->shouldReceive('getAccountsByType') ->withArgs([[AccountType::REVENUE, AccountType::EXPENSE, AccountType::BENEFICIARY, AccountType::DEFAULT, AccountType::ASSET]]) - ->andReturn(new Collection); + ->andReturn($collection); $this->be($this->user()); $response = $this->get(route('json.all-accounts')); $response->assertStatus(200); + $response->assertExactJson([$accountA->name]); + } /** @@ -72,18 +77,39 @@ class AutoCompleteControllerTest extends TestCase public function testExpenseAccounts() { // mock stuff - $account = factory(Account::class)->make(); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $journalRepos = $this->mock(JournalRepositoryInterface::class); + $accountA = factory(Account::class)->make(); + $accountB = factory(Account::class)->make(); + $accountA->active = true; + $accountB->active = false; + $collection = new Collection([$accountA, $accountB]); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); $journalRepos->shouldReceive('first')->once()->andReturn(new TransactionJournal); - $accountRepos->shouldReceive('getAccountsByType')->withArgs([[AccountType::EXPENSE, AccountType::BENEFICIARY]])->once()->andReturn( - new Collection([$account]) - ); + $accountRepos->shouldReceive('getAccountsByType')->withArgs([[AccountType::EXPENSE, AccountType::BENEFICIARY]])->once()->andReturn($collection); $this->be($this->user()); $response = $this->get(route('json.expense-accounts')); $response->assertStatus(200); - $response->assertExactJson([$account->name]); + $response->assertExactJson([$accountA->name]); + } + + /** + * @covers \FireflyIII\Http\Controllers\Json\AutoCompleteController::journalsWithId + */ + public function testJournalsWithId() + { + $journal = $this->user()->transactionJournals()->where('id', '!=', 1)->first(); + $journal->journal_id = $journal->id; + $collection = new Collection([$journal]); + $collector = $this->mock(JournalCollectorInterface::class); + $collector->shouldReceive('setLimit')->withArgs([400])->andReturnSelf(); + $collector->shouldReceive('setPage')->withArgs([1])->andReturnSelf(); + $collector->shouldReceive('getJournals')->andReturn($collection); + + $this->be($this->user()); + $response = $this->get(route('json.journals-with-id', [1])); + $response->assertStatus(200); + $response->assertExactJson([['id' => $journal->id, 'name' => $journal->id . ': ' . $journal->description]]); } /** @@ -92,18 +118,20 @@ class AutoCompleteControllerTest extends TestCase public function testRevenueAccounts() { // mock stuff - $account = factory(Account::class)->make(); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $journalRepos = $this->mock(JournalRepositoryInterface::class); + $accountA = factory(Account::class)->make(); + $accountB = factory(Account::class)->make(); + $accountA->active = true; + $accountB->active = false; + $collection = new Collection([$accountA, $accountB]); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); $journalRepos->shouldReceive('first')->once()->andReturn(new TransactionJournal); - $accountRepos->shouldReceive('getAccountsByType')->withArgs([[AccountType::REVENUE]])->once()->andReturn( - new Collection([$account]) - ); + $accountRepos->shouldReceive('getAccountsByType')->withArgs([[AccountType::REVENUE]])->once()->andReturn($collection); $this->be($this->user()); $response = $this->get(route('json.revenue-accounts')); $response->assertStatus(200); - $response->assertExactJson([$account->name]); + $response->assertExactJson([$accountA->name]); } /** diff --git a/tests/Feature/Controllers/Json/BoxControllerTest.php b/tests/Feature/Controllers/Json/BoxControllerTest.php new file mode 100644 index 0000000000..af5d76688b --- /dev/null +++ b/tests/Feature/Controllers/Json/BoxControllerTest.php @@ -0,0 +1,100 @@ +. + */ +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Json; + +use Carbon\Carbon; +use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; +use Illuminate\Support\Collection; +use Tests\TestCase; + +/** + * Class BoxControllerTest + */ +class BoxControllerTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Controllers\Json\BoxController::available + */ + public function testAvailable() + { + $return = [ + 0 => [ + 'spent' => '-1200', // more than budgeted. + ], + ]; + $repository = $this->mock(BudgetRepositoryInterface::class); + $repository->shouldReceive('getAvailableBudget')->andReturn('1000'); + $repository->shouldReceive('getActiveBudgets')->andReturn(new Collection); + $repository->shouldReceive('collectBudgetInformation')->andReturn($return); + + $this->be($this->user()); + $response = $this->get(route('json.box.available')); + $response->assertStatus(200); + + } + + /** + * @covers \FireflyIII\Http\Controllers\Json\BoxController::balance + */ + public function testBalance() + { + $this->be($this->user()); + $response = $this->get(route('json.box.balance')); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Json\BoxController::bills + */ + public function testBills() + { + $this->be($this->user()); + $response = $this->get(route('json.box.bills')); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Json\BoxController::netWorth() + */ + public function testNetWorth() + { + $this->be($this->user()); + $response = $this->get(route('json.box.net-worth')); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Json\BoxController::netWorth() + */ + public function testNetWorthFuture() + { + $start = new Carbon; + $start->addMonths(6)->startOfMonth(); + $end = clone $start; + $end->endOfMonth(); + $this->session(['start' => $start, 'end' => $end]); + $this->be($this->user()); + $response = $this->get(route('json.box.net-worth')); + $response->assertStatus(200); + } +} diff --git a/tests/Feature/Controllers/Json/FrontpageControllerTest.php b/tests/Feature/Controllers/Json/FrontpageControllerTest.php new file mode 100644 index 0000000000..73f18825dc --- /dev/null +++ b/tests/Feature/Controllers/Json/FrontpageControllerTest.php @@ -0,0 +1,51 @@ +. + */ +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Json; + +use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; +use Illuminate\Support\Collection; +use Tests\TestCase; + +/** + * Class FrontpageControllerTest + * + * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class FrontpageControllerTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Controllers\Json\FrontpageController::piggyBanks + */ + public function testPiggyBanks() + { + $piggy = $this->user()->piggyBanks()->first(); + $repository = $this->mock(PiggyBankRepositoryInterface::class); + $repository->shouldReceive('getPiggyBanks')->andReturn(new Collection([$piggy])); + + $this->be($this->user()); + $response = $this->get(route('json.fp.piggy-banks')); + $response->assertStatus(200); + } +} diff --git a/tests/Feature/Controllers/Json/IntroControllerTest.php b/tests/Feature/Controllers/Json/IntroControllerTest.php new file mode 100644 index 0000000000..56a179d4e2 --- /dev/null +++ b/tests/Feature/Controllers/Json/IntroControllerTest.php @@ -0,0 +1,95 @@ +. + */ +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Json; + +use Tests\TestCase; + +/** + * Class IntroControllerTest + * + * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class IntroControllerTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Controllers\Json\IntroController::getIntroSteps + * @covers \FireflyIII\Http\Controllers\Json\IntroController::getBasicSteps + * @covers \FireflyIII\Http\Controllers\Json\IntroController::getSpecificSteps + * @covers \FireflyIII\Http\Controllers\Json\IntroController::hasOutroStep + */ + public function testGetIntroSteps() + { + $this->be($this->user()); + $response = $this->get(route('json.intro', ['index'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Json\IntroController::getIntroSteps + * @covers \FireflyIII\Http\Controllers\Json\IntroController::getBasicSteps + * @covers \FireflyIII\Http\Controllers\Json\IntroController::getSpecificSteps + * @covers \FireflyIII\Http\Controllers\Json\IntroController::hasOutroStep + */ + public function testGetIntroStepsAsset() + { + $this->be($this->user()); + $response = $this->get(route('json.intro', ['accounts_create', 'asset'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Json\IntroController::getIntroSteps + * @covers \FireflyIII\Http\Controllers\Json\IntroController::getBasicSteps + * @covers \FireflyIII\Http\Controllers\Json\IntroController::getSpecificSteps + * @covers \FireflyIII\Http\Controllers\Json\IntroController::hasOutroStep + */ + public function testGetIntroStepsOutro() + { + $this->be($this->user()); + $response = $this->get(route('json.intro', ['reports_report', 'category'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Json\IntroController::postEnable + */ + public function testPostEnable() + { + $this->be($this->user()); + $response = $this->post(route('json.intro.enable', ['accounts_create', 'asset'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Json\IntroController::postFinished + */ + public function testPostFinished() + { + $this->be($this->user()); + $response = $this->post(route('json.intro.finished', ['accounts_create', 'asset'])); + $response->assertStatus(200); + } + +} diff --git a/tests/Feature/Controllers/PreferencesControllerTest.php b/tests/Feature/Controllers/PreferencesControllerTest.php index 66ea3e4017..f533927840 100644 --- a/tests/Feature/Controllers/PreferencesControllerTest.php +++ b/tests/Feature/Controllers/PreferencesControllerTest.php @@ -140,7 +140,7 @@ class PreferencesControllerTest extends TestCase 'viewRange' => '1M', 'customFiscalYear' => 0, 'showDepositsFrontpage' => 0, - 'transactionPageSize' => 100, + 'listPageSize' => 100, 'twoFactorAuthEnabled' => 0, 'language' => 'en_US', 'tj' => [], @@ -176,7 +176,7 @@ class PreferencesControllerTest extends TestCase 'viewRange' => '1M', 'customFiscalYear' => 0, 'showDepositsFrontpage' => 0, - 'transactionPageSize' => 100, + 'listPageSize' => 100, 'twoFactorAuthEnabled' => 1, 'language' => 'en_US', 'tj' => [], @@ -214,7 +214,7 @@ class PreferencesControllerTest extends TestCase 'viewRange' => '1M', 'customFiscalYear' => 0, 'showDepositsFrontpage' => 0, - 'transactionPageSize' => 100, + 'listPageSize' => 100, 'twoFactorAuthEnabled' => 1, 'language' => 'en_US', 'tj' => [], diff --git a/tests/Feature/Controllers/Report/ExpenseControllerTest.php b/tests/Feature/Controllers/Report/ExpenseControllerTest.php new file mode 100644 index 0000000000..0e30a56b41 --- /dev/null +++ b/tests/Feature/Controllers/Report/ExpenseControllerTest.php @@ -0,0 +1,252 @@ +. + */ +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Report; + +use FireflyIII\Helpers\Collector\JournalCollectorInterface; +use FireflyIII\Models\AccountType; +use FireflyIII\Models\Transaction; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use Illuminate\Support\Collection; +use Tests\TestCase; + +/** + * Class ExpenseControllerTest + * + * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ExpenseControllerTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::__construct + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::budget + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::combineAccounts + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::spentByBudget + */ + public function testBudget() + { + $expense = $this->user()->accounts()->where('account_type_id', 4)->first(); + $revenue = $this->user()->accounts()->where('account_type_id', 5)->first(); + $repository = $this->mock(AccountRepositoryInterface::class); + $repository->shouldReceive('findByName')->once()->withArgs([$expense->name, [AccountType::REVENUE]])->andReturn($revenue); + + // fake collection: + $transA = new Transaction; + $transA->transaction_currency_id = 1; + $transA->transaction_budget_name = 'Budget'; + $transA->transaction_budget_id = 1; + $transA->transaction_currency_symbol = 'A'; + $transA->transaction_currency_dp = 2; + $transA->transaction_amount = '100'; + $transB = new Transaction; + $transB->transaction_currency_id = 2; + $transB->transaction_budget_name = null; + $transB->transaction_budget_id = 0; + $transB->transaction_journal_budget_name = 'Budget2'; + $transB->transaction_journal_budget_id = 2; + $transB->transaction_currency_symbol = 'A'; + $transB->transaction_currency_dp = 2; + $transB->transaction_amount = '100'; + $collection = new Collection([$transA, $transB]); + + // mock collector for spentByBudget (complex) + $collector = $this->mock(JournalCollectorInterface::class); + // dont care about any calls, just return a default set of fake transactions: + $collector->shouldReceive('setRange')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setAccounts')->andReturnSelf(); + $collector->shouldReceive('setOpposingAccounts')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('getJournals')->andReturn($collection); + //$collector->shouldReceive('')->andReturnSelf(); + + + $this->be($this->user()); + $response = $this->get(route('report-data.expense.budget', ['1', $expense->id, '20170101', '20170131'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::category + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::spentByCategory + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::earnedByCategory + */ + public function testCategory() + { + $expense = $this->user()->accounts()->where('account_type_id', 4)->first(); + $revenue = $this->user()->accounts()->where('account_type_id', 5)->first(); + $repository = $this->mock(AccountRepositoryInterface::class); + $repository->shouldReceive('findByName')->once()->withArgs([$expense->name, [AccountType::REVENUE]])->andReturn($revenue); + + // fake collection: + $transA = new Transaction; + $transA->transaction_currency_id = 1; + $transA->transaction_category_name = 'Category'; + $transA->transaction_category_id = 1; + $transA->transaction_currency_symbol = 'A'; + $transA->transaction_currency_dp = 2; + $transA->transaction_amount = '100'; + $transB = new Transaction; + $transB->transaction_currency_id = 2; + $transB->transaction_category_name = null; + $transB->transaction_category_id = 0; + $transB->transaction_journal_category_name = 'Category2'; + $transB->transaction_journal_category_id = 2; + $transB->transaction_currency_symbol = 'A'; + $transB->transaction_currency_dp = 2; + $transB->transaction_amount = '100'; + $collection = new Collection([$transA, $transB]); + $transC = new Transaction; + $transC->transaction_currency_id = 3; + $transC->transaction_category_name = null; + $transC->transaction_category_id = 0; + $transC->transaction_journal_category_name = 'Category3'; + $transC->transaction_journal_category_id = 3; + $transC->transaction_currency_symbol = 'A'; + $transC->transaction_currency_dp = 2; + $transC->transaction_amount = '100'; + $secondCollection = new Collection([$transC]); + + // mock collector for spentByCategory and earnedByCategory (complex) + $collector = $this->mock(JournalCollectorInterface::class); + // dont care about any calls, just return a default set of fake transactions: + $collector->shouldReceive('setRange')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setAccounts')->andReturnSelf(); + $collector->shouldReceive('setOpposingAccounts')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('getJournals')->andReturn($collection, $secondCollection); + //$collector->shouldReceive('')->andReturnSelf(); + + $this->be($this->user()); + $response = $this->get(route('report-data.expense.category', ['1', $expense->id, '20170101', '20170131'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::spent + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::spentInPeriod + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::earnedInPeriod + */ + public function testSpent() + { + $expense = $this->user()->accounts()->where('account_type_id', 4)->first(); + $revenue = $this->user()->accounts()->where('account_type_id', 5)->first(); + $repository = $this->mock(AccountRepositoryInterface::class); + $repository->shouldReceive('findByName')->once()->withArgs([$expense->name, [AccountType::REVENUE]])->andReturn($revenue); + + // fake collection: + $transA = new Transaction; + $transA->transaction_currency_id = 1; + $transA->transaction_category_name = 'Category'; + $transA->transaction_category_id = 1; + $transA->transaction_currency_symbol = 'A'; + $transA->transaction_currency_dp = 2; + $transA->transaction_amount = '100'; + $transB = new Transaction; + $transB->transaction_currency_id = 2; + $transB->transaction_category_name = null; + $transB->transaction_category_id = 0; + $transB->transaction_journal_budget_name = 'Category2'; + $transB->transaction_journal_budget_id = 2; + $transB->transaction_currency_symbol = 'A'; + $transB->transaction_currency_dp = 2; + $transB->transaction_amount = '100'; + $collection = new Collection([$transA, $transB]); + + // mock collector for spentInPeriod and earnedInPeriod (complex) + $collector = $this->mock(JournalCollectorInterface::class); + // dont care about any calls, just return a default set of fake transactions: + $collector->shouldReceive('setRange')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setAccounts')->andReturnSelf(); + $collector->shouldReceive('setOpposingAccounts')->andReturnSelf(); + $collector->shouldReceive('getJournals')->andReturn($collection); + //$collector->shouldReceive('')->andReturnSelf(); + + $this->be($this->user()); + $response = $this->get(route('report-data.expense.spent', ['1', $expense->id, '20170101', '20170131'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::topExpense + */ + public function testTopExpense() + { + $expense = $this->user()->accounts()->where('account_type_id', 4)->first(); + $revenue = $this->user()->accounts()->where('account_type_id', 5)->first(); + $repository = $this->mock(AccountRepositoryInterface::class); + $repository->shouldReceive('findByName')->once()->withArgs([$expense->name, [AccountType::REVENUE]])->andReturn($revenue); + + // fake collection: + $transA = new Transaction; + $transA->transaction_currency_id = 1; + $transA->transaction_category_name = 'Category'; + $transA->transaction_category_id = 1; + $transA->transaction_currency_symbol = 'A'; + $transA->transaction_currency_dp = 2; + $transA->transaction_amount = '100'; + $transB = new Transaction; + $transB->transaction_currency_id = 2; + $transB->transaction_category_name = null; + $transB->transaction_category_id = 0; + $transB->transaction_journal_budget_name = 'Category2'; + $transB->transaction_journal_budget_id = 2; + $transB->transaction_currency_symbol = 'A'; + $transB->transaction_currency_dp = 2; + $transB->transaction_amount = '100'; + $collection = new Collection([$transA, $transB]); + + // mock collector for topExpense (complex) + $collector = $this->mock(JournalCollectorInterface::class); + // dont care about any calls, just return a default set of fake transactions: + $collector->shouldReceive('setRange')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setAccounts')->andReturnSelf(); + $collector->shouldReceive('setOpposingAccounts')->andReturnSelf(); + $collector->shouldReceive('getJournals')->andReturn($collection); + //$collector->shouldReceive('')->andReturnSelf(); + + $this->be($this->user()); + $response = $this->get(route('report-data.expense.expenses', ['1', $expense->id, '20170101', '20170131'])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Report\ExpenseController::topIncome + */ + public function testTopIncome() + { + $expense = $this->user()->accounts()->where('account_type_id', 4)->first(); + $revenue = $this->user()->accounts()->where('account_type_id', 5)->first(); + $repository = $this->mock(AccountRepositoryInterface::class); + $repository->shouldReceive('findByName')->once()->withArgs([$expense->name, [AccountType::REVENUE]])->andReturn($revenue); + + $this->be($this->user()); + $response = $this->get(route('report-data.expense.income', ['1', $expense->id, '20170101', '20170131'])); + $response->assertStatus(200); + } + +} diff --git a/tests/Feature/Controllers/Transaction/LinkControllerTest.php b/tests/Feature/Controllers/Transaction/LinkControllerTest.php new file mode 100644 index 0000000000..310dbbe001 --- /dev/null +++ b/tests/Feature/Controllers/Transaction/LinkControllerTest.php @@ -0,0 +1,147 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Transaction; + +use FireflyIII\Models\LinkType; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Models\TransactionJournalLink; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; +use Tests\TestCase; + + +/** + * Class LinkControllerTest + */ +class LinkControllerTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Controllers\Transaction\LinkController::__construct + * @covers \FireflyIII\Http\Controllers\Transaction\LinkController::delete + */ + public function testDelete() + { + $this->be($this->user()); + $response = $this->get(route('transactions.link.delete', [1])); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Http\Controllers\Transaction\LinkController::destroy + */ + public function testDestroy() + { + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $repository->shouldReceive('destroyLink'); + $this->be($this->user()); + + $this->session(['journal_links.delete.uri' => 'http://localhost/']); + + $response = $this->post(route('transactions.link.destroy', [1])); + $response->assertStatus(302); + $response->assertSessionHas('success'); + + } + + /** + * @covers \FireflyIII\Http\Controllers\Transaction\LinkController::store + */ + public function testStoreAlreadyLinked() + { + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $data = [ + 'link_other' => 8, + 'link_type' => '1_inward', + ]; + + $journalRepos->shouldReceive('first')->andReturn(new TransactionJournal); + $journalRepos->shouldReceive('find')->andReturn(new TransactionJournal); + $repository->shouldReceive('findLink')->andReturn(true); + + $this->be($this->user()); + $response = $this->post(route('transactions.link.store', [1]), $data); + + $response->assertStatus(302); + $response->assertSessionHas('error'); + $response->assertRedirect(route('transactions.show', [1])); + } + + /** + * @covers \FireflyIII\Http\Controllers\Transaction\LinkController::store + */ + public function testStore() + { + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $data = [ + 'link_other' => 8, + 'link_type' => '1_inward', + ]; + + $journalRepos->shouldReceive('first')->andReturn(new TransactionJournal); + $journalRepos->shouldReceive('find')->andReturn(new TransactionJournal); + $repository->shouldReceive('findLink')->andReturn(false); + $repository->shouldReceive('storeLink')->andReturn(new TransactionJournalLink); + + $this->be($this->user()); + $response = $this->post(route('transactions.link.store', [1]), $data); + + $response->assertStatus(302); + $response->assertSessionHas('success'); + $response->assertRedirect(route('transactions.show', [1])); + } + + + /** + * @covers \FireflyIII\Http\Controllers\Transaction\LinkController::store + */ + public function testStoreInvalid() + { + $data = [ + 'link_other' => 0, + 'link_type' => '1_inward', + ]; + + $this->be($this->user()); + $response = $this->post(route('transactions.link.store', [1]), $data); + $response->assertStatus(302); + $response->assertSessionHas('error'); + $response->assertRedirect(route('transactions.show', [1])); + } + + /** + * @covers \FireflyIII\Http\Controllers\Transaction\LinkController::switchLink + */ + public function testSwitchLink() + { + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $repository->shouldReceive('switchLink')->andReturn(false); + $this->be($this->user()); + $response = $this->get(route('transactions.link.switch', [1])); + + + $response->assertStatus(302); + } +} \ No newline at end of file diff --git a/tests/Feature/Controllers/Transaction/MassControllerTest.php b/tests/Feature/Controllers/Transaction/MassControllerTest.php index ea2f9f2863..b075dea02b 100644 --- a/tests/Feature/Controllers/Transaction/MassControllerTest.php +++ b/tests/Feature/Controllers/Transaction/MassControllerTest.php @@ -135,6 +135,16 @@ class MassControllerTest extends TestCase ->where('user_id', $this->user()->id)->first(['transaction_journals.id', DB::raw('count(transactions.`id`) as ct')]) ); + // add reconcile transaction + $collection->push( + TransactionJournal::where('transaction_type_id', 5) + ->whereNull('transaction_journals.deleted_at') + ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->groupBy('transaction_journals.id') + ->orderBy('ct', 'DESC') + ->where('user_id', $this->user()->id)->first(['transaction_journals.id', DB::raw('count(transactions.`id`) as ct')]) + ); + // add opening balance: $collection->push(TransactionJournal::where('transaction_type_id', 4)->where('user_id', $this->user()->id)->first()); $allIds = $collection->pluck('id')->toArray(); diff --git a/tests/Feature/Controllers/Transaction/SingleControllerTest.php b/tests/Feature/Controllers/Transaction/SingleControllerTest.php index 458037cb4a..24639fabf1 100644 --- a/tests/Feature/Controllers/Transaction/SingleControllerTest.php +++ b/tests/Feature/Controllers/Transaction/SingleControllerTest.php @@ -27,6 +27,7 @@ use FireflyIII\Events\StoredTransactionJournal; use FireflyIII\Events\UpdatedTransactionJournal; use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; use FireflyIII\Models\AccountType; +use FireflyIII\Models\Note; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; @@ -54,6 +55,13 @@ class SingleControllerTest extends TestCase */ public function testCloneTransaction() { + $note = new Note(); + $note->id = 5; + $note->text = 'I see you...'; + $repository = $this->mock(JournalRepositoryInterface::class); + $repository->shouldReceive('getNote')->andReturn($note)->once(); + $repository->shouldReceive('first')->once()->andReturn(new TransactionJournal); + $this->be($this->user()); $withdrawal = TransactionJournal::where('transaction_type_id', 1)->whereNull('deleted_at')->where('user_id', $this->user()->id)->first(); $response = $this->get(route('transactions.clone', [$withdrawal->id])); @@ -63,6 +71,7 @@ class SingleControllerTest extends TestCase /** * @covers \FireflyIII\Http\Controllers\Transaction\SingleController::create * @covers \FireflyIII\Http\Controllers\Transaction\SingleController::__construct + * @covers \FireflyIII\Http\Controllers\Transaction\SingleController::groupedActiveAccountList */ public function testCreate() { @@ -124,6 +133,14 @@ class SingleControllerTest extends TestCase $budgetRepos = $this->mock(BudgetRepositoryInterface::class); $budgetRepos->shouldReceive('getBudgets')->andReturn(new Collection)->once(); + $note = new Note(); + $note->id = 5; + $note->text = 'I see you...'; + $repository = $this->mock(JournalRepositoryInterface::class); + $repository->shouldReceive('getNote')->andReturn($note)->once(); + $repository->shouldReceive('first')->once()->andReturn(new TransactionJournal); + $repository->shouldReceive('countTransactions')->andReturn(2); + $this->be($this->user()); $withdrawal = TransactionJournal::where('transaction_type_id', 1)->whereNull('deleted_at')->where('user_id', $this->user()->id)->first(); $response = $this->get(route('transactions.edit', [$withdrawal->id])); @@ -201,6 +218,23 @@ class SingleControllerTest extends TestCase $response->assertStatus(302); } + /** + * @covers \FireflyIII\Http\Controllers\Transaction\SingleController::edit + * @covers \FireflyIII\Http\Controllers\Transaction\SingleController::groupedAccountList + */ + public function testEditReconcile() + { + $this->be($this->user()); + $withdrawal = TransactionJournal::where('transaction_type_id', 5) + ->whereNull('transaction_journals.deleted_at') + ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->groupBy('transaction_journals.id') + ->orderBy('ct', 'DESC') + ->where('user_id', $this->user()->id)->first(['transaction_journals.id', DB::raw('count(transactions.`id`) as ct')]); + $response = $this->get(route('transactions.edit', [$withdrawal->id])); + $response->assertStatus(302); + } + /** * @covers \FireflyIII\Http\Controllers\Transaction\SingleController::edit * @covers \FireflyIII\Http\Controllers\Transaction\SingleController::groupedAccountList @@ -295,8 +329,6 @@ class SingleControllerTest extends TestCase */ public function testStoreSuccess() { - $this->markTestIncomplete('Mockery cannot yet handle PHP7.1 null argument method things.'); - // mock results: $repository = $this->mock(JournalRepositoryInterface::class); $journal = new TransactionJournal();