Files
alrahma_sunday_school_api/tests/Feature/Api/V1/AttendanceCommentTemplateApiTest.php
T
root baa6fff459
API CI/CD / Validate (composer + pint) (push) Successful in 2m6s
API CI/CD / Test (PHPUnit) (push) Failing after 2m24s
API CI/CD / Build frontend assets (push) Successful in 2m25s
API CI/CD / Security audit (push) Successful in 32s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
fix tests isssues
2026-06-24 00:56:12 -04:00

247 lines
7.6 KiB
PHP

<?php
namespace Tests\Feature\Api;
use App\Models\User;
use App\Services\AttendanceCommentTemplateService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Laravel\Sanctum\Sanctum;
use Mockery;
use Tests\TestCase;
class AttendanceCommentTemplateApiTest extends TestCase
{
use RefreshDatabase;
use WithFaker;
protected function setUp(): void
{
parent::setUp();
$user = User::factory()->create();
Sanctum::actingAs($user);
}
protected function tearDown(): void
{
Mockery::close();
parent::tearDown();
}
public function test_can_list_templates(): void
{
$mock = Mockery::mock(AttendanceCommentTemplateService::class);
$mock->shouldReceive('list')
->once()
->with(false)
->andReturn([
[
'id' => 1,
'min_score' => 0,
'max_score' => 59,
'template_text' => 'Needs improvement',
'is_active' => true,
],
[
'id' => 2,
'min_score' => 60,
'max_score' => 79,
'template_text' => 'Good effort',
'is_active' => true,
],
]);
$this->app->instance(AttendanceCommentTemplateService::class, $mock);
$response = $this->getJson('/api/v1/attendance-comment-templates');
$response->assertOk()
->assertJson([
'status' => 'success',
])
->assertJsonCount(2, 'data')
->assertJsonPath('data.0.id', 1)
->assertJsonPath('data.1.max_score', 79);
}
public function test_can_list_templates_active_only(): void
{
$mock = Mockery::mock(AttendanceCommentTemplateService::class);
$mock->shouldReceive('list')
->once()
->with(true)
->andReturn([]);
$this->app->instance(AttendanceCommentTemplateService::class, $mock);
$response = $this->getJson('/api/v1/attendance-comment-templates?active_only=1');
$response->assertOk()
->assertJson([
'status' => 'success',
'data' => [],
]);
}
public function test_can_create_template(): void
{
$payload = [
'min_score' => 80,
'max_score' => 100,
'template_text' => 'Excellent attendance and punctuality.',
'is_active' => true,
];
$mock = Mockery::mock(AttendanceCommentTemplateService::class);
$mock->shouldReceive('create')
->once()
->with(Mockery::on(function ($data) use ($payload) {
return (int) $data['min_score'] === 80
&& (int) $data['max_score'] === 100
&& $data['template_text'] === $payload['template_text']
&& (bool) $data['is_active'] === true;
}))
->andReturn([
'id' => 10,
'min_score' => 80,
'max_score' => 100,
'template_text' => 'Excellent attendance and punctuality.',
'is_active' => true,
]);
$this->app->instance(AttendanceCommentTemplateService::class, $mock);
$response = $this->postJson('/api/v1/attendance-comment-templates', $payload);
$response->assertCreated()
->assertJsonPath('status', 'success')
->assertJsonPath('data.id', 10)
->assertJsonPath('data.min_score', 80)
->assertJsonPath('data.max_score', 100);
}
public function test_store_validation_fails_when_max_less_than_min(): void
{
$payload = [
'min_score' => 90,
'max_score' => 70,
'template_text' => 'Invalid range',
'is_active' => true,
];
$response = $this->postJson('/api/v1/attendance-comment-templates', $payload);
$response->assertStatus(422)
->assertJsonValidationErrors(['max_score']);
}
public function test_can_show_template(): void
{
$mock = Mockery::mock(AttendanceCommentTemplateService::class);
$mock->shouldReceive('findOrFail')
->once()
->with(5)
->andReturn([
'id' => 5,
'min_score' => 60,
'max_score' => 69,
'template_text' => 'Average attendance',
'is_active' => true,
]);
$this->app->instance(AttendanceCommentTemplateService::class, $mock);
$response = $this->getJson('/api/v1/attendance-comment-templates/5');
$response->assertOk()
->assertJsonPath('status', 'success')
->assertJsonPath('data.id', 5);
}
public function test_can_update_template(): void
{
$payload = [
'template_text' => 'Updated comment text',
'is_active' => false,
];
$mock = Mockery::mock(AttendanceCommentTemplateService::class);
$mock->shouldReceive('update')
->once()
->with(7, Mockery::on(function ($data) {
return $data['template_text'] === 'Updated comment text'
&& (bool) $data['is_active'] === false;
}))
->andReturn([
'id' => 7,
'min_score' => 70,
'max_score' => 79,
'template_text' => 'Updated comment text',
'is_active' => false,
]);
$this->app->instance(AttendanceCommentTemplateService::class, $mock);
$response = $this->putJson('/api/v1/attendance-comment-templates/7', $payload);
$response->assertOk()
->assertJsonPath('status', 'success')
->assertJsonPath('data.id', 7)
->assertJsonPath('data.is_active', false);
}
public function test_update_validation_fails_if_both_scores_invalid_relation(): void
{
$payload = [
'min_score' => 50,
'max_score' => 20,
];
$response = $this->putJson('/api/v1/attendance-comment-templates/7', $payload);
$response->assertStatus(422)
->assertJsonValidationErrors(['max_score']);
}
public function test_can_delete_template(): void
{
$mock = Mockery::mock(AttendanceCommentTemplateService::class);
$mock->shouldReceive('delete')
->once()
->with(12);
$this->app->instance(AttendanceCommentTemplateService::class, $mock);
$response = $this->deleteJson('/api/v1/attendance-comment-templates/12');
$response->assertOk()
->assertJsonPath('status', 'success')
->assertJsonPath('message', 'Template deleted successfully.');
}
public function test_legacy_list_data_endpoint_returns_templates_key(): void
{
$mock = Mockery::mock(AttendanceCommentTemplateService::class);
$mock->shouldReceive('list')
->once()
->with(false)
->andReturn([
[
'id' => 1,
'min_score' => 0,
'max_score' => 49,
'template_text' => 'Low attendance',
'is_active' => true,
],
]);
$this->app->instance(AttendanceCommentTemplateService::class, $mock);
$response = $this->getJson('/api/v1/attendance-comment-templates/list-data');
$response->assertOk()
->assertJsonCount(1, 'templates')
->assertJsonPath('templates.0.id', 1);
}
}