Build live HickLab3D overview dashboard
Deploy HickLab3D Dashboard / Deploy to production (push) Successful in 24s

This commit is contained in:
Hickmeister
2026-10-10 19:29:34 +01:00
parent 88dcf5101b
commit 1c72937f9a
6 changed files with 386 additions and 19 deletions
+92
View File
@@ -2,6 +2,8 @@
namespace Tests\Feature;
use App\Models\EtsyConnection;
use App\Models\Filament;
use App\Models\Printer;
use App\Models\User;
use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
@@ -25,6 +27,96 @@ class DashboardAccessTest extends TestCase
$this->actingAs($user)->get(route('dashboard'))->assertOk()->assertSee('HickLab3D')->assertSee('maker');
}
public function test_administrator_sees_live_shop_and_workshop_overview(): void
{
Http::preventStrayRequests();
Http::fake([
'https://api.etsy.com/v3/application/shops/42/receipts*' => Http::response(['results' => [
['receipt_id' => 77, 'name' => 'Buyer One', 'create_timestamp' => now()->timestamp],
]]),
'https://api.etsy.com/v3/application/shops/42/listings*' => Http::response(['count' => 12, 'results' => []]),
'https://3d.example.test/api/v1/printers' => Http::response([['id' => 1, 'name' => 'X1 Carbon']]),
'https://3d.example.test/api/v1/printers/1/status' => Http::response(['connected' => true, 'state' => 'RUNNING', 'progress' => 45]),
'https://auth.example.test/token' => Http::response(['access_token' => 'shipping-token']),
'https://shipping.example.test/api/me/orders/detail' => Http::response(['Orders' => [
['OrderLineId' => 91, 'Courier' => 'Evri', 'Tracking' => ['Delivered' => false]],
]]),
'https://dryer.example.test/api/v1/status' => Http::response(['state' => 'idle']),
]);
config()->set('services.etsy', ['keystring' => 'key', 'shared_secret' => 'secret']);
config()->set('services.bambuddy', ['url' => 'https://3d.example.test', 'api_key' => 'key']);
config()->set('services.parcel2go', [
'client_id' => 'id', 'client_secret' => 'secret',
'auth_url' => 'https://auth.example.test/token', 'base_url' => 'https://shipping.example.test/api',
]);
config()->set('services.dryer', ['url' => 'https://dryer.example.test/api/v1', 'api_key' => 'key']);
EtsyConnection::create(['shop_id' => 42, 'shop_name' => 'HickLab3D', 'access_token' => '123.token', 'refresh_token' => '123.refresh', 'expires_at' => now()->addHour()]);
$admin = User::factory()->create(['role' => 'admin']);
Filament::create(['userId' => $admin->id, 'filamentName' => 'Blue PLA', 'amazonUrl' => 'https://amazon.co.uk/blue', 'material' => 'PLA']);
$this->actingAs($admin)->get(route('dashboard'))->assertOk()
->assertSee('Awaiting dispatch')->assertSee('#77')->assertSee('12')
->assertSee('X1 Carbon')->assertSee('RUNNING')->assertSee('Blue PLA')
->assertSee('#91')->assertSee('data-dashboard-chart="orders"', false)
->assertSee('data-dashboard-chart="materials"', false)
->assertViewHas('orderChart', fn (array $chart): bool => end($chart['series']) === 1);
}
public function test_regular_user_does_not_request_or_see_admin_shop_data(): void
{
Http::preventStrayRequests();
config()->set('services.bambuddy.api_key', null);
config()->set('services.dryer.api_key', null);
$this->actingAs(User::factory()->create())->get(route('dashboard'))->assertOk()
->assertDontSee('Orders to pack')->assertDontSee('Recent shipments')
->assertDontSee('Awaiting dispatch')->assertSee('No materials tracked yet');
Http::assertNothingSent();
}
public function test_etsy_dispatch_stays_visible_when_listings_are_unavailable(): void
{
Http::preventStrayRequests();
Http::fake([
'https://api.etsy.com/v3/application/shops/42/receipts*' => Http::response(['results' => [
['receipt_id' => 77, 'name' => 'Buyer One', 'create_timestamp' => now()->timestamp],
]]),
'https://api.etsy.com/v3/application/shops/42/listings*' => Http::response([], 503),
]);
config()->set('services.etsy', ['keystring' => 'key', 'shared_secret' => 'secret']);
config()->set('services.bambuddy.api_key', null);
config()->set('services.parcel2go.client_id', null);
config()->set('services.dryer.api_key', null);
EtsyConnection::create(['shop_id' => 42, 'shop_name' => 'HickLab3D', 'access_token' => '123.token', 'refresh_token' => '123.refresh', 'expires_at' => now()->addHour()]);
$this->actingAs(User::factory()->create(['role' => 'admin']))->get(route('dashboard'))
->assertOk()->assertSee('#77')->assertSee('data-dashboard-chart="orders"', false)
->assertViewHas('listingCount', null);
}
public function test_unavailable_integrations_do_not_make_overview_fail(): void
{
Http::preventStrayRequests();
Http::fake([
'https://api.etsy.com/*' => Http::response([], 503),
'https://3d.example.test/*' => Http::response([], 503),
'https://auth.example.test/*' => Http::response([], 503),
'https://dryer.example.test/*' => Http::response([], 503),
]);
config()->set('services.etsy', ['keystring' => 'key', 'shared_secret' => 'secret']);
config()->set('services.bambuddy', ['url' => 'https://3d.example.test', 'api_key' => 'key']);
config()->set('services.parcel2go', [
'client_id' => 'id', 'client_secret' => 'secret',
'auth_url' => 'https://auth.example.test/token', 'base_url' => 'https://shipping.example.test/api',
]);
config()->set('services.dryer', ['url' => 'https://dryer.example.test/api/v1', 'api_key' => 'key']);
EtsyConnection::create(['shop_id' => 42, 'shop_name' => 'HickLab3D', 'access_token' => '123.token', 'refresh_token' => '123.refresh', 'expires_at' => now()->addHour()]);
$this->actingAs(User::factory()->create(['role' => 'admin']))->get(route('dashboard'))
->assertOk()->assertSee('Temporarily unavailable')->assertSee('No materials tracked yet')
->assertDontSee('data-dashboard-chart="orders"', false);
}
public function test_disabled_account_cannot_sign_in(): void
{
User::factory()->create(['username' => 'disabled-user', 'disabled' => true, 'password' => 'correct-password']);