diff --git a/resources/views/profile/localization-form.blade.php b/resources/views/profile/localization-form.blade.php
index 1af652a..2e3bffd 100644
--- a/resources/views/profile/localization-form.blade.php
+++ b/resources/views/profile/localization-form.blade.php
@@ -40,7 +40,7 @@ new class extends Component
$this->validate();
- $this->user->options = array_merge($this->user->options ?? [], [
+ $this->user->setOption([
'locale' => $this->locale,
'display_currency' => $this->display_currency,
]);
@@ -51,7 +51,7 @@ new class extends Component
$this->dispatch('saved');
- //$this->js('window.location.reload();');
+ // $this->js('window.location.reload();');
}
}; ?>
diff --git a/tests/0000_00_00_import_configs_test.xlsx b/tests/0000_00_00_import_configs_test.xlsx
new file mode 100644
index 0000000..3253936
Binary files /dev/null and b/tests/0000_00_00_import_configs_test.xlsx differ
diff --git a/tests/0000_00_00_import_multi_curr_test.xlsx b/tests/0000_00_00_import_multi_curr_test.xlsx
new file mode 100644
index 0000000..651cc5a
Binary files /dev/null and b/tests/0000_00_00_import_multi_curr_test.xlsx differ
diff --git a/tests/0000_00_00_import_test.xlsx b/tests/0000_00_00_import_test.xlsx
index a58b90c..36b9a1e 100644
Binary files a/tests/0000_00_00_import_test.xlsx and b/tests/0000_00_00_import_test.xlsx differ
diff --git a/tests/DailyChangeTest.php b/tests/DailyChangeTest.php
index 81bc9ef..d55381a 100644
--- a/tests/DailyChangeTest.php
+++ b/tests/DailyChangeTest.php
@@ -198,4 +198,52 @@ class DailyChangeTest extends TestCase
$this->assertEqualsWithDelta($total_dividends, $last_dividend_change->total_dividends_earned, 0.01);
}
+
+ public function test_daily_changes_synced_into_past_for_older_transactions(): void
+ {
+ $this->actingAs($user = User::factory()->create());
+
+ $portfolio = Portfolio::factory()->create();
+
+ // 1. test daily change will fill to the date of first transaction
+ $first_transaction = Transaction::factory(5)->buy()->lastMonth()->portfolio($portfolio->id)->symbol('AAPL')->create();
+
+ $portfolio->syncDailyChanges();
+
+ $first_date = DailyChange::min('date');
+
+ $this->assertEquals($first_transaction->min('date')->toDateString(), $first_date);
+
+ // 2. test daily change will fill when new transaction pre-dates earliest daily change
+ config()->set('app.env', 'local');
+ $this->withoutDefer();
+
+ $second_transaction = Transaction::create([
+ 'symbol' => 'AAPL',
+ 'portfolio_id' => $portfolio->id,
+ 'date' => now()->subYears(3),
+ 'quantity' => 1,
+ 'cost_basis' => 39.89,
+ 'transaction_type' => 'BUY',
+ ]);
+
+ $second_date = DailyChange::min('date');
+
+ $this->assertEquals($second_transaction->date->toDateString(), $second_date);
+
+ // 3. test daily change will fill when new transaction is between earliest daily change and earliest transaction
+ $third_transaction = Transaction::create([
+ 'symbol' => 'AAPL',
+ 'portfolio_id' => $portfolio->id,
+ 'date' => now()->subYears(1),
+ 'quantity' => 1,
+ 'cost_basis' => 39.89,
+ 'transaction_type' => 'BUY',
+ ]);
+
+ $daily_change_day_after = DailyChange::withDailyPerformance()->whereDate('daily_change.date', $third_transaction->date->addDay())->first();
+ $daily_change_day_before = DailyChange::withDailyPerformance()->whereDate('daily_change.date', $third_transaction->date->subDay())->first();
+
+ $this->assertEquals(39.89, $daily_change_day_after->total_cost_basis - $daily_change_day_before->total_cost_basis);
+ }
}
diff --git a/tests/ImportExportTest.php b/tests/ImportExportTest.php
index 1109d4e..9c87469 100644
--- a/tests/ImportExportTest.php
+++ b/tests/ImportExportTest.php
@@ -6,6 +6,8 @@ namespace Tests;
use App\Exports\BackupExport;
use App\Models\BackupImport as BackupImportModel;
+use App\Models\Holding;
+use App\Models\Portfolio;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
@@ -15,62 +17,89 @@ class ImportExportTest extends TestCase
{
use RefreshDatabase;
- // todo: need to fix import export
+ public function test_can_create_exports(): void
+ {
+ Excel::fake();
- // public function test_can_create_exports(): void
- // {
- // Excel::fake();
+ $this->actingAs($user = User::factory()->create());
- // $this->actingAs($user = User::factory()->create());
+ Transaction::factory(5)->buy()->lastYear()->symbol('AAPL')->create();
- // Transaction::factory(5)->buy()->lastYear()->symbol('AAPL')->create();
+ Excel::download(new BackupExport, now()->format('Y_m_d').'_investbrain_backup.xlsx');
- // Excel::download(new BackupExport, now()->format('Y_m_d').'_investbrain_backup.xlsx');
+ Excel::assertDownloaded(now()->format('Y_m_d').'_investbrain_backup.xlsx', function (BackupExport $export) {
+ return true;
+ });
+ }
- // Excel::assertDownloaded(now()->format('Y_m_d').'_investbrain_backup.xlsx', function (BackupExport $export) {
- // return true;
- // });
- // }
+ public function test_import_job_completes(): void
+ {
+ $this->actingAs($user = User::factory()->create());
- // public function test_backup_job_completes(): void
- // {
- // $this->actingAs($user = User::factory()->create());
+ $import_job = BackupImportModel::create([
+ 'user_id' => auth()->user()->id,
+ 'path' => __DIR__.'/0000_00_00_import_test.xlsx',
+ ]);
- // $backup_job = BackupImportModel::create([
- // 'user_id' => auth()->user()->id,
- // 'path' => __DIR__.'/0000_00_00_import_test.xlsx',
- // ]);
+ $import_job->refresh();
- // $backup_job->refresh();
+ $this->assertEquals('success', $import_job->status);
+ }
- // $this->assertEquals('success', $backup_job->status);
- // }
+ public function test_import_job_inserts_rows(): void
+ {
+ $this->actingAs($user = User::factory()->create());
- // public function test_backup_job_inserts_rows(): void
- // {
- // $this->actingAs($user = User::factory()->create());
+ BackupImportModel::create([
+ 'user_id' => auth()->user()->id,
+ 'path' => __DIR__.'/0000_00_00_import_test.xlsx',
+ ]);
- // BackupImportModel::create([
- // 'user_id' => auth()->user()->id,
- // 'path' => __DIR__.'/0000_00_00_import_test.xlsx',
- // ]);
+ $this->assertEquals(3, $user->transactions->count());
+ }
- // $this->assertEquals(3, $user->transactions->count());
- // }
+ public function test_import_job_calculates_correct_holding_data(): void
+ {
+ $this->actingAs($user = User::factory()->create());
- // public function test_backup_job_calculates_correct_holding_data(): void
- // {
- // $this->actingAs($user = User::factory()->create());
+ BackupImportModel::create([
+ 'user_id' => auth()->user()->id,
+ 'path' => __DIR__.'/0000_00_00_import_test.xlsx',
+ ]);
- // BackupImportModel::create([
- // 'user_id' => auth()->user()->id,
- // 'path' => __DIR__.'/0000_00_00_import_test.xlsx',
- // ]);
+ $holding = $user->holdings->first();
- // $holding = $user->holdings->first();
+ $this->assertEquals('AAPL', $holding->symbol);
+ $this->assertEquals(6, $holding->quantity);
+ $this->assertEqualsWithDelta(233.33, $holding->average_cost_basis, 0.01);
+ }
- // $this->assertEquals('AAPL', $holding->symbol);
- // $this->assertEquals(6, $holding->quantity);
- // $this->assertEqualsWithDelta(233.33, $holding->average_cost_basis, 0.01);
- // }
+ public function test_configurations_are_set_on_import(): void
+ {
+ $this->actingAs($user = User::factory()->create());
+
+ Portfolio::create([
+ 'id' => '9e792bb8-94e7-4ed3-b8cc-43b50d34c337',
+ 'title' => 'Test Portfolio',
+ ]);
+
+ $holding = Holding::create([
+ 'id' => '9cf8a662-7347-49fb-b9de-0cc1430a8d1f',
+ 'portfolio_id' => '9e792bb8-94e7-4ed3-b8cc-43b50d34c337',
+ 'symbol' => 'ACME',
+ 'quantity' => 0,
+ 'reinvest_dividends' => false,
+ ]);
+
+ $this->assertEquals(false, $holding->reinvest_dividends);
+
+ BackupImportModel::create([
+ 'user_id' => auth()->user()->id,
+ 'path' => __DIR__.'/0000_00_00_import_configs_test.xlsx',
+ ]);
+
+ $holding->refresh();
+
+ $this->assertEquals(true, $holding->reinvest_dividends);
+ }
}
diff --git a/tests/MultiCurrencyTest.php b/tests/MultiCurrencyTest.php
index 33e9d7d..621d355 100644
--- a/tests/MultiCurrencyTest.php
+++ b/tests/MultiCurrencyTest.php
@@ -6,6 +6,7 @@ namespace Tests;
use App\Interfaces\MarketData\FakeMarketData;
use App\Interfaces\MarketData\Types\Quote;
+use App\Models\BackupImport;
use App\Models\Currency;
use App\Models\CurrencyRate;
use App\Models\DailyChange;
@@ -549,4 +550,46 @@ class MultiCurrencyTest extends TestCase
$this->assertEqualsWithDelta($metrics->get('realized_gain_dollars'), $dailyChange->last()->realized_gain_dollars, 0.01);
$this->assertEqualsWithDelta($metrics->get('total_market_value') - $metrics->get('total_cost_basis'), $dailyChange->last()->total_gain, 0.01);
}
+
+ public function test_multi_currency_import_calculates_correct_holding_data(): void
+ {
+ $this->actingAs($user = User::factory()->create());
+
+ Frankfurter::expects('setSymbols')
+ ->zeroOrMoreTimes()
+ ->andReturnSelf();
+ Frankfurter::expects('timeSeries')
+ ->zeroOrMoreTimes()
+ ->andReturn(['rates' => [
+ now()->subDays(3)->toDateString() => [
+ 'ZZZ' => .01,
+ ],
+ now()->subDays(2)->toDateString() => [
+ 'ZZZ' => .01,
+ ],
+ now()->subDays(1)->toDateString() => [
+ 'ZZZ' => .01,
+ ],
+ now()->toDateString() => [
+ 'ZZZ' => .01,
+ ],
+ ]]);
+ Frankfurter::expects('historical')
+ ->zeroOrMoreTimes()
+ ->andReturn([
+ 'rates' => [
+ 'GBP' => .89,
+ ],
+ ]);
+
+ BackupImport::create([
+ 'user_id' => auth()->user()->id,
+ 'path' => __DIR__.'/0000_00_00_import_multi_curr_test.xlsx',
+ ]);
+
+ $this->assertContains('AAPL', $user->holdings->pluck('symbol'));
+ $this->assertContains('BP.L', $user->holdings->pluck('symbol'));
+ $this->assertEquals(17, $user->holdings->sum('quantity'));
+ $this->assertEqualsWithDelta(371.42, $user->holdings->sum('average_cost_basis'), 0.01);
+ }
}