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); } }