getJson('/api/v1/settings/events'); $response->assertStatus(401); } public function test_index_returns_events(): void { $user = $this->createUser(); Sanctum::actingAs($user); DB::table('events')->insert([ 'id' => 1, 'event_name' => 'Open House', 'event_category' => 'workshops', 'amount' => 10, 'expiration_date' => '2025-02-01', 'semester' => 'Fall', 'school_year' => '2025-2026', 'created_at' => now(), 'updated_at' => now(), ]); $response = $this->getJson('/api/v1/settings/events'); $response->assertOk(); $response->assertJsonPath('ok', true); $response->assertJsonStructure([ 'ok', 'events', 'pagination', 'active_count', 'categories', ]); } public function test_store_creates_event(): void { $this->mock(InvoiceGenerationService::class, function ($mock) { $mock->shouldReceive('generateInvoice')->andReturn(['ok' => true]); }); $user = $this->createUser(); Sanctum::actingAs($user); DB::table('students')->insert([ 'id' => 1, 'parent_id' => 10, 'firstname' => 'Kid', 'lastname' => 'One', ]); DB::table('enrollments')->insert([ 'id' => 1, 'student_id' => 1, 'parent_id' => 10, 'class_section_id' => 101, 'enrollment_status' => 'enrolled', 'school_year' => '2025-2026', ]); $response = $this->postJson('/api/v1/settings/events', [ 'event_name' => 'Field Trip', 'event_category' => 'field trips', 'description' => 'Visit museum', 'amount' => 25, 'expiration_date' => '2025-02-01', 'semester' => 'Fall', 'school_year' => '2025-2026', ]); $response->assertStatus(201); $response->assertJsonPath('ok', true); $this->assertDatabaseHas('events', [ 'event_name' => 'Field Trip', 'school_year' => '2025-2026', ]); $this->assertDatabaseHas('event_charges', [ 'event_id' => 1, 'student_id' => 1, ]); } public function test_store_requires_authentication(): void { $response = $this->postJson('/api/v1/settings/events', [ 'event_name' => 'Field Trip', 'event_category' => 'field trips', 'amount' => 25, 'expiration_date' => '2025-02-01', 'semester' => 'Fall', 'school_year' => '2025-2026', ]); $response->assertStatus(401); } public function test_store_validates_payload(): void { $user = $this->createUser(); Sanctum::actingAs($user); $response = $this->postJson('/api/v1/settings/events', [ 'event_name' => '', 'event_category' => 'invalid', ]); $response->assertStatus(422); $response->assertJsonStructure(['message', 'errors']); } public function test_store_handles_service_exception(): void { $this->mock(EventManagementService::class, function ($mock) { $mock->shouldReceive('create')->andThrow(new \RuntimeException('boom')); }); $user = $this->createUser(); Sanctum::actingAs($user); $response = $this->postJson('/api/v1/settings/events', [ 'event_name' => 'Field Trip', 'event_category' => 'field trips', 'description' => 'Visit museum', 'amount' => 25, 'expiration_date' => '2025-02-01', 'semester' => 'Fall', 'school_year' => '2025-2026', ]); $response->assertStatus(500); $response->assertJsonPath('ok', false); } public function test_update_updates_event(): void { $user = $this->createUser(); Sanctum::actingAs($user); DB::table('events')->insert([ 'id' => 1, 'event_name' => 'Open House', 'event_category' => 'workshops', 'amount' => 10, 'expiration_date' => '2025-02-01', 'semester' => 'Fall', 'school_year' => '2025-2026', 'created_at' => now(), 'updated_at' => now(), ]); $response = $this->patchJson('/api/v1/settings/events/1', [ 'event_name' => 'Updated', ]); $response->assertOk(); $this->assertDatabaseHas('events', [ 'id' => 1, 'event_name' => 'Updated', ]); } public function test_destroy_deletes_event(): void { $this->mock(InvoiceGenerationService::class, function ($mock) { $mock->shouldReceive('generateInvoice')->andReturn(['ok' => true]); }); $user = $this->createUser(); Sanctum::actingAs($user); DB::table('events')->insert([ 'id' => 1, 'event_name' => 'Open House', 'event_category' => 'workshops', 'amount' => 10, 'expiration_date' => '2025-02-01', 'semester' => 'Fall', 'school_year' => '2025-2026', 'created_at' => now(), 'updated_at' => now(), ]); DB::table('event_charges')->insert([ 'id' => 1, 'event_id' => 1, 'parent_id' => 10, 'student_id' => 1, 'participation' => 'yes', 'charged' => 10, 'school_year' => '2025-2026', 'semester' => 'Fall', ]); $response = $this->deleteJson('/api/v1/settings/events/1'); $response->assertOk(); $this->assertDatabaseMissing('events', ['id' => 1]); } public function test_charges_list_returns_data(): void { $user = $this->createUser(); Sanctum::actingAs($user); DB::table('users')->insert([ 'id' => 10, 'firstname' => 'Parent', 'lastname' => 'User', 'email' => 'p@example.com', 'status' => 'Active', ]); DB::table('students')->insert([ 'id' => 1, 'parent_id' => 10, 'firstname' => 'Kid', 'lastname' => 'One', ]); DB::table('events')->insert([ 'id' => 1, 'event_name' => 'Open House', 'event_category' => 'workshops', 'amount' => 10, 'expiration_date' => '2025-02-01', 'semester' => 'Fall', 'school_year' => '2025-2026', 'created_at' => now(), 'updated_at' => now(), ]); DB::table('event_charges')->insert([ 'id' => 1, 'event_id' => 1, 'parent_id' => 10, 'student_id' => 1, 'participation' => 'yes', 'charged' => 10, 'school_year' => '2025-2026', 'semester' => 'Fall', ]); $response = $this->getJson('/api/v1/settings/events/charges/list'); $response->assertOk(); $response->assertJsonPath('ok', true); $response->assertJsonStructure(['ok', 'charges', 'pagination']); } public function test_update_charges_updates_participation(): void { $this->mock(InvoiceGenerationService::class, function ($mock) { $mock->shouldReceive('generateInvoice')->andReturn(['ok' => true]); }); $user = $this->createUser(); Sanctum::actingAs($user); DB::table('events')->insert([ 'id' => 1, 'event_name' => 'Open House', 'event_category' => 'workshops', 'amount' => 10, 'expiration_date' => '2025-02-01', 'semester' => 'Fall', 'school_year' => '2025-2026', 'created_at' => now(), 'updated_at' => now(), ]); $response = $this->postJson('/api/v1/settings/events/1/charges', [ 'parent_id' => 10, 'school_year' => '2025-2026', 'semester' => 'Fall', 'participation' => [ 1 => 'yes', ], ]); $response->assertOk(); $this->assertDatabaseHas('event_charges', [ 'event_id' => 1, 'student_id' => 1, 'parent_id' => 10, ]); } public function test_students_with_charges_returns_students(): void { $user = $this->createUser(); Sanctum::actingAs($user); DB::table('students')->insert([ 'id' => 1, 'parent_id' => 10, 'firstname' => 'Kid', 'lastname' => 'One', ]); DB::table('event_charges')->insert([ 'id' => 1, 'event_id' => 1, 'parent_id' => 10, 'student_id' => 1, 'participation' => 'yes', 'charged' => 10, 'school_year' => '2025-2026', 'semester' => 'Fall', ]); $response = $this->getJson('/api/v1/settings/events/charges/students?parent_id=10&school_year=2025-2026&semester=Fall'); $response->assertOk(); $response->assertJsonPath('ok', true); $response->assertJsonStructure(['ok', 'students']); } private function createUser(): User { DB::table('users')->insert([ 'id' => 1, 'school_id' => 1, 'firstname' => 'Admin', 'lastname' => 'User', 'cellphone' => '5555555555', 'email' => 'admin@example.com', 'address_street' => '123 Main', 'city' => 'City', 'state' => 'ST', 'zip' => '12345', 'accept_school_policy' => 1, 'is_verified' => 1, 'status' => 'Active', 'is_suspended' => 0, 'failed_attempts' => 0, 'password' => bcrypt('secret'), 'semester' => 'Fall', 'school_year' => '2025-2026', ]); return User::query()->findOrFail(1); } }