Migrate HickLab3D dashboard and add production auto deployment
Deploy HickLab3D Dashboard / Deploy to production (push) Failing after 19s

This commit is contained in:
Hickmeister
2026-10-10 18:51:23 +01:00
parent 8410a50f26
commit 88dd00551f
974 changed files with 14609 additions and 162573 deletions
+137
View File
@@ -0,0 +1,137 @@
<?php
namespace Tests\Feature;
use App\Models\Printer;
use App\Models\User;
use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;
class DashboardAccessTest extends TestCase
{
use LazilyRefreshDatabase;
public function test_guest_is_sent_to_login(): void
{
$this->get(route('dashboard'))->assertRedirect(route('login'));
}
public function test_authenticated_user_sees_hicklab3d_dashboard(): void
{
$user = User::factory()->create(['username' => 'maker']);
$this->actingAs($user)->get(route('dashboard'))->assertOk()->assertSee('HickLab3D')->assertSee('maker');
}
public function test_disabled_account_cannot_sign_in(): void
{
User::factory()->create(['username' => 'disabled-user', 'disabled' => true, 'password' => 'correct-password']);
$this->post(route('login.store'), ['username' => 'disabled-user', 'password' => 'correct-password'])
->assertSessionHasErrors('username');
$this->assertGuest();
}
public function test_regular_user_cannot_create_filament(): void
{
$user = User::factory()->create();
$this->actingAs($user)->post(route('filaments.store'), [
'filamentName' => 'PLA Black', 'amazonUrl' => 'https://www.amazon.co.uk/example',
])->assertForbidden();
$this->assertDatabaseCount('filamentTracker', 0);
}
public function test_administrator_can_create_filament(): void
{
$admin = User::factory()->create(['role' => 'admin']);
$this->actingAs($admin)->post(route('filaments.store'), [
'filamentName' => 'PLA Black', 'amazonUrl' => 'https://www.amazon.co.uk/example',
])->assertRedirect(route('filaments.index'));
$this->assertDatabaseHas('filamentTracker', ['filamentName' => 'PLA Black', 'userId' => $admin->id]);
}
public function test_filament_tracking_rejects_non_amazon_urls(): void
{
$admin = User::factory()->create(['role' => 'admin']);
$this->actingAs($admin)->post(route('filaments.store'), [
'filamentName' => 'PLA Black', 'amazonUrl' => 'https://example.test/product',
])->assertSessionHasErrors('amazonUrl');
$this->assertDatabaseCount('filamentTracker', 0);
}
public function test_administrator_can_view_filament_list(): void
{
$admin = User::factory()->create(['role' => 'admin']);
$this->actingAs($admin)->get(route('filaments.index'))->assertOk()->assertSee('Filament prices');
}
public function test_administrator_can_manage_user_without_replacing_password(): void
{
$admin = User::factory()->create(['role' => 'admin']);
$member = User::factory()->create(['password' => 'original-password']);
$this->actingAs($admin)->patch(route('users.update', $member), [
'email' => 'new@example.test', 'role' => 'user', 'alertEmails' => 1, 'password' => '',
])->assertRedirect();
$this->assertDatabaseHas('users', ['id' => $member->id, 'email' => 'new@example.test', 'alertEmails' => 1]);
$this->assertTrue(Hash::check('original-password', $member->fresh()->password));
}
public function test_user_cannot_remove_another_users_printer(): void
{
$owner = User::factory()->create();
$other = User::factory()->create();
$printer = Printer::create(['userId' => $owner->id, 'printerName' => 'X1', 'printerIp' => '192.168.1.10', 'serialNumber' => 'X1TEST', 'mqttPassword' => 'secret']);
$this->actingAs($other)->delete(route('printers.destroy', $printer))->assertNotFound();
$this->assertModelExists($printer);
}
public function test_dryer_control_is_restricted_to_admins(): void
{
Http::preventStrayRequests();
$user = User::factory()->create();
$this->actingAs($user)->postJson(route('dryer.control'), ['dryerOn' => true, 'targetTemperature' => 45, 'dryingTime' => 240])->assertForbidden();
Http::assertNothingSent();
}
public function test_administrator_can_control_dryer_through_server_proxy(): void
{
Http::preventStrayRequests();
Http::fake(['https://dryer.example.test/api/v1/cycles/start' => Http::response(['ok' => true])]);
config()->set('services.dryer', ['url' => 'https://dryer.example.test/api/v1', 'api_key' => 'test-key']);
$admin = User::factory()->create(['role' => 'admin']);
$this->actingAs($admin)->postJson(route('dryer.control'), ['dryerOn' => true, 'profile' => 'PLA', 'targetTemperature' => 50, 'dryingTime' => 240])
->assertOk()->assertJsonPath('ok', true);
Http::assertSent(fn ($request) => $request->hasHeader('X-API-Key', 'test-key')
&& $request['profile'] === 'PLA' && $request['targetC'] === 50 && str_starts_with($request['requestId'], 'dashboard-'));
}
public function test_administrator_sees_shipping_data_from_parcel2go(): void
{
Http::preventStrayRequests();
Http::fake([
'https://auth.example.test/token' => Http::response(['access_token' => 'test-token']),
'https://shipping.example.test/api/me/detail' => Http::response(['Forename' => 'Lee', 'Surname' => 'Hickman']),
'https://shipping.example.test/api/me/prepay/balance' => Http::response(['Balance' => 12.5]),
'https://shipping.example.test/api/me/orders/detail' => Http::response(['Orders' => []]),
]);
config()->set('services.parcel2go', [
'client_id' => 'id', 'client_secret' => 'secret',
'auth_url' => 'https://auth.example.test/token',
'base_url' => 'https://shipping.example.test/api',
]);
$admin = User::factory()->create(['role' => 'admin']);
$this->actingAs($admin)->get(route('shipping'))->assertOk()->assertSee('Lee Hickman')->assertSee('12.50');
Http::assertSentCount(6);
}
}