Files
alrahma_sunday_school_api/tests/Feature/Api/V1/BadgeControllerTest.php
T
2026-03-08 16:33:24 -04:00

237 lines
7.0 KiB
PHP

<?php
namespace Tests\Feature\Api;
use App\Models\User;
use App\Services\Badges\BadgeFormDataService;
use App\Services\Badges\BadgePdfService;
use App\Services\Badges\BadgePrintLogService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Mockery;
use Tests\TestCase;
class BadgeControllerTest extends TestCase
{
use RefreshDatabase;
protected function authenticate(): User
{
$user = User::factory()->create();
Sanctum::actingAs($user);
return $user;
}
protected function tearDown(): void
{
Mockery::close();
parent::tearDown();
}
public function test_form_data_returns_success_response(): void
{
$this->authenticate();
$mock = Mockery::mock(BadgeFormDataService::class);
$mock->shouldReceive('build')
->once()
->with('2025-2026', [10, 20], 'teacher')
->andReturn([
'users' => [],
'schoolYears' => ['2025-2026'],
'selectedYear' => '2025-2026',
'selectedUserIds' => [10, 20],
'rolesTabs' => ['teacher' => 'Teachers'],
'active_role' => 'teacher',
]);
$this->app->instance(BadgeFormDataService::class, $mock);
$response = $this->getJson('/api/badges/form-data?school_year=2025-2026&user_ids=10,20&active_role=teacher');
$response->assertOk()
->assertJson([
'ok' => true,
'data' => [
'selectedYear' => '2025-2026',
'selectedUserIds' => [10, 20],
'active_role' => 'teacher',
],
]);
}
public function test_print_status_returns_success_response(): void
{
$this->authenticate();
$mock = Mockery::mock(BadgePrintLogService::class);
$mock->shouldReceive('getStatus')
->once()
->with([5, 7], '2025-2026')
->andReturn([
5 => [
'count' => 2,
'last_printed_at' => '2026-03-06 12:00:00',
'last_printed_by' => 1,
],
]);
$this->app->instance(BadgePrintLogService::class, $mock);
$response = $this->getJson('/api/badges/print-status?user_ids=5,7&school_year=2025-2026');
$response->assertOk()
->assertJson([
'ok' => true,
'data' => [
'5' => [
'count' => 2,
'last_printed_at' => '2026-03-06 12:00:00',
'last_printed_by' => 1,
],
],
]);
}
public function test_print_status_returns_500_when_service_throws(): void
{
$this->authenticate();
$mock = Mockery::mock(BadgePrintLogService::class);
$mock->shouldReceive('getStatus')
->once()
->andThrow(new \RuntimeException('db failed'));
$this->app->instance(BadgePrintLogService::class, $mock);
$response = $this->getJson('/api/badges/print-status?user_ids=5,7');
$response->assertStatus(500)
->assertJson([
'ok' => false,
'error' => 'Failed to query status',
]);
}
public function test_log_print_returns_success_response(): void
{
$authUser = $this->authenticate();
$mock = Mockery::mock(BadgePrintLogService::class);
$mock->shouldReceive('log')
->once()
->with(
[10, 20],
$authUser->id,
'2025-2026',
['10' => 'Teacher'],
['10' => '3-A']
)
->andReturn(2);
$this->app->instance(BadgePrintLogService::class, $mock);
$response = $this->postJson('/api/badges/log-print', [
'user_ids' => [10, 20],
'school_year' => '2025-2026',
'roles' => ['10' => 'Teacher'],
'classes' => ['10' => '3-A'],
]);
$response->assertOk()
->assertJson([
'ok' => true,
'inserted' => 2,
]);
}
public function test_log_print_returns_500_when_service_throws(): void
{
$this->authenticate();
$mock = Mockery::mock(BadgePrintLogService::class);
$mock->shouldReceive('log')
->once()
->andThrow(new \RuntimeException('insert failed'));
$this->app->instance(BadgePrintLogService::class, $mock);
$response = $this->postJson('/api/badges/log-print', [
'user_ids' => [10],
]);
$response->assertStatus(500)
->assertJson([
'ok' => false,
'error' => 'insert failed',
]);
}
public function test_generate_pdf_returns_pdf_response(): void
{
$authUser = $this->authenticate();
$mock = Mockery::mock(BadgePdfService::class);
$mock->shouldReceive('generate')
->once()
->with(
[10, 20],
'2025-2026',
['10' => 'Teacher'],
['10' => '3-A'],
$authUser->id
)
->andReturn(response('fake-pdf-content', 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="Staff_Badges.pdf"',
]));
$this->app->instance(BadgePdfService::class, $mock);
$response = $this->post('/api/badges/pdf', [
'user_ids' => [10, 20],
'school_year' => '2025-2026',
'roles' => ['10' => 'Teacher'],
'classes' => ['10' => '3-A'],
]);
$response->assertOk();
$response->assertHeader('Content-Type', 'application/pdf');
$this->assertStringContainsString(
'inline; filename="Staff_Badges.pdf"',
$response->headers->get('Content-Disposition')
);
$this->assertSame('fake-pdf-content', $response->getContent());
}
public function test_generate_pdf_validates_required_user_ids(): void
{
$this->authenticate();
$response = $this->postJson('/api/badges/pdf', [
'school_year' => '2025-2026',
]);
$response->assertStatus(422)
->assertJsonValidationErrors(['user_ids']);
}
public function test_log_print_validates_required_user_ids(): void
{
$this->authenticate();
$response = $this->postJson('/api/badges/log-print', []);
$response->assertStatus(422)
->assertJsonValidationErrors(['user_ids']);
}
public function test_endpoints_require_authentication(): void
{
$this->getJson('/api/badges/form-data')->assertStatus(401);
$this->getJson('/api/badges/print-status')->assertStatus(401);
$this->postJson('/api/badges/log-print', ['user_ids' => [1]])->assertStatus(401);
$this->postJson('/api/badges/pdf', ['user_ids' => [1]])->assertStatus(401);
}
}