diff --git a/app/Support/Import/Information/GetSpectreTokenTrait.php b/app/Support/Import/Information/GetSpectreTokenTrait.php index 8db7942986..15c10202e4 100644 --- a/app/Support/Import/Information/GetSpectreTokenTrait.php +++ b/app/Support/Import/Information/GetSpectreTokenTrait.php @@ -23,8 +23,37 @@ declare(strict_types=1); namespace FireflyIII\Support\Import\Information; +use FireflyIII\Models\ImportJob; +use FireflyIII\Services\Spectre\Object\Customer; +use FireflyIII\Services\Spectre\Object\Token; +use FireflyIII\Services\Spectre\Request\CreateTokenRequest; +use Log; +/** + * Trait GetSpectreTokenTrait + * + * @package FireflyIII\Support\Import\Information + */ trait GetSpectreTokenTrait { + /** + * @param ImportJob $importJob + * @param Customer $customer + * + * @return Token + * @throws \FireflyIII\Exceptions\FireflyException + */ + protected function getToken(ImportJob $importJob, Customer $customer): Token + { + Log::debug('Now in GetSpectreTokenTrait::ChooseLoginsHandler::getToken()'); + /** @var CreateTokenRequest $request */ + $request = app(CreateTokenRequest::class); + $request->setUser($importJob->user); + $request->setUri(route('import.job.status.index', [$importJob->key])); + $request->setCustomer($customer); + $request->call(); + Log::debug('Call to get token is finished'); + return $request->getToken(); + } } \ No newline at end of file diff --git a/app/Support/Import/JobConfiguration/Spectre/AuthenticatedHandler.php b/app/Support/Import/JobConfiguration/Spectre/AuthenticatedHandler.php index b2e4cf97ef..b477232fd8 100644 --- a/app/Support/Import/JobConfiguration/Spectre/AuthenticatedHandler.php +++ b/app/Support/Import/JobConfiguration/Spectre/AuthenticatedHandler.php @@ -24,20 +24,16 @@ declare(strict_types=1); namespace FireflyIII\Support\Import\JobConfiguration\Spectre; use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use Illuminate\Support\MessageBag; use Log; /** + * @codeCoverageIgnore + * * Class AuthenticatedHandler */ class AuthenticatedHandler implements SpectreConfigurationInterface { - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - /** * Return true when this stage is complete. * @@ -59,7 +55,7 @@ class AuthenticatedHandler implements SpectreConfigurationInterface */ public function configureJob(array $data): MessageBag { - Log::debug('AuthenticatedConfigHandler::configurationComplete() always returns empty message bag'); + Log::debug('AuthenticatedConfigHandler::configureJob() always returns empty message bag'); return new MessageBag(); } @@ -95,8 +91,5 @@ class AuthenticatedHandler implements SpectreConfigurationInterface */ public function setImportJob(ImportJob $importJob): void { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); } } \ No newline at end of file diff --git a/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php b/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php index 586df3db55..a4d0b3daec 100644 --- a/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php +++ b/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php @@ -60,11 +60,12 @@ class ChooseAccountsHandler implements SpectreConfigurationInterface */ public function configurationComplete(): bool { - Log::debug('Now in ChooseAccount::configurationComplete()'); + Log::debug('Now in ChooseAccountsHandler::configurationComplete()'); $config = $this->importJob->configuration; $importAccounts = $config['account_mapping'] ?? []; $complete = \count($importAccounts) > 0 && $importAccounts !== [0 => 0]; if ($complete) { + // todo also actually validate content. Log::debug('Looks like user has mapped import accounts to Firefly III accounts', $importAccounts); $this->repository->setStage($this->importJob, 'go-for-import'); } @@ -81,14 +82,14 @@ class ChooseAccountsHandler implements SpectreConfigurationInterface */ public function configureJob(array $data): MessageBag { - Log::debug('Now in ChooseAccount::configureJob()', $data); + Log::debug('Now in ChooseAccountsHandler::configureJob()', $data); $config = $this->importJob->configuration; $mapping = $data['account_mapping'] ?? []; $final = []; - foreach ($mapping as $spectreId => $fireflyIIIId) { + foreach ($mapping as $spectreId => $localId) { // validate each $spectreId = $this->validSpectreAccount((int)$spectreId); - $accountId = $this->validFireflyIIIAccount((int)$fireflyIIIId); + $accountId = $this->validLocalAccount((int)$localId); $final[$spectreId] = $accountId; } @@ -112,11 +113,11 @@ class ChooseAccountsHandler implements SpectreConfigurationInterface */ public function getNextData(): array { - Log::debug('Now in ChooseAccount::getnextData()'); + Log::debug('Now in ChooseAccountsHandler::getnextData()'); $config = $this->importJob->configuration; $accounts = $config['accounts'] ?? []; if (\count($accounts) === 0) { - throw new FireflyException('It seems you have no accounts with this bank. The import cannot continue.'); + throw new FireflyException('It seems you have no accounts with this bank. The import cannot continue.'); // @codeCoverageIgnore } $converted = []; foreach ($accounts as $accountArray) { @@ -128,7 +129,7 @@ class ChooseAccountsHandler implements SpectreConfigurationInterface $logins = $config['all-logins'] ?? []; $selected = $config['selected-login'] ?? 0; if (\count($logins) === 0) { - throw new FireflyException('It seems you have no configured logins in this import job. The import cannot continue.'); + throw new FireflyException('It seems you have no configured logins in this import job. The import cannot continue.'); // @codeCoverageIgnore } Log::debug(sprintf('Selected login to use is %d', $selected)); if ($selected === 0) { @@ -145,7 +146,7 @@ class ChooseAccountsHandler implements SpectreConfigurationInterface } } if (null === $login) { - throw new FireflyException('Was not able to determine which login to use. The import cannot continue.'); + throw new FireflyException('Was not able to determine which login to use. The import cannot continue.'); // @codeCoverageIgnore } // list the users accounts: @@ -173,6 +174,7 @@ class ChooseAccountsHandler implements SpectreConfigurationInterface } /** + * @codeCoverageIgnore * Get the view for this stage. * * @return string @@ -183,6 +185,7 @@ class ChooseAccountsHandler implements SpectreConfigurationInterface } /** + * @codeCoverageIgnore * Set the import job. * * @param ImportJob $importJob @@ -219,7 +222,7 @@ class ChooseAccountsHandler implements SpectreConfigurationInterface * * @return int */ - private function validFireflyIIIAccount(int $accountId): int + private function validLocalAccount(int $accountId): int { $account = $this->accountRepository->findNull($accountId); if (null === $account) { diff --git a/app/Support/Import/JobConfiguration/Spectre/ChooseLoginHandler.php b/app/Support/Import/JobConfiguration/Spectre/ChooseLoginHandler.php index 89b66f3c99..1fa0547366 100644 --- a/app/Support/Import/JobConfiguration/Spectre/ChooseLoginHandler.php +++ b/app/Support/Import/JobConfiguration/Spectre/ChooseLoginHandler.php @@ -32,6 +32,8 @@ use FireflyIII\Services\Spectre\Object\Token; use FireflyIII\Services\Spectre\Request\CreateTokenRequest; use FireflyIII\Services\Spectre\Request\ListCustomersRequest; use FireflyIII\Services\Spectre\Request\NewCustomerRequest; +use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait; +use FireflyIII\Support\Import\Information\GetSpectreTokenTrait; use Illuminate\Support\MessageBag; use Log; @@ -42,6 +44,7 @@ use Log; */ class ChooseLoginHandler implements SpectreConfigurationInterface { + use GetSpectreCustomerTrait, GetSpectreTokenTrait; /** @var ImportJob */ private $importJob; /** @var ImportJobRepositoryInterface */ @@ -77,7 +80,7 @@ class ChooseLoginHandler implements SpectreConfigurationInterface public function configureJob(array $data): MessageBag { Log::debug('Now in ChooseLoginHandler::configureJob()'); - $selectedLogin = (int)$data['spectre_login_id']; + $selectedLogin = (int)($data['spectre_login_id'] ?? 0.0); $config = $this->importJob->configuration; $config['selected-login'] = $selectedLogin; $this->repository->setConfiguration($this->importJob, $config); @@ -85,10 +88,10 @@ class ChooseLoginHandler implements SpectreConfigurationInterface // if selected login is zero, create a new one. if ($selectedLogin === 0) { - Log::debug('Login is zero, get a new customer + token and store it in config.'); - $customer = $this->getCustomer(); + Log::debug('Login is zero, get Spectre customer + token and store it in config.'); + $customer = $this->getCustomer($this->importJob); // get a token for the user and redirect to next stage - $token = $this->getToken($customer); + $token = $this->getToken($this->importJob, $customer); $config['customer'] = $customer->toArray(); $config['token'] = $token->toArray(); $this->repository->setConfiguration($this->importJob, $config); @@ -123,6 +126,7 @@ class ChooseLoginHandler implements SpectreConfigurationInterface } /** + * @codeCoverageIgnore * Get the view for this stage. * * @return string @@ -143,75 +147,4 @@ class ChooseLoginHandler implements SpectreConfigurationInterface $this->repository = app(ImportJobRepositoryInterface::class); $this->repository->setUser($importJob->user); } - - /** - * @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; - } - - /** - * @param Customer $customer - * - * @throws FireflyException - * @return Token - */ - private function getToken(Customer $customer): Token - { - Log::debug('Now in ChooseLoginHandler::ChooseLoginsHandler::getToken()'); - $request = new CreateTokenRequest($this->importJob->user); - $request->setUri(route('import.job.status.index', [$this->importJob->key])); - $request->setCustomer($customer); - $request->call(); - Log::debug('Call to get token is finished'); - - return $request->getToken(); - } } \ No newline at end of file diff --git a/app/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandler.php b/app/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandler.php index 2e5395e02b..351ff99132 100644 --- a/app/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandler.php +++ b/app/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandler.php @@ -26,11 +26,9 @@ namespace FireflyIII\Support\Import\JobConfiguration\Spectre; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\ImportJob; use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Spectre\Object\Customer; use FireflyIII\Services\Spectre\Object\Token; -use FireflyIII\Services\Spectre\Request\CreateTokenRequest; -use FireflyIII\Services\Spectre\Request\ListCustomersRequest; -use FireflyIII\Services\Spectre\Request\NewCustomerRequest; +use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait; +use FireflyIII\Support\Import\Information\GetSpectreTokenTrait; use Illuminate\Support\MessageBag; use Log; @@ -40,12 +38,14 @@ use Log; */ class DoAuthenticateHandler implements SpectreConfigurationInterface { + use GetSpectreTokenTrait, GetSpectreCustomerTrait; /** @var ImportJob */ private $importJob; /** @var ImportJobRepositoryInterface */ private $repository; /** + * @codeCoverageIgnore * Return true when this stage is complete. * * always returns false. @@ -54,12 +54,13 @@ class DoAuthenticateHandler implements SpectreConfigurationInterface */ public function configurationComplete(): bool { - Log::debug('AuthenticateConfig::configurationComplete() will always return false'); + Log::debug('DoAuthenticateHandler::configurationComplete() will always return false'); return false; } /** + * @codeCoverageIgnore * Store the job configuration. * * @param array $data @@ -68,7 +69,7 @@ class DoAuthenticateHandler implements SpectreConfigurationInterface */ public function configureJob(array $data): MessageBag { - Log::debug('AuthenticateConfig::configureJob() will do nothing.'); + Log::debug('DoAuthenticateHandler::configureJob() will do nothing.'); return new MessageBag; } @@ -81,25 +82,29 @@ class DoAuthenticateHandler implements SpectreConfigurationInterface */ public function getNextData(): array { - Log::debug('Now in AuthenticateConfig::getNextData()'); - // next data only makes sure the job is ready for the next stage. + Log::debug('Now in DoAuthenticateHandler::getNextData()'); + + // getNextData() only makes sure the job is ready for the next stage. $this->repository->setStatus($this->importJob, 'ready_to_run'); $this->repository->setStage($this->importJob, 'authenticated'); + + // get token from configuration: $config = $this->importJob->configuration; $token = isset($config['token']) ? new Token($config['token']) : null; - if (null !== $token) { - Log::debug(sprintf('Return "%s" from token in config.', $token->getConnectUrl())); - return ['token-url' => $token->getConnectUrl()]; + if (null === $token) { + // get a new one from Spectre: + Log::debug('No existing token, get a new one.'); + // get a new token from Spectre. + $customer = $this->getCustomer($this->importJob); + $token = $this->getToken($this->importJob, $customer); } - Log::debug('No existing token, get a new one.'); - // get a new token from Spectre. - $customer = $this->getCustomer(); - $token = $this->getToken($customer); + return ['token-url' => $token->getConnectUrl()]; } /** + * @codeCoverageIgnore * Get the view for this stage. * * @return string @@ -110,6 +115,7 @@ class DoAuthenticateHandler implements SpectreConfigurationInterface } /** + * @codeCoverageIgnore * Set the import job. * * @param ImportJob $importJob @@ -120,75 +126,4 @@ class DoAuthenticateHandler implements SpectreConfigurationInterface $this->repository = app(ImportJobRepositoryInterface::class); $this->repository->setUser($importJob->user); } - - /** - * @return Customer - * @throws FireflyException - */ - private function getCustomer(): Customer - { - Log::debug('Now in AuthenticateConfig::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 AuthenticateConfig::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; - } - - /** - * @param Customer $customer - * - * @throws FireflyException - * @return Token - */ - private function getToken(Customer $customer): Token - { - Log::debug('Now in AuthenticateConfig::getToken()'); - $request = new CreateTokenRequest($this->importJob->user); - $request->setUri(route('import.job.status.index', [$this->importJob->key])); - $request->setCustomer($customer); - $request->call(); - Log::debug('Call to get token is finished'); - - return $request->getToken(); - } } \ No newline at end of file diff --git a/app/Support/Import/JobConfiguration/Spectre/NewSpectreJobHandler.php b/app/Support/Import/JobConfiguration/Spectre/NewSpectreJobHandler.php index b42216373f..4b135225bc 100644 --- a/app/Support/Import/JobConfiguration/Spectre/NewSpectreJobHandler.php +++ b/app/Support/Import/JobConfiguration/Spectre/NewSpectreJobHandler.php @@ -26,9 +26,12 @@ namespace FireflyIII\Support\Import\JobConfiguration\Spectre; use FireflyIII\Models\ImportJob; use Illuminate\Support\MessageBag; +use Log; /** - * Class NewConfig + * @codeCoverageIgnore + * + * Class NewSpectreJobHandler * */ class NewSpectreJobHandler implements SpectreConfigurationInterface @@ -41,6 +44,8 @@ class NewSpectreJobHandler implements SpectreConfigurationInterface */ public function configurationComplete(): bool { + Log::debug('NewSpectreJobHandler::configurationComplete() always returns true'); + return true; } @@ -53,6 +58,8 @@ class NewSpectreJobHandler implements SpectreConfigurationInterface */ public function configureJob(array $data): MessageBag { + Log::debug('NewSpectreJobHandler::configureJob() always returns an empty message bag'); + return new MessageBag; } @@ -63,6 +70,8 @@ class NewSpectreJobHandler implements SpectreConfigurationInterface */ public function getNextData(): array { + Log::debug('NewSpectreJobHandler::getNextData() always returns []'); + return []; } @@ -73,6 +82,8 @@ class NewSpectreJobHandler implements SpectreConfigurationInterface */ public function getNextView(): string { + Log::debug('NewSpectreJobHandler::getNextView() always returns ""'); + return ''; } diff --git a/app/User.php b/app/User.php index b9a4de5107..b52ef745cb 100644 --- a/app/User.php +++ b/app/User.php @@ -55,6 +55,7 @@ use FireflyIII\Models\Attachment; /** * Class User. + * @property int $id */ class User extends Authenticatable { diff --git a/tests/Unit/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandlerTest.php b/tests/Unit/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandlerTest.php new file mode 100644 index 0000000000..8c4ab5f197 --- /dev/null +++ b/tests/Unit/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandlerTest.php @@ -0,0 +1,652 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Support\Import\JobConfiguration\Spectre; + + +use Amount; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Models\AccountType; +use FireflyIII\Models\ImportJob; +use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +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\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler; +use Illuminate\Support\Collection; +use Mockery; +use Tests\TestCase; + +/** + * Class ChooseAccountsHandlerTest + */ +class ChooseAccountsHandlerTest extends TestCase +{ + /** + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler + */ + public function testCCFalse(): void + { + // fake job: + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sca-A' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'account_mapping' => [], + ]; + $job->save(); + + // mock repositories: + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $importRepos = $this->mock(ImportJobRepositoryInterface::class); + + // mock calls: + $accountRepos->shouldReceive('setUser')->once(); + $currencyRepos->shouldReceive('setUser')->once(); + $importRepos->shouldReceive('setUser')->once(); + + // call handler: + $handler = new ChooseAccountsHandler(); + $handler->setImportJob($job); + $this->assertFalse($handler->configurationComplete()); + + } + + /** + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler + */ + public function testCCTrue(): void + { + // fake job: + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sca-B' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'account_mapping' => [ + 4 => 6, + ], + ]; + $job->save(); + + // mock repositories: + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $importRepos = $this->mock(ImportJobRepositoryInterface::class); + + // mock calls: + $accountRepos->shouldReceive('setUser')->once(); + $currencyRepos->shouldReceive('setUser')->once(); + $importRepos->shouldReceive('setUser')->once(); + $importRepos->shouldReceive('setStage')->withArgs([Mockery::any(), 'go-for-import'])->once(); + + // call handler: + $handler = new ChooseAccountsHandler(); + $handler->setImportJob($job); + $this->assertTrue($handler->configurationComplete()); + } + + /** + * Case: Local account is valid. Spectre account is valid. + * + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler + */ + public function testConfigureJob(): void + { + // fake job: + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sca-c' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'accounts' => [ + 0 => [ + 'id' => 3131, + 'name' => 'Some fake account', + ], + ], + ]; + $job->save(); + + $account = $this->user()->accounts()->inRandomOrder()->first(); + + // data to submit: + $data = [ + 'account_mapping' => [3131 => 872,], + ]; + // expected configuration: + $config = [ + 'accounts' => [0 => ['id' => 3131, 'name' => 'Some fake account',],], + 'account_mapping' => [3131 => 872,], + ]; + + + // mock repositories: + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $importRepos = $this->mock(ImportJobRepositoryInterface::class); + + // mock calls: + $accountRepos->shouldReceive('setUser')->once(); + $currencyRepos->shouldReceive('setUser')->once(); + $importRepos->shouldReceive('setUser')->once(); + $accountRepos->shouldReceive('findNull')->once()->withArgs([872])->andReturn($account); + $importRepos->shouldReceive('setConfiguration')->once()->withArgs([Mockery::any(), $config]); + + + // call handler: + $handler = new ChooseAccountsHandler(); + $handler->setImportJob($job); + $this->assertCount(0, $handler->configureJob($data)); + } + + /** + * Case: Local account is invalid. Spectre account is valid. + * + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler + */ + public function testConfigureJobInvalidLocal(): void + { + // fake job: + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sca-D' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'accounts' => [ + 0 => [ + 'id' => 3131, + 'name' => 'Some fake account', + ], + ], + ]; + $job->save(); + + // data to submit: + $data = [ + 'account_mapping' => [3131 => 872,], + ]; + // expected configuration: + $config = [ + 'accounts' => [0 => ['id' => 3131, 'name' => 'Some fake account',],], + 'account_mapping' => [3131 => 0,], + ]; + + + // mock repositories: + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $importRepos = $this->mock(ImportJobRepositoryInterface::class); + + // mock calls: + $accountRepos->shouldReceive('setUser')->once(); + $currencyRepos->shouldReceive('setUser')->once(); + $importRepos->shouldReceive('setUser')->once(); + $accountRepos->shouldReceive('findNull')->once()->withArgs([872])->andReturn(null); + $importRepos->shouldReceive('setConfiguration')->once()->withArgs([Mockery::any(), $config]); + + + // call handler: + $handler = new ChooseAccountsHandler(); + $handler->setImportJob($job); + $this->assertCount(0, $handler->configureJob($data)); + } + + /** + * Case: Local account is valid. Spectre account is invalid. + * + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler + */ + public function testConfigureJobInvalidSpectre(): void + { + // fake job: + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sca-E' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'accounts' => [ + 0 => [ + 'id' => 3134, + 'name' => 'Some fake account', + ], + ], + ]; + $job->save(); + + $account = $this->user()->accounts()->inRandomOrder()->first(); + + // data to submit: + $data = [ + 'account_mapping' => [3131 => 872,], + ]; + // expected configuration: + $config = [ + 'accounts' => [0 => ['id' => 3134, 'name' => 'Some fake account',],], + 'account_mapping' => [0 => 872,], + ]; + + + // mock repositories: + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $importRepos = $this->mock(ImportJobRepositoryInterface::class); + + // mock calls: + $accountRepos->shouldReceive('setUser')->once(); + $currencyRepos->shouldReceive('setUser')->once(); + $importRepos->shouldReceive('setUser')->once(); + $accountRepos->shouldReceive('findNull')->once()->withArgs([872])->andReturn($account); + $importRepos->shouldReceive('setConfiguration')->once()->withArgs([Mockery::any(), $config]); + + + // call handler: + $handler = new ChooseAccountsHandler(); + $handler->setImportJob($job); + $this->assertCount(0, $handler->configureJob($data)); + } + + /** + * Case: Local account is invalid. Spectre account is invalid. + * + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler + */ + public function testConfigureJobInvalidBoth(): void + { + // fake job: + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sca-E' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'accounts' => [ + 0 => [ + 'id' => 3134, + 'name' => 'Some fake account', + ], + ], + ]; + $job->save(); + + // data to submit: + $data = [ + 'account_mapping' => [3131 => 872,], + ]; + // expected configuration: + $config = [ + 'accounts' => [0 => ['id' => 3134, 'name' => 'Some fake account',],], + 'account_mapping' => [0 => 0,], + ]; + + + // mock repositories: + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $importRepos = $this->mock(ImportJobRepositoryInterface::class); + + // mock calls: + $accountRepos->shouldReceive('setUser')->once(); + $currencyRepos->shouldReceive('setUser')->once(); + $importRepos->shouldReceive('setUser')->once(); + $accountRepos->shouldReceive('findNull')->once()->withArgs([872])->andReturn(null); + $importRepos->shouldReceive('setConfiguration')->once()->withArgs([Mockery::any(), $config]); + + + // call handler: + $handler = new ChooseAccountsHandler(); + $handler->setImportJob($job); + $result =$handler->configureJob($data); + $this->assertCount(1, $result); + $this->assertEquals('It seems you have not selected any accounts to import from.', $result->first()); + } + + + /** + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler + */ + public function testGetNextData(): void + { + // needs to be a full spectre account this time. + $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' => [], + ]; + + + // need to be a full spectre login this time. + $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', + ] + ); + $spectreLogin = 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, + ] + ); + + // fake job: + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sca-F' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'accounts' => [ + 0 => $spectreAccount, + ], + 'all-logins' => [ + 0 => $spectreLogin->toArray(), + ], + 'selected-login' => 1234, + ]; + $job->save(); + + // mock repositories: + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $importRepos = $this->mock(ImportJobRepositoryInterface::class); + + // mock calls: + $accountRepos->shouldReceive('setUser')->once(); + $currencyRepos->shouldReceive('setUser')->once(); + $importRepos->shouldReceive('setUser')->once(); + + $euro = TransactionCurrency::where('code', 'EUR')->first(); + $usd = TransactionCurrency::where('code', 'USD')->first(); + $first = $this->user()->accounts()->where('account_type_id', 3)->first(); + $second = $this->user()->accounts()->where('account_type_id', 3)->where('id', '!=', $first->id)->first(); + $accountRepos->shouldReceive('getAccountsByType')->withArgs([[AccountType::ASSET]]) + ->once()->andReturn(new Collection([$first, $second])); + $accountRepos->shouldReceive('getMetaValue')->twice()->withArgs([Mockery::any(), 'currency_id']) + ->andReturn(1, 2); + $currencyRepos->shouldReceive('findNull')->once()->withArgs([1])->andReturn($euro); + $currencyRepos->shouldReceive('findNull')->once()->withArgs([2])->andReturn(null); + Amount::shouldReceive('getDefaultCurrencyByUser')->withArgs([Mockery::any()])->once()->andReturn($usd); + + // call handler: + $handler = new ChooseAccountsHandler(); + $handler->setImportJob($job); + $result = []; + try { + $result = $handler->getNextData(); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + + $expected = [ + 'accounts' => [ + 0 => new SpectreAccount($spectreAccount), + ], + 'ff_accounts' => [ + $first->id => [ + 'name' => $first->name, + 'iban' => $first->iban, + 'code' => $euro->code, + ], + $second->id => [ + 'name' => $second->name, + 'iban' => $second->iban, + 'code' => $usd->code, + ], + ], + 'login' => $spectreLogin, + ]; + + $this->assertEquals($expected, $result); + } + + /** + * Select first login. + * + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler + */ + public function testGetNextDataZero(): void + { + // needs to be a full spectre account this time. + $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' => [], + ]; + + + // need to be a full spectre login this time. + $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', + ] + ); + $spectreLogin = 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, + ] + ); + + // fake job: + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'sca-F' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'accounts' => [ + 0 => $spectreAccount, + ], + 'all-logins' => [ + 0 => $spectreLogin->toArray(), + ], + 'selected-login' => 0, + ]; + $job->save(); + + // mock repositories: + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $importRepos = $this->mock(ImportJobRepositoryInterface::class); + + // mock calls: + $accountRepos->shouldReceive('setUser')->once(); + $currencyRepos->shouldReceive('setUser')->once(); + $importRepos->shouldReceive('setUser')->once(); + + $euro = TransactionCurrency::where('code', 'EUR')->first(); + $usd = TransactionCurrency::where('code', 'USD')->first(); + $first = $this->user()->accounts()->where('account_type_id', 3)->first(); + $second = $this->user()->accounts()->where('account_type_id', 3)->where('id', '!=', $first->id)->first(); + $accountRepos->shouldReceive('getAccountsByType')->withArgs([[AccountType::ASSET]]) + ->once()->andReturn(new Collection([$first, $second])); + $accountRepos->shouldReceive('getMetaValue')->twice()->withArgs([Mockery::any(), 'currency_id']) + ->andReturn(1, 2); + $currencyRepos->shouldReceive('findNull')->once()->withArgs([1])->andReturn($euro); + $currencyRepos->shouldReceive('findNull')->once()->withArgs([2])->andReturn(null); + Amount::shouldReceive('getDefaultCurrencyByUser')->withArgs([Mockery::any()])->once()->andReturn($usd); + + // call handler: + $handler = new ChooseAccountsHandler(); + $handler->setImportJob($job); + $result = []; + try { + $result = $handler->getNextData(); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + + $expected = [ + 'accounts' => [ + 0 => new SpectreAccount($spectreAccount), + ], + 'ff_accounts' => [ + $first->id => [ + 'name' => $first->name, + 'iban' => $first->iban, + 'code' => $euro->code, + ], + $second->id => [ + 'name' => $second->name, + 'iban' => $second->iban, + 'code' => $usd->code, + ], + ], + 'login' => $spectreLogin, + ]; + + $this->assertEquals($expected, $result); + } + +} \ No newline at end of file diff --git a/tests/Unit/Support/Import/JobConfiguration/Spectre/ChooseLoginHandlerTest.php b/tests/Unit/Support/Import/JobConfiguration/Spectre/ChooseLoginHandlerTest.php new file mode 100644 index 0000000000..7ecf6f9eb6 --- /dev/null +++ b/tests/Unit/Support/Import/JobConfiguration/Spectre/ChooseLoginHandlerTest.php @@ -0,0 +1,274 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Support\Import\JobConfiguration\Spectre; + + +use Carbon\Carbon; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Models\ImportJob; +use FireflyIII\Models\Preference; +use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; +use FireflyIII\Services\Spectre\Object\Attempt; +use FireflyIII\Services\Spectre\Object\Holder; +use FireflyIII\Services\Spectre\Object\Login; +use FireflyIII\Services\Spectre\Object\Token; +use FireflyIII\Services\Spectre\Request\CreateTokenRequest; +use FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseLoginHandler; +use Mockery; +use Preferences; +use Tests\TestCase; + +/** + * Class ChooseLoginHandlerTest + */ +class ChooseLoginHandlerTest extends TestCase +{ + /** + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseLoginHandler + */ + public function testCCFalse(): void + { + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'slh-A' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = []; + $job->save(); + + $repository = $this->mock(ImportJobRepositoryInterface::class); + $repository->shouldReceive('setUser')->once(); + + $handler = new ChooseLoginHandler; + $handler->setImportJob($job); + $this->assertFalse($handler->configurationComplete()); + } + + /** + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseLoginHandler + */ + public function testCCTrue(): void + { + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'slh-B' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = ['selected-login' => 1,]; + $job->save(); + + $repository = $this->mock(ImportJobRepositoryInterface::class); + $repository->shouldReceive('setUser')->once(); + + $handler = new ChooseLoginHandler; + $handler->setImportJob($job); + $this->assertTrue($handler->configurationComplete()); + } + + /** + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseLoginHandler + */ + public function testConfigureJob(): void + { + + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'slh-C' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = []; + $job->save(); + $data = [ + 'spectre_login_id' => 12, + ]; + $repository = $this->mock(ImportJobRepositoryInterface::class); + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('setConfiguration')->withArgs([Mockery::any(), ['selected-login' => 12],])->once(); + $repository->shouldReceive('setStage')->once()->withArgs([Mockery::any(), 'authenticated']); + + $handler = new ChooseLoginHandler; + $handler->setImportJob($job); + try { + $this->assertCount(0, $handler->configureJob($data)); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + } + + /** + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseLoginHandler + */ + public function testConfigureJobCustomer(): void + { + // fake Spectre customer: + $fakeCustomerPreference = new Preference; + $fakeCustomerPreference->name = 'spectre_customer'; + $fakeCustomerPreference->data = [ + 'id' => 1, + 'identifier' => 'fake', + 'secret' => 'Dumbledore dies', + ]; + + $job = new ImportJob; + $job->user_id = $this->user()->id; + $job->key = 'slh-C' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = []; + $job->save(); + $data = [ + 'spectre_login_id' => 0, + ]; + $carbon = new Carbon(); + $token = new Token(['token' => 'x', 'expires_at' => $carbon->toW3cString(), 'connect_url' => 'https://']); + + // should try to grab customer from preferences: + Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'spectre_customer', null]) + ->andReturn($fakeCustomerPreference)->once(); + + // mock stuff + $ctRequest = $this->mock(CreateTokenRequest::class); + $repository = $this->mock(ImportJobRepositoryInterface::class); + + // mock calls + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('setConfiguration')->once()->withArgs([Mockery::any(), ['selected-login' => 0,]]); + $repository->shouldReceive('setStage')->once()->withArgs([Mockery::any(), 'do-authenticate']); + $repository->shouldReceive('setConfiguration')->once()->withArgs( + [Mockery::any(), + [ + 'selected-login' => 0, + 'customer' => ['id' => 1, 'identifier' => 'fake', 'secret' => 'Dumbledore dies',], + 'token' => ['token' => 'x', 'expires_at' => $carbon->toW3cString(), 'connect_url' => 'https://'], + ]] + ); + + // should try to grab token from Spectre: + $ctRequest->shouldReceive('setUser')->once(); + $ctRequest->shouldReceive('setCustomer')->once(); + $ctRequest->shouldReceive('setUri')->once()->withArgs([route('import.job.status.index', [$job->key])]); + $ctRequest->shouldReceive('call')->once(); + $ctRequest->shouldReceive('getToken')->once()->andReturn($token); + + + $handler = new ChooseLoginHandler; + $handler->setImportJob($job); + try { + $this->assertCount(0, $handler->configureJob($data)); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + + } + + /** + * @covers \FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseLoginHandler + */ + public function testGetNextData(): 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' => 123, + '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 = 'slh-C' . random_int(1, 1000); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = [ + 'all-logins' => [$login->toArray()], + ]; + $job->save(); + + $handler = new ChooseLoginHandler; + $handler->setImportJob($job); + $this->assertEquals(['logins' => [$login]], $handler->getNextData()); + } + +} \ No newline at end of file diff --git a/tests/Unit/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandlerTest.php b/tests/Unit/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandlerTest.php new file mode 100644 index 0000000000..46fe46ae60 --- /dev/null +++ b/tests/Unit/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandlerTest.php @@ -0,0 +1,105 @@ +. + */ + +declare(strict_types=1); + +namespace tests\Unit\Support\Import\JobConfiguration\Spectre; + + +use Carbon\Carbon; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Models\ImportJob; +use FireflyIII\Models\Preference; +use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; +use FireflyIII\Services\Spectre\Object\Token; +use FireflyIII\Services\Spectre\Request\CreateTokenRequest; +use FireflyIII\Support\Import\JobConfiguration\Spectre\DoAuthenticateHandler; +use Mockery; +use Preferences; +use Tests\TestCase; + +/** + * Class DoAuthenticateHandlerTest + */ +class DoAuthenticateHandlerTest extends TestCase +{ + /** + * No token in config, but grab it from users preferences. + * + * @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); + $job->status = 'new'; + $job->stage = 'new'; + $job->provider = 'spectre'; + $job->file_type = ''; + $job->configuration = []; + $job->save(); + + // mock stuff: + $repository = $this->mock(ImportJobRepositoryInterface::class); + $repository->shouldReceive('setUser')->once(); + $repository->shouldReceive('setStatus')->once()->withArgs([Mockery::any(), 'ready_to_run']); + $repository->shouldReceive('setStage')->once()->withArgs([Mockery::any(), 'authenticated']); + + // mock request for a new Token: + $ctRequest = $this->mock(CreateTokenRequest::class); + + // fake token: + $carbon = new Carbon(); + $token = new Token(['token' => 'x', 'expires_at' => $carbon->toW3cString(), 'connect_url' => 'https://']); + + // fake Spectre customer: + $fakeCustomerPreference = new Preference; + $fakeCustomerPreference->name = 'spectre_customer'; + $fakeCustomerPreference->data = [ + 'id' => 1, + 'identifier' => 'fake', + 'secret' => 'Dumbledore dies', + ]; + + // should try to grab customer from preferences: + Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'spectre_customer', null]) + ->andReturn($fakeCustomerPreference)->once(); + + // should try to grab token from Spectre: + $ctRequest->shouldReceive('setUser')->once(); + $ctRequest->shouldReceive('setCustomer')->once(); + $ctRequest->shouldReceive('setUri')->once()->withArgs([route('import.job.status.index', [$job->key])]); + $ctRequest->shouldReceive('call')->once(); + $ctRequest->shouldReceive('getToken')->once()->andReturn($token); + + $handler = new DoAuthenticateHandler; + $handler->setImportJob($job); + $result = []; + try { + $result = $handler->getNextData(); + } catch (FireflyException $e) { + $this->assertFalse(true, $e->getMessage()); + } + $this->assertEquals(['token-url' => $token->getConnectUrl()], $result); + } + +} \ No newline at end of file