adds passing tests

This commit is contained in:
hackerESQ
2024-09-06 21:59:58 -05:00
parent 0baecaefaf
commit d442bbb397
6 changed files with 210 additions and 62 deletions
+15 -7
View File
@@ -19,14 +19,18 @@ class TransactionFactory extends Factory
*/ */
public function definition(): array public function definition(): array
{ {
$transaction_type = $this->faker->randomElement(['BUY', 'SELL']);
return [ return [
'symbol' => $this->faker->randomElement(['AAPL', 'GOOGL', 'AMZN']), 'symbol' => $this->faker->randomElement(['AAPL', 'GOOG', 'AMZN']),
'transaction_type' => static::$transaction_type = $this->faker->randomElement(['BUY', 'SELL']), 'transaction_type' => $transaction_type,
'portfolio_id' => Portfolio::factory()->create(), 'portfolio_id' => Portfolio::factory()->create()->id,
'date' => $this->faker->date('Y-m-d'), 'date' => $this->faker->date('Y-m-d'),
'quantity' => $this->faker->randomFloat(2, 1, 100), 'quantity' => 1,
'cost_basis' => $this->faker->randomFloat(2, 10, 500), 'cost_basis' => $transaction_type == 'BUY'
'sale_price' => static::$transaction_type == 'SELL' ? $this->faker->randomFloat(2, 10, 500)
: null,
'sale_price' => $transaction_type == 'SELL'
? $this->faker->randomFloat(2, 10, 500) ? $this->faker->randomFloat(2, 10, 500)
: null, : null,
]; ];
@@ -39,7 +43,7 @@ class TransactionFactory extends Factory
]); ]);
} }
public function portfolios($portfolio_id): static public function portfolio($portfolio_id): static
{ {
return $this->state(fn (array $attributes) => [ return $this->state(fn (array $attributes) => [
'portfolio_id' => $portfolio_id, 'portfolio_id' => $portfolio_id,
@@ -50,6 +54,8 @@ class TransactionFactory extends Factory
{ {
return $this->state(fn (array $attributes) => [ return $this->state(fn (array $attributes) => [
'transaction_type' => 'BUY', 'transaction_type' => 'BUY',
'cost_basis' => $this->faker->randomFloat(2, 10, 500),
'sale_price' => null
]); ]);
} }
@@ -57,6 +63,8 @@ class TransactionFactory extends Factory
{ {
return $this->state(fn (array $attributes) => [ return $this->state(fn (array $attributes) => [
'transaction_type' => 'SELL', 'transaction_type' => 'SELL',
'sale_price' => $this->faker->randomFloat(2, 10, 500),
'cost_basis' => null,
]); ]);
} }
} }
+1
View File
@@ -26,5 +26,6 @@
<env name="QUEUE_CONNECTION" value="sync"/> <env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/> <env name="TELESCOPE_ENABLED" value="false"/>
<env name="MARKET_DATA_PROVIDER" value="fake"/>
</php> </php>
</phpunit> </phpunit>
+56
View File
@@ -0,0 +1,56 @@
<?php
namespace Tests;
use Tests\TestCase;
use App\Models\User;
use App\Models\Portfolio;
use App\Models\DailyChange;
use App\Models\Transaction;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Foundation\Testing\RefreshDatabase;
class CaptureDailyChangeTest extends TestCase
{
use RefreshDatabase;
public function setUp(): void
{
parent::setUp();
$this->actingAs($user = User::factory()->create());
$this->portfolio = Portfolio::factory()->create();
Transaction::factory(5)->buy()->portfolio($this->portfolio->id)->symbol('AAPL')->create();
$this->transaction = Transaction::factory()->sell()->portfolio($this->portfolio->id)->symbol('AAPL')->create();
}
/**
*/
public function test_daily_change_for_portfolios()
{
// Run the command
Artisan::call('daily-change:capture');
// Assert the daily change was captured for the portfolio
$this->assertDatabaseHas('daily_change', [
'portfolio_id' => $this->portfolio->id,
]);
$output = Artisan::output();
$this->assertStringContainsString('Capturing daily change for', $output);
$daily_change = DailyChange::where([
'portfolio_id' => $this->portfolio->id,
])->get();
$this->assertCount(1, $daily_change);
$this->assertEqualsWithDelta(
$this->transaction->sale_price - $this->transaction->cost_basis,
$daily_change->first()->realized_gains,
0.01
);
}
}
+77
View File
@@ -0,0 +1,77 @@
<?php
namespace Tests;
use Tests\TestCase;
use App\Models\User;
use App\Models\Holding;
use App\Models\Portfolio;
use App\Models\Transaction;
use Illuminate\Foundation\Testing\RefreshDatabase;
class DashboardTest extends TestCase
{
use RefreshDatabase;
/**
*/
public function test_user_has_portfolios(): void
{
$user = User::factory()->create();
$this->actingAs($user);
Portfolio::factory(5)->create();
$this->assertCount(5, $user->portfolios);
}
/**
*/
public function test_user_has_transactions(): void
{
$user = User::factory()->create();
$this->actingAs($user);
Transaction::factory(10)->create();
$this->assertCount(10, $user->transactions);
}
/**
*/
public function test_user_has_holdings(): void
{
$user = User::factory()->create();
$this->actingAs($user);
$portfolio = Portfolio::factory()->create();
Transaction::factory(5)->symbol('AAPL')->portfolio($portfolio->id)->create();
$this->assertCount(1, $user->holdings);
}
/**
*/
public function test_user_has_dashboard_metrics(): void
{
$user = User::factory()->create();
$this->actingAs($user);
$portfolio = Portfolio::factory()->create();
Transaction::factory(5)->buy()->portfolio($portfolio->id)->symbol('AAPL')->create();
$transaction = Transaction::factory()->sell()->portfolio($portfolio->id)->symbol('AAPL')->create();
$metrics = Holding::query()
->myHoldings()
->withPortfolioMetrics()
->first();
$this->assertEqualsWithDelta(
$transaction->sale_price - $transaction->cost_basis,
$metrics->realized_gain_dollars,
0.01
);
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ abstract class TestCase extends BaseTestCase
{ {
parent::setUp(); parent::setUp();
Artisan::call('migrate'); //
} }
protected function tearDown(): void protected function tearDown(): void
+48 -42
View File
@@ -2,72 +2,78 @@
namespace Tests; namespace Tests;
use Tests\TestCase;
use App\Models\User; use App\Models\User;
use App\Models\Holding;
use App\Models\Portfolio; use App\Models\Portfolio;
use App\Models\Transaction; use App\Models\Transaction;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
class TransactionsTest extends TestCase class TransactionsTest extends TestCase
{ {
use RefreshDatabase; use RefreshDatabase;
/** /**
* A basic test example.
*/ */
public function test_can_create_a_transaction(): void public function test_can_create_a_transaction(): void
{ {
$user = User::factory()->create(); $this->actingAs($user = User::factory()->create());
$this->actingAs($user);
$transactions = Transaction::factory()->create(); $transaction = Transaction::factory()->create();
}
$this->assertNotNull($transaction);
} }
/**
*/
public function test_sales_calculate_cost_basis(): void
{
$this->actingAs($user = User::factory()->create());
Transaction::factory(5)->buy()->symbol('AAPL')->create();
$transaction = Transaction::factory()->sell()->symbol('AAPL')->create();
// static::saving(function ($transaction) { $this->assertNotNull($transaction->cost_basis);
}
// if ($transaction->transaction_type == 'SELL') { /**
*/
public function test_purchases_dont_have_sale_price(): void
{
$this->actingAs($user = User::factory()->create());
// $transaction->ensureCostBasisIsAddedToSale(); $transaction = Transaction::factory()->buy()->create();
// }
// });
// static::saved(function ($transaction) { $this->assertNull($transaction->sale_price);
}
// $transaction->syncToHolding(); /**
*/
public function test_transaction_synced_to_holding(): void
{
$this->actingAs($user = User::factory()->create());
// $transaction->refreshMarketData(); $portfolio = Portfolio::factory()->create();
// cache()->tags(['metrics', $transaction->portfolio_id])->flush(); Transaction::factory(5)->buy()->portfolio($portfolio->id)->symbol('AAPL')->create();
// }); $transaction = Transaction::factory()->sell()->portfolio($portfolio->id)->symbol('AAPL')->create();
// public function update() $this->assertDatabaseHas('holdings', [
// { 'portfolio_id' => $portfolio->id,
'symbol' => 'AAPL',
'quantity' => 4
]);
// $this->transaction->update($this->validate()); $holding = Holding::where([
// // $this->transaction->owner_id = auth()->user()->id; 'portfolio_id' => $portfolio->id,
// $this->transaction->save(); 'symbol' => 'AAPL'
])->first();
// $this->success(__('Transaction updated')); $this->assertEqualsWithDelta(
$holding->realized_gain_dollars,
// $this->dispatch('toggle-manage-transaction'); $transaction->sale_price - $transaction->cost_basis,
// $this->dispatch('transaction-updated'); 0.01
// } );
}
// public function save() }
// {
// $validated = $this->validate();
// if (!isset($this->portfolio)) {
// $this->portfolio = Portfolio::find($this->portfolio_id);
// }
// $transaction = $this->portfolio->transactions()->create($validated);
// $transaction->save();
// $this->dispatch('transaction-saved');
// $this->success(__('Transaction created'), redirectTo: route('holding.show', ['portfolio' => $this->portfolio->id, 'symbol' => $this->symbol]));
// }