From b62dbf32d975bcdfc525f7e480d29b38930be074 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Thu, 30 Apr 2026 09:08:41 +0700 Subject: [PATCH] fix: make dashboard sales-by-hour query cross-database compatible and add dashboard feature tests --- app/Http/Controllers/DashboardController.php | 11 +-- tests/Feature/Admin/DashboardTest.php | 73 ++++++++++++++++++++ 2 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 tests/Feature/Admin/DashboardTest.php diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index db2a037..e4dbd0a 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -36,23 +36,26 @@ public function __invoke() $stats['net_profit'] = $this->calculateDiff($stats['gross_profit'], $stats['total_expenses']); $stats['profit_margin'] = $this->calculateMargin($stats['net_profit'], $stats['total_revenue']); + $isSqlite = DB::getDriverName() === 'sqlite'; + $hourSelect = $isSqlite ? "CAST(strftime('%H', created_at) AS INTEGER)" : 'HOUR(created_at)'; + // Get sales by hour $todayOrders = DB::table('orders') ->whereDate('created_at', $today) ->select( - DB::raw('HOUR(created_at) as hour'), + DB::raw("$hourSelect as hour"), DB::raw('COUNT(*) as total') ) - ->groupBy(DB::raw('HOUR(created_at)')) + ->groupBy(DB::raw($hourSelect)) ->get(); $yesterdayOrders = DB::table('orders') ->whereDate('created_at', $yesterday) ->select( - DB::raw('HOUR(created_at) as hour'), + DB::raw("$hourSelect as hour"), DB::raw('COUNT(*) as total') ) - ->groupBy(DB::raw('HOUR(created_at)')) + ->groupBy(DB::raw($hourSelect)) ->get(); $salesByHour = collect(range(0, 23))->map(function ($hour) use ($todayOrders, $yesterdayOrders) { diff --git a/tests/Feature/Admin/DashboardTest.php b/tests/Feature/Admin/DashboardTest.php new file mode 100644 index 0000000..974508d --- /dev/null +++ b/tests/Feature/Admin/DashboardTest.php @@ -0,0 +1,73 @@ +assertRedirect(route('login')); + }); + + it('returns 403 when user has no permission to view dashboard', function () { + actingAs(createUnauthorizedUser()) + ->get(route('dashboard')) + ->assertStatus(403); + }); +}); + +describe('Dashboard Module - Authorized Actions', function () { + beforeEach(function () { + $user = createAuthorizedUser([ + 'View:Dashboard', + ]); + actingAs($user); + }); + + it('can access dashboard page and view statistics', function () { + // Create some dummy data to ensure queries don't fail and aggregations work + Order::factory()->count(3)->create([ + 'created_at' => now(), + 'total' => 100000, + 'cogs' => 50000, + ]); + + Expense::factory()->count(2)->create([ + 'created_at' => now(), + 'amount' => 20000, + ]); + + Purchase::factory()->create([ + 'created_at' => now(), + 'total' => 150000, + ]); + + get(route('dashboard')) + ->assertOk() + ->assertInertia(fn ($page) => $page + ->component('dashboard') + ->has('stats') + ->has('stats.total_sales') + ->has('stats.total_revenue') + ->has('stats.total_expenses') + ->has('stats.gross_profit') + ->has('stats.net_profit') + ->has('salesByHour') + ->has('paymentMethods') + ->has('orderStatuses') + ->has('orderChannels') + ->has('topProducts') + ->has('topCustomers') + ); + }); +});