feat: add feature tests for Studio dashboard components and update Analysis component's purchase filtering and top product aggregation logic.
This commit is contained in:
parent
fd409af9c6
commit
0733bd0d3e
@ -19,6 +19,7 @@
|
|||||||
use App\Models\Voucher;
|
use App\Models\Voucher;
|
||||||
use App\Traits\Notification\WithSubscribeNotification;
|
use App\Traits\Notification\WithSubscribeNotification;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
use Livewire\Attributes\Title;
|
use Livewire\Attributes\Title;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
@ -264,8 +265,7 @@ protected function loadData()
|
|||||||
auth()->user()->hasRole(['Developer', 'Owner']) ? [
|
auth()->user()->hasRole(['Developer', 'Owner']) ? [
|
||||||
'title' => 'Belanja Barang',
|
'title' => 'Belanja Barang',
|
||||||
'value' => formatCurrencyNumber(
|
'value' => formatCurrencyNumber(
|
||||||
Purchase::when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_id', $outletIds))
|
Purchase::when($dateQuery || ($startDate && $endDate), $filterDate)
|
||||||
->when($dateQuery || ($startDate && $endDate), $filterDate)
|
|
||||||
->sum('total'),
|
->sum('total'),
|
||||||
'Rp'
|
'Rp'
|
||||||
),
|
),
|
||||||
@ -283,64 +283,61 @@ protected function loadData()
|
|||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->topPerfumes = Perfume::with(['items' => function ($query) use ($outletIds, $dateQuery, $startDate, $endDate, $filterDate) {
|
$this->topPerfumes = OrderItem::where('orderable_type', Perfume::class)
|
||||||
$query->whereNotNull('order_id')
|
->whereHas('order', function ($q) use ($outletIds, $dateQuery, $startDate, $endDate, $filterDate) {
|
||||||
->whereHas('order', function ($q) use ($outletIds, $dateQuery, $startDate, $endDate, $filterDate) {
|
$q->when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_id', $outletIds))
|
||||||
$q->when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_id', $outletIds))
|
->when($dateQuery || ($startDate && $endDate), $filterDate);
|
||||||
->when($dateQuery || ($startDate && $endDate), $filterDate);
|
})
|
||||||
});
|
->with('orderable')
|
||||||
}])
|
->select('orderable_id', 'orderable_type', DB::raw('SUM(quantity) as total_sold'), DB::raw('SUM(unit_price * quantity) as total_sales_value'))
|
||||||
->select('id', 'name', 'sale_price')
|
->groupBy('orderable_id', 'orderable_type')
|
||||||
->get()
|
->orderByDesc('total_sales_value')
|
||||||
->map(fn ($perfume) => [
|
|
||||||
'name' => $perfume->name,
|
|
||||||
'sale_price' => formatCurrencyNumber($perfume->sale_price, 'Rp'),
|
|
||||||
'total_sold' => formatCurrencyNumber($perfume->items->sum('quantity')),
|
|
||||||
'total_sales' => formatCurrencyNumber($perfume->items->sum(fn ($item) => $item->order?->total ?? 0), 'Rp'),
|
|
||||||
])
|
|
||||||
->sortByDesc('total_sales')
|
|
||||||
->filter(fn ($product) => $product['total_sold'] > 0)
|
|
||||||
->take(5)
|
->take(5)
|
||||||
|
->get()
|
||||||
|
->map(fn ($item) => [
|
||||||
|
'name' => $item->orderable?->name ?? 'Unknown',
|
||||||
|
'sale_price' => formatCurrencyNumber($item->orderable?->sale_price ?? 0, 'Rp'),
|
||||||
|
'total_sold' => formatCurrencyNumber($item->total_sold),
|
||||||
|
'total_sales' => formatCurrencyNumber($item->total_sales_value, 'Rp'),
|
||||||
|
])
|
||||||
->toArray();
|
->toArray();
|
||||||
|
|
||||||
$this->topProducts = Product::with(['items' => function ($query) use ($outletIds, $dateQuery, $startDate, $endDate, $filterDate) {
|
$this->topProducts = OrderItem::where('orderable_type', Product::class)
|
||||||
$query->whereNotNull('order_id')
|
->whereHas('order', function ($q) use ($outletIds, $dateQuery, $startDate, $endDate, $filterDate) {
|
||||||
->whereHas('order', function ($q) use ($outletIds, $dateQuery, $startDate, $endDate, $filterDate) {
|
$q->when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_id', $outletIds))
|
||||||
$q->when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_id', $outletIds))
|
->when($dateQuery || ($startDate && $endDate), $filterDate);
|
||||||
->when($dateQuery || ($startDate && $endDate), $filterDate);
|
})
|
||||||
});
|
->with('orderable')
|
||||||
}])
|
->select('orderable_id', 'orderable_type', DB::raw('SUM(quantity) as total_sold'), DB::raw('SUM(unit_price * quantity) as total_sales_value'))
|
||||||
->select('id', 'name', 'sale_price')
|
->groupBy('orderable_id', 'orderable_type')
|
||||||
->get()
|
->orderByDesc('total_sales_value')
|
||||||
->map(fn ($product) => [
|
|
||||||
'name' => $product->name,
|
|
||||||
'sale_price' => formatCurrencyNumber($product->sale_price, 'Rp'),
|
|
||||||
'total_sold' => formatCurrencyNumber($product->items->sum('quantity')),
|
|
||||||
'total_sales' => formatCurrencyNumber($product->items->sum(fn ($item) => $item->order?->total ?? 0), 'Rp'),
|
|
||||||
])
|
|
||||||
->sortByDesc('total_sales')
|
|
||||||
->filter(fn ($product) => $product['total_sold'] > 0)
|
|
||||||
->take(5)
|
->take(5)
|
||||||
|
->get()
|
||||||
|
->map(fn ($item) => [
|
||||||
|
'name' => $item->orderable?->name ?? 'Unknown',
|
||||||
|
'sale_price' => formatCurrencyNumber($item->orderable?->sale_price ?? 0, 'Rp'),
|
||||||
|
'total_sold' => formatCurrencyNumber($item->total_sold),
|
||||||
|
'total_sales' => formatCurrencyNumber($item->total_sales_value, 'Rp'),
|
||||||
|
])
|
||||||
->toArray();
|
->toArray();
|
||||||
|
|
||||||
$this->topBottles = Bottle::with(['items' => function ($query) use ($outletIds, $dateQuery, $startDate, $endDate, $filterDate) {
|
$this->topBottles = OrderItem::where('orderable_type', Bottle::class)
|
||||||
$query->whereNotNull('order_id')
|
->whereHas('order', function ($q) use ($outletIds, $dateQuery, $startDate, $endDate, $filterDate) {
|
||||||
->whereHas('order', function ($q) use ($outletIds, $dateQuery, $startDate, $endDate, $filterDate) {
|
$q->when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_id', $outletIds))
|
||||||
$q->when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_id', $outletIds))
|
->when($dateQuery || ($startDate && $endDate), $filterDate);
|
||||||
->when($dateQuery || ($startDate && $endDate), $filterDate);
|
})
|
||||||
});
|
->with('orderable')
|
||||||
}])
|
->select('orderable_id', 'orderable_type', DB::raw('SUM(quantity) as total_sold'), DB::raw('SUM(unit_price * quantity) as total_sales_value'))
|
||||||
->select('id', 'name', 'sale_price')
|
->groupBy('orderable_id', 'orderable_type')
|
||||||
->get()
|
->orderByDesc('total_sales_value')
|
||||||
->map(fn ($bottle) => [
|
|
||||||
'name' => $bottle->name,
|
|
||||||
'sale_price' => formatCurrencyNumber($bottle->sale_price, 'Rp'),
|
|
||||||
'total_sold' => formatCurrencyNumber($bottle->items->sum('quantity')),
|
|
||||||
'total_sales' => formatCurrencyNumber($bottle->items->sum(fn ($item) => $item->order?->total ?? 0), 'Rp'),
|
|
||||||
])
|
|
||||||
->sortByDesc('total_sales')
|
|
||||||
->filter(fn ($product) => $product['total_sold'] > 0)
|
|
||||||
->take(5)
|
->take(5)
|
||||||
|
->get()
|
||||||
|
->map(fn ($item) => [
|
||||||
|
'name' => $item->orderable?->name ?? 'Unknown',
|
||||||
|
'sale_price' => formatCurrencyNumber($item->orderable?->sale_price ?? 0, 'Rp'),
|
||||||
|
'total_sold' => formatCurrencyNumber($item->total_sold),
|
||||||
|
'total_sales' => formatCurrencyNumber($item->total_sales_value, 'Rp'),
|
||||||
|
])
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -91,13 +91,9 @@ protected function loadStats()
|
|||||||
->yesterday()
|
->yesterday()
|
||||||
->sum('amount');
|
->sum('amount');
|
||||||
|
|
||||||
$todayPurchase = Purchase::when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_id', $outletIds))
|
$todayPurchase = Purchase::query()->today()->sum('total');
|
||||||
->today()
|
|
||||||
->sum('total');
|
|
||||||
|
|
||||||
$yesterdayPurchase = Purchase::when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_id', $outletIds))
|
$yesterdayPurchase = Purchase::query()->yesterday()->sum('total');
|
||||||
->yesterday()
|
|
||||||
->sum('total');
|
|
||||||
|
|
||||||
$todayGrossProfit = $todayIncome - $todayCogs - $todayDiscount;
|
$todayGrossProfit = $todayIncome - $todayCogs - $todayDiscount;
|
||||||
$yesterdayGrossProfit = $yesterdayIncome - $yesterdayCogs - $yesterdayDiscount;
|
$yesterdayGrossProfit = $yesterdayIncome - $yesterdayCogs - $yesterdayDiscount;
|
||||||
|
|||||||
@ -25,7 +25,7 @@ protected function casts(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'cogs' => 'int',
|
'cogs' => 'int',
|
||||||
'price' => 'int',
|
'unit_price' => 'int',
|
||||||
'quantity' => 'int',
|
'quantity' => 'int',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,4 +37,14 @@ public function salary(): Factory
|
|||||||
{
|
{
|
||||||
return $this->state(fn () => ['type' => ExpenseType::SALARY]);
|
return $this->state(fn () => ['type' => ExpenseType::SALARY]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function today(): Factory
|
||||||
|
{
|
||||||
|
return $this->state(fn () => ['created_at' => now()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function yesterday(): Factory
|
||||||
|
{
|
||||||
|
return $this->state(fn () => ['created_at' => now()->subDay()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -179,10 +179,14 @@ public function today(): Factory
|
|||||||
|
|
||||||
public function yesterday(): Factory
|
public function yesterday(): Factory
|
||||||
{
|
{
|
||||||
return $this->state(fn () => tap(now()->subDay(), fn ($d) => null) && [
|
return $this->state(function () {
|
||||||
'ordered_at' => $d = now()->subDay(),
|
$yesterday = now()->subDay();
|
||||||
'created_at' => $d,
|
|
||||||
]);
|
return [
|
||||||
|
'ordered_at' => $yesterday,
|
||||||
|
'created_at' => $yesterday,
|
||||||
|
];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function thisWeek(): Factory
|
public function thisWeek(): Factory
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\Outlet;
|
|
||||||
use App\Models\Purchase;
|
use App\Models\Purchase;
|
||||||
|
use App\Models\Warehouse;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
@ -14,11 +14,21 @@ class PurchaseFactory extends Factory
|
|||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'outlet_id' => Outlet::factory(),
|
'warehouse_id' => Warehouse::factory(),
|
||||||
'invoice_number' => Str::upper($this->faker->bothify('PO-########')),
|
'invoice_number' => Str::upper($this->faker->bothify('PO-########')),
|
||||||
'purchase_date' => $this->faker->date(),
|
'purchase_date' => $this->faker->date(),
|
||||||
'total' => $this->faker->numberBetween(50000, 500000),
|
'total' => $this->faker->numberBetween(50000, 500000),
|
||||||
'note' => $this->faker->optional()->sentence(6),
|
'note' => $this->faker->optional()->sentence(6),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function today(): Factory
|
||||||
|
{
|
||||||
|
return $this->state(fn () => ['created_at' => now()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function yesterday(): Factory
|
||||||
|
{
|
||||||
|
return $this->state(fn () => ['created_at' => now()->subDay()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
119
tests/Feature/Studio/Dashboard/AnalysisTest.php
Normal file
119
tests/Feature/Studio/Dashboard/AnalysisTest.php
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Livewire\Studio\Dashboard\Analysis;
|
||||||
|
use App\Models\Category;
|
||||||
|
use App\Models\Customer;
|
||||||
|
use App\Models\Order;
|
||||||
|
use App\Models\OrderItem;
|
||||||
|
use App\Models\Outlet;
|
||||||
|
use App\Models\Perfume;
|
||||||
|
use App\Models\User;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Livewire\Livewire;
|
||||||
|
use Spatie\Permission\Models\Permission;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->setupUser();
|
||||||
|
|
||||||
|
$role = Role::firstOrCreate(['name' => 'Developer']);
|
||||||
|
Permission::firstOrCreate(['name' => 'view analysis']);
|
||||||
|
$role->givePermissionTo('view analysis');
|
||||||
|
$this->user->assignRole($role);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders the analysis page correctly', function () {
|
||||||
|
$this->actingAs($this->user)
|
||||||
|
->get(route('studio.dashboard.analysis'))
|
||||||
|
->assertOk()
|
||||||
|
->assertSeeLivewire(Analysis::class);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calculates counting data correctly', function () {
|
||||||
|
// Basic counts
|
||||||
|
Outlet::factory()->count(2)->create();
|
||||||
|
Category::factory()->count(3)->create();
|
||||||
|
|
||||||
|
// Member count (User with customer relation)
|
||||||
|
$customerUser = User::factory()->create();
|
||||||
|
Customer::factory()->create(['user_id' => $customerUser->id]);
|
||||||
|
|
||||||
|
// Employee count (User with employee relation)
|
||||||
|
$employeeUser = User::factory()->create();
|
||||||
|
\App\Models\Employee::factory()->create(['user_id' => $employeeUser->id]);
|
||||||
|
|
||||||
|
Livewire::actingAs($this->user)
|
||||||
|
->test(Analysis::class)
|
||||||
|
->assertSet('countingData.0.title', 'Outlet')
|
||||||
|
->assertSet('countingData.0.value', 3) // 1 from setup + 2 created
|
||||||
|
->assertSet('countingData.4.title', 'Member')
|
||||||
|
->assertSet('countingData.4.value', 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filters data by pre-defined periods', function () {
|
||||||
|
// Order from 10 days ago
|
||||||
|
Order::factory()->paid()->create([
|
||||||
|
'total' => 100000,
|
||||||
|
'created_at' => now()->subDays(10),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Order from today
|
||||||
|
Order::factory()->paid()->create([
|
||||||
|
'total' => 50000,
|
||||||
|
'created_at' => now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
Livewire::actingAs($this->user)
|
||||||
|
->test(Analysis::class)
|
||||||
|
// All period (default)
|
||||||
|
->assertSet('orders.1.value', 'Rp150.000')
|
||||||
|
// Last 7 days (only shows today's order)
|
||||||
|
->set('period', '7')
|
||||||
|
->assertSet('orders.1.value', 'Rp50.000');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filters data by custom date range', function () {
|
||||||
|
// Order in range
|
||||||
|
Order::factory()->paid()->create([
|
||||||
|
'total' => 200000,
|
||||||
|
'created_at' => Carbon::parse('2024-01-15'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Order out of range
|
||||||
|
Order::factory()->paid()->create([
|
||||||
|
'total' => 100000,
|
||||||
|
'created_at' => Carbon::parse('2024-02-15'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
Livewire::actingAs($this->user)
|
||||||
|
->test(Analysis::class)
|
||||||
|
->set('range.start', '2024-01-01')
|
||||||
|
->set('range.end', '2024-01-31')
|
||||||
|
->assertSet('orders.1.value', 'Rp200.000');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows top performers correctly with aggregation', function () {
|
||||||
|
$p1 = Perfume::factory()->create(['name' => 'Perfume A', 'sale_price' => 1000]);
|
||||||
|
$p2 = Perfume::factory()->create(['name' => 'Perfume B', 'sale_price' => 2000]);
|
||||||
|
|
||||||
|
// Sale of Perfume A (Total sales: 1500)
|
||||||
|
$o1 = Order::factory()->paid()->create();
|
||||||
|
OrderItem::factory()->forOrder($o1)->forPerfume($p1)->create([
|
||||||
|
'unit_price' => 500,
|
||||||
|
'quantity' => 3,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Sale of Perfume B (Total sales: 4000)
|
||||||
|
$o2 = Order::factory()->paid()->create();
|
||||||
|
OrderItem::factory()->forOrder($o2)->forPerfume($p2)->create([
|
||||||
|
'unit_price' => 2000,
|
||||||
|
'quantity' => 2,
|
||||||
|
]);
|
||||||
|
|
||||||
|
Livewire::actingAs($this->user)
|
||||||
|
->test(Analysis::class)
|
||||||
|
->assertSet('topPerfumes.0.name', 'Perfume B')
|
||||||
|
->assertSet('topPerfumes.0.total_sales', 'Rp4.000')
|
||||||
|
->assertSet('topPerfumes.1.name', 'Perfume A')
|
||||||
|
->assertSet('topPerfumes.1.total_sales', 'Rp1.500');
|
||||||
|
});
|
||||||
92
tests/Feature/Studio/Dashboard/OverviewTest.php
Normal file
92
tests/Feature/Studio/Dashboard/OverviewTest.php
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Livewire\Studio\Dashboard\Overview;
|
||||||
|
use App\Models\Expense;
|
||||||
|
use App\Models\Order;
|
||||||
|
use App\Models\OrderItem;
|
||||||
|
use App\Models\Perfume;
|
||||||
|
use App\Models\Purchase;
|
||||||
|
use Livewire\Livewire;
|
||||||
|
use Spatie\Permission\Models\Permission;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->setupUser();
|
||||||
|
|
||||||
|
// Ensure the user has Developer role and required permissions
|
||||||
|
$role = Role::firstOrCreate(['name' => 'Developer']);
|
||||||
|
Permission::firstOrCreate(['name' => 'view studio overview']);
|
||||||
|
$role->givePermissionTo('view studio overview');
|
||||||
|
$this->user->assignRole($role);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders the overview page correctly', function () {
|
||||||
|
$this->actingAs($this->user)
|
||||||
|
->get(route('studio.dashboard.overview'))
|
||||||
|
->assertOk()
|
||||||
|
->assertSeeLivewire(Overview::class);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calculates stats correctly for today and yesterday', function () {
|
||||||
|
// Today's data
|
||||||
|
Order::factory()->count(2)->today()->paid()->withOutlet($this->outlet)->create([
|
||||||
|
'total' => 100000,
|
||||||
|
'cogs' => 40000,
|
||||||
|
'discount' => 10000,
|
||||||
|
]);
|
||||||
|
Expense::factory()->today()->create(['amount' => 5000, 'outlet_id' => $this->outlet->id]);
|
||||||
|
Purchase::factory()->today()->create(['total' => 50000]);
|
||||||
|
|
||||||
|
// Yesterday's data
|
||||||
|
Order::factory()->count(1)->yesterday()->paid()->withOutlet($this->outlet)->create([
|
||||||
|
'total' => 80000,
|
||||||
|
'cogs' => 30000,
|
||||||
|
'discount' => 5000,
|
||||||
|
]);
|
||||||
|
Expense::factory()->yesterday()->create(['amount' => 2000, 'outlet_id' => $this->outlet->id]);
|
||||||
|
Purchase::factory()->yesterday()->create(['total' => 30000]);
|
||||||
|
|
||||||
|
Livewire::actingAs($this->user)
|
||||||
|
->test(Overview::class)
|
||||||
|
->assertSet('stats.0.value', 2) // Total Order Today
|
||||||
|
->assertSet('stats.0.previous', 1) // Total Order Yesterday
|
||||||
|
->assertSet('stats.1.value', 'Rp200.000') // Pendapatan Today (2 * 100k)
|
||||||
|
->assertSet('stats.1.previous', 'Rp80.000'); // Pendapatan Yesterday (1 * 80k)
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filters stats by selected outlets', function () {
|
||||||
|
$anotherOutlet = \App\Models\Outlet::factory()->create();
|
||||||
|
$this->user->outlets()->attach($anotherOutlet);
|
||||||
|
|
||||||
|
// Order in main outlet
|
||||||
|
Order::factory()->today()->paid()->withOutlet($this->outlet)->create(['total' => 100000]);
|
||||||
|
// Order in another outlet
|
||||||
|
Order::factory()->today()->paid()->withOutlet($anotherOutlet)->create(['total' => 50000]);
|
||||||
|
|
||||||
|
Livewire::actingAs($this->user)
|
||||||
|
->test(Overview::class)
|
||||||
|
// No filter (shows both)
|
||||||
|
->assertSet('stats.1.value', 'Rp150.000')
|
||||||
|
// Filter by main outlet only
|
||||||
|
->set('selectedOutletIds', [$this->outlet->id])
|
||||||
|
->assertSet('stats.1.value', 'Rp100.000')
|
||||||
|
// Filter by another outlet only
|
||||||
|
->set('selectedOutletIds', [$anotherOutlet->id])
|
||||||
|
->assertSet('stats.1.value', 'Rp50.000');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows top perfume correctly', function () {
|
||||||
|
$perfume = Perfume::factory()->create(['name' => 'Royal Oud']);
|
||||||
|
|
||||||
|
$order = Order::factory()->today()->paid()->withOutlet($this->outlet)->create();
|
||||||
|
OrderItem::factory()->create([
|
||||||
|
'order_id' => $order->id,
|
||||||
|
'orderable_type' => Perfume::class,
|
||||||
|
'orderable_id' => $perfume->id,
|
||||||
|
'quantity' => 100,
|
||||||
|
]);
|
||||||
|
|
||||||
|
Livewire::actingAs($this->user)
|
||||||
|
->test(Overview::class)
|
||||||
|
->assertSee('Royal Oud (100ml)');
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user