refactor: restructure feature tests for StockOpname, Restock, Order, and Article into granular files.
This commit is contained in:
parent
b47a7ff0a3
commit
660e772f1c
65
tests/Feature/Studio/Manage/Article/CreateTest.php
Normal file
65
tests/Feature/Studio/Manage/Article/CreateTest.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\ArticleStatus;
|
||||
use App\Enums\CategoryType;
|
||||
use App\Livewire\Studio\Manage\Article\Create;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->setupUser();
|
||||
|
||||
// Create necessary permissions
|
||||
$permissions = [
|
||||
'view article',
|
||||
'create article',
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
Permission::firstOrCreate(['name' => $permission]);
|
||||
}
|
||||
|
||||
$role = Role::create(['name' => 'Writer']);
|
||||
$role->givePermissionTo($permissions);
|
||||
$this->user->assignRole($role);
|
||||
});
|
||||
|
||||
it('renders the article create page', function () {
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Create::class)
|
||||
->assertStatus(200);
|
||||
});
|
||||
|
||||
it('can store a new article', function () {
|
||||
Storage::fake('public');
|
||||
$category = Category::factory()->create(['type' => CategoryType::ARTICLE]);
|
||||
$image = UploadedFile::fake()->image('thumbnail.jpg');
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Create::class)
|
||||
->set('form.title', 'Test Article')
|
||||
->set('form.excerpt', 'This is a test excerpt')
|
||||
->set('form.content', 'This is the content of the test article.')
|
||||
->set('form.status', ArticleStatus::PUBLISHED->value)
|
||||
->set('form.category_ids', [$category->id])
|
||||
->set('form.thumbnail', [$image])
|
||||
->call('save')
|
||||
->assertRedirect(route('studio.manage.article.index', ['notification' => 'Artikel berhasil ditambahkan.']));
|
||||
|
||||
$this->assertDatabaseHas('articles', [
|
||||
'title' => 'Test Article',
|
||||
'excerpt' => 'This is a test excerpt',
|
||||
'status' => ArticleStatus::PUBLISHED->value,
|
||||
]);
|
||||
});
|
||||
|
||||
it('validates article input', function () {
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Create::class)
|
||||
->call('save')
|
||||
->assertHasErrors(['form.title', 'form.content', 'form.thumbnail', 'form.category_ids']);
|
||||
});
|
||||
43
tests/Feature/Studio/Manage/Article/IndexTest.php
Normal file
43
tests/Feature/Studio/Manage/Article/IndexTest.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\CategoryType;
|
||||
use App\Livewire\Studio\Manage\Article\Index;
|
||||
use App\Models\Article;
|
||||
use App\Models\Category;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->setupUser();
|
||||
|
||||
// Create necessary permissions
|
||||
$permissions = [
|
||||
'view article',
|
||||
'delete article',
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
Permission::firstOrCreate(['name' => $permission]);
|
||||
}
|
||||
|
||||
$role = Role::create(['name' => 'Writer']);
|
||||
$role->givePermissionTo($permissions);
|
||||
$this->user->assignRole($role);
|
||||
});
|
||||
|
||||
it('renders the article index page', function () {
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->assertStatus(200);
|
||||
});
|
||||
|
||||
it('can delete an article', function () {
|
||||
$article = Article::factory()->create(['author_id' => $this->user->id]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->call('delete', $article->id);
|
||||
|
||||
$this->assertSoftDeleted('articles', ['id' => $article->id]);
|
||||
});
|
||||
@ -4,7 +4,6 @@
|
||||
use App\Enums\PaymentStatus;
|
||||
use App\Enums\VoucherType;
|
||||
use App\Livewire\Studio\Manage\Order\Create;
|
||||
use App\Livewire\Studio\Manage\Order\Index;
|
||||
use App\Models\Bottle;
|
||||
use App\Models\Formula;
|
||||
use App\Models\Order;
|
||||
@ -22,7 +21,7 @@
|
||||
$this->setupUser();
|
||||
|
||||
$role = Role::firstOrCreate(['name' => 'Owner']);
|
||||
$permissions = ['view order', 'create order', 'delete order'];
|
||||
$permissions = ['view order', 'create order'];
|
||||
foreach ($permissions as $p) {
|
||||
Permission::firstOrCreate(['name' => $p]);
|
||||
}
|
||||
@ -39,13 +38,6 @@
|
||||
Role::firstOrCreate(['name' => 'Leader']);
|
||||
});
|
||||
|
||||
it('renders the order index page', function () {
|
||||
$this->actingAs($this->user)
|
||||
->get(route('studio.manage.order.index'))
|
||||
->assertOk()
|
||||
->assertSeeLivewire(Index::class);
|
||||
});
|
||||
|
||||
it('renders the order create page', function () {
|
||||
$this->actingAs($this->user)
|
||||
->get(route('studio.manage.order.create'))
|
||||
@ -287,38 +279,6 @@
|
||||
]);
|
||||
});
|
||||
|
||||
it('can delete an order and restore outlet stock', function () {
|
||||
$product = Product::factory()->create();
|
||||
$order = Order::factory()->create([
|
||||
'outlet_id' => $this->outlet->id,
|
||||
'user_id' => $this->user->id,
|
||||
'total' => 100000,
|
||||
]);
|
||||
|
||||
$item = OrderItem::factory()->forProduct($product)->create([
|
||||
'order_id' => $order->id,
|
||||
'user_id' => $this->user->id,
|
||||
'quantity' => 2,
|
||||
]);
|
||||
|
||||
// Initial stock (after order was supposedly created)
|
||||
$this->outlet->products()->attach($product->id, ['stock' => 10]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->call('delete', $order->id)
|
||||
->assertHasNoErrors();
|
||||
|
||||
$this->assertSoftDeleted('orders', ['id' => $order->id]);
|
||||
|
||||
// Check stock restored (10 + 2 = 12)
|
||||
$this->assertDatabaseHas('outlet_product', [
|
||||
'outlet_id' => $this->outlet->id,
|
||||
'product_id' => $product->id,
|
||||
'stock' => 12,
|
||||
]);
|
||||
});
|
||||
|
||||
it('cannot create order with empty cart', function () {
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Create::class)
|
||||
@ -340,14 +300,10 @@
|
||||
->assertHasErrors(['form.outlet_id' => 'required']);
|
||||
});
|
||||
|
||||
it('cannot access order without permission', function () {
|
||||
it('cannot access order create without permission', function () {
|
||||
$this->user->roles()->detach();
|
||||
$this->user->permissions()->detach();
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->get(route('studio.manage.order.index'))
|
||||
->assertForbidden();
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->get(route('studio.manage.order.create'))
|
||||
->assertForbidden();
|
||||
72
tests/Feature/Studio/Manage/Order/IndexTest.php
Normal file
72
tests/Feature/Studio/Manage/Order/IndexTest.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Studio\Manage\Order\Index;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderItem;
|
||||
use App\Models\Product;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->setupUser();
|
||||
|
||||
$role = Role::firstOrCreate(['name' => 'Owner']);
|
||||
$permissions = ['view order', 'delete order'];
|
||||
foreach ($permissions as $p) {
|
||||
Permission::firstOrCreate(['name' => $p]);
|
||||
}
|
||||
$role->syncPermissions($permissions);
|
||||
$this->user->assignRole($role);
|
||||
|
||||
// Ensure user has an outlet
|
||||
$this->user->outlets()->sync([$this->outlet->id]);
|
||||
});
|
||||
|
||||
it('renders the order index page', function () {
|
||||
$this->actingAs($this->user)
|
||||
->get(route('studio.manage.order.index'))
|
||||
->assertOk()
|
||||
->assertSeeLivewire(Index::class);
|
||||
});
|
||||
|
||||
it('can delete an order and restore outlet stock', function () {
|
||||
$product = Product::factory()->create();
|
||||
$order = Order::factory()->create([
|
||||
'outlet_id' => $this->outlet->id,
|
||||
'user_id' => $this->user->id,
|
||||
'total' => 100000,
|
||||
]);
|
||||
|
||||
$item = OrderItem::factory()->forProduct($product)->create([
|
||||
'order_id' => $order->id,
|
||||
'user_id' => $this->user->id,
|
||||
'quantity' => 2,
|
||||
]);
|
||||
|
||||
// Initial stock (after order was supposedly created)
|
||||
$this->outlet->products()->attach($product->id, ['stock' => 10]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->call('delete', $order->id)
|
||||
->assertHasNoErrors();
|
||||
|
||||
$this->assertSoftDeleted('orders', ['id' => $order->id]);
|
||||
|
||||
// Check stock restored (10 + 2 = 12)
|
||||
$this->assertDatabaseHas('outlet_product', [
|
||||
'outlet_id' => $this->outlet->id,
|
||||
'product_id' => $product->id,
|
||||
'stock' => 12,
|
||||
]);
|
||||
});
|
||||
|
||||
it('cannot access order index without permission', function () {
|
||||
$this->user->roles()->detach();
|
||||
$this->user->permissions()->detach();
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->get(route('studio.manage.order.index'))
|
||||
->assertForbidden();
|
||||
});
|
||||
@ -1,11 +1,9 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Studio\Manage\Restock\Create;
|
||||
use App\Livewire\Studio\Manage\Restock\Index;
|
||||
use App\Models\Bottle;
|
||||
use App\Models\Perfume;
|
||||
use App\Models\Product;
|
||||
use App\Models\Restock;
|
||||
use App\Models\Warehouse;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
@ -19,8 +17,6 @@
|
||||
$permissions = [
|
||||
'view restock',
|
||||
'create restock',
|
||||
'update restock',
|
||||
'delete restock',
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
@ -32,12 +28,6 @@
|
||||
$this->user->assignRole($role);
|
||||
});
|
||||
|
||||
it('renders the restock index page', function () {
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->assertStatus(200);
|
||||
});
|
||||
|
||||
it('renders the restock create page', function () {
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Create::class)
|
||||
@ -135,39 +125,6 @@
|
||||
]);
|
||||
});
|
||||
|
||||
it('can delete a restock and reverse stock transfer', function () {
|
||||
$warehouse = Warehouse::factory()->create();
|
||||
$perfume = Perfume::factory()->create();
|
||||
|
||||
// Initial state: Warehouse 90, Outlet 10 (simulating after a restock of 10)
|
||||
$warehouse->perfumes()->attach($perfume->id, ['stock' => 90]);
|
||||
$this->outlet->perfumes()->attach($perfume->id, ['stock' => 10]);
|
||||
|
||||
$restock = Restock::create([
|
||||
'warehouse_id' => $warehouse->id,
|
||||
'outlet_id' => $this->outlet->id,
|
||||
'restock_date' => now(),
|
||||
'note' => 'To be deleted',
|
||||
]);
|
||||
|
||||
$restock->items()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'restockable_type' => Perfume::class,
|
||||
'restockable_id' => $perfume->id,
|
||||
'quantity' => 10,
|
||||
]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->call('delete', $restock->id);
|
||||
|
||||
$this->assertSoftDeleted('restocks', ['id' => $restock->id]);
|
||||
|
||||
// Verify Stock Reversal
|
||||
$this->assertEquals(100, $warehouse->perfumes()->find($perfume->id)->pivot->stock); // 90 + 10
|
||||
$this->assertEquals(0, $this->outlet->perfumes()->find($perfume->id)->pivot->stock); // 10 - 10
|
||||
});
|
||||
|
||||
it('validates restock input', function () {
|
||||
$warehouse = Warehouse::factory()->create();
|
||||
$perfume = Perfume::factory()->create();
|
||||
67
tests/Feature/Studio/Manage/Restock/IndexTest.php
Normal file
67
tests/Feature/Studio/Manage/Restock/IndexTest.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Studio\Manage\Restock\Index;
|
||||
use App\Models\Perfume;
|
||||
use App\Models\Restock;
|
||||
use App\Models\Warehouse;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->setupUser();
|
||||
$this->outlet = $this->user->outlets->first();
|
||||
|
||||
// Create permissions
|
||||
$permissions = [
|
||||
'view restock',
|
||||
'delete restock',
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
Permission::firstOrCreate(['name' => $permission]);
|
||||
}
|
||||
|
||||
$role = Role::create(['name' => 'Owner']);
|
||||
$role->givePermissionTo($permissions);
|
||||
$this->user->assignRole($role);
|
||||
});
|
||||
|
||||
it('renders the restock index page', function () {
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->assertStatus(200);
|
||||
});
|
||||
|
||||
it('can delete a restock and reverse stock transfer', function () {
|
||||
$warehouse = Warehouse::factory()->create();
|
||||
$perfume = Perfume::factory()->create();
|
||||
|
||||
// Initial state: Warehouse 90, Outlet 10 (simulating after a restock of 10)
|
||||
$warehouse->perfumes()->attach($perfume->id, ['stock' => 90]);
|
||||
$this->outlet->perfumes()->attach($perfume->id, ['stock' => 10]);
|
||||
|
||||
$restock = Restock::create([
|
||||
'warehouse_id' => $warehouse->id,
|
||||
'outlet_id' => $this->outlet->id,
|
||||
'restock_date' => now(),
|
||||
'note' => 'To be deleted',
|
||||
]);
|
||||
|
||||
$restock->items()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'restockable_type' => Perfume::class,
|
||||
'restockable_id' => $perfume->id,
|
||||
'quantity' => 10,
|
||||
]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->call('delete', $restock->id);
|
||||
|
||||
$this->assertSoftDeleted('restocks', ['id' => $restock->id]);
|
||||
|
||||
// Verify Stock Reversal
|
||||
$this->assertEquals(100, $warehouse->perfumes()->find($perfume->id)->pivot->stock); // 90 + 10
|
||||
$this->assertEquals(0, $this->outlet->perfumes()->find($perfume->id)->pivot->stock); // 10 - 10
|
||||
});
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
use App\Enums\StockOpnameStatus;
|
||||
use App\Livewire\Studio\Manage\StockOpname\Index;
|
||||
use App\Livewire\Studio\Manage\StockOpname\Manage;
|
||||
use App\Models\Perfume;
|
||||
use App\Models\StockOpname;
|
||||
use App\Models\StockOpnameItem;
|
||||
@ -18,9 +17,8 @@
|
||||
$permissions = [
|
||||
'view stock opname',
|
||||
'create stock opname',
|
||||
'manage stock opname',
|
||||
'show stock opname',
|
||||
'delete stock opname',
|
||||
'manage stock opname', // Used in Manage but Index might need it for buttons
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
@ -38,37 +36,6 @@
|
||||
->assertStatus(200);
|
||||
});
|
||||
|
||||
it('can update physical quantity in manage page', function () {
|
||||
// Create pre-existing StockOpname
|
||||
$stockOpname = StockOpname::create([
|
||||
'outlet_id' => $this->outlet->id,
|
||||
'period_month' => now()->format('Y-m'),
|
||||
'status' => StockOpnameStatus::PROCESS,
|
||||
]);
|
||||
|
||||
$perfume = Perfume::factory()->create();
|
||||
$item = StockOpnameItem::create([
|
||||
'stock_opname_id' => $stockOpname->id,
|
||||
'user_id' => $this->user->id,
|
||||
'itemable_type' => Perfume::class,
|
||||
'itemable_id' => $perfume->id,
|
||||
'qty_system' => 10,
|
||||
]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Manage::class, ['stockOpname' => $stockOpname])
|
||||
->set('form.outlet_stock.'.$item->id, 8) // Physical count is 8
|
||||
->assertSet('form.outlet_stock.'.$item->id, 8);
|
||||
|
||||
// Manage component updates via updated hook, or explicitly called?
|
||||
// Manage.php: updated(...) calls form->update().
|
||||
|
||||
$this->assertDatabaseHas('stock_opname_items', [
|
||||
'id' => $item->id,
|
||||
'qty_physical' => 8,
|
||||
]);
|
||||
});
|
||||
|
||||
it('can request approval for stock opname', function () {
|
||||
$stockOpname = StockOpname::create([
|
||||
'outlet_id' => $this->outlet->id,
|
||||
@ -79,7 +46,7 @@
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Index::class)
|
||||
->call('requestApproval', $stockOpname->id); // Passing ID or Model? Method signature says Model. Livewire handles ID binding.
|
||||
->call('requestApproval', $stockOpname->id);
|
||||
|
||||
$this->assertDatabaseHas('stock_opname', [
|
||||
'id' => $stockOpname->id,
|
||||
@ -95,7 +62,6 @@
|
||||
]);
|
||||
|
||||
$perfume = Perfume::factory()->create();
|
||||
// Verify initial stock of perfume in outlet (empty or 0)
|
||||
// Attach to outlet first to mimic existing stock
|
||||
$this->outlet->perfumes()->attach($perfume->id, ['stock' => 10]);
|
||||
|
||||
@ -120,15 +86,3 @@
|
||||
// Verify outlet stock updated
|
||||
$this->assertEquals(8, $this->outlet->perfumes()->find($perfume->id)->pivot->stock);
|
||||
});
|
||||
|
||||
it('cannot manage stock opname if not in process status', function () {
|
||||
$stockOpname = StockOpname::create([
|
||||
'outlet_id' => $this->outlet->id,
|
||||
'period_month' => now()->format('Y-m'),
|
||||
'status' => StockOpnameStatus::COMPLETED,
|
||||
]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Manage::class, ['stockOpname' => $stockOpname])
|
||||
->assertForbidden();
|
||||
});
|
||||
69
tests/Feature/Studio/Manage/StockOpname/ManageTest.php
Normal file
69
tests/Feature/Studio/Manage/StockOpname/ManageTest.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\StockOpnameStatus;
|
||||
use App\Livewire\Studio\Manage\StockOpname\Manage;
|
||||
use App\Models\Perfume;
|
||||
use App\Models\StockOpname;
|
||||
use App\Models\StockOpnameItem;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->setupUser();
|
||||
$this->outlet = $this->user->outlets->first();
|
||||
|
||||
// Create permissions
|
||||
$permissions = [
|
||||
'view stock opname',
|
||||
'manage stock opname',
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
Permission::firstOrCreate(['name' => $permission]);
|
||||
}
|
||||
|
||||
$role = Role::create(['name' => 'Owner']);
|
||||
$role->givePermissionTo($permissions);
|
||||
$this->user->assignRole($role);
|
||||
});
|
||||
|
||||
it('can update physical quantity in manage page', function () {
|
||||
// Create pre-existing StockOpname
|
||||
$stockOpname = StockOpname::create([
|
||||
'outlet_id' => $this->outlet->id,
|
||||
'period_month' => now()->format('Y-m'),
|
||||
'status' => StockOpnameStatus::PROCESS,
|
||||
]);
|
||||
|
||||
$perfume = Perfume::factory()->create();
|
||||
$item = StockOpnameItem::create([
|
||||
'stock_opname_id' => $stockOpname->id,
|
||||
'user_id' => $this->user->id,
|
||||
'itemable_type' => Perfume::class,
|
||||
'itemable_id' => $perfume->id,
|
||||
'qty_system' => 10,
|
||||
]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Manage::class, ['stockOpname' => $stockOpname])
|
||||
->set('form.outlet_stock.' . $item->id, 8) // Physical count is 8
|
||||
->assertSet('form.outlet_stock.' . $item->id, 8);
|
||||
|
||||
$this->assertDatabaseHas('stock_opname_items', [
|
||||
'id' => $item->id,
|
||||
'qty_physical' => 8,
|
||||
]);
|
||||
});
|
||||
|
||||
it('cannot manage stock opname if not in process status', function () {
|
||||
$stockOpname = StockOpname::create([
|
||||
'outlet_id' => $this->outlet->id,
|
||||
'period_month' => now()->format('Y-m'),
|
||||
'status' => StockOpnameStatus::COMPLETED,
|
||||
]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Manage::class, ['stockOpname' => $stockOpname])
|
||||
->assertForbidden();
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user