chore: code style
This commit is contained in:
+10
-10
@@ -2,18 +2,19 @@
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Holding;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class HoldingsTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected User $user;
|
||||
|
||||
protected Portfolio $portfolio;
|
||||
|
||||
protected function setUp(): void
|
||||
@@ -29,14 +30,14 @@ class HoldingsTest extends TestCase
|
||||
$this->actingAs($this->user);
|
||||
|
||||
Transaction::factory(10)->create();
|
||||
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->getJson(route('api.holding.index', ['page' => 1, 'itemsPerPage' => 5]))
|
||||
->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [['id', 'symbol', 'portfolio_id', 'total_market_value', 'dividends_earned']],
|
||||
'meta' => ['current_page', 'last_page', 'total'],
|
||||
'links' => ['first', 'last', 'prev', 'next']
|
||||
'links' => ['first', 'last', 'prev', 'next'],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -45,7 +46,7 @@ class HoldingsTest extends TestCase
|
||||
// create transactions with existing user
|
||||
$this->actingAs($this->user);
|
||||
Transaction::factory(10)->create();
|
||||
|
||||
|
||||
// Create a new user
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
Transaction::factory(1)->create();
|
||||
@@ -88,14 +89,14 @@ class HoldingsTest extends TestCase
|
||||
$transaction = Transaction::factory()->create();
|
||||
|
||||
$data = [
|
||||
'reinvest_dividends' => true
|
||||
'reinvest_dividends' => true,
|
||||
];
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->putJson(route('api.holding.update', ['portfolio' => $transaction->portfolio_id, 'symbol' => $transaction->symbol]), $data)
|
||||
->assertOk()
|
||||
->assertJsonFragment([
|
||||
'reinvest_dividends' => true
|
||||
'reinvest_dividends' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -105,7 +106,7 @@ class HoldingsTest extends TestCase
|
||||
$transaction = Transaction::factory()->create();
|
||||
|
||||
$data = [
|
||||
'reinvest_dividends' => true
|
||||
'reinvest_dividends' => true,
|
||||
];
|
||||
|
||||
$otherUser = User::factory()->create();
|
||||
@@ -113,5 +114,4 @@ class HoldingsTest extends TestCase
|
||||
->putJson(route('api.holding.update', ['portfolio' => $transaction->portfolio_id, 'symbol' => $transaction->symbol]), $data)
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class PortfoliosTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected User $user;
|
||||
|
||||
protected Portfolio $portfolio;
|
||||
|
||||
protected function setUp(): void
|
||||
@@ -27,14 +28,14 @@ class PortfoliosTest extends TestCase
|
||||
$this->actingAs($this->user);
|
||||
|
||||
Portfolio::factory(10)->create();
|
||||
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->getJson(route('api.portfolio.index', ['page' => 1, 'itemsPerPage' => 5]))
|
||||
->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [['id', 'title', 'owner', 'holdings', 'transactions']],
|
||||
'meta' => ['current_page', 'last_page', 'total'],
|
||||
'links' => ['first', 'last', 'prev', 'next']
|
||||
'links' => ['first', 'last', 'prev', 'next'],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -43,7 +44,7 @@ class PortfoliosTest extends TestCase
|
||||
// create portfolios with existing user
|
||||
$this->actingAs($this->user);
|
||||
Portfolio::factory(10)->create();
|
||||
|
||||
|
||||
// Create a new user
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
Portfolio::factory(1)->create();
|
||||
@@ -61,12 +62,12 @@ class PortfoliosTest extends TestCase
|
||||
public function test_can_create_a_portfolio()
|
||||
{
|
||||
$data = Portfolio::factory()->make()->toArray();
|
||||
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->postJson(route('api.portfolio.store'), $data)
|
||||
->assertCreated()
|
||||
->assertJsonStructure(['id', 'title', 'owner']);
|
||||
|
||||
|
||||
$this->assertDatabaseHas('portfolios', ['title' => $data['title']]);
|
||||
}
|
||||
|
||||
@@ -102,12 +103,12 @@ class PortfoliosTest extends TestCase
|
||||
|
||||
$this->actingAs($this->user);
|
||||
$portfolio = Portfolio::factory()->create();
|
||||
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->putJson(route('api.portfolio.update', $portfolio), $updatedData)
|
||||
->assertOk()
|
||||
->assertJson($updatedData);
|
||||
|
||||
|
||||
$this->assertDatabaseHas('portfolios', $updatedData);
|
||||
}
|
||||
|
||||
@@ -126,7 +127,7 @@ class PortfoliosTest extends TestCase
|
||||
->putJson(route('api.portfolio.update', $portfolio), ['title' => 'A brand new updated title'])
|
||||
->assertOk()
|
||||
->assertJsonFragment([
|
||||
'title' => 'A brand new updated title'
|
||||
'title' => 'A brand new updated title',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -185,7 +186,7 @@ class PortfoliosTest extends TestCase
|
||||
$this->actingAs($this->user)
|
||||
->deleteJson(route('api.portfolio.destroy', $portfolio))
|
||||
->assertNoContent();
|
||||
|
||||
|
||||
$this->assertDatabaseMissing('portfolios', ['id' => $portfolio->id]);
|
||||
}
|
||||
|
||||
@@ -199,4 +200,4 @@ class PortfoliosTest extends TestCase
|
||||
->deleteJson(route('api.portfolio.destroy', $portfolio))
|
||||
->assertForbidden();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,18 @@
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class TransactionsTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected User $user;
|
||||
|
||||
protected Portfolio $portfolio;
|
||||
|
||||
protected function setUp(): void
|
||||
@@ -21,7 +22,7 @@ class TransactionsTest extends TestCase
|
||||
|
||||
// make user
|
||||
$this->user = User::factory()->create();
|
||||
|
||||
|
||||
// make portfolio
|
||||
$this->portfolio = Portfolio::factory()->makeOne();
|
||||
$this->portfolio->setOwnerIdAttribute($this->user->id);
|
||||
@@ -33,14 +34,14 @@ class TransactionsTest extends TestCase
|
||||
$this->actingAs($this->user);
|
||||
|
||||
Transaction::factory(10)->create();
|
||||
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->getJson(route('api.transaction.index', ['page' => 1, 'itemsPerPage' => 5]))
|
||||
->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [['id', 'symbol', 'transaction_type', 'portfolio_id', 'date']],
|
||||
'meta' => ['current_page', 'last_page', 'total'],
|
||||
'links' => ['first', 'last', 'prev', 'next']
|
||||
'links' => ['first', 'last', 'prev', 'next'],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -49,7 +50,7 @@ class TransactionsTest extends TestCase
|
||||
// create transactions with existing user
|
||||
$this->actingAs($this->user);
|
||||
Transaction::factory(10)->create();
|
||||
|
||||
|
||||
// Create a new user
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
Transaction::factory(1)->create();
|
||||
@@ -88,7 +89,7 @@ class TransactionsTest extends TestCase
|
||||
'quantity',
|
||||
'date',
|
||||
'cost_basis',
|
||||
'sale_price'
|
||||
'sale_price',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -97,7 +98,7 @@ class TransactionsTest extends TestCase
|
||||
$this->actingAs($this->user)
|
||||
->postJson(route('api.transaction.store'), [
|
||||
'portfolio_id' => $this->portfolio->id,
|
||||
'symbol' => null
|
||||
'symbol' => null,
|
||||
])
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['symbol']);
|
||||
@@ -133,7 +134,7 @@ class TransactionsTest extends TestCase
|
||||
'symbol' => 'ZZZ',
|
||||
'transaction_type' => 'BUY',
|
||||
'cost_basis' => 200.19,
|
||||
'quantity' => 5
|
||||
'quantity' => 5,
|
||||
];
|
||||
|
||||
$this->actingAs($this->user)
|
||||
@@ -162,7 +163,7 @@ class TransactionsTest extends TestCase
|
||||
->putJson(route('api.transaction.update', $transaction), ['symbol' => 'ZZZ'])
|
||||
->assertOk()
|
||||
->assertJsonFragment([
|
||||
'symbol' => 'ZZZ'
|
||||
'symbol' => 'ZZZ',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -198,4 +199,4 @@ class TransactionsTest extends TestCase
|
||||
->deleteJson(route('api.transaction.destroy', $transaction))
|
||||
->assertForbidden();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Support\Str;
|
||||
use Laravel\Jetstream\Features;
|
||||
use Laravel\Jetstream\Http\Livewire\ApiTokenManager;
|
||||
use Livewire\Livewire;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ApiTokenPermissionsTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Tests;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AuthenticationTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@ use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Laravel\Jetstream\Http\Livewire\LogoutOtherBrowserSessionsForm;
|
||||
use Livewire\Livewire;
|
||||
use Tests\TestCase;
|
||||
|
||||
class BrowserSessionsTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -2,19 +2,18 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\DailyChange;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
class CaptureDailyChangeTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
@@ -25,8 +24,6 @@ class CaptureDailyChangeTest extends TestCase
|
||||
$this->transaction = Transaction::factory()->sell()->lastMonth()->portfolio($this->portfolio->id)->symbol('AAPL')->create();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_daily_change_for_portfolios()
|
||||
{
|
||||
// Run the command
|
||||
@@ -47,10 +44,10 @@ class CaptureDailyChangeTest extends TestCase
|
||||
$this->assertCount(1, $daily_change);
|
||||
|
||||
$this->assertEqualsWithDelta(
|
||||
$this->transaction->sale_price - $this->transaction->cost_basis,
|
||||
$this->transaction->sale_price - $this->transaction->cost_basis,
|
||||
$daily_change->first()->realized_gains,
|
||||
0.01
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Http\Controllers\ConnectedAccountController;
|
||||
use App\Models\ConnectedAccount;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use App\Http\Controllers\ConnectedAccountController;
|
||||
|
||||
class ConnectedAccountTest extends TestCase
|
||||
{
|
||||
@@ -19,7 +18,7 @@ class ConnectedAccountTest extends TestCase
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->controller = new ConnectedAccountController();
|
||||
$this->controller = new ConnectedAccountController;
|
||||
}
|
||||
|
||||
public function test_handle_provider_callback_with_already_connected_account()
|
||||
@@ -33,7 +32,7 @@ class ConnectedAccountTest extends TestCase
|
||||
'email' => 'alice@example.com',
|
||||
'email_verified_at' => now(),
|
||||
]);
|
||||
$providerUser = (object)[
|
||||
$providerUser = (object) [
|
||||
'id' => '67890',
|
||||
'name' => 'Alice Smith',
|
||||
'email' => 'alice@example.com',
|
||||
@@ -47,9 +46,9 @@ class ConnectedAccountTest extends TestCase
|
||||
'provider_id' => $providerUser->id,
|
||||
'user_id' => $user->id,
|
||||
'token' => $providerUser->token,
|
||||
'verified_at' => now()
|
||||
'verified_at' => now(),
|
||||
]);
|
||||
|
||||
|
||||
Socialite::shouldReceive('driver')
|
||||
->with($provider)
|
||||
->andReturnSelf()
|
||||
@@ -68,7 +67,7 @@ class ConnectedAccountTest extends TestCase
|
||||
{
|
||||
$provider = 'github';
|
||||
config(['services.enabled_login_providers' => 'github,google']);
|
||||
$providerUser = (object)[
|
||||
$providerUser = (object) [
|
||||
'id' => '12345',
|
||||
'name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
@@ -109,7 +108,7 @@ class ConnectedAccountTest extends TestCase
|
||||
'email' => 'jane@example.com',
|
||||
'email_verified_at' => now(),
|
||||
]);
|
||||
$providerUser = (object)[
|
||||
$providerUser = (object) [
|
||||
'id' => '54321',
|
||||
'name' => 'Jane Doe',
|
||||
'email' => 'jane@example.com',
|
||||
@@ -164,5 +163,4 @@ class ConnectedAccountTest extends TestCase
|
||||
$response->assertRedirect(route('dashboard'));
|
||||
$response->assertSessionHas('toast');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-15
@@ -2,19 +2,16 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Holding;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
class DashboardTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_user_has_portfolios(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -24,8 +21,6 @@ class DashboardTest extends TestCase
|
||||
$this->assertCount(5, $user->portfolios);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_user_has_transactions(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -35,8 +30,6 @@ class DashboardTest extends TestCase
|
||||
$this->assertCount(10, $user->transactions);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_user_has_holdings(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -48,22 +41,20 @@ class DashboardTest extends TestCase
|
||||
$this->assertCount(1, $user->holdings);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_user_has_dashboard_metrics(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
|
||||
$portfolio = Portfolio::factory()->create();
|
||||
|
||||
|
||||
Transaction::factory(5)->buy()->lastYear()->portfolio($portfolio->id)->symbol('AAPL')->create();
|
||||
$transaction = Transaction::factory()->sell()->lastMonth()->portfolio($portfolio->id)->symbol('AAPL')->create();
|
||||
|
||||
$metrics = Holding::query()
|
||||
->myHoldings()
|
||||
->withPortfolioMetrics()
|
||||
->first();
|
||||
|
||||
->myHoldings()
|
||||
->withPortfolioMetrics()
|
||||
->first();
|
||||
|
||||
$this->assertEqualsWithDelta(
|
||||
$transaction->sale_price - $transaction->cost_basis,
|
||||
$metrics->realized_gain_dollars,
|
||||
|
||||
@@ -7,7 +7,6 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Laravel\Jetstream\Features;
|
||||
use Laravel\Jetstream\Http\Livewire\DeleteUserForm;
|
||||
use Livewire\Livewire;
|
||||
use Tests\TestCase;
|
||||
|
||||
class DeleteAccountTest extends TestCase
|
||||
{
|
||||
|
||||
+11
-19
@@ -2,31 +2,27 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Split;
|
||||
use App\Models\Holding;
|
||||
use App\Models\Dividend;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\Holding;
|
||||
use App\Models\MarketData;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
class DividendsTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_new_dividends_update_holding(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
|
||||
|
||||
$portfolio = Portfolio::factory()->create();
|
||||
Transaction::factory()->buy()->yearsAgo()->portfolio($portfolio->id)->symbol('ACME')->create();
|
||||
|
||||
$holding = Holding::query()->portfolio($portfolio->id)->symbol('ACME')->first();
|
||||
|
||||
|
||||
$this->assertEquals(0, $holding->dividends_earned);
|
||||
|
||||
Dividend::refreshDividendData('ACME');
|
||||
@@ -36,19 +32,17 @@ class DividendsTest extends TestCase
|
||||
$this->assertEquals(4.95, $holding->dividends_earned);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_new_dividends_are_reinvested(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
|
||||
|
||||
$portfolio = Portfolio::factory()->create();
|
||||
Transaction::factory()->buy()->yearsAgo()->portfolio($portfolio->id)->symbol('ACME')->create();
|
||||
|
||||
$holding = Holding::query()->portfolio($portfolio->id)->symbol('ACME')->first();
|
||||
$holding->reinvest_dividends = true;
|
||||
$holding->save();
|
||||
|
||||
|
||||
$this->assertEquals(0, $holding->dividends_earned);
|
||||
|
||||
Dividend::refreshDividendData('ACME');
|
||||
@@ -56,18 +50,16 @@ class DividendsTest extends TestCase
|
||||
$transactions = Transaction::where(['reinvested_dividend' => true])->symbol('ACME')->portfolio($portfolio->id)->get();
|
||||
|
||||
$market_data = MarketData::symbol('ACME')->first();
|
||||
$dividendsReinvested = $transactions->sum('quantity');
|
||||
$dividendsReinvested = $transactions->sum('quantity');
|
||||
|
||||
$this->assertCount(3, $transactions);
|
||||
$this->assertEqualsWithDelta(4.95, $dividendsReinvested * $market_data->market_value, 0.01);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_do_not_duplicate_recent_dividends(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
|
||||
|
||||
$portfolio = Portfolio::factory()->create();
|
||||
Transaction::factory()->buy()->yearsAgo()->portfolio($portfolio->id)->symbol('ACME')->create();
|
||||
|
||||
@@ -76,9 +68,9 @@ class DividendsTest extends TestCase
|
||||
Dividend::create([
|
||||
'symbol' => 'ACME',
|
||||
'date' => now()->subDay(2),
|
||||
'dividend_amount' => .01
|
||||
'dividend_amount' => .01,
|
||||
]);
|
||||
|
||||
|
||||
Dividend::refreshDividendData('ACME');
|
||||
|
||||
$this->assertCount(1, $holding->dividends);
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Laravel\Fortify\Features;
|
||||
use Tests\TestCase;
|
||||
|
||||
class EmailVerificationTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
<?php
|
||||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Interfaces\MarketData\YahooMarketData;
|
||||
use App\Interfaces\MarketData\FallbackInterface;
|
||||
use App\Interfaces\MarketData\AlphaVantageMarketData;
|
||||
use App\Interfaces\MarketData\FallbackInterface;
|
||||
use App\Interfaces\MarketData\Types\Quote;
|
||||
use App\Interfaces\MarketData\YahooMarketData;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Mockery;
|
||||
|
||||
class FallbackInterfaceTest extends TestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
Log::spy();
|
||||
}
|
||||
|
||||
public function testFallbackToNextProviderOnFailure()
|
||||
public function test_fallback_to_next_provider_on_failure()
|
||||
{
|
||||
config()->set('investbrain.provider', 'yahoo,alphavantage');
|
||||
config()->set('investbrain.interfaces', [
|
||||
@@ -29,16 +28,16 @@ class FallbackInterfaceTest extends TestCase
|
||||
|
||||
$yahooMock = Mockery::mock(YahooMarketData::class);
|
||||
$yahooMock->shouldReceive('quote')
|
||||
->andThrow(new \Exception("Yahoo failed"));
|
||||
->andThrow(new \Exception('Yahoo failed'));
|
||||
|
||||
$alphaMock = Mockery::mock(AlphaVantageMarketData::class);
|
||||
$alphaMock->shouldReceive('quote')
|
||||
->andReturn(new Quote(['market_value' => 10]));
|
||||
->andReturn(new Quote(['market_value' => 10]));
|
||||
|
||||
$this->app->instance(YahooMarketData::class, $yahooMock);
|
||||
$this->app->instance(AlphaVantageMarketData::class, $alphaMock);
|
||||
|
||||
$fallbackInterface = new FallbackInterface();
|
||||
$fallbackInterface = new FallbackInterface;
|
||||
|
||||
$result = $fallbackInterface->quote('ACME');
|
||||
|
||||
@@ -47,7 +46,7 @@ class FallbackInterfaceTest extends TestCase
|
||||
Log::shouldHaveReceived('warning')->with('Failed calling method quote (yahoo): Yahoo failed');
|
||||
}
|
||||
|
||||
public function testAllProvidersFail()
|
||||
public function test_all_providers_fail()
|
||||
{
|
||||
config()->set('investbrain.provider', 'yahoo,alpha');
|
||||
config()->set('investbrain.interfaces', [
|
||||
@@ -57,16 +56,16 @@ class FallbackInterfaceTest extends TestCase
|
||||
|
||||
$yahooMock = Mockery::mock(YahooMarketData::class);
|
||||
$yahooMock->shouldReceive('quote')
|
||||
->andThrow(new \Exception("Yahoo failed"));
|
||||
->andThrow(new \Exception('Yahoo failed'));
|
||||
|
||||
$alphaMock = Mockery::mock(AlphaVantageMarketData::class);
|
||||
$alphaMock->shouldReceive('quote')
|
||||
->andThrow(new \Exception("Alpha failed"));
|
||||
->andThrow(new \Exception('Alpha failed'));
|
||||
|
||||
$this->app->instance(YahooMarketData::class, $yahooMock);
|
||||
$this->app->instance(AlphaVantageMarketData::class, $alphaMock);
|
||||
|
||||
$fallbackInterface = new FallbackInterface();
|
||||
$fallbackInterface = new FallbackInterface;
|
||||
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('Could not get market data: Provider [alpha] is not a valid market data interface.');
|
||||
@@ -76,4 +75,4 @@ class FallbackInterfaceTest extends TestCase
|
||||
Log::shouldHaveReceived('warning')->with('Failed calling method quote (yahoo): Yahoo failed');
|
||||
Log::shouldHaveReceived('warning')->with('Failed calling method quote (alpha): Alpha failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,17 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Transaction;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Exports\BackupExport;
|
||||
use App\Models\BackupImport as BackupImportModel;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
|
||||
class ImportExportTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_can_create_exports(): void
|
||||
{
|
||||
Excel::fake();
|
||||
@@ -24,22 +21,20 @@ class ImportExportTest extends TestCase
|
||||
|
||||
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) {
|
||||
Excel::assertDownloaded(now()->format('Y_m_d').'_investbrain_backup.xlsx', function (BackupExport $export) {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_backup_job_completes(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
|
||||
$backup_job = BackupImportModel::create([
|
||||
'user_id' => auth()->user()->id,
|
||||
'path' => __DIR__.'/0000_00_00_import_test.xlsx'
|
||||
'path' => __DIR__.'/0000_00_00_import_test.xlsx',
|
||||
]);
|
||||
|
||||
$backup_job->refresh();
|
||||
@@ -47,29 +42,25 @@ class ImportExportTest extends TestCase
|
||||
$this->assertEquals('success', $backup_job->status);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
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'
|
||||
'path' => __DIR__.'/0000_00_00_import_test.xlsx',
|
||||
]);
|
||||
|
||||
$this->assertEquals(3, $user->transactions->count());
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
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'
|
||||
'path' => __DIR__.'/0000_00_00_import_test.xlsx',
|
||||
]);
|
||||
|
||||
$holding = $user->holdings->first();
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Tests;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class PasswordConfirmationTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -7,7 +7,6 @@ use Illuminate\Auth\Notifications\ResetPassword;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Laravel\Fortify\Features;
|
||||
use Tests\TestCase;
|
||||
|
||||
class PasswordResetTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -2,27 +2,29 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\User;
|
||||
use App\Policies\PortfolioPolicy;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class PortfolioPolicyTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected $policy;
|
||||
|
||||
protected $owner;
|
||||
|
||||
protected $user;
|
||||
|
||||
protected $portfolio;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->policy = new PortfolioPolicy();
|
||||
$this->policy = new PortfolioPolicy;
|
||||
|
||||
$this->owner = User::factory()->create();
|
||||
Auth::login($this->owner);
|
||||
@@ -34,7 +36,7 @@ class PortfolioPolicyTest extends TestCase
|
||||
$this->user->id => [
|
||||
'full_access' => false,
|
||||
'owner' => false,
|
||||
]
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -109,5 +111,4 @@ class PortfolioPolicyTest extends TestCase
|
||||
$result = $this->policy->owner($this->user, $this->portfolio);
|
||||
$this->assertFalse($result, 'User should not be the owner');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,17 +2,14 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
class PortfoliosTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_owner_is_assigned_to_portfolio_on_create(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -22,8 +19,6 @@ class PortfoliosTest extends TestCase
|
||||
$this->assertEquals($user->id, $portfolio->owner_id);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_owner_can_be_forced_on_create(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -35,8 +30,6 @@ class PortfoliosTest extends TestCase
|
||||
$this->assertEquals($user->id, $portfolio->owner_id);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_owner_cannot_be_changed_on_update(): void
|
||||
{
|
||||
$this->actingAs($owner = User::factory()->create());
|
||||
@@ -49,6 +42,4 @@ class PortfoliosTest extends TestCase
|
||||
|
||||
$this->assertEquals($owner->id, $portfolio->owner_id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Laravel\Jetstream\Http\Livewire\UpdateProfileInformationForm;
|
||||
use Livewire\Livewire;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ProfileInformationTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace Tests;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Laravel\Fortify\Features;
|
||||
use Laravel\Jetstream\Jetstream;
|
||||
use Tests\TestCase;
|
||||
|
||||
class RegistrationTest extends TestCase
|
||||
{
|
||||
|
||||
+6
-11
@@ -2,32 +2,29 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Split;
|
||||
use App\Models\Holding;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\Split;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
class SplitsTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_splits_create_new_transaction(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
|
||||
|
||||
$portfolio = Portfolio::factory()->create();
|
||||
Transaction::factory()->buy()->yearsAgo()->portfolio($portfolio->id)->symbol('ACME')->create();
|
||||
|
||||
// manually reset the split last sync date (which is set when the holding is created)
|
||||
Holding::query()->portfolio($portfolio->id)->symbol('ACME')->update([
|
||||
'splits_synced_at' => null
|
||||
'splits_synced_at' => null,
|
||||
]);
|
||||
|
||||
|
||||
Split::refreshSplitData('ACME');
|
||||
|
||||
$transactions = Transaction::query()->symbol('ACME')->portfolio($portfolio->id)->get();
|
||||
@@ -35,12 +32,10 @@ class SplitsTest extends TestCase
|
||||
$this->assertCount(2, $transactions);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_splits_do_not_create_new_transaction_if_already_synced(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
|
||||
|
||||
$portfolio = Portfolio::factory()->create();
|
||||
Transaction::factory()->buy()->yearsAgo()->portfolio($portfolio->id)->symbol('ACME')->create();
|
||||
|
||||
|
||||
@@ -2,23 +2,20 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Holding;
|
||||
use Carbon\CarbonPeriod;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\DailyChange;
|
||||
use App\Models\Holding;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User;
|
||||
use Carbon\CarbonPeriod;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
class SyncDailyChangeTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_can_sync_daily_change_history(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -36,16 +33,14 @@ class SyncDailyChangeTest extends TestCase
|
||||
|
||||
$count_of_daily_changes = $portfolio->daily_change()->count('date');
|
||||
$days_between_now_and_first_trans = (int) CarbonPeriod::create(
|
||||
$portfolio->transactions()->min('date'),
|
||||
$portfolio->transactions()->min('date'),
|
||||
now()->isBefore(Carbon::parse(config('investbrain.daily_change_time_of_day'))) ? now()->subDay() : now()
|
||||
)->filter('isWeekday')
|
||||
->count();
|
||||
->count();
|
||||
|
||||
$this->assertEquals($count_of_daily_changes, $days_between_now_and_first_trans);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_cost_basis_is_synced(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -56,33 +51,31 @@ class SyncDailyChangeTest extends TestCase
|
||||
Artisan::call('sync:daily-change', ['portfolio_id' => $portfolio->id]);
|
||||
$holding = Holding::symbol('ACME')->portfolio($portfolio->id)->first();
|
||||
$daily_change = DailyChange::whereDate('date', '<=', $first_transaction->date->addDays(2))
|
||||
->whereDate('date', '>=', $first_transaction->date->subDays(2))
|
||||
->orderByDesc('date')
|
||||
->first();
|
||||
->whereDate('date', '>=', $first_transaction->date->subDays(2))
|
||||
->orderByDesc('date')
|
||||
->first();
|
||||
|
||||
$this->assertEquals($holding->average_cost_basis, $daily_change->total_cost_basis);
|
||||
|
||||
$second_transaction = Transaction::factory()->buy()->lastYear()->portfolio($portfolio->id)->symbol('ACME')->create();
|
||||
Artisan::call('sync:daily-change', ['portfolio_id' => $portfolio->id]);
|
||||
$daily_change = DailyChange::whereDate('date', '<=', $second_transaction->date->addDays(2))
|
||||
->whereDate('date', '>=', $second_transaction->date->subDays(2))
|
||||
->orderByDesc('date')
|
||||
->first();
|
||||
|
||||
$this->assertEqualsWithDelta($first_transaction->cost_basis + $second_transaction->cost_basis, $daily_change->total_cost_basis, 0.01);
|
||||
->whereDate('date', '>=', $second_transaction->date->subDays(2))
|
||||
->orderByDesc('date')
|
||||
->first();
|
||||
|
||||
$this->assertEqualsWithDelta($first_transaction->cost_basis + $second_transaction->cost_basis, $daily_change->total_cost_basis, 0.01);
|
||||
|
||||
$third_transaction = Transaction::factory(2)->sell()->lastMonth()->portfolio($portfolio->id)->symbol('ACME')->create()->first();
|
||||
Artisan::call('sync:daily-change', ['portfolio_id' => $portfolio->id]);
|
||||
$daily_change = DailyChange::whereDate('date', '<=', $third_transaction->date->addDays(2))
|
||||
->whereDate('date', '>=', $third_transaction->date->subDays(2))
|
||||
->orderByDesc('date')
|
||||
->first();
|
||||
->whereDate('date', '>=', $third_transaction->date->subDays(2))
|
||||
->orderByDesc('date')
|
||||
->first();
|
||||
|
||||
$this->assertEquals(0, $daily_change->total_cost_basis);
|
||||
$this->assertEquals(0, $daily_change->total_cost_basis);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_sales_are_captured_as_realized_gains(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
|
||||
+3
-3
@@ -9,14 +9,14 @@ abstract class TestCase extends BaseTestCase
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,16 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User;
|
||||
use App\Models\Holding;
|
||||
use App\Models\Portfolio;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
class TransactionsTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_can_create_a_transaction(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -24,8 +21,6 @@ class TransactionsTest extends TestCase
|
||||
$this->assertNotNull($transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_sales_calculate_cost_basis(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -37,8 +32,6 @@ class TransactionsTest extends TestCase
|
||||
$this->assertNotNull($transaction->cost_basis);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_purchases_dont_have_sale_price(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -48,8 +41,6 @@ class TransactionsTest extends TestCase
|
||||
$this->assertNull($transaction->sale_price);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_transaction_synced_to_holding(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
@@ -62,17 +53,17 @@ class TransactionsTest extends TestCase
|
||||
$this->assertDatabaseHas('holdings', [
|
||||
'portfolio_id' => $portfolio->id,
|
||||
'symbol' => 'AAPL',
|
||||
'quantity' => 4
|
||||
'quantity' => 4,
|
||||
]);
|
||||
|
||||
$holding = Holding::where([
|
||||
'portfolio_id' => $portfolio->id,
|
||||
'symbol' => 'AAPL'
|
||||
'symbol' => 'AAPL',
|
||||
])->first();
|
||||
|
||||
$this->assertEqualsWithDelta(
|
||||
$holding->realized_gain_dollars,
|
||||
$transaction->sale_price - $transaction->cost_basis,
|
||||
$holding->realized_gain_dollars,
|
||||
$transaction->sale_price - $transaction->cost_basis,
|
||||
0.01
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Laravel\Fortify\Features;
|
||||
use Laravel\Jetstream\Http\Livewire\TwoFactorAuthenticationForm;
|
||||
use Livewire\Livewire;
|
||||
use Tests\TestCase;
|
||||
|
||||
class TwoFactorAuthenticationSettingsTest extends TestCase
|
||||
{
|
||||
|
||||
@@ -7,7 +7,6 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Laravel\Jetstream\Http\Livewire\UpdatePasswordForm;
|
||||
use Livewire\Livewire;
|
||||
use Tests\TestCase;
|
||||
|
||||
class UpdatePasswordTest extends TestCase
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user