diff --git a/app/Models/Outlet.php b/app/Models/Outlet.php index ccb105e..b698a9c 100644 --- a/app/Models/Outlet.php +++ b/app/Models/Outlet.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Enums\OutletStatus; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\SoftDeletes; @@ -11,7 +12,7 @@ class Outlet extends Model { - use HasSlug, SoftDeletes; + use HasFactory, HasSlug, SoftDeletes; protected $guarded = ['id']; diff --git a/database/factories/OutletFactory.php b/database/factories/OutletFactory.php new file mode 100644 index 0000000..21bc861 --- /dev/null +++ b/database/factories/OutletFactory.php @@ -0,0 +1,66 @@ + $this->faker->company(), + 'phone_number' => sprintf( + '%04d %04d %03d', + $this->faker->numberBetween(8000, 8999), + $this->faker->numberBetween(1000, 9999), + $this->faker->numberBetween(100, 999) + ), + 'address' => $this->faker->address(), + 'landmark' => $this->faker->streetName(), + 'maps_url' => 'https://goo.gl/maps/'.$this->faker->regexify('[A-Za-z0-9]{6,10}'), + 'opening_hours' => collect(['senin', 'selasa', 'rabu', 'kamis', 'jumat', 'sabtu', 'minggu']) + ->mapWithKeys(fn ($day) => [ + $day => [ + 'open' => $this->faker->time('H:i'), + 'close' => $this->faker->time('H:i'), + ], + ]) + ->toArray(), + 'facilities' => $this->faker->randomElements( + ['WiFi', 'Parking', 'Toilet', 'Musholla', 'Smoking Area'], + $this->faker->numberBetween(1, 3) + ), + 'opened_date' => $this->faker->date(), + 'closed_date' => $this->faker->optional()->date(), + ]; + } + + public function operational(): Factory + { + return $this->state(function (array $attributes) { + return [ + 'status' => OutletStatus::OPERATIONAL, + ]; + }); + } + + public function underConstruction(): Factory + { + return $this->state(function (array $attributes) { + return [ + 'status' => OutletStatus::UNDER_CONSTRUCTION, + ]; + }); + } + + public function terminated(): Factory + { + return $this->state(function (array $attributes) { + return [ + 'status' => OutletStatus::TERMINATED, + ]; + }); + } +} diff --git a/tests/Feature/Livewire/Studio/Master/Outlet/CreateTest.php b/tests/Feature/Livewire/Studio/Master/Outlet/CreateTest.php new file mode 100644 index 0000000..e2ce11a --- /dev/null +++ b/tests/Feature/Livewire/Studio/Master/Outlet/CreateTest.php @@ -0,0 +1,37 @@ +assertViewIs('livewire.studio.master.outlet.form') + ->assertViewHas('pageTitle', 'Tambah Outlet'); +}); + +it('can create an outlet', function () { + $data = Outlet::factory()->operational()->raw(); + + Livewire::test(Create::class) + ->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.opening_hours', $data['opening_hours']) + ->set('form.facilities', $data['facilities']) + ->set('form.opened_date', $data['opened_date']) + ->set('form.status', $data['status']->value) + ->call('save') + ->assertRedirect(Index::class); + + $this->assertDatabaseHas('outlets', [ + 'name' => $data['name'], + 'phone_number' => $data['phone_number'], + ]); +}); diff --git a/tests/Feature/Livewire/Studio/Master/Outlet/EditTest.php b/tests/Feature/Livewire/Studio/Master/Outlet/EditTest.php new file mode 100644 index 0000000..5d10d0c --- /dev/null +++ b/tests/Feature/Livewire/Studio/Master/Outlet/EditTest.php @@ -0,0 +1,43 @@ +operational()->create(); + + Livewire::test(Edit::class, ['outlet' => $outlet]) + ->assertViewIs('livewire.studio.master.outlet.form') + ->assertViewHas('pageTitle', 'Ubah Outlet'); +}); + +it('can update an outlet', function () { + $outlet = Outlet::factory()->operational()->create(); + + $data = Outlet::factory()->operational()->raw(); + + Livewire::test(Edit::class, ['outlet' => $outlet]) + ->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.opening_hours', $data['opening_hours']) + ->set('form.facilities', $data['facilities']) + ->set('form.opened_date', $data['opened_date']) + ->set('form.status', $data['status']->value) + ->call('save') + ->assertDispatched('refreshDatatable') + ->assertRedirect(Index::class); + + $this->assertDatabaseHas('outlets', [ + 'id' => $outlet->id, + 'name' => $data['name'], + 'phone_number' => $data['phone_number'], + ]); +}); diff --git a/tests/Feature/Livewire/Studio/Master/Outlet/IndexTest.php b/tests/Feature/Livewire/Studio/Master/Outlet/IndexTest.php new file mode 100644 index 0000000..ffc5af2 --- /dev/null +++ b/tests/Feature/Livewire/Studio/Master/Outlet/IndexTest.php @@ -0,0 +1,38 @@ +assertViewIs('livewire.studio.master.outlet.index') + ->assertViewHas('pageTitle', 'Outlet'); +}); + +it('displays all outlets', function () { + Outlet::Factory() + ->count(10) + ->state(fn () => [ + 'status' => fake()->randomElement(OutletStatus::cases()), + ]) + ->create(); + + $outlet = Outlet::first(); + + Livewire::test(Index::class)->assertSee($outlet->name); +}); + +it('can delete an outlet', function () { + $outlet = Outlet::factory()->operational()->create(); + + Livewire::test(Index::class) + ->call('delete', $outlet) + ->assertDispatched('refreshDatatable'); + + expect(Outlet::count())->toBe(0); +});