migrants-nt-sec/tests/Feature/PersonApiTest.php

261 lines
7.7 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
use App\Models\Person;
class PersonApiTest extends TestCase
{
use RefreshDatabase, WithFaker;
/**
* Set up authentication for each test
*/
protected function setUp(): void
{
parent::setUp();
// Create and authenticate as admin user for all tests
$user = User::factory()->create([
'email' => 'test.admin@example.com',
'is_admin' => true
]);
Sanctum::actingAs($user, ['*']);
}
/**
* Test creating a new person with related entities.
*/
public function test_can_create_person_with_related_entities(): void
{
$personData = [
'surname' => $this->faker->lastName,
'christian_name' => $this->faker->firstName,
'full_name' => $this->faker->name,
'date_of_birth' => $this->faker->date(),
'place_of_birth' => $this->faker->city,
'occupation' => $this->faker->jobTitle,
'migration' => [
'date_of_arrival_aus' => $this->faker->date(),
'date_of_arrival_nt' => $this->faker->date(),
'arrival_period' => '1950-1960',
],
'residence' => [
'darwin' => true,
'katherine' => false,
'tennant_creek' => false,
'alice_springs' => false,
],
'family' => [
'names_of_parents' => 'John Doe, Jane Doe',
'names_of_children' => 'Tim, Sarah, Michael',
],
];
$response = $this->postJson('/api/persons', $personData);
$response->assertStatus(201)
->assertJsonStructure([
'success',
'data' => [
'person_id',
'surname',
'christian_name',
'full_name',
'date_of_birth',
'place_of_birth',
'occupation',
'migration',
'residence',
'family',
],
'message',
])
->assertJson([
'success' => true,
'message' => 'Person created successfully',
]);
$this->assertDatabaseHas('person', [
'surname' => $personData['surname'],
'christian_name' => $personData['christian_name'],
]);
$personId = $response->json('data.person_id');
$this->assertDatabaseHas('migration', ['person_id' => $personId]);
$this->assertDatabaseHas('residence', ['person_id' => $personId]);
$this->assertDatabaseHas('family', ['person_id' => $personId]);
}
/**
* Test retrieving a list of persons.
*/
public function test_can_get_all_persons(): void
{
// Create some test persons
Person::factory(3)->create();
$response = $this->getJson('/api/persons');
$response->assertStatus(200)
->assertJsonStructure([
'success',
'data' => [
'data',
'meta',
'links',
],
'message',
])
->assertJson([
'success' => true,
'message' => 'Persons retrieved successfully',
]);
}
/**
* Test searching for persons by name or occupation.
*/
public function test_can_search_persons(): void
{
// Create a test person
$person = Person::factory()->create([
'surname' => 'Smith',
'occupation' => 'Engineer',
]);
// Create some other persons
Person::factory(3)->create();
$response = $this->getJson('/api/persons?search=Smith');
$response->assertStatus(200)
->assertJsonStructure([
'success',
'data',
'message',
])
->assertJson([
'success' => true,
'message' => 'Persons retrieved successfully',
]);
// Check that the search works with occupation too
$response = $this->getJson('/api/persons?search=Engineer');
$response->assertStatus(200);
}
/**
* Test retrieving a specific person.
*/
public function test_can_get_specific_person(): void
{
$person = Person::factory()->create();
$response = $this->getJson("/api/persons/{$person->person_id}");
$response->assertStatus(200)
->assertJsonStructure([
'success',
'data' => [
'person_id',
'surname',
'christian_name',
'full_name',
],
'message',
])
->assertJson([
'success' => true,
'message' => 'Person retrieved successfully',
]);
}
/**
* Test updating a person and related entities.
*/
public function test_can_update_person_and_related_entities(): void
{
$person = Person::factory()->create();
$updateData = [
'surname' => 'Updated Surname',
'christian_name' => 'Updated Name',
'naturalization' => [
'date_of_naturalisation' => '2000-01-01',
'no_of_cert' => 'CERT123',
'issued_at' => 'Darwin',
],
'internment' => [
'corps_issued' => 'Test Corps',
'interned_in' => 'Test Location',
],
];
$response = $this->putJson("/api/persons/{$person->person_id}", $updateData);
$response->assertStatus(200)
->assertJsonStructure([
'success',
'data',
'message',
])
->assertJson([
'success' => true,
'message' => 'Person updated successfully',
]);
$this->assertDatabaseHas('person', [
'person_id' => $person->person_id,
'surname' => 'Updated Surname',
'christian_name' => 'Updated Name',
]);
$this->assertDatabaseHas('naturalization', [
'person_id' => $person->person_id,
'date_of_naturalisation' => '2000-01-01',
]);
$this->assertDatabaseHas('internment', [
'person_id' => $person->person_id,
'corps_issued' => 'Test Corps',
]);
}
/**
* Test deleting a person and related entities.
*/
public function test_can_delete_person_and_related_entities(): void
{
$person = Person::factory()->create();
// Create related records
$person->migration()->create([
'date_of_arrival_aus' => '1950-01-01',
]);
$person->family()->create([
'names_of_parents' => 'Test Parents',
]);
$response = $this->deleteJson("/api/persons/{$person->person_id}");
$response->assertStatus(200)
->assertJson([
'success' => true,
'message' => 'Person deleted successfully',
]);
// Since we're using soft deletes, check that the records are soft deleted
$this->assertSoftDeleted('person', ['person_id' => $person->person_id]);
$this->assertSoftDeleted('migration', ['person_id' => $person->person_id]);
$this->assertSoftDeleted('family', ['person_id' => $person->person_id]);
}
}