- menyesuaikan testing - menghapus route untuk delete karena tidak lewat route - menyesuaikan tipe prop dan lainnya
347 lines
12 KiB
PHP
347 lines
12 KiB
PHP
<?php
|
|
|
|
require_once __DIR__.'/TestHelpers.php';
|
|
|
|
use App\Enums\Day;
|
|
use App\Enums\OutletStatus;
|
|
use App\Livewire\Studio\Master\Outlet\Edit;
|
|
use App\Livewire\Studio\Master\Outlet\Index;
|
|
use App\Models\Employee;
|
|
use App\Models\Facility;
|
|
use App\Models\OpeningHour;
|
|
use App\Models\Outlet;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Gate;
|
|
use Livewire\Livewire;
|
|
use Spatie\Permission\Models\Permission;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
$this->user = User::factory()
|
|
->active()
|
|
->has(Employee::factory())
|
|
->create();
|
|
});
|
|
|
|
function mountEditComponent(User $user, Outlet $outlet)
|
|
{
|
|
return Livewire::actingAs($user)->test(Edit::class, ['outlet' => $outlet]);
|
|
}
|
|
|
|
it('renders page successfully', function () {
|
|
$outlet = Outlet::factory()->operational()->create();
|
|
|
|
mountEditComponent($this->user, $outlet)
|
|
->assertViewIs('livewire.studio.master.outlet.form')
|
|
->assertViewHas('pageTitle', 'Ubah Outlet');
|
|
});
|
|
|
|
it('mounts days and sets form with outlet', function () {
|
|
$outlet = Outlet::factory()->operational()->create();
|
|
$component = mountEditComponent($this->user, $outlet);
|
|
|
|
$days = Day::cases();
|
|
expect($component->days)->toHaveCount(count($days));
|
|
expect($component->form->outlet->id)->toBe($outlet->id);
|
|
});
|
|
|
|
it('prevents update when user is unauthorized', function () {
|
|
$outlet = Outlet::factory()->operational()->create();
|
|
Gate::define('update outlet', fn () => false);
|
|
|
|
mountEditComponent($this->user, $outlet)
|
|
->call('save')
|
|
->assertForbidden();
|
|
});
|
|
|
|
it('updates outlet successfully when authorized', function () {
|
|
$permission = Permission::create(['name' => 'update outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outletModel = Outlet::factory()->operational()->create(); // model instance
|
|
$outletData = Outlet::factory()->operational()->raw(); // data for update
|
|
$facilities = Facility::factory()->count(5)->raw();
|
|
|
|
$featuredImage = makeLivewireFile('featured.jpg');
|
|
for ($i = 1; $i <= 5; $i++) {
|
|
$images[] = makeLivewireFile("image{$i}.jpg");
|
|
}
|
|
|
|
$openingHours = collect(Day::cases())
|
|
->mapWithKeys(fn ($day) => [
|
|
$day->value => [
|
|
'day' => $day->value,
|
|
'open_time' => fake()->time('H:i'),
|
|
'close_time' => fake()->time('H:i'),
|
|
],
|
|
])
|
|
->toArray();
|
|
|
|
$data = array_merge($outletData, [
|
|
'opening_hours' => $openingHours,
|
|
'facilities' => collect($facilities)->pluck('name')->toArray(),
|
|
'featured_image' => [$featuredImage],
|
|
'images' => $images,
|
|
]);
|
|
|
|
mountEditComponent($this->user, $outletModel)
|
|
->set('form.name', $data['name'])
|
|
->set('form.phone_number', $data['phone_number'])
|
|
->set('form.address', $data['address'])
|
|
->set('form.landmark', $data['landmark'])
|
|
->set('form.maps_url', $data['maps_url'])
|
|
->set('form.opened_date', $data['opened_date'])
|
|
->set('form.status', $data['status']->value)
|
|
->set('form.opening_hours', $data['opening_hours'])
|
|
->set('form.facilities', $data['facilities'])
|
|
->set('form.featured_image', $data['featured_image'])
|
|
->set('form.images', $data['images'])
|
|
->call('save')
|
|
->assertHasNoErrors()
|
|
->assertRedirect(Index::class);
|
|
|
|
$outletModel->refresh();
|
|
|
|
$this->assertDatabaseHas('outlets', [
|
|
'id' => $outletModel->id,
|
|
'name' => $data['name'],
|
|
'phone_number' => $data['phone_number'],
|
|
]);
|
|
|
|
$this->assertCount(1, $outletModel->getMedia('featured_image'));
|
|
$this->assertCount(5, $outletModel->getMedia('images'));
|
|
|
|
expect($outletModel->getFirstMedia('featured_image')->getPath())->toBeFile();
|
|
foreach ($outletModel->getMedia('images') as $media) {
|
|
expect($media->getPath())->toBeFile();
|
|
}
|
|
});
|
|
|
|
it('loads outlet data into form correctly', function () {
|
|
$outlet = Outlet::factory()
|
|
->operational()
|
|
->has(OpeningHour::factory()->count(7))
|
|
->has(Facility::factory()->count(3))
|
|
->create();
|
|
|
|
$component = mountEditComponent($this->user, $outlet);
|
|
|
|
expect($component->form->outlet->id)->toBe($outlet->id);
|
|
expect($component->form->name)->toBe($outlet->name);
|
|
expect($component->form->phone_number)->toBe($outlet->phone_number);
|
|
expect($component->form->address)->toBe($outlet->address);
|
|
expect($component->form->landmark)->toBe($outlet->landmark);
|
|
expect($component->form->status)->toBe($outlet->status->value);
|
|
expect($component->form->facilities)->toBe($outlet->facilities->pluck('name')->toArray());
|
|
});
|
|
|
|
it('loads opening hours into form correctly', function () {
|
|
$outlet = Outlet::factory()->operational()->create();
|
|
|
|
// Create specific opening hours
|
|
$openingHours = [];
|
|
foreach (Day::cases() as $day) {
|
|
$openingHours[] = OpeningHour::factory()->create([
|
|
'outlet_id' => $outlet->id,
|
|
'day' => $day,
|
|
'open_time' => '09:00',
|
|
'close_time' => '21:00',
|
|
]);
|
|
}
|
|
|
|
$component = mountEditComponent($this->user, $outlet);
|
|
|
|
foreach (Day::cases() as $day) {
|
|
expect($component->form->opening_hours[$day->value]['open_time'])->toBe('09:00');
|
|
expect($component->form->opening_hours[$day->value]['close_time'])->toBe('21:00');
|
|
}
|
|
});
|
|
|
|
it('updates outlet with partial data changes', function () {
|
|
$permission = Permission::create(['name' => 'update outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outlet = Outlet::factory()
|
|
->operational()
|
|
->has(Facility::factory()->count(2))
|
|
->create();
|
|
|
|
$newName = 'Updated Outlet Name';
|
|
$images = [makeLivewireFile('image1.jpg')];
|
|
|
|
$featuredImage = makeLivewireFile('featured.jpg');
|
|
|
|
mountEditComponent($this->user, $outlet)
|
|
->set('form.name', $newName)
|
|
->set('form.opening_hours', makeValidOpeningHours())
|
|
->set('form.facilities', ['Parkir'])
|
|
->set('form.featured_image', [$featuredImage])
|
|
->set('form.images', $images)
|
|
->call('save')
|
|
->assertHasNoErrors()
|
|
->assertRedirect(Index::class);
|
|
|
|
$outlet->refresh();
|
|
expect($outlet->name)->toBe($newName);
|
|
expect($outlet->phone_number)->toBe($outlet->phone_number); // Unchanged
|
|
});
|
|
|
|
it('updates outlet status to TERMINATED and sets closed_date', function () {
|
|
$permission = Permission::create(['name' => 'update outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outlet = Outlet::factory()->operational()->create();
|
|
$featuredImage = makeLivewireFile('featured.jpg');
|
|
$images = [makeLivewireFile('image1.jpg')];
|
|
|
|
mountEditComponent($this->user, $outlet)
|
|
->set('form.status', OutletStatus::TERMINATED->value)
|
|
->set('form.opening_hours', makeValidOpeningHours())
|
|
->set('form.facilities', ['Parkir'])
|
|
->set('form.featured_image', [$featuredImage])
|
|
->set('form.images', $images)
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$outlet->refresh();
|
|
expect($outlet->status->value)->toBe(OutletStatus::TERMINATED->value);
|
|
expect($outlet->closed_date)->not->toBeNull();
|
|
});
|
|
|
|
it('updates facilities correctly', function () {
|
|
$permission = Permission::create(['name' => 'update outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outlet = Outlet::factory()
|
|
->operational()
|
|
->has(Facility::factory()->count(2))
|
|
->create();
|
|
|
|
$featuredImage = makeLivewireFile('featured.jpg');
|
|
$images = [makeLivewireFile('image1.jpg')];
|
|
$newFacilities = ['WiFi', 'AC', 'Parking'];
|
|
|
|
mountEditComponent($this->user, $outlet)
|
|
->set('form.facilities', $newFacilities)
|
|
->set('form.opening_hours', makeValidOpeningHours())
|
|
->set('form.featured_image', [$featuredImage])
|
|
->set('form.images', $images)
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$outlet->refresh();
|
|
expect($outlet->facilities->pluck('name')->toArray())->toBe($newFacilities);
|
|
});
|
|
|
|
it('updates opening hours correctly', function () {
|
|
$permission = Permission::create(['name' => 'update outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outlet = Outlet::factory()->operational()->create();
|
|
$featuredImage = makeLivewireFile('featured.jpg');
|
|
$images = [makeLivewireFile('image1.jpg')];
|
|
|
|
$newOpeningHours = makeValidOpeningHours();
|
|
|
|
mountEditComponent($this->user, $outlet)
|
|
->set('form.opening_hours', $newOpeningHours)
|
|
->set('form.facilities', ['Parkir'])
|
|
->set('form.featured_image', [$featuredImage])
|
|
->set('form.images', $images)
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$outlet->refresh();
|
|
expect($outlet->openingHours)->toHaveCount(count(Day::cases()));
|
|
|
|
foreach ($outlet->openingHours as $openingHour) {
|
|
expect($openingHour->open_time)->toBe('09:00');
|
|
expect($openingHour->close_time)->toBe('21:00');
|
|
}
|
|
});
|
|
|
|
it('validates required fields on update', function () {
|
|
$permission = Permission::create(['name' => 'update outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outlet = Outlet::factory()->operational()->create();
|
|
|
|
mountEditComponent($this->user, $outlet)
|
|
->set('form.name', '') // Empty required field
|
|
->call('save')
|
|
->assertHasErrors(['form.name']);
|
|
});
|
|
|
|
it('maintains outlet relationships integrity', function () {
|
|
$permission = Permission::create(['name' => 'update outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outlet = Outlet::factory()
|
|
->operational()
|
|
->has(Facility::factory()->count(3))
|
|
->create();
|
|
|
|
$originalOpeningHoursCount = count(Day::cases()); // Should be 7 after setOutlet
|
|
$originalFacilitiesCount = 1; // We set facilities to ['Parkir'] in the test
|
|
|
|
$featuredImage = makeLivewireFile('featured.jpg');
|
|
$images = [makeLivewireFile('image1.jpg')];
|
|
|
|
mountEditComponent($this->user, $outlet)
|
|
->set('form.name', 'Updated Name')
|
|
->set('form.opening_hours', makeValidOpeningHours())
|
|
->set('form.facilities', ['Parkir'])
|
|
->set('form.featured_image', [$featuredImage])
|
|
->set('form.images', $images)
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$outlet->refresh();
|
|
expect($outlet->openingHours)->toHaveCount($originalOpeningHoursCount);
|
|
expect($outlet->facilities)->toHaveCount($originalFacilitiesCount);
|
|
});
|
|
|
|
it('handles outlet with no existing media', function () {
|
|
$permission = Permission::create(['name' => 'update outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outlet = Outlet::factory()->operational()->create();
|
|
$featuredImage = makeLivewireFile('featured.jpg');
|
|
$images = [makeLivewireFile('image1.jpg')];
|
|
|
|
mountEditComponent($this->user, $outlet)
|
|
->set('form.opening_hours', makeValidOpeningHours())
|
|
->set('form.facilities', ['Parkir'])
|
|
->set('form.featured_image', [$featuredImage])
|
|
->set('form.images', $images)
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$outlet->refresh();
|
|
expect($outlet->getMedia('featured_image'))->toHaveCount(1);
|
|
});
|
|
|
|
it('preserves outlet slug when updating', function () {
|
|
$permission = Permission::create(['name' => 'update outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outlet = Outlet::factory()->operational()->create();
|
|
$originalSlug = $outlet->slug;
|
|
$featuredImage = makeLivewireFile('featured.jpg');
|
|
$images = [makeLivewireFile('image1.jpg')];
|
|
|
|
mountEditComponent($this->user, $outlet)
|
|
->set('form.phone_number', '0812 3456 7890') // Change non-slug field
|
|
->set('form.opening_hours', makeValidOpeningHours())
|
|
->set('form.facilities', ['Parkir'])
|
|
->set('form.featured_image', [$featuredImage])
|
|
->set('form.images', $images)
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$outlet->refresh();
|
|
expect($outlet->slug)->toBe($originalSlug);
|
|
});
|