diff --git a/app/Helpers/Help/Help.php b/app/Helpers/Help/Help.php index 1831591db4..a07818d6cd 100644 --- a/app/Helpers/Help/Help.php +++ b/app/Helpers/Help/Help.php @@ -43,6 +43,8 @@ class Help implements HelpInterface /** * Get from cache. * + * @codeCoverageIgnore + * * @param string $route * @param string $language * @@ -70,7 +72,7 @@ class Help implements HelpInterface $opt = ['headers' => ['User-Agent' => $this->userAgent]]; $content = ''; $statusCode = 500; - $client = new Client; + $client = app(Client::class); try { $res = $client->request('GET', $uri, $opt); $statusCode = $res->getStatusCode(); @@ -94,6 +96,8 @@ class Help implements HelpInterface /** * Do we have the route? * + * @codeCoverageIgnore + * * @param string $route * * @return bool @@ -106,6 +110,8 @@ class Help implements HelpInterface /** * Is in cache? * + * @codeCoverageIgnore + * * @param string $route * @param string $language * @@ -128,6 +134,8 @@ class Help implements HelpInterface /** * Put help text in cache. * + * @codeCoverageIgnore + * * @param string $route * @param string $language * @param string $content diff --git a/app/Helpers/Report/BalanceReportHelper.php b/app/Helpers/Report/BalanceReportHelper.php index c2d807f530..ae1404c83f 100644 --- a/app/Helpers/Report/BalanceReportHelper.php +++ b/app/Helpers/Report/BalanceReportHelper.php @@ -34,6 +34,8 @@ use Log; /** * Class BalanceReportHelper. + * + * @codeCoverageIgnore */ class BalanceReportHelper implements BalanceReportHelperInterface { diff --git a/app/Helpers/Report/BudgetReportHelper.php b/app/Helpers/Report/BudgetReportHelper.php index 5d33e5ca71..dde31c246c 100644 --- a/app/Helpers/Report/BudgetReportHelper.php +++ b/app/Helpers/Report/BudgetReportHelper.php @@ -30,6 +30,8 @@ use Illuminate\Support\Collection; /** * Class BudgetReportHelper. + * + * @codeCoverageIgnore */ class BudgetReportHelper implements BudgetReportHelperInterface { diff --git a/app/Http/Controllers/Chart/ReportController.php b/app/Http/Controllers/Chart/ReportController.php index 309eb36ba1..b13125d2da 100644 --- a/app/Http/Controllers/Chart/ReportController.php +++ b/app/Http/Controllers/Chart/ReportController.php @@ -26,6 +26,8 @@ use Carbon\Carbon; use FireflyIII\Generator\Chart\Basic\GeneratorInterface; use FireflyIII\Helpers\Report\NetWorthInterface; use FireflyIII\Http\Controllers\Controller; +use FireflyIII\Models\Account; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountTaskerInterface; use FireflyIII\Support\CacheProperties; use FireflyIII\Support\Http\Controllers\BasicDataSupport; @@ -56,8 +58,6 @@ class ReportController extends Controller * This chart, by default, is shown on the multi-year and year report pages, * which means that giving it a 2 week "period" should be enough granularity. * - * TODO this chart is not multi-currency aware. - * * @param Collection $accounts * @param Carbon $start * @param Carbon $end @@ -81,9 +81,26 @@ class ReportController extends Controller $helper = app(NetWorthInterface::class); $helper->setUser(auth()->user()); + // filter accounts on having the preference for being included. + /** @var AccountRepositoryInterface $accountRepository */ + $accountRepository = app(AccountRepositoryInterface::class); + $filtered = $accounts->filter( + function (Account $account) use ($accountRepository) { + $includeNetWorth = $accountRepository->getMetaValue($account, 'include_net_worth'); + $result = null === $includeNetWorth ? true : '1' === $includeNetWorth; + if (false === $result) { + Log::debug(sprintf('Will not include "%s" in net worth charts.', $account->name)); + } + + return $result; + } + ); + + + while ($current < $end) { // get balances by date, grouped by currency. - $result = $helper->getNetWorthByCurrency($accounts, $current); + $result = $helper->getNetWorthByCurrency($filtered, $current); // loop result, add to array. /** @var array $netWorthItem */ diff --git a/tests/Api/V1/Controllers/AccountControllerTest.php b/tests/Api/V1/Controllers/AccountControllerTest.php index d2d92c1dc2..d6cdbfe354 100644 --- a/tests/Api/V1/Controllers/AccountControllerTest.php +++ b/tests/Api/V1/Controllers/AccountControllerTest.php @@ -264,6 +264,54 @@ class AccountControllerTest extends TestCase $response->assertHeader('Content-Type', 'application/vnd.api+json'); } + /** + * Send correct data. Should call account repository store method. + * + * @covers \FireflyIII\Api\V1\Controllers\AccountController + * @covers \FireflyIII\Api\V1\Requests\AccountRequest + */ + public function testStoreLiability(): void + { + // mock repositories + $repository = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $account = $this->user()->accounts()->first(); + // mock calls: + $repository->shouldReceive('setUser'); + $repository->shouldReceive('store')->once()->andReturn($account); + $repository->shouldReceive('getOpeningBalanceAmount')->andReturn('10'); + $repository->shouldReceive('getOpeningBalanceDate')->andReturn('2018-01-01'); + $currencyRepos->shouldReceive('setUser')->once(); + + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('defaultAsset'); + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1'); + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountNumber'])->andReturn('1'); + $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC'); + $repository->shouldReceive('getNoteText')->withArgs([Mockery::any()])->andReturn('Hello'); + + // data to submit + $data = [ + 'name' => 'Some new liability account #' . random_int(1, 10000), + 'currency_id' => 1, + 'type' => 'liability', + 'active' => 1, + 'include_net_worth' => 1, + 'liability_amount' => '10000', + 'liability_start_date' => '2016-01-01', + 'liability_type' => 'mortgage', + 'interest' => '1', + 'interest_period' => 'daily', + ]; + + // test API + $response = $this->post('/api/v1/accounts', $data, ['Accept' => 'application/json']); + $response->assertSee($account->name); + $response->assertStatus(200); + $response->assertJson(['data' => ['type' => 'accounts', 'links' => true],]); + $response->assertHeader('Content-Type', 'application/vnd.api+json'); + + } + /** * Name already in use. * diff --git a/tests/Unit/Generator/Chart/Basic/ChartJsGeneratorTest.php b/tests/Unit/Generator/Chart/Basic/ChartJsGeneratorTest.php index 77af41988e..9184b02c94 100644 --- a/tests/Unit/Generator/Chart/Basic/ChartJsGeneratorTest.php +++ b/tests/Unit/Generator/Chart/Basic/ChartJsGeneratorTest.php @@ -113,6 +113,48 @@ class ChartJsGeneratorTest extends TestCase } + /** + * @covers \FireflyIII\Generator\Chart\Basic\ChartJsGenerator + */ + public function testMultiCurrencyPieChart(): void + { + + $data = [ + 'one' => ['amount' => -1,'currency_symbol' => 'a'], + 'two' => ['amount' => -2,'currency_symbol' => 'b'], + 'three' => ['amount' => -3,'currency_symbol' => 'c'], + ]; + + /** @var ChartJsGenerator $generator */ + $generator = new ChartJsGenerator(); + $result = $generator->multiCurrencyPieChart($data); + + $this->assertEquals('three', $result['labels'][0]); + $this->assertEquals(3.0, $result['datasets'][0]['data'][0]); + + } + + /** + * @covers \FireflyIII\Generator\Chart\Basic\ChartJsGenerator + */ + public function testMultiCurrencyPieChartPositive(): void + { + + $data = [ + 'one' => ['amount' => 1,'currency_symbol' => 'a'], + 'two' => ['amount' => 2,'currency_symbol' => 'b'], + 'three' => ['amount' => 3,'currency_symbol' => 'c'], + ]; + + /** @var ChartJsGenerator $generator */ + $generator = new ChartJsGenerator(); + $result = $generator->multiCurrencyPieChart($data); + + $this->assertEquals('three', $result['labels'][0]); + $this->assertEquals(3.0, $result['datasets'][0]['data'][0]); + + } + /** * @covers \FireflyIII\Generator\Chart\Basic\ChartJsGenerator */ diff --git a/tests/Unit/Helpers/FiscalHelperTest.php b/tests/Unit/Helpers/FiscalHelperTest.php new file mode 100644 index 0000000000..e8c93a337c --- /dev/null +++ b/tests/Unit/Helpers/FiscalHelperTest.php @@ -0,0 +1,171 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Helpers; + + +use Carbon\Carbon; +use FireflyIII\Helpers\FiscalHelper; +use FireflyIII\Models\Preference; +use Log; +use Preferences; +use Tests\TestCase; + + +/** + * + * Class FiscalHelperTest + */ +class FiscalHelperTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Log::debug(sprintf('Now in %s.', \get_class($this))); + } + + /** + * Fiscal year starts on April 1st. + * Current date is June 6th. + * + * Fiscal year ends next year on Mar 31. + * + * @covers \FireflyIII\Helpers\FiscalHelper + */ + public function testEndOfFiscalYear(): void + { + + $pref = new Preference; + $pref->data = true; + + $datePref = new Preference; + $datePref->data = '04-01'; + + Preferences::shouldReceive('get')->withArgs(['customFiscalYear', false])->andReturn($pref)->once(); + Preferences::shouldReceive('get')->withArgs(['fiscalYearStart', '01-01'])->andReturn($datePref)->once(); + + $helper = new FiscalHelper; + $date = new Carbon('2018-06-06'); + $result = $helper->endOfFiscalYear($date); + $this->assertEquals('2019-03-31', $result->format('Y-m-d')); + } + + /** + * No fiscal year + * Current date is June 6th. + * + * Fiscal year ends next year on Dec 31. + * + * @covers \FireflyIII\Helpers\FiscalHelper + */ + public function testEndOfFiscalYearNoPref(): void + { + + $pref = new Preference; + $pref->data = false; + + Preferences::shouldReceive('get')->withArgs(['customFiscalYear', false])->andReturn($pref)->once(); + + $helper = new FiscalHelper; + $date = new Carbon('2018-06-06'); + $result = $helper->endOfFiscalYear($date); + $this->assertEquals('2018-12-31', $result->format('Y-m-d')); + } + + /** + * Fiscal year starts on April 1st. + * Current date is June 6th. + * + * Fiscal year starts in current year. + * + * @covers \FireflyIII\Helpers\FiscalHelper + */ + public function testStartOfFiscalYear(): void + { + + $pref = new Preference; + $pref->data = true; + + $datePref = new Preference; + $datePref->data = '04-01'; + + Preferences::shouldReceive('get')->withArgs(['customFiscalYear', false])->andReturn($pref)->once(); + Preferences::shouldReceive('get')->withArgs(['fiscalYearStart', '01-01'])->andReturn($datePref)->once(); + + $helper = new FiscalHelper; + $date = new Carbon('2018-06-06'); + $result = $helper->startOfFiscalYear($date); + $this->assertEquals('2018-04-01', $result->format('Y-m-d')); + } + + /** + * No fiscal year + * Current date is June 6th. + * + * Fiscal year starts Jan 1st. + * + * @covers \FireflyIII\Helpers\FiscalHelper + */ + public function testStartOfFiscalYearNoPref(): void + { + + $pref = new Preference; + $pref->data = false; + + Preferences::shouldReceive('get')->withArgs(['customFiscalYear', false])->andReturn($pref)->once(); + + $helper = new FiscalHelper; + $date = new Carbon('2018-06-06'); + $result = $helper->startOfFiscalYear($date); + $this->assertEquals('2018-01-01', $result->format('Y-m-d')); + } + + /** + * Fiscal year starts on April 1st. + * Current date is Feb 6th. + * + * Fiscal year starts in previous year. + * + * @covers \FireflyIII\Helpers\FiscalHelper + */ + public function testStartOfFiscalYearPrev(): void + { + + $pref = new Preference; + $pref->data = true; + + $datePref = new Preference; + $datePref->data = '04-01'; + + Preferences::shouldReceive('get')->withArgs(['customFiscalYear', false])->andReturn($pref)->once(); + Preferences::shouldReceive('get')->withArgs(['fiscalYearStart', '01-01'])->andReturn($datePref)->once(); + + $helper = new FiscalHelper; + $date = new Carbon('2018-02-06'); + $result = $helper->startOfFiscalYear($date); + $this->assertEquals('2017-04-01', $result->format('Y-m-d')); + } +} \ No newline at end of file diff --git a/tests/Unit/Helpers/Help/HelpTest.php b/tests/Unit/Helpers/Help/HelpTest.php new file mode 100644 index 0000000000..2c0f109473 --- /dev/null +++ b/tests/Unit/Helpers/Help/HelpTest.php @@ -0,0 +1,95 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Helpers\Help; + + +use FireflyIII\Helpers\Help\Help; +use GuzzleHttp\Client; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Psr7\Response; +use Log; +use Tests\TestCase; + +/** + * + * Class HelpTest + */ +class HelpTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Log::debug(sprintf('Now in %s.', \get_class($this))); + } + + /** + * @covers \FireflyIII\Helpers\Help\Help + */ + public function testGetFromGitHub(): void + { + $headers = ['Content-Type' => 'application/json']; + $response = new Response(200, $headers, 'Some help text.'); + $mock = new MockHandler([$response]); + + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + + //client instance is bound to the mock here. + $this->app->instance(Client::class, $client); + + + // now let's see what happens: + $help = new Help; + $result = $help->getFromGitHub('test-route', 'en_US'); + $this->assertEquals('

Some help text.

'."\n", $result); + } + + /** + * @covers \FireflyIII\Helpers\Help\Help + */ + public function testGetFromGitHubError(): void + { + $headers = ['Content-Type' => 'application/json']; + $response = new Response(500, $headers, 'Big bad error.'); + $mock = new MockHandler([$response]); + + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + + //client instance is bound to the mock here. + $this->app->instance(Client::class, $client); + + + // now let's see what happens: + $help = new Help; + $result = $help->getFromGitHub('test-route', 'en_US'); + $this->assertEquals('', $result); + } + + +} \ No newline at end of file diff --git a/tests/Unit/Support/Import/Routine/Bunq/StageImportDataHandlerTest.php b/tests/Unit/Support/Import/Routine/Bunq/StageImportDataHandlerTest.php index a153c93d81..ab66906612 100644 --- a/tests/Unit/Support/Import/Routine/Bunq/StageImportDataHandlerTest.php +++ b/tests/Unit/Support/Import/Routine/Bunq/StageImportDataHandlerTest.php @@ -171,6 +171,11 @@ class StageImportDataHandlerTest extends TestCase $accountFactory->shouldReceive('create')->withArgs([$expectedAccount]) ->andReturn($deposit)->once(); + // set new last transaction ID: + $lastPref = new Preference; + $lastPref->data =0; + Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-last-transaction-1234', 0])->andReturn($lastPref)->once(); + $handler = new StageImportDataHandler; $handler->setImportJob($job); @@ -233,6 +238,11 @@ class StageImportDataHandlerTest extends TestCase $accountRepository->shouldReceive('findNull')->withArgs([5678])->andReturn($account)->once(); $payment->shouldReceive('listing')->once()->andReturn($list); + // set new last transaction ID: + $lastPref = new Preference; + $lastPref->data =0; + Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-last-transaction-1234', 0])->andReturn($lastPref)->once(); + $handler = new StageImportDataHandler; $handler->setImportJob($job); try { @@ -279,6 +289,11 @@ class StageImportDataHandlerTest extends TestCase $amount = new Amount('150', 'EUR'); $pointer = new Pointer('iban', 'ES2364265841767173822054', 'Test Site'); + // set new last transaction ID: + $lastPref = new Preference; + $lastPref->data =0; + Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-last-transaction-1234', 0])->andReturn($lastPref)->once(); + // ignore the deprecated fields: $amount->setValue('150'); @@ -431,6 +446,11 @@ class StageImportDataHandlerTest extends TestCase $value = [$payment]; $list = new BunqResponsePaymentList($value, [], null); + // set new last transaction ID: + $lastPref = new Preference; + $lastPref->data =0; + Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-last-transaction-1234', 0])->andReturn($lastPref)->once(); + $expectedTransactions = [ [ 'user' => 1,