Finalize Typescript restructure

This commit is contained in:
Darko Gjorgjijoski
2026-04-06 17:59:15 +02:00
parent cab785172e
commit 74b4b2df4e
209 changed files with 12419 additions and 1745 deletions

View File

@@ -0,0 +1,136 @@
<?php
use App\Models\User;
use Illuminate\Support\Facades\Artisan;
use Laravel\Sanctum\Sanctum;
use function Pest\Laravel\getJson;
use function Pest\Laravel\postJson;
beforeEach(function () {
Artisan::call('db:seed', ['--class' => 'DatabaseSeeder', '--force' => true]);
Artisan::call('db:seed', ['--class' => 'DemoSeeder', '--force' => true]);
$user = User::find(1);
$this->withHeaders([
'company' => $user->companies()->first()->id,
]);
Sanctum::actingAs(
$user,
['*']
);
});
test('company settings config uses canonical v2 links', function () {
$links = collect(config('invoiceshelf.setting_menu'))->pluck('link');
expect($links)->toContain('/admin/settings/exchange-rate');
expect($links)->toContain('/admin/settings/payment-modes');
expect($links)->toContain('/admin/settings/expense-categories');
expect($links)->toContain('/admin/settings/roles');
expect($links)->toContain('/admin/settings/mail-config');
expect($links)->not->toContain('/admin/settings/roles-settings');
expect($links)->not->toContain('/admin/settings/exchange-rate-provider');
expect($links)->not->toContain('/admin/settings/payment-mode');
expect($links)->not->toContain('/admin/settings/expense-category');
expect($links)->not->toContain('/admin/settings/mail-configuration');
$bootstrapMenu = json_encode(getJson('/api/v1/bootstrap')
->assertOk()
->json('setting_menu'));
expect($bootstrapMenu)->not->toContain('roles-settings');
expect($bootstrapMenu)->not->toContain('exchange-rate-provider');
expect($bootstrapMenu)->not->toContain('payment-mode');
expect($bootstrapMenu)->not->toContain('expense-category');
expect($bootstrapMenu)->not->toContain('mail-configuration');
});
test('super admin bootstrap uses administration mode when requested', function () {
getJson('/api/v1/bootstrap?admin_mode=1')
->assertOk()
->assertJsonPath('admin_mode', true)
->assertJsonPath('current_company', null)
->assertJsonCount(0, 'setting_menu');
});
test('bootstrap without administration mode hydrates the selected company', function () {
$companyId = User::find(1)->companies()->first()->id;
getJson('/api/v1/bootstrap')
->assertOk()
->assertJsonPath('current_company.id', $companyId);
});
test('get global mail configuration', function () {
getJson('/api/v1/mail/config')
->assertOk()
->assertJsonStructure([
'mail_driver',
'from_name',
'from_mail',
]);
});
test('save global mail configuration', function () {
postJson('/api/v1/mail/config', [
'mail_driver' => 'smtp',
'mail_host' => 'smtp.example.com',
'mail_port' => 587,
'mail_username' => 'demo-user',
'mail_password' => 'secret',
'mail_encryption' => 'tls',
'from_name' => 'InvoiceShelf',
'from_mail' => 'hello@example.com',
])
->assertOk()
->assertJson([
'success' => 'mail_variables_save_successfully',
]);
$this->assertDatabaseHas('settings', [
'option' => 'mail_driver',
'value' => 'smtp',
]);
$this->assertDatabaseHas('settings', [
'option' => 'from_mail',
'value' => 'hello@example.com',
]);
});
test('get pdf configuration', function () {
getJson('/api/v1/pdf/config')
->assertOk()
->assertJsonStructure([
'pdf_driver',
'gotenberg_host',
'gotenberg_margins',
'gotenberg_papersize',
]);
});
test('save pdf configuration', function () {
postJson('/api/v1/pdf/config', [
'pdf_driver' => 'dompdf',
])
->assertOk()
->assertJson([
'success' => 'pdf_variables_save_successfully',
]);
$this->assertDatabaseHas('settings', [
'option' => 'pdf_driver',
'value' => 'dompdf',
]);
});
test('get app version', function () {
getJson('/api/v1/app/version')
->assertOk()
->assertJsonStructure([
'version',
'channel',
]);
});

View File

@@ -0,0 +1,48 @@
<?php
use App\Jobs\CreateBackupJob;
use App\Models\FileDisk;
use App\Models\User;
use App\Services\Backup\BackupConfigurationFactory;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Queue;
use Laravel\Sanctum\Sanctum;
use Spatie\Backup\Config\Config;
use function Pest\Laravel\postJson;
beforeEach(function () {
Artisan::call('db:seed', ['--class' => 'DatabaseSeeder', '--force' => true]);
Artisan::call('db:seed', ['--class' => 'DemoSeeder', '--force' => true]);
Sanctum::actingAs(
User::findOrFail(1),
['*']
);
});
test('create backup does not require company header', function () {
Queue::fake();
$disk = FileDisk::factory()->create();
postJson('/api/v1/backups', [
'option' => 'full',
'file_disk_id' => $disk->id,
])->assertOk()->assertJson([
'success' => true,
]);
Queue::assertPushed(CreateBackupJob::class);
});
test('backup configuration factory does not require company context', function () {
$disk = FileDisk::factory()->create();
$config = BackupConfigurationFactory::make([
'option' => 'full',
'file_disk_id' => $disk->id,
]);
expect($config)->toBeInstanceOf(Config::class);
});

View File

@@ -42,7 +42,31 @@ test('customer stats', function () {
$response = getJson("api/v1/customers/{$customer->id}/stats");
$response->assertStatus(200);
$response
->assertOk()
->assertJsonPath('data.id', $customer->id)
->assertJsonPath('data.name', $customer->name)
->assertJsonPath('data.email', $customer->email)
->assertJsonStructure([
'data' => [
'id',
'name',
'email',
],
'meta' => [
'chartData' => [
'salesTotal',
'totalReceipts',
'totalExpenses',
'netProfit',
'expenseTotals',
'netProfits',
'months',
'receiptTotals',
'invoiceTotals',
],
],
]);
});
test('create customer', function () {