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

181 lines
6.5 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\User;
use App\Models\Person;
use App\Models\Photo;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class MigrantPhotoTest 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 migrant with multiple photos and setting one as profile.
*/
public function test_can_create_migrant_with_multiple_photos_and_set_profile(): void
{
// Create fake storage disk for testing
Storage::fake('public');
// Create test photo files (using create instead of image to avoid GD dependency)
$photo1 = UploadedFile::fake()->create('photo1.jpg', 100, 'image/jpeg');
$photo2 = UploadedFile::fake()->create('photo2.jpg', 100, 'image/jpeg');
$photo3 = UploadedFile::fake()->create('photo3.jpg', 100, 'image/jpeg');
// Create migrant data
$migrantData = [
'surname' => $this->faker->lastName,
'christian_name' => $this->faker->firstName,
'date_of_birth' => $this->faker->date(),
'place_of_birth' => $this->faker->city,
'occupation' => $this->faker->jobTitle,
'id_card_no' => (string)$this->faker->unique()->randomNumber(6),
'migration' => [
'date_of_arrival_aus' => $this->faker->date(),
'date_of_arrival_nt' => $this->faker->date(),
'arrival_period' => '1950-1960',
],
// Add photos to the request
'photos' => [$photo1, $photo2, $photo3],
'captions' => ['First photo', 'Second photo', 'Third photo'],
'set_as_profile' => 1, // Set the first photo as profile
];
// Make the API request to create a migrant with photos
$response = $this->postJson('/api/migrants', $migrantData);
// Assert the response is successful
$response->assertStatus(201)
->assertJsonStructure([
'success',
'data' => [
'person',
'uploaded_photos',
],
'message',
])
->assertJson([
'success' => true,
'message' => 'Person created successfully',
]);
// Get the created person ID
$personId = $response->json('data.person.person_id');
// Assert that the person was created in the database
$this->assertDatabaseHas('person', [
'surname' => $migrantData['surname'],
'christian_name' => $migrantData['christian_name'],
]);
// Assert that 3 photos were created for this person
$this->assertEquals(3, Photo::where('person_id', $personId)->count());
// Assert that exactly one photo is set as profile
$this->assertEquals(1, Photo::where('person_id', $personId)
->where('is_profile_photo', true)
->count());
// Get the profile photo
$profilePhoto = Photo::where('person_id', $personId)
->where('is_profile_photo', true)
->first();
// Assert that the first photo is the profile (based on caption)
$this->assertEquals('First photo', $profilePhoto->caption);
// Assert that the files were stored in the storage
foreach (Photo::where('person_id', $personId)->get() as $photo) {
Storage::disk('public')->assertExists('photos/' . $personId . '/' . $photo->filename);
}
}
/**
* Test updating the profile photo of an existing migrant.
*/
public function test_can_change_profile_photo(): void
{
// Create fake storage disk for testing
Storage::fake('public');
// Create a migrant
$person = Person::factory()->create();
// Create three photos for this migrant
$photos = [];
$captions = ['Photo 1', 'Photo 2', 'Photo 3'];
for ($i = 0; $i < 3; $i++) {
$filename = "photo{$i}.jpg";
$file = UploadedFile::fake()->create($filename, 100, 'image/jpeg');
// Upload the file to the storage
$path = $file->storeAs("photos/{$person->person_id}", $filename, 'public');
// Create the photo record
$photo = Photo::create([
'person_id' => $person->person_id,
'filename' => $filename,
'original_filename' => $filename,
'file_path' => Storage::url($path),
'mime_type' => 'image/jpeg',
'file_size' => $file->getSize() / 1024,
'caption' => $captions[$i],
'is_profile_photo' => $i === 0 // Make the first one the profile initially
]);
$photos[] = $photo;
}
// Now try to set the second photo as the profile
$response = $this->postJson("/api/migrants/photos/{$photos[1]->id}/set-as-profile");
// Assert response is successful
$response->assertStatus(200)
->assertJson([
'success' => true,
'message' => 'Profile photo set successfully',
]);
// Assert that now the second photo is the profile
$this->assertDatabaseHas('photos', [
'id' => $photos[1]->id,
'is_profile_photo' => true
]);
// Assert that the first photo is no longer the profile
$this->assertDatabaseHas('photos', [
'id' => $photos[0]->id,
'is_profile_photo' => false
]);
// Assert that only one photo is set as profile
$this->assertEquals(1, Photo::where('person_id', $person->person_id)
->where('is_profile_photo', true)
->count());
}
}