438 lines
17 KiB
PHP
438 lines
17 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 MigrantPhotoUpdateTest 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 removing photos during migrant update.
|
|
*/
|
|
public function test_can_remove_photos_during_migrant_update(): void
|
|
{
|
|
// Create fake storage disk for testing
|
|
Storage::fake('public');
|
|
|
|
// 1. First create a migrant with multiple photos
|
|
// Create test photo files
|
|
$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'],
|
|
'main_photo_index' => 0, // 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);
|
|
|
|
// Get the created person ID
|
|
$personId = $response->json('data.person.person_id');
|
|
|
|
// Get all photos for this person
|
|
$photos = Photo::where('person_id', $personId)->get();
|
|
|
|
// Confirm we have 3 photos
|
|
$this->assertEquals(3, $photos->count());
|
|
|
|
// Get IDs of the photos we want to remove
|
|
$photoToRemove1 = $photos[1]->id; // Second photo
|
|
$photoToRemove2 = $photos[2]->id; // Third photo
|
|
|
|
// 2. Now update the migrant and remove two photos
|
|
// Create an array of photos to remove
|
|
$photosToRemove = [$photoToRemove1, $photoToRemove2];
|
|
|
|
$updateData = [
|
|
'surname' => 'Updated Surname',
|
|
'remove_photos' => $photosToRemove
|
|
];
|
|
|
|
$response = $this->putJson("/api/migrants/{$personId}", $updateData);
|
|
|
|
// Assert the response is successful
|
|
$response->assertStatus(200)
|
|
->assertJson([
|
|
'success' => true,
|
|
'message' => 'Person updated successfully',
|
|
]);
|
|
|
|
// Assert that only one photo remains (the profile photo)
|
|
$this->assertEquals(1, Photo::where('person_id', $personId)->count());
|
|
|
|
// Assert the removed photos no longer exist in the database
|
|
$this->assertDatabaseMissing('photos', ['id' => $photoToRemove1]);
|
|
$this->assertDatabaseMissing('photos', ['id' => $photoToRemove2]);
|
|
|
|
// Check that the remaining photo is still the profile photo
|
|
$remainingPhoto = Photo::where('person_id', $personId)->first();
|
|
$this->assertTrue($remainingPhoto->is_profile_photo);
|
|
$this->assertEquals('First photo', $remainingPhoto->caption);
|
|
}
|
|
|
|
/**
|
|
* Test updating migrant with new photos while removing existing ones.
|
|
*/
|
|
public function test_can_update_migrant_with_new_photos_while_removing_existing(): void
|
|
{
|
|
// Create fake storage disk for testing
|
|
Storage::fake('public');
|
|
|
|
// 1. First create a migrant with multiple photos
|
|
$photo1 = UploadedFile::fake()->create('photo1.jpg', 100, 'image/jpeg');
|
|
$photo2 = UploadedFile::fake()->create('photo2.jpg', 100, 'image/jpeg');
|
|
|
|
$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),
|
|
'photos' => [$photo1, $photo2],
|
|
'captions' => ['Photo One', 'Photo Two'],
|
|
'main_photo_index' => 0,
|
|
];
|
|
|
|
$response = $this->postJson('/api/migrants', $migrantData);
|
|
$response->assertStatus(201);
|
|
|
|
$personId = $response->json('data.person.person_id');
|
|
$photos = Photo::where('person_id', $personId)->get();
|
|
$this->assertEquals(2, $photos->count());
|
|
|
|
// Get ID of the photo we want to remove
|
|
$photoToRemove = $photos[1]->id; // Second photo
|
|
|
|
// 2. Update the migrant: remove one photo, add new ones, and change profile photo
|
|
$newPhoto1 = UploadedFile::fake()->create('new1.jpg', 100, 'image/jpeg');
|
|
$newPhoto2 = UploadedFile::fake()->create('new2.jpg', 100, 'image/jpeg');
|
|
|
|
$updateData = [
|
|
'christian_name' => 'Updated Name',
|
|
'photos' => [$newPhoto1, $newPhoto2],
|
|
'captions' => ['New Photo 1', 'New Photo 2'],
|
|
'main_photo_index' => 0, // Set the first new photo as profile
|
|
'remove_photos' => [$photoToRemove]
|
|
];
|
|
|
|
$response = $this->putJson("/api/migrants/{$personId}", $updateData);
|
|
|
|
$response->assertStatus(200)
|
|
->assertJson([
|
|
'success' => true,
|
|
'message' => 'Person updated successfully',
|
|
]);
|
|
|
|
// Assert we now have 3 photos (1 original + 2 new - 1 removed)
|
|
$this->assertEquals(3, Photo::where('person_id', $personId)->count());
|
|
|
|
// Assert the removed photo no longer exists
|
|
$this->assertDatabaseMissing('photos', ['id' => $photoToRemove]);
|
|
|
|
// Assert the new profile photo is set correctly
|
|
$newPhotos = Photo::where('person_id', $personId)
|
|
->where('caption', 'New Photo 1')
|
|
->get();
|
|
|
|
$this->assertEquals(1, $newPhotos->count());
|
|
$this->assertTrue($newPhotos->first()->is_profile_photo);
|
|
|
|
// Assert the old profile photo is no longer the profile
|
|
$oldProfilePhoto = Photo::where('person_id', $personId)
|
|
->where('caption', 'Photo One')
|
|
->first();
|
|
|
|
$this->assertFalse($oldProfilePhoto->is_profile_photo);
|
|
}
|
|
|
|
/**
|
|
* Test that when the profile photo is removed, another photo is set as profile.
|
|
*/
|
|
public function test_when_profile_photo_is_removed_another_is_set_as_profile(): void
|
|
{
|
|
// Create fake storage disk for testing
|
|
Storage::fake('public');
|
|
|
|
// 1. First create a migrant with multiple photos
|
|
$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');
|
|
|
|
$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),
|
|
'photos' => [$photo1, $photo2, $photo3],
|
|
'captions' => ['Photo One', 'Photo Two', 'Photo Three'],
|
|
'main_photo_index' => 0, // First photo is profile
|
|
];
|
|
|
|
$response = $this->postJson('/api/migrants', $migrantData);
|
|
$response->assertStatus(201);
|
|
|
|
$personId = $response->json('data.person.person_id');
|
|
$photos = Photo::where('person_id', $personId)->get();
|
|
|
|
// Get ID of the profile photo we want to remove
|
|
$profilePhotoId = $photos->where('is_profile_photo', true)->first()->id;
|
|
|
|
// 2. Update the migrant and remove the profile photo
|
|
$updateData = [
|
|
'remove_photos' => [$profilePhotoId]
|
|
];
|
|
|
|
$response = $this->putJson("/api/migrants/{$personId}", $updateData);
|
|
|
|
$response->assertStatus(200);
|
|
|
|
// Assert we now have 2 photos
|
|
$this->assertEquals(2, Photo::where('person_id', $personId)->count());
|
|
|
|
// Assert that a new profile photo was automatically set
|
|
$this->assertEquals(1, Photo::where('person_id', $personId)
|
|
->where('is_profile_photo', true)
|
|
->count());
|
|
|
|
// Assert the removed photo no longer exists
|
|
$this->assertDatabaseMissing('photos', ['id' => $profilePhotoId]);
|
|
}
|
|
|
|
/**
|
|
* Test that removing non-profile photos doesn't affect the profile photo.
|
|
*/
|
|
public function test_removing_non_profile_photos_preserves_profile_photo(): void
|
|
{
|
|
// Create fake storage disk for testing
|
|
Storage::fake('public');
|
|
|
|
// 1. First create a migrant with multiple photos
|
|
// Create test photo files
|
|
$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' => ['Profile photo', 'Second photo', 'Third photo'],
|
|
'main_photo_index' => 0, // 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);
|
|
|
|
// Get the created person ID
|
|
$personId = $response->json('data.person.person_id');
|
|
|
|
// Get all photos for this person
|
|
$photos = Photo::where('person_id', $personId)->get();
|
|
|
|
// Confirm we have 3 photos
|
|
$this->assertEquals(3, $photos->count());
|
|
|
|
// Get the profile photo ID
|
|
$profilePhotoId = null;
|
|
$photoToRemove1 = null;
|
|
$photoToRemove2 = null;
|
|
|
|
foreach ($photos as $photo) {
|
|
if ($photo->is_profile_photo) {
|
|
$profilePhotoId = $photo->id;
|
|
} else {
|
|
if ($photoToRemove1 === null) {
|
|
$photoToRemove1 = $photo->id;
|
|
} else {
|
|
$photoToRemove2 = $photo->id;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ensure we have a profile photo and two non-profile photos
|
|
$this->assertNotNull($profilePhotoId);
|
|
$this->assertNotNull($photoToRemove1);
|
|
$this->assertNotNull($photoToRemove2);
|
|
|
|
// 2. Now update the migrant and remove the non-profile photos
|
|
// Create an array of photos to remove
|
|
$photosToRemove = [$photoToRemove1, $photoToRemove2];
|
|
|
|
$updateData = [
|
|
'surname' => 'Updated Surname',
|
|
'remove_photos' => $photosToRemove
|
|
];
|
|
|
|
$response = $this->putJson("/api/migrants/{$personId}", $updateData);
|
|
|
|
// Assert the response is successful
|
|
$response->assertStatus(200)
|
|
->assertJson([
|
|
'success' => true,
|
|
'message' => 'Person updated successfully',
|
|
]);
|
|
|
|
// Assert that only one photo remains (the profile photo)
|
|
$this->assertEquals(1, Photo::where('person_id', $personId)->count());
|
|
|
|
// Assert the removed photos no longer exist in the database
|
|
$this->assertDatabaseMissing('photos', ['id' => $photoToRemove1]);
|
|
$this->assertDatabaseMissing('photos', ['id' => $photoToRemove2]);
|
|
|
|
// Check that the profile photo is still the same and marked as profile
|
|
$remainingPhoto = Photo::where('person_id', $personId)->first();
|
|
$this->assertEquals($profilePhotoId, $remainingPhoto->id);
|
|
$this->assertTrue($remainingPhoto->is_profile_photo);
|
|
$this->assertEquals('Profile photo', $remainingPhoto->caption);
|
|
}
|
|
|
|
/**
|
|
* Test adding new photos and setting one as the profile photo.
|
|
*/
|
|
public function test_adding_new_photos_and_setting_as_profile(): void
|
|
{
|
|
// Create fake storage disk for testing
|
|
Storage::fake('public');
|
|
|
|
// 1. First create a migrant with one photo
|
|
// Create test photo file
|
|
$initialPhoto = UploadedFile::fake()->create('initial.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 initial photo
|
|
'photos' => [$initialPhoto],
|
|
'captions' => ['Initial photo'],
|
|
'main_photo_index' => 0, // Set as profile
|
|
];
|
|
|
|
// Make the API request to create a migrant with a photo
|
|
$response = $this->postJson('/api/migrants', $migrantData);
|
|
|
|
// Assert the response is successful
|
|
$response->assertStatus(201);
|
|
|
|
// Get the created person ID
|
|
$personId = $response->json('data.person.person_id');
|
|
|
|
// Confirm we have 1 photo and it's the profile photo
|
|
$initialPhotos = Photo::where('person_id', $personId)->get();
|
|
$this->assertEquals(1, $initialPhotos->count());
|
|
$this->assertTrue($initialPhotos[0]->is_profile_photo);
|
|
|
|
// 2. Now update the migrant with new photos, setting one as profile
|
|
$newPhoto1 = UploadedFile::fake()->create('new1.jpg', 100, 'image/jpeg');
|
|
$newPhoto2 = UploadedFile::fake()->create('new2.jpg', 100, 'image/jpeg');
|
|
|
|
$updateData = [
|
|
'surname' => 'Updated Surname',
|
|
// Add new photos
|
|
'photos' => [$newPhoto1, $newPhoto2],
|
|
'captions' => ['New photo 1', 'New photo 2 (profile)'],
|
|
'main_photo_index' => 1 // Set the second new photo as profile
|
|
];
|
|
|
|
$response = $this->putJson("/api/migrants/{$personId}", $updateData);
|
|
|
|
// Assert the response is successful
|
|
$response->assertStatus(200)
|
|
->assertJson([
|
|
'success' => true,
|
|
'message' => 'Person updated successfully',
|
|
]);
|
|
|
|
// Assert that we now have 3 photos (1 initial + 2 new)
|
|
$this->assertEquals(3, Photo::where('person_id', $personId)->count());
|
|
|
|
// Assert that exactly one photo is marked as profile
|
|
$this->assertEquals(1, Photo::where('person_id', $personId)
|
|
->where('is_profile_photo', true)
|
|
->count());
|
|
|
|
// Assert that the profile photo is the one we designated
|
|
$profilePhoto = Photo::where('person_id', $personId)
|
|
->where('is_profile_photo', true)
|
|
->first();
|
|
$this->assertEquals('New photo 2 (profile)', $profilePhoto->caption);
|
|
|
|
// Assert that the original photo is no longer the profile photo
|
|
$originalPhoto = Photo::where('person_id', $personId)
|
|
->where('caption', 'Initial photo')
|
|
->first();
|
|
$this->assertFalse($originalPhoto->is_profile_photo);
|
|
}
|
|
}
|