From 13f72c73fbf79c3d7e81dd974ed4a61be1bbb05e Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 31 Aug 2018 21:12:53 +0200 Subject: [PATCH] Expand test coverage. --- .../Controllers/Import/IndexController.php | 24 +- .../Import/JobConfigurationController.php | 6 +- app/Http/Controllers/Json/BoxController.php | 28 -- .../Controllers/Json/FrontpageController.php | 2 + .../Controllers/Json/ReconcileController.php | 6 +- .../Controllers/Json/RecurrenceController.php | 4 +- .../ImportJob/ImportJobRepository.php | 12 - .../ImportJobRepositoryInterface.php | 7 - .../Chart/ReportControllerTest.php | 19 +- .../Import/IndexControllerTest.php | 36 ++ .../Import/JobConfigurationControllerTest.php | 4 +- .../Controllers/Json/BoxControllerTest.php | 31 ++ .../Json/ExchangeControllerTest.php | 19 + .../Json/RecurrenceControllerTest.php | 360 ++++++++++++++++++ .../Recurring/CreateControllerTest.php | 62 +++ .../Controllers/Rule/SelectControllerTest.php | 3 + 16 files changed, 552 insertions(+), 71 deletions(-) create mode 100644 tests/Feature/Controllers/Json/RecurrenceControllerTest.php create mode 100644 tests/Feature/Controllers/Recurring/CreateControllerTest.php diff --git a/app/Http/Controllers/Import/IndexController.php b/app/Http/Controllers/Import/IndexController.php index b24ab51fbb..fd8817913b 100644 --- a/app/Http/Controllers/Import/IndexController.php +++ b/app/Http/Controllers/Import/IndexController.php @@ -76,29 +76,29 @@ class IndexController extends Controller */ public function create(string $importProvider) { - Log::debug(sprintf('Will create job for provider "%s"', $importProvider)); - $importJob = $this->repository->create($importProvider); + $hasPreReq = (bool)config(sprintf('import.has_prereq.%s', $importProvider)); $hasConfig = (bool)config(sprintf('import.has_job_config.%s', $importProvider)); $allowedForDemo = (bool)config(sprintf('import.allowed_for_demo.%s', $importProvider)); $isDemoUser = $this->userRepository->hasRole(auth()->user(), 'demo'); + Log::debug(sprintf('Will create job for provider "%s"', $importProvider)); + Log::debug(sprintf('Is demo user? %s',var_export($isDemoUser, true))); + Log::debug(sprintf('Is allowed for user? %s',var_export($allowedForDemo, true))); + Log::debug(sprintf('Has prerequisites? %s',var_export($hasPreReq, true))); + Log::debug(sprintf('Has config? %s',var_export($hasConfig, true))); + + if ($isDemoUser && !$allowedForDemo) { + Log::debug('User is demo and this provider doesnt work for demo users.'); return redirect(route('import.index')); } + $importJob = $this->repository->create($importProvider); + Log::debug(sprintf('Created job #%d for provider %s', $importJob->id, $importProvider)); - // no prerequisites and no config: - if (false === $hasPreReq && false === $hasConfig) { - Log::debug('Provider needs no configuration for job. Job is ready to start.'); - $this->repository->updateStatus($importJob, 'ready_to_run'); - Log::debug('Redirect to status-page.'); - - return redirect(route('import.job.status.index', [$importJob->key])); - } - // no prerequisites but job has config: if (false === $hasPreReq && false !== $hasConfig) { Log::debug('Provider has no prerequisites. Continue.'); @@ -130,7 +130,7 @@ class IndexController extends Controller if (false === $hasConfig) { // @codeCoverageIgnoreStart Log::debug('Provider has no configuration. Job is ready to start.'); - $this->repository->updateStatus($importJob, 'ready_to_run'); + $this->repository->setStatus($importJob, 'ready_to_run'); Log::debug('Redirect to status-page.'); return redirect(route('import.job.status.index', [$importJob->key])); diff --git a/app/Http/Controllers/Import/JobConfigurationController.php b/app/Http/Controllers/Import/JobConfigurationController.php index 7c74b03c32..0a2d9e96d5 100644 --- a/app/Http/Controllers/Import/JobConfigurationController.php +++ b/app/Http/Controllers/Import/JobConfigurationController.php @@ -88,7 +88,7 @@ class JobConfigurationController extends Controller if (!(bool)config(sprintf('import.has_job_config.%s', $importProvider))) { // @codeCoverageIgnoreStart Log::debug('Job needs no config, is ready to run!'); - $this->repository->updateStatus($importJob, 'ready_to_run'); + $this->repository->setStatus($importJob, 'ready_to_run'); return redirect(route('import.job.status.index', [$importJob->key])); // @codeCoverageIgnoreEnd @@ -97,7 +97,7 @@ class JobConfigurationController extends Controller $configurator = $this->makeConfigurator($importJob); if ($configurator->configurationComplete()) { Log::debug('Config is complete, set status to ready_to_run.'); - $this->repository->updateStatus($importJob, 'ready_to_run'); + $this->repository->setStatus($importJob, 'ready_to_run'); return redirect(route('import.job.status.index', [$importJob->key])); } @@ -137,7 +137,7 @@ class JobConfigurationController extends Controller // is the job already configured? if ($configurator->configurationComplete()) { - $this->repository->updateStatus($importJob, 'ready_to_run'); + $this->repository->setStatus($importJob, 'ready_to_run'); return redirect(route('import.job.status.index', [$importJob->key])); } diff --git a/app/Http/Controllers/Json/BoxController.php b/app/Http/Controllers/Json/BoxController.php index 82a0a8c2eb..60027f0a83 100644 --- a/app/Http/Controllers/Json/BoxController.php +++ b/app/Http/Controllers/Json/BoxController.php @@ -291,32 +291,4 @@ class BoxController extends Controller return response()->json($return); } - /** - * Get a currency or return default currency. - * - * @param Account $account - * - * @return TransactionCurrency - */ - protected function getCurrencyOrDefault(Account $account): TransactionCurrency // get a preference - { - /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class); - /** @var CurrencyRepositoryInterface $currencyRepos */ - $currencyRepos = app(CurrencyRepositoryInterface::class); - - $currency = app('amount')->getDefaultCurrency(); - $accountCurrency = null; - $currencyId = (int)$repository->getMetaValue($account, 'currency_id'); - if (0 !== $currencyId) { - $accountCurrency = $currencyRepos->findNull($currencyId); - } - if (null === $accountCurrency) { - $accountCurrency = $currency; - } - - return $accountCurrency; - } - - } diff --git a/app/Http/Controllers/Json/FrontpageController.php b/app/Http/Controllers/Json/FrontpageController.php index 7a8247b79e..1303ba1109 100644 --- a/app/Http/Controllers/Json/FrontpageController.php +++ b/app/Http/Controllers/Json/FrontpageController.php @@ -67,10 +67,12 @@ class FrontpageController extends Controller if (\count($info) > 0) { try { $html = view('json.piggy-banks', compact('info'))->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::error(sprintf('Cannot render json.piggy-banks: %s', $e->getMessage())); $html = 'Could not render view.'; } + // @codeCoverageIgnoreEnd } return response()->json(['html' => $html]); diff --git a/app/Http/Controllers/Json/ReconcileController.php b/app/Http/Controllers/Json/ReconcileController.php index 87f0f62f3b..0739102c7c 100644 --- a/app/Http/Controllers/Json/ReconcileController.php +++ b/app/Http/Controllers/Json/ReconcileController.php @@ -119,7 +119,7 @@ class ReconcileController extends Controller /** @var Transaction $transaction */ foreach ($cleared as $transaction) { if ($transaction->transactionJournal->date <= $end) { - $clearedAmount = bcadd($clearedAmount, $transaction->amount); + $clearedAmount = bcadd($clearedAmount, $transaction->amount); // @codeCoverageIgnore ++$countCleared; } } @@ -134,10 +134,12 @@ class ReconcileController extends Controller 'route', 'countCleared' ) )->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::debug(sprintf('View error: %s', $e->getMessage())); $view = 'Could not render accounts.reconcile.overview'; } + // @codeCoverageIgnoreEnd $return = [ @@ -194,10 +196,12 @@ class ReconcileController extends Controller $html = view( 'accounts.reconcile.transactions', compact('account', 'transactions', 'currency', 'start', 'end', 'selectionStart', 'selectionEnd') )->render(); + // @codeCoverageIgnoreStart } catch (Throwable $e) { Log::debug(sprintf('Could not render: %s', $e->getMessage())); $html = 'Could not render accounts.reconcile.transactions'; } + // @codeCoverageIgnoreEnd return response()->json(['html' => $html, 'startBalance' => $startBalance, 'endBalance' => $endBalance]); } diff --git a/app/Http/Controllers/Json/RecurrenceController.php b/app/Http/Controllers/Json/RecurrenceController.php index b983022876..37f2e58b81 100644 --- a/app/Http/Controllers/Json/RecurrenceController.php +++ b/app/Http/Controllers/Json/RecurrenceController.php @@ -103,10 +103,8 @@ class RecurrenceController extends Controller $repetition->repetition_skip = (int)$request->get('skip'); $repetition->weekend = (int)$request->get('weekend'); $actualEnd = clone $end; - + $occurrences = []; switch ($endsAt) { - default: - throw new FireflyException(sprintf('Cannot generate events for type that ends at "%s".', $endsAt)); case 'forever': // simply generate up until $end. No change from default behavior. $occurrences = $this->recurring->getOccurrencesInRange($repetition, $actualStart, $actualEnd); diff --git a/app/Repositories/ImportJob/ImportJobRepository.php b/app/Repositories/ImportJob/ImportJobRepository.php index 7b65e7f5cd..f325f85166 100644 --- a/app/Repositories/ImportJob/ImportJobRepository.php +++ b/app/Repositories/ImportJob/ImportJobRepository.php @@ -379,19 +379,7 @@ class ImportJobRepository implements ImportJobRepositoryInterface return new MessageBag; } - /** - * @param ImportJob $job - * @param string $status - * - * @return ImportJob - */ - public function updateStatus(ImportJob $job, string $status): ImportJob - { - $job->status = $status; - $job->save(); - return $job; - } /** * @codeCoverageIgnore diff --git a/app/Repositories/ImportJob/ImportJobRepositoryInterface.php b/app/Repositories/ImportJob/ImportJobRepositoryInterface.php index 11db5d8186..f63fd236bc 100644 --- a/app/Repositories/ImportJob/ImportJobRepositoryInterface.php +++ b/app/Repositories/ImportJob/ImportJobRepositoryInterface.php @@ -164,12 +164,5 @@ interface ImportJobRepositoryInterface */ public function storeFileUpload(ImportJob $job, string $name, UploadedFile $file): MessageBag; - /** - * @param ImportJob $job - * @param string $status - * - * @return ImportJob - */ - public function updateStatus(ImportJob $job, string $status): ImportJob; } diff --git a/tests/Feature/Controllers/Chart/ReportControllerTest.php b/tests/Feature/Controllers/Chart/ReportControllerTest.php index 6efa3044d6..31e7b92d99 100644 --- a/tests/Feature/Controllers/Chart/ReportControllerTest.php +++ b/tests/Feature/Controllers/Chart/ReportControllerTest.php @@ -23,11 +23,12 @@ declare(strict_types=1); namespace Tests\Feature\Controllers\Chart; use FireflyIII\Generator\Chart\Basic\GeneratorInterface; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountTaskerInterface; use Log; use Steam; use Tests\TestCase; - +use Mockery; /** * Class ReportControllerTest */ @@ -47,13 +48,25 @@ class ReportControllerTest extends TestCase */ public function testNetWorth(): void { - $generator = $this->mock(GeneratorInterface::class); + $generator = $this->mock(GeneratorInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + + // mock calls: + $accountRepos->shouldReceive('setUser'); + + $accountRepos->shouldReceive('getMetaValue')->times(2) + ->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1','0'); + $accountRepos->shouldReceive('getMetaValue') + ->withArgs([Mockery::any(), 'currency_id'])->andReturn(1); + $accountRepos->shouldReceive('getMetaValue') + ->withArgs([Mockery::any(), 'accountRole'])->andReturn('ccAsset'); + Steam::shouldReceive('balancesByAccounts')->andReturn(['5', '10']); $generator->shouldReceive('multiSet')->andReturn([]); $this->be($this->user()); - $response = $this->get(route('chart.report.net-worth', [1, '20120101', '20120131'])); + $response = $this->get(route('chart.report.net-worth', ['1,2', '20120101', '20120131'])); $response->assertStatus(200); } diff --git a/tests/Feature/Controllers/Import/IndexControllerTest.php b/tests/Feature/Controllers/Import/IndexControllerTest.php index 4e9a0852c1..58e936878e 100644 --- a/tests/Feature/Controllers/Import/IndexControllerTest.php +++ b/tests/Feature/Controllers/Import/IndexControllerTest.php @@ -87,6 +87,42 @@ class IndexControllerTest extends TestCase $response->assertStatus(404); } + /** + * @covers \FireflyIII\Http\Controllers\Import\IndexController + */ + public function testCreateDemoUser(): void + { + // mock stuff: + $repository = $this->mock(ImportJobRepositoryInterface::class); + $userRepository = $this->mock(UserRepositoryInterface::class); + $fakePrerequisites = $this->mock(FakePrerequisites::class); + $bunqPrerequisites = $this->mock(BunqPrerequisites::class); + $spectrePrerequisites = $this->mock(SpectrePrerequisites::class); + $ynabPrerequisites = $this->mock(YnabPrerequisites::class); + + // fake job: + $importJob = new ImportJob; + $importJob->provider = 'spectre'; + $importJob->key = 'fake_job_1'; + + // mock calls: + $ynabPrerequisites->shouldReceive('setUser')->times(2); + $fakePrerequisites->shouldReceive('setUser')->times(2); + $bunqPrerequisites->shouldReceive('setUser')->times(2); + $spectrePrerequisites->shouldReceive('setUser')->times(2); + $fakePrerequisites->shouldReceive('isComplete')->times(2)->andReturn(true); + $bunqPrerequisites->shouldReceive('isComplete')->times(2)->andReturn(true); + $spectrePrerequisites->shouldReceive('isComplete')->times(2)->andReturn(true); + $ynabPrerequisites->shouldReceive('isComplete')->times(2)->andReturn(true); + + $userRepository->shouldReceive('hasRole')->withArgs([Mockery::any(), 'demo'])->andReturn(true)->times(3); + + $this->be($this->user()); + $response = $this->get(route('import.create', ['spectre'])); + $response->assertStatus(302); + $response->assertRedirect(route('import.index')); + } + /** * @covers \FireflyIII\Http\Controllers\Import\IndexController */ diff --git a/tests/Feature/Controllers/Import/JobConfigurationControllerTest.php b/tests/Feature/Controllers/Import/JobConfigurationControllerTest.php index 0dcc0fbf89..b004e39c22 100644 --- a/tests/Feature/Controllers/Import/JobConfigurationControllerTest.php +++ b/tests/Feature/Controllers/Import/JobConfigurationControllerTest.php @@ -124,7 +124,7 @@ class JobConfigurationControllerTest extends TestCase // mock calls: $configurator->shouldReceive('setImportJob')->once(); $configurator->shouldReceive('configurationComplete')->once()->andReturn(true); - $repository->shouldReceive('updateStatus')->withArgs([Mockery::any(), 'ready_to_run']); + $repository->shouldReceive('setStatus')->withArgs([Mockery::any(), 'ready_to_run']); $this->be($this->user()); $response = $this->get(route('import.job.configuration.index', [$job->key])); @@ -216,7 +216,7 @@ class JobConfigurationControllerTest extends TestCase // mock calls: $configurator->shouldReceive('setImportJob')->once(); $configurator->shouldReceive('configurationComplete')->once()->andReturn(true); - $repository->shouldReceive('updateStatus')->withArgs([Mockery::any(), 'ready_to_run']); + $repository->shouldReceive('setStatus')->withArgs([Mockery::any(), 'ready_to_run']); // call thing. $this->be($this->user()); diff --git a/tests/Feature/Controllers/Json/BoxControllerTest.php b/tests/Feature/Controllers/Json/BoxControllerTest.php index 39396ef985..8195a55ea4 100644 --- a/tests/Feature/Controllers/Json/BoxControllerTest.php +++ b/tests/Feature/Controllers/Json/BoxControllerTest.php @@ -182,6 +182,37 @@ class BoxControllerTest extends TestCase $response->assertStatus(200); } + /** + * @covers \FireflyIII\Http\Controllers\Json\BoxController + */ + public function testNetWorthNoInclude(): void + { + $result = [ + [ + 'currency' => TransactionCurrency::find(1), + 'balance' => '3', + ], + ]; + + + $netWorthHelper = $this->mock(NetWorthInterface::class); + $netWorthHelper->shouldReceive('setUser')->once(); + $netWorthHelper->shouldReceive('getNetWorthByCurrency')->once()->andReturn($result); + + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $accountRepos->shouldReceive('getActiveAccountsByType')->andReturn(new Collection([$this->user()->accounts()->first()])); + $currencyRepos->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1)); + $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1'); + $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('ccAsset'); + $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('0'); + + + $this->be($this->user()); + $response = $this->get(route('json.box.net-worth')); + $response->assertStatus(200); + } + /** * @covers \FireflyIII\Http\Controllers\Json\BoxController */ diff --git a/tests/Feature/Controllers/Json/ExchangeControllerTest.php b/tests/Feature/Controllers/Json/ExchangeControllerTest.php index 027ad15d5b..2e083e8dc0 100644 --- a/tests/Feature/Controllers/Json/ExchangeControllerTest.php +++ b/tests/Feature/Controllers/Json/ExchangeControllerTest.php @@ -24,6 +24,7 @@ namespace Tests\Feature\Controllers\Json; use FireflyIII\Models\CurrencyExchangeRate; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use FireflyIII\Services\Currency\ExchangeRateInterface; use Log; use Tests\TestCase; @@ -60,6 +61,24 @@ class ExchangeControllerTest extends TestCase $response->assertStatus(200); } + /** + * @covers \FireflyIII\Http\Controllers\Json\ExchangeController + */ + public function testGetRateNull(): void + { + $repository = $this->mock(CurrencyRepositoryInterface::class); + + $rate = factory(CurrencyExchangeRate::class)->make(); + $repository->shouldReceive('getExchangeRate')->andReturnNull(); + $interface = $this->mock(ExchangeRateInterface::class); + $interface->shouldReceive('setUser')->once(); + $interface->shouldReceive('getRate')->andReturn($rate); + + $this->be($this->user()); + $response = $this->get(route('json.rate', ['EUR', 'USD', '20170101'])); + $response->assertStatus(200); + } + /** * @covers \FireflyIII\Http\Controllers\Json\ExchangeController */ diff --git a/tests/Feature/Controllers/Json/RecurrenceControllerTest.php b/tests/Feature/Controllers/Json/RecurrenceControllerTest.php new file mode 100644 index 0000000000..653e7b5486 --- /dev/null +++ b/tests/Feature/Controllers/Json/RecurrenceControllerTest.php @@ -0,0 +1,360 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Json; + + +use Carbon\Carbon; +use FireflyIII\Models\RecurrenceRepetition; +use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; +use Log; +use Tests\TestCase; + +/** + * + * Class RecurrenceControllerTest + */ +class RecurrenceControllerTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Log::debug(sprintf('Now in %s.', \get_class($this))); + } + + /** + * Ndom test + * + * @covers \FireflyIII\Http\Controllers\Json\RecurrenceController + */ + public function testEventsNdom(): void + { + $repository = $this->mock(RecurringRepositoryInterface::class); + + // collection of dates: + $dates = [new Carbon('2018-01-01'), new Carbon('2018-01-07')]; + $repository->shouldReceive('getOccurrencesInRange')->withAnyArgs()->once() + ->andReturn($dates); + + $parameters = [ + 'start' => '2018-01-01', + 'end' => '2018-01-31', + 'first_date' => '2018-01-01', + 'ends' => 'forever', + 'type' => 'ndom,1,1', // weekly on Monday + 'reps' => 0, + 'weekend' => RecurrenceRepetition::WEEKEND_DO_NOTHING, + 'skip' => 0, + ]; + $this->be($this->user()); + $response = $this->get(route('recurring.events') . '?' . http_build_query($parameters)); + $response->assertStatus(200); + + // expected data: + $expected = [ + [ + 'id' => 'ndom20180101', + 'title' => 'X', + 'allDay' => true, + 'start' => '2018-01-01', + 'end' => '2018-01-01', + 'editable' => false, + 'rendering' => 'background', + ], + [ + 'id' => 'ndom20180101', + 'title' => 'X', + 'allDay' => true, + 'start' => '2018-01-07', + 'end' => '2018-01-07', + 'editable' => false, + 'rendering' => 'background', + ], + ]; + + $response->assertExactJson($expected); + } + + /** + * yearly, until date + * + * @covers \FireflyIII\Http\Controllers\Json\RecurrenceController + */ + public function testEventsNumberOfEvents(): void + { + $repository = $this->mock(RecurringRepositoryInterface::class); + + // collection of dates: + $dates = [new Carbon('2018-01-01'), new Carbon('2018-01-07')]; + $repository->shouldReceive('getXOccurrences')->withAnyArgs()->once() + ->andReturn($dates); + + $parameters = [ + 'start' => '2018-01-01', + 'end' => '2018-01-31', + 'first_date' => '2018-01-01', + 'ends' => 'times', + 'type' => 'yearly,1,1', // weekly on Monday + 'reps' => 0, + 'weekend' => RecurrenceRepetition::WEEKEND_DO_NOTHING, + 'skip' => 0, + ]; + $this->be($this->user()); + $response = $this->get(route('recurring.events') . '?' . http_build_query($parameters)); + $response->assertStatus(200); + + // expected data: + $expected = [ + [ + 'id' => 'yearly20180101', + 'title' => 'X', + 'allDay' => true, + 'start' => '2018-01-01', + 'end' => '2018-01-01', + 'editable' => false, + 'rendering' => 'background', + ], + [ + 'id' => 'yearly20180101', + 'title' => 'X', + 'allDay' => true, + 'start' => '2018-01-07', + 'end' => '2018-01-07', + 'editable' => false, + 'rendering' => 'background', + ], + ]; + + $response->assertExactJson($expected); + } + + /** + * First date is after range, so nothing happens. + * + * @covers \FireflyIII\Http\Controllers\Json\RecurrenceController + */ + public function testEventsStartAfterEnd(): void + { + $parameters = [ + 'start' => '2018-01-01', + 'end' => '2018-01-31', + 'first_date' => '2018-02-01', + 'ends' => '', + 'type' => 'daily,', + 'reps' => 1, + ]; + $this->be($this->user()); + $response = $this->get(route('recurring.events') . '?' . http_build_query($parameters)); + $response->assertStatus(200); + $response->assertExactJson([]); + } + + /** + * yearly, until date + * + * @covers \FireflyIII\Http\Controllers\Json\RecurrenceController + */ + public function testEventsUntilDate(): void + { + $repository = $this->mock(RecurringRepositoryInterface::class); + + // collection of dates: + $dates = [new Carbon('2018-01-01'), new Carbon('2018-01-07')]; + $repository->shouldReceive('getOccurrencesInRange')->withAnyArgs()->once() + ->andReturn($dates); + + $parameters = [ + 'start' => '2018-01-01', + 'end' => '2018-01-31', + 'first_date' => '2018-01-01', + 'ends' => 'until_date', + 'type' => 'yearly,1,1', // weekly on Monday + 'reps' => 0, + 'weekend' => RecurrenceRepetition::WEEKEND_DO_NOTHING, + 'skip' => 0, + ]; + $this->be($this->user()); + $response = $this->get(route('recurring.events') . '?' . http_build_query($parameters)); + $response->assertStatus(200); + + // expected data: + $expected = [ + [ + 'id' => 'yearly20180101', + 'title' => 'X', + 'allDay' => true, + 'start' => '2018-01-01', + 'end' => '2018-01-01', + 'editable' => false, + 'rendering' => 'background', + ], + [ + 'id' => 'yearly20180101', + 'title' => 'X', + 'allDay' => true, + 'start' => '2018-01-07', + 'end' => '2018-01-07', + 'editable' => false, + 'rendering' => 'background', + ], + ]; + + $response->assertExactJson($expected); + } + + /** + * Every week on Monday. + * + * @covers \FireflyIII\Http\Controllers\Json\RecurrenceController + */ + public function testEventsWeeklyMonday(): void + { + $repository = $this->mock(RecurringRepositoryInterface::class); + + // collection of dates: + $dates = [new Carbon('2018-01-01'), new Carbon('2018-01-07')]; + $repository->shouldReceive('getOccurrencesInRange')->withAnyArgs()->once() + ->andReturn($dates); + + $parameters = [ + 'start' => '2018-01-01', + 'end' => '2018-01-31', + 'first_date' => '2018-01-01', + 'ends' => 'forever', + 'type' => 'weekly,1', // weekly on Monday + 'reps' => 0, + 'weekend' => RecurrenceRepetition::WEEKEND_DO_NOTHING, + 'skip' => 0, + ]; + $this->be($this->user()); + $response = $this->get(route('recurring.events') . '?' . http_build_query($parameters)); + $response->assertStatus(200); + + // expected data: + $expected = [ + [ + 'id' => 'weekly20180101', + 'title' => 'X', + 'allDay' => true, + 'start' => '2018-01-01', + 'end' => '2018-01-01', + 'editable' => false, + 'rendering' => 'background', + ], + [ + 'id' => 'weekly20180101', + 'title' => 'X', + 'allDay' => true, + 'start' => '2018-01-07', + 'end' => '2018-01-07', + 'editable' => false, + 'rendering' => 'background', + ], + ]; + + $response->assertExactJson($expected); + } + + /** + * yearly + * + * @covers \FireflyIII\Http\Controllers\Json\RecurrenceController + */ + public function testEventsYearly(): void + { + $repository = $this->mock(RecurringRepositoryInterface::class); + + // collection of dates: + $dates = [new Carbon('2018-01-01'), new Carbon('2018-01-07')]; + $repository->shouldReceive('getOccurrencesInRange')->withAnyArgs()->once() + ->andReturn($dates); + + $parameters = [ + 'start' => '2018-01-01', + 'end' => '2018-01-31', + 'first_date' => '2018-01-01', + 'ends' => 'forever', + 'type' => 'yearly,1,1', // weekly on Monday + 'reps' => 0, + 'weekend' => RecurrenceRepetition::WEEKEND_DO_NOTHING, + 'skip' => 0, + ]; + $this->be($this->user()); + $response = $this->get(route('recurring.events') . '?' . http_build_query($parameters)); + $response->assertStatus(200); + + // expected data: + $expected = [ + [ + 'id' => 'yearly20180101', + 'title' => 'X', + 'allDay' => true, + 'start' => '2018-01-01', + 'end' => '2018-01-01', + 'editable' => false, + 'rendering' => 'background', + ], + [ + 'id' => 'yearly20180101', + 'title' => 'X', + 'allDay' => true, + 'start' => '2018-01-07', + 'end' => '2018-01-07', + 'editable' => false, + 'rendering' => 'background', + ], + ]; + + $response->assertExactJson($expected); + } + + /** + * @covers \FireflyIII\Http\Controllers\Json\RecurrenceController + */ + public function testSuggest(): void + { + $this->be($this->user()); + + $parameters = [ + 'past' => 'true', + 'pre_select' => 'daily', + 'date' => '2018-01-01', + ]; + + $response = $this->get(route('recurring.suggest') . '?' . http_build_query($parameters)); + $response->assertStatus(200); + + $expected = [ + 'daily' => ['label' => 'Every day', 'selected' => true], + 'monthly,1' => ['label' => 'Every month on the 1(st/nd/rd/th) day', 'selected' => false], + 'ndom,1,1' => ['label' => 'Every month on the 1(st/nd/rd/th) Monday', 'selected' => false], + 'weekly,1' => ['label' => 'Every week on Monday', 'selected' => false], + 'yearly,2018-01-01' => ['label' => 'Every year on January 1', 'selected' => false], + ]; + + $response->assertExactJson($expected); + } +} \ No newline at end of file diff --git a/tests/Feature/Controllers/Recurring/CreateControllerTest.php b/tests/Feature/Controllers/Recurring/CreateControllerTest.php new file mode 100644 index 0000000000..d91be2f808 --- /dev/null +++ b/tests/Feature/Controllers/Recurring/CreateControllerTest.php @@ -0,0 +1,62 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Feature\Controllers\Recurring; + + +use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; +use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; +use Illuminate\Support\Collection; +use Log; +use Tests\TestCase; + +/** + * + * Class CreateControllerTest + */ +class CreateControllerTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Log::debug(sprintf('Now in %s.', \get_class($this))); + } + + public function testCreate() { + $recurringRepos =$this->mock(RecurringRepositoryInterface::class); + $budgetRepos = $this->mock(BudgetRepositoryInterface::class); + + $budgetRepos->shouldReceive('getActiveBudgets')->andReturn(new Collection)->once(); + \Amount::shouldReceive('getDefaultCurrency')->andReturn(TransactionCurrency::find(1)); + + + $this->be($this->user()); + $response = $this->get(route('recurring.create')); + $response->assertStatus(200); + $response->assertSee('