From d4096103cb894a3d5565c5aa4c6d6c161ae95518 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 23 Aug 2018 18:33:39 +0200 Subject: [PATCH] Improve test coverage and fix test code. --- .../Controllers/AvailableBudgetController.php | 4 +- .../V1/Controllers/PiggyBankController.php | 2 +- app/Api/V1/Controllers/RuleController.php | 2 +- .../V1/Controllers/RuleGroupController.php | 2 +- .../PiggyBank/PiggyBankRepository.php | 4 +- .../PiggyBankRepositoryInterface.php | 4 +- .../Controllers/AttachmentControllerTest.php | 1 + .../AvailableBudgetControllerTest.php | 74 ++++- .../V1/Controllers/BudgetControllerTest.php | 2 + .../Controllers/BudgetLimitControllerTest.php | 4 + .../V1/Controllers/CategoryControllerTest.php | 2 + .../Controllers/JournalLinkControllerTest.php | 251 +++++++++++++++++ .../V1/Controllers/LinkTypeControllerTest.php | 141 ++++++++++ .../Controllers/PiggyBankControllerTest.php | 255 ++++++++++++++++++ .../Controllers/PreferencesControllerTest.php | 139 ++++++++++ .../Controllers/RecurrenceControllerTest.php | 79 ++++++ .../Api/V1/Controllers/RuleControllerTest.php | 253 +++++++++++++++++ .../Controllers/RuleGroupControllerTest.php | 151 +++++++++++ .../Account/ShowControllerTest.php | 3 + tests/Unit/Factory/BillFactoryTest.php | 24 +- .../Events/VersionCheckEventHandlerTest.php | 2 +- 21 files changed, 1378 insertions(+), 21 deletions(-) create mode 100644 tests/Api/V1/Controllers/PiggyBankControllerTest.php create mode 100644 tests/Api/V1/Controllers/PreferencesControllerTest.php create mode 100644 tests/Api/V1/Controllers/RuleControllerTest.php create mode 100644 tests/Api/V1/Controllers/RuleGroupControllerTest.php diff --git a/app/Api/V1/Controllers/AvailableBudgetController.php b/app/Api/V1/Controllers/AvailableBudgetController.php index b91dae8c5f..13c56f1495 100644 --- a/app/Api/V1/Controllers/AvailableBudgetController.php +++ b/app/Api/V1/Controllers/AvailableBudgetController.php @@ -154,7 +154,7 @@ class AvailableBudgetController extends Controller $data = $request->getAll(); $currency = $this->currencyRepository->findNull($data['currency_id']); if (null === $currency) { - $this->currencyRepository->findByCodeNull($data['currency_code']); + $currency = $this->currencyRepository->findByCodeNull($data['currency_code']); } if (null === $currency) { throw new FireflyException('Could not find the indicated currency.'); @@ -169,6 +169,8 @@ class AvailableBudgetController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); } + + /** * Update the specified resource in storage. * diff --git a/app/Api/V1/Controllers/PiggyBankController.php b/app/Api/V1/Controllers/PiggyBankController.php index 4b1da3528f..8ab73dbcdc 100644 --- a/app/Api/V1/Controllers/PiggyBankController.php +++ b/app/Api/V1/Controllers/PiggyBankController.php @@ -161,7 +161,7 @@ class PiggyBankController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); } - throw new FireflyException('Could not store new piggy bank.'); // @codeCoverageIgnore + throw new FireflyException('Could not store new piggy bank.'); } diff --git a/app/Api/V1/Controllers/RuleController.php b/app/Api/V1/Controllers/RuleController.php index 42e016332a..07ff7c870c 100644 --- a/app/Api/V1/Controllers/RuleController.php +++ b/app/Api/V1/Controllers/RuleController.php @@ -101,7 +101,7 @@ class RuleController extends Controller // make paginator: $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.piggy_banks.index') . $this->buildParams()); + $paginator->setPath(route('api.v1.rules.index') . $this->buildParams()); // present to user. $manager->setSerializer(new JsonApiSerializer($baseUrl)); diff --git a/app/Api/V1/Controllers/RuleGroupController.php b/app/Api/V1/Controllers/RuleGroupController.php index 83185cec11..d0d9a8d07c 100644 --- a/app/Api/V1/Controllers/RuleGroupController.php +++ b/app/Api/V1/Controllers/RuleGroupController.php @@ -95,7 +95,7 @@ class RuleGroupController extends Controller // types to get, page size: $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; - // get list of budgets. Count it and split it. + // get list of rule groups. Count it and split it. $collection = $this->ruleGroupRepository->get(); $count = $collection->count(); $ruleGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); diff --git a/app/Repositories/PiggyBank/PiggyBankRepository.php b/app/Repositories/PiggyBank/PiggyBankRepository.php index 325146cde4..a06aabe5c6 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepository.php +++ b/app/Repositories/PiggyBank/PiggyBankRepository.php @@ -443,9 +443,9 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface /** * @param array $data * - * @return PiggyBank + * @return PiggyBank|null */ - public function store(array $data): PiggyBank + public function store(array $data): ?PiggyBank { $data['order'] = $this->getMaxOrder() + 1; /** @var PiggyBank $piggyBank */ diff --git a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php index dd606c48ba..d6af71404f 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php +++ b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php @@ -220,9 +220,9 @@ interface PiggyBankRepositoryInterface * * @param array $data * - * @return PiggyBank + * @return PiggyBank|null */ - public function store(array $data): PiggyBank; + public function store(array $data): ?PiggyBank; /** * Update existing piggy bank. diff --git a/tests/Api/V1/Controllers/AttachmentControllerTest.php b/tests/Api/V1/Controllers/AttachmentControllerTest.php index ed68ea80ca..d6273d3952 100644 --- a/tests/Api/V1/Controllers/AttachmentControllerTest.php +++ b/tests/Api/V1/Controllers/AttachmentControllerTest.php @@ -210,6 +210,7 @@ class AttachmentControllerTest extends TestCase * Store a new attachment. * * @covers \FireflyIII\Api\V1\Controllers\AttachmentController + * @covers \FireflyIII\Api\V1\Requests\AttachmentRequest */ public function testStore(): void { diff --git a/tests/Api/V1/Controllers/AvailableBudgetControllerTest.php b/tests/Api/V1/Controllers/AvailableBudgetControllerTest.php index ea52b0aef1..65bd2f7295 100644 --- a/tests/Api/V1/Controllers/AvailableBudgetControllerTest.php +++ b/tests/Api/V1/Controllers/AvailableBudgetControllerTest.php @@ -129,7 +129,7 @@ class AvailableBudgetControllerTest extends TestCase // mock calls: $repository->shouldReceive('setUser')->once(); $repository->shouldReceive('setAvailableBudget')->once()->andReturn($availableBudget); - $currencyRepository->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1)); + $currencyRepository->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::find(1)); // data to submit $data = [ @@ -148,6 +148,78 @@ class AvailableBudgetControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * Store new available budget without a valid currency. + * + * @covers \FireflyIII\Api\V1\Controllers\AvailableBudgetController + * @covers \FireflyIII\Api\V1\Requests\AvailableBudgetRequest + */ + public function testStoreNoCurrencyId(): void + { + /** @var AvailableBudget $availableBudget */ + $availableBudget = $this->user()->availableBudgets()->first(); + + // mock stuff: + $repository = $this->mock(BudgetRepositoryInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('setAvailableBudget')->once()->andReturn($availableBudget); + $currencyRepository->shouldReceive('findNull')->withArgs([1])->andReturn(null)->once(); + $currencyRepository->shouldReceive('findByCodeNull')->withArgs(['EUR'])->andReturn(TransactionCurrency::find(1))->once(); + + // data to submit + $data = [ + 'currency_id' => '1', + 'currency_code' => 'EUR', + 'amount' => '100', + 'start_date' => '2018-01-01', + 'end_date' => '2018-01-31', + ]; + + + // test API + $response = $this->post('/api/v1/available_budgets', $data); + $response->assertStatus(200); + $response->assertJson(['data' => ['type' => 'available_budgets', 'links' => true],]); + $response->assertSee($availableBudget->amount); // the amount + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + /** + * Store new available budget without a valid currency. + * + * @covers \FireflyIII\Api\V1\Controllers\AvailableBudgetController + * @covers \FireflyIII\Api\V1\Requests\AvailableBudgetRequest + */ + public function testStoreNoCurrencyAtAll(): void + { + // mock stuff: + $repository = $this->mock(BudgetRepositoryInterface::class); + $currencyRepository = $this->mock(CurrencyRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $currencyRepository->shouldReceive('findNull')->withArgs([1])->andReturn(null)->once(); + $currencyRepository->shouldReceive('findByCodeNull')->withArgs(['EUR'])->andReturn(null)->once(); + + // data to submit + $data = [ + 'currency_id' => '1', + 'currency_code' => 'EUR', + 'amount' => '100', + 'start_date' => '2018-01-01', + 'end_date' => '2018-01-31', + ]; + + + // test API + $response = $this->post('/api/v1/available_budgets', $data, ['Accept' => 'application/json']); + $response->assertStatus(500); + $response->assertSee('Could not find the indicated currency.'); // the amount + $response->assertHeader('Content-Type', 'application/json'); + } + /** * Update available budget. diff --git a/tests/Api/V1/Controllers/BudgetControllerTest.php b/tests/Api/V1/Controllers/BudgetControllerTest.php index ad5751b1cc..5c22cda9a1 100644 --- a/tests/Api/V1/Controllers/BudgetControllerTest.php +++ b/tests/Api/V1/Controllers/BudgetControllerTest.php @@ -113,6 +113,7 @@ class BudgetControllerTest extends TestCase * Store a new budget. * * @covers \FireflyIII\Api\V1\Controllers\BudgetController + * @covers \FireflyIII\Api\V1\Requests\BudgetRequest */ public function testStore(): void { @@ -144,6 +145,7 @@ class BudgetControllerTest extends TestCase * Update a budget. * * @covers \FireflyIII\Api\V1\Controllers\BudgetController + * @covers \FireflyIII\Api\V1\Requests\BudgetRequest */ public function testUpdate(): void { diff --git a/tests/Api/V1/Controllers/BudgetLimitControllerTest.php b/tests/Api/V1/Controllers/BudgetLimitControllerTest.php index d20d9296c5..3febef2744 100644 --- a/tests/Api/V1/Controllers/BudgetLimitControllerTest.php +++ b/tests/Api/V1/Controllers/BudgetLimitControllerTest.php @@ -191,6 +191,7 @@ class BudgetLimitControllerTest extends TestCase * Store new budget limit. * * @covers \FireflyIII\Api\V1\Controllers\BudgetLimitController + * @covers \FireflyIII\Api\V1\Requests\BudgetLimitRequest */ public function testStore(): void { @@ -229,6 +230,7 @@ class BudgetLimitControllerTest extends TestCase * Store new budget limit, but give error * * @covers \FireflyIII\Api\V1\Controllers\BudgetLimitController + * @covers \FireflyIII\Api\V1\Requests\BudgetLimitRequest */ public function testStoreBadBudget(): void { @@ -257,6 +259,7 @@ class BudgetLimitControllerTest extends TestCase * Test update of budget limit. * * @covers \FireflyIII\Api\V1\Controllers\BudgetLimitController + * @covers \FireflyIII\Api\V1\Requests\BudgetLimitRequest */ public function testUpdate(): void { @@ -296,6 +299,7 @@ class BudgetLimitControllerTest extends TestCase * Test update of budget limit but submit bad budget. * * @covers \FireflyIII\Api\V1\Controllers\BudgetLimitController + * @covers \FireflyIII\Api\V1\Requests\BudgetLimitRequest */ public function testUpdateBadBudget(): void { diff --git a/tests/Api/V1/Controllers/CategoryControllerTest.php b/tests/Api/V1/Controllers/CategoryControllerTest.php index 0bfb3dfe16..5e4161742b 100644 --- a/tests/Api/V1/Controllers/CategoryControllerTest.php +++ b/tests/Api/V1/Controllers/CategoryControllerTest.php @@ -115,6 +115,7 @@ class CategoryControllerTest extends TestCase * Store a new category. * * @covers \FireflyIII\Api\V1\Controllers\CategoryController + * @covers \FireflyIII\Api\V1\Requests\CategoryRequest */ public function testStore(): void { @@ -146,6 +147,7 @@ class CategoryControllerTest extends TestCase * Update a category. * * @covers \FireflyIII\Api\V1\Controllers\CategoryController + * @covers \FireflyIII\Api\V1\Requests\CategoryRequest */ public function testUpdate(): void { diff --git a/tests/Api/V1/Controllers/JournalLinkControllerTest.php b/tests/Api/V1/Controllers/JournalLinkControllerTest.php index c424ac1144..770f29d091 100644 --- a/tests/Api/V1/Controllers/JournalLinkControllerTest.php +++ b/tests/Api/V1/Controllers/JournalLinkControllerTest.php @@ -189,6 +189,207 @@ class JournalLinkControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * In this particular test the journal link request will fail. + * + * @covers \FireflyIII\Api\V1\Controllers\JournalLinkController + * @covers \FireflyIII\Api\V1\Requests\JournalLinkRequest + */ + public function testStoreExistingLink(): void + { + $journalLink = TransactionJournalLink::first(); + $journal = $this->user()->transactionJournals()->find(1); + $transaction = Transaction::first(); + $transaction->date = new Carbon; + $transaction->transaction_type_type = 'Withdrawal'; + + // mock stuff: + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $journalRepos->shouldReceive('setUser'); + $collector->shouldReceive('setUser')->withAnyArgs(); + + $collector->shouldReceive('setUser')->withAnyArgs(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setJournals')->andReturnSelf(); + $collector->shouldReceive('getTransactions')->andReturn(new Collection([$transaction])); + + $journalRepos->shouldReceive('findNull')->andReturn($journal); + $repository->shouldReceive('findLink')->once()->andReturn(true); + + + // data to submit + $data = [ + 'link_type_id' => '1', + 'inward_id' => '1', + 'outward_id' => '2', + 'notes' => 'Some notes', + ]; + + // test API + $response = $this->post('/api/v1/journal_links', $data, ['Accept' => 'application/json']); + $response->assertStatus(422); + $response->assertSee('Already have a link between inward and outward.'); + + + $response->assertHeader('Content-Type', 'application/json'); + } + + /** + * In this particular test the JournalLinkRequest will report the failure. + * + * @covers \FireflyIII\Api\V1\Controllers\JournalLinkController + * @covers \FireflyIII\Api\V1\Requests\JournalLinkRequest + */ + public function testStoreInvalidInward(): void + { + $journalLink = TransactionJournalLink::first(); + $journal = $this->user()->transactionJournals()->find(1); + $transaction = Transaction::first(); + $transaction->date = new Carbon; + $transaction->transaction_type_type = 'Withdrawal'; + + // mock stuff: + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $journalRepos->shouldReceive('setUser'); + $collector->shouldReceive('setUser')->withAnyArgs(); + + $collector->shouldReceive('setUser')->withAnyArgs(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setJournals')->andReturnSelf(); + $collector->shouldReceive('getTransactions')->andReturn(new Collection([$transaction])); + + $journalRepos->shouldReceive('findNull')->once()->withArgs([1])->andReturn(null); + $journalRepos->shouldReceive('findNull')->once()->withArgs([2])->andReturn(null); + + + // data to submit + $data = [ + 'link_type_id' => '1', + 'inward_id' => '1', + 'outward_id' => '2', + 'notes' => 'Some notes', + ]; + + // test API + $response = $this->post('/api/v1/journal_links', $data, ['Accept' => 'application/json']); + $response->assertSee('Invalid inward ID.'); // the creation moment. + $response->assertStatus(422); + $response->assertHeader('Content-Type', 'application/json'); + } + + /** + * In this particular test the JournalLinkRequest will report the failure. + * + * @covers \FireflyIII\Api\V1\Controllers\JournalLinkController + * @covers \FireflyIII\Api\V1\Requests\JournalLinkRequest + */ + public function testStoreInvalidOutward(): void + { + $journalLink = TransactionJournalLink::first(); + $journal = $this->user()->transactionJournals()->find(1); + $transaction = Transaction::first(); + $transaction->date = new Carbon; + $transaction->transaction_type_type = 'Withdrawal'; + + // mock stuff: + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $journalRepos->shouldReceive('setUser'); + $collector->shouldReceive('setUser')->withAnyArgs(); + + $collector->shouldReceive('setUser')->withAnyArgs(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setJournals')->andReturnSelf(); + $collector->shouldReceive('getTransactions')->andReturn(new Collection([$transaction])); + + $journalRepos->shouldReceive('findNull')->once()->withArgs([1])->andReturn($journal); + $journalRepos->shouldReceive('findNull')->once()->withArgs([2])->andReturn(null); + + + // data to submit + $data = [ + 'link_type_id' => '1', + 'inward_id' => '1', + 'outward_id' => '2', + 'notes' => 'Some notes', + ]; + + // test API + $response = $this->post('/api/v1/journal_links', $data, ['Accept' => 'application/json']); + $response->assertSee('Invalid outward ID.'); + $response->assertStatus(422); + $response->assertHeader('Content-Type', 'application/json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\JournalLinkController + * @covers \FireflyIII\Api\V1\Requests\JournalLinkRequest + */ + public function testStoreNoJournal(): void + { + $journalLink = TransactionJournalLink::first(); + $journal = $this->user()->transactionJournals()->find(1); + $transaction = Transaction::first(); + $transaction->date = new Carbon; + $transaction->transaction_type_type = 'Withdrawal'; + + // mock stuff: + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $journalRepos->shouldReceive('setUser'); + $collector->shouldReceive('setUser')->withAnyArgs(); + + $collector->shouldReceive('setUser')->withAnyArgs(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setJournals')->andReturnSelf(); + $collector->shouldReceive('getTransactions')->andReturn(new Collection([$transaction])); + + $journalRepos->shouldReceive('findNull')->twice()->withArgs([1])->andReturn($journal, null); + $journalRepos->shouldReceive('findNull')->twice()->withArgs([2])->andReturn($journal, null); + $repository->shouldReceive('findLink')->once()->andReturn(false); + + + // data to submit + $data = [ + 'link_type_id' => '1', + 'inward_id' => '1', + 'outward_id' => '2', + 'notes' => 'Some notes', + ]; + + // test API + $response = $this->post('/api/v1/journal_links', $data, ['Accept' => 'application/json']); + $response->assertStatus(500); + $response->assertSee('Source or destination is NULL.'); // the creation moment. + $response->assertHeader('Content-Type', 'application/json'); + } + /** * @covers \FireflyIII\Api\V1\Controllers\JournalLinkController * @covers \FireflyIII\Api\V1\Requests\JournalLinkRequest @@ -286,6 +487,56 @@ class JournalLinkControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * @covers \FireflyIII\Api\V1\Controllers\JournalLinkController + * @covers \FireflyIII\Api\V1\Requests\JournalLinkRequest + */ + public function testUpdateNoJournal(): void + { + + // mock repositories + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $collector = $this->mock(TransactionCollectorInterface::class); + + $journalLink = TransactionJournalLink::first(); + $journal = $this->user()->transactionJournals()->find(1); + $transaction = Transaction::first(); + $transaction->date = new Carbon; + $transaction->transaction_type_type = 'Withdrawal'; + + + // mock calls: + $repository->shouldReceive('setUser'); + $journalRepos->shouldReceive('setUser'); + $collector->shouldReceive('setUser')->withAnyArgs(); + + $collector->shouldReceive('setUser')->withAnyArgs(); + $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); + $collector->shouldReceive('withCategoryInformation')->andReturnSelf(); + $collector->shouldReceive('withBudgetInformation')->andReturnSelf(); + $collector->shouldReceive('setJournals')->andReturnSelf(); + $collector->shouldReceive('getTransactions')->andReturn(new Collection([$transaction])); + + $journalRepos->shouldReceive('findNull')->twice()->withArgs([1])->andReturn($journal, null); + $journalRepos->shouldReceive('findNull')->twice()->withArgs([2])->andReturn($journal, null); + $repository->shouldReceive('findLink')->once()->andReturn(false); + + // data to submit + $data = [ + 'link_type_id' => '1', + 'inward_id' => '1', + 'outward_id' => '2', + 'notes' => 'Some notes', + ]; + + // test API + $response = $this->put('/api/v1/journal_links/' . $journalLink->id, $data, ['Accept' => 'application/json']); + $response->assertStatus(500); + $response->assertSee('Source or destination is NULL.'); // the creation moment. + $response->assertHeader('Content-Type', 'application/json'); + } + /** * @covers \FireflyIII\Api\V1\Controllers\JournalLinkController * @covers \FireflyIII\Api\V1\Requests\JournalLinkRequest diff --git a/tests/Api/V1/Controllers/LinkTypeControllerTest.php b/tests/Api/V1/Controllers/LinkTypeControllerTest.php index d296d3d7ba..003ae40c98 100644 --- a/tests/Api/V1/Controllers/LinkTypeControllerTest.php +++ b/tests/Api/V1/Controllers/LinkTypeControllerTest.php @@ -77,6 +77,36 @@ class LinkTypeControllerTest extends TestCase $response->assertStatus(204); } + + /** + * @covers \FireflyIII\Api\V1\Controllers\LinkTypeController + */ + public function testDeleteNotEditable(): void + { + // mock stuff: + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $userRepository = $this->mock(UserRepositoryInterface::class); + + // create editable link type: + $linkType = LinkType::create( + [ + 'name' => 'random' . random_int(1, 100000), + 'outward' => 'outward' . random_int(1, 100000), + 'inward' => 'inward ' . random_int(1, 100000), + 'editable' => false, + + ] + ); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + + // call API + $response = $this->delete('/api/v1/link_types/' . $linkType->id); + $response->assertStatus(500); + $response->assertSee('You cannot delete this link type'); + } + /** * @covers \FireflyIII\Api\V1\Controllers\LinkTypeController */ @@ -154,6 +184,38 @@ class LinkTypeControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * @covers \FireflyIII\Api\V1\Controllers\LinkTypeController + * @covers \FireflyIII\Api\V1\Requests\LinkTypeRequest + */ + public function testStoreNotOwner(): void + { + $linkType = LinkType::first(); + + // mock stuff: + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $userRepository = $this->mock(UserRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $userRepository->shouldReceive('hasRole')->once()->andReturn(false); + + + // data to submit + $data = [ + 'name' => 'random' . random_int(1, 100000), + 'outward' => 'outward' . random_int(1, 100000), + 'inward' => 'inward ' . random_int(1, 100000), + 'editable' => true, + + ]; + + // test API + $response = $this->post('/api/v1/link_types', $data, ['Accept' => 'application/json']); + $response->assertStatus(500); + $response->assertSee('You need the \"owner\"-role to do this.'); + } + /** * @covers \FireflyIII\Api\V1\Controllers\LinkTypeController * @covers \FireflyIII\Api\V1\Requests\LinkTypeRequest @@ -196,5 +258,84 @@ class LinkTypeControllerTest extends TestCase $response->assertSee($linkType->created_at->toAtomString()); } + /** + * @covers \FireflyIII\Api\V1\Controllers\LinkTypeController + * @covers \FireflyIII\Api\V1\Requests\LinkTypeRequest + */ + public function testUpdateNotEditable(): void + { + // mock stuff: + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $userRepository = $this->mock(UserRepositoryInterface::class); + + // create editable link type: + $linkType = LinkType::create( + [ + 'name' => 'random' . random_int(1, 100000), + 'outward' => 'outward' . random_int(1, 100000), + 'inward' => 'inward ' . random_int(1, 100000), + 'editable' => false, + + ] + ); + + // mock calls: + $repository->shouldReceive('setUser'); + + // data to submit + $data = [ + 'name' => 'random' . random_int(1, 100000), + 'outward' => 'outward' . random_int(1, 100000), + 'inward' => 'inward ' . random_int(1, 100000), + 'editable' => true, + + ]; + + // test API + $response = $this->put('/api/v1/link_types/' . $linkType->id, $data, ['Accept' => 'application/json']); + $response->assertStatus(500); + $response->assertSee('You cannot edit this link type '); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\LinkTypeController + * @covers \FireflyIII\Api\V1\Requests\LinkTypeRequest + */ + public function testUpdateNotOwner(): void + { + // mock stuff: + $repository = $this->mock(LinkTypeRepositoryInterface::class); + $userRepository = $this->mock(UserRepositoryInterface::class); + $userRepository->shouldReceive('hasRole')->once()->andReturn(false); + + // create editable link type: + $linkType = LinkType::create( + [ + 'name' => 'random' . random_int(1, 100000), + 'outward' => 'outward' . random_int(1, 100000), + 'inward' => 'inward ' . random_int(1, 100000), + 'editable' => true, + + ] + ); + + // mock calls: + $repository->shouldReceive('setUser'); + + // data to submit + $data = [ + 'name' => 'random' . random_int(1, 100000), + 'outward' => 'outward' . random_int(1, 100000), + 'inward' => 'inward ' . random_int(1, 100000), + 'editable' => true, + + ]; + + // test API + $response = $this->put('/api/v1/link_types/' . $linkType->id, $data, ['Accept' => 'application/json']); + $response->assertStatus(500); + $response->assertSee('You need the \"owner\"-role to do this.'); + } + } diff --git a/tests/Api/V1/Controllers/PiggyBankControllerTest.php b/tests/Api/V1/Controllers/PiggyBankControllerTest.php new file mode 100644 index 0000000000..6b80771ee0 --- /dev/null +++ b/tests/Api/V1/Controllers/PiggyBankControllerTest.php @@ -0,0 +1,255 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Api\V1\Controllers; + +use FireflyIII\Models\PiggyBank; +use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; +use Laravel\Passport\Passport; +use Log; +use Mockery; +use Tests\TestCase; + +/** + * + * Class PiggyBankControllerTest + */ +class PiggyBankControllerTest extends TestCase +{ + /** + * Set up test + */ + public function setUp(): void + { + parent::setUp(); + Passport::actingAs($this->user()); + Log::debug(sprintf('Now in %s.', \get_class($this))); + } + + /** + * Destroy piggy bank over API + * + * @covers \FireflyIII\Api\V1\Controllers\PiggyBankController + */ + public function testDelete(): void + { // mock stuff: + $repository = $this->mock(PiggyBankRepositoryInterface::class); + // mock calls: + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('destroy')->once()->andReturn(true); + + // get piggy bank: + $piggyBank = $this->user()->piggyBanks()->first(); + + // call API + $response = $this->delete('/api/v1/piggy_banks/' . $piggyBank->id); + $response->assertStatus(204); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\PiggyBankController + */ + public function testIndex(): void + { + // create stuff + $piggies = factory(PiggyBank::class, 10)->create(); + $repository = $this->mock(PiggyBankRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $repository->shouldReceive('getPiggyBanks')->withAnyArgs()->andReturn($piggies)->once(); + $repository->shouldReceive('getCurrentAmount')->andReturn('12'); + $repository->shouldReceive('getSuggestedMonthlyAmount')->andReturn('12'); + + $accountRepos->shouldReceive('setUser'); + $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1'); + + $currencyRepos->shouldReceive('setUser'); + $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::first()); + + // test API + $response = $this->get('/api/v1/piggy_banks'); + $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\PiggyBankController + */ + public function testShow(): void + { + // create stuff + $piggy = $this->user()->piggyBanks()->first(); + + // mock stuff: + $repository = $this->mock(PiggyBankRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $currencyRepos->shouldReceive('setUser')->once(); + $accountRepos->shouldReceive('setUser')->once(); + + $repository->shouldReceive('getCurrentAmount')->andReturn('12'); + $repository->shouldReceive('getSuggestedMonthlyAmount')->andReturn('12'); + + $accountRepos->shouldReceive('setUser'); + $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1'); + + $currencyRepos->shouldReceive('setUser'); + $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::first()); + + // test API + $response = $this->get('/api/v1/piggy_banks/' . $piggy->id); + $response->assertStatus(200); + $response->assertJson(['data' => ['type' => 'piggy_banks', 'links' => true],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\PiggyBankController + * @covers \FireflyIII\Api\V1\Requests\PiggyBankRequest + */ + public function testStore(): void + { + // create stuff + $piggy = $this->user()->piggyBanks()->first(); + + // mock stuff: + $repository = $this->mock(PiggyBankRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $accountRepos->shouldReceive('setUser')->once(); + $repository->shouldReceive('store')->once()->andReturn($piggy); + + $repository->shouldReceive('getCurrentAmount')->andReturn('12')->once(); + $repository->shouldReceive('getSuggestedMonthlyAmount')->andReturn('12')->once(); + + $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->once(); + + $currencyRepos->shouldReceive('setUser')->once(); + $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::first())->once(); + + $data = [ + 'name' => 'New piggy #' . random_int(1, 100000), + 'account_id' => 1, + 'target_amount' => '100', + ]; + + // test API + $response = $this->post('/api/v1/piggy_banks/', $data, ['Accept' => 'application/json']); + $response->assertStatus(200); + $response->assertJson(['data' => ['type' => 'piggy_banks', 'links' => true],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\PiggyBankController + * @covers \FireflyIII\Api\V1\Requests\PiggyBankRequest + */ + public function testStoreNull(): void + { + // mock stuff: + $repository = $this->mock(PiggyBankRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $repository->shouldReceive('store')->once()->andReturn(null)->once(); + + + $data = [ + 'name' => 'New piggy #' . random_int(1, 100000), + 'account_id' => 1, + 'target_amount' => '100', + ]; + + // test API + $response = $this->post('/api/v1/piggy_banks/', $data, ['Accept' => 'application/json']); + $response->assertStatus(500); + $response->assertHeader('Content-Type', 'application/json'); + $response->assertSee('Could not store new piggy bank.'); + + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\PiggyBankController + * @covers \FireflyIII\Api\V1\Requests\PiggyBankRequest + */ + public function testUpdate(): void + { + // create stuff + $piggy = $this->user()->piggyBanks()->first(); + + // mock stuff: + $repository = $this->mock(PiggyBankRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + + // mock calls: + $repository->shouldReceive('setUser'); + $currencyRepos->shouldReceive('setUser')->once(); + $accountRepos->shouldReceive('setUser')->once(); + + $repository->shouldReceive('update')->once()->andReturn($piggy); + + $repository->shouldReceive('getCurrentAmount')->andReturn('12'); + $repository->shouldReceive('getSuggestedMonthlyAmount')->andReturn('12'); + + $accountRepos->shouldReceive('setUser'); + $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1'); + + $currencyRepos->shouldReceive('setUser'); + $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::first()); + + $data = [ + 'name' => 'new pigy bank ' . random_int(1, 10000), + 'account_id' => 1, + 'target_amount' => '100', + ]; + + // test API + $response = $this->put('/api/v1/piggy_banks/' . $piggy->id, $data, ['Accept' => 'application/json']); + $response->assertStatus(200); + $response->assertJson(['data' => ['type' => 'piggy_banks', 'links' => true],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + +} \ No newline at end of file diff --git a/tests/Api/V1/Controllers/PreferencesControllerTest.php b/tests/Api/V1/Controllers/PreferencesControllerTest.php new file mode 100644 index 0000000000..f2fdf4e3d1 --- /dev/null +++ b/tests/Api/V1/Controllers/PreferencesControllerTest.php @@ -0,0 +1,139 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Api\V1\Controllers; + +use FireflyIII\Models\Preference; +use Laravel\Passport\Passport; +use Log; +use Mockery; +use Preferences; +use Tests\TestCase; + +/** + * + * Class PreferencesControllerTest + */ +class PreferencesControllerTest extends TestCase +{ + + /** + * Set up test + */ + public function setUp(): void + { + parent::setUp(); + Passport::actingAs($this->user()); + Log::debug(sprintf('Now in %s.', \get_class($this))); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\PreferenceController + */ + public function testIndex(): void + { + + $available = ['language', 'customFiscalYear', 'fiscalYearStart', 'currencyPreference', 'transaction_journal_optional_fields', 'frontPageAccounts', + 'viewRange', 'listPageSize, twoFactorAuthEnabled',]; + + foreach ($available as $pref) { + Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), $pref])->once(); + } + + + // call API + $response = $this->get('/api/v1/preferences'); + $response->assertStatus(200); + } + + public function testShow(): void + { + /** @var Preference $preference */ + $preference = $this->user()->preferences()->first(); + + $response = $this->get('/api/v1/preferences/' . $preference->id); + $response->assertStatus(200); + $response->assertSee($preference->name); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\PreferenceController + * @covers \FireflyIII\Api\V1\Requests\PreferenceRequest + */ + public function testUpdateArray(): void + { + /** @var Preference $preference */ + $preference = Preferences::setForUser($this->user(), 'frontPageAccounts', [1, 2, 3]); + $data = ['data' => '4,5,6']; + $response = $this->put('/api/v1/preferences/' . $preference->id, $data, ['Accept' => 'application/json']); + $response->assertSee($preference->name); + $response->assertStatus(200); + + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\PreferenceController + * @covers \FireflyIII\Api\V1\Requests\PreferenceRequest + */ + public function testUpdateBoolean(): void + { + /** @var Preference $preference */ + $preference = Preferences::setForUser($this->user(), 'twoFactorAuthEnabled', false); + $data = ['data' => '1']; + $response = $this->put('/api/v1/preferences/' . $preference->id, $data, ['Accept' => 'application/json']); + $response->assertSee($preference->name); + $response->assertStatus(200); + + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\PreferenceController + * @covers \FireflyIII\Api\V1\Requests\PreferenceRequest + */ + public function testUpdateDefault(): void + { + /** @var Preference $preference */ + $preference = Preferences::setForUser($this->user(), 'currencyPreference', false); + $data = ['data' => 'EUR']; + $response = $this->put('/api/v1/preferences/' . $preference->id, $data, ['Accept' => 'application/json']); + $response->assertSee($preference->name); + $response->assertStatus(200); + + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\PreferenceController + * @covers \FireflyIII\Api\V1\Requests\PreferenceRequest + */ + public function testUpdateInteger(): void + { + /** @var Preference $preference */ + $preference = Preferences::setForUser($this->user(), 'listPageSize', 13); + $data = ['data' => '434']; + $response = $this->put('/api/v1/preferences/' . $preference->id, $data, ['Accept' => 'application/json']); + $response->assertSee($preference->name); + $response->assertStatus(200); + + } + +} \ No newline at end of file diff --git a/tests/Api/V1/Controllers/RecurrenceControllerTest.php b/tests/Api/V1/Controllers/RecurrenceControllerTest.php index ac41bf1309..59100edca7 100644 --- a/tests/Api/V1/Controllers/RecurrenceControllerTest.php +++ b/tests/Api/V1/Controllers/RecurrenceControllerTest.php @@ -1628,4 +1628,83 @@ class RecurrenceControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * Just a basic test because the store() tests cover everything. + * + * @covers \FireflyIII\Api\V1\Controllers\RecurrenceController + * @covers \FireflyIII\Api\V1\Requests\RecurrenceRequest + */ + public function testUpdate(): void + { + /** @var Recurrence $recurrence */ + $recurrence = $this->user()->recurrences()->first(); + + // mock stuff: + $repository = $this->mock(RecurringRepositoryInterface::class); + $factory = $this->mock(CategoryFactory::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + + $assetAccount = $this->user()->accounts()->where('account_type_id', 3)->first(); + + // mock calls: + $repository->shouldReceive('setUser'); + $factory->shouldReceive('setUser'); + $budgetRepos->shouldReceive('setUser'); + $accountRepos->shouldReceive('setUser'); + $repository->shouldReceive('update')->once()->andReturn($recurrence); + + + // used by the validator to find the source_id: + $accountRepos->shouldReceive('getAccountsById')->withArgs([[1]])->once()->andReturn(new Collection([$assetAccount])); + + + // entries used by the transformer + $repository->shouldReceive('getNoteText')->andReturn('Note text'); + $repository->shouldReceive('repetitionDescription')->andReturn('Some description.'); + $repository->shouldReceive('getXOccurrences')->andReturn([]); + + // entries used by the transformer (the fake entry has a category + a budget): + $factory->shouldReceive('findOrCreate')->andReturn(null); + $budgetRepos->shouldReceive('findNull')->andReturn(null); + + + // data to submit + $firstDate = new Carbon; + $firstDate->addDays(2); + $data = [ + 'type' => 'deposit', + 'title' => 'Hello', + 'first_date' => $firstDate->format('Y-m-d'), + 'apply_rules' => 1, + 'active' => 1, + 'transactions' => [ + [ + 'amount' => '100', + 'currency_id' => '1', + 'description' => 'Test description deposit', + 'source_name' => 'Some expense account', + 'destination_id' => '1', + ], + ], + 'repetitions' => [ + [ + 'type' => 'daily', + 'moment' => '', + 'skip' => '0', + 'weekend' => '1', + + ], + ], + ]; + + // test API + $response = $this->put('/api/v1/recurrences/' . $recurrence->id, $data, ['Accept' => 'application/json']); + $response->assertSee($recurrence->title); + $response->assertStatus(200); + + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + } diff --git a/tests/Api/V1/Controllers/RuleControllerTest.php b/tests/Api/V1/Controllers/RuleControllerTest.php new file mode 100644 index 0000000000..86f195db9d --- /dev/null +++ b/tests/Api/V1/Controllers/RuleControllerTest.php @@ -0,0 +1,253 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Api\V1\Controllers; + + +use FireflyIII\Models\Rule; +use FireflyIII\Repositories\Rule\RuleRepositoryInterface; +use Laravel\Passport\Passport; +use Log; +use Tests\TestCase; + +/** + * + * Class RuleControllerTest + */ +class RuleControllerTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Passport::actingAs($this->user()); + Log::debug(sprintf('Now in %s.', \get_class($this))); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleController + */ + public function testDelete(): void + { + /** @var Rule $rule */ + $rule = $this->user()->rules()->first(); + + // mock stuff: + $ruleRepos = $this->mock(RuleRepositoryInterface::class); + + // mock calls: + $ruleRepos->shouldReceive('setUser')->once(); + $ruleRepos->shouldReceive('destroy')->once()->andReturn(true); + + $response = $this->delete('/api/v1/rules/' . $rule->id); + $response->assertStatus(204); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleController + */ + public function testIndex(): void + { + $rules = $this->user()->rules()->get(); + + $ruleRepos = $this->mock(RuleRepositoryInterface::class); + $ruleRepos->shouldReceive('setUser')->once(); + $ruleRepos->shouldReceive('getAll')->once()->andReturn($rules); + + + // call API + $response = $this->get('/api/v1/rules'); + $response->assertStatus(200); + $response->assertSee($rules->first()->title); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleController + */ + public function testShow(): void + { + $rule = $this->user()->rules()->first(); + + $ruleRepos = $this->mock(RuleRepositoryInterface::class); + $ruleRepos->shouldReceive('setUser')->once(); + + + // call API + $response = $this->get('/api/v1/rules/' . $rule->id); + $response->assertStatus(200); + $response->assertSee($rule->title); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleController + * @covers \FireflyIII\Api\V1\Requests\RuleRequest + */ + public function testStore(): void + { + $ruleRepos = $this->mock(RuleRepositoryInterface::class); + $ruleRepos->shouldReceive('setUser')->once(); + $rule = $this->user()->rules()->first(); + $data = [ + 'title' => 'Store new rule', + 'rule_group_id' => 1, + 'trigger' => 'store-journal', + 'strict' => 1, + 'stop_processing' => 1, + 'active' => 1, + 'rule_triggers' => [ + [ + 'name' => 'description_is', + 'value' => 'Hello', + 'stop_processing' => 1, + ], + ], + 'rule_actions' => [ + [ + 'name' => 'add_tag', + 'value' => 'A', + 'stop_processing' => 1, + ], + ], + ]; + + $ruleRepos->shouldReceive('store')->once()->andReturn($rule); + + // test API + $response = $this->post('/api/v1/rules', $data, ['Accept' => 'application/json']); + $response->assertStatus(200); + + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleController + * @covers \FireflyIII\Api\V1\Requests\RuleRequest + */ + public function testUpdate(): void + { + $ruleRepos = $this->mock(RuleRepositoryInterface::class); + $ruleRepos->shouldReceive('setUser')->once(); + /** @var Rule $rule */ + $rule = $this->user()->rules()->first(); + $data = [ + 'title' => 'Store new rule', + 'rule_group_id' => 1, + 'trigger' => 'store-journal', + 'strict' => 1, + 'stop_processing' => 1, + 'active' => 1, + 'rule_triggers' => [ + [ + 'name' => 'description_is', + 'value' => 'Hello', + 'stop_processing' => 1, + ], + ], + 'rule_actions' => [ + [ + 'name' => 'add_tag', + 'value' => 'A', + 'stop_processing' => 1, + ], + ], + ]; + + $ruleRepos->shouldReceive('update')->once()->andReturn($rule); + + // test API + $response = $this->put('/api/v1/rules/' . $rule->id, $data, ['Accept' => 'application/json']); + $response->assertStatus(200); + + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleController + * @covers \FireflyIII\Api\V1\Requests\RuleRequest + */ + public function testStoreNoTriggers(): void + { + $ruleRepos = $this->mock(RuleRepositoryInterface::class); + $ruleRepos->shouldReceive('setUser')->once(); + $rule = $this->user()->rules()->first(); + $data = [ + 'title' => 'Store new rule', + 'rule_group_id' => 1, + 'trigger' => 'store-journal', + 'strict' => 1, + 'stop_processing' => 1, + 'active' => 1, + 'rule_triggers' => [ + ], + 'rule_actions' => [ + [ + 'name' => 'add_tag', + 'value' => 'A', + 'stop_processing' => 1, + ], + ], + ]; + + // test API + $response = $this->post('/api/v1/rules', $data, ['Accept' => 'application/json']); + $response->assertStatus(422); + $response->assertSee(''); + + } + + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleController + * @covers \FireflyIII\Api\V1\Requests\RuleRequest + */ + public function testStoreNoActions(): void + { + $ruleRepos = $this->mock(RuleRepositoryInterface::class); + $ruleRepos->shouldReceive('setUser')->once(); + $rule = $this->user()->rules()->first(); + $data = [ + 'title' => 'Store new rule', + 'rule_group_id' => 1, + 'trigger' => 'store-journal', + 'strict' => 1, + 'stop_processing' => 1, + 'active' => 1, + 'rule_triggers' => [ + [ + 'name' => 'description_is', + 'value' => 'Hello', + 'stop_processing' => 1, + ], + ], + 'rule_actions' => [ + ], + ]; + + // test API + $response = $this->post('/api/v1/rules', $data, ['Accept' => 'application/json']); + $response->assertStatus(422); + } + +} \ No newline at end of file diff --git a/tests/Api/V1/Controllers/RuleGroupControllerTest.php b/tests/Api/V1/Controllers/RuleGroupControllerTest.php new file mode 100644 index 0000000000..f77ea61029 --- /dev/null +++ b/tests/Api/V1/Controllers/RuleGroupControllerTest.php @@ -0,0 +1,151 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Api\V1\Controllers; + + +use FireflyIII\Models\RuleGroup; +use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; +use Laravel\Passport\Passport; +use Log; +use Tests\TestCase; + +/** + * + * Class RuleGroupControllerTest + */ +class RuleGroupControllerTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Passport::actingAs($this->user()); + Log::debug(sprintf('Now in %s.', \get_class($this))); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleGroupController + */ + public function testDelete(): void + { + /** @var RuleGroup $ruleGroup */ + $ruleGroup = $this->user()->ruleGroups()->first(); + + // mock stuff: + $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); + + // mock calls: + $ruleGroupRepos->shouldReceive('setUser')->once(); + $ruleGroupRepos->shouldReceive('destroy')->once()->andReturn(true); + + $response = $this->delete('/api/v1/rule_groups/' . $ruleGroup->id); + $response->assertStatus(204); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleGroupController + */ + public function testIndex(): void + { + $ruleGroups = $this->user()->ruleGroups()->get(); + + $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); + $ruleGroupRepos->shouldReceive('setUser')->once(); + $ruleGroupRepos->shouldReceive('get')->once()->andReturn($ruleGroups); + + + // call API + $response = $this->get('/api/v1/rule_groups'); + $response->assertStatus(200); + $response->assertSee($ruleGroups->first()->title); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleGroupController + */ + public function testShow(): void + { + /** @var RuleGroup $ruleGroup */ + $ruleGroup = $this->user()->ruleGroups()->first(); + $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); + $ruleGroupRepos->shouldReceive('setUser')->once(); + + + // call API + $response = $this->get('/api/v1/rule_groups/' . $ruleGroup->id); + $response->assertStatus(200); + $response->assertSee($ruleGroup->title); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleGroupController + * @covers \FireflyIII\Api\V1\Requests\RuleGroupRequest + */ + public function testStore(): void + { + $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); + $ruleGroupRepos->shouldReceive('setUser')->once(); + $ruleGroup = $this->user()->ruleGroups()->first(); + $data = [ + 'title' => 'Store new rule ' . random_int(1, 100000), + 'active' => 1, + 'description' => 'Hello', + ]; + + $ruleGroupRepos->shouldReceive('store')->once()->andReturn($ruleGroup); + + // test API + $response = $this->post('/api/v1/rule_groups', $data, ['Accept' => 'application/json']); + $response->assertStatus(200); + + } + + /** + * @covers \FireflyIII\Api\V1\Controllers\RuleGroupController + * @covers \FireflyIII\Api\V1\Requests\RuleGroupRequest + */ + public function testUpdate(): void + { + $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); + $ruleGroupRepos->shouldReceive('setUser')->once(); + $ruleGroup = $this->user()->ruleGroups()->first(); + $data = [ + 'title' => 'Store new rule ' . random_int(1, 100000), + 'active' => 1, + 'description' => 'Hello', + ]; + + $ruleGroupRepos->shouldReceive('update')->once()->andReturn($ruleGroup); + + // test API + $response = $this->put('/api/v1/rule_groups/' . $ruleGroup->id, $data, ['Accept' => 'application/json']); + $response->assertStatus(200); + + } + +} \ No newline at end of file diff --git a/tests/Feature/Controllers/Account/ShowControllerTest.php b/tests/Feature/Controllers/Account/ShowControllerTest.php index a6d3edf92b..5105bf4af5 100644 --- a/tests/Feature/Controllers/Account/ShowControllerTest.php +++ b/tests/Feature/Controllers/Account/ShowControllerTest.php @@ -78,6 +78,7 @@ class ShowControllerTest extends TestCase $repository = $this->mock(AccountRepositoryInterface::class); $repository->shouldReceive('oldestJournalDate')->andReturn(clone $date)->once(); $repository->shouldReceive('getMetaValue')->andReturn(''); + $repository->shouldReceive('isLiability')->andReturn(false); $transaction = factory(Transaction::class)->make(); @@ -125,6 +126,7 @@ class ShowControllerTest extends TestCase $repository = $this->mock(AccountRepositoryInterface::class); $repository->shouldReceive('oldestJournalDate')->andReturn(clone $date)->once(); $repository->shouldReceive('getMetaValue')->andReturn(''); + $repository->shouldReceive('isLiability')->andReturn(false); $transaction = factory(Transaction::class)->make(); @@ -206,6 +208,7 @@ class ShowControllerTest extends TestCase $repository = $this->mock(AccountRepositoryInterface::class); $repository->shouldReceive('oldestJournalDate')->andReturn(new Carbon); $repository->shouldReceive('getMetaValue')->andReturn(''); + $repository->shouldReceive('isLiability')->andReturn(false); $collector->shouldReceive('setTypes')->andReturnSelf(); $collector->shouldReceive('withOpposingAccount')->andReturnSelf(); diff --git a/tests/Unit/Factory/BillFactoryTest.php b/tests/Unit/Factory/BillFactoryTest.php index af07cc5dda..048cff0a37 100644 --- a/tests/Unit/Factory/BillFactoryTest.php +++ b/tests/Unit/Factory/BillFactoryTest.php @@ -42,16 +42,17 @@ class BillFactoryTest extends TestCase public function testCreateBasic(): void { $data = [ - 'name' => 'Some new bill #' . random_int(1, 10000), - 'amount_min' => '5', - 'transaction_currency_id' => 1, - 'amount_max' => '10', - 'date' => '2018-01-01', - 'repeat_freq' => 'monthly', - 'skip' => 0, - 'automatch' => true, - 'active' => true, - 'notes' => 'Hello!', + 'name' => 'Some new bill #' . random_int(1, 10000), + 'amount_min' => '5', + 'currency_id' => 1, + 'currency_code' => '', + 'amount_max' => '10', + 'date' => '2018-01-01', + 'repeat_freq' => 'monthly', + 'skip' => 0, + 'automatch' => true, + 'active' => true, + 'notes' => 'Hello!', ]; /** @var BillFactory $factory */ @@ -81,7 +82,8 @@ class BillFactoryTest extends TestCase 'amount_max' => '10', 'date' => '2018-01-01', 'repeat_freq' => 'monthly', - 'transaction_currency_id' => 1, + 'currency_id' => 1, + 'currency_code' => '', 'skip' => 0, 'automatch' => true, 'active' => true, diff --git a/tests/Unit/Handlers/Events/VersionCheckEventHandlerTest.php b/tests/Unit/Handlers/Events/VersionCheckEventHandlerTest.php index 528b5bbc2d..bb33fbab54 100644 --- a/tests/Unit/Handlers/Events/VersionCheckEventHandlerTest.php +++ b/tests/Unit/Handlers/Events/VersionCheckEventHandlerTest.php @@ -162,7 +162,7 @@ class VersionCheckEventHandlerTest extends TestCase // report on config variables: FireflyConfig::shouldReceive('get')->withArgs(['last_update_check', Mockery::any()])->once()->andReturn($checkConfig); - FireflyConfig::shouldReceive('set')->withArgs(['last_update_check', Mockery::any()])->once()->andReturn($checkConfig); + //FireflyConfig::shouldReceive('set')->withArgs(['last_update_check', Mockery::any()])->once()->andReturn($checkConfig); $handler = new VersionCheckEventHandler; $handler->checkForUpdates($event);