From d5f25c6f764ce45c7d1268a99fcaeb744492ea8b Mon Sep 17 00:00:00 2001 From: hackerESQ Date: Mon, 28 Oct 2024 19:20:52 -0500 Subject: [PATCH] tests:import and exporting --- app/Imports/Sheets/DailyChangesSheet.php | 2 +- app/Imports/Sheets/PortfoliosSheet.php | 2 +- app/Imports/Sheets/TransactionsSheet.php | 4 +- tests/0000_00_00_import_test.xlsx | Bin 0 -> 10371 bytes tests/ImportExportTest.php | 81 +++++++++++++++++++++++ 5 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 tests/0000_00_00_import_test.xlsx create mode 100644 tests/ImportExportTest.php diff --git a/app/Imports/Sheets/DailyChangesSheet.php b/app/Imports/Sheets/DailyChangesSheet.php index 90b7223..356be9a 100644 --- a/app/Imports/Sheets/DailyChangesSheet.php +++ b/app/Imports/Sheets/DailyChangesSheet.php @@ -85,7 +85,7 @@ class DailyChangesSheet implements ToCollection, WithHeadingRow, WithValidation, public function rules(): array { return [ - 'portfolio_id' => ['required'], + 'portfolio_id' => ['required', 'uuid'], 'date' => ['required', 'date'], 'total_market_value' => ['sometimes', 'nullable', 'numeric'], 'total_cost_basis' => ['sometimes', 'nullable', 'min:0', 'numeric'], diff --git a/app/Imports/Sheets/PortfoliosSheet.php b/app/Imports/Sheets/PortfoliosSheet.php index bf43d98..015ff05 100644 --- a/app/Imports/Sheets/PortfoliosSheet.php +++ b/app/Imports/Sheets/PortfoliosSheet.php @@ -58,7 +58,7 @@ class PortfoliosSheet implements ToCollection, WithValidation, WithHeadingRow, S public function rules(): array { return [ - 'portfolio_id' => ['sometimes', 'nullable'], + 'portfolio_id' => ['sometimes', 'nullable', 'uuid'], 'title' => ['required', 'string'], 'wishlist' => ['sometimes', 'nullable', 'boolean'], 'notes' => ['sometimes', 'nullable', 'string'], diff --git a/app/Imports/Sheets/TransactionsSheet.php b/app/Imports/Sheets/TransactionsSheet.php index e3d21f1..b331830 100644 --- a/app/Imports/Sheets/TransactionsSheet.php +++ b/app/Imports/Sheets/TransactionsSheet.php @@ -106,9 +106,9 @@ class TransactionsSheet implements ToCollection, WithHeadingRow, WithValidation, public function rules(): array { return [ - 'transaction_id' => ['sometimes', 'nullable'], + 'transaction_id' => ['sometimes', 'nullable', 'uuid'], 'symbol' => ['required', 'string'], - 'portfolio_id' => ['required'], + 'portfolio_id' => ['required', 'uuid'], 'quantity' => ['required', 'min:0', 'numeric'], 'transaction_type' => ['required', 'in:BUY,SELL'], 'date' => ['required', 'date'], diff --git a/tests/0000_00_00_import_test.xlsx b/tests/0000_00_00_import_test.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a58b90ce7dd0aa2ae1f9547eb7ba7a063012e543 GIT binary patch literal 10371 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 = User::factory()->create()); + + Transaction::factory(5)->buy()->lastYear()->symbol('AAPL')->create(); + + 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; + }); + } + + /** + */ + 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' + ]); + + $backup_job->refresh(); + + $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' + ]); + + $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' + ]); + + $holding = $user->holdings->first(); + + $this->assertEquals('AAPL', $holding->symbol); + $this->assertEquals(6, $holding->quantity); + $this->assertEqualsWithDelta(233.33, $holding->average_cost_basis, 0.01); + } +}