Files
investbrain/tests/Api/TransactionsTest.php
T

200 lines
5.9 KiB
PHP
Raw Normal View History

2025-01-27 20:04:03 -06:00
<?php
namespace Tests\Api;
use Tests\TestCase;
use App\Models\User;
use App\Models\Portfolio;
use App\Models\Transaction;
use Illuminate\Foundation\Testing\RefreshDatabase;
class TransactionsTest extends TestCase
{
use RefreshDatabase;
protected User $user;
protected Portfolio $portfolio;
protected function setUp(): void
{
parent::setUp();
// make user
$this->user = User::factory()->create();
// make portfolio
$this->portfolio = Portfolio::factory()->makeOne();
$this->portfolio->setOwnerIdAttribute($this->user->id);
$this->portfolio->save();
}
public function test_can_list_transactions()
{
$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']
]);
}
public function test_cannot_list_others_transactions()
{
// 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();
$this->actingAs($user)
->getJson(route('api.transaction.index', ['page' => 1, 'itemsPerPage' => 5]))
->assertOk()
->assertJsonCount(1, 'data');
}
public function test_cannot_access_transactions_when_unauthenticated()
{
$this->getJson(route('api.transaction.index'))->assertUnauthorized();
}
public function test_can_create_transaction()
{
$this->actingAs($this->user);
$data = [
'symbol' => 'AAPL',
'portfolio_id' => $this->portfolio->id,
'transaction_type' => 'BUY',
'quantity' => 10,
'date' => now()->toDateString(),
'cost_basis' => 150,
];
$this->postJson(route('api.transaction.store'), $data)
->assertCreated()
->assertJsonStructure([
'id',
'symbol',
'portfolio_id',
'transaction_type',
'quantity',
'date',
'cost_basis',
'sale_price'
]);
}
public function test_cannot_create_transaction_without_required_fields()
{
$this->actingAs($this->user)
->postJson(route('api.transaction.store'), [
'portfolio_id' => $this->portfolio->id,
'symbol' => null
])
->assertUnprocessable()
->assertJsonValidationErrors(['symbol']);
}
public function test_can_show_a_transaction()
{
$this->actingAs($this->user);
$transaction = Transaction::factory()->create();
$this->getJson(route('api.transaction.show', $transaction))
->assertOk()
->assertJsonFragment([
'id' => $transaction->id,
]);
}
public function test_cannot_show_nonexistent_transactions()
{
$this->actingAs($this->user)
->getJson(route('api.transaction.show', ['transaction' => 999]))
->assertNotFound();
}
public function test_can_update_a_transaction()
{
$this->actingAs($this->user);
$transaction = Transaction::factory()->create();
$data = [
'symbol' => 'ZZZ',
'transaction_type' => 'BUY',
'cost_basis' => 200.19,
'quantity' => 5
];
$this->actingAs($this->user)
->putJson(route('api.transaction.update', $transaction), $data)
->assertOk()
->assertJsonFragment([
'symbol' => 'ZZZ',
'transaction_type' => 'BUY',
'cost_basis' => 200.19,
'quantity' => 5,
]);
}
public function test_shared_user_can_update_transaction()
{
// create transaction (and portfolio)
$this->actingAs($this->user);
$transaction = Transaction::factory()->create();
// share it
$otherUser = User::factory()->create();
$transaction->portfolio->share($otherUser->email, true);
// shared user tries to update it
$this->actingAs($otherUser)
->putJson(route('api.transaction.update', $transaction), ['symbol' => 'ZZZ'])
->assertOk()
->assertJsonFragment([
'symbol' => 'ZZZ'
]);
}
public function test_cannot_update_transaction_without_permission()
{
$this->actingAs($this->user);
$transaction = Transaction::factory()->create();
$otherUser = User::factory()->create();
$this->actingAs($otherUser)
->putJson(route('api.transaction.update', $transaction), ['symbol' => 'AAPL'])
->assertForbidden();
}
public function test_can_delete_a_transaction()
{
$this->actingAs($this->user);
$transaction = Transaction::factory()->create();
$this->deleteJson(route('api.transaction.destroy', $transaction))
->assertNoContent();
$this->assertDatabaseMissing('transactions', ['id' => $transaction->id]);
}
public function test_cannot_delete_transaction_without_permission()
{
$this->actingAs($this->user);
$transaction = Transaction::factory()->create();
$otherUser = User::factory()->create();
$this->actingAs($otherUser)
->deleteJson(route('api.transaction.destroy', $transaction))
->assertForbidden();
}
}