From b195a6149853c0d13da01d971b1ab65dc9306c4d Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 21 May 2018 19:17:33 +0200 Subject: [PATCH] Improve coverage for Spectre. --- .../Spectre/StageAuthenticatedHandler.php | 69 +-- .../Spectre/DoAuthenticateHandlerTest.php | 3 +- .../Spectre/StageAuthenticatedHandlerTest.php | 450 ++++++++++++++++++ 3 files changed, 462 insertions(+), 60 deletions(-) create mode 100644 tests/Unit/Support/Import/Routine/Spectre/StageAuthenticatedHandlerTest.php diff --git a/app/Support/Import/Routine/Spectre/StageAuthenticatedHandler.php b/app/Support/Import/Routine/Spectre/StageAuthenticatedHandler.php index 611ce33f8e..3daea6cf72 100644 --- a/app/Support/Import/Routine/Spectre/StageAuthenticatedHandler.php +++ b/app/Support/Import/Routine/Spectre/StageAuthenticatedHandler.php @@ -27,12 +27,10 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\ImportJob; use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use FireflyIII\Services\Spectre\Object\Account; -use FireflyIII\Services\Spectre\Object\Customer; use FireflyIII\Services\Spectre\Object\Login; use FireflyIII\Services\Spectre\Request\ListAccountsRequest; -use FireflyIII\Services\Spectre\Request\ListCustomersRequest; use FireflyIII\Services\Spectre\Request\ListLoginsRequest; -use FireflyIII\Services\Spectre\Request\NewCustomerRequest; +use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait; use Log; /** @@ -40,6 +38,7 @@ use Log; */ class StageAuthenticatedHandler { + use GetSpectreCustomerTrait; /** @var ImportJob */ private $importJob; /** @var ImportJobRepositoryInterface */ @@ -109,7 +108,9 @@ class StageAuthenticatedHandler private function getAccounts(Login $login): array { Log::debug(sprintf('Now in StageAuthenticatedHandler::getAccounts() for login #%d', $login->getId())); - $request = new ListAccountsRequest($this->importJob->user); + /** @var ListAccountsRequest $request */ + $request = app(ListAccountsRequest::class); + $request->setUser($this->importJob->user); $request->setLogin($login); $request->call(); $accounts = $request->getAccounts(); @@ -118,67 +119,17 @@ class StageAuthenticatedHandler return $accounts; } - /** - * @return Customer - * @throws FireflyException - */ - private function getCustomer(): Customer - { - Log::debug('Now in stageNewHandler::getCustomer()'); - $customer = $this->getExistingCustomer(); - if (null === $customer) { - Log::debug('The customer is NULL, will fire a newCustomerRequest.'); - $newCustomerRequest = new NewCustomerRequest($this->importJob->user); - $customer = $newCustomerRequest->getCustomer(); - - } - Log::debug('The customer is not null.'); - - return $customer; - } - - /** - * @return Customer|null - * @throws FireflyException - */ - private function getExistingCustomer(): ?Customer - { - Log::debug('Now in ChooseLoginHandler::getExistingCustomer()'); - $preference = app('preferences')->getForUser($this->importJob->user, 'spectre_customer'); - if (null !== $preference) { - Log::debug('Customer is in user configuration'); - $customer = new Customer($preference->data); - - return $customer; - } - Log::debug('Customer is not in user config'); - $customer = null; - $getCustomerRequest = new ListCustomersRequest($this->importJob->user); - $getCustomerRequest->call(); - $customers = $getCustomerRequest->getCustomers(); - - Log::debug(sprintf('Found %d customer(s)', \count($customers))); - /** @var Customer $current */ - foreach ($customers as $current) { - if ('default_ff3_customer' === $current->getIdentifier()) { - $customer = $current; - Log::debug('Found the correct customer.'); - app('preferences')->setForUser($this->importJob->user, 'spectre_customer', $customer->toArray()); - break; - } - } - - return $customer; - } - /** * @return array * @throws FireflyException */ private function getLogins(): array { - $customer = $this->getCustomer(); - $request = new ListLoginsRequest($this->importJob->user); + $customer = $this->getCustomer($this->importJob); + + /** @var ListLoginsRequest $request */ + $request = app(ListLoginsRequest::class); + $request->setUser($this->importJob->user); $request->setCustomer($customer); $request->call(); $logins = $request->getLogins(); diff --git a/tests/Unit/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandlerTest.php b/tests/Unit/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandlerTest.php index 46fe46ae60..3a9828a336 100644 --- a/tests/Unit/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandlerTest.php +++ b/tests/Unit/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandlerTest.php @@ -43,11 +43,12 @@ class DoAuthenticateHandlerTest extends TestCase { /** * No token in config, but grab it from users preferences. - * + * @covers \FireflyIII\Support\Import\Information\GetSpectreTokenTrait * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\DoAuthenticateHandler */ public function testGetNextDataNoToken(): void { + $job = new ImportJob; $job->user_id = $this->user()->id; $job->key = 'sda-A' . random_int(1, 1000); diff --git a/tests/Unit/Support/Import/Routine/Spectre/StageAuthenticatedHandlerTest.php b/tests/Unit/Support/Import/Routine/Spectre/StageAuthenticatedHandlerTest.php new file mode 100644 index 0000000000..99bc1e4a3b --- /dev/null +++ b/tests/Unit/Support/Import/Routine/Spectre/StageAuthenticatedHandlerTest.php @@ -0,0 +1,450 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Support\Import\Routine\Spectre; + + +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Models\ImportJob; +use FireflyIII\Models\Preference; +use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; +use FireflyIII\Services\Spectre\Object\Account as SpectreAccount; +use FireflyIII\Services\Spectre\Object\Attempt; +use FireflyIII\Services\Spectre\Object\Holder; +use FireflyIII\Services\Spectre\Object\Login; +use FireflyIII\Services\Spectre\Request\ListAccountsRequest; +use FireflyIII\Services\Spectre\Request\ListLoginsRequest; +use FireflyIII\Support\Import\Routine\Spectre\StageAuthenticatedHandler; +use Mockery; +use Preferences; +use Tests\TestCase; + +/** + * Class StageAuthenticatedHandlerTest + */ +class StageAuthenticatedHandlerTest extends TestCase +{ + /** + * Already have logins in configuration. + * + * @covers \FireflyIII\Support\Import\Routine\Spectre\StageAuthenticatedHandler + */ + public function testRunBasicHaveLogins(): void + { + // fake login: + $holder = new Holder([]); + $attempt = new Attempt( + [ + 'api_mode' => 'x', + 'api_version' => 4, + 'automatic_fetch' => true, + 'categorize' => true, + 'created_at' => '2018-05-21 12:00:00', + 'consent_given_at' => '2018-05-21 12:00:00', + 'consent_types' => ['transactions'], + 'custom_fields' => [], + 'daily_refresh' => true, + 'device_type' => 'mobile', + 'user_agent' => 'Mozilla/x', + 'remote_ip' => '127.0.0.1', + 'exclude_accounts' => [], + 'fail_at' => '2018-05-21 12:00:00', + 'fail_error_class' => 'err', + 'fail_message' => 'message', + 'fetch_scopes' => [], + 'finished' => true, + 'finished_recent' => true, + 'from_date' => '2018-05-21 12:00:00', + 'id' => 1, + 'interactive' => true, + 'locale' => 'en', + 'partial' => true, + 'show_consent_confirmation' => true, + 'stages' => [], + 'store_credentials' => true, + 'success_at' => '2018-05-21 12:00:00', + 'to_date' => '2018-05-21 12:00:00', + 'updated_at' => '2018-05-21 12:00:00', + ] + ); + $login = new Login( + [ + 'consent_given_at' => '2018-05-21 12:00:00', + 'consent_types' => ['transactions'], + 'country_code' => 'NL', + 'created_at' => '2018-05-21 12:00:00', + 'updated_at' => '2018-05-21 12:00:00', + 'customer_id' => '1', + 'daily_refresh' => true, + 'holder_info' => $holder->toArray(), + 'id' => 1234, + 'last_attempt' => $attempt->toArray(), + 'last_success_at' => '2018-05-21 12:00:00', + 'next_refresh_possible_at' => '2018-05-21 12:00:00', + 'provider_code' => 'XF', + 'provider_id' => '123', + 'provider_name' => 'Fake', + 'show_consent_confirmation' => true, + 'status' => 'active', + 'store_credentials' => true, + ] + ); + + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sa_a_' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'all-logins' => [ + $login->toArray(), + ], + 'selected-login' => 1234, + ]; + $job->save(); + + // needs to be a full spectre account this time. + $spectreAccount = new SpectreAccount( + [ + 'id' => 1234, + 'login_id' => 5678, + 'currency_code' => 'EUR', + 'balance' => 1000, + 'name' => 'Fake Spectre Account', + 'nature' => 'account', + 'created_at' => '2018-01-01 12:12:12', + 'updated_at' => '2018-01-01 12:12:12', + 'extra' => [], + ] + ); + + // mock repository: + $repository = $this->mock(ImportJobRepositoryInterface::class); + $laRequest = $this->mock(ListAccountsRequest::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $laRequest->shouldReceive('setUser')->once(); + $laRequest->shouldReceive('setLogin')->withArgs([Mockery::any()])->once(); + $laRequest->shouldReceive('call')->once(); + $laRequest->shouldReceive('getAccounts')->once()->andReturn([$spectreAccount]); + + $expected = [ + 'all-logins' => [ + $login->toArray(), + ], + 'selected-login' => 1234, + 'accounts' => [ + 0 => $spectreAccount->toArray(), + ], + ]; + + $repository->shouldReceive('setConfiguration') + ->withArgs([Mockery::any(), $expected])->once(); + + $handler = new StageAuthenticatedHandler; + $handler->setImportJob($job); + try { + $handler->run(); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + } + + /** + * Already have logins in configuration, but none selected. + * + * @covers \FireflyIII\Support\Import\Routine\Spectre\StageAuthenticatedHandler + */ + public function testRunBasicHaveLoginsNull(): void + { + // fake login: + $holder = new Holder([]); + $attempt = new Attempt( + [ + 'api_mode' => 'x', + 'api_version' => 4, + 'automatic_fetch' => true, + 'categorize' => true, + 'created_at' => '2018-05-21 12:00:00', + 'consent_given_at' => '2018-05-21 12:00:00', + 'consent_types' => ['transactions'], + 'custom_fields' => [], + 'daily_refresh' => true, + 'device_type' => 'mobile', + 'user_agent' => 'Mozilla/x', + 'remote_ip' => '127.0.0.1', + 'exclude_accounts' => [], + 'fail_at' => '2018-05-21 12:00:00', + 'fail_error_class' => 'err', + 'fail_message' => 'message', + 'fetch_scopes' => [], + 'finished' => true, + 'finished_recent' => true, + 'from_date' => '2018-05-21 12:00:00', + 'id' => 1, + 'interactive' => true, + 'locale' => 'en', + 'partial' => true, + 'show_consent_confirmation' => true, + 'stages' => [], + 'store_credentials' => true, + 'success_at' => '2018-05-21 12:00:00', + 'to_date' => '2018-05-21 12:00:00', + 'updated_at' => '2018-05-21 12:00:00', + ] + ); + $login = new Login( + [ + 'consent_given_at' => '2018-05-21 12:00:00', + 'consent_types' => ['transactions'], + 'country_code' => 'NL', + 'created_at' => '2018-05-21 12:00:00', + 'updated_at' => '2018-05-21 12:00:00', + 'customer_id' => '1', + 'daily_refresh' => true, + 'holder_info' => $holder->toArray(), + 'id' => 1234, + 'last_attempt' => $attempt->toArray(), + 'last_success_at' => '2018-05-21 12:00:00', + 'next_refresh_possible_at' => '2018-05-21 12:00:00', + 'provider_code' => 'XF', + 'provider_id' => '123', + 'provider_name' => 'Fake', + 'show_consent_confirmation' => true, + 'status' => 'active', + 'store_credentials' => true, + ] + ); + + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sa_a_' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'all-logins' => [ + $login->toArray(), + ], + 'selected-login' => 0, + ]; + $job->save(); + + // needs to be a full spectre account this time. + $spectreAccount = new SpectreAccount( + [ + 'id' => 1234, + 'login_id' => 5678, + 'currency_code' => 'EUR', + 'balance' => 1000, + 'name' => 'Fake Spectre Account', + 'nature' => 'account', + 'created_at' => '2018-01-01 12:12:12', + 'updated_at' => '2018-01-01 12:12:12', + 'extra' => [], + ] + ); + + // mock repository: + $repository = $this->mock(ImportJobRepositoryInterface::class); + $laRequest = $this->mock(ListAccountsRequest::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $laRequest->shouldReceive('setUser')->once(); + $laRequest->shouldReceive('setLogin')->withArgs([Mockery::any()])->once(); + $laRequest->shouldReceive('call')->once(); + $laRequest->shouldReceive('getAccounts')->once()->andReturn([$spectreAccount]); + + $expected = [ + 'all-logins' => [ + $login->toArray(), + ], + 'selected-login' => 0, + 'accounts' => [ + 0 => $spectreAccount->toArray(), + ], + ]; + + $repository->shouldReceive('setConfiguration') + ->withArgs([Mockery::any(), $expected])->once(); + + $handler = new StageAuthenticatedHandler; + $handler->setImportJob($job); + try { + $handler->run(); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + } + + /** + * No logins in config, will grab them from Spectre. + * + * @covers \FireflyIII\Support\Import\Routine\Spectre\StageAuthenticatedHandler + */ + public function testRunBasicZeroLogins(): void + { + // fake login: + $holder = new Holder([]); + $attempt = new Attempt( + [ + 'api_mode' => 'x', + 'api_version' => 4, + 'automatic_fetch' => true, + 'categorize' => true, + 'created_at' => '2018-05-21 12:00:00', + 'consent_given_at' => '2018-05-21 12:00:00', + 'consent_types' => ['transactions'], + 'custom_fields' => [], + 'daily_refresh' => true, + 'device_type' => 'mobile', + 'user_agent' => 'Mozilla/x', + 'remote_ip' => '127.0.0.1', + 'exclude_accounts' => [], + 'fail_at' => '2018-05-21 12:00:00', + 'fail_error_class' => 'err', + 'fail_message' => 'message', + 'fetch_scopes' => [], + 'finished' => true, + 'finished_recent' => true, + 'from_date' => '2018-05-21 12:00:00', + 'id' => 1, + 'interactive' => true, + 'locale' => 'en', + 'partial' => true, + 'show_consent_confirmation' => true, + 'stages' => [], + 'store_credentials' => true, + 'success_at' => '2018-05-21 12:00:00', + 'to_date' => '2018-05-21 12:00:00', + 'updated_at' => '2018-05-21 12:00:00', + ] + ); + $login = new Login( + [ + 'consent_given_at' => '2018-05-21 12:00:00', + 'consent_types' => ['transactions'], + 'country_code' => 'NL', + 'created_at' => '2018-05-21 12:00:00', + 'updated_at' => '2018-05-21 12:00:00', + 'customer_id' => '1', + 'daily_refresh' => true, + 'holder_info' => $holder->toArray(), + 'id' => 1234, + 'last_attempt' => $attempt->toArray(), + 'last_success_at' => '2018-05-21 12:00:00', + 'next_refresh_possible_at' => '2018-05-21 12:00:00', + 'provider_code' => 'XF', + 'provider_id' => '123', + 'provider_name' => 'Fake', + 'show_consent_confirmation' => true, + 'status' => 'active', + 'store_credentials' => true, + ] + ); + + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sa_a_' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'all-logins' => [], + 'selected-login' => 0, + ]; + $job->save(); + + // needs to be a full spectre account this time. + $spectreAccount = new SpectreAccount( + [ + 'id' => 1234, + 'login_id' => 5678, + 'currency_code' => 'EUR', + 'balance' => 1000, + 'name' => 'Fake Spectre Account', + 'nature' => 'account', + 'created_at' => '2018-01-01 12:12:12', + 'updated_at' => '2018-01-01 12:12:12', + 'extra' => [], + ] + ); + // mock preference + $fakeCustomerPreference = new Preference; + $fakeCustomerPreference->name = 'spectre_customer'; + $fakeCustomerPreference->data = [ + 'id' => 1, + 'identifier' => 'fake', + 'secret' => 'Dumbledore dies', + ]; + + // mock call for preferences + Preferences::shouldReceive('getForUser')->once()->withArgs([Mockery::any(), 'spectre_customer', null])->andReturn($fakeCustomerPreference); + + // mock repository: + $repository = $this->mock(ImportJobRepositoryInterface::class); + $laRequest = $this->mock(ListAccountsRequest::class); + $llRequest = $this->mock(ListLoginsRequest::class); + + // mock calls: + $repository->shouldReceive('setUser')->once(); + $laRequest->shouldReceive('setUser')->once(); + $laRequest->shouldReceive('setLogin')->withArgs([Mockery::any()])->once(); + $laRequest->shouldReceive('call')->once(); + $laRequest->shouldReceive('getAccounts')->once()->andReturn([$spectreAccount]); + + // mock calls for list logins (return empty list for now). + $llRequest->shouldReceive('setUser')->once(); + $llRequest->shouldReceive('setCustomer')->once(); + $llRequest->shouldReceive('call')->once(); + $llRequest->shouldReceive('getLogins')->once()->andReturn([$login]); + + $expected = [ + 'all-logins' => [ + $login->toArray(), + ], + 'selected-login' => 0, + 'accounts' => [ + 0 => $spectreAccount->toArray(), + ], + ]; + + $repository->shouldReceive('setConfiguration') + ->withArgs([Mockery::any(), $expected])->once(); + + $handler = new StageAuthenticatedHandler; + $handler->setImportJob($job); + try { + $handler->run(); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + } + +} \ No newline at end of file