test: Add feature tests for various models including Announcement, Category, Cooperation, and more to ensure proper relationships and factory functionality.

This commit is contained in:
Yoga Pangestu 2026-03-17 22:30:20 +07:00
parent 374a2e0d10
commit 21be2fbb5e
33 changed files with 698 additions and 0 deletions

View File

@ -0,0 +1,20 @@
<?php
use App\Models\Announcement;
use App\Models\AnnouncementMedia;
use App\Models\PartnerMedia;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('announcement media relation works', function () {
$announcement = Announcement::factory()->create();
$media = PartnerMedia::factory()->create();
$announcementMedia = AnnouncementMedia::factory()->create([
'announcement_id' => $announcement->id,
'partner_media_id' => $media->id,
]);
expect($announcementMedia->announcement->id)->toBe($announcement->id);
expect($announcementMedia->partnerMedia->id)->toBe($media->id);
});

View File

@ -0,0 +1,13 @@
<?php
use App\Enums\AnnouncementType;
use App\Models\Announcement;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('announcement can be created using factory', function () {
$announcement = Announcement::factory()->create(['title' => 'Test Promo']);
expect($announcement->title)->toBe('Test Promo');
expect($announcement->type)->toBe(AnnouncementType::PUBLIC);
});

View File

@ -0,0 +1,21 @@
<?php
use App\Models\Category;
use App\Models\CategoryNews;
use App\Models\News;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('category news relation works', function () {
$news = News::factory()->create();
$category = Category::factory()->create();
$categoryNews = CategoryNews::factory()->create([
'news_id' => $news->id,
'category_id' => $category->id,
]);
expect($categoryNews->news->id)->toBe($news->id);
expect($categoryNews->category->id)->toBe($category->id);
});

View File

@ -0,0 +1,13 @@
<?php
use App\Enums\IsActive;
use App\Models\Category;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('category can be created using factory', function () {
$category = Category::factory()->create(['name' => 'Politik']);
expect($category->name)->toBe('Politik');
expect($category->is_active)->toBe(IsActive::ACTIVE);
});

View File

@ -0,0 +1,56 @@
<?php
use App\Enums\IsActive;
use App\Models\Classification;
use App\Models\SubClassification;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('classification has correct fillable/guarded properties', function () {
$classification = new Classification;
expect($classification->getGuarded())->toBe(['id']);
});
test('classification has correct casts', function () {
$classification = new Classification;
expect($classification->getCasts())->toHaveKey('is_active', IsActive::class);
expect($classification->getCasts())->toHaveKey('deleted_at', 'datetime');
});
test('classification can be created using factory', function () {
$classification = Classification::factory()->create([
'name' => 'Test Classification',
]);
expect($classification->name)->toBe('Test Classification');
$this->assertDatabaseHas('classifications', [
'id' => $classification->id,
'name' => 'Test Classification',
]);
});
test('classification active scope filters correctly', function () {
Classification::factory()->count(3)->active()->create();
Classification::factory()->count(2)->inactive()->create();
expect(Classification::active()->count())->toBe(3);
});
test('classification inactive scope filters correctly', function () {
Classification::factory()->count(3)->active()->create();
Classification::factory()->count(2)->inactive()->create();
expect(Classification::inactive()->count())->toBe(2);
});
test('classification has many sub classifications', function () {
$classification = Classification::factory()->create();
// We need SubClassification factory for this, but let's just check the relation type for now
// or create a quick test without factory if it's not ready.
expect($classification->subClassifications())->toBeInstanceOf(HasMany::class);
});

View File

@ -0,0 +1,46 @@
<?php
use App\Models\Company;
use App\Models\User;
use App\Models\VerificationRequest;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('company has correct guarded properties', function () {
$company = new Company;
expect($company->getGuarded())->toBe(['id']);
});
test('company can be created using factory', function () {
$company = Company::factory()->create([
'name' => 'PT Media Maju',
]);
expect($company->name)->toBe('PT Media Maju');
$this->assertDatabaseHas('companies', ['name' => 'PT Media Maju']);
});
test('company belongs to a user', function () {
$user = User::factory()->create();
$company = Company::factory()->create(['user_id' => $user->id]);
expect($company->user)->toBeInstanceOf(User::class);
expect($company->user->id)->toBe($user->id);
});
test('company has one verification request', function () {
$company = Company::factory()->create();
$request = VerificationRequest::factory()->create(['company_id' => $company->id]);
expect($company->verificationRequest)->toBeInstanceOf(VerificationRequest::class);
expect($company->verificationRequest->id)->toBe($request->id);
});
test('company has static method for data change labels', function () {
$labels = Company::dataChangeEntryLabels();
expect($labels)->toBeArray();
expect($labels)->toHaveKey('name', 'Nama');
expect($labels)->toHaveKey('director_nik', 'NIK Direktur');
});

View File

@ -0,0 +1,11 @@
<?php
use App\Models\Contact;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('contact can be created', function () {
$contact = Contact::factory()->create(['email' => 'user@test.com']);
expect($contact->email)->toBe('user@test.com');
});

View File

@ -0,0 +1,13 @@
<?php
use App\Models\Classification;
use App\Models\ContentRecap;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('content recap belongs to classification', function () {
$recap = ContentRecap::factory()->create(['title' => 'Weekly Recap']);
expect($recap->title)->toBe('Weekly Recap');
expect($recap->classification)->toBeInstanceOf(Classification::class);
});

View File

@ -0,0 +1,21 @@
<?php
use App\Models\Cooperation;
use App\Models\CooperationMedia;
use App\Models\PartnerMedia;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('cooperation media relation works', function () {
$cooperation = Cooperation::factory()->create();
$media = PartnerMedia::factory()->create();
$coopMedia = CooperationMedia::factory()->create([
'cooperation_id' => $cooperation->id,
'partner_media_id' => $media->id,
]);
expect($coopMedia->cooperation->id)->toBe($cooperation->id);
expect($coopMedia->partnerMedia->id)->toBe($media->id);
});

View File

@ -0,0 +1,18 @@
<?php
use App\Models\CooperationMedia;
use App\Models\CooperationPayment;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('cooperation payment can be created', function () {
$coopMedia = CooperationMedia::factory()->create();
$payment = CooperationPayment::factory()->create([
'cooperation_media_id' => $coopMedia->id,
'amount' => 5000000,
]);
expect($payment->amount)->toBe(5000000);
expect($payment->cooperationMedia->id)->toBe($coopMedia->id);
});

View File

@ -0,0 +1,15 @@
<?php
use App\Enums\ApprovalStatus;
use App\Models\CooperationProposal;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('cooperation proposal can be created', function () {
$proposal = CooperationProposal::factory()->create([
'status' => ApprovalStatus::PENDING,
]);
expect($proposal->status)->toBe(ApprovalStatus::PENDING);
});

View File

@ -0,0 +1,12 @@
<?php
use App\Enums\CooperationStatus;
use App\Models\Cooperation;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('cooperation can be created using factory', function () {
$cooperation = Cooperation::factory()->create();
expect($cooperation->status)->toBe(CooperationStatus::PENDING);
});

View File

@ -0,0 +1,21 @@
<?php
use App\Enums\DataChangeStatus;
use App\Models\Company;
use App\Models\DataChangeRequest;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('data change request can be created', function () {
$company = Company::factory()->create();
$request = DataChangeRequest::factory()->create([
'entity_type' => Company::class,
'entity_id' => $company->id,
'status' => DataChangeStatus::PENDING,
]);
expect($request->status)->toBe(DataChangeStatus::PENDING);
expect($request->entity)->toBeInstanceOf(Company::class);
expect($request->entity->id)->toBe($company->id);
});

View File

@ -0,0 +1,19 @@
<?php
use App\Enums\DataChangeDecision;
use App\Models\DataChangeRequest;
use App\Models\DataChangeReview;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('data change review works', function () {
$request = DataChangeRequest::factory()->create();
$review = DataChangeReview::factory()->create([
'data_change_request_id' => $request->id,
'decision' => DataChangeDecision::APPROVED,
]);
expect($request->review->id)->toBe($review->id);
expect($review->request->id)->toBe($request->id);
});

View File

@ -0,0 +1,13 @@
<?php
use App\Enums\IsActive;
use App\Models\Department;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('department can be created', function () {
$dept = Department::factory()->create(['name' => 'IT Research', 'alias' => 'ITR']);
expect($dept->name)->toBe('IT Research');
expect($dept->is_active)->toBe(IsActive::ACTIVE);
});

View File

@ -0,0 +1,27 @@
<?php
use App\Enums\IssueSentiment;
use App\Models\Classification;
use App\Models\IssueManagement;
use App\Models\Location;
use App\Models\MediaMonitoring;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('issue management relates monitoring and location', function () {
$location = Location::factory()->create();
$classification = Classification::factory()->create();
$monitoring = MediaMonitoring::factory()->create();
$issue = IssueManagement::factory()->create([
'location_id' => $location->id,
'classification_id' => $classification->id,
'media_monitoring_id' => $monitoring->id,
'issue' => IssueSentiment::POSITIVE,
]);
expect($issue->issue)->toBe(IssueSentiment::POSITIVE);
expect($issue->location->id)->toBe($location->id);
expect($issue->mediaMonitoring->id)->toBe($monitoring->id);
});

View File

@ -0,0 +1,14 @@
<?php
use App\Models\Journalist;
use App\Models\PartnerMedia;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('journalist belongs to partner media', function () {
$media = PartnerMedia::factory()->create();
$journalist = Journalist::factory()->create(['partner_media_id' => $media->id]);
expect($journalist->partnerMedia->id)->toBe($media->id);
});

View File

@ -0,0 +1,13 @@
<?php
use App\Enums\IsActive;
use App\Models\Location;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('location can be created', function () {
$location = Location::factory()->create(['name' => 'Purwakarta']);
expect($location->name)->toBe('Purwakarta');
expect($location->is_active)->toBe(IsActive::ACTIVE);
});

View File

@ -0,0 +1,11 @@
<?php
use App\Models\MediaMonitoring;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('media monitoring can be created', function () {
$monitoring = MediaMonitoring::factory()->create(['media_name' => 'Tempo']);
expect($monitoring->media_name)->toBe('Tempo');
});

View File

@ -0,0 +1,21 @@
<?php
use App\Models\MediaMonitoring;
use App\Models\MediaMonitoringTheme;
use App\Models\Theme;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('media monitoring theme relation works', function () {
$monitoring = MediaMonitoring::factory()->create();
$theme = Theme::factory()->create();
$mmt = MediaMonitoringTheme::factory()->create([
'media_monitoring_id' => $monitoring->id,
'theme_id' => $theme->id,
]);
expect($mmt->mediaMonitoring->id)->toBe($monitoring->id);
expect($mmt->theme->id)->toBe($theme->id);
expect($monitoring->themes->first()->id)->toBe($theme->id);
});

View File

@ -0,0 +1,15 @@
<?php
use App\Models\MediaTaskAssignment;
use App\Models\Report;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('report relates to media task assignment', function () {
$mta = MediaTaskAssignment::factory()->create();
$report = Report::factory()->create(['media_task_assignment_id' => $mta->id]);
expect($report->mediaTaskAssignment->id)->toBe($mta->id);
expect($mta->reports)->toHaveCount(1);
});

View File

@ -0,0 +1,15 @@
<?php
use App\Models\News;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('news can be created using factory', function () {
$news = News::factory()->create([
'title' => 'Kabar Purwakarta',
'slug' => 'kabar-purwakarta',
]);
expect($news->title)->toBe('Kabar Purwakarta');
expect($news->slug)->toBe('kabar-purwakarta');
});

View File

@ -0,0 +1,14 @@
<?php
use App\Models\Journalist;
use App\Models\PartnerMedia;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('partner media has journalists', function () {
$media = PartnerMedia::factory()->create();
Journalist::factory()->count(2)->create(['partner_media_id' => $media->id]);
expect($media->journalists)->toHaveCount(2);
});

View File

@ -0,0 +1,19 @@
<?php
use App\Models\RejectionReason;
use App\Models\Report;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('rejection reason uses polymorphic relation', function () {
$report = Report::factory()->create();
$rejection = RejectionReason::factory()->create([
'rejectable_type' => Report::class,
'rejectable_id' => $report->id,
'reason' => 'Invalid link',
]);
expect($rejection->reason)->toBe('Invalid link');
expect($rejection->rejectable)->toBeInstanceOf(Report::class);
});

View File

@ -0,0 +1,12 @@
<?php
use App\Enums\ApprovalStatus;
use App\Models\Report;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('report can be created and has status', function () {
$report = Report::factory()->create(['status' => ApprovalStatus::PENDING]);
expect($report->status)->toBe(ApprovalStatus::PENDING);
});

View File

@ -0,0 +1,28 @@
<?php
use App\Models\Classification;
use App\Models\SubClassification;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('sub classification can be created using factory', function () {
$sub = SubClassification::factory()->create(['name' => 'Sub Test']);
expect($sub->name)->toBe('Sub Test');
expect($sub->classification)->toBeInstanceOf(Classification::class);
});
test('sub classification belongs to a classification', function () {
$parent = Classification::factory()->create();
$sub = SubClassification::factory()->create(['classification_id' => $parent->id]);
expect($sub->classification->id)->toBe($parent->id);
});
test('classification has many sub classifications relationship works', function () {
$parent = Classification::factory()->create();
SubClassification::factory()->count(3)->create(['classification_id' => $parent->id]);
expect($parent->subClassifications)->toHaveCount(3);
});

View File

@ -0,0 +1,15 @@
<?php
use App\Models\Location;
use App\Models\SubLocation;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('sub location belongs to location', function () {
$parent = Location::factory()->create();
$sub = SubLocation::factory()->create(['location_id' => $parent->id]);
expect($sub->location->id)->toBe($parent->id);
expect($parent->subLocations)->toHaveCount(1);
});

View File

@ -0,0 +1,15 @@
<?php
use App\Models\Cooperation;
use App\Models\TaskAssignment;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('task assignment works', function () {
$cooperation = Cooperation::factory()->create();
$task = TaskAssignment::factory()->create(['cooperation_id' => $cooperation->id]);
expect($task->cooperation->id)->toBe($cooperation->id);
expect($cooperation->taskAssignment->id)->toBe($task->id);
});

View File

@ -0,0 +1,13 @@
<?php
use App\Enums\IsActive;
use App\Models\Theme;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('theme can be created', function () {
$theme = Theme::factory()->create(['name' => 'Politik']);
expect($theme->name)->toBe('Politik');
expect($theme->is_active)->toBe(IsActive::ACTIVE);
});

View File

@ -0,0 +1,57 @@
<?php
use App\Enums\IsActive;
use App\Models\User;
use Filament\Panel;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
uses(RefreshDatabase::class);
test('user has correct fillable/guarded properties', function () {
$user = new User;
expect($user->getGuarded())->toBe(['id']);
});
test('user has correct casts', function () {
$user = new User;
expect($user->getCasts())->toHaveKey('password', 'hashed');
expect($user->getCasts())->toHaveKey('is_active', IsActive::class);
});
test('user can be created using factory', function () {
$user = User::factory()->create([
'name' => 'John Doe',
'email' => 'john@example.com',
]);
expect($user->name)->toBe('John Doe');
expect(Hash::check('password', $user->password))->toBeTrue();
$this->assertDatabaseHas('users', ['email' => 'john@example.com']);
});
test('user active scope filters correctly', function () {
User::factory()->count(2)->create(['is_active' => IsActive::ACTIVE]);
User::factory()->count(1)->create(['is_active' => IsActive::INACTIVE]);
expect(User::active()->count())->toBe(2);
});
test('user can access panel if active', function () {
$user = User::factory()->create(['is_active' => IsActive::ACTIVE]);
// Default mock for Filament Panel if needed, but the method logic is simple
expect($user->canAccessPanel(mock(Panel::class)))->toBeTrue();
});
test('user cannot access panel if inactive', function () {
$user = User::factory()->create(['is_active' => IsActive::INACTIVE]);
expect($user->canAccessPanel(mock(Panel::class)))->toBeFalse();
});
test('user has company relation', function () {
$user = User::factory()->create();
expect($user->company())->toBeInstanceOf(HasOne::class);
});

View File

@ -0,0 +1,53 @@
<?php
use App\Enums\VerificationStatus;
use App\Models\Company;
use App\Models\User;
use App\Models\VerificationRequest;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('verification request has correct guarded properties', function () {
$request = new VerificationRequest;
expect($request->getGuarded())->toBe(['id']);
});
test('verification request has correct casts', function () {
$request = new VerificationRequest;
expect($request->getCasts())->toHaveKey('status', VerificationStatus::class);
});
test('verification request can be created using factory', function () {
$request = VerificationRequest::factory()->create();
expect($request->status)->toBe(VerificationStatus::PENDING);
$this->assertDatabaseHas('verification_requests', ['id' => $request->id]);
});
test('verification request scopes filter correctly', function () {
VerificationRequest::factory()->count(2)->approved()->create();
VerificationRequest::factory()->count(3)->pending()->create();
VerificationRequest::factory()->count(1)->rejected()->create();
VerificationRequest::factory()->count(1)->needRevision()->create();
expect(VerificationRequest::approved()->count())->toBe(2);
expect(VerificationRequest::pending()->count())->toBe(3);
expect(VerificationRequest::rejected()->count())->toBe(1);
expect(VerificationRequest::needRevision()->count())->toBe(1);
});
test('verification request belongs to company and user', function () {
$company = Company::factory()->create();
$user = User::factory()->create();
$request = VerificationRequest::factory()->create([
'company_id' => $company->id,
'submitted_by' => $user->id,
]);
expect($request->company)->toBeInstanceOf(Company::class);
expect($request->submittedBy)->toBeInstanceOf(User::class);
expect($request->company->id)->toBe($company->id);
expect($request->submittedBy->id)->toBe($user->id);
});

View File

@ -0,0 +1,31 @@
<?php
use App\Enums\DecisionAdmin;
use App\Models\User;
use App\Models\VerificationRequest;
use App\Models\VerificationReview;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('verification review can be created', function () {
$request = VerificationRequest::factory()->create();
$reviewer = User::factory()->create();
$review = VerificationReview::factory()->create([
'verification_request_id' => $request->id,
'reviewer_id' => $reviewer->id,
'decision' => DecisionAdmin::APPROVED,
]);
expect($review->decision)->toBe(DecisionAdmin::APPROVED);
expect($review->verificationRequest->id)->toBe($request->id);
expect($review->reviewer->id)->toBe($reviewer->id);
});
test('verification request has many reviews', function () {
$request = VerificationRequest::factory()->create();
VerificationReview::factory()->count(2)->create(['verification_request_id' => $request->id]);
expect($request->reviews)->toHaveCount(2);
});

View File

@ -0,0 +1,13 @@
<?php
use App\Models\User;
use App\Models\Visitor;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('visitor can be created', function () {
$visitor = Visitor::factory()->create(['ip' => '127.0.0.1']);
expect($visitor->ip)->toBe('127.0.0.1');
expect($visitor->user)->toBeInstanceOf(User::class);
});