257 lines
8.1 KiB
PHP
257 lines
8.1 KiB
PHP
<?php
|
|
|
|
use App\Enums\Day;
|
|
use App\Livewire\Studio\Master\Outlet\Create;
|
|
use App\Livewire\Studio\Master\Outlet\Index;
|
|
use App\Models\Employee;
|
|
use App\Models\Facility;
|
|
use App\Models\Outlet;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\Gate;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
use Livewire\Livewire;
|
|
use Spatie\Permission\Models\Permission;
|
|
use Spatie\Permission\Models\Role;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
$roles = collect(['Developer', 'Owner', 'Leader', 'Admin', 'Partner', 'Customer'])
|
|
->map(fn ($role) => Role::create(['name' => $role]));
|
|
|
|
$this->user = User::factory()
|
|
->active()
|
|
->has(Employee::factory())
|
|
->has(Outlet::factory()->count(5))
|
|
->create();
|
|
|
|
$this->user->roles()->attach($roles->pluck('id'));
|
|
});
|
|
|
|
function makeLivewireFile(string $name)
|
|
{
|
|
$file = UploadedFile::fake()->image($name, 100, 100);
|
|
$tmpId = Str::random(32);
|
|
$filename = $tmpId.'-'.base64_encode($file->getClientOriginalName()).'.'.$file->getClientOriginalExtension();
|
|
$path = "livewire-tmp/{$filename}";
|
|
|
|
Storage::disk('local')->putFileAs('livewire-tmp', $file, $filename);
|
|
|
|
return [
|
|
'tmpFilename' => $filename,
|
|
'name' => $file->getClientOriginalName(),
|
|
'extension' => $file->getClientOriginalExtension(),
|
|
'path' => storage_path("app/private/{$path}"),
|
|
'temporaryUrl' => url("livewire/preview-file/{$filename}"),
|
|
'size' => $file->getSize(),
|
|
];
|
|
}
|
|
|
|
function mountCreateComponent(User $user)
|
|
{
|
|
return Livewire::actingAs($user)->test(Create::class);
|
|
}
|
|
|
|
it('renders page successfully', function () {
|
|
mountCreateComponent($this->user)
|
|
->assertViewIs('livewire.studio.master.outlet.form')
|
|
->assertViewHas('pageTitle', 'Tambah Outlet');
|
|
});
|
|
|
|
it('mounts days and form opening_hours correctly', function () {
|
|
$component = mountCreateComponent($this->user);
|
|
$days = Day::cases();
|
|
|
|
expect($component->days)->toHaveCount(count($days));
|
|
|
|
foreach ($days as $day) {
|
|
expect(array_key_exists($day->value, $component->form->opening_hours))->toBeTrue();
|
|
expect($component->form->opening_hours[$day->value])->toBe(['open_time' => null, 'close_time' => null]);
|
|
}
|
|
});
|
|
|
|
it('prevents create when user is unauthorized', function () {
|
|
Gate::define('create outlet', fn () => false);
|
|
|
|
mountCreateComponent($this->user)
|
|
->call('save')
|
|
->assertForbidden();
|
|
});
|
|
|
|
it('saves outlet successfully when authorized', function () {
|
|
$permission = Permission::create(['name' => 'create outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outlet = Outlet::factory()->operational()->raw();
|
|
$facilities = Facility::factory()->count(5)->raw();
|
|
|
|
$featuredImage = makeLivewireFile('featured.jpg');
|
|
$images = [];
|
|
|
|
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($outlet, [
|
|
'opening_hours' => $openingHours,
|
|
'facilities' => collect($facilities)->pluck('name')->toArray(),
|
|
'featured_image' => [$featuredImage],
|
|
'images' => $images,
|
|
]);
|
|
|
|
mountCreateComponent($this->user)
|
|
->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);
|
|
|
|
$outlet = Outlet::first();
|
|
|
|
$this->assertDatabaseHas('outlets', [
|
|
'id' => $outlet->id,
|
|
'name' => $data['name'],
|
|
'phone_number' => $data['phone_number'],
|
|
]);
|
|
|
|
$this->assertCount(1, $outlet->getMedia('featured_image'));
|
|
$this->assertCount(5, $outlet->getMedia('images'));
|
|
|
|
expect($outlet->getFirstMedia('featured_image')->getPath())->toBeFile();
|
|
foreach ($outlet->getMedia('images') as $media) {
|
|
expect($media->getPath())->toBeFile();
|
|
}
|
|
});
|
|
|
|
it('validates required fields', function () {
|
|
$permission = Permission::create(['name' => 'create outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
mountCreateComponent($this->user)
|
|
->call('save')
|
|
->assertHasErrors([
|
|
'form.name',
|
|
'form.phone_number',
|
|
'form.address',
|
|
'form.landmark',
|
|
'form.opening_hours',
|
|
'form.facilities',
|
|
'form.opened_date',
|
|
'form.featured_image',
|
|
'form.images',
|
|
]);
|
|
});
|
|
|
|
it('validates name field max length', function () {
|
|
$permission = Permission::create(['name' => 'create outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
mountCreateComponent($this->user)
|
|
->set('form.name', str_repeat('a', 101))
|
|
->call('save')
|
|
->assertHasErrors(['form.name']);
|
|
});
|
|
|
|
it('validates facilities minimum count', function () {
|
|
$permission = Permission::create(['name' => 'create outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
mountCreateComponent($this->user)
|
|
->set('form.facilities', [])
|
|
->call('save')
|
|
->assertHasErrors(['form.facilities']);
|
|
});
|
|
|
|
it('validates featured image max count', function () {
|
|
$permission = Permission::create(['name' => 'create outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$featuredImages = [
|
|
makeLivewireFile('featured1.jpg'),
|
|
makeLivewireFile('featured2.jpg'),
|
|
];
|
|
|
|
mountCreateComponent($this->user)
|
|
->set('form.featured_image', $featuredImages)
|
|
->call('save')
|
|
->assertHasErrors(['form.featured_image']);
|
|
});
|
|
|
|
it('validates images max count', function () {
|
|
$permission = Permission::create(['name' => 'create outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$images = [];
|
|
for ($i = 1; $i <= 6; $i++) {
|
|
$images[] = makeLivewireFile("image{$i}.jpg");
|
|
}
|
|
|
|
mountCreateComponent($this->user)
|
|
->set('form.images', $images)
|
|
->call('save')
|
|
->assertHasErrors(['form.images']);
|
|
});
|
|
|
|
it('has default facilities value', function () {
|
|
$component = mountCreateComponent($this->user);
|
|
|
|
expect($component->form->facilities)->toBe(['Parkir']);
|
|
});
|
|
|
|
it('creates outlet with opening hours for all days', function () {
|
|
$permission = Permission::create(['name' => 'create outlet']);
|
|
$this->user->givePermissionTo($permission);
|
|
|
|
$outlet = Outlet::factory()->operational()->raw();
|
|
$featuredImage = makeLivewireFile('featured.jpg');
|
|
$images = [makeLivewireFile('image1.jpg')];
|
|
|
|
$openingHours = collect(Day::cases())
|
|
->mapWithKeys(fn ($day) => [
|
|
$day->value => [
|
|
'open_time' => '09:00',
|
|
'close_time' => '21:00',
|
|
],
|
|
])
|
|
->toArray();
|
|
|
|
mountCreateComponent($this->user)
|
|
->set('form.name', $outlet['name'])
|
|
->set('form.phone_number', $outlet['phone_number'])
|
|
->set('form.address', $outlet['address'])
|
|
->set('form.landmark', $outlet['landmark'])
|
|
->set('form.opened_date', $outlet['opened_date'])
|
|
->set('form.status', $outlet['status']->value)
|
|
->set('form.opening_hours', $openingHours)
|
|
->set('form.facilities', ['Parkir'])
|
|
->set('form.featured_image', [$featuredImage])
|
|
->set('form.images', $images)
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$createdOutlet = Outlet::first();
|
|
expect($createdOutlet->openingHours)->toHaveCount(count(Day::cases()));
|
|
});
|