diff --git a/app/Helpers/Report/PopupReport.php b/app/Helpers/Report/PopupReport.php
index 23c8d50d18..a50b248377 100644
--- a/app/Helpers/Report/PopupReport.php
+++ b/app/Helpers/Report/PopupReport.php
@@ -33,6 +33,8 @@ use Illuminate\Support\Collection;
/**
* Class PopupReport.
+ *
+ * @codeCoverageIgnore
*/
class PopupReport implements PopupReportInterface
{
diff --git a/app/Helpers/Report/ReportHelper.php b/app/Helpers/Report/ReportHelper.php
index 1ae2577ae5..bd8c5af15a 100644
--- a/app/Helpers/Report/ReportHelper.php
+++ b/app/Helpers/Report/ReportHelper.php
@@ -35,6 +35,8 @@ use Illuminate\Support\Collection;
/**
* Class ReportHelper.
+ *
+ * @codeCoverageIgnore
*/
class ReportHelper implements ReportHelperInterface
{
diff --git a/app/Http/Controllers/Budget/AmountController.php b/app/Http/Controllers/Budget/AmountController.php
index cccc4682cc..f6d7a52ba0 100644
--- a/app/Http/Controllers/Budget/AmountController.php
+++ b/app/Http/Controllers/Budget/AmountController.php
@@ -36,6 +36,7 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
+use Log;
/**
* Class AmountController
@@ -160,6 +161,8 @@ class AmountController extends Controller
$average = $this->repository->getAverageAvailable($start, $end);
$available = bcmul($average, (string)$daysInPeriod);
+ Log::debug(sprintf('Average is %s, so total available is %s because days is %d.', $average, $available, $daysInPeriod));
+
// amount earned in this period:
/** @var TransactionCollectorInterface $collector */
$collector = app(TransactionCollectorInterface::class);
@@ -169,6 +172,8 @@ class AmountController extends Controller
// This is multiplied by the number of days in the current period, showing you the average.
$earnedAverage = bcmul(bcdiv($earned, (string)$daysInSearchPeriod), (string)$daysInPeriod);
+ Log::debug(sprintf('Earned is %s, earned average is %s', $earned, $earnedAverage));
+
// amount spent in period
/** @var TransactionCollectorInterface $collector */
$collector = app(TransactionCollectorInterface::class);
@@ -176,11 +181,16 @@ class AmountController extends Controller
$spent = (string)$collector->getTransactions()->sum('transaction_amount');
$spentAverage = app('steam')->positive(bcmul(bcdiv($spent, (string)$daysInSearchPeriod), (string)$daysInPeriod));
+ Log::debug(sprintf('Spent is %s, spent average is %s', $earned, $earnedAverage));
+
// the default suggestion is the money the user has spent, on average, over this period.
$suggested = $spentAverage;
+ Log::debug(sprintf('Suggested is now %s (spent average)',$suggested));
+
// if the user makes less per period, suggest that amount instead.
if (1 === bccomp($spentAverage, $earnedAverage)) {
+ Log::debug(sprintf('Because earned average (%s) is less than spent average (%s) will suggest earned average instead.', $earnedAverage, $spentAverage));
$suggested = $earnedAverage;
}
diff --git a/app/Http/Controllers/Import/CallbackController.php b/app/Http/Controllers/Import/CallbackController.php
index 2fb1e0b612..f85915ac19 100644
--- a/app/Http/Controllers/Import/CallbackController.php
+++ b/app/Http/Controllers/Import/CallbackController.php
@@ -48,10 +48,13 @@ class CallbackController extends Controller
{
$code = (string)$request->get('code');
$jobKey = (string)$request->get('state');
- $importJob = $repository->findByKey($jobKey);
+
if ('' === $code) {
return view('error')->with('message', 'You Need A Budget did not reply with a valid authorization code. Firefly III cannot continue.');
}
+
+ $importJob = $repository->findByKey($jobKey);
+
if ('' === $jobKey || null === $importJob) {
return view('error')->with('message', 'You Need A Budget did not reply with the correct state identifier. Firefly III cannot continue.');
}
diff --git a/app/Http/Controllers/JsonController.php b/app/Http/Controllers/JsonController.php
index a270d98a8b..a3f36b4ad0 100644
--- a/app/Http/Controllers/JsonController.php
+++ b/app/Http/Controllers/JsonController.php
@@ -49,10 +49,12 @@ class JsonController extends Controller
}
try {
$view = view('rules.partials.action', compact('actions', 'count'))->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $e) {
Log::error(sprintf('Cannot render rules.partials.action: %s', $e->getMessage()));
$view = 'Could not render view.';
}
+ // @codeCoverageIgnoreEnd
return response()->json(['html' => $view]);
}
@@ -78,10 +80,12 @@ class JsonController extends Controller
try {
$view = view('rules.partials.trigger', compact('triggers', 'count'))->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $e) {
Log::error(sprintf('Cannot render rules.partials.trigger: %s', $e->getMessage()));
$view = 'Could not render view.';
}
+ // @codeCoverageIgnoreEnd
return response()->json(['html' => $view]);
}
diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index 74d6c134e2..a22196b051 100644
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -190,17 +190,10 @@ class ProfileController extends Controller
/**
* Enable 2FA screen.
*
- * @param UserRepositoryInterface $repository
- *
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
- public function enable2FA(UserRepositoryInterface $repository)
+ public function enable2FA()
{
- /** @var User $user */
- $user = auth()->user();
- if ($repository->hasRole($user, 'demo')) {
- return redirect(route('profile.index'));
- }
$hasSecret = (null !== app('preferences')->get('twoFactorAuthSecret'));
// if we don't have a valid secret yet, redirect to the code page to get one.
diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index 57e1b9e949..3799299e90 100644
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -102,10 +102,12 @@ class SearchController extends Controller
}
try {
$html = view('search.search', compact('transactions'))->render();
+ // @codeCoverageIgnoreStart
} catch (Throwable $e) {
Log::error(sprintf('Cannot render search.search: %s', $e->getMessage()));
$html = 'Could not render view.';
}
+ // @codeCoverageIgnoreEnd
return response()->json(['count' => $transactions->count(), 'html' => $html]);
}
diff --git a/tests/Feature/Controllers/Account/EditControllerTest.php b/tests/Feature/Controllers/Account/EditControllerTest.php
index ed2ea90af1..d05f92e21c 100644
--- a/tests/Feature/Controllers/Account/EditControllerTest.php
+++ b/tests/Feature/Controllers/Account/EditControllerTest.php
@@ -92,6 +92,47 @@ class EditControllerTest extends TestCase
$response->assertSee('Some text');
}
+ /**
+ * @covers \FireflyIII\Http\Controllers\Account\EditController
+ */
+ public function testEditLiability(): void
+ {
+ $journalRepos = $this->mock(JournalRepositoryInterface::class);
+ $repository = $this->mock(CurrencyRepositoryInterface::class);
+ $accountRepos = $this->mock(AccountRepositoryInterface::class);
+
+ $repository->shouldReceive('findNull')->once()->andReturn(TransactionCurrency::find(1));
+ $repository->shouldReceive('get')->andReturn(new Collection);
+ $journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
+ $accountRepos->shouldReceive('getNoteText')->andReturn('Some text')->once();
+ $accountRepos->shouldReceive('getOpeningBalanceAmount')->andReturnNull();
+ $accountRepos->shouldReceive('getOpeningBalanceDate')->andReturnNull();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountNumber'])->andReturn('123');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('defaultAsset');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccType'])->andReturn('');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccMonthlyPaymentDate'])->andReturn('');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('1');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest_period'])->andReturn('monthly');
+
+ // get all types:
+ $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
+ $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
+ $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
+ $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Credit card'])->andReturn(AccountType::find(13))->once();
+
+
+ $this->be($this->user());
+ $account = $this->user()->accounts()->where('account_type_id', 12)->whereNull('deleted_at')->first();
+ $response = $this->get(route('accounts.edit', [$account->id]));
+ $response->assertStatus(200);
+ // has bread crumb
+ $response->assertSee('
');
+ $response->assertSee('Some text');
+ }
+
/**
* @covers \FireflyIII\Http\Controllers\Account\EditController
*/
diff --git a/tests/Feature/Controllers/Account/ReconcileControllerTest.php b/tests/Feature/Controllers/Account/ReconcileControllerTest.php
index 16e6883de9..289e9233cb 100644
--- a/tests/Feature/Controllers/Account/ReconcileControllerTest.php
+++ b/tests/Feature/Controllers/Account/ReconcileControllerTest.php
@@ -188,6 +188,28 @@ class ReconcileControllerTest extends TestCase
$response->assertSee('');
}
+
+ /**
+ * Test show for actual reconciliation.
+ *
+ * @covers \FireflyIII\Http\Controllers\Account\ReconcileController
+ */
+ public function testShowError(): void
+ {
+ $journal = $this->user()->transactionJournals()->where('transaction_type_id', 5)->first();
+ $repository = $this->mock(JournalRepositoryInterface::class);
+ $repository->shouldReceive('firstNull')->andReturn(new TransactionJournal);
+ $repository->shouldReceive('getAssetTransaction')->once()->andReturnNull();
+
+ $this->be($this->user());
+ $response = $this->get(route('accounts.reconcile.show', [$journal->id]));
+ $response->assertStatus(500);
+
+ // has bread crumb
+ $response->assertSee('The transaction data is incomplete. This is probably a bug. Apologies.');
+ }
+
+
/**
* Test show for actual reconciliation, but its not a reconciliation.
*
diff --git a/tests/Feature/Controllers/Account/ShowControllerTest.php b/tests/Feature/Controllers/Account/ShowControllerTest.php
index 5105bf4af5..149069dcc5 100644
--- a/tests/Feature/Controllers/Account/ShowControllerTest.php
+++ b/tests/Feature/Controllers/Account/ShowControllerTest.php
@@ -100,6 +100,40 @@ class ShowControllerTest extends TestCase
$response->assertSee('');
}
+ /**
+ * @covers \FireflyIII\Http\Controllers\Account\ShowController
+ * @dataProvider dateRangeProvider
+ *
+ * @param string $range
+ */
+ public function testShowLiability(string $range): void
+ {
+ $date = new Carbon;
+ $this->session(['start' => $date, 'end' => clone $date]);
+ $account = $this->user()->accounts()->where('account_type_id', 12)->whereNull('deleted_at')->first();
+
+ // mock stuff:
+ $tasker = $this->mock(AccountTaskerInterface::class);
+ $journalRepos = $this->mock(JournalRepositoryInterface::class);
+ $currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
+
+ $currencyRepos->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1));
+
+ $journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
+ $tasker->shouldReceive('amountOutInPeriod')->withAnyArgs()->andReturn('-1');
+ $tasker->shouldReceive('amountInInPeriod')->withAnyArgs()->andReturn('1');
+
+ $repository = $this->mock(AccountRepositoryInterface::class);
+ $repository->shouldReceive('getMetaValue')->andReturn('');
+ $repository->shouldReceive('isLiability')->andReturn(true);
+
+ $this->be($this->user());
+ $this->changeDateRange($this->user(), $range);
+ $response = $this->get(route('accounts.show', [$account->id]));
+ $response->assertStatus(302);
+ $response->assertRedirect(route('accounts.show.all', [$account->id]));
+ }
+
/**
* @covers \FireflyIII\Http\Controllers\Account\ShowController
diff --git a/tests/Feature/Controllers/Admin/UpdateControllerTest.php b/tests/Feature/Controllers/Admin/UpdateControllerTest.php
index 8b9b0a2d33..35603f58aa 100644
--- a/tests/Feature/Controllers/Admin/UpdateControllerTest.php
+++ b/tests/Feature/Controllers/Admin/UpdateControllerTest.php
@@ -89,6 +89,7 @@ class UpdateControllerTest extends TestCase
/**
* @covers \FireflyIII\Http\Controllers\Admin\UpdateController
+ * @covers \FireflyIII\Helpers\Update\UpdateTrait
*/
public function testUpdateCheck(): void
{
@@ -118,6 +119,7 @@ class UpdateControllerTest extends TestCase
/**
* @covers \FireflyIII\Http\Controllers\Admin\UpdateController
+ * @covers \FireflyIII\Helpers\Update\UpdateTrait
*/
public function testUpdateCheckCurrent(): void
{
@@ -145,6 +147,7 @@ class UpdateControllerTest extends TestCase
/**
* @covers \FireflyIII\Http\Controllers\Admin\UpdateController
+ * @covers \FireflyIII\Helpers\Update\UpdateTrait
*/
public function testUpdateCheckError(): void
{
@@ -167,6 +170,7 @@ class UpdateControllerTest extends TestCase
/**
* @covers \FireflyIII\Http\Controllers\Admin\UpdateController
+ * @covers \FireflyIII\Helpers\Update\UpdateTrait
*/
public function testUpdateCheckNewer(): void
{
diff --git a/tests/Feature/Controllers/Budget/AmountControllerTest.php b/tests/Feature/Controllers/Budget/AmountControllerTest.php
index a4f4caba3e..3e37426ae3 100644
--- a/tests/Feature/Controllers/Budget/AmountControllerTest.php
+++ b/tests/Feature/Controllers/Budget/AmountControllerTest.php
@@ -25,7 +25,9 @@ namespace Tests\Feature\Controllers\Budget;
use Carbon\Carbon;
+use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Models\BudgetLimit;
+use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
@@ -58,6 +60,7 @@ class AmountControllerTest extends TestCase
// mock stuff
$repository = $this->mock(BudgetRepositoryInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
+ $collector = $this->mock(TransactionCollectorInterface::class);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$repository->shouldReceive('updateLimitAmount')->andReturn(new BudgetLimit);
$repository->shouldReceive('spentInPeriod')->andReturn('0');
@@ -80,6 +83,7 @@ class AmountControllerTest extends TestCase
// mock stuff
$repository = $this->mock(BudgetRepositoryInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
+ $collector = $this->mock(TransactionCollectorInterface::class);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$repository->shouldReceive('updateLimitAmount')->andReturn(new BudgetLimit);
$repository->shouldReceive('spentInPeriod')->andReturn('0');
@@ -102,6 +106,7 @@ class AmountControllerTest extends TestCase
// mock stuff
$repository = $this->mock(BudgetRepositoryInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
+ $collector = $this->mock(TransactionCollectorInterface::class);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$repository->shouldReceive('updateLimitAmount')->andReturn(new BudgetLimit);
$repository->shouldReceive('spentInPeriod')->andReturn('0');
@@ -125,6 +130,7 @@ class AmountControllerTest extends TestCase
// mock stuff
$repository = $this->mock(BudgetRepositoryInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
+ $collector = $this->mock(TransactionCollectorInterface::class);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$repository->shouldReceive('updateLimitAmount')->andReturn(new BudgetLimit);
$repository->shouldReceive('spentInPeriod')->andReturn('0');
@@ -145,6 +151,62 @@ class AmountControllerTest extends TestCase
// mock stuff
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$repository = $this->mock(BudgetRepositoryInterface::class);
+ $collector = $this->mock(TransactionCollectorInterface::class);
+
+ $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf()->times(2);
+ $collector->shouldReceive('setRange')->andReturnSelf()->times(2);
+ $collector->shouldReceive('setTypes')->andReturnSelf()->times(2);
+ $collector->shouldReceive('withOpposingAccount')->andReturnSelf()->times(2);
+
+ // collect transactions to return. First an expense, then income.
+ $income = new Transaction;
+ $income->transaction_amount = '150';
+ $incomeCollection = new Collection([$income]);
+ $expense = new Transaction;
+ $expense->transaction_amount = '100';
+ $expenseCollection = new Collection([$expense]);
+
+ $collector->shouldReceive('getTransactions')->andReturn($incomeCollection, $expenseCollection)->times(2);
+
+
+
+ $repository->shouldReceive('getAvailableBudget')->andReturn('100.123');
+ $accountRepos->shouldReceive('setUser');
+ $accountRepos->shouldReceive('getAccountsByType')->andReturn(new Collection);
+ $repository->shouldReceive('getAverageAvailable')->andReturn('100.123')->once();
+
+ $this->be($this->user());
+ $response = $this->get(route('budgets.income.info', ['20170101', '20170131']));
+ $response->assertStatus(200);
+ }
+
+ /**
+ * @covers \FireflyIII\Http\Controllers\Budget\AmountController
+ */
+ public function testInfoIncomeInversed(): void
+ {
+ Log::debug('Now in testInfoIncome()');
+ // mock stuff
+ $accountRepos = $this->mock(AccountRepositoryInterface::class);
+ $repository = $this->mock(BudgetRepositoryInterface::class);
+ $collector = $this->mock(TransactionCollectorInterface::class);
+
+ $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf()->times(2);
+ $collector->shouldReceive('setRange')->andReturnSelf()->times(2);
+ $collector->shouldReceive('setTypes')->andReturnSelf()->times(2);
+ $collector->shouldReceive('withOpposingAccount')->andReturnSelf()->times(2);
+
+ // collect transactions to return. First an expense, then income.
+ $income = new Transaction;
+ $income->transaction_amount = '100';
+ $incomeCollection = new Collection([$income]);
+ $expense = new Transaction;
+ $expense->transaction_amount = '150';
+ $expenseCollection = new Collection([$expense]);
+
+ $collector->shouldReceive('getTransactions')->andReturn($incomeCollection, $expenseCollection)->times(2);
+
+
$repository->shouldReceive('getAvailableBudget')->andReturn('100.123');
$accountRepos->shouldReceive('setUser');
@@ -168,11 +230,27 @@ class AmountControllerTest extends TestCase
// mock stuff
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$repository = $this->mock(BudgetRepositoryInterface::class);
+ $collector = $this->mock(TransactionCollectorInterface::class);
$repository->shouldReceive('getAvailableBudget')->andReturn('100.123');
$accountRepos->shouldReceive('setUser');
$accountRepos->shouldReceive('getAccountsByType')->andReturn(new Collection);
$repository->shouldReceive('getAverageAvailable')->andReturn('100.123')->once();
+ $collector->shouldReceive('setAllAssetAccounts')->andReturnSelf()->times(2);
+ $collector->shouldReceive('setRange')->andReturnSelf()->times(2);
+ $collector->shouldReceive('setTypes')->andReturnSelf()->times(2);
+ $collector->shouldReceive('withOpposingAccount')->andReturnSelf()->times(2);
+
+ // collect transactions to return. First an expense, then income.
+ $income = new Transaction;
+ $income->transaction_amount = '150';
+ $incomeCollection = new Collection([$income]);
+ $expense = new Transaction;
+ $expense->transaction_amount = '100';
+ $expenseCollection = new Collection([$expense]);
+
+ $collector->shouldReceive('getTransactions')->andReturn($incomeCollection, $expenseCollection)->times(2);
+
$this->be($this->user());
$this->changeDateRange($this->user(), $range);
$response = $this->get(route('budgets.income.info', ['20170301', '20170430']));
@@ -189,6 +267,7 @@ class AmountControllerTest extends TestCase
// mock stuff
$repository = $this->mock(BudgetRepositoryInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
+ $collector = $this->mock(TransactionCollectorInterface::class);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$repository->shouldReceive('setAvailableBudget');
$repository->shouldReceive('cleanupBudgets');
@@ -212,6 +291,7 @@ class AmountControllerTest extends TestCase
// mock stuff
$repository = $this->mock(BudgetRepositoryInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
+ $collector = $this->mock(TransactionCollectorInterface::class);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$repository->shouldReceive('getAvailableBudget')->andReturn('1');
$repository->shouldReceive('cleanupBudgets');
diff --git a/tests/Feature/Controllers/Chart/CategoryControllerTest.php b/tests/Feature/Controllers/Chart/CategoryControllerTest.php
index 6161bd81de..db0fa81ef4 100644
--- a/tests/Feature/Controllers/Chart/CategoryControllerTest.php
+++ b/tests/Feature/Controllers/Chart/CategoryControllerTest.php
@@ -90,7 +90,7 @@ class CategoryControllerTest extends TestCase
// spent per currency data:
$spentData = [
- 1 => '123.45',
+ 1 => '-123.45',
2 => '567.21',
];
diff --git a/tests/Feature/Controllers/CurrencyControllerTest.php b/tests/Feature/Controllers/CurrencyControllerTest.php
index b4ce36c889..b07f20ebeb 100644
--- a/tests/Feature/Controllers/CurrencyControllerTest.php
+++ b/tests/Feature/Controllers/CurrencyControllerTest.php
@@ -289,6 +289,34 @@ class CurrencyControllerTest extends TestCase
$response->assertSessionHas('success');
}
+ /**
+ * @covers \FireflyIII\Http\Controllers\CurrencyController
+ * @covers \FireflyIII\Http\Requests\CurrencyFormRequest
+ */
+ public function testStoreError(): void
+ {
+ // mock stuff
+ $repository = $this->mock(CurrencyRepositoryInterface::class);
+ $userRepos = $this->mock(UserRepositoryInterface::class);
+ $journalRepos = $this->mock(JournalRepositoryInterface::class);
+
+ $journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
+ $repository->shouldReceive('store')->andReturnNull();
+ $userRepos->shouldReceive('hasRole')->once()->andReturn(true);
+
+ $this->session(['currencies.create.uri' => 'http://localhost']);
+ $data = [
+ 'name' => 'XX',
+ 'code' => 'XXX',
+ 'symbol' => 'x',
+ 'decimal_places' => 2,
+ ];
+ $this->be($this->user());
+ $response = $this->post(route('currencies.store'), $data);
+ $response->assertStatus(302);
+ $response->assertSessionHas('error','Could not store the new currency.');
+ }
+
/**
* @covers \FireflyIII\Http\Controllers\CurrencyController
* @covers \FireflyIII\Http\Requests\CurrencyFormRequest
diff --git a/tests/Feature/Controllers/Import/CallbackControllerTest.php b/tests/Feature/Controllers/Import/CallbackControllerTest.php
new file mode 100644
index 0000000000..12788d9f65
--- /dev/null
+++ b/tests/Feature/Controllers/Import/CallbackControllerTest.php
@@ -0,0 +1,104 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace Tests\Feature\Controllers\Import;
+
+
+use FireflyIII\Models\ImportJob;
+use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
+use Tests\TestCase;
+use Log;
+use Mockery;
+
+/**
+ *
+ * Class CallbackControllerTest
+ */
+class CallbackControllerTest extends TestCase
+{
+ /**
+ *
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+ Log::debug(sprintf('Now in %s.', \get_class($this)));
+ }
+
+ /**
+ * @covers \FireflyIII\Http\Controllers\Import\CallbackController
+ */
+ public function testYnabBasic(): void {
+ $repository = $this->mock(ImportJobRepositoryInterface::class);
+
+ // config for job:
+ $config = [];
+ $newConfig = ['auth_code' => 'abc'];
+
+ // mock calls.
+ $repository->shouldReceive('findByKey')->andReturn(new ImportJob)->once();
+ $repository->shouldReceive('getConfiguration')->andReturn($config)->once();
+ $repository->shouldReceive('setConfiguration')->once()->withArgs([Mockery::any(), $newConfig]);
+
+ $repository->shouldReceive('setStatus')->once()->withArgs([Mockery::any(), 'ready_to_run']);
+ $repository->shouldReceive('setStage')->once()->withArgs([Mockery::any(), 'get_access_token']);
+
+
+ $this->be($this->user());
+ $response = $this->get(route('import.callback.ynab') . '?code=abc&state=def');
+ $response->assertStatus(302);
+ }
+
+ /**
+ * @covers \FireflyIII\Http\Controllers\Import\CallbackController
+ */
+ public function testYnabBasicBadJob(): void {
+ $repository = $this->mock(ImportJobRepositoryInterface::class);
+
+ // mock calls.
+ $repository->shouldReceive('findByKey')->andReturnNull()->once();
+
+ $this->be($this->user());
+ $response = $this->get(route('import.callback.ynab') . '?code=abc&state=def');
+ $response->assertStatus(200);
+ $response->assertSee('You Need A Budget did not reply with the correct state identifier. Firefly III cannot continue.');
+ }
+
+ /**
+ * @covers \FireflyIII\Http\Controllers\Import\CallbackController
+ */
+ public function testYnabBasicNoCode(): void {
+ $repository = $this->mock(ImportJobRepositoryInterface::class);
+
+ // config for job:
+ $config = [];
+ $newConfig = ['auth_code' => 'abc'];
+
+ // mock calls.
+
+ $this->be($this->user());
+ $response = $this->get(route('import.callback.ynab') . '?code=&state=def');
+ $response->assertStatus(200);
+ $response->assertSee('You Need A Budget did not reply with a valid authorization code. Firefly III cannot continue.');
+ }
+}
\ No newline at end of file
diff --git a/tests/Feature/Controllers/ProfileControllerTest.php b/tests/Feature/Controllers/ProfileControllerTest.php
index 8fff851215..d525a9bc38 100644
--- a/tests/Feature/Controllers/ProfileControllerTest.php
+++ b/tests/Feature/Controllers/ProfileControllerTest.php
@@ -163,7 +163,7 @@ class ProfileControllerTest extends TestCase
public function testEnable2FANoSecret(): void
{
$repository = $this->mock(UserRepositoryInterface::class);
- $repository->shouldReceive('hasRole')->withArgs([Mockery::any(), 'demo'])->twice()->andReturn(false);
+ $repository->shouldReceive('hasRole')->withArgs([Mockery::any(), 'demo'])->times(1)->andReturn(false);
// ask about language:
$langPreference = new Preference;
@@ -205,7 +205,7 @@ class ProfileControllerTest extends TestCase
public function testEnable2FASecret(): void
{
$repository = $this->mock(UserRepositoryInterface::class);
- $repository->shouldReceive('hasRole')->withArgs([Mockery::any(), 'demo'])->twice()->andReturn(false);
+ $repository->shouldReceive('hasRole')->withArgs([Mockery::any(), 'demo'])->times(1)->andReturn(false);
// ask about language:
$langPreference = new Preference;
@@ -515,7 +515,7 @@ class ProfileControllerTest extends TestCase
}
/**
- * @covers \FireflyIII\Http\Controllers\ProfileController
+ * @covers \FireflyIII\Http\Controllers\ProfileController
* @expectedExceptionMessage Invalid token
*/
public function testUndoEmailChangeBadHash(): void
@@ -540,7 +540,7 @@ class ProfileControllerTest extends TestCase
}
/**
- * @covers \FireflyIII\Http\Controllers\ProfileController
+ * @covers \FireflyIII\Http\Controllers\ProfileController
* @expectedExceptionMessage Invalid token
*/
public function testUndoEmailChangeBadToken(): void
diff --git a/tests/Unit/Helpers/Report/NetWorthTest.php b/tests/Unit/Helpers/Report/NetWorthTest.php
new file mode 100644
index 0000000000..75b65ec2fd
--- /dev/null
+++ b/tests/Unit/Helpers/Report/NetWorthTest.php
@@ -0,0 +1,126 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace Tests\Unit\Helpers\Report;
+
+
+use Amount;
+use Carbon\Carbon;
+use FireflyIII\Helpers\Report\NetWorth;
+use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Repositories\Account\AccountRepositoryInterface;
+use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use Illuminate\Support\Collection;
+use Log;
+use Mockery;
+use Steam;
+use Tests\TestCase;
+
+/**
+ *
+ * Class NetWorthTest
+ */
+class NetWorthTest extends TestCase
+{
+ /**
+ *
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+ Log::debug(sprintf('Now in %s.', \get_class($this)));
+ }
+
+ /**
+ * @covers \FireflyIII\Helpers\Report\NetWorth
+ */
+ public function testGetNetWorthByCurrency(): void
+ {
+ // variables
+ $accounts = $this->user()->accounts()->take(2)->where('account_type_id', 3)->get();
+ $date = new Carbon('2018-01-01');
+ $balanceInfo = [];
+ foreach ($accounts as $account) {
+ $balanceInfo[$account->id] = '100';
+ }
+
+ // mock repositories
+ $accountRepos = $this->mock(AccountRepositoryInterface::class);
+ $currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
+
+ // mock calls to facades
+ Amount::shouldReceive('getDefaultCurrencyByUser')->once()->andReturn(TransactionCurrency::find(1));
+ Steam::shouldReceive('balancesByAccounts')->once()->withAnyArgs()->andReturn($balanceInfo);
+
+ // mock other calls:
+ $accountRepos->shouldReceive('setUser')->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->times(2)->andReturn('1');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->times(2)->andReturn('defaultAsset');
+ $currencyRepos->shouldReceive('setUser')->once();
+ $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::find(1))->times(1);
+
+
+ $helper = new NetWorth();
+ $helper->setUser($this->user());
+ $result = $helper->getNetWorthByCurrency($accounts, $date);
+
+ $this->assertEquals(200, (int)$result[0]['balance']);
+ }
+
+ /**
+ * @covers \FireflyIII\Helpers\Report\NetWorth
+ */
+ public function testGetNetWorthByCurrencyWithCC(): void
+ {
+ // variables
+ $first = $this->user()->accounts()->take(1)->where('account_type_id', 3)->first();
+ $second = $this->user()->accounts()->take(1)->where('account_type_id', 3)->where('id', '!=', $first->id)->first();
+ $second->virtualBalance = '500';
+ $date = new Carbon('2018-01-01');
+ $balanceInfo = [];
+ $balanceInfo[$first->id] = '100';
+ $balanceInfo[$second->id] = '100';
+
+ // mock repositories
+ $accountRepos = $this->mock(AccountRepositoryInterface::class);
+ $currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
+
+ // mock calls to facades
+ Amount::shouldReceive('getDefaultCurrencyByUser')->once()->andReturn(TransactionCurrency::find(1));
+ Steam::shouldReceive('balancesByAccounts')->once()->withAnyArgs()->andReturn($balanceInfo);
+
+ // mock other calls:
+ $accountRepos->shouldReceive('setUser')->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->times(2)->andReturn('1');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->times(2)->andReturn('defaultAsset', 'ccAsset');
+ $currencyRepos->shouldReceive('setUser')->once();
+ $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::find(1))->times(1);
+
+
+ $helper = new NetWorth();
+ $helper->setUser($this->user());
+ $result = $helper->getNetWorthByCurrency(new Collection([$first, $second]), $date);
+
+ $this->assertEquals(-300, (int)$result[0]['balance']);
+ }
+}
\ No newline at end of file
diff --git a/tests/Unit/Import/Routine/BunqRoutineTest.php b/tests/Unit/Import/Routine/BunqRoutineTest.php
index 32530df53e..b384993c15 100644
--- a/tests/Unit/Import/Routine/BunqRoutineTest.php
+++ b/tests/Unit/Import/Routine/BunqRoutineTest.php
@@ -63,9 +63,9 @@ class BunqRoutineTest extends TestCase
$handler->shouldReceive('setImportJob')->once();
$handler->shouldReceive('run')->once();
$handler->shouldReceive('getTransactions')->once()->andReturn(['a' => 'c']);
- $repository->shouldReceive('setStatus')->withArgs([Mockery::any(), 'provider_finished'])->once();
- $repository->shouldReceive('setStage')->withArgs([Mockery::any(), 'final'])->once();
- $repository->shouldReceive('setTransactions')->withArgs([Mockery::any(), ['a' => 'c']])->once();
+ //$repository->shouldReceive('setStatus')->withArgs([Mockery::any(), 'provider_finished'])->once();
+ //$repository->shouldReceive('setStage')->withArgs([Mockery::any(), 'final'])->once();
+ $repository->shouldReceive('appendTransactions')->withArgs([Mockery::any(), ['a' => 'c']])->once();
$routine = new BunqRoutine;
$routine->setImportJob($job);
diff --git a/tests/Unit/Support/Import/Routine/Bunq/StageImportDataHandlerTest.php b/tests/Unit/Support/Import/Routine/Bunq/StageImportDataHandlerTest.php
index ab66906612..91b7efa50f 100644
--- a/tests/Unit/Support/Import/Routine/Bunq/StageImportDataHandlerTest.php
+++ b/tests/Unit/Support/Import/Routine/Bunq/StageImportDataHandlerTest.php
@@ -172,9 +172,16 @@ class StageImportDataHandlerTest extends TestCase
->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();
+ $lastPref = new Preference;
+ $lastPref->data = 0;
+ Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-oldest-transaction-1234', 0])->andReturn($lastPref)->times(2);
+
+ $lastPref = new Preference;
+ $lastPref->data = 0;
+ Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-newest-transaction-1234', 0])->andReturn($lastPref)->once();
+
+ // todo: improve test thing:
+ Preferences::shouldReceive('setForUser');
$handler = new StageImportDataHandler;
@@ -239,9 +246,16 @@ class StageImportDataHandlerTest extends TestCase
$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();
+ $lastPref = new Preference;
+ $lastPref->data = 0;
+ Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-oldest-transaction-1234', 0])->andReturn($lastPref)->times(2);
+
+ $lastPref = new Preference;
+ $lastPref->data = 0;
+ Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-newest-transaction-1234', 0])->andReturn($lastPref)->once();
+
+ // todo: improve test thing:
+ Preferences::shouldReceive('setForUser');
$handler = new StageImportDataHandler;
$handler->setImportJob($job);
@@ -290,9 +304,16 @@ class StageImportDataHandlerTest extends TestCase
$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();
+ $lastPref = new Preference;
+ $lastPref->data = 0;
+ Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-oldest-transaction-1234', 0])->andReturn($lastPref)->times(2);
+
+ $lastPref = new Preference;
+ $lastPref->data = 0;
+ Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-newest-transaction-1234', 0])->andReturn($lastPref)->once();
+
+ // todo: improve test thing:
+ Preferences::shouldReceive('setForUser');
// ignore the deprecated fields:
@@ -447,9 +468,9 @@ class StageImportDataHandlerTest extends TestCase
$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();
+ $lastPref = new Preference;
+ $lastPref->data = 0;
+ Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-oldest-transaction-1234', 0])->andReturn($lastPref)->once();
$expectedTransactions = [
[
@@ -510,6 +531,18 @@ class StageImportDataHandlerTest extends TestCase
$accountRepository->shouldReceive('findByIbanNull')->withArgs(['RS88844660406878687897', [AccountType::ASSET]])->once()->andReturn($asset);
+ // set new last transaction ID:
+ $lastPref = new Preference;
+ $lastPref->data = 0;
+ Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-oldest-transaction-1234', 0])->andReturn($lastPref)->times(1);
+
+ $lastPref = new Preference;
+ $lastPref->data = 0;
+ Preferences::shouldReceive('getForUser')->withArgs([Mockery::any(), 'bunq-newest-transaction-1234', 0])->andReturn($lastPref)->once();
+
+ // todo: improve test thing:
+ Preferences::shouldReceive('setForUser');
+
$handler = new StageImportDataHandler;
$handler->setImportJob($job);
try {