From 075253c06a06194d6fba59a5b04a69b1a20ec790 Mon Sep 17 00:00:00 2001 From: IanM Date: Fri, 17 Oct 2025 08:25:06 +0100 Subject: [PATCH 01/10] fix: type error on delete endpoint --- src/Api/UserResourceDeleteEndpoint.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Api/UserResourceDeleteEndpoint.php b/src/Api/UserResourceDeleteEndpoint.php index a2c2d6f..da22bff 100644 --- a/src/Api/UserResourceDeleteEndpoint.php +++ b/src/Api/UserResourceDeleteEndpoint.php @@ -32,7 +32,7 @@ public function __construct( public function __invoke(Endpoint\Delete $endpoint): Endpoint\Delete { - return $endpoint->action(function (User $user, Context $context) use ($endpoint) { + return $endpoint->action(function (Context $context) use ($endpoint) { $model = $context->model; /** @var AbstractResource $resource */ From 719c5fee2bfb3c3fc69fa42f370da30d07d407b9 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Fri, 17 Oct 2025 07:25:17 +0000 Subject: [PATCH 02/10] Apply fixes from StyleCI --- src/Extend/UserData.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Extend/UserData.php b/src/Extend/UserData.php index 1187710..95d50cb 100644 --- a/src/Extend/UserData.php +++ b/src/Extend/UserData.php @@ -20,7 +20,7 @@ class UserData implements ExtenderInterface protected array $removeTypes = []; protected array $removeUserColumns = []; - public function extend(Container $container, Extension $extension = null): void + public function extend(Container $container, ?Extension $extension = null): void { foreach ($this->types as $type) { DataProcessor::addType($type, $extension?->getId()); From d606eb0b664599143ecab727e8a03a47ecb159a0 Mon Sep 17 00:00:00 2001 From: IanM Date: Fri, 17 Oct 2025 08:26:30 +0100 Subject: [PATCH 03/10] chore: remove php versions --- .github/workflows/backend.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index dd3fce9..d4b75c8 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -8,6 +8,5 @@ jobs: with: enable_backend_testing: true enable_phpstan: true - php_versions: '["8.0", "8.1", "8.2", "8.3"]' backend_directory: . From 30d13d0c3fcf0d0471efd54819ff9c0ef4288409 Mon Sep 17 00:00:00 2001 From: IanM Date: Fri, 17 Oct 2025 19:06:56 +0100 Subject: [PATCH 04/10] fix: cancel erasure tests --- tests/integration/api/CancelErasureTest.php | 42 ++++++++------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/tests/integration/api/CancelErasureTest.php b/tests/integration/api/CancelErasureTest.php index 1d967aa..17392cf 100644 --- a/tests/integration/api/CancelErasureTest.php +++ b/tests/integration/api/CancelErasureTest.php @@ -18,6 +18,7 @@ use Flarum\Testing\integration\TestCase; use Flarum\User\User; use PHPUnit\Framework\Attributes\Test; +use Psr\Http\Message\ResponseInterface; class CancelErasureTest extends TestCase { @@ -58,12 +59,19 @@ public function setUp(): void $this->extension('flarum-gdpr'); } + public function cancelErasureRequest(int $userId, ?int $actorId): ResponseInterface + { + return $this->send( + $this->request('POST', "/api/user-erasure-requests/{$userId}/cancel", [ + 'authenticatedAs' => $actorId, + ]) + ); + } + #[Test] public function guest_cannot_cancel_unconfirmed_erasure_request() { - $response = $this->send( - $this->request('DELETE', '/api/user-erasure-requests/1') - ); + $response = $this->cancelErasureRequest(1, null); $this->assertEquals(401, $response->getStatusCode()); } @@ -71,9 +79,7 @@ public function guest_cannot_cancel_unconfirmed_erasure_request() #[Test] public function guest_cannot_cancel_confirmed_erasure_request() { - $response = $this->send( - $this->request('DELETE', '/api/user-erasure-requests/2') - ); + $response = $this->cancelErasureRequest(2, null); $this->assertEquals(401, $response->getStatusCode()); } @@ -81,11 +87,7 @@ public function guest_cannot_cancel_confirmed_erasure_request() #[Test] public function user_can_cancel_own_unconfirmed_erasure_request() { - $response = $this->send( - $this->request('DELETE', '/api/user-erasure-requests/1', [ - 'authenticatedAs' => 4, - ]) - ); + $response = $this->cancelErasureRequest(1, 4); $this->assertEquals(204, $response->getStatusCode()); @@ -102,11 +104,7 @@ public function user_can_cancel_own_unconfirmed_erasure_request() #[Test] public function user_can_cancel_own_confirmed_erasure_request() { - $response = $this->send( - $this->request('DELETE', '/api/user-erasure-requests/2', [ - 'authenticatedAs' => 5, - ]) - ); + $response = $this->cancelErasureRequest(2, 5); $this->assertEquals(204, $response->getStatusCode()); @@ -123,11 +121,7 @@ public function user_can_cancel_own_confirmed_erasure_request() #[Test] public function user_cannot_cancel_others_erasure_request() { - $response = $this->send( - $this->request('DELETE', '/api/user-erasure-requests/1', [ - 'authenticatedAs' => 5, - ]) - ); + $response = $this->cancelErasureRequest(1, 5); $this->assertEquals(403, $response->getStatusCode()); } @@ -135,11 +129,7 @@ public function user_cannot_cancel_others_erasure_request() #[Test] public function moderator_can_cancel_others_erasure_request() { - $response = $this->send( - $this->request('DELETE', '/api/user-erasure-requests/1', [ - 'authenticatedAs' => 3, - ]) - ); + $response = $this->cancelErasureRequest(1, 3); $this->assertEquals(204, $response->getStatusCode()); From 36e6255d3f42ec32c81a1b97829743f4eb8c98a9 Mon Sep 17 00:00:00 2001 From: IanM Date: Fri, 17 Oct 2025 20:02:48 +0100 Subject: [PATCH 05/10] fix: delete user tests --- tests/integration/api/DeleteUserTest.php | 42 +++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/tests/integration/api/DeleteUserTest.php b/tests/integration/api/DeleteUserTest.php index ee18ad2..855ebf3 100644 --- a/tests/integration/api/DeleteUserTest.php +++ b/tests/integration/api/DeleteUserTest.php @@ -53,15 +53,40 @@ public function delete_user_endpoint_is_processed_by_this_extension() $this->assertEquals(ErasureRequest::STATUS_MANUAL, $user->erasureRequest->status); } + #[Test] + public function delete_user_endpoint_uses_default_when_no_mode_provided() + { + $response = $this->send( + $this->request( + 'DELETE', + '/api/users/2', + [ + 'authenticatedAs' => 1, + 'json' => [] + ] + ) + ); + + $this->assertEquals(204, $response->getStatusCode()); + + $user = User::query()->where('id', 2)->with('erasureRequest')->first(); + $this->assertNotNull($user); + $this->assertEquals("Anonymous{$user->erasureRequest->id}", $user->username); + $this->assertEquals(ErasureRequest::STATUS_MANUAL, $user->erasureRequest->status); + } + #[Test] public function delete_user_endpoint_can_be_called_with_anonymization_mode() { $response = $this->send( $this->request( 'DELETE', - '/api/users/2/gdpr/'.ErasureRequest::MODE_ANONYMIZATION, + '/api/users/2', [ 'authenticatedAs' => 1, + 'json' => [ + 'gdprMode' => ErasureRequest::MODE_ANONYMIZATION, + ] ] ) ); @@ -80,9 +105,12 @@ public function delete_user_endpoint_with_deletion_mode_not_enabled_by_default() $response = $this->send( $this->request( 'DELETE', - '/api/users/2/gdpr/'.ErasureRequest::MODE_DELETION, + '/api/users/2', [ 'authenticatedAs' => 1, + 'json' => [ + 'gdprMode' => ErasureRequest::MODE_DELETION, + ] ] ) ); @@ -103,9 +131,12 @@ public function delete_user_endpoint_can_be_called_with_deletion_mode_enabled() $response = $this->send( $this->request( 'DELETE', - '/api/users/2/gdpr/'.ErasureRequest::MODE_DELETION, + '/api/users/2', [ 'authenticatedAs' => 1, + 'json' => [ + 'gdprMode' => ErasureRequest::MODE_DELETION, + ] ] ) ); @@ -122,9 +153,12 @@ public function invalid_erasure_mode_throws_validation_error() $response = $this->send( $this->request( 'DELETE', - '/api/users/2/gdpr/invalid-mode', + '/api/users/2', [ 'authenticatedAs' => 1, + 'json' => [ + 'gdprMode' => 'invalid-mode', + ] ] ) ); From 35272316a42c05c3740c57abb0ca7c8b1e399414 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Fri, 17 Oct 2025 19:03:10 +0000 Subject: [PATCH 06/10] Apply fixes from StyleCI --- tests/integration/api/DeleteUserTest.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/integration/api/DeleteUserTest.php b/tests/integration/api/DeleteUserTest.php index 855ebf3..bcc1058 100644 --- a/tests/integration/api/DeleteUserTest.php +++ b/tests/integration/api/DeleteUserTest.php @@ -62,7 +62,7 @@ public function delete_user_endpoint_uses_default_when_no_mode_provided() '/api/users/2', [ 'authenticatedAs' => 1, - 'json' => [] + 'json' => [], ] ) ); @@ -84,9 +84,9 @@ public function delete_user_endpoint_can_be_called_with_anonymization_mode() '/api/users/2', [ 'authenticatedAs' => 1, - 'json' => [ + 'json' => [ 'gdprMode' => ErasureRequest::MODE_ANONYMIZATION, - ] + ], ] ) ); @@ -108,9 +108,9 @@ public function delete_user_endpoint_with_deletion_mode_not_enabled_by_default() '/api/users/2', [ 'authenticatedAs' => 1, - 'json' => [ + 'json' => [ 'gdprMode' => ErasureRequest::MODE_DELETION, - ] + ], ] ) ); @@ -134,9 +134,9 @@ public function delete_user_endpoint_can_be_called_with_deletion_mode_enabled() '/api/users/2', [ 'authenticatedAs' => 1, - 'json' => [ + 'json' => [ 'gdprMode' => ErasureRequest::MODE_DELETION, - ] + ], ] ) ); @@ -156,9 +156,9 @@ public function invalid_erasure_mode_throws_validation_error() '/api/users/2', [ 'authenticatedAs' => 1, - 'json' => [ + 'json' => [ 'gdprMode' => 'invalid-mode', - ] + ], ] ) ); From 75323bf62311ce6b3ad8398ec861ce46d0231457 Mon Sep 17 00:00:00 2001 From: IanM Date: Fri, 17 Oct 2025 20:13:26 +0100 Subject: [PATCH 07/10] fix: list datatype tests --- tests/integration/api/ListDataTypesControllerTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/api/ListDataTypesControllerTest.php b/tests/integration/api/ListDataTypesControllerTest.php index 15d0d3c..c03899d 100644 --- a/tests/integration/api/ListDataTypesControllerTest.php +++ b/tests/integration/api/ListDataTypesControllerTest.php @@ -36,7 +36,7 @@ public function setUp(): void public function non_admin_cannot_list_types() { $response = $this->send( - $this->request('GET', '/api/gdpr/datatypes', ['authenticatedAs' => 2]) + $this->request('GET', '/api/gdpr-datatypes', ['authenticatedAs' => 2]) ); $this->assertEquals(403, $response->getStatusCode()); @@ -46,7 +46,7 @@ public function non_admin_cannot_list_types() public function admin_can_list_types() { $response = $this->send( - $this->request('GET', '/api/gdpr/datatypes', ['authenticatedAs' => 1]) + $this->request('GET', '/api/gdpr-datatypes', ['authenticatedAs' => 1]) ); $this->assertEquals(200, $response->getStatusCode()); From bb8fd4130fd9a1aa5b89810277ab886bc7cd0bd1 Mon Sep 17 00:00:00 2001 From: IanM Date: Fri, 17 Oct 2025 20:45:14 +0100 Subject: [PATCH 08/10] fix: process erasure tests --- tests/integration/api/ProcessErasureTest.php | 56 +++++++------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/tests/integration/api/ProcessErasureTest.php b/tests/integration/api/ProcessErasureTest.php index 39ad097..d0b3030 100644 --- a/tests/integration/api/ProcessErasureTest.php +++ b/tests/integration/api/ProcessErasureTest.php @@ -115,17 +115,15 @@ public function authorized_user_cannot_process_unconfirmed_request() 'json' => [ 'data' => [ 'attributes' => [ - 'processor_comment' => 'I am trying to process this request', - 'meta' => [ - 'mode' => ErasureRequest::MODE_DELETION, - ], + 'processorComment' => 'I am trying to process this request', + 'processedMode' => ErasureRequest::MODE_DELETION, ], ], ], ]) ); - $this->assertEquals(422, $response->getStatusCode()); + $this->assertEquals(403, $response->getStatusCode()); } #[Test] @@ -139,10 +137,8 @@ public function authorized_user_can_process_confirmed_erasure_request_in_deletio 'json' => [ 'data' => [ 'attributes' => [ - 'processor_comment' => 'I have processed this request', - 'meta' => [ - 'mode' => ErasureRequest::MODE_DELETION, - ], + 'processorComment' => 'I have processed this request', + 'processedMode' => ErasureRequest::MODE_DELETION, ], ], ], @@ -169,10 +165,8 @@ public function authorized_user_can_process_confirmed_erasure_request_in_anonymi 'json' => [ 'data' => [ 'attributes' => [ - 'processor_comment' => 'I have processed this request', - 'meta' => [ - 'mode' => ErasureRequest::MODE_ANONYMIZATION, - ], + 'processorComment' => 'I have processed this request', + 'processedMode' => ErasureRequest::MODE_ANONYMIZATION, ], ], ], @@ -208,10 +202,8 @@ public function anonymization_with_custom_username_works() 'json' => [ 'data' => [ 'attributes' => [ - 'processor_comment' => 'I have processed this request', - 'meta' => [ - 'mode' => ErasureRequest::MODE_ANONYMIZATION, - ], + 'processorComment' => 'I have processed this request', + 'processedMode' => ErasureRequest::MODE_ANONYMIZATION, ], ], ], @@ -236,10 +228,8 @@ public function authorized_user_cannot_process_confirmed_erasure_request_in_anon 'json' => [ 'data' => [ 'attributes' => [ - 'processor_comment' => 'I have processed this request', - 'meta' => [ - 'mode' => ErasureRequest::MODE_ANONYMIZATION, - ], + 'processorComment' => 'I have processed this request', + 'processedMode' => ErasureRequest::MODE_ANONYMIZATION, ], ], ], @@ -260,10 +250,8 @@ public function authorized_user_cannot_process_confirmed_erasure_request_in_dele 'json' => [ 'data' => [ 'attributes' => [ - 'processor_comment' => 'I have processed this request', - 'meta' => [ - 'mode' => ErasureRequest::MODE_DELETION, - ], + 'processorComment' => 'I have processed this request', + 'processedMode' => ErasureRequest::MODE_DELETION, ], ], ], @@ -291,10 +279,8 @@ public function user_is_anonymized_when_nicknames_is_enabled() 'json' => [ 'data' => [ 'attributes' => [ - 'processor_comment' => 'I have processed this request', - 'meta' => [ - 'mode' => ErasureRequest::MODE_ANONYMIZATION, - ], + 'processorComment' => 'I have processed this request', + 'processedMode' => ErasureRequest::MODE_ANONYMIZATION, ], ], ], @@ -320,20 +306,14 @@ public function cancelled_erasure_requests_are_not_processed() 'json' => [ 'data' => [ 'attributes' => [ - 'processor_comment' => 'I have processed this request', - 'meta' => [ - 'mode' => ErasureRequest::MODE_DELETION, - ], + 'processorComment' => 'I have processed this request', + 'processedMode' => ErasureRequest::MODE_DELETION, ], ], ], ]) ); - $this->assertEquals(422, $response->getStatusCode()); - - $data = json_decode($response->getBody()->getContents(), true); - - $this->assertEquals('Erasure request is cancelled.', $data['errors'][0]['detail']); + $this->assertEquals(403, $response->getStatusCode()); } } From 319ad1e93a05d9e4494045ec909814e0a9398adb Mon Sep 17 00:00:00 2001 From: IanM Date: Fri, 17 Oct 2025 21:25:06 +0100 Subject: [PATCH 09/10] fix: request erasure request tests --- tests/integration/api/RequestErasureTest.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/integration/api/RequestErasureTest.php b/tests/integration/api/RequestErasureTest.php index d433b1b..877f612 100644 --- a/tests/integration/api/RequestErasureTest.php +++ b/tests/integration/api/RequestErasureTest.php @@ -141,9 +141,7 @@ public function normal_user_can_request_erasure_and_recieves_notification_to_con $this->assertNull($erasureRequest->processed_at); $this->assertNull($erasureRequest->processed_mode); - $notification = Notification::query()->where('user_id', 2)->where('type', 'gdpr_erasure_confirm')->orderBy('id', 'desc')->first(); - - $this->assertNotNull($notification); + // TODO: Check that email was sent } #[Test] @@ -191,9 +189,7 @@ public function user_can_request_erasure_without_giving_reason() $this->assertNull($erasureRequest->processed_at); $this->assertNull($erasureRequest->processed_mode); - $notification = Notification::query()->where('user_id', 2)->where('type', 'gdpr_erasure_confirm')->orderBy('id', 'desc')->first(); - - $this->assertNotNull($notification); + // TODO: Check that email was sent } #[Test] From 3ab42e7dac6516a24c8698dfd031c6bcff346392 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Fri, 17 Oct 2025 20:25:17 +0000 Subject: [PATCH 10/10] Apply fixes from StyleCI --- tests/integration/api/ProcessErasureTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/api/ProcessErasureTest.php b/tests/integration/api/ProcessErasureTest.php index d0b3030..89a92b1 100644 --- a/tests/integration/api/ProcessErasureTest.php +++ b/tests/integration/api/ProcessErasureTest.php @@ -138,7 +138,7 @@ public function authorized_user_can_process_confirmed_erasure_request_in_deletio 'data' => [ 'attributes' => [ 'processorComment' => 'I have processed this request', - 'processedMode' => ErasureRequest::MODE_DELETION, + 'processedMode' => ErasureRequest::MODE_DELETION, ], ], ],