From 159fffef2ef5a21917036aa6416f09ff258a9217 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 10 Dec 2018 21:45:44 +0100 Subject: [PATCH] Improve test coverage. --- app/Api/V1/Controllers/AccountController.php | 2 + app/Api/V1/Controllers/BudgetController.php | 5 +- .../V1/Controllers/BudgetLimitController.php | 5 - app/Api/V1/Controllers/CurrencyController.php | 116 ++- .../V1/Controllers/PiggyBankController.php | 2 +- .../V1/Controllers/PreferenceController.php | 22 - .../V1/Controllers/RecurrenceController.php | 8 +- app/Api/V1/Controllers/RuleController.php | 2 +- composer.lock | 816 ++++++++++++++---- database/factories/ModelFactory.php | 24 - database/factories/UserFactory.php | 43 + .../V1/Controllers/AboutControllerTest.php | 29 +- .../V1/Controllers/AccountControllerTest.php | 244 +++++- .../Controllers/AttachmentControllerTest.php | 24 +- .../Api/V1/Controllers/BillControllerTest.php | 182 ++++ .../V1/Controllers/BudgetControllerTest.php | 197 ++++- .../Controllers/BudgetLimitControllerTest.php | 95 +- .../V1/Controllers/CategoryControllerTest.php | 134 ++- .../ConfigurationControllerTest.php | 6 +- .../V1/Controllers/CurrencyControllerTest.php | 406 +++++++++ .../V1/Controllers/ImportControllerTest.php | 115 +++ .../V1/Controllers/LinkTypeControllerTest.php | 37 +- .../Controllers/PiggyBankControllerTest.php | 16 + .../Controllers/RecurrenceControllerTest.php | 82 +- .../Api/V1/Controllers/RuleControllerTest.php | 68 ++ .../Controllers/TransactionControllerTest.php | 2 +- 26 files changed, 2335 insertions(+), 347 deletions(-) create mode 100644 database/factories/UserFactory.php create mode 100644 tests/Api/V1/Controllers/ImportControllerTest.php diff --git a/app/Api/V1/Controllers/AccountController.php b/app/Api/V1/Controllers/AccountController.php index 73301d199a..e94727ccdf 100644 --- a/app/Api/V1/Controllers/AccountController.php +++ b/app/Api/V1/Controllers/AccountController.php @@ -134,6 +134,8 @@ class AccountController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); } + + /** * List all of them. * diff --git a/app/Api/V1/Controllers/BudgetController.php b/app/Api/V1/Controllers/BudgetController.php index bd45020a7e..45def0dbdb 100644 --- a/app/Api/V1/Controllers/BudgetController.php +++ b/app/Api/V1/Controllers/BudgetController.php @@ -244,13 +244,10 @@ class BudgetController extends Controller $collector->setAllAssetAccounts(); $collector->setBudget($budget); - if (\in_array(TransactionType::TRANSFER, $types, true)) { - $collector->removeFilter(InternalTransferFilter::class); - } - if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } + $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); $collector->setTypes($types); $paginator = $collector->getPaginatedTransactions(); diff --git a/app/Api/V1/Controllers/BudgetLimitController.php b/app/Api/V1/Controllers/BudgetLimitController.php index e227c77200..e06d4b6e4e 100644 --- a/app/Api/V1/Controllers/BudgetLimitController.php +++ b/app/Api/V1/Controllers/BudgetLimitController.php @@ -198,11 +198,6 @@ class BudgetLimitController extends Controller $collector->setAllAssetAccounts(); $collector->setBudget($budgetLimit->budget); $collector->setRange($budgetLimit->start_date, $budgetLimit->end_date); - - if (\in_array(TransactionType::TRANSFER, $types, true)) { - $collector->removeFilter(InternalTransferFilter::class); - } - $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); $collector->setTypes($types); $paginator = $collector->getPaginatedTransactions(); diff --git a/app/Api/V1/Controllers/CurrencyController.php b/app/Api/V1/Controllers/CurrencyController.php index 8bb3e7de58..f0e0e2e4d5 100644 --- a/app/Api/V1/Controllers/CurrencyController.php +++ b/app/Api/V1/Controllers/CurrencyController.php @@ -42,7 +42,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; -use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; use FireflyIII\Repositories\Rule\RuleRepositoryInterface; use FireflyIII\Repositories\User\UserRepositoryInterface; @@ -153,54 +152,6 @@ class CurrencyController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); } - /** - * Show all transactions. - * - * @param Request $request - * - * @param TransactionCurrency $currency - * - * @return JsonResponse - */ - public function transactions(Request $request, TransactionCurrency $currency): JsonResponse - { - $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; - $type = $request->get('type') ?? 'default'; - $this->parameters->set('type', $type); - - $types = $this->mapTransactionTypes($this->parameters->get('type')); - $manager = new Manager(); - $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; - $manager->setSerializer(new JsonApiSerializer($baseUrl)); - - /** @var User $admin */ - $admin = auth()->user(); - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setUser($admin); - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - $collector->setAllAssetAccounts(); - $collector->setCurrency($currency); - - if (\in_array(TransactionType::TRANSFER, $types, true)) { - $collector->removeFilter(InternalTransferFilter::class); - } - - if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { - $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); - } - $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); - $collector->setTypes($types); - $paginator = $collector->getPaginatedTransactions(); - $paginator->setPath(route('api.v1.currencies.transactions', [$currency->code]) . $this->buildParams()); - $transactions = $paginator->getCollection(); - - $resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions'); - $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); - - return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); - } - /** * Display a listing of the resource. * @@ -212,6 +163,9 @@ class CurrencyController extends Controller */ public function availableBudgets(Request $request, TransactionCurrency $currency): JsonResponse { + /** @var User $admin */ + $admin = auth()->user(); + // create some objects: $manager = new Manager; $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; @@ -222,6 +176,7 @@ class CurrencyController extends Controller // get list of available budgets. Count it and split it. /** @var BudgetRepositoryInterface $repository */ $repository = app(BudgetRepositoryInterface::class); + $repository->setUser($admin); $unfiltered = $repository->getAvailableBudgets(); // filter list. @@ -302,18 +257,8 @@ class CurrencyController extends Controller $repository = app(BudgetRepositoryInterface::class); $manager = new Manager; $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; - $budgetId = (int)($request->get('budget_id') ?? 0); - $budget = $repository->findNull($budgetId); $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; - $this->parameters->set('budget_id', $budgetId); - - $unfiltered = new Collection; - if (null === $budget) { - $unfiltered = $repository->getAllBudgetLimits($this->parameters->get('start'), $this->parameters->get('end')); - } - if (null !== $budget) { - $unfiltered = $repository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end')); - } + $unfiltered = $repository->getAllBudgetLimits($this->parameters->get('start'), $this->parameters->get('end')); // filter budget limits on currency ID $collection = $unfiltered->filter( @@ -404,7 +349,6 @@ class CurrencyController extends Controller return response()->json([], 409); } $this->repository->disable($currency); - $currency = $this->repository->find($currency->id); $manager = new Manager(); $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; $manager->setSerializer(new JsonApiSerializer($baseUrl)); @@ -429,7 +373,6 @@ class CurrencyController extends Controller public function enable(Request $request, TransactionCurrency $currency): JsonResponse { $this->repository->enable($currency); - $currency = $this->repository->find($currency->id); $manager = new Manager(); $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; $manager->setSerializer(new JsonApiSerializer($baseUrl)); @@ -488,7 +431,6 @@ class CurrencyController extends Controller app('preferences')->set('currencyPreference', $currency->code); app('preferences')->mark(); - $currency = $this->repository->find($currency->id); $manager = new Manager(); $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; $manager->setSerializer(new JsonApiSerializer($baseUrl)); @@ -653,6 +595,54 @@ class CurrencyController extends Controller } + /** + * Show all transactions. + * + * @param Request $request + * + * @param TransactionCurrency $currency + * + * @return JsonResponse + */ + public function transactions(Request $request, TransactionCurrency $currency): JsonResponse + { + $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + $type = $request->get('type') ?? 'default'; + $this->parameters->set('type', $type); + + $types = $this->mapTransactionTypes($this->parameters->get('type')); + $manager = new Manager(); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + /** @var User $admin */ + $admin = auth()->user(); + /** @var TransactionCollectorInterface $collector */ + $collector = app(TransactionCollectorInterface::class); + $collector->setUser($admin); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setCurrency($currency); + + if (\in_array(TransactionType::TRANSFER, $types, true)) { + $collector->removeFilter(InternalTransferFilter::class); + } + + if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { + $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); + } + $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); + $collector->setTypes($types); + $paginator = $collector->getPaginatedTransactions(); + $paginator->setPath(route('api.v1.currencies.transactions', [$currency->code]) . $this->buildParams()); + $transactions = $paginator->getCollection(); + + $resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions'); + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); + } + /** * Update a currency. * diff --git a/app/Api/V1/Controllers/PiggyBankController.php b/app/Api/V1/Controllers/PiggyBankController.php index 7b1917030d..ca34b13104 100644 --- a/app/Api/V1/Controllers/PiggyBankController.php +++ b/app/Api/V1/Controllers/PiggyBankController.php @@ -134,7 +134,7 @@ class PiggyBankController extends Controller $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; $manager->setSerializer(new JsonApiSerializer($baseUrl)); - $collection = $piggyBank->piggyBankEvents()->get(); + $collection = $this->repository->getEvents($piggyBank); $count = $collection->count(); $events = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); diff --git a/app/Api/V1/Controllers/PreferenceController.php b/app/Api/V1/Controllers/PreferenceController.php index 23d9de3028..8d23b02904 100644 --- a/app/Api/V1/Controllers/PreferenceController.php +++ b/app/Api/V1/Controllers/PreferenceController.php @@ -78,28 +78,6 @@ class PreferenceController extends Controller } - /** - * List single resource. - * - * @param Request $request - * @param Preference $preference - * - * @return JsonResponse - */ - public function show(Request $request, Preference $preference): JsonResponse - { - // create some objects: - $manager = new Manager; - $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; - - // present to user. - $manager->setSerializer(new JsonApiSerializer($baseUrl)); - $resource = new Item($preference, new PreferenceTransformer($this->parameters), 'preferences'); - - return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); - - } - /** * Update a preference. * diff --git a/app/Api/V1/Controllers/RecurrenceController.php b/app/Api/V1/Controllers/RecurrenceController.php index 8a4184d187..8fbcb98c85 100644 --- a/app/Api/V1/Controllers/RecurrenceController.php +++ b/app/Api/V1/Controllers/RecurrenceController.php @@ -29,7 +29,6 @@ use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Filter\InternalTransferFilter; use FireflyIII\Models\Recurrence; use FireflyIII\Models\TransactionType; -use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; use FireflyIII\Support\Cronjobs\RecurringCronjob; use FireflyIII\Support\Http\Api\TransactionFilter; @@ -205,7 +204,7 @@ class RecurrenceController extends Controller $paginator = $collector->getPaginatedTransactions(); $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); $transactions = $paginator->getCollection(); - $resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions'); + $resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions'); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); @@ -217,7 +216,8 @@ class RecurrenceController extends Controller */ public function trigger(): JsonResponse { - $recurring = new RecurringCronjob; + /** @var RecurringCronjob $recurring */ + $recurring = app(RecurringCronjob::class); try { $result = $recurring->fire(); } catch (FireflyException $e) { @@ -230,7 +230,7 @@ class RecurrenceController extends Controller if (true === $result) { return response()->json([], 200); } - throw new FireflyException('Could not fire recurring cron job.'); + return response()->json([], 418); // @codeCoverageIgnore } /** diff --git a/app/Api/V1/Controllers/RuleController.php b/app/Api/V1/Controllers/RuleController.php index f15ed0de92..10eb4456df 100644 --- a/app/Api/V1/Controllers/RuleController.php +++ b/app/Api/V1/Controllers/RuleController.php @@ -249,7 +249,7 @@ class RuleController extends Controller foreach ($accountList as $accountId) { Log::debug(sprintf('Searching for asset account with id "%s"', $accountId)); $account = $this->accountRepository->findNull((int)$accountId); - if (null !== $account && AccountType::ASSET === $account->accountType->type) { + if (null !== $account && $this->accountRepository->isAsset($account)) { Log::debug(sprintf('Found account #%d ("%s") and its an asset account', $account->id, $account->name)); $accounts->push($account); } diff --git a/composer.lock b/composer.lock index 88f1b46471..c53cf81e66 100644 --- a/composer.lock +++ b/composer.lock @@ -591,16 +591,16 @@ }, { "name": "doctrine/dbal", - "version": "v2.8.0", + "version": "v2.9.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "5140a64c08b4b607b9bedaae0cedd26f04a0e621" + "reference": "21fdabe2fc01e004e1966f200d900554876bc63c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/5140a64c08b4b607b9bedaae0cedd26f04a0e621", - "reference": "5140a64c08b4b607b9bedaae0cedd26f04a0e621", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/21fdabe2fc01e004e1966f200d900554876bc63c", + "reference": "21fdabe2fc01e004e1966f200d900554876bc63c", "shasum": "" }, "require": { @@ -610,11 +610,10 @@ "php": "^7.1" }, "require-dev": { - "doctrine/coding-standard": "^4.0", + "doctrine/coding-standard": "^5.0", "jetbrains/phpstorm-stubs": "^2018.1.2", "phpstan/phpstan": "^0.10.1", - "phpunit/phpunit": "^7.1.2", - "phpunit/phpunit-mock-objects": "!=3.2.4,!=3.2.5", + "phpunit/phpunit": "^7.4", "symfony/console": "^2.0.5|^3.0|^4.0", "symfony/phpunit-bridge": "^3.4.5|^4.0.5" }, @@ -627,13 +626,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8.x-dev", + "dev-master": "2.9.x-dev", "dev-develop": "3.0.x-dev" } }, "autoload": { - "psr-0": { - "Doctrine\\DBAL\\": "lib/" + "psr-4": { + "Doctrine\\DBAL\\": "lib/Doctrine/DBAL" } }, "notification-url": "https://packagist.org/downloads/", @@ -658,15 +657,19 @@ "email": "jonwage@gmail.com" } ], - "description": "Database Abstraction Layer", - "homepage": "http://www.doctrine-project.org", + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", "keywords": [ + "abstraction", "database", "dbal", + "mysql", "persistence", + "pgsql", + "php", "queryobject" ], - "time": "2018-07-13T03:16:35+00:00" + "time": "2018-12-04T04:39:48+00:00" }, { "name": "doctrine/event-manager", @@ -914,16 +917,16 @@ }, { "name": "egulias/email-validator", - "version": "2.1.6", + "version": "2.1.7", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "0578b32b30b22de3e8664f797cf846fc9246f786" + "reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/0578b32b30b22de3e8664f797cf846fc9246f786", - "reference": "0578b32b30b22de3e8664f797cf846fc9246f786", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/709f21f92707308cdf8f9bcfa1af4cb26586521e", + "reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e", "shasum": "" }, "require": { @@ -967,7 +970,7 @@ "validation", "validator" ], - "time": "2018-09-25T20:47:26+00:00" + "time": "2018-12-04T22:38:24+00:00" }, { "name": "erusev/parsedown", @@ -1233,32 +1236,33 @@ }, { "name": "guzzlehttp/psr7", - "version": "1.4.2", + "version": "1.5.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" + "reference": "9f83dded91781a01c63574e387eaa769be769115" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115", + "reference": "9f83dded91781a01c63574e387eaa769be769115", "shasum": "" }, "require": { "php": ">=5.4.0", - "psr/http-message": "~1.0" + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5" }, "provide": { "psr/http-message-implementation": "1.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.5-dev" } }, "autoload": { @@ -1288,26 +1292,27 @@ "keywords": [ "http", "message", + "psr-7", "request", "response", "stream", "uri", "url" ], - "time": "2017-03-20T17:10:46+00:00" + "time": "2018-12-04T20:46:45+00:00" }, { "name": "laravel/framework", - "version": "v5.7.14", + "version": "v5.7.16", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "ad6c1fe1e455c0f73a431928282704879ccbd856" + "reference": "9acea9e0a356cba7e6a13f8784d5532a82fee92a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/ad6c1fe1e455c0f73a431928282704879ccbd856", - "reference": "ad6c1fe1e455c0f73a431928282704879ccbd856", + "url": "https://api.github.com/repos/laravel/framework/zipball/9acea9e0a356cba7e6a13f8784d5532a82fee92a", + "reference": "9acea9e0a356cba7e6a13f8784d5532a82fee92a", "shasum": "" }, "require": { @@ -1316,6 +1321,8 @@ "erusev/parsedown": "^1.7", "ext-mbstring": "*", "ext-openssl": "*", + "laravel/nexmo-notification-channel": "^1.0", + "laravel/slack-notification-channel": "^1.0", "league/flysystem": "^1.0.8", "monolog/monolog": "^1.12", "nesbot/carbon": "^1.26.3", @@ -1438,7 +1445,64 @@ "framework", "laravel" ], - "time": "2018-11-21T13:46:08+00:00" + "time": "2018-12-05T14:36:24+00:00" + }, + { + "name": "laravel/nexmo-notification-channel", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/nexmo-notification-channel.git", + "reference": "03edd42a55b306ff980c9950899d5a2b03260d48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/nexmo-notification-channel/zipball/03edd42a55b306ff980c9950899d5a2b03260d48", + "reference": "03edd42a55b306ff980c9950899d5a2b03260d48", + "shasum": "" + }, + "require": { + "nexmo/client": "^1.0", + "php": "^7.1.3" + }, + "require-dev": { + "illuminate/notifications": "~5.7", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "laravel": { + "providers": [ + "Illuminate\\Notifications\\NexmoChannelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Notifications\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Nexmo Notification Channel for laravel.", + "keywords": [ + "laravel", + "nexmo", + "notifications" + ], + "time": "2018-12-04T12:57:08+00:00" }, { "name": "laravel/passport", @@ -1509,6 +1573,63 @@ ], "time": "2018-10-22T14:47:22+00:00" }, + { + "name": "laravel/slack-notification-channel", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/slack-notification-channel.git", + "reference": "0ede60acbbf5f91be2e45d0c0b4d95e2f3837252" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/0ede60acbbf5f91be2e45d0c0b4d95e2f3837252", + "reference": "0ede60acbbf5f91be2e45d0c0b4d95e2f3837252", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0", + "php": "^7.1.3" + }, + "require-dev": { + "illuminate/notifications": "~5.7", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "laravel": { + "providers": [ + "Illuminate\\Notifications\\SlackChannelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Notifications\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Slack Notification Channel for laravel.", + "keywords": [ + "laravel", + "notifications", + "slack" + ], + "time": "2018-12-04T12:58:59+00:00" + }, { "name": "laravelcollective/html", "version": "v5.7.1", @@ -1773,16 +1894,16 @@ }, { "name": "league/event", - "version": "2.1.2", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/thephpleague/event.git", - "reference": "e4bfc88dbcb60c8d8a2939a71f9813e141bbe4cd" + "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/event/zipball/e4bfc88dbcb60c8d8a2939a71f9813e141bbe4cd", - "reference": "e4bfc88dbcb60c8d8a2939a71f9813e141bbe4cd", + "url": "https://api.github.com/repos/thephpleague/event/zipball/d2cc124cf9a3fab2bb4ff963307f60361ce4d119", + "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119", "shasum": "" }, "require": { @@ -1790,7 +1911,7 @@ }, "require-dev": { "henrikbjorn/phpspec-code-coverage": "~1.0.1", - "phpspec/phpspec": "~2.0.0" + "phpspec/phpspec": "^2.2" }, "type": "library", "extra": { @@ -1819,20 +1940,20 @@ "event", "listener" ], - "time": "2015-05-21T12:24:47+00:00" + "time": "2018-11-26T11:52:41+00:00" }, { "name": "league/flysystem", - "version": "1.0.48", + "version": "1.0.49", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "a6ded5b2f6055e2db97b4b859fdfca2b952b78aa" + "reference": "a63cc83d8a931b271be45148fa39ba7156782ffd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a6ded5b2f6055e2db97b4b859fdfca2b952b78aa", - "reference": "a6ded5b2f6055e2db97b4b859fdfca2b952b78aa", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a63cc83d8a931b271be45148fa39ba7156782ffd", + "reference": "a63cc83d8a931b271be45148fa39ba7156782ffd", "shasum": "" }, "require": { @@ -1903,7 +2024,7 @@ "sftp", "storage" ], - "time": "2018-10-15T13:53:10+00:00" + "time": "2018-11-23T23:41:29+00:00" }, { "name": "league/flysystem-replicate-adapter", @@ -2346,6 +2467,54 @@ ], "time": "2018-11-22T18:23:02+00:00" }, + { + "name": "nexmo/client", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/Nexmo/nexmo-php.git", + "reference": "f192c84ec3cc3e2657fc754e0da1a17e39ac5542" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nexmo/nexmo-php/zipball/f192c84ec3cc3e2657fc754e0da1a17e39ac5542", + "reference": "f192c84ec3cc3e2657fc754e0da1a17e39ac5542", + "shasum": "" + }, + "require": { + "lcobucci/jwt": "^3.2", + "php": ">=5.6", + "php-http/client-implementation": "^1.0", + "php-http/guzzle6-adapter": "^1.0", + "zendframework/zend-diactoros": "^1.3" + }, + "require-dev": { + "estahn/phpunit-json-assertions": "^1.0.0", + "php-http/mock-client": "^0.3.0", + "phpunit/phpunit": "^5.7", + "squizlabs/php_codesniffer": "^3.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nexmo\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tim Lytle", + "email": "tim@nexmo.com", + "homepage": "http://twitter.com/tjlytle", + "role": "Developer" + } + ], + "description": "PHP Client for using Nexmo's API.", + "time": "2018-11-14T14:12:22+00:00" + }, { "name": "opis/closure", "version": "3.1.1", @@ -2514,6 +2683,172 @@ ], "time": "2018-07-02T15:55:56+00:00" }, + { + "name": "php-http/guzzle6-adapter", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/guzzle6-adapter.git", + "reference": "a56941f9dc6110409cfcddc91546ee97039277ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/guzzle6-adapter/zipball/a56941f9dc6110409cfcddc91546ee97039277ab", + "reference": "a56941f9dc6110409cfcddc91546ee97039277ab", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0", + "php": ">=5.5.0", + "php-http/httplug": "^1.0" + }, + "provide": { + "php-http/async-client-implementation": "1.0", + "php-http/client-implementation": "1.0" + }, + "require-dev": { + "ext-curl": "*", + "php-http/adapter-integration-tests": "^0.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Adapter\\Guzzle6\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + }, + { + "name": "David de Boer", + "email": "david@ddeboer.nl" + } + ], + "description": "Guzzle 6 HTTP Adapter", + "homepage": "http://httplug.io", + "keywords": [ + "Guzzle", + "http" + ], + "time": "2016-05-10T06:13:32+00:00" + }, + { + "name": "php-http/httplug", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "1c6381726c18579c4ca2ef1ec1498fdae8bdf018" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/1c6381726c18579c4ca2ef1ec1498fdae8bdf018", + "reference": "1c6381726c18579c4ca2ef1ec1498fdae8bdf018", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "php-http/promise": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "^1.0", + "phpspec/phpspec": "^2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "time": "2016-08-31T08:30:17+00:00" + }, + { + "name": "php-http/promise", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "dc494cdc9d7160b9a09bd5573272195242ce7980" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/dc494cdc9d7160b9a09bd5573272195242ce7980", + "reference": "dc494cdc9d7160b9a09bd5573272195242ce7980", + "shasum": "" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "^1.0", + "phpspec/phpspec": "^2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + }, + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "time": "2016-01-26T13:27:02+00:00" + }, { "name": "phpseclib/phpseclib", "version": "2.0.12", @@ -2932,6 +3267,46 @@ ], "time": "2017-10-23T01:57:42+00:00" }, + { + "name": "ralouphie/getallheaders", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~3.7.0", + "satooshi/php-coveralls": ">=1.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2016-02-11T07:05:27+00:00" + }, { "name": "ramsey/uuid", "version": "3.8.0", @@ -3147,20 +3522,21 @@ }, { "name": "symfony/console", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "432122af37d8cd52fba1b294b11976e0d20df595" + "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/432122af37d8cd52fba1b294b11976e0d20df595", - "reference": "432122af37d8cd52fba1b294b11976e0d20df595", + "url": "https://api.github.com/repos/symfony/console/zipball/4dff24e5d01e713818805c1862d2e3f901ee7dd0", + "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0", "shasum": "" }, "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -3184,7 +3560,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -3211,20 +3587,88 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:30:44+00:00" + "time": "2018-11-27T07:40:44+00:00" }, { - "name": "symfony/css-selector", - "version": "v4.1.7", + "name": "symfony/contracts", + "version": "v1.0.2", "source": { "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "d67de79a70a27d93c92c47f37ece958bf8de4d8a" + "url": "https://github.com/symfony/contracts.git", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/d67de79a70a27d93c92c47f37ece958bf8de4d8a", - "reference": "d67de79a70a27d93c92c47f37ece958bf8de4d8a", + "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2018-12-05T08:06:11+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v4.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "aa9fa526ba1b2ec087ffdfb32753803d999fcfcd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/aa9fa526ba1b2ec087ffdfb32753803d999fcfcd", + "reference": "aa9fa526ba1b2ec087ffdfb32753803d999fcfcd", "shasum": "" }, "require": { @@ -3233,7 +3677,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -3264,20 +3708,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2018-10-02T16:36:10+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/debug", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "19090917b848a799cbae4800abf740fe4eb71c1d" + "reference": "e0a2b92ee0b5b934f973d90c2f58e18af109d276" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/19090917b848a799cbae4800abf740fe4eb71c1d", - "reference": "19090917b848a799cbae4800abf740fe4eb71c1d", + "url": "https://api.github.com/repos/symfony/debug/zipball/e0a2b92ee0b5b934f973d90c2f58e18af109d276", + "reference": "e0a2b92ee0b5b934f973d90c2f58e18af109d276", "shasum": "" }, "require": { @@ -3293,7 +3737,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -3320,24 +3764,25 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:09:42+00:00" + "time": "2018-11-28T18:24:18+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "552541dad078c85d9414b09c041ede488b456cd5" + "reference": "921f49c3158a276d27c0d770a5a347a3b718b328" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5", - "reference": "552541dad078c85d9414b09c041ede488b456cd5", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/921f49c3158a276d27c0d770a5a347a3b718b328", + "reference": "921f49c3158a276d27c0d770a5a347a3b718b328", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "conflict": { "symfony/dependency-injection": "<3.4" @@ -3356,7 +3801,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -3383,20 +3828,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-10-10T13:52:42+00:00" + "time": "2018-12-01T08:52:38+00:00" }, { "name": "symfony/finder", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "1f17195b44543017a9c9b2d437c670627e96ad06" + "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/1f17195b44543017a9c9b2d437c670627e96ad06", - "reference": "1f17195b44543017a9c9b2d437c670627e96ad06", + "url": "https://api.github.com/repos/symfony/finder/zipball/e53d477d7b5c4982d0e1bfd2298dbee63d01441d", + "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d", "shasum": "" }, "require": { @@ -3405,7 +3850,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -3432,20 +3877,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-10-03T08:47:56+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af" + "reference": "1b31f3017fadd8cb05cf2c8aebdbf3b12a943851" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/82d494c1492b0dd24bbc5c2d963fb02eb44491af", - "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/1b31f3017fadd8cb05cf2c8aebdbf3b12a943851", + "reference": "1b31f3017fadd8cb05cf2c8aebdbf3b12a943851", "shasum": "" }, "require": { @@ -3459,7 +3904,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -3486,25 +3931,26 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:09:42+00:00" + "time": "2018-11-26T10:55:26+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "958be64ab13b65172ad646ef5ae20364c2305fae" + "reference": "b39ceffc0388232c309cbde3a7c3685f2ec0a624" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/958be64ab13b65172ad646ef5ae20364c2305fae", - "reference": "958be64ab13b65172ad646ef5ae20364c2305fae", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/b39ceffc0388232c309cbde3a7c3685f2ec0a624", + "reference": "b39ceffc0388232c309cbde3a7c3685f2ec0a624", "shasum": "" }, "require": { "php": "^7.1.3", "psr/log": "~1.0", + "symfony/contracts": "^1.0.2", "symfony/debug": "~3.4|~4.0", "symfony/event-dispatcher": "~4.1", "symfony/http-foundation": "^4.1.1", @@ -3512,7 +3958,8 @@ }, "conflict": { "symfony/config": "<3.4", - "symfony/dependency-injection": "<4.1", + "symfony/dependency-injection": "<4.2", + "symfony/translation": "<4.2", "symfony/var-dumper": "<4.1.1", "twig/twig": "<1.34|<2.4,>=2" }, @@ -3525,7 +3972,7 @@ "symfony/config": "~3.4|~4.0", "symfony/console": "~3.4|~4.0", "symfony/css-selector": "~3.4|~4.0", - "symfony/dependency-injection": "^4.1", + "symfony/dependency-injection": "^4.2", "symfony/dom-crawler": "~3.4|~4.0", "symfony/expression-language": "~3.4|~4.0", "symfony/finder": "~3.4|~4.0", @@ -3533,7 +3980,7 @@ "symfony/routing": "~3.4|~4.0", "symfony/stopwatch": "~3.4|~4.0", "symfony/templating": "~3.4|~4.0", - "symfony/translation": "~3.4|~4.0", + "symfony/translation": "~4.2", "symfony/var-dumper": "^4.1.1" }, "suggest": { @@ -3546,7 +3993,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -3573,7 +4020,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2018-11-03T11:11:23+00:00" + "time": "2018-12-06T17:39:52+00:00" }, { "name": "symfony/polyfill-ctype", @@ -3857,16 +4304,16 @@ }, { "name": "symfony/process", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9" + "reference": "2b341009ccec76837a7f46f59641b431e4d4c2b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/3e83acef94d979b1de946599ef86b3a352abcdc9", - "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9", + "url": "https://api.github.com/repos/symfony/process/zipball/2b341009ccec76837a7f46f59641b431e4d4c2b0", + "reference": "2b341009ccec76837a7f46f59641b431e4d4c2b0", "shasum": "" }, "require": { @@ -3875,7 +4322,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -3902,7 +4349,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-10-14T20:48:13+00:00" + "time": "2018-11-20T16:22:05+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -3967,30 +4414,30 @@ }, { "name": "symfony/routing", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "d4a3c14cfbe6b9c05a1d6e948654022d4d1ad3fd" + "reference": "649460207e77da6c545326c7f53618d23ad2c866" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/d4a3c14cfbe6b9c05a1d6e948654022d4d1ad3fd", - "reference": "d4a3c14cfbe6b9c05a1d6e948654022d4d1ad3fd", + "url": "https://api.github.com/repos/symfony/routing/zipball/649460207e77da6c545326c7f53618d23ad2c866", + "reference": "649460207e77da6c545326c7f53618d23ad2c866", "shasum": "" }, "require": { "php": "^7.1.3" }, "conflict": { - "symfony/config": "<3.4", + "symfony/config": "<4.2", "symfony/dependency-injection": "<3.4", "symfony/yaml": "<3.4" }, "require-dev": { "doctrine/annotations": "~1.0", "psr/log": "~1.0", - "symfony/config": "~3.4|~4.0", + "symfony/config": "~4.2", "symfony/dependency-injection": "~3.4|~4.0", "symfony/expression-language": "~3.4|~4.0", "symfony/http-foundation": "~3.4|~4.0", @@ -4007,7 +4454,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -4040,24 +4487,25 @@ "uri", "url" ], - "time": "2018-10-28T18:38:52+00:00" + "time": "2018-12-03T22:08:12+00:00" }, { "name": "symfony/translation", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c" + "reference": "c0e2191e9bed845946ab3d99767513b56ca7dcd6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c", - "reference": "aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c", + "url": "https://api.github.com/repos/symfony/translation/zipball/c0e2191e9bed845946ab3d99767513b56ca7dcd6", + "reference": "c0e2191e9bed845946ab3d99767513b56ca7dcd6", "shasum": "" }, "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0.2", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -4065,6 +4513,9 @@ "symfony/dependency-injection": "<3.4", "symfony/yaml": "<3.4" }, + "provide": { + "symfony/translation-contracts-implementation": "1.0" + }, "require-dev": { "psr/log": "~1.0", "symfony/config": "~3.4|~4.0", @@ -4082,7 +4533,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -4109,20 +4560,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2018-10-28T18:38:52+00:00" + "time": "2018-12-06T10:45:32+00:00" }, { "name": "symfony/var-dumper", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "60319b45653580b0cdacca499344577d87732f16" + "reference": "db61258540350725f4beb6b84006e32398acd120" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/60319b45653580b0cdacca499344577d87732f16", - "reference": "60319b45653580b0cdacca499344577d87732f16", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/db61258540350725f4beb6b84006e32398acd120", + "reference": "db61258540350725f4beb6b84006e32398acd120", "shasum": "" }, "require": { @@ -4150,7 +4601,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -4184,7 +4635,7 @@ "debug", "dump" ], - "time": "2018-10-02T16:36:10+00:00" + "time": "2018-11-25T12:50:42+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -4596,16 +5047,16 @@ }, { "name": "composer/composer", - "version": "1.7.3", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7" + "reference": "d8aef3af866b28786ce9b8647e52c42496436669" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/e965b9aaa8854c3067f1ed2ae45f436572d73eb7", - "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7", + "url": "https://api.github.com/repos/composer/composer/zipball/d8aef3af866b28786ce9b8647e52c42496436669", + "reference": "d8aef3af866b28786ce9b8647e52c42496436669", "shasum": "" }, "require": { @@ -4641,7 +5092,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7-dev" + "dev-master": "1.8-dev" } }, "autoload": { @@ -4672,7 +5123,7 @@ "dependency", "package" ], - "time": "2018-11-01T09:05:06+00:00" + "time": "2018-12-03T09:31:16+00:00" }, { "name": "composer/semver", @@ -4799,16 +5250,16 @@ }, { "name": "composer/xdebug-handler", - "version": "1.3.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c" + "reference": "dc523135366eb68f22268d069ea7749486458562" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/b8e9745fb9b06ea6664d8872c4505fb16df4611c", - "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562", + "reference": "dc523135366eb68f22268d069ea7749486458562", "shasum": "" }, "require": { @@ -4839,7 +5290,7 @@ "Xdebug", "performance" ], - "time": "2018-08-31T19:07:57+00:00" + "time": "2018-11-29T10:59:02+00:00" }, { "name": "doctrine/instantiator", @@ -5935,16 +6386,16 @@ }, { "name": "phpunit/phpunit", - "version": "7.4.4", + "version": "7.5.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "b1be2c8530c4c29c3519a052c9fb6cee55053bbd" + "reference": "520723129e2b3fc1dc4c0953e43c9d40e1ecb352" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b1be2c8530c4c29c3519a052c9fb6cee55053bbd", - "reference": "b1be2c8530c4c29c3519a052c9fb6cee55053bbd", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/520723129e2b3fc1dc4c0953e43c9d40e1ecb352", + "reference": "520723129e2b3fc1dc4c0953e43c9d40e1ecb352", "shasum": "" }, "require": { @@ -5965,7 +6416,7 @@ "phpunit/php-timer": "^2.0", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", - "sebastian/environment": "^3.1 || ^4.0", + "sebastian/environment": "^4.0", "sebastian/exporter": "^3.1", "sebastian/global-state": "^2.0", "sebastian/object-enumerator": "^3.0.3", @@ -5989,7 +6440,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.4-dev" + "dev-master": "7.5-dev" } }, "autoload": { @@ -6015,7 +6466,7 @@ "testing", "xunit" ], - "time": "2018-11-14T16:52:02+00:00" + "time": "2018-12-07T07:08:12+00:00" }, { "name": "roave/security-advisories", @@ -6023,12 +6474,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "d71acf1340f7fb24b3469a892c130263c08e0a43" + "reference": "1ce3116aa589688c340d408bb8dedb3cc8e392ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/d71acf1340f7fb24b3469a892c130263c08e0a43", - "reference": "d71acf1340f7fb24b3469a892c130263c08e0a43", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/1ce3116aa589688c340d408bb8dedb3cc8e392ff", + "reference": "1ce3116aa589688c340d408bb8dedb3cc8e392ff", "shasum": "" }, "conflict": { @@ -6065,7 +6516,10 @@ "drupal/core": ">=7,<7.60|>=8,<8.5.8|>=8.6,<8.6.2", "drupal/drupal": ">=7,<7.60|>=8,<8.5.8|>=8.6,<8.6.2", "erusev/parsedown": "<1.7", - "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.5|>=5.4,<5.4.12.2|>=2017.8,<2017.8.1.1|>=2017.12,<2017.12.4.2|>=2018.6,<2018.6.1.3|>=2018.9,<2018.9.1.2", + "ezsystems/ezplatform": "<1.7.8.1|>=1.8,<1.13.4.1|>=2,<2.2.3.1|>=2.3,<2.3.2.1", + "ezsystems/ezpublish-kernel": ">=5.3,<5.3.12.1|>=5.4,<5.4.13.1|>=6,<6.7.9.1|>=6.8,<6.13.5.1|>=7,<7.2.4.1|>=7.3,<7.3.2.1", + "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.6|>=5.4,<5.4.12.3|>=2011,<2017.12.4.3|>=2018.6,<2018.6.1.4|>=2018.9,<2018.9.1.3", + "ezsystems/repository-forms": ">=2.3,<2.3.2.1", "ezyang/htmlpurifier": "<4.1.1", "firebase/php-jwt": "<2", "fooman/tcpdf": "<6.2.22", @@ -6089,9 +6543,9 @@ "la-haute-societe/tcpdf": "<6.2.22", "laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30", "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", - "magento/magento1ce": "<1.9.3.9", - "magento/magento1ee": ">=1.9,<1.14.3.2", - "magento/product-community-edition": ">=2,<2.2.6", + "magento/magento1ce": "<1.9.4", + "magento/magento1ee": ">=1.9,<1.14.4", + "magento/product-community-edition": ">=2,<2.2.7", "monolog/monolog": ">=1.8,<1.12", "namshi/jose": "<2.2", "onelogin/php-saml": "<2.10.4", @@ -6103,6 +6557,7 @@ "paragonie/random_compat": "<2", "paypal/merchant-sdk-php": "<3.12", "phpmailer/phpmailer": ">=5,<5.2.27|>=6,<6.0.6", + "phpoffice/phpexcel": "<=1.8.1", "phpoffice/phpspreadsheet": "<=1.5", "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", "phpwhois/phpwhois": "<=4.2.5", @@ -6133,7 +6588,7 @@ "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", "sylius/sylius": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", "symfony/dependency-injection": ">=2,<2.0.17", - "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2", "symfony/http-foundation": ">=2,<2.7.49|>=2.8,<2.8.44|>=3,<3.3.18|>=3.4,<3.4.14|>=4,<4.0.14|>=4.1,<4.1.3", "symfony/http-kernel": ">=2,<2.3.29|>=2.4,<2.5.12|>=2.6,<2.6.8", @@ -6141,21 +6596,21 @@ "symfony/polyfill": ">=1,<1.10", "symfony/polyfill-php55": ">=1,<1.10", "symfony/routing": ">=2,<2.0.19", - "symfony/security": ">=2,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", + "symfony/security": ">=2,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.19|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", "symfony/security-bundle": ">=2,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<2.8.37|>=3,<3.3.17|>=3.4,<3.4.7|>=4,<4.0.7", "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-guard": ">=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", - "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", + "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", "symfony/serializer": ">=2,<2.0.11", - "symfony/symfony": ">=2,<2.7.49|>=2.8,<2.8.44|>=3,<3.3.18|>=3.4,<3.4.14|>=4,<4.0.14|>=4.1,<4.1.3", + "symfony/symfony": ">=2,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", "symfony/translation": ">=2,<2.0.17", "symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3", "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7", "tecnickcom/tcpdf": "<6.2.22", "thelia/backoffice-default-template": ">=2.1,<2.1.2", - "thelia/thelia": ">=2.1,<2.1.2|>=2.1.0-beta1,<2.1.3", + "thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2", "theonedemon/phpwhois": "<=4.2.5", "titon/framework": ">=0,<9.9.99", "truckersmp/phpwhois": "<=4.3.1", @@ -6212,7 +6667,7 @@ } ], "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", - "time": "2018-11-21T13:18:22+00:00" + "time": "2018-12-10T15:00:47+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -6381,28 +6836,28 @@ }, { "name": "sebastian/environment", - "version": "3.1.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + "reference": "febd209a219cea7b56ad799b30ebbea34b71eb8f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/febd209a219cea7b56ad799b30ebbea34b71eb8f", + "reference": "febd209a219cea7b56ad799b30ebbea34b71eb8f", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.1" + "phpunit/phpunit": "^7.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -6427,7 +6882,7 @@ "environment", "hhvm" ], - "time": "2017-07-01T08:51:00+00:00" + "time": "2018-11-25T09:31:21+00:00" }, { "name": "sebastian/exporter", @@ -6872,16 +7327,16 @@ }, { "name": "symfony/config", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238" + "reference": "005d9a083d03f588677d15391a716b1ac9b887c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", - "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", + "url": "https://api.github.com/repos/symfony/config/zipball/005d9a083d03f588677d15391a716b1ac9b887c0", + "reference": "005d9a083d03f588677d15391a716b1ac9b887c0", "shasum": "" }, "require": { @@ -6904,7 +7359,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -6931,20 +7386,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:09:42+00:00" + "time": "2018-11-30T22:21:14+00:00" }, { "name": "symfony/filesystem", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981" + "reference": "2f4c8b999b3b7cadb2a69390b01af70886753710" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/fd7bd6535beb1f0a0a9e3ee960666d0598546981", - "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/2f4c8b999b3b7cadb2a69390b01af70886753710", + "reference": "2f4c8b999b3b7cadb2a69390b01af70886753710", "shasum": "" }, "require": { @@ -6954,7 +7409,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -6981,29 +7436,30 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-10-30T13:18:25+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "5bfc064125b73ff81229e19381ce1c34d3416f4b" + "reference": "ec076716412274e51f8a7ea675d9515e5c311123" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5bfc064125b73ff81229e19381ce1c34d3416f4b", - "reference": "5bfc064125b73ff81229e19381ce1c34d3416f4b", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/ec076716412274e51f8a7ea675d9515e5c311123", + "reference": "ec076716412274e51f8a7ea675d9515e5c311123", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -7030,20 +7486,20 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/yaml", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "367e689b2fdc19965be435337b50bc8adf2746c9" + "reference": "c41175c801e3edfda90f32e292619d10c27103d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/367e689b2fdc19965be435337b50bc8adf2746c9", - "reference": "367e689b2fdc19965be435337b50bc8adf2746c9", + "url": "https://api.github.com/repos/symfony/yaml/zipball/c41175c801e3edfda90f32e292619d10c27103d7", + "reference": "c41175c801e3edfda90f32e292619d10c27103d7", "shasum": "" }, "require": { @@ -7062,7 +7518,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -7089,7 +7545,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-10-02T16:36:10+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "theseer/tokenizer", diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index 9a702f7221..dd086000bc 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -22,30 +22,6 @@ declare(strict_types=1); use Carbon\Carbon; -/* -|-------------------------------------------------------------------------- -| Model Factories -|-------------------------------------------------------------------------- -| -| Here you may define all of your model factories. Model factories give -| you a convenient way to create models for testing and seeding your -| database. Just tell the factory how a default model should look. -| -*/ - -$factory->define( - FireflyIII\User::class, - function (Faker\Generator $faker) { - static $password; - - return [ - 'email' => $faker->safeEmail, - 'password' => $password ?: $password = bcrypt('secret'), - 'remember_token' => str_random(10), - ]; - } -); - $factory->define( FireflyIII\Models\Attachment::class, diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php new file mode 100644 index 0000000000..a4728e7945 --- /dev/null +++ b/database/factories/UserFactory.php @@ -0,0 +1,43 @@ +. + */ + +use Faker\Generator as Faker; + +/* +|-------------------------------------------------------------------------- +| Model Factories +|-------------------------------------------------------------------------- +| +| This directory should contain each of the model factory definitions for +| your application. Factories provide a convenient way to generate new +| model instances for testing / seeding your application's database. +| +*/ + +$factory->define( + FireflyIII\User::class, function (Faker $faker) { + return [ + 'email' => $faker->unique()->safeEmail, + 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret + 'remember_token' => str_random(10), + ]; +} +); diff --git a/tests/Api/V1/Controllers/AboutControllerTest.php b/tests/Api/V1/Controllers/AboutControllerTest.php index a36c5dbaa8..3e99f3e932 100644 --- a/tests/Api/V1/Controllers/AboutControllerTest.php +++ b/tests/Api/V1/Controllers/AboutControllerTest.php @@ -49,14 +49,20 @@ class AboutControllerTest extends TestCase */ public function testAbout(): void { - // test API - $response = $this->get('/api/v1/about'); + + $search = ['~', '#']; + $replace = ['\~', '# ']; + $phpVersion = str_replace($search, $replace, PHP_VERSION); + $phpOs = str_replace($search, $replace, PHP_OS); + $response = $this->get(route('api.v1.about.index')); $response->assertStatus(200); $response->assertJson( ['data' => [ - 'version' => true, - 'api_version' => true, - 'php_version' => true, + 'version' => config('firefly.version'), + 'api_version' => config('firefly.api_version'), + 'php_version' => $phpVersion, + 'os' => $phpOs, + 'driver' => 'sqlite', ]] ); } @@ -68,11 +74,16 @@ class AboutControllerTest extends TestCase */ public function testUser(): void { - // test API - $response = $this->get('/api/v1/about/user'); + $response = $this->get(route('api.v1.about.user')); $response->assertStatus(200); - $response->assertJson(['data' => ['attributes' => true, 'links' => true]]); - $this->assertEquals($this->user()->id, $response->json()['data']['id']); + $response->assertJson( + [ + 'data' => [ + 'attributes' => true, + 'links' => true, + ], + ] + ); } diff --git a/tests/Api/V1/Controllers/AccountControllerTest.php b/tests/Api/V1/Controllers/AccountControllerTest.php index 9fd573ee99..019a2a1a4e 100644 --- a/tests/Api/V1/Controllers/AccountControllerTest.php +++ b/tests/Api/V1/Controllers/AccountControllerTest.php @@ -23,10 +23,15 @@ declare(strict_types=1); namespace Tests\Api\V1\Controllers; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Collector\TransactionCollector; +use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Models\Account; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; use Laravel\Passport\Passport; use Log; use Mockery; @@ -184,7 +189,7 @@ class AccountControllerTest extends TestCase [ 'message' => 'The given data was invalid.', 'errors' => [ - 'credit_card_type' => ['The credit card type field is required when account role is ccAsset.'], + 'credit_card_type' => ['The credit card type field is required when account role is ccAsset.'], 'monthly_payment_date' => ['The monthly payment date field is required when account role is ccAsset.'], ], @@ -233,6 +238,47 @@ class AccountControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/json'); } + /** + * Test the list of piggy banks. + * + * @covers \FireflyIII\Api\V1\Controllers\AccountController + */ + public function testPiggyBanks(): void + { + // mock stuff: + $repository = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + + // get piggies for this user. + $piggies = $this->user()->piggyBanks()->get(); + $asset = $this->getRandomAsset(); + + // mock calls: + $repository->shouldReceive('setUser'); + $currencyRepos->shouldReceive('setUser'); + $piggyRepos->shouldReceive('setUser'); + + $repository->shouldReceive('getPiggyBanks')->andReturn($piggies)->once(); + $piggyRepos->shouldReceive('getCurrentAmount')->andReturn('12.45'); + $piggyRepos->shouldReceive('getSuggestedMonthlyAmount')->andReturn('12.45'); + $repository->shouldReceive('getMetaValue')->atLeast()->once()->andReturn(''); + + // test API + $response = $this->get(route('api.v1.accounts.piggy_banks', [$asset->id])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson( + ['meta' => ['pagination' => ['total' => $piggies->count(), 'count' => $piggies->count(), 'per_page' => true, 'current_page' => 1, + 'total_pages' => 1]],] + ); + $response->assertJson( + ['links' => ['self' => true, 'first' => true, 'last' => true,],] + ); + $response->assertSee('page=1'); // default returns this. + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Show an account. * @@ -459,6 +505,202 @@ class AccountControllerTest extends TestCase $response->assertSee($account->name); } + /** + * Show index. + * + * @covers \FireflyIII\Api\V1\Controllers\AccountController + */ + public function testTransactionsBasic(): void + { + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $accountRepos->shouldReceive('setUser'); + $accountRepos->shouldReceive('getAccountsByType') + ->andReturn($this->user()->accounts()->where('account_type_id', 3)->get()); + + $asset = $this->getRandomAsset(); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $accountRepos->shouldReceive('isAsset')->atLeast()->once()->andReturnTrue(); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setAccounts')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + + + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // mock some calls: + + // test API + $response = $this->get(route('api.v1.accounts.transactions', [$asset->id])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * Show index. + * + * @covers \FireflyIII\Api\V1\Controllers\AccountController + */ + public function testTransactionsOpposing(): void + { + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $accountRepos->shouldReceive('setUser'); + $accountRepos->shouldReceive('getAccountsByType') + ->andReturn($this->user()->accounts()->where('account_type_id', 3)->get()); + + $revenue = $this->getRandomRevenue(); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $accountRepos->shouldReceive('isAsset')->atLeast()->once()->andReturnFalse(); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setOpposingAccounts')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + + + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // mock some calls: + + // test API + $response = $this->get(route('api.v1.accounts.transactions', [$revenue->id])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * Show index. + * + * @covers \FireflyIII\Api\V1\Controllers\AccountController + */ + public function testTransactionsRange(): void + { + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $accountRepos->shouldReceive('setUser'); + $accountRepos->shouldReceive('getAccountsByType') + ->andReturn($this->user()->accounts()->where('account_type_id', 3)->get()); + + $asset = $this->getRandomAsset(); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $accountRepos->shouldReceive('isAsset')->atLeast()->once()->andReturnTrue(); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setAccounts')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setRange')->andReturnSelf(); + + + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // mock some calls: + + // test API + $response = $this->get(route('api.v1.accounts.transactions', [$asset->id]) . '?' . http_build_query(['start' => '2018-01-01', 'end' => '2018-01-31'])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Update first asset account we find. Name can be the same as it was. * diff --git a/tests/Api/V1/Controllers/AttachmentControllerTest.php b/tests/Api/V1/Controllers/AttachmentControllerTest.php index ac515576e0..70cb52f6fe 100644 --- a/tests/Api/V1/Controllers/AttachmentControllerTest.php +++ b/tests/Api/V1/Controllers/AttachmentControllerTest.php @@ -57,7 +57,7 @@ class AttachmentControllerTest extends TestCase public function testDelete(): void { // mock stuff: - $repository = $this->mock(AttachmentRepositoryInterface::class); + $repository = $this->mock(AttachmentRepositoryInterface::class); $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); // mock calls: $repository->shouldReceive('setUser')->once(); @@ -79,10 +79,10 @@ class AttachmentControllerTest extends TestCase public function testDownload(): void { // mock stuff: - $repository = $this->mock(AttachmentRepositoryInterface::class); + $repository = $this->mock(AttachmentRepositoryInterface::class); $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); - $content = 'Attachment content ' . random_int(100, 1000); + $content = 'Attachment content ' . random_int(100, 1000); // mock calls: $repository->shouldReceive('setUser')->once(); $repository->shouldReceive('exists')->andReturn(true)->once(); @@ -107,10 +107,10 @@ class AttachmentControllerTest extends TestCase public function testDownloadNotExisting(): void { // mock stuff: - $repository = $this->mock(AttachmentRepositoryInterface::class); + $repository = $this->mock(AttachmentRepositoryInterface::class); $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); - $content = 'Attachment content ' . random_int(100, 1000); + $content = 'Attachment content ' . random_int(100, 1000); // mock calls: $repository->shouldReceive('setUser')->once(); $repository->shouldReceive('exists')->andReturn(false)->once(); @@ -133,7 +133,7 @@ class AttachmentControllerTest extends TestCase public function testDownloadNotUploaded(): void { // mock stuff: - $repository = $this->mock(AttachmentRepositoryInterface::class); + $repository = $this->mock(AttachmentRepositoryInterface::class); $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); // mock calls: @@ -172,7 +172,7 @@ class AttachmentControllerTest extends TestCase $attachments = factory(Attachment::class, 10)->create(); // mock stuff: - $repository = $this->mock(AttachmentRepositoryInterface::class); + $repository = $this->mock(AttachmentRepositoryInterface::class); $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); @@ -201,7 +201,7 @@ class AttachmentControllerTest extends TestCase $attachment = $this->user()->attachments()->first(); // mock stuff: - $repository = $this->mock(AttachmentRepositoryInterface::class); + $repository = $this->mock(AttachmentRepositoryInterface::class); $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); @@ -230,8 +230,8 @@ class AttachmentControllerTest extends TestCase $attachment = $this->user()->attachments()->first(); // mock stuff: - $repository = $this->mock(AttachmentRepositoryInterface::class); - $journalRepos = $this->mock(JournalRepositoryInterface::class); + $repository = $this->mock(AttachmentRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); @@ -268,7 +268,7 @@ class AttachmentControllerTest extends TestCase public function testUpdate(): void { // mock repositories - $repository = $this->mock(AttachmentRepositoryInterface::class); + $repository = $this->mock(AttachmentRepositoryInterface::class); $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); @@ -304,7 +304,7 @@ class AttachmentControllerTest extends TestCase */ public function testUpload(): void { - $repository = $this->mock(AttachmentRepositoryInterface::class); + $repository = $this->mock(AttachmentRepositoryInterface::class); $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); $repository->shouldReceive('setUser')->once(); diff --git a/tests/Api/V1/Controllers/BillControllerTest.php b/tests/Api/V1/Controllers/BillControllerTest.php index 15b4ea1069..10a799f56e 100644 --- a/tests/Api/V1/Controllers/BillControllerTest.php +++ b/tests/Api/V1/Controllers/BillControllerTest.php @@ -24,8 +24,16 @@ declare(strict_types=1); namespace Tests\Api\V1\Controllers; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Collector\TransactionCollector; +use FireflyIII\Helpers\Collector\TransactionCollectorInterface; +use FireflyIII\Models\Attachment; use FireflyIII\Models\Bill; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Collection; use Laravel\Passport\Passport; @@ -48,6 +56,37 @@ class BillControllerTest extends TestCase } + /** + * List all attachments. + * + * @covers \FireflyIII\Api\V1\Controllers\BillController + */ + public function testAttachments(): void + { + // create stuff + $attachments = factory(Attachment::class, 10)->create(); + $bill = $this->user()->bills()->first(); + // mock stuff: + $repository = $this->mock(AttachmentRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $billRepos = $this->mock(BillRepositoryInterface::class); + + + // mock calls: + $repository->shouldReceive('setUser'); + $billRepos->shouldReceive('setUser'); + $billRepos->shouldReceive('getAttachments')->once()->andReturn($attachments); + $repository->shouldReceive('getNoteText')->andReturn('Hi There'); + + // test API + $response = $this->get(route('api.v1.bills.attachments', [$bill->id])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => 10, 'count' => 10, 'per_page' => true, 'current_page' => 1, 'total_pages' => 1]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Send delete * @@ -100,6 +139,24 @@ class BillControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * @covers \FireflyIII\Api\V1\Controllers\BillController + */ + public function testRules(): void + { + $rules = $this->user()->rules()->get(); + $bill = $this->user()->bills()->first(); + $billRepos = $this->mock(BillRepositoryInterface::class); + $billRepos->shouldReceive('setUser')->once(); + $billRepos->shouldReceive('getRulesForBill')->once()->andReturn($rules); + + // call API + $response = $this->get(route('api.v1.bills.rules', [$bill->id])); + $response->assertStatus(200); + $response->assertSee($rules->first()->title); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Show one bill * @@ -213,6 +270,131 @@ class BillControllerTest extends TestCase $response->assertSee($bill->name); } + /** + * Show index. + * + * @covers \FireflyIII\Api\V1\Controllers\BillController + */ + public function testTransactionsBasic(): void + { + $bill = $this->user()->bills()->first(); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $billRepos = $this->mock(BillRepositoryInterface::class); + $billRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setBills')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf(); + + + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // mock some calls: + + // test API + $response = $this->get(route('api.v1.bills.transactions', [$bill->id])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * Show index. + * + * @covers \FireflyIII\Api\V1\Controllers\BillController + */ + public function testTransactionsRange(): void + { + $bill = $this->user()->bills()->first(); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $billRepos = $this->mock(BillRepositoryInterface::class); + $billRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setBills')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setRange')->andReturnSelf(); + + + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // mock some calls: + + // test API + $response = $this->get(route('api.v1.bills.transactions', [$bill->id]) . '?' . http_build_query(['start' => '2018-01-01', 'end' => '2018-01-31'])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Update a valid bill. * diff --git a/tests/Api/V1/Controllers/BudgetControllerTest.php b/tests/Api/V1/Controllers/BudgetControllerTest.php index 1c00519a84..618803975b 100644 --- a/tests/Api/V1/Controllers/BudgetControllerTest.php +++ b/tests/Api/V1/Controllers/BudgetControllerTest.php @@ -24,8 +24,16 @@ declare(strict_types=1); namespace Tests\Api\V1\Controllers; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Collector\TransactionCollector; +use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Models\Budget; +use FireflyIII\Models\BudgetLimit; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use Laravel\Passport\Passport; use Log; use Tests\TestCase; @@ -46,6 +54,27 @@ class BudgetControllerTest extends TestCase Log::info(sprintf('Now in %s.', \get_class($this))); } + /** + * Show all budgets + * + * @covers \FireflyIII\Api\V1\Controllers\BudgetController + */ + public function testBudgetLimits(): void + { + $budget = $this->user()->budgets()->first(); + $budgetLimits = BudgetLimit::get(); + $repository = $this->mock(BudgetRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('getBudgetLimits')->once()->andReturn($budgetLimits); + + // call API + $response = $this->get(route('api.v1.budgets.budget_limits', [$budget->id])); + $response->assertStatus(200); + $response->assertSee('budget_limits'); + } + /** * Delete a budget. * @@ -141,6 +170,173 @@ class BudgetControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * Store new budget limit. + * + * @covers \FireflyIII\Api\V1\Controllers\BudgetController + * @covers \FireflyIII\Api\V1\Requests\BudgetLimitRequest + */ + public function testStoreBudgetLimit(): void + { + $budget = $this->user()->budgets()->first(); + $budgetLimit = BudgetLimit::create( + [ + 'budget_id' => $budget->id, + 'start_date' => '2018-01-01', + 'end_date' => '2018-01-31', + 'amount' => 1, + ] + ); + $data + = [ + 'budget_id' => $budget->id, + 'start' => '2018-01-01', + 'end' => '2018-01-31', + 'amount' => 1, + ]; + // mock stuff: + $repository = $this->mock(BudgetRepositoryInterface::class); + $repository->shouldReceive('storeBudgetLimit')->andReturn($budgetLimit)->once(); + + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('storeBudgetLimit')->andReturn($budgetLimit); + + // call API + $response = $this->post(route('api.v1.budgets.store_budget_limit', [$budget->id]), $data, ['Accept' => 'application/json']); + $response->assertStatus(200); + $response->assertSee('budget_limits'); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * Show index. + * + * @covers \FireflyIII\Api\V1\Controllers\BudgetController + */ + public function testTransactionsBasic(): void + { + $budget = $this->user()->budgets()->first(); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $billRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + $budgetRepos->shouldReceive('setUser'); + + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setBudget')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf(); + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // mock some calls: + + // test API + $response = $this->get(route('api.v1.budgets.transactions', [$budget->id])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * Show index. + * + * @covers \FireflyIII\Api\V1\Controllers\BudgetController + */ + public function testTransactionsRange(): void + { + $budget = $this->user()->budgets()->first(); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $billRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + $budgetRepos->shouldReceive('setUser'); + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setBudget')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setRange')->andReturnSelf(); + + + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // mock some calls: + + // test API + $response = $this->get(route('api.v1.budgets.transactions', [$budget->id]) . '?' . http_build_query(['start' => '2018-01-01', 'end' => '2018-01-31'])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Update a budget. * @@ -173,5 +369,4 @@ class BudgetControllerTest extends TestCase $response->assertSee($budget->name); } - } diff --git a/tests/Api/V1/Controllers/BudgetLimitControllerTest.php b/tests/Api/V1/Controllers/BudgetLimitControllerTest.php index 17bf4ed966..417d23ab89 100644 --- a/tests/Api/V1/Controllers/BudgetLimitControllerTest.php +++ b/tests/Api/V1/Controllers/BudgetLimitControllerTest.php @@ -24,9 +24,16 @@ declare(strict_types=1); namespace Tests\Api\V1\Controllers; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Collector\TransactionCollector; +use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use Laravel\Passport\Passport; use Log; use Tests\TestCase; @@ -174,10 +181,10 @@ class BudgetLimitControllerTest extends TestCase $budget = $this->user()->budgets()->first(); $budgetLimit = BudgetLimit::create( [ - 'budget_id' => $budget->id, - 'start_date' => '2018-01-01', - 'end_date' => '2018-01-31', - 'amount' => 1, + 'budget_id' => $budget->id, + 'start_date' => '2018-01-01', + 'end_date' => '2018-01-31', + 'amount' => 1, ] ); @@ -198,10 +205,10 @@ class BudgetLimitControllerTest extends TestCase $budget = $this->user()->budgets()->first(); $budgetLimit = BudgetLimit::create( [ - 'budget_id' => $budget->id, - 'start_date' => '2018-01-01', - 'end_date' => '2018-01-31', - 'amount' => 1, + 'budget_id' => $budget->id, + 'start_date' => '2018-01-01', + 'end_date' => '2018-01-31', + 'amount' => 1, ] ); $data @@ -255,6 +262,70 @@ class BudgetLimitControllerTest extends TestCase $response->assertSee('Unknown budget.'); } + /** + * Show index. + * + * @covers \FireflyIII\Api\V1\Controllers\BudgetLimitController + */ + public function testTransactionsBasic(): void + { + $budgetLimit = BudgetLimit::first(); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $billRepos = $this->mock(BillRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $billRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + $budgetRepos->shouldReceive('setUser'); + + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setBudget')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setRange')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf(); + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // mock some calls: + + // test API + $response = $this->get(route('api.v1.budget_limits.transactions', [$budgetLimit->id])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Test update of budget limit. * @@ -266,10 +337,10 @@ class BudgetLimitControllerTest extends TestCase $budget = $this->user()->budgets()->first(); $budgetLimit = BudgetLimit::create( [ - 'budget_id' => $budget->id, - 'start_date' => '2018-01-01', - 'end_date' => '2018-01-31', - 'amount' => 1, + 'budget_id' => $budget->id, + 'start_date' => '2018-01-01', + 'end_date' => '2018-01-31', + 'amount' => 1, ] ); $data diff --git a/tests/Api/V1/Controllers/CategoryControllerTest.php b/tests/Api/V1/Controllers/CategoryControllerTest.php index 0dfae77a9b..2757375abb 100644 --- a/tests/Api/V1/Controllers/CategoryControllerTest.php +++ b/tests/Api/V1/Controllers/CategoryControllerTest.php @@ -24,8 +24,15 @@ declare(strict_types=1); namespace Tests\Api\V1\Controllers; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Collector\TransactionCollector; +use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Models\Category; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use Laravel\Passport\Passport; use Log; use Tests\TestCase; @@ -143,6 +150,132 @@ class CategoryControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * Show index. + * + * @covers \FireflyIII\Api\V1\Controllers\CategoryController + */ + public function testTransactionsBasic(): void + { + $category = $this->user()->categories()->first(); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $billRepos = $this->mock(BillRepositoryInterface::class); + $billRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setCategory')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf(); + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // mock some calls: + + // test API + $response = $this->get(route('api.v1.categories.transactions', [$category->id])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * Show index. + * + * @covers \FireflyIII\Api\V1\Controllers\CategoryController + */ + public function testTransactionsRange(): void + { + $category = $this->user()->categories()->first(); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $billRepos = $this->mock(BillRepositoryInterface::class); + $billRepos->shouldReceive('setUser'); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setCategory')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('setRange')->andReturnSelf(); + + + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // mock some calls: + + // test API + + $response = $this->get( + route('api.v1.categories.transactions', [$category->id]) . '?' . http_build_query(['start' => '2018-01-01', 'end' => '2018-01-31']) + ); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Update a category. * @@ -175,5 +308,4 @@ class CategoryControllerTest extends TestCase $response->assertSee($category->name); } - } diff --git a/tests/Api/V1/Controllers/ConfigurationControllerTest.php b/tests/Api/V1/Controllers/ConfigurationControllerTest.php index 60856b8fa8..e69126950d 100644 --- a/tests/Api/V1/Controllers/ConfigurationControllerTest.php +++ b/tests/Api/V1/Controllers/ConfigurationControllerTest.php @@ -119,7 +119,7 @@ class ConfigurationControllerTest extends TestCase { $userRepos = $this->mock(UserRepositoryInterface::class); $userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true); - $data = [ + $data = [ 'value' => 1, ]; @@ -221,10 +221,10 @@ class ConfigurationControllerTest extends TestCase public function testUpdateInvalid(): void { $userRepos = $this->mock(UserRepositoryInterface::class); - $data = [ + $data = [ 'value' => 'true', ]; - $response = $this->post('/api/v1/configuration/last_update_check', $data); + $response = $this->post('/api/v1/configuration/last_update_check', $data); $response->assertStatus(404); } diff --git a/tests/Api/V1/Controllers/CurrencyControllerTest.php b/tests/Api/V1/Controllers/CurrencyControllerTest.php index d472187f76..6e5f08eb80 100644 --- a/tests/Api/V1/Controllers/CurrencyControllerTest.php +++ b/tests/Api/V1/Controllers/CurrencyControllerTest.php @@ -24,10 +24,25 @@ declare(strict_types=1); namespace Tests\Api\V1\Controllers; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Collector\TransactionCollector; +use FireflyIII\Helpers\Collector\TransactionCollectorInterface; +use FireflyIII\Models\Account; +use FireflyIII\Models\Bill; +use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\Preference; use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; +use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; +use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; +use FireflyIII\Repositories\Rule\RuleRepositoryInterface; use FireflyIII\Repositories\User\UserRepositoryInterface; +use Illuminate\Pagination\LengthAwarePaginator; +use Illuminate\Support\Collection; use Laravel\Passport\Passport; use Log; use Mockery; @@ -50,6 +65,134 @@ class CurrencyControllerTest extends TestCase } + /** + * Test the list of accounts. + * + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testAccounts(): void + { + // create stuff + $accounts = factory(Account::class, 10)->create(); + + // mock stuff: + $repository = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $userRepos = $this->mock(UserRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $repository->shouldReceive('getAccountsByType')->withAnyArgs()->andReturn($accounts)->once(); + $currencyRepos->shouldReceive('setUser'); + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('defaultAsset'); + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1'); + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountNumber'])->andReturn('1'); + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC'); + $repository->shouldReceive('getNoteText')->withArgs([Mockery::any()])->andReturn('Hello'); + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('2')->atLeast()->once(); + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest_period'])->andReturn('daily')->atLeast()->once(); + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn(true)->atLeast()->once(); + + // test API + $currency = TransactionCurrency::first(); + $response = $this->get(route('api.v1.currencies.accounts', [$currency->code])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => 10, 'count' => 10, 'per_page' => true, 'current_page' => 1, 'total_pages' => 1]],]); + $response->assertJson( + ['links' => ['self' => true, 'first' => true, 'last' => true,],] + ); + $response->assertSee('type=all'); // default returns this. + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * Show all available budgets. + * + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testAvailableBudgets(): void + { + $availableBudgets = $this->user()->availableBudgets()->get(); + // mock stuff: + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + + + // mock calls: + $budgetRepos->shouldReceive('setUser')->once(); + $budgetRepos->shouldReceive('getAvailableBudgets')->once()->andReturn($availableBudgets); + + // call API + $currency = TransactionCurrency::first(); + $response = $this->get(route('api.v1.currencies.available_budgets', [$currency->code])); + $response->assertStatus(200); + $response->assertSee($availableBudgets->first()->id); + } + + /** + * Show all bills + * + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testBills(): void + { + // create stuff + $bills = factory(Bill::class, 10)->create(); + $paginator = new LengthAwarePaginator($bills, 10, 50, 1); + // mock stuff: + $repository = $this->mock(BillRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $repository->shouldReceive('getPaginator')->withAnyArgs()->andReturn($paginator)->once(); + $repository->shouldReceive('getRulesForBill')->withAnyArgs()->andReturn(new Collection()); + $repository->shouldReceive('getNoteText')->andReturn('Hi there'); + + // test API + $currency = TransactionCurrency::first(); + $response = $this->get(route('api.v1.currencies.bills', [$currency->code])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => 10, 'count' => 10, 'per_page' => true, 'current_page' => 1, 'total_pages' => 1]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testBudgetLimits(): void + { + $repository = $this->mock(BudgetRepositoryInterface::class); + $currency = TransactionCurrency::first(); + $budgetLimit = BudgetLimit::first(); + $budgetLimit->transaction_currency_id = $currency->id; + $collection = new Collection([$budgetLimit]); + // mock calls: + $repository->shouldReceive('getAllBudgetLimits')->once()->andReturn($collection); + + + $response = $this->get(route('api.v1.currencies.budget_limits', [$currency->code])); + $response->assertStatus(200); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testCer(): void + { + $repository = $this->mock(CurrencyRepositoryInterface::class); + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('getExchangeRates')->once()->andReturn(new Collection); + + + $currency = TransactionCurrency::first(); + $response = $this->get(route('api.v1.currencies.cer', [$currency->code])); + $response->assertStatus(200); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Send delete * @@ -77,6 +220,80 @@ class CurrencyControllerTest extends TestCase $response->assertStatus(204); } + /** + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testDisable(): void + { + // create stuff + $currency = TransactionCurrency::first(); + $repository = $this->mock(CurrencyRepositoryInterface::class); + $userRepos = $this->mock(UserRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('disable')->once(); + $repository->shouldReceive('currencyInUse')->once()->andReturnFalse(); + + // test API + $response = $this->post(route('api.v1.currencies.disable', [$currency->code])); + $response->assertStatus(200); + $response->assertJson( + ['data' => [ + 'type' => 'currencies', + 'id' => $currency->id, + ],] + ); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testDisableInUse(): void + { + // create stuff + $currency = TransactionCurrency::first(); + $repository = $this->mock(CurrencyRepositoryInterface::class); + $userRepos = $this->mock(UserRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('currencyInUse')->once()->andReturnTrue(); + + // test API + $response = $this->post(route('api.v1.currencies.disable', [$currency->code])); + $response->assertStatus(409); + $response->assertJson([]); + $response->assertHeader('Content-Type', 'application/json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testEnable(): void + { + // create stuff + $currency = TransactionCurrency::first(); + $repository = $this->mock(CurrencyRepositoryInterface::class); + $userRepos = $this->mock(UserRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('enable')->once(); + + // test API + $response = $this->post(route('api.v1.currencies.enable', [$currency->code])); + $response->assertStatus(200); + $response->assertJson( + ['data' => [ + 'type' => 'currencies', + 'id' => $currency->id, + ],] + ); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Show index. * @@ -116,6 +333,78 @@ class CurrencyControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testMakeDefault(): void + { + // create stuff + $currency = TransactionCurrency::first(); + $repository = $this->mock(CurrencyRepositoryInterface::class); + $userRepos = $this->mock(UserRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('enable')->once(); + + // test API + $response = $this->post(route('api.v1.currencies.default', [$currency->code])); + $response->assertStatus(200); + $response->assertJson( + ['data' => [ + 'type' => 'currencies', + 'id' => $currency->id, + ],] + ); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testRecurrences(): void + { + $recurrences = $this->user()->recurrences()->get(); + + // mock stuff: + $repository = $this->mock(RecurringRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $repository->shouldReceive('getAll')->once()->andReturn($recurrences); + $repository->shouldReceive('getNoteText')->andReturn('Notes.'); + $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); + $repository->shouldReceive('getXOccurrences')->andReturn([]); + + + // call API + $currency = TransactionCurrency::first(); + $response = $this->get(route('api.v1.currencies.recurrences', [$currency->code])); + $response->assertStatus(200); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testRules(): void + { + $rules = $this->user()->rules()->get(); + + $ruleRepos = $this->mock(RuleRepositoryInterface::class); + $ruleRepos->shouldReceive('getAll')->once()->andReturn($rules); + + + // call API + $currency = TransactionCurrency::first(); + $response = $this->get(route('api.v1.currencies.rules', [$currency->code])); + $response->assertStatus(200); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** * Test show of a currency. * @@ -218,6 +507,123 @@ class CurrencyControllerTest extends TestCase $response->assertSee($currency->name); } + /** + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testTransactionsBasic(): void + { + $currency = TransactionCurrency::first(); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $accountRepos->shouldReceive('setUser'); + $accountRepos->shouldReceive('getAccountsByType')->atLeast()->once() + ->andReturn($this->user()->accounts()->where('account_type_id', 3)->get()); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setCurrency')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // test API + $response = $this->get(route('api.v1.currencies.transactions', [$currency->code])); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\CurrencyController + */ + public function testTransactionsRange(): void + { + $currency = TransactionCurrency::first(); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $accountRepos->shouldReceive('setUser'); + $accountRepos->shouldReceive('getAccountsByType')->atLeast()->once() + ->andReturn($this->user()->accounts()->where('account_type_id', 3)->get()); + + // get some transactions using the collector: + Log::info('This transaction collector is OK, because it is used in a test:'); + $collector = new TransactionCollector; + $collector->setUser($this->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setLimit(5)->setPage(1); + try { + $paginator = $collector->getPaginatedTransactions(); + } catch (FireflyException $e) { + $this->assertTrue(false, $e->getMessage()); + } + + // mock stuff: + $repository = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + $repository->shouldReceive('setUser'); + $currencyRepository->shouldReceive('setUser'); + + $repository->shouldReceive('getNoteText')->atLeast()->once()->andReturn('Note'); + $repository->shouldReceive('getMetaField')->atLeast()->once()->andReturn(null); + $repository->shouldReceive('getMetaDateString')->atLeast()->once()->andReturn('2018-01-01'); + + $collector->shouldReceive('setUser')->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setCurrency')->andReturnSelf(); + $collector->shouldReceive('removeFilter')->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('setRange')->andReturnSelf(); + $collector->shouldReceive('setTypes')->andReturnSelf(); + $collector->shouldReceive('getPaginatedTransactions')->andReturn($paginator); + + + // test API + $response = $this->get( + route('api.v1.currencies.transactions', [$currency->code]) . '?' . http_build_query(['start' => '2018-01-01', 'end' => '2018-01-31']) + ); + $response->assertStatus(200); + $response->assertJson(['data' => [],]); + $response->assertJson(['meta' => ['pagination' => ['total' => true, 'count' => true, 'per_page' => 5, 'current_page' => 1, 'total_pages' => true]],]); + $response->assertJson(['links' => ['self' => true, 'first' => true, 'last' => true,],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * Update currency. * diff --git a/tests/Api/V1/Controllers/ImportControllerTest.php b/tests/Api/V1/Controllers/ImportControllerTest.php new file mode 100644 index 0000000000..99141e2628 --- /dev/null +++ b/tests/Api/V1/Controllers/ImportControllerTest.php @@ -0,0 +1,115 @@ +. + */ + +declare(strict_types=1); + +namespace tests\Api\V1\Controllers; + +use FireflyIII\Helpers\Collector\TransactionCollectorInterface; +use FireflyIII\Models\ImportJob; +use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; +use Illuminate\Pagination\LengthAwarePaginator; +use Illuminate\Support\Collection; +use Laravel\Passport\Passport; +use Log; +use Tests\TestCase; + +/** + * Class ImportControllerTest + */ +class ImportControllerTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Passport::actingAs($this->user()); + Log::info(sprintf('Now in %s.', \get_class($this))); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\ImportController + */ + public function testListAll(): void + { + $repository = $this->mock(ImportJobRepositoryInterface::class); + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('get')->once()->andReturn(new Collection); + + + $response = $this->get(route('api.v1.import.list')); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\ImportController + */ + public function testShow(): void + { + /** @var ImportJob $job */ + $job = $this->user()->importJobs()->first(); + $repository = $this->mock(ImportJobRepositoryInterface::class); + $repository->shouldReceive('setUser')->once(); + + $response = $this->get(route('api.v1.import.show', [$job->key]), ['accept' => 'application/json']); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\ImportController + */ + public function testTransactions(): void + { + /** @var ImportJob $job */ + $job = $this->user()->importJobs()->first(); + $tag = $this->user()->tags()->first(); + $job->tag_id = $tag->id; + $job->save(); + $repository = $this->mock(ImportJobRepositoryInterface::class); + $repository->shouldReceive('setUser')->once(); + + // paginator: + $paginator = new LengthAwarePaginator(new Collection, 0, 50); + + $collector = $this->mock(TransactionCollectorInterface::class); + $collector->shouldReceive('setUser')->once()->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->once()->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->once()->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->once()->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->once()->andReturnSelf(); + $collector->shouldReceive('setTag')->once()->andReturnSelf(); + $collector->shouldReceive('setLimit')->once()->andReturnSelf(); + $collector->shouldReceive('setPage')->once()->andReturnSelf(); + $collector->shouldReceive('setTypes')->once()->andReturnSelf(); + $collector->shouldReceive('setRange')->once()->andReturnSelf(); + $collector->shouldReceive('getPaginatedTransactions')->once()->andReturn($paginator); + $collector->shouldReceive('removeFilter')->once()->andReturnSelf(); + + $response = $this->get( + route('api.v1.import.transactions', [$job->key]) . '?' . http_build_query(['start' => '2018-01-01', 'end' => '2018-01-31']), + ['accept' => 'application/json'] + ); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + +} \ No newline at end of file diff --git a/tests/Api/V1/Controllers/LinkTypeControllerTest.php b/tests/Api/V1/Controllers/LinkTypeControllerTest.php index f138c0c9fc..268bce73bc 100644 --- a/tests/Api/V1/Controllers/LinkTypeControllerTest.php +++ b/tests/Api/V1/Controllers/LinkTypeControllerTest.php @@ -23,9 +23,12 @@ declare(strict_types=1); namespace Tests\Api\V1\Controllers; +use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Models\LinkType; use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; use FireflyIII\Repositories\User\UserRepositoryInterface; +use Illuminate\Pagination\LengthAwarePaginator; +use Illuminate\Support\Collection; use Laravel\Passport\Passport; use Log; use Tests\TestCase; @@ -77,7 +80,6 @@ class LinkTypeControllerTest extends TestCase $response->assertStatus(204); } - /** * @covers \FireflyIII\Api\V1\Controllers\LinkTypeController */ @@ -216,6 +218,39 @@ class LinkTypeControllerTest extends TestCase $response->assertSee('You need the \"owner\"-role to do this.'); } + /** + * @covers \FireflyIII\Api\V1\Controllers\LinkTypeController + */ + public function testTransactions(): void + { + $linkType = LinkType::first(); + $paginator = new LengthAwarePaginator(new Collection, 0, 50); + // mock repositories: + $linkTypeRepos = $this->mock(LinkTypeRepositoryInterface::class); + $userRepos = $this->mock(UserRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $journalIds = $linkTypeRepos->shouldReceive('getJournalIds')->once()->andReturn([1, 2, 3]); + $collector->shouldReceive('setUser')->once()->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->once()->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->once()->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->once()->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->once()->andReturnSelf(); + $collector->shouldReceive('setJournalIds')->once()->andReturnSelf(); + $collector->shouldReceive('setRange')->once()->andReturnSelf(); + $collector->shouldReceive('setLimit')->once()->andReturnSelf(); + $collector->shouldReceive('setPage')->once()->andReturnSelf(); + $collector->shouldReceive('setTypes')->once()->andReturnSelf(); + $collector->shouldReceive('getPaginatedTransactions')->once()->andReturn($paginator); + + $collector->shouldReceive('removeFilter')->once()->andReturnSelf(); + $linkTypeRepos->shouldReceive('setUser')->once(); + + $response = $this->get( + route('api.v1.link_types.transactions', [$linkType->id]) . '?' . http_build_query(['start' => '2018-01-01', 'end' => '2018-01-31']) + ); + $response->assertStatus(200); + } + /** * @covers \FireflyIII\Api\V1\Controllers\LinkTypeController * @covers \FireflyIII\Api\V1\Requests\LinkTypeRequest diff --git a/tests/Api/V1/Controllers/PiggyBankControllerTest.php b/tests/Api/V1/Controllers/PiggyBankControllerTest.php index 74931d6000..60609c5f6d 100644 --- a/tests/Api/V1/Controllers/PiggyBankControllerTest.php +++ b/tests/Api/V1/Controllers/PiggyBankControllerTest.php @@ -28,6 +28,7 @@ use FireflyIII\Models\TransactionCurrency; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; +use Illuminate\Support\Collection; use Laravel\Passport\Passport; use Log; use Mockery; @@ -103,6 +104,21 @@ class PiggyBankControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * @covers \FireflyIII\Api\V1\Controllers\PiggyBankController + */ + public function testPiggyBankEvents(): void + { + $piggyBank = $this->user()->piggyBanks()->first(); + $repository = $this->mock(PiggyBankRepositoryInterface::class); + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('getEvents')->once()->andReturn(new Collection); + + $response = $this->get(route('api.v1.piggy_banks.events', [$piggyBank->id])); + $response->assertStatus(200); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** * @covers \FireflyIII\Api\V1\Controllers\PiggyBankController */ diff --git a/tests/Api/V1/Controllers/RecurrenceControllerTest.php b/tests/Api/V1/Controllers/RecurrenceControllerTest.php index d9fa24a92b..427aa2508b 100644 --- a/tests/Api/V1/Controllers/RecurrenceControllerTest.php +++ b/tests/Api/V1/Controllers/RecurrenceControllerTest.php @@ -24,13 +24,18 @@ declare(strict_types=1); namespace Tests\Api\V1\Controllers; use Carbon\Carbon; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\CategoryFactory; +use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Models\AccountType; use FireflyIII\Models\Recurrence; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; +use FireflyIII\Repositories\User\UserRepositoryInterface; +use FireflyIII\Support\Cronjobs\RecurringCronjob; +use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Collection; use Laravel\Passport\Passport; use Log; @@ -89,10 +94,10 @@ class RecurrenceControllerTest extends TestCase $piggyRepos = $this->mock(PiggyBankRepositoryInterface::class); $budgetRepos->shouldReceive('findNull')->atLeast()->once()->withAnyArgs() - ->andReturn($this->user()->budgets()->first()); + ->andReturn($this->user()->budgets()->first()); $piggyRepos->shouldReceive('findNull')->atLeast()->once()->withAnyArgs() - ->andReturn($this->user()->piggyBanks()->first()); + ->andReturn($this->user()->piggyBanks()->first()); // mock calls: $repository->shouldReceive('setUser'); @@ -1672,6 +1677,79 @@ class RecurrenceControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * @covers \FireflyIII\Api\V1\Controllers\RecurrenceController + */ + public function testTransactions(): void + { + $recurrence = $this->user()->recurrences()->first(); + $paginator = new LengthAwarePaginator(new Collection, 0, 50); + // mock repositories: + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $userRepos = $this->mock(UserRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + $journalIds = $recurringRepos->shouldReceive('getJournalIds')->once()->andReturn([1, 2, 3]); + $collector->shouldReceive('setUser')->once()->andReturnSelf(); + $collector->shouldReceive('withOpposingAccount')->once()->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->once()->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->once()->andReturnSelf(); + $collector->shouldReceive('setAllAssetAccounts')->once()->andReturnSelf(); + $collector->shouldReceive('setJournalIds')->once()->andReturnSelf(); + $collector->shouldReceive('setRange')->once()->andReturnSelf(); + $collector->shouldReceive('setLimit')->once()->andReturnSelf(); + $collector->shouldReceive('setPage')->once()->andReturnSelf(); + $collector->shouldReceive('setTypes')->once()->andReturnSelf(); + $collector->shouldReceive('getPaginatedTransactions')->once()->andReturn($paginator); + + $collector->shouldReceive('removeFilter')->once()->andReturnSelf(); + $recurringRepos->shouldReceive('setUser')->once(); + + $response = $this->get( + route('api.v1.recurrences.transactions', [$recurrence->id]) . '?' . http_build_query(['start' => '2018-01-01', 'end' => '2018-01-31']) + ); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RecurrenceController + */ + public function testTriggerError(): void + { + $cronjob = $this->mock(RecurringCronjob::class); + $cronjob->shouldReceive('fire')->andThrow(FireflyException::class); + + + $response = $this->post(route('api.v1.recurrences.trigger')); + $response->assertStatus(500); + $response->assertSee('Could not fire recurring cron job.'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RecurrenceController + */ + public function testTriggerFalse(): void + { + $cronjob = $this->mock(RecurringCronjob::class); + $cronjob->shouldReceive('fire')->once()->andReturnFalse(); + + + $response = $this->post(route('api.v1.recurrences.trigger')); + $response->assertStatus(204); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RecurrenceController + */ + public function testTriggerTrue(): void + { + $cronjob = $this->mock(RecurringCronjob::class); + $cronjob->shouldReceive('fire')->once()->andReturnTrue(); + + + $response = $this->post(route('api.v1.recurrences.trigger')); + $response->assertStatus(200); + } + /** * Just a basic test because the store() tests cover everything. * diff --git a/tests/Api/V1/Controllers/RuleControllerTest.php b/tests/Api/V1/Controllers/RuleControllerTest.php index 69112301ca..2b899abc0d 100644 --- a/tests/Api/V1/Controllers/RuleControllerTest.php +++ b/tests/Api/V1/Controllers/RuleControllerTest.php @@ -24,10 +24,17 @@ declare(strict_types=1); namespace Tests\Api\V1\Controllers; +use FireflyIII\Jobs\ExecuteRuleOnExistingTransactions; +use FireflyIII\Jobs\Job; use FireflyIII\Models\Rule; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Rule\RuleRepositoryInterface; +use FireflyIII\TransactionRules\TransactionMatcher; +use Illuminate\Support\Collection; use Laravel\Passport\Passport; use Log; +use Queue; use Tests\TestCase; /** @@ -208,6 +215,67 @@ class RuleControllerTest extends TestCase } + /** + * + */ + public function testTestRule(): void + { + $rule = $this->user()->rules()->first(); + $repository = $this->mock(AccountRepositoryInterface::class); + $matcher = $this->mock(TransactionMatcher::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $asset = $this->getRandomAsset(); + $repository->shouldReceive('setUser')->once(); + + $repository->shouldReceive('findNull')->withArgs([1])->andReturn($asset); + $repository->shouldReceive('findNull')->withArgs([2])->andReturn($asset); + $repository->shouldReceive('findNull')->withArgs([3])->andReturn(null); + $repository->shouldReceive('isAsset')->withArgs([1])->andReturn(true); + $repository->shouldReceive('isAsset')->withArgs([2])->andReturn(false); + + $matcher->shouldReceive('setRule')->once(); + $matcher->shouldReceive('setEndDate')->once(); + $matcher->shouldReceive('setStartDate')->once(); + $matcher->shouldReceive('setSearchLimit')->once(); + $matcher->shouldReceive('setTriggeredLimit')->once(); + $matcher->shouldReceive('setAccounts')->once(); + $matcher->shouldReceive('findTransactionsByRule')->once()->andReturn(new Collection); + + + $response = $this->get(route('api.v1.rules.test', [$rule->id]) . '?accounts=1,2,3'); + $response->assertStatus(200); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleController + */ + public function testTriggerRule(): void + { + + $rule = $this->user()->rules()->first(); + $repository = $this->mock(AccountRepositoryInterface::class); + $matcher = $this->mock(TransactionMatcher::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $asset = $this->getRandomAsset(); + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('findNull')->withArgs([1])->andReturn($asset); + $repository->shouldReceive('findNull')->withArgs([2])->andReturn($asset); + $repository->shouldReceive('findNull')->withArgs([3])->andReturn(null); + $repository->shouldReceive('isAsset')->andReturn(true, false); + + Queue::fake(); + + + $response = $this->post(route('api.v1.rules.trigger', [$rule->id]) . '?accounts=1,2,3'); + $response->assertStatus(204); + + Queue::assertPushed( + ExecuteRuleOnExistingTransactions::class, function (Job $job) use ($rule) { + return $job->getRule()->id === $rule->id; + } + ); + } + /** * @covers \FireflyIII\Api\V1\Controllers\RuleController * @covers \FireflyIII\Api\V1\Requests\RuleRequest diff --git a/tests/Api/V1/Controllers/TransactionControllerTest.php b/tests/Api/V1/Controllers/TransactionControllerTest.php index 0d4911d131..d36f3a637b 100644 --- a/tests/Api/V1/Controllers/TransactionControllerTest.php +++ b/tests/Api/V1/Controllers/TransactionControllerTest.php @@ -2669,7 +2669,7 @@ class TransactionControllerTest extends TestCase $accountRepos->shouldReceive('setUser'); $accountRepos->shouldReceive('getAccountsById')->withArgs([[$account->id]])->andReturn(new Collection([$account])); - $data = [ + $data = [ 'description' => 'Some deposit #' . random_int(1, 10000), 'date' => '2018-01-01', 'transactions' => [