app->instance(AttendanceTrackingService::class, $service); return $service; } public function test_pending_violations_returns_json_response(): void { $service = $this->mockService(); $service->shouldReceive('getPendingViolations') ->once() ->with('2025-2026', 'Fall') ->andReturn([ 'students' => [ ['id' => 1, 'name' => 'John Doe'], ], 'school_year' => '2025-2026', 'semester' => 'Fall', ]); $response = $this->getJson('/api/attendance-tracking/pending-violations?school_year=2025-2026&semester=Fall'); $response->assertOk() ->assertJson([ 'success' => true, 'data' => [ 'school_year' => '2025-2026', 'semester' => 'Fall', ], ]); } public function test_notified_violations_returns_json_response(): void { $service = $this->mockService(); $service->shouldReceive('getNotifiedViolations') ->once() ->with('2025-2026', 'Fall') ->andReturn([ 'students' => [], 'school_year' => '2025-2026', 'semester' => 'Fall', ]); $response = $this->getJson('/api/attendance-tracking/notified-violations?school_year=2025-2026&semester=Fall'); $response->assertOk() ->assertJson([ 'success' => true, 'data' => [ 'school_year' => '2025-2026', 'semester' => 'Fall', ], ]); } public function test_student_case_returns_service_payload(): void { $service = $this->mockService(); $service->shouldReceive('getStudentCase') ->once() ->andReturn([ 'success' => true, 'data' => [ 'student' => ['id' => 10, 'name' => 'John Doe'], 'attendance' => [], ], ]); $response = $this->getJson('/api/attendance-tracking/student-case/10'); $response->assertOk() ->assertJson([ 'success' => true, 'data' => [ 'student' => ['id' => 10, 'name' => 'John Doe'], ], ]); } public function test_student_case_returns_service_status_code_when_not_found(): void { $service = $this->mockService(); $service->shouldReceive('getStudentCase') ->once() ->andReturn([ 'success' => false, 'message' => 'Student not found', 'status' => 404, ]); $response = $this->getJson('/api/attendance-tracking/student-case/999'); $response->assertStatus(404) ->assertJson([ 'success' => false, 'message' => 'Student not found', ]); } public function test_record_validates_and_returns_service_response(): void { $service = $this->mockService(); $payload = [ 'student_id' => 10, 'date' => '2026-03-01', 'parent_email' => 'parent@example.com', 'parent_name' => 'Jane Doe', 'subject_type' => 'Absent', ]; $service->shouldReceive('record') ->once() ->with($payload) ->andReturn([ 'success' => true, 'message' => 'Notification queued.', ]); $response = $this->postJson('/api/attendance-tracking/record', $payload); $response->assertOk() ->assertJson([ 'success' => true, 'message' => 'Notification queued.', ]); } public function test_record_returns_validation_errors_for_bad_payload(): void { $response = $this->postJson('/api/attendance-tracking/record', [ 'student_id' => 0, 'date' => 'bad-date', ]); $response->assertStatus(422) ->assertJsonValidationErrors(['student_id', 'date']); } public function test_send_auto_emails_returns_service_response(): void { $service = $this->mockService(); $service->shouldReceive('sendAutoEmails') ->once() ->with('default') ->andReturn([ 'success' => true, 'sent' => 2, 'skipped' => 1, 'errors' => 0, 'details' => [], ]); $response = $this->postJson('/api/attendance-tracking/send-auto-emails', [ 'variant' => 'default', ]); $response->assertOk() ->assertJson([ 'success' => true, 'sent' => 2, 'skipped' => 1, 'errors' => 0, ]); } public function test_compose_returns_service_response(): void { $service = $this->mockService(); $service->shouldReceive('compose') ->once() ->with(10, 'ABS_1', 'default', '2026-03-01') ->andReturn([ 'success' => true, 'data' => [ 'student_id' => 10, 'subject' => 'Test Subject', ], ]); $response = $this->getJson('/api/attendance-tracking/compose?student_id=10&code=ABS_1&variant=default&incident_date=2026-03-01'); $response->assertOk() ->assertJson([ 'success' => true, 'data' => [ 'student_id' => 10, 'subject' => 'Test Subject', ], ]); } public function test_send_manual_email_returns_service_response(): void { $service = $this->mockService(); $payload = [ 'student_id' => 10, 'to' => 'parent@example.com', 'subject' => 'Hello', 'body_html' => 'Body', 'code' => 'ABS_1', 'variant' => 'default', 'incident_date' => '2026-03-01', ]; $service->shouldReceive('sendEmailManual') ->once() ->with($payload) ->andReturn([ 'success' => true, 'message' => 'Email sent successfully.', ]); $response = $this->postJson('/api/attendance-tracking/send-manual-email', $payload); $response->assertOk() ->assertJson([ 'success' => true, 'message' => 'Email sent successfully.', ]); } public function test_send_manual_email_validates_payload(): void { $response = $this->postJson('/api/attendance-tracking/send-manual-email', [ 'student_id' => 0, 'to' => 'not-an-email', ]); $response->assertStatus(422) ->assertJsonValidationErrors(['student_id', 'to', 'subject', 'body_html', 'code']); } public function test_parents_info_returns_service_response(): void { $service = $this->mockService(); $service->shouldReceive('parentsInfo') ->once() ->with(10) ->andReturn([ 'success' => true, 'data' => [ 'primary' => ['email' => 'parent@example.com'], 'secondary' => ['email' => 'second@example.com'], ], ]); $response = $this->getJson('/api/attendance-tracking/parents-info?student_id=10'); $response->assertOk() ->assertJson([ 'success' => true, 'data' => [ 'primary' => ['email' => 'parent@example.com'], 'secondary' => ['email' => 'second@example.com'], ], ]); } public function test_save_notification_note_returns_service_response(): void { $service = $this->mockService(); $payload = [ 'student_id' => 10, 'code' => 'ABS_1', 'note' => 'Called parent', 'incident_date' => '2026-03-01', ]; $service->shouldReceive('saveNotificationNote') ->once() ->with($payload) ->andReturn([ 'success' => true, 'message' => 'Note saved.', ]); $response = $this->postJson('/api/attendance-tracking/save-notification-note', $payload); $response->assertOk() ->assertJson([ 'success' => true, 'message' => 'Note saved.', ]); } public function test_save_notification_note_validates_payload(): void { $response = $this->postJson('/api/attendance-tracking/save-notification-note', [ 'student_id' => 0, 'code' => '', 'note' => '', ]); $response->assertStatus(422) ->assertJsonValidationErrors(['student_id', 'code', 'note']); } }