add test batches
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdminNotificationSubjectService;
|
||||
use App\Services\Administrator\AdminNotificationUserService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
@@ -45,7 +44,7 @@ class AdminNotificationSubjectServiceTest extends TestCase
|
||||
'role_id' => 1,
|
||||
]);
|
||||
|
||||
$userService = new AdminNotificationUserService;
|
||||
$userService = new \App\Services\Administrator\AdminNotificationUserService();
|
||||
$service = new AdminNotificationSubjectService($userService);
|
||||
|
||||
$data = $service->alertsData();
|
||||
|
||||
@@ -66,7 +66,7 @@ class AdminNotificationUserServiceTest extends TestCase
|
||||
['id' => 2, 'user_id' => 2, 'role_id' => 2],
|
||||
]);
|
||||
|
||||
$service = new AdminNotificationUserService;
|
||||
$service = new AdminNotificationUserService();
|
||||
$admins = $service->fetchAdminNotificationUsers();
|
||||
|
||||
$this->assertCount(1, $admins);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdminNotificationUserService;
|
||||
use App\Services\Administrator\AdminPrintRecipientService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -51,7 +50,7 @@ class AdminPrintRecipientServiceTest extends TestCase
|
||||
'subject' => 'print_requests',
|
||||
]);
|
||||
|
||||
$service = new AdminPrintRecipientService(new AdminNotificationUserService);
|
||||
$service = new AdminPrintRecipientService(new \App\Services\Administrator\AdminNotificationUserService());
|
||||
$data = $service->data();
|
||||
|
||||
$this->assertTrue($data['assigned'][1]);
|
||||
|
||||
@@ -2,13 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Models\StaffAttendance;
|
||||
use App\Models\User;
|
||||
use App\Services\Administrator\AdministratorAbsenceService;
|
||||
use App\Services\Administrator\AdministratorSharedService;
|
||||
use App\Services\SemesterRangeService;
|
||||
use App\Services\Semesters\SemesterConfigService;
|
||||
use App\Services\Staff\StaffTimeOffLinkService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\Request;
|
||||
use Mockery;
|
||||
@@ -20,17 +14,17 @@ class AdministratorAbsenceServiceTest extends TestCase
|
||||
|
||||
public function test_submit_requires_reason(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$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 User,
|
||||
new StaffAttendance,
|
||||
new SemesterRangeService(new SemesterConfigService),
|
||||
Mockery::mock(StaffTimeOffLinkService::class)
|
||||
new \App\Models\User(),
|
||||
new \App\Models\StaffAttendance(),
|
||||
new \App\Services\SemesterRangeService(new \App\Services\Semesters\SemesterConfigService()),
|
||||
Mockery::mock(\App\Services\Staff\StaffTimeOffLinkService::class)
|
||||
);
|
||||
|
||||
$request = Request::create('/absences', 'POST', ['dates' => ['2025-01-05']]);
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorDashboardService;
|
||||
use App\Services\Administrator\AdministratorMetricsService;
|
||||
use App\Services\Administrator\AdministratorUserSearchService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
@@ -15,10 +13,10 @@ class AdministratorDashboardServiceTest extends TestCase
|
||||
|
||||
public function test_delegates_to_metrics_and_search(): void
|
||||
{
|
||||
$metrics = Mockery::mock(AdministratorMetricsService::class);
|
||||
$metrics = Mockery::mock(\App\Services\Administrator\AdministratorMetricsService::class);
|
||||
$metrics->shouldReceive('metrics')->once()->andReturn(['counts' => []]);
|
||||
|
||||
$search = Mockery::mock(AdministratorUserSearchService::class);
|
||||
$search = Mockery::mock(\App\Services\Administrator\AdministratorUserSearchService::class);
|
||||
$search->shouldReceive('search')->once()->with('john')->andReturn(['results' => []]);
|
||||
|
||||
$service = new AdministratorDashboardService($metrics, $search);
|
||||
|
||||
@@ -15,7 +15,7 @@ class AdministratorEnrollmentEventServiceTest extends TestCase
|
||||
{
|
||||
Event::fake();
|
||||
|
||||
$service = new AdministratorEnrollmentEventService;
|
||||
$service = new AdministratorEnrollmentEventService();
|
||||
$service->dispatchGroupedEvents([], [], [], '2025-2026');
|
||||
|
||||
Event::assertNotDispatched('studentEnrolled');
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Models\ClassSection;
|
||||
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 Mockery;
|
||||
use Tests\TestCase;
|
||||
@@ -18,17 +13,17 @@ class AdministratorEnrollmentQueryServiceTest extends TestCase
|
||||
|
||||
public function test_enrollment_withdrawal_data_returns_structure(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$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(
|
||||
$shared,
|
||||
new Student,
|
||||
new StudentClass,
|
||||
new Enrollment,
|
||||
new ClassSection
|
||||
new \App\Models\Student(),
|
||||
new \App\Models\StudentClass(),
|
||||
new \App\Models\Enrollment(),
|
||||
new \App\Models\ClassSection()
|
||||
);
|
||||
|
||||
$data = $service->enrollmentWithdrawalData('2025-2026');
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorEnrollmentRefundService;
|
||||
use App\Services\FeeCalculationService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Mockery;
|
||||
@@ -25,7 +24,7 @@ class AdministratorEnrollmentRefundServiceTest extends TestCase
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$feeCalc = Mockery::mock(FeeCalculationService::class);
|
||||
$feeCalc = Mockery::mock(\App\Services\FeeCalculationService::class);
|
||||
$service = new AdministratorEnrollmentRefundService($feeCalc);
|
||||
|
||||
$result = $service->processRefunds([10], '2025-2026', 1);
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorEnrollmentQueryService;
|
||||
use App\Services\Administrator\AdministratorEnrollmentService;
|
||||
use App\Services\Administrator\AdministratorEnrollmentStatusService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
@@ -15,11 +13,11 @@ class AdministratorEnrollmentServiceTest extends TestCase
|
||||
|
||||
public function test_delegates_to_query_and_status_services(): void
|
||||
{
|
||||
$query = Mockery::mock(AdministratorEnrollmentQueryService::class);
|
||||
$query = Mockery::mock(\App\Services\Administrator\AdministratorEnrollmentQueryService::class);
|
||||
$query->shouldReceive('enrollmentWithdrawalData')->once()->andReturn(['rows' => []]);
|
||||
$query->shouldReceive('newStudentsData')->once()->andReturn(['students' => []]);
|
||||
|
||||
$status = Mockery::mock(AdministratorEnrollmentStatusService::class);
|
||||
$status = Mockery::mock(\App\Services\Administrator\AdministratorEnrollmentStatusService::class);
|
||||
$status->shouldReceive('updateStatuses')->once()->andReturn(['success' => true]);
|
||||
|
||||
$service = new AdministratorEnrollmentService($query, $status);
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
|
||||
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\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
@@ -18,17 +13,17 @@ class AdministratorEnrollmentStatusServiceTest extends TestCase
|
||||
|
||||
public function test_update_statuses_requires_payload(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$shared = Mockery::mock(\App\Services\Administrator\AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
|
||||
$refundService = Mockery::mock(AdministratorEnrollmentRefundService::class);
|
||||
$eventService = Mockery::mock(AdministratorEnrollmentEventService::class);
|
||||
$refundService = Mockery::mock(\App\Services\Administrator\AdministratorEnrollmentRefundService::class);
|
||||
$eventService = Mockery::mock(\App\Services\Administrator\AdministratorEnrollmentEventService::class);
|
||||
|
||||
$service = new AdministratorEnrollmentStatusService(
|
||||
$shared,
|
||||
new Student,
|
||||
new User,
|
||||
new \App\Models\Student(),
|
||||
new \App\Models\User(),
|
||||
$refundService,
|
||||
$eventService
|
||||
);
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Models\Configuration;
|
||||
use App\Models\LoginActivity;
|
||||
use App\Models\User;
|
||||
use App\Services\Administrator\AdministratorMetricsService;
|
||||
use App\Services\Administrator\AdministratorSharedService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
@@ -23,9 +19,9 @@ class AdministratorMetricsServiceTest extends TestCase
|
||||
]);
|
||||
|
||||
$service = new AdministratorMetricsService(
|
||||
new AdministratorSharedService(new Configuration),
|
||||
new User,
|
||||
new LoginActivity
|
||||
new \App\Services\Administrator\AdministratorSharedService(new \App\Models\Configuration()),
|
||||
new \App\Models\User(),
|
||||
new \App\Models\LoginActivity()
|
||||
);
|
||||
|
||||
$metrics = $service->metrics();
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorNotificationService;
|
||||
use App\Services\Administrator\AdminNotificationSubjectService;
|
||||
use App\Services\Administrator\AdminPrintRecipientService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
@@ -15,11 +13,11 @@ class AdministratorNotificationServiceTest extends TestCase
|
||||
|
||||
public function test_delegates_to_subject_and_print_services(): void
|
||||
{
|
||||
$subject = Mockery::mock(AdminNotificationSubjectService::class);
|
||||
$subject = Mockery::mock(\App\Services\Administrator\AdminNotificationSubjectService::class);
|
||||
$subject->shouldReceive('alertsData')->once()->andReturn(['admins' => []]);
|
||||
$subject->shouldReceive('save')->once()->andReturn(['success' => true]);
|
||||
|
||||
$print = Mockery::mock(AdminPrintRecipientService::class);
|
||||
$print = Mockery::mock(\App\Services\Administrator\AdminPrintRecipientService::class);
|
||||
$print->shouldReceive('data')->once()->andReturn(['admins' => []]);
|
||||
$print->shouldReceive('save')->once()->andReturn(['success' => true]);
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Models\Configuration;
|
||||
use App\Services\Administrator\AdministratorSharedService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
@@ -13,7 +12,7 @@ class AdministratorSharedServiceTest extends TestCase
|
||||
|
||||
public function test_get_previous_school_year(): void
|
||||
{
|
||||
$service = new AdministratorSharedService(new Configuration);
|
||||
$service = new AdministratorSharedService(new \App\Models\Configuration());
|
||||
|
||||
$this->assertSame('2024-2025', $service->getPreviousSchoolYear('2025-2026'));
|
||||
$this->assertSame('2024-25', $service->getPreviousSchoolYear('2025-26'));
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorTeacherSubmissionService;
|
||||
use App\Services\Administrator\TeacherSubmissionNotificationService;
|
||||
use App\Services\Administrator\TeacherSubmissionReportService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\Request;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -16,15 +13,15 @@ class AdministratorTeacherSubmissionServiceTest extends TestCase
|
||||
|
||||
public function test_delegates_to_report_and_notification(): void
|
||||
{
|
||||
$report = Mockery::mock(TeacherSubmissionReportService::class);
|
||||
$report = Mockery::mock(\App\Services\Administrator\TeacherSubmissionReportService::class);
|
||||
$report->shouldReceive('report')->once()->andReturn(['rows' => []]);
|
||||
|
||||
$notify = Mockery::mock(TeacherSubmissionNotificationService::class);
|
||||
$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 Request, 1));
|
||||
$this->assertSame(['success' => true], $service->sendNotifications(new \Illuminate\Http\Request(), 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AdministratorUserSearchServiceTest extends TestCase
|
||||
|
||||
public function test_empty_query_returns_no_results(): void
|
||||
{
|
||||
$service = new AdministratorUserSearchService;
|
||||
$service = new AdministratorUserSearchService();
|
||||
$result = $service->search('');
|
||||
|
||||
$this->assertSame('', $result['query']);
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
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 Mockery;
|
||||
@@ -16,8 +14,8 @@ class TeacherSubmissionNotificationServiceTest extends TestCase
|
||||
|
||||
public function test_send_requires_targets(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$support = Mockery::mock(TeacherSubmissionSupportService::class);
|
||||
$shared = Mockery::mock(\App\Services\Administrator\AdministratorSharedService::class);
|
||||
$support = Mockery::mock(\App\Services\Administrator\TeacherSubmissionSupportService::class);
|
||||
|
||||
$service = new TeacherSubmissionNotificationService($shared, $support);
|
||||
$request = Request::create('/notify', 'POST', []);
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\Administrator;
|
||||
|
||||
use App\Services\Administrator\AdministratorSharedService;
|
||||
use App\Services\Administrator\TeacherSubmissionReportService;
|
||||
use App\Services\Administrator\TeacherSubmissionSupportService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
@@ -15,11 +13,11 @@ class TeacherSubmissionReportServiceTest extends TestCase
|
||||
|
||||
public function test_report_returns_summary(): void
|
||||
{
|
||||
$shared = Mockery::mock(AdministratorSharedService::class);
|
||||
$shared = Mockery::mock(\App\Services\Administrator\AdministratorSharedService::class);
|
||||
$shared->shouldReceive('getSemester')->andReturn('Fall');
|
||||
$shared->shouldReceive('getSchoolYear')->andReturn('2025-2026');
|
||||
|
||||
$support = Mockery::mock(TeacherSubmissionSupportService::class);
|
||||
$support = Mockery::mock(\App\Services\Administrator\TeacherSubmissionSupportService::class);
|
||||
$support->shouldReceive('submissionStatus')->andReturn([
|
||||
'label' => 'No students',
|
||||
'badge' => 'bg-secondary',
|
||||
|
||||
@@ -12,7 +12,7 @@ class TeacherSubmissionSupportServiceTest extends TestCase
|
||||
|
||||
public function test_submission_status_labels(): void
|
||||
{
|
||||
$service = new TeacherSubmissionSupportService;
|
||||
$service = new TeacherSubmissionSupportService();
|
||||
$status = $service->submissionStatus(3, 5);
|
||||
|
||||
$this->assertSame('Missing', $status['label']);
|
||||
@@ -21,7 +21,7 @@ class TeacherSubmissionSupportServiceTest extends TestCase
|
||||
|
||||
public function test_build_missing_items(): void
|
||||
{
|
||||
$service = new TeacherSubmissionSupportService;
|
||||
$service = new TeacherSubmissionSupportService();
|
||||
$items = $service->buildMissingItems([
|
||||
'attendance_status' => ['completed' => false],
|
||||
'midterm_score_status' => ['completed' => true],
|
||||
|
||||
@@ -19,7 +19,7 @@ class AssignmentContextServiceTest extends TestCase
|
||||
['id' => 2, 'config_key' => 'semester', 'config_value' => 'Fall'],
|
||||
]);
|
||||
|
||||
$service = new AssignmentContextService(new Configuration);
|
||||
$service = new AssignmentContextService(new Configuration());
|
||||
|
||||
$this->assertSame('Fall', $service->getCurrentSemester());
|
||||
$this->assertSame('2025-2026', $service->getCurrentSchoolYear());
|
||||
|
||||
@@ -17,7 +17,7 @@ class AssignmentDataLoaderServiceTest extends TestCase
|
||||
{
|
||||
$this->seedTeacherData();
|
||||
|
||||
$service = new AssignmentDataLoaderService(new TeacherClass, new StudentClass);
|
||||
$service = new AssignmentDataLoaderService(new TeacherClass(), new StudentClass());
|
||||
$rows = $service->loadTeacherClasses('2025-2026');
|
||||
|
||||
$this->assertCount(1, $rows);
|
||||
@@ -28,7 +28,7 @@ class AssignmentDataLoaderServiceTest extends TestCase
|
||||
{
|
||||
$this->seedStudentData();
|
||||
|
||||
$service = new AssignmentDataLoaderService(new TeacherClass, new StudentClass);
|
||||
$service = new AssignmentDataLoaderService(new TeacherClass(), new StudentClass());
|
||||
$rows = $service->loadStudentClasses('2025-2026');
|
||||
|
||||
$this->assertCount(1, $rows);
|
||||
|
||||
@@ -13,7 +13,7 @@ class AssignmentMetaServiceTest extends TestCase
|
||||
|
||||
public function test_get_school_years_uses_fallback(): void
|
||||
{
|
||||
$service = new AssignmentMetaService;
|
||||
$service = new AssignmentMetaService();
|
||||
$years = $service->getSchoolYears('2025-2026');
|
||||
|
||||
$this->assertSame(['2025-2026'], $years);
|
||||
@@ -27,7 +27,7 @@ class AssignmentMetaServiceTest extends TestCase
|
||||
['class_section_id' => 103, 'teacher_id' => 3, 'position' => 'main', 'school_year' => '2025-2026', 'semester' => 'Fall'],
|
||||
]);
|
||||
|
||||
$service = new AssignmentMetaService;
|
||||
$service = new AssignmentMetaService();
|
||||
$years = $service->getSchoolYears();
|
||||
|
||||
$this->assertSame(['2025-2026', '2024-2025'], $years);
|
||||
@@ -35,7 +35,7 @@ class AssignmentMetaServiceTest extends TestCase
|
||||
|
||||
public function test_first_non_empty_returns_first_value(): void
|
||||
{
|
||||
$service = new AssignmentMetaService;
|
||||
$service = new AssignmentMetaService();
|
||||
$value = $service->firstNonEmpty([null, '', 'Fall', 'Spring']);
|
||||
|
||||
$this->assertSame('Fall', $value);
|
||||
|
||||
@@ -23,7 +23,7 @@ class AssignmentSectionServiceTest extends TestCase
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$service = new AssignmentSectionService(new ClassSection);
|
||||
$service = new AssignmentSectionService(new ClassSection());
|
||||
$map = $service->getSectionNamesMap([1]);
|
||||
|
||||
$this->assertSame('1-A', $map[1]);
|
||||
|
||||
@@ -17,19 +17,12 @@ class AssignmentServiceTest extends TestCase
|
||||
use RefreshDatabase;
|
||||
|
||||
protected AssignmentService $service;
|
||||
|
||||
protected User $teacherMain;
|
||||
|
||||
protected User $teacherAssistant;
|
||||
|
||||
protected User $updatedByUser;
|
||||
|
||||
protected ClassSection $sectionA;
|
||||
|
||||
protected ClassSection $sectionB;
|
||||
|
||||
protected Student $studentOne;
|
||||
|
||||
protected Student $studentTwo;
|
||||
|
||||
protected function setUp(): void
|
||||
|
||||
@@ -16,7 +16,7 @@ class AttendanceAutoPublishJobServiceTest extends TestCase
|
||||
|
||||
public function test_run_publishes_due_records(): void
|
||||
{
|
||||
$autoPublish = new AttendanceAutoPublishService;
|
||||
$autoPublish = new AttendanceAutoPublishService();
|
||||
$service = new AttendanceAutoPublishJobService($autoPublish);
|
||||
|
||||
$now = new DateTimeImmutable('2025-03-01 10:00:00', new DateTimeZone('UTC'));
|
||||
|
||||
@@ -10,7 +10,7 @@ class AttendanceAutoPublishServiceTest extends TestCase
|
||||
{
|
||||
public function test_second_sunday_after_end_of_day(): void
|
||||
{
|
||||
$service = new AttendanceAutoPublishService;
|
||||
$service = new AttendanceAutoPublishService();
|
||||
|
||||
$result = $service->secondSundayAfterEndOfDay('2025-02-03', 'UTC');
|
||||
|
||||
@@ -19,7 +19,7 @@ class AttendanceAutoPublishServiceTest extends TestCase
|
||||
|
||||
public function test_second_sunday_backward_date(): void
|
||||
{
|
||||
$service = new AttendanceAutoPublishService;
|
||||
$service = new AttendanceAutoPublishService();
|
||||
$now = new DateTimeImmutable('2025-02-16 10:00:00', new \DateTimeZone('UTC'));
|
||||
|
||||
$result = $service->secondSundayBackwardDate($now, 'UTC');
|
||||
|
||||
@@ -28,7 +28,7 @@ class AttendanceCommentServiceTest extends TestCase
|
||||
],
|
||||
]);
|
||||
|
||||
$service = new AttendanceCommentService;
|
||||
$service = new AttendanceCommentService();
|
||||
$comment = $service->commentFromScore(95, 'James');
|
||||
|
||||
$this->assertSame("James' attendance is excellent.", $comment);
|
||||
@@ -43,7 +43,7 @@ class AttendanceCommentServiceTest extends TestCase
|
||||
'is_active' => 1,
|
||||
]);
|
||||
|
||||
$service = new AttendanceCommentService;
|
||||
$service = new AttendanceCommentService();
|
||||
$comment = $service->commentFromScore(70);
|
||||
|
||||
$this->assertSame("This student's needs improvement in attendance.", $comment);
|
||||
|
||||
@@ -7,7 +7,6 @@ use App\Services\Attendance\AttendanceConsequenceService;
|
||||
use App\Services\EmailService;
|
||||
use App\Services\Notifications\UserNotificationDispatchService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -31,7 +30,7 @@ class AttendanceConsequenceServiceTest extends TestCase
|
||||
|
||||
public function test_send_follow_up_marks_tracking_and_notifies(): void
|
||||
{
|
||||
DB::table('students')->insert([
|
||||
\Illuminate\Support\Facades\DB::table('students')->insert([
|
||||
'id' => 1,
|
||||
'school_id' => 1,
|
||||
'parent_id' => 1,
|
||||
|
||||
@@ -12,7 +12,7 @@ class AttendancePolicyServiceTest extends TestCase
|
||||
|
||||
public function test_teacher_can_edit_draft(): void
|
||||
{
|
||||
$service = new AttendancePolicyService;
|
||||
$service = new AttendancePolicyService();
|
||||
$allowed = $service->canEditDay(
|
||||
['status' => 'draft'],
|
||||
['roles' => ['Teacher'], 'permissions' => []]
|
||||
@@ -23,7 +23,7 @@ class AttendancePolicyServiceTest extends TestCase
|
||||
|
||||
public function test_teacher_cannot_edit_finalized(): void
|
||||
{
|
||||
$service = new AttendancePolicyService;
|
||||
$service = new AttendancePolicyService();
|
||||
$allowed = $service->canEditDay(
|
||||
['status' => 'finalized'],
|
||||
['roles' => ['Teacher'], 'permissions' => []]
|
||||
@@ -34,7 +34,7 @@ class AttendancePolicyServiceTest extends TestCase
|
||||
|
||||
public function test_admin_like_by_permission(): void
|
||||
{
|
||||
$service = new AttendancePolicyService;
|
||||
$service = new AttendancePolicyService();
|
||||
$isAdmin = $service->isAdminLike([], ['attendance.manage.daily']);
|
||||
|
||||
$this->assertTrue($isAdmin);
|
||||
@@ -42,7 +42,7 @@ class AttendancePolicyServiceTest extends TestCase
|
||||
|
||||
public function test_can_manage_early_dismissals_for_teacher(): void
|
||||
{
|
||||
$service = new AttendancePolicyService;
|
||||
$service = new AttendancePolicyService();
|
||||
$allowed = $service->canManageEarlyDismissals(['Teacher']);
|
||||
|
||||
$this->assertTrue($allowed);
|
||||
|
||||
@@ -2,25 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\Attendance;
|
||||
|
||||
use App\Models\AttendanceData;
|
||||
use App\Models\AttendanceDay;
|
||||
use App\Models\AttendanceRecord;
|
||||
use App\Models\Calendar;
|
||||
use App\Models\ClassSection;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\Student;
|
||||
use App\Models\StudentClass;
|
||||
use App\Models\TeacherClass;
|
||||
use App\Models\User;
|
||||
use App\Models\UserRole;
|
||||
use App\Services\Attendance\AttendanceAutoPublishService;
|
||||
use App\Services\Attendance\AttendancePolicyService;
|
||||
use App\Services\Attendance\AttendanceQueryService;
|
||||
use App\Services\Attendance\AttendanceRecordSyncService;
|
||||
use App\Services\Attendance\AttendanceService;
|
||||
use App\Services\Attendance\SemesterRangeService;
|
||||
use App\Services\Attendance\StudentAttendanceWriterService;
|
||||
use App\Services\Attendance\TeacherAttendanceSubmissionService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
@@ -80,45 +62,45 @@ class AttendanceQueryServiceTest extends TestCase
|
||||
]);
|
||||
|
||||
$service = new AttendanceQueryService(
|
||||
new Configuration,
|
||||
new AttendanceData,
|
||||
new AttendanceDay,
|
||||
new AttendanceRecord,
|
||||
new Student,
|
||||
new StudentClass,
|
||||
new ClassSection,
|
||||
new TeacherClass,
|
||||
new Calendar,
|
||||
new User,
|
||||
new UserRole,
|
||||
new AttendanceService(
|
||||
new Configuration,
|
||||
new AttendanceData,
|
||||
new AttendanceDay,
|
||||
new ClassSection,
|
||||
new UserRole,
|
||||
new AttendancePolicyService,
|
||||
new StudentAttendanceWriterService(
|
||||
new AttendanceData,
|
||||
new Student,
|
||||
new AttendanceRecordSyncService(new AttendanceRecord)
|
||||
new \App\Models\Configuration(),
|
||||
new \App\Models\AttendanceData(),
|
||||
new \App\Models\AttendanceDay(),
|
||||
new \App\Models\AttendanceRecord(),
|
||||
new \App\Models\Student(),
|
||||
new \App\Models\StudentClass(),
|
||||
new \App\Models\ClassSection(),
|
||||
new \App\Models\TeacherClass(),
|
||||
new \App\Models\Calendar(),
|
||||
new \App\Models\User(),
|
||||
new \App\Models\UserRole(),
|
||||
new \App\Services\Attendance\AttendanceService(
|
||||
new \App\Models\Configuration(),
|
||||
new \App\Models\AttendanceData(),
|
||||
new \App\Models\AttendanceDay(),
|
||||
new \App\Models\ClassSection(),
|
||||
new \App\Models\UserRole(),
|
||||
new \App\Services\Attendance\AttendancePolicyService(),
|
||||
new \App\Services\Attendance\StudentAttendanceWriterService(
|
||||
new \App\Models\AttendanceData(),
|
||||
new \App\Models\Student(),
|
||||
new \App\Services\Attendance\AttendanceRecordSyncService(new \App\Models\AttendanceRecord())
|
||||
),
|
||||
new TeacherAttendanceSubmissionService(
|
||||
new AttendanceDay,
|
||||
new AttendanceData,
|
||||
new TeacherClass,
|
||||
new Student,
|
||||
new AttendancePolicyService,
|
||||
new StudentAttendanceWriterService(
|
||||
new AttendanceData,
|
||||
new Student,
|
||||
new AttendanceRecordSyncService(new AttendanceRecord)
|
||||
new \App\Services\Attendance\TeacherAttendanceSubmissionService(
|
||||
new \App\Models\AttendanceDay(),
|
||||
new \App\Models\AttendanceData(),
|
||||
new \App\Models\TeacherClass(),
|
||||
new \App\Models\Student(),
|
||||
new \App\Services\Attendance\AttendancePolicyService(),
|
||||
new \App\Services\Attendance\StudentAttendanceWriterService(
|
||||
new \App\Models\AttendanceData(),
|
||||
new \App\Models\Student(),
|
||||
new \App\Services\Attendance\AttendanceRecordSyncService(new \App\Models\AttendanceRecord())
|
||||
),
|
||||
new AttendanceAutoPublishService
|
||||
new \App\Services\Attendance\AttendanceAutoPublishService()
|
||||
),
|
||||
new AttendanceRecordSyncService(new AttendanceRecord)
|
||||
new \App\Services\Attendance\AttendanceRecordSyncService(new \App\Models\AttendanceRecord())
|
||||
),
|
||||
new SemesterRangeService
|
||||
new \App\Services\Attendance\SemesterRangeService()
|
||||
);
|
||||
|
||||
$grid = $service->teacherGrid('Fall', '2025-2026', '2025-01-05', 10);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Tests\Unit\Services\Attendance;
|
||||
|
||||
use App\Models\AttendanceRecord;
|
||||
use App\Services\Attendance\AttendanceRecordSyncService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -26,7 +25,7 @@ class AttendanceRecordSyncServiceTest extends TestCase
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$service = new AttendanceRecordSyncService(new AttendanceRecord);
|
||||
$service = new AttendanceRecordSyncService(new \App\Models\AttendanceRecord());
|
||||
$service->updateAttendanceRecord(10, 'S1', 'absent', 'Fall', '2025-2026', 'present', 1);
|
||||
|
||||
$row = DB::table('attendance_record')->where('student_id', 10)->first();
|
||||
@@ -36,7 +35,7 @@ class AttendanceRecordSyncServiceTest extends TestCase
|
||||
|
||||
public function test_add_new_attendance_record_creates_row(): void
|
||||
{
|
||||
$service = new AttendanceRecordSyncService(new AttendanceRecord);
|
||||
$service = new AttendanceRecordSyncService(new \App\Models\AttendanceRecord());
|
||||
$service->addNewAttendanceRecord(1, 10, 'S1', 'present', 'Fall', '2025-2026', 1);
|
||||
|
||||
$this->assertDatabaseHas('attendance_record', [
|
||||
|
||||
@@ -12,7 +12,7 @@ class AttendanceSemesterRangeServiceTest extends TestCase
|
||||
|
||||
public function test_get_semester_range(): void
|
||||
{
|
||||
$service = new SemesterRangeService;
|
||||
$service = new SemesterRangeService();
|
||||
$range = $service->getSemesterRange('2025-2026', 'fall');
|
||||
|
||||
$this->assertSame(['2025-09-21', '2026-01-18'], $range);
|
||||
@@ -20,7 +20,7 @@ class AttendanceSemesterRangeServiceTest extends TestCase
|
||||
|
||||
public function test_build_sunday_list_returns_sundays(): void
|
||||
{
|
||||
$service = new SemesterRangeService;
|
||||
$service = new SemesterRangeService();
|
||||
$dates = $service->buildSundayList('2025-09-01', '2025-09-30');
|
||||
|
||||
$this->assertContains('2025-09-07', $dates);
|
||||
|
||||
@@ -34,11 +34,11 @@ class AttendanceServiceTest extends TestCase
|
||||
$recordSync = Mockery::mock(AttendanceRecordSyncService::class);
|
||||
|
||||
$service = new AttendanceService(
|
||||
new Configuration,
|
||||
new AttendanceData,
|
||||
new AttendanceDay,
|
||||
new ClassSection,
|
||||
new UserRole,
|
||||
new Configuration(),
|
||||
new AttendanceData(),
|
||||
new AttendanceDay(),
|
||||
new ClassSection(),
|
||||
new UserRole(),
|
||||
$policy,
|
||||
$writer,
|
||||
$teacherSubmission,
|
||||
@@ -70,11 +70,11 @@ class AttendanceServiceTest extends TestCase
|
||||
$recordSync = Mockery::mock(AttendanceRecordSyncService::class);
|
||||
|
||||
$service = new AttendanceService(
|
||||
new Configuration,
|
||||
new AttendanceData,
|
||||
new AttendanceDay,
|
||||
new ClassSection,
|
||||
new UserRole,
|
||||
new Configuration(),
|
||||
new AttendanceData(),
|
||||
new AttendanceDay(),
|
||||
new ClassSection(),
|
||||
new UserRole(),
|
||||
$policy,
|
||||
$writer,
|
||||
$teacherSubmission,
|
||||
|
||||
@@ -46,7 +46,7 @@ class AttendanceSummaryRebuildServiceTest extends TestCase
|
||||
],
|
||||
]);
|
||||
|
||||
$service = new AttendanceSummaryRebuildService;
|
||||
$service = new AttendanceSummaryRebuildService();
|
||||
$result = $service->rebuild();
|
||||
|
||||
$this->assertSame(2, $result['inserted']);
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\AttendanceData;
|
||||
use App\Models\AttendanceEmailTemplate;
|
||||
use App\Models\AttendanceTracking;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\ParentNotification;
|
||||
use App\Models\Student;
|
||||
use App\Models\StudentClass;
|
||||
use App\Models\Student;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\AttendanceData;
|
||||
use App\Models\ParentNotification;
|
||||
use App\Models\AttendanceEmailTemplate;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -19,11 +19,8 @@ use Throwable;
|
||||
class AttendanceTrackingService
|
||||
{
|
||||
protected string $semester;
|
||||
|
||||
protected string $schoolYear;
|
||||
|
||||
protected array $debugCompute = [];
|
||||
|
||||
protected ?array $attendanceReportedColumns = null;
|
||||
|
||||
public function __construct(
|
||||
@@ -43,19 +40,19 @@ class AttendanceTrackingService
|
||||
public function getPendingViolations(?string $schoolYearParam = null, ?string $semesterParam = null): array
|
||||
{
|
||||
$schoolYear = filled($schoolYearParam) ? (string) $schoolYearParam : (string) $this->schoolYear;
|
||||
$semester = filled($semesterParam) ? (string) $semesterParam : null; // disabled like legacy
|
||||
$semester = filled($semesterParam) ? (string) $semesterParam : null; // disabled like legacy
|
||||
|
||||
$debugInfo = [
|
||||
'school_year_param' => $schoolYear,
|
||||
'semester_param' => $semester,
|
||||
'class_students' => 0,
|
||||
'student_ids' => 0,
|
||||
'attendance_rows' => 0,
|
||||
'filtered_rows' => 0,
|
||||
'violations' => 0,
|
||||
'active_weeks' => 0,
|
||||
'abs_last5' => 0,
|
||||
'late_last5' => 0,
|
||||
'semester_param' => $semester,
|
||||
'class_students' => 0,
|
||||
'student_ids' => 0,
|
||||
'attendance_rows' => 0,
|
||||
'filtered_rows' => 0,
|
||||
'violations' => 0,
|
||||
'active_weeks' => 0,
|
||||
'abs_last5' => 0,
|
||||
'late_last5' => 0,
|
||||
];
|
||||
|
||||
$classStudentsQuery = $this->studentClassModel->query();
|
||||
@@ -76,9 +73,9 @@ class AttendanceTrackingService
|
||||
->orderByDesc('id')
|
||||
->first();
|
||||
|
||||
if ($latestTerm && ! empty($latestTerm->school_year)) {
|
||||
if ($latestTerm && !empty($latestTerm->school_year)) {
|
||||
$schoolYear = (string) $latestTerm->school_year;
|
||||
if (! empty($latestTerm->semester)) {
|
||||
if (!empty($latestTerm->semester)) {
|
||||
$semester = (string) $latestTerm->semester;
|
||||
}
|
||||
|
||||
@@ -109,7 +106,7 @@ class AttendanceTrackingService
|
||||
if (empty($studentIds) && empty($studentCodes)) {
|
||||
$attendanceStudents = DB::table('attendance_data')
|
||||
->selectRaw('DISTINCT student_id')
|
||||
->when(! empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
|
||||
->when(!empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
|
||||
->orderBy('student_id')
|
||||
->get();
|
||||
|
||||
@@ -126,7 +123,7 @@ class AttendanceTrackingService
|
||||
$studentIds = array_values(array_unique(array_filter($studentIds, fn ($v) => $v > 0)));
|
||||
$studentCodes = array_values(array_unique(array_filter($studentCodes, fn ($v) => $v !== '')));
|
||||
|
||||
if (! empty($studentIds)) {
|
||||
if (!empty($studentIds)) {
|
||||
$inactiveRows = $this->studentModel->query()
|
||||
->select('id')
|
||||
->whereIn('id', $studentIds)
|
||||
@@ -141,11 +138,11 @@ class AttendanceTrackingService
|
||||
|
||||
$studentIds = array_values(array_filter(
|
||||
$studentIds,
|
||||
static fn ($id) => ! isset($inactiveIdSet[$id])
|
||||
static fn ($id) => !isset($inactiveIdSet[$id])
|
||||
));
|
||||
}
|
||||
|
||||
if (! empty($studentCodes)) {
|
||||
if (!empty($studentCodes)) {
|
||||
$inactiveCodeRows = $this->studentModel->query()
|
||||
->select('school_id')
|
||||
->whereIn('school_id', $studentCodes)
|
||||
@@ -160,7 +157,7 @@ class AttendanceTrackingService
|
||||
|
||||
$studentCodes = array_values(array_filter(
|
||||
$studentCodes,
|
||||
static fn ($code) => $code !== '' && ! isset($inactiveCodeSet[$code])
|
||||
static fn ($code) => $code !== '' && !isset($inactiveCodeSet[$code])
|
||||
));
|
||||
}
|
||||
|
||||
@@ -177,7 +174,7 @@ class AttendanceTrackingService
|
||||
}
|
||||
|
||||
$students = [];
|
||||
if (! empty($studentIds)) {
|
||||
if (!empty($studentIds)) {
|
||||
$students = $this->studentModel->query()
|
||||
->whereIn('id', $studentIds)
|
||||
->where('is_active', 1)
|
||||
@@ -185,7 +182,7 @@ class AttendanceTrackingService
|
||||
->toArray();
|
||||
}
|
||||
|
||||
if (! empty($studentCodes)) {
|
||||
if (!empty($studentCodes)) {
|
||||
$byCode = $this->studentModel->query()
|
||||
->whereIn('school_id', $studentCodes)
|
||||
->where('is_active', 1)
|
||||
@@ -195,7 +192,7 @@ class AttendanceTrackingService
|
||||
$seen = array_flip(array_map(fn ($s) => (int) ($s['id'] ?? 0), $students));
|
||||
foreach ($byCode as $s) {
|
||||
$sid = (int) ($s['id'] ?? 0);
|
||||
if ($sid > 0 && ! isset($seen[$sid])) {
|
||||
if ($sid > 0 && !isset($seen[$sid])) {
|
||||
$students[] = $s;
|
||||
$seen[$sid] = true;
|
||||
}
|
||||
@@ -211,7 +208,7 @@ class AttendanceTrackingService
|
||||
}
|
||||
|
||||
foreach ($studentCodes as $code) {
|
||||
if (! isset($knownCodes[$code])) {
|
||||
if (!isset($knownCodes[$code])) {
|
||||
$virtualId = abs(crc32($code)) ?: random_int(1000000, 1999999);
|
||||
$students[] = [
|
||||
'id' => $virtualId,
|
||||
@@ -247,7 +244,7 @@ class AttendanceTrackingService
|
||||
foreach (array_merge($studentIds, $studentCodes) as $sidOrCode) {
|
||||
if (is_numeric($sidOrCode)) {
|
||||
$sid = (int) $sidOrCode;
|
||||
if ($sid > 0 && ! isset($existingIds[$sid])) {
|
||||
if ($sid > 0 && !isset($existingIds[$sid])) {
|
||||
$students[] = [
|
||||
'id' => $sid,
|
||||
'school_id' => (string) $sid,
|
||||
@@ -260,7 +257,7 @@ class AttendanceTrackingService
|
||||
}
|
||||
} else {
|
||||
$code = (string) $sidOrCode;
|
||||
if ($code !== '' && ! isset($studentCodeToId[$code])) {
|
||||
if ($code !== '' && !isset($studentCodeToId[$code])) {
|
||||
$virtualId = abs(crc32($code)) ?: random_int(2000000, 2999999);
|
||||
$students[] = [
|
||||
'id' => $virtualId,
|
||||
@@ -298,14 +295,14 @@ class AttendanceTrackingService
|
||||
'is_reported',
|
||||
'is_notified',
|
||||
])
|
||||
->when(! empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
|
||||
->when(! empty($semester), fn ($q) => $q->where('semester', $semester))
|
||||
->when(!empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
|
||||
->when(!empty($semester), fn ($q) => $q->where('semester', $semester))
|
||||
->where(function ($q) use ($studentIds, $studentCodes) {
|
||||
if (! empty($studentIds)) {
|
||||
if (!empty($studentIds)) {
|
||||
$q->whereIn('student_id', $studentIds);
|
||||
}
|
||||
if (! empty($studentCodes)) {
|
||||
if (! empty($studentIds)) {
|
||||
if (!empty($studentCodes)) {
|
||||
if (!empty($studentIds)) {
|
||||
$q->orWhereIn('student_id', $studentCodes);
|
||||
} else {
|
||||
$q->whereIn('student_id', $studentCodes);
|
||||
@@ -325,16 +322,16 @@ class AttendanceTrackingService
|
||||
if (empty($termRows)) {
|
||||
$latestAttendanceTerm = DB::table('attendance_data')
|
||||
->select('school_year', 'semester', 'date')
|
||||
->when(! empty($studentIds), fn ($q) => $q->whereIn('student_id', $studentIds))
|
||||
->when(!empty($studentIds), fn ($q) => $q->whereIn('student_id', $studentIds))
|
||||
->orderByDesc('date')
|
||||
->first();
|
||||
|
||||
if ($latestAttendanceTerm) {
|
||||
$schoolYear = ! empty($latestAttendanceTerm->school_year)
|
||||
$schoolYear = !empty($latestAttendanceTerm->school_year)
|
||||
? (string) $latestAttendanceTerm->school_year
|
||||
: $schoolYear;
|
||||
|
||||
$semester = ! empty($latestAttendanceTerm->semester)
|
||||
$semester = !empty($latestAttendanceTerm->semester)
|
||||
? (string) $latestAttendanceTerm->semester
|
||||
: $semester;
|
||||
|
||||
@@ -357,14 +354,14 @@ class AttendanceTrackingService
|
||||
'is_reported',
|
||||
'is_notified',
|
||||
])
|
||||
->when(! empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
|
||||
->when(! empty($semester), fn ($q) => $q->where('semester', $semester))
|
||||
->when(!empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
|
||||
->when(!empty($semester), fn ($q) => $q->where('semester', $semester))
|
||||
->where(function ($q) use ($studentIds, $studentCodes) {
|
||||
if (! empty($studentIds)) {
|
||||
if (!empty($studentIds)) {
|
||||
$q->whereIn('student_id', $studentIds);
|
||||
}
|
||||
if (! empty($studentCodes)) {
|
||||
if (! empty($studentIds)) {
|
||||
if (!empty($studentCodes)) {
|
||||
if (!empty($studentIds)) {
|
||||
$q->orWhereIn('student_id', $studentCodes);
|
||||
} else {
|
||||
$q->whereIn('student_id', $studentCodes);
|
||||
@@ -395,7 +392,7 @@ class AttendanceTrackingService
|
||||
$attendanceRows = [];
|
||||
foreach ($termRows as $row) {
|
||||
$dStr = $row['date'] ?? null;
|
||||
if (! $dStr) {
|
||||
if (!$dStr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -405,7 +402,7 @@ class AttendanceTrackingService
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($d->lt($start) || ! $d->lt($endEx)) {
|
||||
if ($d->lt($start) || !$d->lt($endEx)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -421,7 +418,7 @@ class AttendanceTrackingService
|
||||
if ($sid === null) {
|
||||
$sid = abs(crc32($code)) ?: random_int(3000000, 3999999);
|
||||
$studentCodeToId[$code] = $sid;
|
||||
if (! isset($existingIds[$sid])) {
|
||||
if (!isset($existingIds[$sid])) {
|
||||
$students[] = [
|
||||
'id' => $sid,
|
||||
'school_id' => $code,
|
||||
@@ -446,7 +443,7 @@ class AttendanceTrackingService
|
||||
|
||||
foreach ($attendanceRows as $arow) {
|
||||
$sid = (int) ($arow['student_id'] ?? 0);
|
||||
if ($sid > 0 && ! isset($existingIds[$sid])) {
|
||||
if ($sid > 0 && !isset($existingIds[$sid])) {
|
||||
$students[] = [
|
||||
'id' => $sid,
|
||||
'school_id' => (string) ($arow['student_code'] ?? $arow['student_id']),
|
||||
@@ -498,13 +495,13 @@ class AttendanceTrackingService
|
||||
$parentEmail = $data['parent_email'] ?? '';
|
||||
$parentName = $data['parent_name'] ?? '';
|
||||
|
||||
if (! $parentEmail) {
|
||||
if (!$parentEmail) {
|
||||
$parent = $this->getPrimaryParentForStudent($sid) ?? [];
|
||||
$parentEmail = $parent['email'] ?? '';
|
||||
$parentName = $parent['parent_name'] ?? '';
|
||||
}
|
||||
|
||||
if (! $parentEmail) {
|
||||
if (!$parentEmail) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'No parent email found for this student.',
|
||||
@@ -555,7 +552,7 @@ class AttendanceTrackingService
|
||||
try {
|
||||
$this->attendanceMailerService->queueAttendanceEvent($payload);
|
||||
|
||||
if ($row && ! empty($row['id']) && method_exists($this->attendanceTrackingModel, 'markAsNotified')) {
|
||||
if ($row && !empty($row['id']) && method_exists($this->attendanceTrackingModel, 'markAsNotified')) {
|
||||
$this->attendanceTrackingModel->markAsNotified((int) $row['id']);
|
||||
}
|
||||
|
||||
@@ -565,7 +562,7 @@ class AttendanceTrackingService
|
||||
'data' => $payload,
|
||||
];
|
||||
} catch (Throwable $e) {
|
||||
Log::error('Attendance record queue failed: '.$e->getMessage());
|
||||
Log::error('Attendance record queue failed: ' . $e->getMessage());
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
@@ -585,7 +582,7 @@ class AttendanceTrackingService
|
||||
?string $semesterFilter = null
|
||||
): array {
|
||||
$student = $this->studentModel->query()->find($studentId);
|
||||
if (! $student) {
|
||||
if (!$student) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Student not found',
|
||||
@@ -594,7 +591,7 @@ class AttendanceTrackingService
|
||||
}
|
||||
|
||||
$student = $student->toArray();
|
||||
$student['name'] = trim(($student['firstname'] ?? '').' '.($student['lastname'] ?? ''));
|
||||
$student['name'] = trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? ''));
|
||||
|
||||
$codeParam = strtoupper((string) ($codeParam ?? ''));
|
||||
$incidentDate = preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) $incidentDate) ? (string) $incidentDate : '';
|
||||
@@ -659,7 +656,7 @@ class AttendanceTrackingService
|
||||
])
|
||||
->where(function ($q) use ($studentIdValues, $studentCodeValues) {
|
||||
$q->whereIn('student_id', $studentIdValues);
|
||||
if (! empty($studentCodeValues)) {
|
||||
if (!empty($studentCodeValues)) {
|
||||
$q->orWhereIn('student_id', $studentCodeValues);
|
||||
}
|
||||
})
|
||||
@@ -677,7 +674,7 @@ class AttendanceTrackingService
|
||||
if ($pendingOnly) {
|
||||
$this->applyUnreportedAttendanceFilter($qb);
|
||||
|
||||
if (! $includeNotified) {
|
||||
if (!$includeNotified) {
|
||||
$qb->whereRaw("(LOWER(TRIM(COALESCE(is_notified, ''))) NOT IN ('yes','1'))");
|
||||
}
|
||||
}
|
||||
@@ -703,11 +700,11 @@ class AttendanceTrackingService
|
||||
'semester' => $semester,
|
||||
];
|
||||
|
||||
if ($data['violation_date'] === '' && ! empty($data['attendance'][0]['date'])) {
|
||||
if ($data['violation_date'] === '' && !empty($data['attendance'][0]['date'])) {
|
||||
$data['violation_date'] = substr((string) $data['attendance'][0]['date'], 0, 10);
|
||||
}
|
||||
|
||||
if (! empty($data['attendance'][0]['is_notified'])) {
|
||||
if (!empty($data['attendance'][0]['is_notified'])) {
|
||||
$data['violation_notified'] = $data['attendance'][0]['is_notified'];
|
||||
}
|
||||
|
||||
@@ -785,17 +782,15 @@ class AttendanceTrackingService
|
||||
$to = trim((string) ($v['parent_email'] ?? ''));
|
||||
$pname = (string) ($v['parent_name'] ?? '');
|
||||
|
||||
if ($sid <= 0 || ! $code || ! $date || ! $to) {
|
||||
if ($sid <= 0 || !$code || !$date || !$to) {
|
||||
$errors++;
|
||||
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'missing data'];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->notificationAlreadySent($sid, $code, $date, 'email', $to)) {
|
||||
$skipped++;
|
||||
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'duplicate'];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -816,7 +811,7 @@ class AttendanceTrackingService
|
||||
|
||||
$tpl = $this->renderTemplate($code, $variant, $context);
|
||||
|
||||
if (! $tpl) {
|
||||
if (!$tpl) {
|
||||
$subject = match ($code) {
|
||||
'ABS_1' => 'Attendance Notice: Unreported Absence',
|
||||
'LATE_2' => 'Attendance Notice: Repeated Lateness',
|
||||
@@ -824,14 +819,14 @@ class AttendanceTrackingService
|
||||
};
|
||||
|
||||
$studentName = (string) ($v['name'] ?? '');
|
||||
$body = '<p>Dear '.($pname ?: 'Parent/Guardian').'</p>'
|
||||
."<p>We'd like to inform you about your student's recent attendance:</p>"
|
||||
.'<ul>'
|
||||
."<li><strong>Student:</strong> {$studentName}</li>"
|
||||
.'<li><strong>Issue:</strong> '.(string) ($v['violation'] ?? '').'</li>'
|
||||
."<li><strong>As of:</strong> {$date}</li>"
|
||||
.'</ul>'
|
||||
.'<p>If you have any questions, please contact the school office.</p>';
|
||||
$body = "<p>Dear " . ($pname ?: 'Parent/Guardian') . "</p>"
|
||||
. "<p>We'd like to inform you about your student's recent attendance:</p>"
|
||||
. "<ul>"
|
||||
. "<li><strong>Student:</strong> {$studentName}</li>"
|
||||
. "<li><strong>Issue:</strong> " . (string) ($v['violation'] ?? '') . "</li>"
|
||||
. "<li><strong>As of:</strong> {$date}</li>"
|
||||
. "</ul>"
|
||||
. "<p>If you have any questions, please contact the school office.</p>";
|
||||
} else {
|
||||
[$subject, $body] = $tpl;
|
||||
}
|
||||
@@ -854,7 +849,7 @@ class AttendanceTrackingService
|
||||
} catch (Throwable $e) {
|
||||
$errors++;
|
||||
$this->logNotification($sid, $code, $date, 'email', $to, $subject, 'failed', $e->getMessage());
|
||||
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'error: '.$e->getMessage()];
|
||||
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'error: ' . $e->getMessage()];
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -880,7 +875,7 @@ class AttendanceTrackingService
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
$errors++;
|
||||
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'cc_error: '.$e->getMessage()];
|
||||
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'cc_error: ' . $e->getMessage()];
|
||||
}
|
||||
|
||||
if ($anyOk) {
|
||||
@@ -900,10 +895,10 @@ class AttendanceTrackingService
|
||||
$absDates = array_map(fn ($d) => substr((string) $d, 0, 10), (array) ($v['absences'] ?? []));
|
||||
$lateDates = array_map(fn ($d) => substr((string) $d, 0, 10), (array) ($v['lates'] ?? []));
|
||||
|
||||
if (! empty($absDates)) {
|
||||
if (!empty($absDates)) {
|
||||
$allDates = array_merge($allDates, $absDates);
|
||||
}
|
||||
if (! empty($lateDates)) {
|
||||
if (!empty($lateDates)) {
|
||||
$allDates = array_merge($allDates, $lateDates);
|
||||
}
|
||||
if (empty($allDates)) {
|
||||
@@ -1039,7 +1034,7 @@ class AttendanceTrackingService
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$sid = (int) ($row->student_id ?? 0);
|
||||
if ($sid > 0 && ! isset($classByStudent[$sid])) {
|
||||
if ($sid > 0 && !isset($classByStudent[$sid])) {
|
||||
$classByStudent[$sid] = [
|
||||
'class_section_id' => $row->class_section_id ?? null,
|
||||
'class_section_name' => (string) ($row->class_section_name ?? ''),
|
||||
@@ -1054,7 +1049,7 @@ class AttendanceTrackingService
|
||||
$mergedData = [];
|
||||
foreach ($trackingData as $row) {
|
||||
$sid = (int) ($row['student_id'] ?? 0);
|
||||
if (! isset($studentMap[$sid])) {
|
||||
if (!isset($studentMap[$sid])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1062,7 +1057,7 @@ class AttendanceTrackingService
|
||||
if (isset($classByStudent[$sid])) {
|
||||
$merged['class_section_name'] = (string) ($classByStudent[$sid]['class_section_name'] ?? '');
|
||||
$merged['class_name'] = (string) ($classByStudent[$sid]['class_name'] ?? '');
|
||||
} elseif (! empty($merged['registration_grade'])) {
|
||||
} elseif (!empty($merged['registration_grade'])) {
|
||||
$merged['grade'] = (string) $merged['registration_grade'];
|
||||
}
|
||||
|
||||
@@ -1106,7 +1101,7 @@ class AttendanceTrackingService
|
||||
|
||||
$violation = [
|
||||
'id' => $studentId,
|
||||
'name' => trim(($student['firstname'] ?? '').' '.($student['lastname'] ?? '')),
|
||||
'name' => trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? '')),
|
||||
'last_date' => $lastDate,
|
||||
'violation' => $code,
|
||||
'violation_code' => $code,
|
||||
@@ -1115,7 +1110,7 @@ class AttendanceTrackingService
|
||||
$ctx = $this->buildTemplateContext($violation, $parent);
|
||||
$rendered = $this->renderTemplate($code, $variant, $ctx);
|
||||
|
||||
if (! $rendered) {
|
||||
if (!$rendered) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => "Template not found for {$code} ({$variant}).",
|
||||
@@ -1193,7 +1188,7 @@ class AttendanceTrackingService
|
||||
$sec = $this->getSecondaryParentForStudent($sid);
|
||||
$to2 = trim((string) ($sec['email'] ?? ''));
|
||||
if ($to2 !== '' && strcasecmp($to2, $to) !== 0) {
|
||||
if (! $this->notificationAlreadySent($sid, $code, $ymd, 'email', $to2)) {
|
||||
if (!$this->notificationAlreadySent($sid, $code, $ymd, 'email', $to2)) {
|
||||
$ok2 = $this->attendanceMailerService->send($to2, $subject, $wrapped);
|
||||
$this->logNotification(
|
||||
$sid,
|
||||
@@ -1211,7 +1206,7 @@ class AttendanceTrackingService
|
||||
}
|
||||
}
|
||||
|
||||
if (! $anyOk) {
|
||||
if (!$anyOk) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Failed to send email.',
|
||||
@@ -1256,7 +1251,7 @@ class AttendanceTrackingService
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Error: '.$e->getMessage(),
|
||||
'message' => 'Error: ' . $e->getMessage(),
|
||||
'status' => 500,
|
||||
];
|
||||
}
|
||||
@@ -1278,7 +1273,7 @@ class AttendanceTrackingService
|
||||
->where('id', $studentId)
|
||||
->first();
|
||||
|
||||
if (! $stu) {
|
||||
if (!$stu) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Student not found',
|
||||
@@ -1303,7 +1298,7 @@ class AttendanceTrackingService
|
||||
] : null;
|
||||
|
||||
$pb = DB::table('parents')->where('firstparent_id', $primaryId);
|
||||
if (! empty($schoolYear)) {
|
||||
if (!empty($schoolYear)) {
|
||||
$pb->where('school_year', $schoolYear);
|
||||
}
|
||||
|
||||
@@ -1330,7 +1325,7 @@ class AttendanceTrackingService
|
||||
}
|
||||
}
|
||||
|
||||
if (! $secondary) {
|
||||
if (!$secondary) {
|
||||
$fallbackEmail = (string) ($pRow->secondparent_email ?? '');
|
||||
$fallbackPhone = (string) ($pRow->secondparent_phone ?? '');
|
||||
$fallbackFirst = (string) ($pRow->secondparent_firstname ?? '');
|
||||
@@ -1356,7 +1351,7 @@ class AttendanceTrackingService
|
||||
],
|
||||
];
|
||||
} catch (Throwable $e) {
|
||||
Log::error('parentsInfo() failed: '.$e->getMessage());
|
||||
Log::error('parentsInfo() failed: ' . $e->getMessage());
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
@@ -1384,11 +1379,11 @@ class AttendanceTrackingService
|
||||
->where('school_year', $this->schoolYear)
|
||||
->where('date', '>=', $start)
|
||||
->where('date', '<', $end)
|
||||
->where('reason', 'like', '%'.$code.'%')
|
||||
->where('reason', 'like', '%' . $code . '%')
|
||||
->orderByDesc('date')
|
||||
->first();
|
||||
|
||||
if (! $row) {
|
||||
if (!$row) {
|
||||
$row = $this->attendanceTrackingModel->query()
|
||||
->where('student_id', $sid)
|
||||
->where('semester', $this->semester)
|
||||
@@ -1399,7 +1394,7 @@ class AttendanceTrackingService
|
||||
->first();
|
||||
}
|
||||
|
||||
if ($row && ! empty($row->id)) {
|
||||
if ($row && !empty($row->id)) {
|
||||
DB::table($this->attendanceTrackingModel->getTable())
|
||||
->where('id', (int) $row->id)
|
||||
->update([
|
||||
@@ -1431,7 +1426,7 @@ class AttendanceTrackingService
|
||||
} catch (Throwable $e) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Failed to save note: '.$e->getMessage(),
|
||||
'message' => 'Failed to save note: ' . $e->getMessage(),
|
||||
'status' => 500,
|
||||
];
|
||||
}
|
||||
@@ -1455,14 +1450,13 @@ class AttendanceTrackingService
|
||||
->where('incident_date', $ymd)
|
||||
->where('channel', $channel);
|
||||
|
||||
if (! empty($to)) {
|
||||
if (!empty($to)) {
|
||||
$query->where('to_address', $to);
|
||||
}
|
||||
|
||||
return $query->exists();
|
||||
} catch (Throwable $e) {
|
||||
Log::debug('notificationAlreadySent(): '.$e->getMessage());
|
||||
|
||||
Log::debug('notificationAlreadySent(): ' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1485,7 +1479,7 @@ class AttendanceTrackingService
|
||||
'channel' => $channel,
|
||||
];
|
||||
|
||||
if (! empty($to)) {
|
||||
if (!empty($to)) {
|
||||
$where['to_address'] = $to;
|
||||
}
|
||||
|
||||
@@ -1494,7 +1488,7 @@ class AttendanceTrackingService
|
||||
->orderByDesc('id')
|
||||
->first();
|
||||
|
||||
if ($existing && ! empty($existing->id)) {
|
||||
if ($existing && !empty($existing->id)) {
|
||||
$existing->update([
|
||||
'subject' => $subject,
|
||||
'status' => $status,
|
||||
@@ -1518,7 +1512,7 @@ class AttendanceTrackingService
|
||||
]);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
Log::debug('logNotification(): '.$e->getMessage());
|
||||
Log::debug('logNotification(): ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1530,7 +1524,7 @@ class AttendanceTrackingService
|
||||
->where('s.id', $studentId)
|
||||
->first();
|
||||
|
||||
if (! $row || empty($row->user_id)) {
|
||||
if (!$row || empty($row->user_id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1550,7 +1544,7 @@ class AttendanceTrackingService
|
||||
->where('id', $studentId)
|
||||
->first();
|
||||
|
||||
if (! $stu) {
|
||||
if (!$stu) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1563,7 +1557,7 @@ class AttendanceTrackingService
|
||||
}
|
||||
|
||||
$pRow = $pb->orderByDesc('updated_at')->first();
|
||||
if (! $pRow) {
|
||||
if (!$pRow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1574,11 +1568,11 @@ class AttendanceTrackingService
|
||||
->where('id', $secondId)
|
||||
->first();
|
||||
|
||||
if ($u2 && ! empty($u2->email)) {
|
||||
if ($u2 && !empty($u2->email)) {
|
||||
return [
|
||||
'user_id' => (int) $u2->id,
|
||||
'email' => (string) $u2->email,
|
||||
'parent_name' => trim(($u2->firstname ?? '').' '.($u2->lastname ?? '')),
|
||||
'parent_name' => trim(($u2->firstname ?? '') . ' ' . ($u2->lastname ?? '')),
|
||||
'phone' => (string) ($u2->cellphone ?? ''),
|
||||
];
|
||||
}
|
||||
@@ -1593,12 +1587,12 @@ class AttendanceTrackingService
|
||||
return [
|
||||
'user_id' => $secondId ?: null,
|
||||
'email' => $fallbackEmail,
|
||||
'parent_name' => trim($fallbackFirst.' '.$fallbackLast) ?: null,
|
||||
'parent_name' => trim($fallbackFirst . ' ' . $fallbackLast) ?: null,
|
||||
'phone' => $fallbackPhone,
|
||||
];
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
Log::error('getSecondaryParentForStudent() failed: '.$e->getMessage());
|
||||
Log::error('getSecondaryParentForStudent() failed: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -1637,7 +1631,7 @@ class AttendanceTrackingService
|
||||
$ymd = substr((string) ($r['date'] ?? ''), 0, 10);
|
||||
$stat = strtolower(trim((string) ($r['status'] ?? '')));
|
||||
|
||||
if (! in_array($stat, ['absent', 'late'], true)) {
|
||||
if (!in_array($stat, ['absent', 'late'], true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1649,10 +1643,10 @@ class AttendanceTrackingService
|
||||
[$syStart, $syEnd] = $this->deriveSchoolYearBounds($schoolYear);
|
||||
$weekRowsSource = null;
|
||||
|
||||
if (! empty($weekRowsFallback)) {
|
||||
if (!empty($weekRowsFallback)) {
|
||||
foreach ($weekRowsFallback as $r) {
|
||||
$st = strtolower(trim((string) ($r['status'] ?? '')));
|
||||
if ($st !== '' && ! in_array($st, ['absent', 'late'], true)) {
|
||||
if ($st !== '' && !in_array($st, ['absent', 'late'], true)) {
|
||||
$weekRowsSource = $weekRowsFallback;
|
||||
break;
|
||||
}
|
||||
@@ -1685,7 +1679,6 @@ class AttendanceTrackingService
|
||||
}
|
||||
$out = array_values(array_unique($out));
|
||||
rsort($out);
|
||||
|
||||
return $out;
|
||||
};
|
||||
|
||||
@@ -1696,7 +1689,7 @@ class AttendanceTrackingService
|
||||
$students
|
||||
)));
|
||||
|
||||
if (! empty($studentIdsForClass)) {
|
||||
if (!empty($studentIdsForClass)) {
|
||||
$rows = DB::table('student_class as sc')
|
||||
->select([
|
||||
'sc.student_id',
|
||||
@@ -1714,7 +1707,7 @@ class AttendanceTrackingService
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$sid = (int) ($row->student_id ?? 0);
|
||||
if ($sid > 0 && ! isset($classByStudent[$sid])) {
|
||||
if ($sid > 0 && !isset($classByStudent[$sid])) {
|
||||
$classByStudent[$sid] = [
|
||||
'class_section_id' => $row->class_section_id ?? null,
|
||||
'class_section_name' => (string) ($row->class_section_name ?? ''),
|
||||
@@ -1725,7 +1718,7 @@ class AttendanceTrackingService
|
||||
}
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
Log::debug('computeViolations(): class prefetch failed: '.$e->getMessage());
|
||||
Log::debug('computeViolations(): class prefetch failed: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
$out = [];
|
||||
@@ -1734,7 +1727,7 @@ class AttendanceTrackingService
|
||||
|
||||
foreach ($students as $stu) {
|
||||
$sid = (int) ($stu['id'] ?? 0);
|
||||
$name = trim(($stu['firstname'] ?? '').' '.($stu['lastname'] ?? ''));
|
||||
$name = trim(($stu['firstname'] ?? '') . ' ' . ($stu['lastname'] ?? ''));
|
||||
|
||||
$absDatesAll = array_values(array_unique($byStudent[$sid]['absent'] ?? []));
|
||||
$lateDatesAll = array_values(array_unique($byStudent[$sid]['late'] ?? []));
|
||||
@@ -1752,7 +1745,7 @@ class AttendanceTrackingService
|
||||
$lateCountLast5 += count($lateDates);
|
||||
|
||||
$absenceViolation = null;
|
||||
if (! empty($absDates)) {
|
||||
if (!empty($absDates)) {
|
||||
$lastAbsDate = $absDates[0];
|
||||
$A2row = $this->hasNConsecutiveItems($absDates, 2, 7);
|
||||
$A3row = $this->hasNConsecutiveItems($absDates, 3, 7);
|
||||
@@ -1799,7 +1792,7 @@ class AttendanceTrackingService
|
||||
}
|
||||
|
||||
$lateViolation = null;
|
||||
if (! empty($lateDates)) {
|
||||
if (!empty($lateDates)) {
|
||||
$lastLateDate = $lateDates[0];
|
||||
|
||||
$L2row = $this->hasNConsecutiveItems($lateDates, 2, 7);
|
||||
@@ -1814,7 +1807,7 @@ class AttendanceTrackingService
|
||||
$lateWeeksSet = array_flip($lateWeekIdx);
|
||||
$lateCoversAllWindowWeeks = true;
|
||||
for ($i = $windowStartIdx; $i <= $currentWeekIdx; $i++) {
|
||||
if (! isset($lateWeeksSet[$i])) {
|
||||
if (!isset($lateWeeksSet[$i])) {
|
||||
$lateCoversAllWindowWeeks = false;
|
||||
break;
|
||||
}
|
||||
@@ -1865,7 +1858,7 @@ class AttendanceTrackingService
|
||||
|
||||
$chosen = $this->chooseHigherSeverity($absenceViolation, $lateViolation);
|
||||
|
||||
if (! $chosen && count($absDates) === 1) {
|
||||
if (!$chosen && count($absDates) === 1) {
|
||||
$chosen = [
|
||||
'type' => 'absence',
|
||||
'code' => 'ABS_1',
|
||||
@@ -1878,7 +1871,7 @@ class AttendanceTrackingService
|
||||
];
|
||||
}
|
||||
|
||||
if (! $chosen) {
|
||||
if (!$chosen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1890,7 +1883,7 @@ class AttendanceTrackingService
|
||||
->where('school_year', $schoolYear)
|
||||
->where('date', '>=', $start)
|
||||
->where('date', '<', $end)
|
||||
->where('reason', 'like', '%'.$chosen['code'].'%');
|
||||
->where('reason', 'like', '%' . $chosen['code'] . '%');
|
||||
|
||||
if ($semester !== null) {
|
||||
$trackingQ->where('semester', $semester);
|
||||
@@ -1904,7 +1897,7 @@ class AttendanceTrackingService
|
||||
|
||||
$cls = $classByStudent[$sid] ?? [];
|
||||
$classLabel = (string) ($cls['class_section_name'] ?? '');
|
||||
if ($classLabel === '' && ! empty($cls['class_name'])) {
|
||||
if ($classLabel === '' && !empty($cls['class_name'])) {
|
||||
$classLabel = (string) $cls['class_name'];
|
||||
}
|
||||
|
||||
@@ -1954,7 +1947,6 @@ class AttendanceTrackingService
|
||||
if ($a && $b) {
|
||||
if ($a['severity'] === $b['severity']) {
|
||||
$prio = ['expel_notify' => 3, 'team_notify' => 2, 'auto_email' => 1];
|
||||
|
||||
return ($prio[$a['action']] ?? 0) >= ($prio[$b['action']] ?? 0) ? $a : $b;
|
||||
}
|
||||
|
||||
@@ -1984,11 +1976,11 @@ class AttendanceTrackingService
|
||||
{
|
||||
$cols = $this->attendanceReportedColumns();
|
||||
|
||||
if (! empty($cols['is_reported'])) {
|
||||
if (!empty($cols['is_reported'])) {
|
||||
$qb->whereRaw("(LOWER(TRIM(COALESCE(is_reported, ''))) NOT IN ('yes','1','true','y','on'))");
|
||||
}
|
||||
|
||||
if (! empty($cols['reported'])) {
|
||||
if (!empty($cols['reported'])) {
|
||||
$qb->whereRaw("(LOWER(TRIM(COALESCE(reported, ''))) NOT IN ('yes','1','true','y','on'))");
|
||||
}
|
||||
|
||||
@@ -2010,10 +2002,9 @@ class AttendanceTrackingService
|
||||
protected function dayBounds(string $ymd): array
|
||||
{
|
||||
$d = substr($ymd, 0, 10);
|
||||
|
||||
return [
|
||||
$d.' 00:00:00',
|
||||
date('Y-m-d', strtotime($d.' +1 day')).' 00:00:00',
|
||||
$d . ' 00:00:00',
|
||||
date('Y-m-d', strtotime($d . ' +1 day')) . ' 00:00:00',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -2033,10 +2024,9 @@ class AttendanceTrackingService
|
||||
|
||||
protected function deriveSchoolYearBounds(string $schoolYear): array
|
||||
{
|
||||
if (! preg_match('/^(\d{4})-(\d{4})$/', $schoolYear, $m)) {
|
||||
if (!preg_match('/^(\d{4})-(\d{4})$/', $schoolYear, $m)) {
|
||||
$y = (int) date('Y');
|
||||
$startY = (int) (date('n') >= 8 ? $y : $y - 1);
|
||||
|
||||
return [sprintf('%d-08-01', $startY), sprintf('%d-07-31', $startY + 1)];
|
||||
}
|
||||
|
||||
@@ -2076,7 +2066,7 @@ class AttendanceTrackingService
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
|
||||
if (! $row) {
|
||||
if (!$row) {
|
||||
$row = $this->attendanceEmailTemplateModel->query()
|
||||
->where('code', $code)
|
||||
->where('variant', 'default')
|
||||
@@ -2087,7 +2077,7 @@ class AttendanceTrackingService
|
||||
$row = $row?->toArray();
|
||||
}
|
||||
|
||||
if (! $row) {
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2145,10 +2135,10 @@ class AttendanceTrackingService
|
||||
$semester = ($semester !== null && $semester !== '') ? (string) $semester : null;
|
||||
$weeks = [];
|
||||
|
||||
if (! empty($weekRowsFallback)) {
|
||||
if (!empty($weekRowsFallback)) {
|
||||
foreach ($weekRowsFallback as $r) {
|
||||
$d = $r['date'] ?? null;
|
||||
if (! $d) {
|
||||
if (!$d) {
|
||||
continue;
|
||||
}
|
||||
$ts = strtotime($d);
|
||||
@@ -2205,38 +2195,25 @@ class AttendanceTrackingService
|
||||
}
|
||||
$idx = array_keys($set);
|
||||
sort($idx);
|
||||
|
||||
return $idx;
|
||||
}
|
||||
|
||||
protected function windowWeeksForViolationCode(string $code): int
|
||||
{
|
||||
$code = strtoupper(trim($code));
|
||||
if ($code === '') {
|
||||
return 5;
|
||||
}
|
||||
if (Str::startsWith($code, 'ABS_2') || Str::startsWith($code, 'LATE_2')) {
|
||||
return 3;
|
||||
}
|
||||
if (Str::startsWith($code, 'ABS_3') || Str::startsWith($code, 'LATE_3') || Str::startsWith($code, 'MIX')) {
|
||||
return 4;
|
||||
}
|
||||
if (Str::startsWith($code, 'LATE_4')) {
|
||||
return 4;
|
||||
}
|
||||
if (Str::startsWith($code, 'ABS_4')) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
if ($code === '') return 5;
|
||||
if (Str::startsWith($code, 'ABS_2') || Str::startsWith($code, 'LATE_2')) return 3;
|
||||
if (Str::startsWith($code, 'ABS_3') || Str::startsWith($code, 'LATE_3') || Str::startsWith($code, 'MIX')) return 4;
|
||||
if (Str::startsWith($code, 'LATE_4')) return 4;
|
||||
if (Str::startsWith($code, 'ABS_4')) return 5;
|
||||
return 5;
|
||||
}
|
||||
|
||||
protected function isoWeekStartYmd(string $weekKey): string
|
||||
{
|
||||
if (preg_match('/^(\d{4})-W(\d{2})$/', $weekKey, $m)) {
|
||||
return date('Y-m-d', strtotime($m[1].'-W'.$m[2].'-1'));
|
||||
return date('Y-m-d', strtotime($m[1] . '-W' . $m[2] . '-1'));
|
||||
}
|
||||
|
||||
return date('Y-m-d');
|
||||
}
|
||||
|
||||
@@ -2257,15 +2234,14 @@ class AttendanceTrackingService
|
||||
|
||||
if (empty($activeWeekKeys)) {
|
||||
$days = ($windowWeeks * 7) - 1;
|
||||
|
||||
return date('Y-m-d', strtotime($endBound.' -'.$days.' days'));
|
||||
return date('Y-m-d', strtotime($endBound . ' -' . $days . ' days'));
|
||||
}
|
||||
|
||||
$activeWeekKeys = array_values($activeWeekKeys);
|
||||
$weekIndex = array_flip($activeWeekKeys);
|
||||
$endWeekKey = date('o-\WW', strtotime($endBound));
|
||||
|
||||
if (! isset($weekIndex[$endWeekKey])) {
|
||||
if (!isset($weekIndex[$endWeekKey])) {
|
||||
$endWeekKey = null;
|
||||
for ($i = count($activeWeekKeys) - 1; $i >= 0; $i--) {
|
||||
$wkStart = $this->isoWeekStartYmd($activeWeekKeys[$i]);
|
||||
@@ -2289,9 +2265,7 @@ class AttendanceTrackingService
|
||||
protected function hasNConsecutiveItems(array $datesDesc, int $n, int $daysApart): bool
|
||||
{
|
||||
$N = count($datesDesc);
|
||||
if ($N < $n) {
|
||||
return false;
|
||||
}
|
||||
if ($N < $n) return false;
|
||||
|
||||
$dates = $datesDesc;
|
||||
sort($dates);
|
||||
@@ -2304,9 +2278,7 @@ class AttendanceTrackingService
|
||||
|
||||
if ($diff === $daysApart) {
|
||||
$run++;
|
||||
if ($run >= $n) {
|
||||
return true;
|
||||
}
|
||||
if ($run >= $n) return true;
|
||||
} else {
|
||||
$run = 1;
|
||||
}
|
||||
@@ -2318,9 +2290,7 @@ class AttendanceTrackingService
|
||||
protected function hasNInWActiveWeeks(array $weekIdx, int $n, int $w): bool
|
||||
{
|
||||
$N = count($weekIdx);
|
||||
if ($N < $n) {
|
||||
return false;
|
||||
}
|
||||
if ($N < $n) return false;
|
||||
|
||||
$l = 0;
|
||||
for ($r = 0; $r < $N; $r++) {
|
||||
@@ -2337,9 +2307,7 @@ class AttendanceTrackingService
|
||||
|
||||
protected function twoLatesOneAbsInWWeeks(array $lateIdx, array $absIdx, int $w): bool
|
||||
{
|
||||
if (count($lateIdx) < 2 || count($absIdx) < 1) {
|
||||
return false;
|
||||
}
|
||||
if (count($lateIdx) < 2 || count($absIdx) < 1) return false;
|
||||
|
||||
$L = $lateIdx;
|
||||
$A = $absIdx;
|
||||
@@ -2354,7 +2322,6 @@ class AttendanceTrackingService
|
||||
if ($L[$iL2] > $windowEnd) {
|
||||
$iL1++;
|
||||
$iL2 = $iL1 + 1;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2375,4 +2342,4 @@ class AttendanceTrackingService
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ class SemesterRangeServiceTest extends TestCase
|
||||
{
|
||||
public function test_normalize_semester(): void
|
||||
{
|
||||
$service = new SemesterRangeService;
|
||||
$service = new SemesterRangeService();
|
||||
|
||||
$this->assertSame('Fall', $service->normalizeSemester('fall'));
|
||||
$this->assertSame('Spring', $service->normalizeSemester('SPRING'));
|
||||
@@ -18,7 +18,7 @@ class SemesterRangeServiceTest extends TestCase
|
||||
|
||||
public function test_get_school_year_range(): void
|
||||
{
|
||||
$service = new SemesterRangeService;
|
||||
$service = new SemesterRangeService();
|
||||
|
||||
[$start, $end] = $service->getSchoolYearRange('2025-2026');
|
||||
|
||||
@@ -28,7 +28,7 @@ class SemesterRangeServiceTest extends TestCase
|
||||
|
||||
public function test_build_sunday_list(): void
|
||||
{
|
||||
$service = new SemesterRangeService;
|
||||
$service = new SemesterRangeService();
|
||||
|
||||
$sundays = $service->buildSundayList('2025-09-01', '2025-09-30');
|
||||
|
||||
@@ -37,4 +37,4 @@ class SemesterRangeServiceTest extends TestCase
|
||||
$this->assertContains('2025-09-21', $sundays);
|
||||
$this->assertContains('2025-09-28', $sundays);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
namespace Tests\Unit\Services\Attendance;
|
||||
|
||||
use App\Models\ClassSection;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\StaffAttendance;
|
||||
use App\Models\TeacherClass;
|
||||
use App\Services\Attendance\SemesterRangeService;
|
||||
use App\Services\Attendance\StaffAttendanceService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -80,11 +75,11 @@ class StaffAttendanceServiceTest extends TestCase
|
||||
]);
|
||||
|
||||
$service = new StaffAttendanceService(
|
||||
new Configuration,
|
||||
new StaffAttendance,
|
||||
new TeacherClass,
|
||||
new ClassSection,
|
||||
new SemesterRangeService
|
||||
new \App\Models\Configuration(),
|
||||
new \App\Models\StaffAttendance(),
|
||||
new \App\Models\TeacherClass(),
|
||||
new \App\Models\ClassSection(),
|
||||
new \App\Services\Attendance\SemesterRangeService()
|
||||
);
|
||||
|
||||
$payload = $service->monthData('Fall', '2025-2026');
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
namespace Tests\Unit\Services\Attendance;
|
||||
|
||||
use App\Models\AttendanceData;
|
||||
use App\Models\Student;
|
||||
use App\Services\Attendance\AttendanceRecordSyncService;
|
||||
use App\Services\Attendance\StudentAttendanceWriterService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
@@ -31,7 +29,7 @@ class StudentAttendanceWriterServiceTest extends TestCase
|
||||
]);
|
||||
|
||||
$sync = Mockery::mock(AttendanceRecordSyncService::class);
|
||||
$service = new StudentAttendanceWriterService(new AttendanceData, new Student, $sync);
|
||||
$service = new StudentAttendanceWriterService(new \App\Models\AttendanceData(), new \App\Models\Student(), $sync);
|
||||
|
||||
$this->assertSame('S1', $service->resolveStudentSchoolId(1, null));
|
||||
}
|
||||
@@ -67,7 +65,7 @@ class StudentAttendanceWriterServiceTest extends TestCase
|
||||
$sync = Mockery::mock(AttendanceRecordSyncService::class);
|
||||
$sync->shouldReceive('updateAttendanceRecord')->once();
|
||||
|
||||
$service = new StudentAttendanceWriterService(new AttendanceData, new Student, $sync);
|
||||
$service = new StudentAttendanceWriterService(new \App\Models\AttendanceData(), new \App\Models\Student(), $sync);
|
||||
|
||||
$service->saveOrUpdateStudentAttendance([
|
||||
'class_section_id' => 1,
|
||||
|
||||
@@ -2,16 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\Attendance;
|
||||
|
||||
use App\Models\AttendanceData;
|
||||
use App\Models\AttendanceDay;
|
||||
use App\Models\AttendanceRecord;
|
||||
use App\Models\Student;
|
||||
use App\Models\TeacherClass;
|
||||
use App\Models\User;
|
||||
use App\Services\Attendance\AttendanceAutoPublishService;
|
||||
use App\Services\Attendance\AttendancePolicyService;
|
||||
use App\Services\Attendance\AttendanceRecordSyncService;
|
||||
use App\Services\Attendance\StudentAttendanceWriterService;
|
||||
use App\Services\Attendance\TeacherAttendanceSubmissionService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -35,21 +26,21 @@ class TeacherAttendanceSubmissionServiceTest extends TestCase
|
||||
|
||||
$user = $this->seedUser();
|
||||
|
||||
$policy = Mockery::mock(AttendancePolicyService::class);
|
||||
$policy = Mockery::mock(\App\Services\Attendance\AttendancePolicyService::class);
|
||||
$policy->shouldReceive('canEditDay')->andReturn(true);
|
||||
|
||||
$service = new TeacherAttendanceSubmissionService(
|
||||
new AttendanceDay,
|
||||
new AttendanceData,
|
||||
new TeacherClass,
|
||||
new Student,
|
||||
new \App\Models\AttendanceDay(),
|
||||
new \App\Models\AttendanceData(),
|
||||
new \App\Models\TeacherClass(),
|
||||
new \App\Models\Student(),
|
||||
$policy,
|
||||
new StudentAttendanceWriterService(
|
||||
new AttendanceData,
|
||||
new Student,
|
||||
new AttendanceRecordSyncService(new AttendanceRecord)
|
||||
new \App\Services\Attendance\StudentAttendanceWriterService(
|
||||
new \App\Models\AttendanceData(),
|
||||
new \App\Models\Student(),
|
||||
new \App\Services\Attendance\AttendanceRecordSyncService(new \App\Models\AttendanceRecord())
|
||||
),
|
||||
new AttendanceAutoPublishService
|
||||
new \App\Services\Attendance\AttendanceAutoPublishService()
|
||||
);
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
@@ -16,7 +16,7 @@ class AttendanceManagementServiceTest extends TestCase
|
||||
$this->seedConfiguration();
|
||||
$this->seedUserWithBadge('RFID-100');
|
||||
|
||||
$service = new AttendanceManagementService;
|
||||
$service = new AttendanceManagementService();
|
||||
|
||||
$row = $service->badgeScan([
|
||||
'badge_scan' => 'RFID-100',
|
||||
@@ -46,7 +46,7 @@ class AttendanceManagementServiceTest extends TestCase
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$service = new AttendanceManagementService;
|
||||
$service = new AttendanceManagementService();
|
||||
|
||||
$data = $service->dashboard([
|
||||
'date' => '2026-02-10',
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\AttendanceTracking;
|
||||
|
||||
use App\Models\AttendanceData;
|
||||
use App\Models\AttendanceTracking;
|
||||
use App\Models\Student;
|
||||
use App\Services\AttendanceTracking\AttendanceCaseQueryService;
|
||||
use App\Services\AttendanceTracking\AttendanceParentLookupService;
|
||||
use App\Services\AttendanceTracking\ViolationRuleEngineService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
@@ -19,11 +14,11 @@ class AttendanceCaseQueryServiceTest extends TestCase
|
||||
public function test_returns_not_found_when_student_missing(): void
|
||||
{
|
||||
$service = new AttendanceCaseQueryService(
|
||||
new Student,
|
||||
new AttendanceData,
|
||||
new AttendanceTracking,
|
||||
Mockery::mock(ViolationRuleEngineService::class),
|
||||
Mockery::mock(AttendanceParentLookupService::class)
|
||||
new \App\Models\Student(),
|
||||
new \App\Models\AttendanceData(),
|
||||
new \App\Models\AttendanceTracking(),
|
||||
Mockery::mock(\App\Services\AttendanceTracking\ViolationRuleEngineService::class),
|
||||
Mockery::mock(\App\Services\AttendanceTracking\AttendanceParentLookupService::class)
|
||||
);
|
||||
|
||||
$result = $service->getStudentCase(999);
|
||||
|
||||
+5
-10
@@ -2,12 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\AttendanceTracking;
|
||||
|
||||
use App\Models\AttendanceData;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\Student;
|
||||
use App\Services\AttendanceTracking\AttendanceCommunicationSupportService;
|
||||
use App\Services\AttendanceTracking\AttendanceEmailComposerService;
|
||||
use App\Services\AttendanceTracking\AttendanceParentLookupService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Mockery;
|
||||
@@ -54,13 +49,13 @@ class AttendanceCommunicationSupportServiceTest extends TestCase
|
||||
|
||||
private function makeService(): AttendanceCommunicationSupportService
|
||||
{
|
||||
$parentLookup = Mockery::mock(AttendanceParentLookupService::class);
|
||||
$emailComposer = Mockery::mock(AttendanceEmailComposerService::class);
|
||||
$parentLookup = Mockery::mock(\App\Services\AttendanceTracking\AttendanceParentLookupService::class);
|
||||
$emailComposer = Mockery::mock(\App\Services\AttendanceTracking\AttendanceEmailComposerService::class);
|
||||
|
||||
return new AttendanceCommunicationSupportService(
|
||||
new Student,
|
||||
new AttendanceData,
|
||||
new Configuration,
|
||||
new \App\Models\Student(),
|
||||
new \App\Models\AttendanceData(),
|
||||
new \App\Models\Configuration(),
|
||||
$parentLookup,
|
||||
$emailComposer
|
||||
);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Tests\Unit\Services\AttendanceTracking;
|
||||
|
||||
use App\Models\AttendanceEmailTemplate;
|
||||
use App\Services\AttendanceTracking\AttendanceEmailComposerService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -22,7 +21,7 @@ class AttendanceEmailComposerServiceTest extends TestCase
|
||||
'is_active' => 1,
|
||||
]);
|
||||
|
||||
$service = new AttendanceEmailComposerService(new AttendanceEmailTemplate);
|
||||
$service = new AttendanceEmailComposerService(new \App\Models\AttendanceEmailTemplate());
|
||||
$context = ['{{student_name}}' => 'Student A', '{{parent_name}}' => 'Parent A'];
|
||||
$rendered = $service->renderTemplate('ABS_1', 'default', $context);
|
||||
|
||||
@@ -32,7 +31,7 @@ class AttendanceEmailComposerServiceTest extends TestCase
|
||||
|
||||
public function test_pick_variant_fallback(): void
|
||||
{
|
||||
$service = new AttendanceEmailComposerService(new AttendanceEmailTemplate);
|
||||
$service = new AttendanceEmailComposerService(new \App\Models\AttendanceEmailTemplate());
|
||||
$this->assertSame('no_answer', $service->pickVariant('ABS_2'));
|
||||
$this->assertSame('default', $service->pickVariant('ABS_1'));
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Tests\Unit\Services\AttendanceTracking;
|
||||
|
||||
use App\Models\ParentNotification;
|
||||
use App\Services\AttendanceTracking\AttendanceNotificationLogService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -14,7 +13,7 @@ class AttendanceNotificationLogServiceTest extends TestCase
|
||||
|
||||
public function test_log_notification_creates_and_updates(): void
|
||||
{
|
||||
$service = new AttendanceNotificationLogService(new ParentNotification);
|
||||
$service = new AttendanceNotificationLogService(new \App\Models\ParentNotification());
|
||||
|
||||
$service->logNotification(1, 'ABS_1', '2025-01-01', 'email', 'parent@example.com', 'Subject', 'sent');
|
||||
$this->assertDatabaseHas('parent_notifications', [
|
||||
|
||||
+10
-20
@@ -2,17 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\AttendanceTracking;
|
||||
|
||||
use App\Models\AttendanceData;
|
||||
use App\Models\AttendanceTracking;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\Student;
|
||||
use App\Models\StudentClass;
|
||||
use App\Services\AttendanceTracking\AttendanceEmailComposerService;
|
||||
use App\Services\AttendanceTracking\AttendanceMailerService;
|
||||
use App\Services\AttendanceTracking\AttendanceNotificationLogService;
|
||||
use App\Services\AttendanceTracking\AttendanceNotificationWorkflowService;
|
||||
use App\Services\AttendanceTracking\AttendanceParentLookupService;
|
||||
use App\Services\AttendanceTracking\ViolationRuleEngineService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Mockery;
|
||||
@@ -37,20 +27,20 @@ class AttendanceNotificationWorkflowServiceTest extends TestCase
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$parentLookup = Mockery::mock(AttendanceParentLookupService::class);
|
||||
$parentLookup = Mockery::mock(\App\Services\AttendanceTracking\AttendanceParentLookupService::class);
|
||||
$parentLookup->shouldReceive('getPrimaryParentForStudent')->once()->andReturn([]);
|
||||
|
||||
$service = new AttendanceNotificationWorkflowService(
|
||||
new Student,
|
||||
new StudentClass,
|
||||
new AttendanceData,
|
||||
new AttendanceTracking,
|
||||
new Configuration,
|
||||
Mockery::mock(AttendanceMailerService::class),
|
||||
Mockery::mock(ViolationRuleEngineService::class),
|
||||
new \App\Models\Student(),
|
||||
new \App\Models\StudentClass(),
|
||||
new \App\Models\AttendanceData(),
|
||||
new \App\Models\AttendanceTracking(),
|
||||
new \App\Models\Configuration(),
|
||||
Mockery::mock(\App\Services\AttendanceTracking\AttendanceMailerService::class),
|
||||
Mockery::mock(\App\Services\AttendanceTracking\ViolationRuleEngineService::class),
|
||||
$parentLookup,
|
||||
Mockery::mock(AttendanceEmailComposerService::class),
|
||||
Mockery::mock(AttendanceNotificationLogService::class)
|
||||
Mockery::mock(\App\Services\AttendanceTracking\AttendanceEmailComposerService::class),
|
||||
Mockery::mock(\App\Services\AttendanceTracking\AttendanceNotificationLogService::class)
|
||||
);
|
||||
|
||||
$result = $service->record([
|
||||
|
||||
@@ -47,7 +47,7 @@ class AttendanceParentLookupServiceTest extends TestCase
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$service = new AttendanceParentLookupService;
|
||||
$service = new AttendanceParentLookupService();
|
||||
$parent = $service->getPrimaryParentForStudent(1);
|
||||
|
||||
$this->assertSame('parent@example.com', $parent['email']);
|
||||
@@ -80,7 +80,7 @@ class AttendanceParentLookupServiceTest extends TestCase
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$service = new AttendanceParentLookupService;
|
||||
$service = new AttendanceParentLookupService();
|
||||
$parent = $service->getSecondaryParentForStudent(1, '2025-2026');
|
||||
|
||||
$this->assertSame('second@example.com', $parent['email']);
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\AttendanceTracking;
|
||||
|
||||
use App\Models\AttendanceData;
|
||||
use App\Services\AttendanceTracking\AttendancePendingViolationService;
|
||||
use App\Services\AttendanceTracking\AttendanceViolationStudentResolverService;
|
||||
use App\Services\AttendanceTracking\ViolationRuleEngineService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
use Tests\TestCase;
|
||||
@@ -16,7 +13,7 @@ class AttendancePendingViolationServiceTest extends TestCase
|
||||
|
||||
public function test_returns_error_when_no_students(): void
|
||||
{
|
||||
$resolver = Mockery::mock(AttendanceViolationStudentResolverService::class);
|
||||
$resolver = Mockery::mock(\App\Services\AttendanceTracking\AttendanceViolationStudentResolverService::class);
|
||||
$resolver->shouldReceive('resolveForSchoolYear')->andReturn([
|
||||
'school_year' => '2025-2026',
|
||||
'semester' => 'Fall',
|
||||
@@ -28,10 +25,10 @@ class AttendancePendingViolationServiceTest extends TestCase
|
||||
'debug' => [],
|
||||
]);
|
||||
|
||||
$engine = Mockery::mock(ViolationRuleEngineService::class);
|
||||
$engine = Mockery::mock(\App\Services\AttendanceTracking\ViolationRuleEngineService::class);
|
||||
|
||||
$service = new AttendancePendingViolationService(
|
||||
new AttendanceData,
|
||||
new \App\Models\AttendanceData(),
|
||||
$engine,
|
||||
$resolver
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ class AttendanceTrackingServiceTest extends TestCase
|
||||
|
||||
public function test_service_instantiates(): void
|
||||
{
|
||||
$service = new AttendanceTrackingService;
|
||||
$service = new AttendanceTrackingService();
|
||||
$this->assertInstanceOf(AttendanceTrackingService::class, $service);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-6
@@ -2,9 +2,6 @@
|
||||
|
||||
namespace Tests\Unit\Services\AttendanceTracking;
|
||||
|
||||
use App\Models\AttendanceData;
|
||||
use App\Models\Student;
|
||||
use App\Models\StudentClass;
|
||||
use App\Services\AttendanceTracking\AttendanceViolationStudentResolverService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -37,9 +34,9 @@ class AttendanceViolationStudentResolverServiceTest extends TestCase
|
||||
]);
|
||||
|
||||
$service = new AttendanceViolationStudentResolverService(
|
||||
new Student,
|
||||
new StudentClass,
|
||||
new AttendanceData
|
||||
new \App\Models\Student(),
|
||||
new \App\Models\StudentClass(),
|
||||
new \App\Models\AttendanceData()
|
||||
);
|
||||
|
||||
$result = $service->resolveForSchoolYear('2025-2026', 'Fall');
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
namespace Tests\Unit\Services\AttendanceTracking;
|
||||
|
||||
use App\Models\AttendanceTracking;
|
||||
use App\Services\AttendanceTracking\AttendanceParentLookupService;
|
||||
use App\Services\AttendanceTracking\ViolationRuleEngineService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Mockery;
|
||||
@@ -32,8 +30,8 @@ class ViolationRuleEngineServiceTest extends TestCase
|
||||
|
||||
private function makeService(): ViolationRuleEngineService
|
||||
{
|
||||
$tracking = new AttendanceTracking;
|
||||
$parentLookup = Mockery::mock(AttendanceParentLookupService::class);
|
||||
$tracking = new \App\Models\AttendanceTracking();
|
||||
$parentLookup = Mockery::mock(\App\Services\AttendanceTracking\AttendanceParentLookupService::class);
|
||||
|
||||
return new ViolationRuleEngineService($tracking, $parentLookup);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class PasswordResetCleanupServiceTest extends TestCase
|
||||
['ip_address' => '127.0.0.1', 'requested_at' => now()->subDays(5)],
|
||||
]);
|
||||
|
||||
$service = new PasswordResetCleanupService;
|
||||
$service = new PasswordResetCleanupService();
|
||||
$deleted = $service->cleanup(30);
|
||||
|
||||
$this->assertSame(1, $deleted);
|
||||
|
||||
@@ -34,7 +34,7 @@ class PermissionCheckServiceTest extends TestCase
|
||||
'can_read' => 1,
|
||||
]);
|
||||
|
||||
$service = new PermissionCheckService;
|
||||
$service = new PermissionCheckService();
|
||||
|
||||
$this->assertTrue($service->hasPermission(10, 'edit_students'));
|
||||
$this->assertFalse($service->hasPermission(10, 'missing_perm'));
|
||||
|
||||
@@ -12,7 +12,7 @@ class RegistrationCaptchaServiceTest extends TestCase
|
||||
|
||||
public function test_generate_sets_cache_value(): void
|
||||
{
|
||||
$service = new RegistrationCaptchaService;
|
||||
$service = new RegistrationCaptchaService();
|
||||
$value = $service->generate(6);
|
||||
|
||||
$this->assertNotEmpty($value);
|
||||
@@ -21,7 +21,7 @@ class RegistrationCaptchaServiceTest extends TestCase
|
||||
|
||||
public function test_verify_and_clear(): void
|
||||
{
|
||||
$service = new RegistrationCaptchaService;
|
||||
$service = new RegistrationCaptchaService();
|
||||
$value = $service->generate(6);
|
||||
|
||||
$this->assertTrue($service->verify($value));
|
||||
|
||||
@@ -13,7 +13,7 @@ class RegistrationFormatterServiceTest extends TestCase
|
||||
|
||||
public function test_format_normalizes_parent_fields(): void
|
||||
{
|
||||
$formatter = new RegistrationFormatterService(new PhoneFormatterService);
|
||||
$formatter = new RegistrationFormatterService(new PhoneFormatterService());
|
||||
|
||||
$result = $formatter->format([
|
||||
'firstname' => 'john',
|
||||
@@ -41,7 +41,7 @@ class RegistrationFormatterServiceTest extends TestCase
|
||||
|
||||
public function test_format_includes_second_parent_when_present(): void
|
||||
{
|
||||
$formatter = new RegistrationFormatterService(new PhoneFormatterService);
|
||||
$formatter = new RegistrationFormatterService(new PhoneFormatterService());
|
||||
|
||||
$result = $formatter->format([
|
||||
'firstname' => 'john',
|
||||
|
||||
@@ -35,7 +35,7 @@ class RegistrationServiceTest extends TestCase
|
||||
'is_active' => 1,
|
||||
]);
|
||||
|
||||
$captchaService = new RegistrationCaptchaService;
|
||||
$captchaService = new RegistrationCaptchaService();
|
||||
$captcha = $captchaService->generate(4);
|
||||
|
||||
$emailService = Mockery::mock(EmailService::class);
|
||||
@@ -43,8 +43,8 @@ class RegistrationServiceTest extends TestCase
|
||||
|
||||
$service = new RegistrationService(
|
||||
$emailService,
|
||||
new SchoolIdService,
|
||||
new RegistrationFormatterService(new PhoneFormatterService),
|
||||
new SchoolIdService(),
|
||||
new RegistrationFormatterService(new PhoneFormatterService()),
|
||||
$captchaService
|
||||
);
|
||||
|
||||
@@ -115,7 +115,7 @@ class RegistrationServiceTest extends TestCase
|
||||
'token' => 'token',
|
||||
]);
|
||||
|
||||
$captchaService = new RegistrationCaptchaService;
|
||||
$captchaService = new RegistrationCaptchaService();
|
||||
$captcha = $captchaService->generate(4);
|
||||
|
||||
$emailService = Mockery::mock(EmailService::class);
|
||||
@@ -123,8 +123,8 @@ class RegistrationServiceTest extends TestCase
|
||||
|
||||
$service = new RegistrationService(
|
||||
$emailService,
|
||||
new SchoolIdService,
|
||||
new RegistrationFormatterService(new PhoneFormatterService),
|
||||
new SchoolIdService(),
|
||||
new RegistrationFormatterService(new PhoneFormatterService()),
|
||||
$captchaService
|
||||
);
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class UserRoleServiceTest extends TestCase
|
||||
'can_manage' => 0,
|
||||
]);
|
||||
|
||||
$service = new UserRoleService;
|
||||
$service = new UserRoleService();
|
||||
$roleIds = $service->getRoleIds(5);
|
||||
|
||||
$this->assertTrue($service->hasPermissionForCrud($roleIds, 'manage_students', 'read'));
|
||||
|
||||
@@ -19,7 +19,7 @@ class BadgeFormDataServiceTest extends TestCase
|
||||
public function test_build_formats_users_and_assigns_latest_class_for_teacherish_roles(): void
|
||||
{
|
||||
$lookup = Mockery::mock(BadgeUserLookupService::class);
|
||||
$formatter = new BadgeTextFormatter;
|
||||
$formatter = new BadgeTextFormatter();
|
||||
|
||||
$lookup->shouldReceive('fetchStaffList')
|
||||
->once()
|
||||
@@ -75,7 +75,7 @@ class BadgeFormDataServiceTest extends TestCase
|
||||
public function test_build_defaults_invalid_active_role_to_teacher(): void
|
||||
{
|
||||
$lookup = Mockery::mock(BadgeUserLookupService::class);
|
||||
$formatter = new BadgeTextFormatter;
|
||||
$formatter = new BadgeTextFormatter();
|
||||
|
||||
$lookup->shouldReceive('fetchStaffList')
|
||||
->once()
|
||||
@@ -91,4 +91,4 @@ class BadgeFormDataServiceTest extends TestCase
|
||||
|
||||
$this->assertSame('teacher', $result['active_role']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ class BadgePdfServiceTest extends TestCase
|
||||
{
|
||||
$lookup = Mockery::mock(BadgeUserLookupService::class);
|
||||
$printLog = Mockery::mock(BadgePrintLogService::class);
|
||||
$formatter = new BadgeTextFormatter;
|
||||
$formatter = new BadgeTextFormatter();
|
||||
|
||||
$lookup->shouldReceive('getUserInfoById')
|
||||
->once()
|
||||
@@ -65,7 +65,7 @@ class BadgePdfServiceTest extends TestCase
|
||||
{
|
||||
$lookup = Mockery::mock(BadgeUserLookupService::class);
|
||||
$printLog = Mockery::mock(BadgePrintLogService::class);
|
||||
$formatter = new BadgeTextFormatter;
|
||||
$formatter = new BadgeTextFormatter();
|
||||
|
||||
$lookup->shouldReceive('getUserInfoById')
|
||||
->once()
|
||||
@@ -94,7 +94,7 @@ class BadgePdfServiceTest extends TestCase
|
||||
{
|
||||
$lookup = Mockery::mock(BadgeUserLookupService::class);
|
||||
$printLog = Mockery::mock(BadgePrintLogService::class);
|
||||
$formatter = new BadgeTextFormatter;
|
||||
$formatter = new BadgeTextFormatter();
|
||||
|
||||
$userInfo = [
|
||||
'user_id' => 10,
|
||||
|
||||
@@ -20,7 +20,7 @@ class BadgePrintLogServiceTest extends TestCase
|
||||
public function test_get_status_normalizes_ids_before_calling_model(): void
|
||||
{
|
||||
$model = Mockery::mock(BadgePrintLog::class);
|
||||
$formatter = new BadgeTextFormatter;
|
||||
$formatter = new BadgeTextFormatter();
|
||||
|
||||
$expected = [
|
||||
5 => ['count' => 2, 'last_printed_at' => '2026-03-06 10:00:00', 'last_printed_by' => 1],
|
||||
@@ -41,7 +41,7 @@ class BadgePrintLogServiceTest extends TestCase
|
||||
public function test_log_normalizes_ids_and_returns_inserted_count(): void
|
||||
{
|
||||
$model = Mockery::mock(BadgePrintLog::class);
|
||||
$formatter = new BadgeTextFormatter;
|
||||
$formatter = new BadgeTextFormatter();
|
||||
|
||||
$model->shouldReceive('logPrints')
|
||||
->once()
|
||||
@@ -74,7 +74,7 @@ class BadgePrintLogServiceTest extends TestCase
|
||||
Log::spy();
|
||||
|
||||
$model = Mockery::mock(BadgePrintLog::class);
|
||||
$formatter = new BadgeTextFormatter;
|
||||
$formatter = new BadgeTextFormatter();
|
||||
|
||||
$model->shouldReceive('logPrints')
|
||||
->once()
|
||||
@@ -91,4 +91,4 @@ class BadgePrintLogServiceTest extends TestCase
|
||||
Log::shouldHaveReceived('error')->once();
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ class BadgeTextFormatterTest extends TestCase
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->formatter = new BadgeTextFormatter;
|
||||
$this->formatter = new BadgeTextFormatter();
|
||||
}
|
||||
|
||||
public function test_normalize_ids_filters_and_deduplicates(): void
|
||||
@@ -86,7 +86,7 @@ class BadgeTextFormatterTest extends TestCase
|
||||
|
||||
public function test_fit_text_returns_size_within_bounds(): void
|
||||
{
|
||||
$pdf = new FPDF;
|
||||
$pdf = new FPDF();
|
||||
$pdf->AddPage();
|
||||
$pdf->SetFont('Arial', '', 12);
|
||||
|
||||
@@ -95,4 +95,4 @@ class BadgeTextFormatterTest extends TestCase
|
||||
$this->assertGreaterThanOrEqual(7, $size);
|
||||
$this->assertLessThanOrEqual(11, $size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,13 +192,13 @@ class BalanceCalculationServiceTest extends TestCase
|
||||
|
||||
private function makeService(): BalanceCalculationService
|
||||
{
|
||||
$config = new FeeConfigService;
|
||||
$config = new FeeConfigService();
|
||||
$tuition = new TuitionCalculationService(
|
||||
$config,
|
||||
new FeeStudentFeeService(new FeeGradeService, $config)
|
||||
new FeeStudentFeeService(new FeeGradeService(), $config)
|
||||
);
|
||||
|
||||
return new BalanceCalculationService($config, $tuition, new BillingTotalsService);
|
||||
return new BalanceCalculationService($config, $tuition, new BillingTotalsService());
|
||||
}
|
||||
|
||||
private function seedFeeConfig(): void
|
||||
@@ -226,7 +226,7 @@ class BalanceCalculationServiceTest extends TestCase
|
||||
{
|
||||
return (int) DB::table('invoices')->insertGetId([
|
||||
'parent_id' => $parentId,
|
||||
'invoice_number' => 'INV-'.$parentId,
|
||||
'invoice_number' => 'INV-' . $parentId,
|
||||
'total_amount' => $total,
|
||||
'balance' => 0.00,
|
||||
'paid_amount' => 0.00,
|
||||
|
||||
@@ -51,7 +51,7 @@ class BillingTotalsServiceTest extends TestCase
|
||||
],
|
||||
]);
|
||||
|
||||
$service = new BillingTotalsService;
|
||||
$service = new BillingTotalsService();
|
||||
|
||||
$eventSubtotal = $service->eventSubtotal(10, '2025-2026');
|
||||
$additionalSubtotal = $service->additionalSubtotal(99, '2025-2026');
|
||||
@@ -95,7 +95,7 @@ class BillingTotalsServiceTest extends TestCase
|
||||
],
|
||||
]);
|
||||
|
||||
$service = new BillingTotalsService;
|
||||
$service = new BillingTotalsService();
|
||||
|
||||
$this->assertSame(30.0, $service->additionalSubtotalByParent(10, '2025-2026'));
|
||||
}
|
||||
@@ -126,7 +126,7 @@ class BillingTotalsServiceTest extends TestCase
|
||||
],
|
||||
]);
|
||||
|
||||
$service = new BillingTotalsService;
|
||||
$service = new BillingTotalsService();
|
||||
$byStudent = $service->eventSubtotalsByStudent(5, '2025-2026');
|
||||
|
||||
$this->assertSame(20.0, $byStudent[1]);
|
||||
|
||||
@@ -9,7 +9,7 @@ class BroadcastEmailComposerServiceTest extends TestCase
|
||||
{
|
||||
public function test_sanitize_removes_script_and_events(): void
|
||||
{
|
||||
$service = new BroadcastEmailComposerService;
|
||||
$service = new BroadcastEmailComposerService();
|
||||
$html = '<p onclick="alert(1)">Hi</p><script>alert(2)</script>';
|
||||
|
||||
$clean = $service->sanitizeHtml($html);
|
||||
@@ -20,7 +20,7 @@ class BroadcastEmailComposerServiceTest extends TestCase
|
||||
|
||||
public function test_compose_replaces_name_when_personalized(): void
|
||||
{
|
||||
$service = new BroadcastEmailComposerService;
|
||||
$service = new BroadcastEmailComposerService();
|
||||
$html = '<p>Hello {{name}}</p>';
|
||||
|
||||
$rendered = $service->compose(false, 'Subject', $html, 'Parent', '', '', '', true);
|
||||
|
||||
@@ -15,7 +15,7 @@ class BroadcastEmailRecipientServiceTest extends TestCase
|
||||
{
|
||||
$this->seedParentData();
|
||||
|
||||
$service = new BroadcastEmailRecipientService;
|
||||
$service = new BroadcastEmailRecipientService();
|
||||
$parents = $service->parentsWithEmails();
|
||||
|
||||
$this->assertCount(1, $parents);
|
||||
@@ -26,7 +26,7 @@ class BroadcastEmailRecipientServiceTest extends TestCase
|
||||
{
|
||||
$this->seedParentData();
|
||||
|
||||
$service = new BroadcastEmailRecipientService;
|
||||
$service = new BroadcastEmailRecipientService();
|
||||
$recipients = $service->recipientsByIds([10]);
|
||||
|
||||
$this->assertCount(1, $recipients);
|
||||
|
||||
@@ -12,12 +12,12 @@ class BroadcastEmailSenderOptionsServiceTest extends TestCase
|
||||
$old = getenv('MAIL_SENDERS') ?: '';
|
||||
putenv('MAIL_SENDERS={"general":{"name":"Office","email":"office@example.com"}}');
|
||||
|
||||
$service = new BroadcastEmailSenderOptionsService;
|
||||
$service = new BroadcastEmailSenderOptionsService();
|
||||
$options = $service->listOptions();
|
||||
|
||||
$this->assertSame('general', $options[0]['key']);
|
||||
$this->assertSame('Office <office@example.com>', $options[0]['label']);
|
||||
|
||||
putenv('MAIL_SENDERS='.$old);
|
||||
putenv('MAIL_SENDERS=' . $old);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class ClassRosterServiceTest extends TestCase
|
||||
{
|
||||
$this->seedRosterData();
|
||||
|
||||
$service = new ClassRosterService;
|
||||
$service = new ClassRosterService();
|
||||
$students = $service->listStudentsByClass(101, '2025-2026');
|
||||
|
||||
$this->assertCount(1, $students);
|
||||
|
||||
@@ -15,7 +15,7 @@ class StickerCountServiceTest extends TestCase
|
||||
{
|
||||
$this->seedStickerData();
|
||||
|
||||
$service = new StickerCountService;
|
||||
$service = new StickerCountService();
|
||||
$payload = $service->listAll('2025-2026', 'Fall');
|
||||
|
||||
$this->assertSame(2, $payload['totals']['students']);
|
||||
@@ -27,7 +27,7 @@ class StickerCountServiceTest extends TestCase
|
||||
{
|
||||
$this->seedStickerData();
|
||||
|
||||
$service = new StickerCountService;
|
||||
$service = new StickerCountService();
|
||||
$payload = $service->listForClass('2025-2026', 'Fall', 101);
|
||||
|
||||
$this->assertSame(1, $payload['totals']['students']);
|
||||
|
||||
@@ -21,7 +21,7 @@ class ClassPreparationAdjustmentServiceTest extends TestCase
|
||||
'adjustable' => 1,
|
||||
]);
|
||||
|
||||
$service = new ClassPreparationAdjustmentService;
|
||||
$service = new ClassPreparationAdjustmentService();
|
||||
[$items, $adjMap] = $service->applyAdjustments(['Small Table' => 1], '101', '2025-2026');
|
||||
|
||||
$this->assertSame(3, $items['Small Table']);
|
||||
|
||||
@@ -22,7 +22,7 @@ class ClassPreparationCalculatorServiceTest extends TestCase
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$service = new ClassPreparationCalculatorService;
|
||||
$service = new ClassPreparationCalculatorService();
|
||||
|
||||
$this->assertSame(2, $service->getClassLevelBySection('101'));
|
||||
$this->assertSame(1, $service->getClassLevelBySection('KG'));
|
||||
@@ -49,7 +49,7 @@ class ClassPreparationCalculatorServiceTest extends TestCase
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$service = new ClassPreparationCalculatorService;
|
||||
$service = new ClassPreparationCalculatorService();
|
||||
$items = $service->calculatePrepItems(6, 1, '101');
|
||||
|
||||
$this->assertSame(2, $items['Small Table']);
|
||||
|
||||
@@ -20,7 +20,7 @@ class ClassPreparationContextServiceTest extends TestCase
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$service = new ClassPreparationContextService;
|
||||
$service = new ClassPreparationContextService();
|
||||
|
||||
$this->assertTrue($service->hasRosterForSemester('2025-2026', 'Fall'));
|
||||
$this->assertFalse($service->hasRosterForSemester('2025-2026', 'Spring'));
|
||||
|
||||
@@ -40,7 +40,7 @@ class ClassPreparationInventoryServiceTest extends TestCase
|
||||
],
|
||||
]);
|
||||
|
||||
$service = new ClassPreparationInventoryService;
|
||||
$service = new ClassPreparationInventoryService();
|
||||
$map = $service->buildAvailability('2025-2026', 'Fall', true, ['Small Table']);
|
||||
|
||||
$this->assertSame(8, $map['Small Table']);
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Tests\Unit\Services\ClassPreparation;
|
||||
|
||||
use App\Services\ClassPreparation\ClassPreparationLogService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ClassPreparationLogServiceTest extends TestCase
|
||||
@@ -12,7 +13,7 @@ class ClassPreparationLogServiceTest extends TestCase
|
||||
|
||||
public function test_has_prep_changed_detects_diff(): void
|
||||
{
|
||||
$service = new ClassPreparationLogService;
|
||||
$service = new ClassPreparationLogService();
|
||||
|
||||
$this->assertTrue($service->hasPrepChanged(['a' => 1], ['a' => 2]));
|
||||
$this->assertFalse($service->hasPrepChanged(['a' => 1], ['a' => 1]));
|
||||
@@ -20,7 +21,7 @@ class ClassPreparationLogServiceTest extends TestCase
|
||||
|
||||
public function test_create_log_and_get_latest(): void
|
||||
{
|
||||
$service = new ClassPreparationLogService;
|
||||
$service = new ClassPreparationLogService();
|
||||
$created = $service->createLog('101', '1-A', '2025-2026', ['Small Table' => 2], '2025-09-01 00:00:00');
|
||||
|
||||
$this->assertTrue($created);
|
||||
|
||||
@@ -15,7 +15,7 @@ class ClassPreparationRosterServiceTest extends TestCase
|
||||
{
|
||||
$this->seedRoster();
|
||||
|
||||
$service = new ClassPreparationRosterService;
|
||||
$service = new ClassPreparationRosterService();
|
||||
$rows = $service->getClassSectionStudentCounts('2025-2026', 'Fall', true);
|
||||
|
||||
$this->assertCount(1, $rows);
|
||||
@@ -27,7 +27,7 @@ class ClassPreparationRosterServiceTest extends TestCase
|
||||
{
|
||||
$this->seedRoster();
|
||||
|
||||
$service = new ClassPreparationRosterService;
|
||||
$service = new ClassPreparationRosterService();
|
||||
$count = $service->getStudentCountForSection('2025-2026', 'Fall', true, '101');
|
||||
|
||||
$this->assertSame(2, $count);
|
||||
|
||||
@@ -18,7 +18,7 @@ class ClassProgressAttachmentServiceTest extends TestCase
|
||||
Storage::fake('public');
|
||||
|
||||
$report = ClassProgressReport::factory()->create();
|
||||
$service = new ClassProgressAttachmentService;
|
||||
$service = new ClassProgressAttachmentService();
|
||||
|
||||
$files = [UploadedFile::fake()->create('sample.pdf', 12)];
|
||||
$stored = $service->storeAttachments($report->id, $files);
|
||||
|
||||
@@ -9,7 +9,7 @@ class ClassProgressMetaServiceTest extends TestCase
|
||||
{
|
||||
public function test_subject_sections_return_configured_values(): void
|
||||
{
|
||||
$service = new ClassProgressMetaService;
|
||||
$service = new ClassProgressMetaService();
|
||||
|
||||
$sections = $service->subjectSections();
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ class ClassProgressMutationServiceTest extends TestCase
|
||||
$this->assignTeacher($user->id, 101);
|
||||
|
||||
$service = new ClassProgressMutationService(
|
||||
new ClassProgressRuleService,
|
||||
new ClassProgressAttachmentService
|
||||
new ClassProgressRuleService(),
|
||||
new ClassProgressAttachmentService()
|
||||
);
|
||||
|
||||
$payload = [
|
||||
@@ -47,8 +47,8 @@ class ClassProgressMutationServiceTest extends TestCase
|
||||
]);
|
||||
|
||||
$service = new ClassProgressMutationService(
|
||||
new ClassProgressRuleService,
|
||||
new ClassProgressAttachmentService
|
||||
new ClassProgressRuleService(),
|
||||
new ClassProgressAttachmentService()
|
||||
);
|
||||
|
||||
$updated = $service->updateReport($report, ['status' => 'behind'], []);
|
||||
@@ -60,8 +60,8 @@ class ClassProgressMutationServiceTest extends TestCase
|
||||
{
|
||||
$report = ClassProgressReport::factory()->create();
|
||||
$service = new ClassProgressMutationService(
|
||||
new ClassProgressRuleService,
|
||||
new ClassProgressAttachmentService
|
||||
new ClassProgressRuleService(),
|
||||
new ClassProgressAttachmentService()
|
||||
);
|
||||
|
||||
$service->deleteReport($report);
|
||||
|
||||
@@ -26,7 +26,7 @@ class ClassProgressQueryServiceTest extends TestCase
|
||||
'class_section_id' => 202,
|
||||
]);
|
||||
|
||||
$service = new ClassProgressQueryService(new ClassProgressRuleService);
|
||||
$service = new ClassProgressQueryService(new ClassProgressRuleService());
|
||||
$results = $service->listReports($user, ['class_section_id' => 101]);
|
||||
|
||||
$this->assertSame(1, $results->total());
|
||||
|
||||
@@ -9,7 +9,7 @@ class ClassProgressRuleServiceTest extends TestCase
|
||||
{
|
||||
public function test_build_unit_chapter_summary_limits_length(): void
|
||||
{
|
||||
$service = new ClassProgressRuleService;
|
||||
$service = new ClassProgressRuleService();
|
||||
|
||||
$summary = $service->buildUnitChapterSummary(['Unit 1'], ['Chapter A']);
|
||||
|
||||
@@ -18,7 +18,7 @@ class ClassProgressRuleServiceTest extends TestCase
|
||||
|
||||
public function test_ensure_week_end_defaults_to_six_days(): void
|
||||
{
|
||||
$service = new ClassProgressRuleService;
|
||||
$service = new ClassProgressRuleService();
|
||||
|
||||
$weekEnd = $service->ensureWeekEnd('2025-09-07', null);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class CommunicationTemplateServiceTest extends TestCase
|
||||
'is_active' => 1,
|
||||
]);
|
||||
|
||||
$service = new CommunicationTemplateService;
|
||||
$service = new CommunicationTemplateService();
|
||||
$templates = $service->listActiveTemplates();
|
||||
|
||||
$this->assertSame('welcome', $templates[0]['template_key']);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Services\CompetitionScores;
|
||||
|
||||
use App\Models\CompetitionScore;
|
||||
use App\Services\CompetitionScores\CompetitionScoresSaveService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -13,7 +14,7 @@ class CompetitionScoresSaveServiceTest extends TestCase
|
||||
|
||||
public function test_filter_scores_rejects_non_integers(): void
|
||||
{
|
||||
$service = new CompetitionScoresSaveService;
|
||||
$service = new CompetitionScoresSaveService();
|
||||
[$clean, $invalid] = $service->filterScores([
|
||||
1 => '10',
|
||||
2 => '4.5',
|
||||
@@ -32,7 +33,7 @@ class CompetitionScoresSaveServiceTest extends TestCase
|
||||
'score' => 2,
|
||||
]);
|
||||
|
||||
$service = new CompetitionScoresSaveService;
|
||||
$service = new CompetitionScoresSaveService();
|
||||
$service->saveScores(1, 101, [1 => 7]);
|
||||
|
||||
$this->assertDatabaseHas('competition_scores', [
|
||||
|
||||
@@ -30,7 +30,7 @@ class DiscountApplyServiceTest extends TestCase
|
||||
'is_active' => 1,
|
||||
]);
|
||||
|
||||
$service = new DiscountApplyService(new DiscountContextService, new DiscountInvoiceService);
|
||||
$service = new DiscountApplyService(new DiscountContextService(), new DiscountInvoiceService());
|
||||
$result = $service->applyVoucher(1, [10], true, 1);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
|
||||
@@ -44,7 +44,7 @@ class EmailExtractorServiceTest extends TestCase
|
||||
'school_year' => '2025-2026',
|
||||
]);
|
||||
|
||||
$service = new EmailExtractorService;
|
||||
$service = new EmailExtractorService();
|
||||
$emails = $service->listEmails();
|
||||
|
||||
$this->assertContains('user1@example.com', $emails['users']);
|
||||
|
||||
@@ -9,7 +9,7 @@ class EmailProfileServiceTest extends TestCase
|
||||
{
|
||||
public function test_resolve_profile_maps_aliases(): void
|
||||
{
|
||||
$service = new EmailProfileService;
|
||||
$service = new EmailProfileService();
|
||||
|
||||
$this->assertSame('communication', $service->resolveProfile('comm'));
|
||||
$this->assertSame('default', $service->resolveProfile('system'));
|
||||
@@ -18,14 +18,14 @@ class EmailProfileServiceTest extends TestCase
|
||||
|
||||
public function test_env_key_from_profile(): void
|
||||
{
|
||||
$service = new EmailProfileService;
|
||||
$service = new EmailProfileService();
|
||||
|
||||
$this->assertSame('PAYMENT_ALERTS', $service->envKeyFromProfile('payment alerts'));
|
||||
}
|
||||
|
||||
public function test_sanitize_reply_to_name(): void
|
||||
{
|
||||
$service = new EmailProfileService;
|
||||
$service = new EmailProfileService();
|
||||
|
||||
$this->assertSame('Fallback', $service->sanitizeReplyToName('no-reply', 'Fallback'));
|
||||
$this->assertSame('Support', $service->sanitizeReplyToName('Support', 'Fallback'));
|
||||
|
||||
@@ -26,7 +26,7 @@ class EventChargeQueryServiceTest extends TestCase
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$service = new EventChargeQueryService;
|
||||
$service = new EventChargeQueryService();
|
||||
$result = $service->list(['per_page' => 10, 'page' => 1]);
|
||||
|
||||
$this->assertSame(1, $result['pagination']['total']);
|
||||
|
||||
@@ -38,7 +38,7 @@ class EventListServiceTest extends TestCase
|
||||
],
|
||||
]);
|
||||
|
||||
$service = new EventListService;
|
||||
$service = new EventListService();
|
||||
$result = $service->list(['active' => true, 'per_page' => 10]);
|
||||
|
||||
$this->assertSame(1, $result['pagination']['total']);
|
||||
|
||||
@@ -31,7 +31,7 @@ class EventStudentChargeServiceTest extends TestCase
|
||||
'semester' => 'Fall',
|
||||
]);
|
||||
|
||||
$service = new EventStudentChargeService;
|
||||
$service = new EventStudentChargeService();
|
||||
$rows = $service->listStudentsWithCharges(10, '2025-2026', 'Fall');
|
||||
|
||||
$this->assertTrue($rows[0]['charged']);
|
||||
|
||||
@@ -21,7 +21,7 @@ class ExamDraftTeacherServiceTest extends TestCase
|
||||
$classSectionId = $this->seedClassSection();
|
||||
$this->seedAssignment($teacherId, $classSectionId);
|
||||
|
||||
$service = new ExamDraftTeacherService(new ExamDraftConfigService, new ExamDraftFileService);
|
||||
$service = new ExamDraftTeacherService(new ExamDraftConfigService(), new ExamDraftFileService());
|
||||
|
||||
$file = UploadedFile::fake()->create('draft.docx', 10, 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
|
||||
$result = $service->store($teacherId, [
|
||||
|
||||
@@ -16,11 +16,11 @@ class ExpenseReceiptServiceTest extends TestCase
|
||||
{
|
||||
Storage::fake();
|
||||
|
||||
$service = new ExpenseReceiptService;
|
||||
$service = new ExpenseReceiptService();
|
||||
$file = UploadedFile::fake()->create('receipt.pdf', 10, 'application/pdf');
|
||||
$filename = $service->storeReceipt($file);
|
||||
|
||||
$this->assertNotEmpty($filename);
|
||||
$this->assertSame(url('receipts/'.$filename), $service->receiptUrl($filename));
|
||||
$this->assertSame(url('receipts/' . $filename), $service->receiptUrl($filename));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class ExpenseStaffServiceTest extends TestCase
|
||||
['user_id' => 11, 'role_id' => 2],
|
||||
]);
|
||||
|
||||
$service = new ExpenseStaffService;
|
||||
$service = new ExpenseStaffService();
|
||||
$staff = $service->listStaffUsers();
|
||||
|
||||
$this->assertCount(1, $staff);
|
||||
|
||||
@@ -13,7 +13,7 @@ class ExtraChargesMetaServiceTest extends TestCase
|
||||
|
||||
public function test_get_school_years_uses_fallback(): void
|
||||
{
|
||||
$service = new ExtraChargesMetaService;
|
||||
$service = new ExtraChargesMetaService();
|
||||
$years = $service->getSchoolYears('2025-2026');
|
||||
|
||||
$this->assertSame(['2025-2026', '2024-2025', '2023-2024', '2022-2023'], $years);
|
||||
@@ -53,7 +53,7 @@ class ExtraChargesMetaServiceTest extends TestCase
|
||||
],
|
||||
]);
|
||||
|
||||
$service = new ExtraChargesMetaService;
|
||||
$service = new ExtraChargesMetaService();
|
||||
$years = $service->getSchoolYears();
|
||||
|
||||
$this->assertSame(['2025-2026', '2024-2025', '2023-2024'], $years);
|
||||
|
||||
@@ -40,7 +40,7 @@ class FamilyFinanceServiceTest extends TestCase
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$service = new FamilyFinanceService;
|
||||
$service = new FamilyFinanceService();
|
||||
$result = $service->loadFinancialsForParents([1]);
|
||||
|
||||
$this->assertSame(1, $result['summary']['invoices_count']);
|
||||
|
||||
@@ -16,7 +16,7 @@ class FamilyMutationServiceTest extends TestCase
|
||||
$this->seedUser(1);
|
||||
$this->seedStudent(10, 1);
|
||||
|
||||
$service = new FamilyMutationService;
|
||||
$service = new FamilyMutationService();
|
||||
$result = $service->bootstrapFamilies();
|
||||
|
||||
$this->assertSame(1, $result['families_created']);
|
||||
@@ -36,7 +36,7 @@ class FamilyMutationServiceTest extends TestCase
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$service = new FamilyMutationService;
|
||||
$service = new FamilyMutationService();
|
||||
$result = $service->attachSecondByEmail(10, 'secondary@example.com', 'Second', 'Parent');
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
@@ -63,7 +63,7 @@ class FamilyMutationServiceTest extends TestCase
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$service = new FamilyMutationService;
|
||||
$service = new FamilyMutationService();
|
||||
$service->setPrimaryHome($familyId, 10, true);
|
||||
|
||||
$this->assertDatabaseHas('family_students', [
|
||||
@@ -80,7 +80,7 @@ class FamilyMutationServiceTest extends TestCase
|
||||
'firstname' => 'Parent',
|
||||
'lastname' => 'User',
|
||||
'cellphone' => '9999999999',
|
||||
'email' => 'parent'.$id.'@example.com',
|
||||
'email' => 'parent' . $id . '@example.com',
|
||||
'address_street' => '123 Street',
|
||||
'city' => 'City',
|
||||
'state' => 'ST',
|
||||
|
||||
@@ -20,7 +20,7 @@ class FamilyQueryServiceTest extends TestCase
|
||||
$this->seedFamilyStudent($familyId, $studentId);
|
||||
$this->seedFamilyGuardian($familyId, 1);
|
||||
|
||||
$service = new FamilyQueryService(new FamilyFinanceService);
|
||||
$service = new FamilyQueryService(new FamilyFinanceService());
|
||||
$result = $service->adminIndexData($studentId, null, '2025-2026');
|
||||
|
||||
$this->assertNotEmpty($result['families']);
|
||||
@@ -31,7 +31,7 @@ class FamilyQueryServiceTest extends TestCase
|
||||
{
|
||||
$this->seedStudent(10, 1);
|
||||
|
||||
$service = new FamilyQueryService(new FamilyFinanceService);
|
||||
$service = new FamilyQueryService(new FamilyFinanceService());
|
||||
$items = $service->searchSuggestions('Student', 5);
|
||||
|
||||
$this->assertNotEmpty($items);
|
||||
@@ -46,7 +46,7 @@ class FamilyQueryServiceTest extends TestCase
|
||||
$this->seedFamilyStudent($familyId, $studentId);
|
||||
$this->seedFamilyGuardian($familyId, 1);
|
||||
|
||||
$service = new FamilyQueryService(new FamilyFinanceService);
|
||||
$service = new FamilyQueryService(new FamilyFinanceService());
|
||||
$family = $service->familyCard(null, null, $familyId, '2025-2026');
|
||||
|
||||
$this->assertNotNull($family);
|
||||
@@ -68,7 +68,7 @@ class FamilyQueryServiceTest extends TestCase
|
||||
'firstname' => 'Parent',
|
||||
'lastname' => 'User',
|
||||
'cellphone' => '9999999999',
|
||||
'email' => 'parent'.$parentId.'@example.com',
|
||||
'email' => 'parent' . $parentId . '@example.com',
|
||||
'address_street' => '123 Street',
|
||||
'city' => 'City',
|
||||
'state' => 'ST',
|
||||
@@ -103,7 +103,7 @@ class FamilyQueryServiceTest extends TestCase
|
||||
{
|
||||
return DB::table('families')->insertGetId([
|
||||
'family_code' => $code,
|
||||
'household_name' => 'Family '.$code,
|
||||
'household_name' => 'Family ' . $code,
|
||||
'is_active' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
|
||||
@@ -9,7 +9,7 @@ class FeeGradeServiceTest extends TestCase
|
||||
{
|
||||
public function test_grade_level_parsing(): void
|
||||
{
|
||||
$service = new FeeGradeService;
|
||||
$service = new FeeGradeService();
|
||||
|
||||
$this->assertSame(0, $service->getGradeLevel('K'));
|
||||
$this->assertSame(99, $service->getGradeLevel('Y'));
|
||||
@@ -19,7 +19,7 @@ class FeeGradeServiceTest extends TestCase
|
||||
|
||||
public function test_compare_grades_orders_numeric_then_suffix(): void
|
||||
{
|
||||
$service = new FeeGradeService;
|
||||
$service = new FeeGradeService();
|
||||
|
||||
$this->assertSame(-1, $service->compareGrades('2', '3'));
|
||||
$this->assertSame(-1, $service->compareGrades('3-A', '3-B'));
|
||||
|
||||
@@ -225,8 +225,8 @@ class FeeRefundCalculatorServiceTest extends TestCase
|
||||
private function makeService(): FeeRefundCalculatorService
|
||||
{
|
||||
return new FeeRefundCalculatorService(
|
||||
new FeeConfigService,
|
||||
new FeeStudentFeeService(new FeeGradeService, new FeeConfigService)
|
||||
new FeeConfigService(),
|
||||
new FeeStudentFeeService(new FeeGradeService(), new FeeConfigService())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ class FeeRefundCalculatorServiceTest extends TestCase
|
||||
{
|
||||
$invoiceId = DB::table('invoices')->insertGetId([
|
||||
'parent_id' => $parentId,
|
||||
'invoice_number' => 'INV-'.$parentId,
|
||||
'invoice_number' => 'INV-' . $parentId,
|
||||
'total_amount' => $amount,
|
||||
'balance' => 0.00,
|
||||
'paid_amount' => $amount,
|
||||
|
||||
@@ -55,7 +55,7 @@ class FeeRefundDetailServiceTest extends TestCase
|
||||
'status' => 'Paid',
|
||||
]);
|
||||
|
||||
$service = new FeeRefundDetailService;
|
||||
$service = new FeeRefundDetailService();
|
||||
$result = $service->calculateRefundDetails([
|
||||
[
|
||||
'student_id' => 1,
|
||||
|
||||
@@ -138,7 +138,7 @@ class FeeStudentFeeServiceTest extends TestCase
|
||||
|
||||
private function makeService(): FeeStudentFeeService
|
||||
{
|
||||
return new FeeStudentFeeService(new FeeGradeService, new FeeConfigService);
|
||||
return new FeeStudentFeeService(new FeeGradeService(), new FeeConfigService());
|
||||
}
|
||||
|
||||
private function seedFeeConfig(): void
|
||||
|
||||
@@ -148,11 +148,10 @@ class TuitionCalculationServiceTest extends TestCase
|
||||
|
||||
private function makeService(): TuitionCalculationService
|
||||
{
|
||||
$config = new FeeConfigService;
|
||||
|
||||
$config = new FeeConfigService();
|
||||
return new TuitionCalculationService(
|
||||
$config,
|
||||
new FeeStudentFeeService(new FeeGradeService, $config)
|
||||
new FeeStudentFeeService(new FeeGradeService(), $config)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class ExamDraftDownloadNameServiceTest extends TestCase
|
||||
'status' => 'draft',
|
||||
]);
|
||||
|
||||
$service = new ExamDraftDownloadNameService;
|
||||
$service = new ExamDraftDownloadNameService();
|
||||
$name = $service->build('draft2.pdf', 'drafts');
|
||||
|
||||
$this->assertSame('2b_final_exam_v3', $name);
|
||||
|
||||
@@ -15,13 +15,13 @@ class FileServeServiceTest extends TestCase
|
||||
public function test_meta_returns_file_metadata(): void
|
||||
{
|
||||
$dir = storage_path('testing/files');
|
||||
if (! is_dir($dir)) {
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
$path = $dir.DIRECTORY_SEPARATOR.'sample.pdf';
|
||||
$path = $dir . DIRECTORY_SEPARATOR . 'sample.pdf';
|
||||
file_put_contents($path, 'PDFDATA');
|
||||
|
||||
$service = new FileServeService;
|
||||
$service = new FileServeService();
|
||||
$meta = $service->meta($dir, 'sample.pdf', ['pdf'], 'download');
|
||||
|
||||
$this->assertSame('sample.pdf', $meta['name']);
|
||||
@@ -33,13 +33,13 @@ class FileServeServiceTest extends TestCase
|
||||
public function test_serve_inline_returns_304_when_etag_matches(): void
|
||||
{
|
||||
$dir = storage_path('testing/files');
|
||||
if (! is_dir($dir)) {
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
$path = $dir.DIRECTORY_SEPARATOR.'cached.pdf';
|
||||
$path = $dir . DIRECTORY_SEPARATOR . 'cached.pdf';
|
||||
file_put_contents($path, 'PDFDATA');
|
||||
|
||||
$service = new FileServeService;
|
||||
$service = new FileServeService();
|
||||
$meta = $service->meta($dir, 'cached.pdf', ['pdf']);
|
||||
|
||||
$request = Request::create('/files/cached.pdf', 'GET', [], [], [], [
|
||||
@@ -57,13 +57,13 @@ class FileServeServiceTest extends TestCase
|
||||
$this->expectException(HttpException::class);
|
||||
|
||||
$dir = storage_path('testing/files');
|
||||
if (! is_dir($dir)) {
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
$path = $dir.DIRECTORY_SEPARATOR.'sample.exe';
|
||||
$path = $dir . DIRECTORY_SEPARATOR . 'sample.exe';
|
||||
file_put_contents($path, 'DATA');
|
||||
|
||||
$service = new FileServeService;
|
||||
$service = new FileServeService();
|
||||
$service->meta($dir, 'sample.exe', ['pdf']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class FinancialChartServiceTest extends TestCase
|
||||
|
||||
public function test_generate_charts_returns_null_in_tests(): void
|
||||
{
|
||||
$service = new FinancialChartService;
|
||||
$service = new FinancialChartService();
|
||||
|
||||
$summary = [
|
||||
'totalCharges' => 100,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user