@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Enums\ConsultationStatus;
|
||||
use App\Enums\UserRole;
|
||||
use App\Models\Consultation;
|
||||
use App\Models\Office;
|
||||
use App\Models\Project;
|
||||
use App\Models\Testimonial;
|
||||
use App\Models\User;
|
||||
use App\Support\SiteInfo;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Inertia\Testing\AssertableInertia as Assert;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdminCmsTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_guests_cannot_open_admin_pages()
|
||||
{
|
||||
$this->get(route('admin.projects.index'))->assertRedirect(route('login'));
|
||||
$this->get(route('admin.consultations.index'))->assertRedirect(route('login'));
|
||||
}
|
||||
|
||||
public function test_editor_can_manage_content_but_not_users()
|
||||
{
|
||||
$editor = User::factory()->create();
|
||||
|
||||
$this->actingAs($editor);
|
||||
|
||||
$this->get(route('admin.consultations.index'))->assertOk();
|
||||
$this->get(route('admin.projects.index'))->assertOk();
|
||||
$this->get(route('admin.company.edit'))->assertOk();
|
||||
$this->get(route('admin.testimonials.index'))->assertOk();
|
||||
$this->get(route('admin.users.index'))->assertForbidden();
|
||||
$this->post(route('admin.users.store'), [])->assertForbidden();
|
||||
}
|
||||
|
||||
public function test_admin_can_create_users()
|
||||
{
|
||||
$admin = User::factory()->admin()->create();
|
||||
|
||||
$this->actingAs($admin)
|
||||
->post(route('admin.users.store'), [
|
||||
'name' => 'Staf Marketing',
|
||||
'email' => 'marketing@probindo.com',
|
||||
'role' => 'editor',
|
||||
'password' => 'Rahasia#2026',
|
||||
'password_confirmation' => 'Rahasia#2026',
|
||||
])
|
||||
->assertSessionHasNoErrors();
|
||||
|
||||
$user = User::query()->where('email', 'marketing@probindo.com')->sole();
|
||||
$this->assertSame(UserRole::Editor, $user->role);
|
||||
$this->assertNotNull($user->email_verified_at);
|
||||
}
|
||||
|
||||
public function test_admin_cannot_delete_or_demote_themselves()
|
||||
{
|
||||
$admin = User::factory()->admin()->create();
|
||||
|
||||
$this->actingAs($admin)
|
||||
->put(route('admin.users.update', $admin), [
|
||||
'name' => $admin->name,
|
||||
'email' => $admin->email,
|
||||
'role' => 'editor',
|
||||
])
|
||||
->assertSessionHasNoErrors();
|
||||
|
||||
$this->assertSame(UserRole::Admin, $admin->fresh()->role);
|
||||
|
||||
$this->delete(route('admin.users.destroy', $admin))->assertForbidden();
|
||||
}
|
||||
|
||||
public function test_projects_can_be_managed_and_appear_on_the_site()
|
||||
{
|
||||
$this->actingAs(User::factory()->create())
|
||||
->post(route('admin.projects.store'), [
|
||||
'title' => 'Implementasi Odoo',
|
||||
'client' => 'PT Contoh',
|
||||
'year' => 2026,
|
||||
'sector' => 'private',
|
||||
'program' => 'erp',
|
||||
])
|
||||
->assertSessionHasNoErrors();
|
||||
|
||||
$project = Project::query()->sole();
|
||||
|
||||
$this->get(route('clients'))->assertInertia(fn (Assert $page) => $page
|
||||
->has('projects', 1)
|
||||
->where('projects.0.title', 'Implementasi Odoo'));
|
||||
|
||||
$this->put(route('admin.projects.update', $project), [
|
||||
'title' => 'Implementasi Odoo Enterprise',
|
||||
'client' => 'PT Contoh',
|
||||
'year' => 2026,
|
||||
'sector' => 'private',
|
||||
'program' => '',
|
||||
])->assertSessionHasNoErrors();
|
||||
|
||||
$this->assertNull($project->fresh()->program);
|
||||
|
||||
$this->delete(route('admin.projects.destroy', $project));
|
||||
$this->assertDatabaseCount('projects', 0);
|
||||
}
|
||||
|
||||
public function test_consultation_status_can_be_updated()
|
||||
{
|
||||
$consultation = Consultation::query()->create([
|
||||
'source' => 'home',
|
||||
'name' => 'Budi',
|
||||
'email' => 'budi@example.com',
|
||||
'phone' => '0811',
|
||||
]);
|
||||
|
||||
$this->actingAs(User::factory()->create())
|
||||
->put(route('admin.consultations.update', $consultation), [
|
||||
'status' => 'contacted',
|
||||
'admin_notes' => 'Sudah ditelepon.',
|
||||
])
|
||||
->assertSessionHasNoErrors();
|
||||
|
||||
$consultation->refresh();
|
||||
$this->assertSame(ConsultationStatus::Contacted, $consultation->status);
|
||||
$this->assertSame('Sudah ditelepon.', $consultation->admin_notes);
|
||||
}
|
||||
|
||||
public function test_company_changes_refresh_the_shared_site_info()
|
||||
{
|
||||
$this->assertSame('busdev@probindo.com', SiteInfo::get()['contact']['email_busdev']);
|
||||
|
||||
$this->actingAs(User::factory()->create())
|
||||
->put(route('admin.company.contact.update'), [
|
||||
'phone' => '(021) 1111-2222',
|
||||
'whatsapp' => '0811-1111-2222',
|
||||
'email_busdev' => 'sales@probindo.com',
|
||||
'email_support' => 'support@probindo.com',
|
||||
])
|
||||
->assertSessionHasNoErrors();
|
||||
|
||||
$this->post(route('admin.offices.store'), [
|
||||
'name' => 'Kantor Baru',
|
||||
'icon' => 'apartment',
|
||||
'building' => 'Gedung A',
|
||||
'street' => 'Jl. Contoh',
|
||||
'area' => 'Kebayoran',
|
||||
'city' => 'Jakarta 12345',
|
||||
'district' => 'Jakarta Selatan',
|
||||
'phone' => '(021) 1111-2222',
|
||||
'sort_order' => 1,
|
||||
])->assertSessionHasNoErrors();
|
||||
|
||||
$site = SiteInfo::get();
|
||||
$this->assertSame('sales@probindo.com', $site['contact']['email_busdev']);
|
||||
$this->assertSame('Kantor Baru', $site['offices'][0]['name']);
|
||||
$this->assertSame(1, Office::query()->count());
|
||||
}
|
||||
|
||||
public function test_only_published_testimonials_reach_the_site()
|
||||
{
|
||||
$testimonial = Testimonial::query()->create([
|
||||
'quote_id' => 'Bagus', 'quote_en' => 'Great',
|
||||
'role_id' => 'Direktur', 'role_en' => 'Director',
|
||||
'organization_id' => 'PT A', 'organization_en' => 'PT A',
|
||||
'sort_order' => 1,
|
||||
]);
|
||||
|
||||
$this->get(route('clients'))->assertInertia(fn (Assert $page) => $page->has('testimonials', 1));
|
||||
|
||||
// An unchecked "publish" box is not submitted at all.
|
||||
$this->actingAs(User::factory()->create())
|
||||
->put(route('admin.testimonials.update', $testimonial), [
|
||||
'quote_id' => 'Bagus', 'quote_en' => 'Great',
|
||||
'role_id' => 'Direktur', 'role_en' => 'Director',
|
||||
'organization_id' => 'PT A', 'organization_en' => 'PT A',
|
||||
'sort_order' => 1,
|
||||
])
|
||||
->assertSessionHasNoErrors();
|
||||
|
||||
$this->assertFalse($testimonial->fresh()->is_published);
|
||||
$this->get(route('clients'))->assertInertia(fn (Assert $page) => $page->has('testimonials', 0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Enums\ConsultationStatus;
|
||||
use App\Models\Consultation;
|
||||
use App\Notifications\NewConsultationRequest;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Notifications\AnonymousNotifiable;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ConsultationRequestTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function payload(array $overrides = []): array
|
||||
{
|
||||
return [
|
||||
'source' => 'home',
|
||||
'name' => 'Budi Santoso',
|
||||
'email' => 'budi@example.com',
|
||||
'phone' => '0811 2345 678',
|
||||
'service' => 'Implementasi Odoo ERP',
|
||||
...$overrides,
|
||||
];
|
||||
}
|
||||
|
||||
public function test_visitor_request_is_saved_and_busdev_is_notified()
|
||||
{
|
||||
Notification::fake();
|
||||
|
||||
$this->from(route('home'))
|
||||
->post(route('consultations.store'), $this->payload())
|
||||
->assertRedirect(route('home'))
|
||||
->assertSessionHasNoErrors();
|
||||
|
||||
$consultation = Consultation::query()->sole();
|
||||
$this->assertSame('Budi Santoso', $consultation->name);
|
||||
$this->assertSame(ConsultationStatus::New, $consultation->status);
|
||||
$this->assertSame('id', $consultation->locale);
|
||||
|
||||
Notification::assertSentTo(
|
||||
new AnonymousNotifiable,
|
||||
NewConsultationRequest::class,
|
||||
fn ($notification, $channels, $notifiable) => $notifiable->routes['mail'] === 'busdev@probindo.com',
|
||||
);
|
||||
}
|
||||
|
||||
public function test_required_fields_are_validated()
|
||||
{
|
||||
Notification::fake();
|
||||
|
||||
$this->post(route('consultations.store'), $this->payload(['name' => '', 'email' => 'bukan-email']))
|
||||
->assertSessionHasErrors(['name', 'email']);
|
||||
|
||||
$this->assertDatabaseCount('consultations', 0);
|
||||
Notification::assertNothingSent();
|
||||
}
|
||||
|
||||
public function test_contact_form_requires_nda_consent()
|
||||
{
|
||||
$this->post(route('consultations.store'), $this->payload(['source' => 'contact']))
|
||||
->assertSessionHasErrors('nda_agreed');
|
||||
|
||||
$this->post(route('consultations.store'), $this->payload(['source' => 'contact', 'nda_agreed' => '1']))
|
||||
->assertSessionHasNoErrors();
|
||||
|
||||
$this->assertTrue(Consultation::query()->sole()->nda_agreed);
|
||||
}
|
||||
|
||||
public function test_honeypot_submissions_are_rejected()
|
||||
{
|
||||
$this->post(route('consultations.store'), $this->payload(['website' => 'http://spam.test']))
|
||||
->assertSessionHasErrors('website');
|
||||
|
||||
$this->assertDatabaseCount('consultations', 0);
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,15 @@
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Inertia\Testing\AssertableInertia as Assert;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Tests\TestCase;
|
||||
|
||||
class SitePagesTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
* @return array<string, array{string, string}>
|
||||
*/
|
||||
@@ -30,6 +33,18 @@ class SitePagesTest extends TestCase
|
||||
->assertInertia(fn (Assert $page) => $page->component($component));
|
||||
}
|
||||
|
||||
public function test_admin_login_page_renders()
|
||||
{
|
||||
$this->get(route('login'))
|
||||
->assertOk()
|
||||
->assertInertia(fn (Assert $page) => $page->component('auth/login'));
|
||||
}
|
||||
|
||||
public function test_public_registration_is_disabled()
|
||||
{
|
||||
$this->get('/register')->assertNotFound();
|
||||
}
|
||||
|
||||
public function test_site_defaults_to_indonesian()
|
||||
{
|
||||
$this->get(route('home'))
|
||||
|
||||
Reference in New Issue
Block a user