add controllers, servoices
This commit is contained in:
@@ -2,120 +2,54 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Models\AdminNotificationSubject;
|
||||
use App\Services\Administrator\AdminNotificationSubjectService;
|
||||
use App\Services\Administrator\AdminNotificationUserService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdminNotificationSubjectServiceTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_alerts_data_includes_admins(): void
|
||||
{
|
||||
Mockery::close();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function test_alerts_data_returns_expected_payload_when_table_exists(): void
|
||||
{
|
||||
DB::shouldReceive('getSchemaBuilder->hasTable')
|
||||
->once()
|
||||
->with('admin_notification_subjects')
|
||||
->andReturn(true);
|
||||
|
||||
$userService = Mockery::mock(AdminNotificationUserService::class);
|
||||
$userService->shouldReceive('fetchAdminNotificationUsers')
|
||||
->once()
|
||||
->andReturn([
|
||||
['id' => 1, 'firstname' => 'Admin', 'lastname' => 'One', 'email' => 'a1@test.com'],
|
||||
['id' => 2, 'firstname' => 'Admin', 'lastname' => 'Two', 'email' => 'a2@test.com'],
|
||||
]);
|
||||
|
||||
$row1 = (object) ['id' => 10, 'admin_id' => 1, 'subject' => 'academics'];
|
||||
$row2 = (object) ['id' => 11, 'admin_id' => 1, 'subject' => 'finance'];
|
||||
$row3 = (object) ['id' => 12, 'admin_id' => 2, 'subject' => 'general'];
|
||||
|
||||
AdminNotificationSubject::shouldReceive('query->select->whereIn->get')
|
||||
->once()
|
||||
->andReturn(collect([$row1, $row2, $row3]));
|
||||
|
||||
$service = new AdminNotificationSubjectService($userService);
|
||||
|
||||
$result = $service->alertsData();
|
||||
|
||||
$this->assertTrue($result['tableReady']);
|
||||
$this->assertCount(2, $result['admins']);
|
||||
$this->assertArrayHasKey('academics', $result['subjects']);
|
||||
$this->assertTrue($result['assignedSubjects'][1]['academics']);
|
||||
$this->assertTrue($result['assignedSubjects'][1]['finance']);
|
||||
$this->assertTrue($result['assignedSubjects'][2]['general']);
|
||||
}
|
||||
|
||||
public function test_save_returns_error_when_table_missing(): void
|
||||
{
|
||||
DB::shouldReceive('getSchemaBuilder->hasTable')
|
||||
->once()
|
||||
->with('admin_notification_subjects')
|
||||
->andReturn(false);
|
||||
|
||||
$userService = Mockery::mock(AdminNotificationUserService::class);
|
||||
$service = new AdminNotificationSubjectService($userService);
|
||||
|
||||
$result = $service->save([
|
||||
1 => ['academics'],
|
||||
DB::table('roles')->insert([
|
||||
['id' => 1, 'name' => 'Admin', 'slug' => 'admin', 'dashboard_route' => 'admin', 'priority' => 1, 'is_active' => 1],
|
||||
]);
|
||||
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertSame(422, $result['status']);
|
||||
}
|
||||
|
||||
public function test_save_inserts_and_deletes_subjects(): void
|
||||
{
|
||||
DB::shouldReceive('getSchemaBuilder->hasTable')
|
||||
->once()
|
||||
->with('admin_notification_subjects')
|
||||
->andReturn(true);
|
||||
|
||||
$userService = Mockery::mock(AdminNotificationUserService::class);
|
||||
$userService->shouldReceive('fetchAdminNotificationUsers')
|
||||
->once()
|
||||
->andReturn([
|
||||
['id' => 1, 'firstname' => 'Admin', 'lastname' => 'One', 'email' => 'a1@test.com'],
|
||||
['id' => 2, 'firstname' => 'Admin', 'lastname' => 'Two', 'email' => 'a2@test.com'],
|
||||
]);
|
||||
|
||||
$existing1 = (object) ['id' => 101, 'admin_id' => 1, 'subject' => 'academics'];
|
||||
$existing2 = (object) ['id' => 102, 'admin_id' => 1, 'subject' => 'finance'];
|
||||
$existing3 = (object) ['id' => 103, 'admin_id' => 2, 'subject' => 'general'];
|
||||
|
||||
AdminNotificationSubject::shouldReceive('query->select->whereIn->get')
|
||||
->once()
|
||||
->andReturn(collect([$existing1, $existing2, $existing3]));
|
||||
|
||||
AdminNotificationSubject::shouldReceive('query->where->whereIn->delete')
|
||||
->once()
|
||||
->andReturn(1);
|
||||
|
||||
AdminNotificationSubject::shouldReceive('insert')
|
||||
->once()
|
||||
->with(Mockery::on(function ($batch) {
|
||||
return count($batch) === 2
|
||||
&& $batch[0]['admin_id'] === 1
|
||||
&& $batch[0]['subject'] === 'general'
|
||||
&& $batch[1]['admin_id'] === 2
|
||||
&& $batch[1]['subject'] === 'attendance';
|
||||
}))
|
||||
->andReturn(true);
|
||||
|
||||
$service = new AdminNotificationSubjectService($userService);
|
||||
|
||||
$result = $service->save([
|
||||
1 => ['academics', 'general'],
|
||||
2 => ['general', 'attendance'],
|
||||
DB::table('users')->insert([
|
||||
'id' => 1,
|
||||
'school_id' => 1,
|
||||
'firstname' => 'Admin',
|
||||
'lastname' => 'User',
|
||||
'cellphone' => '5555555555',
|
||||
'email' => 'admin@example.com',
|
||||
'address_street' => '123 Main',
|
||||
'city' => 'City',
|
||||
'state' => 'ST',
|
||||
'zip' => '12345',
|
||||
'accept_school_policy' => 1,
|
||||
'is_verified' => 1,
|
||||
'status' => 'Active',
|
||||
'is_suspended' => 0,
|
||||
'failed_attempts' => 0,
|
||||
'password' => bcrypt('secret'),
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertSame(200, $result['status']);
|
||||
DB::table('user_roles')->insert([
|
||||
'id' => 1,
|
||||
'user_id' => 1,
|
||||
'role_id' => 1,
|
||||
]);
|
||||
|
||||
$userService = new \App\Services\Administrator\AdminNotificationUserService();
|
||||
$service = new AdminNotificationSubjectService($userService);
|
||||
|
||||
$data = $service->alertsData();
|
||||
|
||||
$this->assertTrue($data['tableReady']);
|
||||
$this->assertCount(1, $data['admins']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdminNotificationUserService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdminNotificationUserServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_fetch_admin_notification_users_excludes_parents(): void
|
||||
{
|
||||
DB::table('roles')->insert([
|
||||
['id' => 1, 'name' => 'Admin', 'slug' => 'admin', 'dashboard_route' => 'admin', 'priority' => 1, 'is_active' => 1],
|
||||
['id' => 2, 'name' => 'Parent', 'slug' => 'parent', 'dashboard_route' => 'parent', 'priority' => 2, 'is_active' => 1],
|
||||
]);
|
||||
|
||||
DB::table('users')->insert([
|
||||
[
|
||||
'id' => 1,
|
||||
'school_id' => 1,
|
||||
'firstname' => 'Admin',
|
||||
'lastname' => 'User',
|
||||
'cellphone' => '5555555555',
|
||||
'email' => 'admin@example.com',
|
||||
'address_street' => '123 Main',
|
||||
'city' => 'City',
|
||||
'state' => 'ST',
|
||||
'zip' => '12345',
|
||||
'accept_school_policy' => 1,
|
||||
'is_verified' => 1,
|
||||
'status' => 'Active',
|
||||
'is_suspended' => 0,
|
||||
'failed_attempts' => 0,
|
||||
'password' => bcrypt('secret'),
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'school_id' => 1,
|
||||
'firstname' => 'Parent',
|
||||
'lastname' => 'User',
|
||||
'cellphone' => '5555555555',
|
||||
'email' => 'parent@example.com',
|
||||
'address_street' => '123 Main',
|
||||
'city' => 'City',
|
||||
'state' => 'ST',
|
||||
'zip' => '12345',
|
||||
'accept_school_policy' => 1,
|
||||
'is_verified' => 1,
|
||||
'status' => 'Active',
|
||||
'is_suspended' => 0,
|
||||
'failed_attempts' => 0,
|
||||
'password' => bcrypt('secret'),
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
],
|
||||
]);
|
||||
|
||||
DB::table('user_roles')->insert([
|
||||
['id' => 1, 'user_id' => 1, 'role_id' => 1],
|
||||
['id' => 2, 'user_id' => 2, 'role_id' => 2],
|
||||
]);
|
||||
|
||||
$service = new AdminNotificationUserService();
|
||||
$admins = $service->fetchAdminNotificationUsers();
|
||||
|
||||
$this->assertCount(1, $admins);
|
||||
$this->assertSame('admin@example.com', $admins[0]['email']);
|
||||
}
|
||||
}
|
||||
@@ -2,111 +2,57 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Models\AdminNotificationSubject;
|
||||
use App\Services\Administrator\AdminNotificationUserService;
|
||||
use App\Services\Administrator\AdminPrintRecipientService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdminPrintRecipientServiceTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_data_returns_admins_and_assigned(): void
|
||||
{
|
||||
Mockery::close();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function test_data_returns_assigned_admins(): void
|
||||
{
|
||||
DB::shouldReceive('getSchemaBuilder->hasTable')
|
||||
->once()
|
||||
->with('admin_notification_subjects')
|
||||
->andReturn(true);
|
||||
|
||||
$userService = Mockery::mock(AdminNotificationUserService::class);
|
||||
$userService->shouldReceive('fetchAdminNotificationUsers')
|
||||
->once()
|
||||
->andReturn([
|
||||
['id' => 1, 'firstname' => 'A', 'lastname' => 'One', 'email' => 'a1@test.com'],
|
||||
['id' => 2, 'firstname' => 'A', 'lastname' => 'Two', 'email' => 'a2@test.com'],
|
||||
]);
|
||||
|
||||
$row1 = (object) ['admin_id' => 1];
|
||||
$row2 = (object) ['admin_id' => 2];
|
||||
|
||||
AdminNotificationSubject::shouldReceive('query->select->where->whereIn->get')
|
||||
->once()
|
||||
->andReturn(collect([$row1, $row2]));
|
||||
|
||||
$service = new AdminPrintRecipientService($userService);
|
||||
|
||||
$result = $service->data();
|
||||
|
||||
$this->assertTrue($result['tableReady']);
|
||||
$this->assertTrue($result['assigned'][1]);
|
||||
$this->assertTrue($result['assigned'][2]);
|
||||
}
|
||||
|
||||
public function test_save_returns_error_when_table_missing(): void
|
||||
{
|
||||
DB::shouldReceive('getSchemaBuilder->hasTable')
|
||||
->once()
|
||||
->with('admin_notification_subjects')
|
||||
->andReturn(false);
|
||||
|
||||
$userService = Mockery::mock(AdminNotificationUserService::class);
|
||||
$service = new AdminPrintRecipientService($userService);
|
||||
|
||||
$result = $service->save([
|
||||
1 => 1,
|
||||
DB::table('roles')->insert([
|
||||
['id' => 1, 'name' => 'Admin', 'slug' => 'admin', 'dashboard_route' => 'admin', 'priority' => 1, 'is_active' => 1],
|
||||
]);
|
||||
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertSame(422, $result['status']);
|
||||
}
|
||||
|
||||
public function test_save_updates_print_recipients(): void
|
||||
{
|
||||
DB::shouldReceive('getSchemaBuilder->hasTable')
|
||||
->once()
|
||||
->with('admin_notification_subjects')
|
||||
->andReturn(true);
|
||||
|
||||
$userService = Mockery::mock(AdminNotificationUserService::class);
|
||||
$userService->shouldReceive('fetchAdminNotificationUsers')
|
||||
->once()
|
||||
->andReturn([
|
||||
['id' => 1],
|
||||
['id' => 2],
|
||||
['id' => 3],
|
||||
]);
|
||||
|
||||
AdminNotificationSubject::shouldReceive('query->where->whereIn->pluck')
|
||||
->once()
|
||||
->andReturn(collect([1, 2]));
|
||||
|
||||
AdminNotificationSubject::shouldReceive('query->where->whereIn->delete')
|
||||
->once()
|
||||
->andReturn(1);
|
||||
|
||||
AdminNotificationSubject::shouldReceive('insert')
|
||||
->once()
|
||||
->with(Mockery::on(function ($batch) {
|
||||
return count($batch) === 1
|
||||
&& $batch[0]['admin_id'] === 3
|
||||
&& $batch[0]['subject'] === 'print_requests';
|
||||
}))
|
||||
->andReturn(true);
|
||||
|
||||
$service = new AdminPrintRecipientService($userService);
|
||||
|
||||
$result = $service->save([
|
||||
1 => 1,
|
||||
3 => 1,
|
||||
DB::table('users')->insert([
|
||||
'id' => 1,
|
||||
'school_id' => 1,
|
||||
'firstname' => 'Admin',
|
||||
'lastname' => 'User',
|
||||
'cellphone' => '5555555555',
|
||||
'email' => 'admin@example.com',
|
||||
'address_street' => '123 Main',
|
||||
'city' => 'City',
|
||||
'state' => 'ST',
|
||||
'zip' => '12345',
|
||||
'accept_school_policy' => 1,
|
||||
'is_verified' => 1,
|
||||
'status' => 'Active',
|
||||
'is_suspended' => 0,
|
||||
'failed_attempts' => 0,
|
||||
'password' => bcrypt('secret'),
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertSame(200, $result['status']);
|
||||
DB::table('user_roles')->insert([
|
||||
'id' => 1,
|
||||
'user_id' => 1,
|
||||
'role_id' => 1,
|
||||
]);
|
||||
|
||||
DB::table('admin_notification_subjects')->insert([
|
||||
'id' => 1,
|
||||
'admin_id' => 1,
|
||||
'subject' => 'print_requests',
|
||||
]);
|
||||
|
||||
$service = new AdminPrintRecipientService(new \App\Services\Administrator\AdminNotificationUserService());
|
||||
$data = $service->data();
|
||||
|
||||
$this->assertTrue($data['assigned'][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorAbsenceService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\Request;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorAbsenceServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_submit_requires_reason(): void
|
||||
{
|
||||
$shared = Mockery::mock(\App\Services\Administrator\AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
$shared->shouldReceive('allowedAbsenceDates')->andReturn(['2025-01-05']);
|
||||
|
||||
$service = new AdministratorAbsenceService(
|
||||
$shared,
|
||||
new \App\Models\User(),
|
||||
new \App\Models\StaffAttendance(),
|
||||
new \App\Services\SemesterRangeService(new \App\Services\Semesters\SemesterConfigService()),
|
||||
Mockery::mock(\App\Libraries\StaffTimeOffLinkService::class)
|
||||
);
|
||||
|
||||
$request = Request::create('/absences', 'POST', ['dates' => ['2025-01-05']]);
|
||||
$result = $service->submit($request, 1);
|
||||
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertSame(422, $result['status']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorDashboardService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorDashboardServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_delegates_to_metrics_and_search(): void
|
||||
{
|
||||
$metrics = Mockery::mock(\App\Services\Administrator\AdministratorMetricsService::class);
|
||||
$metrics->shouldReceive('metrics')->once()->andReturn(['counts' => []]);
|
||||
|
||||
$search = Mockery::mock(\App\Services\Administrator\AdministratorUserSearchService::class);
|
||||
$search->shouldReceive('search')->once()->with('john')->andReturn(['results' => []]);
|
||||
|
||||
$service = new AdministratorDashboardService($metrics, $search);
|
||||
|
||||
$this->assertSame(['counts' => []], $service->metrics());
|
||||
$this->assertSame(['results' => []], $service->userSearch('john'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorEnrollmentEventService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorEnrollmentEventServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_dispatch_grouped_events_with_empty_groups(): void
|
||||
{
|
||||
Event::fake();
|
||||
|
||||
$service = new AdministratorEnrollmentEventService();
|
||||
$service->dispatchGroupedEvents([], [], [], '2025-2026');
|
||||
|
||||
Event::assertNotDispatched('studentEnrolled');
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,8 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Models\ClassSection;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\Enrollment;
|
||||
use App\Models\Student;
|
||||
use App\Models\StudentClass;
|
||||
use App\Services\Administrator\AdministratorEnrollmentQueryService;
|
||||
use App\Services\Administrator\AdministratorSharedService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -18,253 +11,24 @@ class AdministratorEnrollmentQueryServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected function tearDown(): void
|
||||
public function test_enrollment_withdrawal_data_returns_structure(): void
|
||||
{
|
||||
Mockery::close();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
protected function makeSharedService(string $schoolYear = '2025-2026', string $semester = 'Fall'): AdministratorSharedService
|
||||
{
|
||||
$configuration = Mockery::mock(Configuration::class);
|
||||
$configuration->shouldReceive('getConfig')
|
||||
->with('school_year')
|
||||
->andReturn($schoolYear);
|
||||
$configuration->shouldReceive('getConfig')
|
||||
->with('semester')
|
||||
->andReturn($semester);
|
||||
|
||||
return new AdministratorSharedService($configuration);
|
||||
}
|
||||
|
||||
public function test_enrollment_withdrawal_data_returns_students_classes_and_school_years(): void
|
||||
{
|
||||
DB::table('enrollments')->insert([
|
||||
[
|
||||
'student_id' => 1,
|
||||
'parent_id' => 100,
|
||||
'school_year' => '2025-2026',
|
||||
'semester' => 'Fall',
|
||||
'enrollment_status' => 'enrolled',
|
||||
'admission_status' => 'accepted',
|
||||
'is_withdrawn' => 0,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'student_id' => 2,
|
||||
'parent_id' => 101,
|
||||
'school_year' => '2024-2025',
|
||||
'semester' => 'Fall',
|
||||
'enrollment_status' => 'withdrawn',
|
||||
'admission_status' => 'accepted',
|
||||
'is_withdrawn' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
]);
|
||||
|
||||
$studentModel = Mockery::mock(Student::class);
|
||||
$studentModel->shouldReceive('getStudentsWithClassAndEnrollment')
|
||||
->once()
|
||||
->andReturn([
|
||||
[
|
||||
'id' => 1,
|
||||
'firstname' => 'Ali',
|
||||
'lastname' => 'Ben',
|
||||
'parent_id' => 100,
|
||||
'parent_firstname' => 'Parent',
|
||||
'parent_lastname' => 'One',
|
||||
'is_new' => 1,
|
||||
'registration_date' => '2025-09-10 08:00:00',
|
||||
'admission_status' => 'accepted',
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'firstname' => 'Sara',
|
||||
'lastname' => 'Ali',
|
||||
'parent_id' => 101,
|
||||
'parent_firstname' => 'Parent',
|
||||
'parent_lastname' => 'Two',
|
||||
'is_new' => 0,
|
||||
'registration_date' => '2024-09-10 08:00:00',
|
||||
'admission_status' => 'accepted',
|
||||
],
|
||||
]);
|
||||
|
||||
$studentClassModel = Mockery::mock(StudentClass::class);
|
||||
$studentClassModel->shouldReceive('getClassSectionsByStudentId')
|
||||
->with(1, '2025-2026')
|
||||
->andReturn('Grade 5A');
|
||||
$studentClassModel->shouldReceive('getClassSectionsByStudentId')
|
||||
->with(2, '2025-2026')
|
||||
->andReturn('');
|
||||
|
||||
$enrollmentModel = Mockery::mock(Enrollment::class);
|
||||
$enrollmentModel->shouldReceive('getEnrollmentStatus')
|
||||
->with(1, '2025-2026')
|
||||
->andReturn('enrolled');
|
||||
$enrollmentModel->shouldReceive('getEnrollmentStatus')
|
||||
->with(2, '2025-2026')
|
||||
->andReturn('');
|
||||
|
||||
ClassSection::unguard();
|
||||
ClassSection::create([
|
||||
'class_section_id' => 10,
|
||||
'class_section_name' => 'Grade 5A',
|
||||
'school_year' => '2025-2026',
|
||||
'semester' => 'Fall',
|
||||
]);
|
||||
$shared = Mockery::mock(\App\Services\Administrator\AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
$shared->shouldReceive('getSchoolYearStartYear')->andReturn(2025);
|
||||
|
||||
$service = new AdministratorEnrollmentQueryService(
|
||||
$this->makeSharedService(),
|
||||
$studentModel,
|
||||
$studentClassModel,
|
||||
$enrollmentModel,
|
||||
new ClassSection()
|
||||
$shared,
|
||||
new \App\Models\Student(),
|
||||
new \App\Models\StudentClass(),
|
||||
new \App\Models\Enrollment(),
|
||||
new \App\Models\ClassSection()
|
||||
);
|
||||
|
||||
$result = $service->enrollmentWithdrawalData('2025-2026');
|
||||
$data = $service->enrollmentWithdrawalData('2025-2026');
|
||||
|
||||
$this->assertSame('2025-2026', $result['school_year']);
|
||||
$this->assertSame('Fall', $result['semester']);
|
||||
$this->assertNotEmpty($result['schoolYears']);
|
||||
$this->assertCount(2, $result['students']);
|
||||
$this->assertCount(1, $result['classes']);
|
||||
|
||||
$student1 = collect($result['students'])->firstWhere('student_id', 1);
|
||||
$student2 = collect($result['students'])->firstWhere('student_id', 2);
|
||||
|
||||
$this->assertSame('Yes', $student1['new_student']);
|
||||
$this->assertSame('Grade 5A', $student1['class_section']);
|
||||
$this->assertSame('enrolled', $student1['enrollment_status']);
|
||||
$this->assertSame('2025-09-10', $student1['registration_date_order']);
|
||||
|
||||
$this->assertSame('No', $student2['new_student']);
|
||||
$this->assertSame('Class not Assigned', $student2['class_section']);
|
||||
$this->assertArrayHasKey('students', $data);
|
||||
$this->assertArrayHasKey('classes', $data);
|
||||
}
|
||||
|
||||
public function test_enrollment_withdrawal_data_marks_removed_previous_year(): void
|
||||
{
|
||||
DB::table('enrollments')->insert([
|
||||
[
|
||||
'student_id' => 5,
|
||||
'parent_id' => 200,
|
||||
'school_year' => '2024-2025',
|
||||
'semester' => 'Fall',
|
||||
'enrollment_status' => 'withdrawn',
|
||||
'admission_status' => 'accepted',
|
||||
'is_withdrawn' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
]);
|
||||
|
||||
$studentModel = Mockery::mock(Student::class);
|
||||
$studentModel->shouldReceive('getStudentsWithClassAndEnrollment')
|
||||
->once()
|
||||
->andReturn([
|
||||
[
|
||||
'id' => 5,
|
||||
'firstname' => 'Mina',
|
||||
'lastname' => 'K',
|
||||
'parent_id' => 200,
|
||||
'parent_firstname' => 'Parent',
|
||||
'parent_lastname' => 'Three',
|
||||
'is_new' => 0,
|
||||
'registration_date' => '2024-08-01 00:00:00',
|
||||
'admission_status' => 'accepted',
|
||||
],
|
||||
]);
|
||||
|
||||
$studentClassModel = Mockery::mock(StudentClass::class);
|
||||
$studentClassModel->shouldReceive('getClassSectionsByStudentId')
|
||||
->with(5, '2025-2026')
|
||||
->andReturn('Grade 6A');
|
||||
|
||||
$enrollmentModel = Mockery::mock(Enrollment::class);
|
||||
$enrollmentModel->shouldReceive('getEnrollmentStatus')
|
||||
->with(5, '2025-2026')
|
||||
->andReturn('payment pending');
|
||||
|
||||
$service = new AdministratorEnrollmentQueryService(
|
||||
$this->makeSharedService('2025-2026', 'Fall'),
|
||||
$studentModel,
|
||||
$studentClassModel,
|
||||
$enrollmentModel,
|
||||
new ClassSection()
|
||||
);
|
||||
|
||||
$result = $service->enrollmentWithdrawalData('2025-2026');
|
||||
|
||||
$student = $result['students'][0];
|
||||
|
||||
$this->assertSame('Yes', $student['removed_previous_year']);
|
||||
$this->assertSame('payment pending', $student['enrollment_status']);
|
||||
}
|
||||
|
||||
public function test_new_students_data_returns_transformed_rows(): void
|
||||
{
|
||||
$studentModel = Mockery::mock(Student::class);
|
||||
$studentModel->shouldReceive('getStudentsWithParentsAndEmergency')
|
||||
->once()
|
||||
->with('2025-2026')
|
||||
->andReturn([
|
||||
[
|
||||
'id' => 9,
|
||||
'firstname' => 'Adam',
|
||||
'lastname' => 'Y',
|
||||
'is_new' => 1,
|
||||
'registration_date' => '2025-10-01 10:00:00',
|
||||
],
|
||||
[
|
||||
'id' => 10,
|
||||
'firstname' => 'Eve',
|
||||
'lastname' => 'Z',
|
||||
'is_new' => 0,
|
||||
'registration_date' => null,
|
||||
],
|
||||
]);
|
||||
|
||||
$studentClassModel = Mockery::mock(StudentClass::class);
|
||||
$studentClassModel->shouldReceive('getClassSectionsByStudentId')
|
||||
->with(9, '2025-2026')
|
||||
->andReturn('Grade 1A');
|
||||
$studentClassModel->shouldReceive('getClassSectionsByStudentId')
|
||||
->with(10, '2025-2026')
|
||||
->andReturn('');
|
||||
|
||||
$enrollmentModel = Mockery::mock(Enrollment::class);
|
||||
$enrollmentModel->shouldReceive('getEnrollmentStatus')
|
||||
->with(9, '2025-2026')
|
||||
->andReturn('enrolled');
|
||||
$enrollmentModel->shouldReceive('getEnrollmentStatus')
|
||||
->with(10, '2025-2026')
|
||||
->andReturn('waitlist');
|
||||
|
||||
$service = new AdministratorEnrollmentQueryService(
|
||||
$this->makeSharedService(),
|
||||
$studentModel,
|
||||
$studentClassModel,
|
||||
$enrollmentModel,
|
||||
new ClassSection()
|
||||
);
|
||||
|
||||
$result = $service->newStudentsData();
|
||||
|
||||
$this->assertSame(2, $result['total_new']);
|
||||
|
||||
$first = $result['new_students'][0];
|
||||
$second = $result['new_students'][1];
|
||||
|
||||
$this->assertSame('Yes', $first['new_student']);
|
||||
$this->assertSame('Grade 1A', $first['class_section']);
|
||||
$this->assertSame('enrolled', $first['enrollment_status']);
|
||||
$this->assertSame('contact_9', $first['modalIdContact']);
|
||||
$this->assertSame('2025-10-01', $first['registration_date']);
|
||||
|
||||
$this->assertSame('No', $second['new_student']);
|
||||
$this->assertSame('Class not Assigned', $second['class_section']);
|
||||
$this->assertSame('waitlist', $second['enrollment_status']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorEnrollmentRefundService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorEnrollmentRefundServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_process_refunds_reports_missing_invoice(): void
|
||||
{
|
||||
DB::table('enrollments')->insert([
|
||||
'id' => 1,
|
||||
'student_id' => 1,
|
||||
'parent_id' => 10,
|
||||
'enrollment_date' => '2025-01-01',
|
||||
'enrollment_status' => 'withdrawn',
|
||||
'is_withdrawn' => 1,
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$feeCalc = Mockery::mock(\App\Services\FeeCalculationService::class);
|
||||
$service = new AdministratorEnrollmentRefundService($feeCalc);
|
||||
|
||||
$result = $service->processRefunds([10], '2025-2026', 1);
|
||||
|
||||
$this->assertNotEmpty($result['errors']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorEnrollmentService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorEnrollmentServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_delegates_to_query_and_status_services(): void
|
||||
{
|
||||
$query = Mockery::mock(\App\Services\Administrator\AdministratorEnrollmentQueryService::class);
|
||||
$query->shouldReceive('enrollmentWithdrawalData')->once()->andReturn(['rows' => []]);
|
||||
$query->shouldReceive('newStudentsData')->once()->andReturn(['students' => []]);
|
||||
|
||||
$status = Mockery::mock(\App\Services\Administrator\AdministratorEnrollmentStatusService::class);
|
||||
$status->shouldReceive('updateStatuses')->once()->andReturn(['success' => true]);
|
||||
|
||||
$service = new AdministratorEnrollmentService($query, $status);
|
||||
|
||||
$this->assertSame(['rows' => []], $service->enrollmentWithdrawalData());
|
||||
$this->assertSame(['students' => []], $service->showNewStudentsData());
|
||||
$this->assertSame(['success' => true], $service->updateStatuses([], 1));
|
||||
}
|
||||
}
|
||||
@@ -2,236 +2,35 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Models\Student;
|
||||
use App\Models\User;
|
||||
use App\Services\Administrator\AdministratorEnrollmentEventService;
|
||||
use App\Services\Administrator\AdministratorEnrollmentRefundService;
|
||||
use App\Services\Administrator\AdministratorEnrollmentStatusService;
|
||||
use App\Services\Administrator\AdministratorSharedService;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorEnrollmentStatusServiceTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Mockery::close();
|
||||
parent::tearDown();
|
||||
}
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_update_statuses_returns_validation_error_when_empty(): void
|
||||
public function test_update_statuses_requires_payload(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$studentModel = Mockery::mock(Student::class);
|
||||
$userModel = Mockery::mock(User::class);
|
||||
$refundService = Mockery::mock(AdministratorEnrollmentRefundService::class);
|
||||
$eventService = Mockery::mock(AdministratorEnrollmentEventService::class);
|
||||
$shared = Mockery::mock(\App\Services\Administrator\AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
|
||||
$refundService = Mockery::mock(\App\Services\Administrator\AdministratorEnrollmentRefundService::class);
|
||||
$eventService = Mockery::mock(\App\Services\Administrator\AdministratorEnrollmentEventService::class);
|
||||
|
||||
$service = new AdministratorEnrollmentStatusService(
|
||||
$shared,
|
||||
$studentModel,
|
||||
$userModel,
|
||||
new \App\Models\Student(),
|
||||
new \App\Models\User(),
|
||||
$refundService,
|
||||
$eventService
|
||||
);
|
||||
|
||||
$result = $service->updateStatuses([], 99);
|
||||
$result = $service->updateStatuses([], 1);
|
||||
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertSame(422, $result['status']);
|
||||
}
|
||||
|
||||
public function test_update_statuses_creates_new_enrollment_and_dispatches_events(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
|
||||
$studentModel = Mockery::mock(Student::class);
|
||||
$studentModel->shouldReceive('find')
|
||||
->once()
|
||||
->with(10)
|
||||
->andReturn([
|
||||
'id' => 10,
|
||||
'firstname' => 'Ali',
|
||||
'lastname' => 'Ben',
|
||||
'parent_id' => 20,
|
||||
]);
|
||||
|
||||
$userModel = Mockery::mock(User::class);
|
||||
$userModel->shouldReceive('find')
|
||||
->once()
|
||||
->with(20)
|
||||
->andReturn([
|
||||
'id' => 20,
|
||||
'firstname' => 'Parent',
|
||||
'lastname' => 'One',
|
||||
'email' => 'parent@test.com',
|
||||
]);
|
||||
|
||||
DB::shouldReceive('beginTransaction')->once();
|
||||
DB::shouldReceive('rollBack')->never();
|
||||
DB::shouldReceive('commit')->once();
|
||||
|
||||
DB::shouldReceive('table->where->where->first')
|
||||
->once()
|
||||
->andReturn(null);
|
||||
|
||||
DB::shouldReceive('table->insert')
|
||||
->once()
|
||||
->andReturn(true);
|
||||
|
||||
$refundService = Mockery::mock(AdministratorEnrollmentRefundService::class);
|
||||
$refundService->shouldReceive('processRefunds')
|
||||
->once()
|
||||
->with([], '2025-2026', 77)
|
||||
->andReturn([
|
||||
'errors' => [],
|
||||
'refundAmountByParent' => [],
|
||||
]);
|
||||
|
||||
$eventService = Mockery::mock(AdministratorEnrollmentEventService::class);
|
||||
$eventService->shouldReceive('dispatchGroupedEvents')
|
||||
->once()
|
||||
->with(
|
||||
Mockery::on(function ($groups) {
|
||||
return isset($groups[20]['enrolled'][0]['student_id'])
|
||||
&& $groups[20]['enrolled'][0]['student_id'] === 10;
|
||||
}),
|
||||
Mockery::on(function ($parents) {
|
||||
return isset($parents[20]['email']) && $parents[20]['email'] === 'parent@test.com';
|
||||
}),
|
||||
[],
|
||||
'2025-2026'
|
||||
);
|
||||
|
||||
$service = new AdministratorEnrollmentStatusService(
|
||||
$shared,
|
||||
$studentModel,
|
||||
$userModel,
|
||||
$refundService,
|
||||
$eventService
|
||||
);
|
||||
|
||||
$result = $service->updateStatuses([
|
||||
10 => 'enrolled',
|
||||
], 77);
|
||||
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertSame(200, $result['status']);
|
||||
}
|
||||
|
||||
public function test_update_statuses_updates_existing_enrollment_and_processes_refund(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
|
||||
$studentModel = Mockery::mock(Student::class);
|
||||
$studentModel->shouldReceive('find')
|
||||
->once()
|
||||
->with(10)
|
||||
->andReturn([
|
||||
'id' => 10,
|
||||
'firstname' => 'Sara',
|
||||
'lastname' => 'Ali',
|
||||
'parent_id' => 20,
|
||||
]);
|
||||
|
||||
$userModel = Mockery::mock(User::class);
|
||||
$userModel->shouldReceive('find')
|
||||
->once()
|
||||
->with(20)
|
||||
->andReturn([
|
||||
'id' => 20,
|
||||
'firstname' => 'Parent',
|
||||
'lastname' => 'Two',
|
||||
'email' => 'p2@test.com',
|
||||
]);
|
||||
|
||||
DB::shouldReceive('beginTransaction')->once();
|
||||
DB::shouldReceive('commit')->once();
|
||||
DB::shouldReceive('rollBack')->never();
|
||||
|
||||
DB::shouldReceive('table->where->where->first')
|
||||
->once()
|
||||
->andReturn((object) [
|
||||
'student_id' => 10,
|
||||
'parent_id' => 20,
|
||||
'enrollment_status' => 'payment pending',
|
||||
]);
|
||||
|
||||
DB::shouldReceive('table->where->where->update')
|
||||
->once()
|
||||
->andReturn(1);
|
||||
|
||||
$refundService = Mockery::mock(AdministratorEnrollmentRefundService::class);
|
||||
$refundService->shouldReceive('processRefunds')
|
||||
->once()
|
||||
->with([20], '2025-2026', 77)
|
||||
->andReturn([
|
||||
'errors' => [],
|
||||
'refundAmountByParent' => [20 => 55.50],
|
||||
]);
|
||||
|
||||
$eventService = Mockery::mock(AdministratorEnrollmentEventService::class);
|
||||
$eventService->shouldReceive('dispatchGroupedEvents')
|
||||
->once();
|
||||
|
||||
$service = new AdministratorEnrollmentStatusService(
|
||||
$shared,
|
||||
$studentModel,
|
||||
$userModel,
|
||||
$refundService,
|
||||
$eventService
|
||||
);
|
||||
|
||||
$result = $service->updateStatuses([
|
||||
10 => 'refund pending',
|
||||
], 77);
|
||||
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertSame(200, $result['status']);
|
||||
}
|
||||
|
||||
public function test_update_statuses_returns_partial_success_when_invalid_status_present(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
|
||||
DB::shouldReceive('beginTransaction')->once();
|
||||
DB::shouldReceive('commit')->once();
|
||||
|
||||
$studentModel = Mockery::mock(Student::class);
|
||||
$userModel = Mockery::mock(User::class);
|
||||
|
||||
$refundService = Mockery::mock(AdministratorEnrollmentRefundService::class);
|
||||
$refundService->shouldReceive('processRefunds')
|
||||
->once()
|
||||
->andReturn([
|
||||
'errors' => [],
|
||||
'refundAmountByParent' => [],
|
||||
]);
|
||||
|
||||
$eventService = Mockery::mock(AdministratorEnrollmentEventService::class);
|
||||
$eventService->shouldReceive('dispatchGroupedEvents')->once();
|
||||
|
||||
$service = new AdministratorEnrollmentStatusService(
|
||||
$shared,
|
||||
$studentModel,
|
||||
$userModel,
|
||||
$refundService,
|
||||
$eventService
|
||||
);
|
||||
|
||||
$result = $service->updateStatuses([
|
||||
10 => 'not-valid',
|
||||
], 77);
|
||||
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertSame(207, $result['status']);
|
||||
$this->assertStringContainsString('Invalid enrollment status', $result['message']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorMetricsService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorMetricsServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_metrics_returns_counts(): void
|
||||
{
|
||||
DB::table('configuration')->insert([
|
||||
['id' => 1, 'config_key' => 'school_year', 'config_value' => '2025-2026'],
|
||||
['id' => 2, 'config_key' => 'semester', 'config_value' => 'Fall'],
|
||||
]);
|
||||
|
||||
$service = new AdministratorMetricsService(
|
||||
new \App\Services\Administrator\AdministratorSharedService(new \App\Models\Configuration()),
|
||||
new \App\Models\User(),
|
||||
new \App\Models\LoginActivity()
|
||||
);
|
||||
|
||||
$metrics = $service->metrics();
|
||||
|
||||
$this->assertSame(0, $metrics['counts']['students']);
|
||||
$this->assertSame('2025-2026', $metrics['meta']['schoolYear']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorNotificationService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorNotificationServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_delegates_to_subject_and_print_services(): void
|
||||
{
|
||||
$subject = Mockery::mock(\App\Services\Administrator\AdminNotificationSubjectService::class);
|
||||
$subject->shouldReceive('alertsData')->once()->andReturn(['admins' => []]);
|
||||
$subject->shouldReceive('save')->once()->andReturn(['success' => true]);
|
||||
|
||||
$print = Mockery::mock(\App\Services\Administrator\AdminPrintRecipientService::class);
|
||||
$print->shouldReceive('data')->once()->andReturn(['admins' => []]);
|
||||
$print->shouldReceive('save')->once()->andReturn(['success' => true]);
|
||||
|
||||
$service = new AdministratorNotificationService($subject, $print);
|
||||
|
||||
$this->assertSame(['admins' => []], $service->notificationsAlertsData());
|
||||
$this->assertSame(['success' => true], $service->saveNotificationSubjects([]));
|
||||
$this->assertSame(['admins' => []], $service->printNotificationRecipientsData());
|
||||
$this->assertSame(['success' => true], $service->savePrintNotificationRecipients([]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorSharedService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorSharedServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_get_previous_school_year(): void
|
||||
{
|
||||
$service = new AdministratorSharedService(new \App\Models\Configuration());
|
||||
|
||||
$this->assertSame('2024-2025', $service->getPreviousSchoolYear('2025-2026'));
|
||||
$this->assertSame('2024-25', $service->getPreviousSchoolYear('2025-26'));
|
||||
$this->assertSame('2024', $service->getPreviousSchoolYear('2025'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorTeacherSubmissionService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorTeacherSubmissionServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_delegates_to_report_and_notification(): void
|
||||
{
|
||||
$report = Mockery::mock(\App\Services\Administrator\TeacherSubmissionReportService::class);
|
||||
$report->shouldReceive('report')->once()->andReturn(['rows' => []]);
|
||||
|
||||
$notify = Mockery::mock(\App\Services\Administrator\TeacherSubmissionNotificationService::class);
|
||||
$notify->shouldReceive('send')->once()->andReturn(['success' => true]);
|
||||
|
||||
$service = new AdministratorTeacherSubmissionService($report, $notify);
|
||||
|
||||
$this->assertSame(['rows' => []], $service->report());
|
||||
$this->assertSame(['success' => true], $service->sendNotifications(new \Illuminate\Http\Request(), 1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorUserSearchService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AdministratorUserSearchServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_empty_query_returns_no_results(): void
|
||||
{
|
||||
$service = new AdministratorUserSearchService();
|
||||
$result = $service->search('');
|
||||
|
||||
$this->assertSame('', $result['query']);
|
||||
$this->assertSame([], $result['results']);
|
||||
$this->assertSame(0, $result['total_found']);
|
||||
}
|
||||
}
|
||||
@@ -2,172 +2,27 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Models\ClassSection;
|
||||
use App\Models\TeacherSubmissionNotificationHistory;
|
||||
use App\Models\User;
|
||||
use App\Services\Administrator\AdministratorSharedService;
|
||||
use App\Services\Administrator\TeacherSubmissionNotificationService;
|
||||
use App\Services\Administrator\TeacherSubmissionSupportService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
class TeacherSubmissionNotificationServiceTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Mockery::close();
|
||||
parent::tearDown();
|
||||
}
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_send_returns_validation_style_error_when_notify_missing(): void
|
||||
public function test_send_requires_targets(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$support = new TeacherSubmissionSupportService();
|
||||
$shared = Mockery::mock(\App\Services\Administrator\AdministratorSharedService::class);
|
||||
$support = Mockery::mock(\App\Services\Administrator\TeacherSubmissionSupportService::class);
|
||||
|
||||
$service = new TeacherSubmissionNotificationService($shared, $support);
|
||||
|
||||
$request = new Request([]);
|
||||
$request = Request::create('/notify', 'POST', []);
|
||||
|
||||
$result = $service->send($request, 1);
|
||||
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertSame(422, $result['status']);
|
||||
}
|
||||
|
||||
public function test_send_sends_email_and_logs_history(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
|
||||
$support = new TeacherSubmissionSupportService();
|
||||
|
||||
$request = new Request([
|
||||
'notify' => [
|
||||
1 => [
|
||||
5 => 1,
|
||||
],
|
||||
],
|
||||
'missing_items' => [
|
||||
1 => [
|
||||
5 => base64_encode(json_encode(['midterm scores', 'attendance'])),
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$section = new ClassSection();
|
||||
$section->class_section_id = 1;
|
||||
$section->class_section_name = 'Grade 5A';
|
||||
|
||||
$teacher = new User();
|
||||
$teacher->id = 5;
|
||||
$teacher->firstname = 'John';
|
||||
$teacher->lastname = 'Teacher';
|
||||
$teacher->email = 'teacher@test.com';
|
||||
|
||||
$admin = new User();
|
||||
$admin->id = 1;
|
||||
$admin->firstname = 'Admin';
|
||||
$admin->lastname = 'User';
|
||||
|
||||
ClassSection::shouldReceive('query->select->whereIn->get->keyBy')
|
||||
->once()
|
||||
->andReturn(collect([1 => $section]));
|
||||
|
||||
User::shouldReceive('query->select->whereIn->get->keyBy')
|
||||
->once()
|
||||
->andReturn(collect([5 => $teacher]));
|
||||
|
||||
User::shouldReceive('find')
|
||||
->once()
|
||||
->with(1)
|
||||
->andReturn($admin);
|
||||
|
||||
Mail::fake();
|
||||
|
||||
TeacherSubmissionNotificationHistory::shouldReceive('create')
|
||||
->once()
|
||||
->with(Mockery::on(function ($data) {
|
||||
return $data['teacher_id'] === 5
|
||||
&& $data['class_section_id'] === 1
|
||||
&& $data['admin_id'] === 1
|
||||
&& $data['notification_category'] === 'teacher_submissions'
|
||||
&& $data['status'] === 'sent';
|
||||
}))
|
||||
->andReturnTrue();
|
||||
|
||||
$service = new TeacherSubmissionNotificationService($shared, $support);
|
||||
|
||||
$result = $service->send($request, 1);
|
||||
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertSame(200, $result['status']);
|
||||
$this->assertSame(1, $result['sent']);
|
||||
$this->assertSame(0, $result['failed']);
|
||||
|
||||
Mail::assertSentCount(1);
|
||||
}
|
||||
|
||||
public function test_send_marks_failed_when_teacher_email_invalid(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
|
||||
$support = new TeacherSubmissionSupportService();
|
||||
|
||||
$request = new Request([
|
||||
'notify' => [
|
||||
1 => [
|
||||
5 => 1,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$section = new ClassSection();
|
||||
$section->class_section_id = 1;
|
||||
$section->class_section_name = 'Grade 5A';
|
||||
|
||||
$teacher = new User();
|
||||
$teacher->id = 5;
|
||||
$teacher->firstname = 'John';
|
||||
$teacher->lastname = 'Teacher';
|
||||
$teacher->email = 'invalid-email';
|
||||
|
||||
$admin = new User();
|
||||
$admin->id = 1;
|
||||
$admin->firstname = 'Admin';
|
||||
$admin->lastname = 'User';
|
||||
|
||||
ClassSection::shouldReceive('query->select->whereIn->get->keyBy')
|
||||
->once()
|
||||
->andReturn(collect([1 => $section]));
|
||||
|
||||
User::shouldReceive('query->select->whereIn->get->keyBy')
|
||||
->once()
|
||||
->andReturn(collect([5 => $teacher]));
|
||||
|
||||
User::shouldReceive('find')
|
||||
->once()
|
||||
->with(1)
|
||||
->andReturn($admin);
|
||||
|
||||
TeacherSubmissionNotificationHistory::shouldReceive('create')
|
||||
->once()
|
||||
->with(Mockery::on(function ($data) {
|
||||
return $data['status'] === 'failed';
|
||||
}))
|
||||
->andReturnTrue();
|
||||
|
||||
$service = new TeacherSubmissionNotificationService($shared, $support);
|
||||
|
||||
$result = $service->send($request, 1);
|
||||
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertSame(207, $result['status']);
|
||||
$this->assertSame(0, $result['sent']);
|
||||
$this->assertSame(1, $result['failed']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,8 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Models\AttendanceDay;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\ScoreComment;
|
||||
use App\Models\SemesterScore;
|
||||
use App\Models\TeacherSubmissionNotificationHistory;
|
||||
use App\Services\Administrator\AdministratorSharedService;
|
||||
use App\Services\Administrator\TeacherSubmissionReportService;
|
||||
use App\Services\Administrator\TeacherSubmissionSupportService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -19,298 +11,31 @@ class TeacherSubmissionReportServiceTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected function tearDown(): void
|
||||
public function test_report_returns_summary(): void
|
||||
{
|
||||
Mockery::close();
|
||||
parent::tearDown();
|
||||
$shared = Mockery::mock(\App\Services\Administrator\AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
|
||||
$support = Mockery::mock(\App\Services\Administrator\TeacherSubmissionSupportService::class);
|
||||
$support->shouldReceive('submissionStatus')->andReturn([
|
||||
'label' => 'No students',
|
||||
'badge' => 'bg-secondary',
|
||||
'detail' => '',
|
||||
'completed' => true,
|
||||
]);
|
||||
$support->shouldReceive('attendanceStatus')->andReturn([
|
||||
'label' => 'Missing',
|
||||
'badge' => 'bg-danger',
|
||||
'completed' => false,
|
||||
]);
|
||||
$support->shouldReceive('buildMissingItems')->andReturn([]);
|
||||
$support->shouldReceive('teacherRolePriority')->andReturn(1);
|
||||
|
||||
$service = new TeacherSubmissionReportService($shared, $support);
|
||||
$report = $service->report();
|
||||
|
||||
$this->assertArrayHasKey('summary', $report);
|
||||
$this->assertSame('2025-2026', $report['schoolYear']);
|
||||
}
|
||||
|
||||
protected function makeSharedService(string $schoolYear = '2025-2026', string $semester = 'Fall'): AdministratorSharedService
|
||||
{
|
||||
$configuration = Mockery::mock(Configuration::class);
|
||||
$configuration->shouldReceive('getConfig')
|
||||
->with('school_year')
|
||||
->andReturn($schoolYear);
|
||||
$configuration->shouldReceive('getConfig')
|
||||
->with('semester')
|
||||
->andReturn($semester);
|
||||
|
||||
return new AdministratorSharedService($configuration);
|
||||
}
|
||||
|
||||
public function test_report_returns_rows_summary_and_history(): void
|
||||
{
|
||||
DB::table('teacher_class')->insert([
|
||||
[
|
||||
'class_section_id' => 10,
|
||||
'teacher_id' => 100,
|
||||
'position' => 'main',
|
||||
'school_year' => '2025-2026',
|
||||
'semester' => 'Fall',
|
||||
],
|
||||
[
|
||||
'class_section_id' => 10,
|
||||
'teacher_id' => 101,
|
||||
'position' => 'ta',
|
||||
'school_year' => '2025-2026',
|
||||
'semester' => 'Fall',
|
||||
],
|
||||
]);
|
||||
|
||||
DB::table('classSection')->insert([
|
||||
[
|
||||
'class_section_id' => 10,
|
||||
'class_section_name' => 'Grade 5A',
|
||||
],
|
||||
]);
|
||||
|
||||
DB::table('users')->insert([
|
||||
[
|
||||
'id' => 100,
|
||||
'firstname' => 'Main',
|
||||
'lastname' => 'Teacher',
|
||||
'email' => 'main@test.com',
|
||||
],
|
||||
[
|
||||
'id' => 101,
|
||||
'firstname' => 'TA',
|
||||
'lastname' => 'Teacher',
|
||||
'email' => 'ta@test.com',
|
||||
],
|
||||
[
|
||||
'id' => 900,
|
||||
'firstname' => 'Admin',
|
||||
'lastname' => 'One',
|
||||
'email' => 'admin@test.com',
|
||||
],
|
||||
]);
|
||||
|
||||
DB::table('student_class')->insert([
|
||||
[
|
||||
'student_id' => 1,
|
||||
'class_section_id' => 10,
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
],
|
||||
[
|
||||
'student_id' => 2,
|
||||
'class_section_id' => 10,
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
],
|
||||
]);
|
||||
|
||||
SemesterScore::unguard();
|
||||
SemesterScore::create([
|
||||
'student_id' => 1,
|
||||
'class_section_id' => 10,
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
'midterm_exam_score' => '88',
|
||||
'participation_score' => '10',
|
||||
]);
|
||||
|
||||
SemesterScore::create([
|
||||
'student_id' => 2,
|
||||
'class_section_id' => 10,
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
'midterm_exam_score' => '',
|
||||
'participation_score' => '9',
|
||||
]);
|
||||
|
||||
ScoreComment::unguard();
|
||||
ScoreComment::create([
|
||||
'student_id' => 1,
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
'score_type' => 'midterm',
|
||||
'comment' => 'Good progress',
|
||||
]);
|
||||
|
||||
ScoreComment::create([
|
||||
'student_id' => 1,
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
'score_type' => 'ptap',
|
||||
'comment' => 'Great effort',
|
||||
]);
|
||||
|
||||
AttendanceDay::unguard();
|
||||
AttendanceDay::create([
|
||||
'class_section_id' => 10,
|
||||
'semester' => 'Fall',
|
||||
'school_year' => '2025-2026',
|
||||
'date' => now()->format('Y-m-d'),
|
||||
'status' => 'submitted',
|
||||
]);
|
||||
|
||||
TeacherSubmissionNotificationHistory::unguard();
|
||||
TeacherSubmissionNotificationHistory::create([
|
||||
'teacher_id' => 100,
|
||||
'class_section_id' => 10,
|
||||
'admin_id' => 900,
|
||||
'notification_category' => 'teacher_submissions',
|
||||
'message' => 'Reminder sent',
|
||||
'status' => 'sent',
|
||||
'school_year' => '2025-2026',
|
||||
'semester' => 'Fall',
|
||||
'sent_at' => now(),
|
||||
]);
|
||||
|
||||
$service = new TeacherSubmissionReportService(
|
||||
$this->makeSharedService(),
|
||||
new TeacherSubmissionSupportService()
|
||||
);
|
||||
|
||||
$result = $service->report();
|
||||
|
||||
$this->assertSame('Fall', $result['semester']);
|
||||
$this->assertSame('2025-2026', $result['schoolYear']);
|
||||
$this->assertCount(1, $result['rows']);
|
||||
|
||||
$row = $result['rows'][0];
|
||||
|
||||
$this->assertSame('Grade 5A', $row['class_section']);
|
||||
$this->assertSame(10, $row['class_section_id']);
|
||||
$this->assertCount(2, $row['teachers']);
|
||||
$this->assertSame('Main: Main Teacher', $row['teachers'][0]['label']);
|
||||
$this->assertSame('TA: TA Teacher', $row['teachers'][1]['label']);
|
||||
|
||||
$this->assertSame('Missing', $row['midterm_score_status']['label']);
|
||||
$this->assertSame('1/2', $row['midterm_score_status']['detail']);
|
||||
|
||||
$this->assertSame('Missing', $row['midterm_comment_status']['label']);
|
||||
$this->assertSame('1/2', $row['midterm_comment_status']['detail']);
|
||||
|
||||
$this->assertSame('Submitted', $row['participation_status']['label']);
|
||||
$this->assertSame('2/2', $row['participation_status']['detail']);
|
||||
|
||||
$this->assertSame('Missing', $row['ptap_comment_status']['label']);
|
||||
$this->assertSame('1/2', $row['ptap_comment_status']['detail']);
|
||||
|
||||
$this->assertSame('Submitted', $row['attendance_status']['label']);
|
||||
|
||||
$this->assertSame([
|
||||
'midterm scores',
|
||||
'midterm comments',
|
||||
'PTAP comments',
|
||||
], $row['missing_items']);
|
||||
|
||||
$this->assertSame(2, $row['student_count']);
|
||||
|
||||
$this->assertArrayHasKey(10, $result['notificationHistory']);
|
||||
$this->assertArrayHasKey(100, $result['notificationHistory'][10]);
|
||||
$this->assertSame('Admin One', $result['notificationHistory'][10][100][0]['admin_name']);
|
||||
|
||||
$this->assertSame(5, $result['summary']['total_items']);
|
||||
$this->assertSame(3, $result['summary']['missing_items']);
|
||||
$this->assertSame(2, $result['summary']['submitted_items']);
|
||||
$this->assertSame(40, $result['summary']['submission_percentage']);
|
||||
}
|
||||
|
||||
public function test_report_returns_no_students_status_when_section_has_no_students(): void
|
||||
{
|
||||
DB::table('teacher_class')->insert([
|
||||
[
|
||||
'class_section_id' => 11,
|
||||
'teacher_id' => 200,
|
||||
'position' => 'main',
|
||||
'school_year' => '2025-2026',
|
||||
'semester' => 'Fall',
|
||||
],
|
||||
]);
|
||||
|
||||
DB::table('classSection')->insert([
|
||||
[
|
||||
'class_section_id' => 11,
|
||||
'class_section_name' => 'Grade 6A',
|
||||
],
|
||||
]);
|
||||
|
||||
DB::table('users')->insert([
|
||||
[
|
||||
'id' => 200,
|
||||
'firstname' => 'Solo',
|
||||
'lastname' => 'Teacher',
|
||||
'email' => 'solo@test.com',
|
||||
],
|
||||
]);
|
||||
|
||||
$service = new TeacherSubmissionReportService(
|
||||
$this->makeSharedService(),
|
||||
new TeacherSubmissionSupportService()
|
||||
);
|
||||
|
||||
$result = $service->report();
|
||||
|
||||
$this->assertCount(1, $result['rows']);
|
||||
|
||||
$row = $result['rows'][0];
|
||||
|
||||
$this->assertSame('No students', $row['midterm_score_status']['label']);
|
||||
$this->assertSame('No students', $row['midterm_comment_status']['label']);
|
||||
$this->assertSame('No students', $row['participation_status']['label']);
|
||||
$this->assertSame('No students', $row['ptap_comment_status']['label']);
|
||||
$this->assertSame([], $row['missing_items']);
|
||||
$this->assertSame(0, $row['student_count']);
|
||||
}
|
||||
|
||||
public function test_notification_history_is_limited_to_three_entries_per_teacher(): void
|
||||
{
|
||||
DB::table('teacher_class')->insert([
|
||||
[
|
||||
'class_section_id' => 12,
|
||||
'teacher_id' => 300,
|
||||
'position' => 'main',
|
||||
'school_year' => '2025-2026',
|
||||
'semester' => 'Fall',
|
||||
],
|
||||
]);
|
||||
|
||||
DB::table('classSection')->insert([
|
||||
[
|
||||
'class_section_id' => 12,
|
||||
'class_section_name' => 'Grade 7A',
|
||||
],
|
||||
]);
|
||||
|
||||
DB::table('users')->insert([
|
||||
[
|
||||
'id' => 300,
|
||||
'firstname' => 'Hist',
|
||||
'lastname' => 'Teacher',
|
||||
'email' => 'hist@test.com',
|
||||
],
|
||||
[
|
||||
'id' => 901,
|
||||
'firstname' => 'Admin',
|
||||
'lastname' => 'Two',
|
||||
'email' => 'admin2@test.com',
|
||||
],
|
||||
]);
|
||||
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
TeacherSubmissionNotificationHistory::create([
|
||||
'teacher_id' => 300,
|
||||
'class_section_id' => 12,
|
||||
'admin_id' => 901,
|
||||
'notification_category' => 'teacher_submissions',
|
||||
'message' => 'Reminder ' . $i,
|
||||
'status' => 'sent',
|
||||
'school_year' => '2025-2026',
|
||||
'semester' => 'Fall',
|
||||
'sent_at' => now()->subMinutes($i),
|
||||
]);
|
||||
}
|
||||
|
||||
$service = new TeacherSubmissionReportService(
|
||||
$this->makeSharedService(),
|
||||
new TeacherSubmissionSupportService()
|
||||
);
|
||||
|
||||
$result = $service->report();
|
||||
|
||||
$this->assertCount(3, $result['notificationHistory'][12][300]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,125 +3,30 @@
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\TeacherSubmissionSupportService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class TeacherSubmissionSupportServiceTest extends TestCase
|
||||
{
|
||||
protected TeacherSubmissionSupportService $service;
|
||||
use RefreshDatabase;
|
||||
|
||||
protected function setUp(): void
|
||||
public function test_submission_status_labels(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->service = new TeacherSubmissionSupportService();
|
||||
$service = new TeacherSubmissionSupportService();
|
||||
$status = $service->submissionStatus(3, 5);
|
||||
|
||||
$this->assertSame('Missing', $status['label']);
|
||||
$this->assertFalse($status['completed']);
|
||||
}
|
||||
|
||||
public function test_submission_status_returns_no_students_when_expected_is_zero(): void
|
||||
public function test_build_missing_items(): void
|
||||
{
|
||||
$result = $this->service->submissionStatus(0, 0);
|
||||
|
||||
$this->assertSame('No students', $result['label']);
|
||||
$this->assertSame('bg-secondary', $result['badge']);
|
||||
$this->assertTrue($result['completed']);
|
||||
}
|
||||
|
||||
public function test_submission_status_returns_submitted_when_filled_matches_expected(): void
|
||||
{
|
||||
$result = $this->service->submissionStatus(10, 10);
|
||||
|
||||
$this->assertSame('Submitted', $result['label']);
|
||||
$this->assertSame('bg-success', $result['badge']);
|
||||
$this->assertSame('10/10', $result['detail']);
|
||||
$this->assertTrue($result['completed']);
|
||||
}
|
||||
|
||||
public function test_submission_status_returns_missing_when_not_complete(): void
|
||||
{
|
||||
$result = $this->service->submissionStatus(7, 10);
|
||||
|
||||
$this->assertSame('Missing', $result['label']);
|
||||
$this->assertSame('bg-danger', $result['badge']);
|
||||
$this->assertSame('7/10', $result['detail']);
|
||||
$this->assertFalse($result['completed']);
|
||||
}
|
||||
|
||||
public function test_attendance_status_returns_submitted(): void
|
||||
{
|
||||
$result = $this->service->attendanceStatus(true);
|
||||
|
||||
$this->assertSame('Submitted', $result['label']);
|
||||
$this->assertSame('bg-success', $result['badge']);
|
||||
$this->assertTrue($result['completed']);
|
||||
}
|
||||
|
||||
public function test_attendance_status_returns_missing(): void
|
||||
{
|
||||
$result = $this->service->attendanceStatus(false);
|
||||
|
||||
$this->assertSame('Missing', $result['label']);
|
||||
$this->assertSame('bg-danger', $result['badge']);
|
||||
$this->assertFalse($result['completed']);
|
||||
}
|
||||
|
||||
public function test_build_missing_items_returns_only_incomplete_items(): void
|
||||
{
|
||||
$result = $this->service->buildMissingItems([
|
||||
'midterm_score_status' => ['completed' => false],
|
||||
'midterm_comment_status' => ['completed' => true],
|
||||
'participation_status' => ['completed' => false],
|
||||
'ptap_comment_status' => ['completed' => true],
|
||||
$service = new TeacherSubmissionSupportService();
|
||||
$items = $service->buildMissingItems([
|
||||
'attendance_status' => ['completed' => false],
|
||||
'midterm_score_status' => ['completed' => true],
|
||||
]);
|
||||
|
||||
$this->assertSame([
|
||||
'midterm scores',
|
||||
'participation',
|
||||
'attendance',
|
||||
], $result);
|
||||
$this->assertSame(['attendance'], $items);
|
||||
}
|
||||
|
||||
public function test_teacher_role_priority_orders_main_before_ta_before_other(): void
|
||||
{
|
||||
$this->assertSame(1, $this->service->teacherRolePriority('main'));
|
||||
$this->assertSame(2, $this->service->teacherRolePriority('ta'));
|
||||
$this->assertSame(3, $this->service->teacherRolePriority('teacher'));
|
||||
}
|
||||
|
||||
public function test_truncate_notification_message_strips_tags_and_truncates(): void
|
||||
{
|
||||
$html = '<p>Hello <strong>world</strong></p>';
|
||||
$result = $this->service->truncateNotificationMessage($html, 5);
|
||||
|
||||
$this->assertSame('Hello…', $result);
|
||||
}
|
||||
|
||||
public function test_parse_missing_items_payload_returns_unique_trimmed_values(): void
|
||||
{
|
||||
$payload = base64_encode(json_encode([
|
||||
' midterm scores ',
|
||||
'attendance',
|
||||
'attendance',
|
||||
'',
|
||||
]));
|
||||
|
||||
$result = $this->service->parseMissingItemsPayload($payload);
|
||||
|
||||
$this->assertSame([
|
||||
'midterm scores',
|
||||
'attendance',
|
||||
], $result);
|
||||
}
|
||||
|
||||
public function test_format_missing_items_text_formats_lists_correctly(): void
|
||||
{
|
||||
$this->assertSame('', $this->service->formatMissingItemsText([]));
|
||||
$this->assertSame('attendance', $this->service->formatMissingItemsText(['attendance']));
|
||||
$this->assertSame(
|
||||
'attendance and midterm scores',
|
||||
$this->service->formatMissingItemsText(['attendance', 'midterm scores'])
|
||||
);
|
||||
$this->assertSame(
|
||||
'attendance, midterm scores and participation',
|
||||
$this->service->formatMissingItemsText(['attendance', 'midterm scores', 'participation'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user