mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-16 04:02:15 +01:00
add photo delete logic to user update endpoint
This commit is contained in:
committed by
Constantin Graf
parent
15b5f4b586
commit
15fe8beecc
@@ -49,18 +49,23 @@ class UserController extends Controller
|
|||||||
throw new AuthorizationException;
|
throw new AuthorizationException;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->getPhoto() !== null) {
|
if ($request->hasPhotoKey()) {
|
||||||
$photo = Base64File::decode($request->getPhoto());
|
|
||||||
assert($photo !== null);
|
|
||||||
$extension = Base64File::extension($photo['mime_type']);
|
|
||||||
assert($extension !== null);
|
|
||||||
|
|
||||||
$previousPhotoPath = $user->profile_photo_path;
|
|
||||||
$photoPath = 'profile-photos/'.Str::uuid().'.'.$extension;
|
|
||||||
$photoDisk = (string) config('jetstream.profile_photo_disk', 'public');
|
$photoDisk = (string) config('jetstream.profile_photo_disk', 'public');
|
||||||
|
$previousPhotoPath = $user->profile_photo_path;
|
||||||
|
$newPhoto = $request->getPhoto();
|
||||||
|
|
||||||
Storage::disk($photoDisk)->put($photoPath, $photo['data'], 'public');
|
if ($newPhoto === null) {
|
||||||
$user->profile_photo_path = $photoPath;
|
$user->profile_photo_path = null;
|
||||||
|
} else {
|
||||||
|
$decoded = Base64File::decode($newPhoto);
|
||||||
|
assert($decoded !== null);
|
||||||
|
$extension = Base64File::extension($decoded['mime_type']);
|
||||||
|
assert($extension !== null);
|
||||||
|
|
||||||
|
$photoPath = 'profile-photos/'.Str::uuid().'.'.$extension;
|
||||||
|
Storage::disk($photoDisk)->put($photoPath, $decoded['data'], 'public');
|
||||||
|
$user->profile_photo_path = $photoPath;
|
||||||
|
}
|
||||||
|
|
||||||
if ($previousPhotoPath !== null) {
|
if ($previousPhotoPath !== null) {
|
||||||
Storage::disk($photoDisk)->delete($previousPhotoPath);
|
Storage::disk($photoDisk)->delete($previousPhotoPath);
|
||||||
|
|||||||
@@ -81,8 +81,15 @@ class UserUpdateRequest extends BaseFormRequest
|
|||||||
return $this->has('week_start') ? Weekday::from($this->input('week_start')) : null;
|
return $this->has('week_start') ? Weekday::from($this->input('week_start')) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasPhotoKey(): bool
|
||||||
|
{
|
||||||
|
return $this->has('photo');
|
||||||
|
}
|
||||||
|
|
||||||
public function getPhoto(): ?string
|
public function getPhoto(): ?string
|
||||||
{
|
{
|
||||||
return $this->has('photo') ? (string) $this->input('photo') : null;
|
$value = $this->input('photo');
|
||||||
|
|
||||||
|
return is_string($value) ? $value : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -354,6 +354,75 @@ class UserEndpointTest extends ApiEndpointTestAbstract
|
|||||||
$response->assertJsonValidationErrors(['photo']);
|
$response->assertJsonValidationErrors(['photo']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_update_with_null_photo_deletes_photo_file_and_clears_profile_photo_path(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$data = $this->createUserWithPermission();
|
||||||
|
$photoDisk = (string) config('jetstream.profile_photo_disk', 'public');
|
||||||
|
$photoPath = 'profile-photos/existing.png';
|
||||||
|
Storage::fake($photoDisk);
|
||||||
|
Storage::disk($photoDisk)->put($photoPath, 'photo contents');
|
||||||
|
$data->user->profile_photo_path = $photoPath;
|
||||||
|
$data->user->save();
|
||||||
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->putJson(route('api.v1.users.update', $data->user->getKey()), [
|
||||||
|
'photo' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertSuccessful();
|
||||||
|
$user = $data->user->fresh();
|
||||||
|
$this->assertNull($user->profile_photo_path);
|
||||||
|
Storage::disk($photoDisk)->assertMissing($photoPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_update_with_null_photo_is_a_noop_when_user_has_no_photo(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$data = $this->createUserWithPermission();
|
||||||
|
$photoDisk = (string) config('jetstream.profile_photo_disk', 'public');
|
||||||
|
Storage::fake($photoDisk);
|
||||||
|
$data->user->profile_photo_path = null;
|
||||||
|
$data->user->save();
|
||||||
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->putJson(route('api.v1.users.update', $data->user->getKey()), [
|
||||||
|
'photo' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertSuccessful();
|
||||||
|
$user = $data->user->fresh();
|
||||||
|
$this->assertNull($user->profile_photo_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_update_without_photo_key_leaves_existing_photo_untouched(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$data = $this->createUserWithPermission();
|
||||||
|
$photoDisk = (string) config('jetstream.profile_photo_disk', 'public');
|
||||||
|
$photoPath = 'profile-photos/existing.png';
|
||||||
|
Storage::fake($photoDisk);
|
||||||
|
Storage::disk($photoDisk)->put($photoPath, 'photo contents');
|
||||||
|
$data->user->profile_photo_path = $photoPath;
|
||||||
|
$data->user->save();
|
||||||
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->putJson(route('api.v1.users.update', $data->user->getKey()), [
|
||||||
|
'name' => 'Just A Name Change',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertSuccessful();
|
||||||
|
$user = $data->user->fresh();
|
||||||
|
$this->assertSame($photoPath, $user->profile_photo_path);
|
||||||
|
Storage::disk($photoDisk)->assertExists($photoPath);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_delete_fails_if_given_user_is_not_the_authenticated_user(): void
|
public function test_delete_fails_if_given_user_is_not_the_authenticated_user(): void
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|||||||
Reference in New Issue
Block a user