diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 238e6248a1..685402b618 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -784,7 +784,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId') if ($membership->getAttribute('confirm')) { // Count only confirmed members $team = $projectDB->updateDocument(\array_merge($team->getArrayCopy(), [ - 'sum' => $team->getAttribute('sum', 0) - 1, + 'sum' => \max($team->getAttribute('sum', 0) - 1, 0), // Ensure that sum >= 0 ])); } diff --git a/app/workers/deletes.php b/app/workers/deletes.php index cda60b78e5..5316783c49 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -31,8 +31,8 @@ class DeletesV1 } public function perform() - { - $projectId = $this->args['projectId']; + { + $projectId = isset($this->args['projectId']) ? $this->args['projectId'] : ''; $type = $this->args['type']; switch (strval($type)) { @@ -127,11 +127,22 @@ class DeletesV1 } } - // Delete Memberships + // Delete Memberships and decrement team membership counts $this->deleteByGroup([ '$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS, 'userId='.$document->getId(), - ], $this->getProjectDB($projectId)); + ], $this->getProjectDB($projectId), function(Document $document) use ($projectId) { + + if ($document->getAttribute('confirm')) { // Count only confirmed members + $teamId = $document->getAttribute('teamId'); + $team = $this->getProjectDB($projectId)->getDocument($teamId); + if(!$team->isEmpty()) { + $team = $this->getProjectDB($projectId)->updateDocument(\array_merge($team->getArrayCopy(), [ + 'sum' => \max($team->getAttribute('sum', 0) - 1, 0), // Ensure that sum >= 0 + ])); + } + } + }); } protected function deleteExecutionLogs($timestamp) diff --git a/tests/e2e/Services/Teams/TeamsBaseServer.php b/tests/e2e/Services/Teams/TeamsBaseServer.php index 44d75fdb32..3b5958eecb 100644 --- a/tests/e2e/Services/Teams/TeamsBaseServer.php +++ b/tests/e2e/Services/Teams/TeamsBaseServer.php @@ -168,5 +168,55 @@ trait TeamsBaseServer $this->assertEquals(401, $response['headers']['status-code']); + return $data; + } + + /** + * @depends testUpdateMembershipRoles + */ + public function testDeleteUserUpdatesTeamMembershipCount($data) { + $teamUid = $data['teamUid'] ?? ''; + $userUid = $data['userUid'] ?? ''; + + /** Get Team Count */ + $response = $this->client->call(Client::METHOD_GET, '/teams/'.$teamUid, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertEquals('Arsenal', $response['body']['name']); + $this->assertEquals(1, $response['body']['sum']); + $this->assertIsInt($response['body']['sum']); + $this->assertIsInt($response['body']['dateCreated']); + + + /** Delete User */ + $user = $this->client->call(Client::METHOD_DELETE, '/users/' . $userUid, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals($user['headers']['status-code'], 204); + + /** Wait for deletes worker to delete membership and update team membership count */ + sleep(5); + + /** Get Team Count */ + $response = $this->client->call(Client::METHOD_GET, '/teams/'.$teamUid, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertEquals('Arsenal', $response['body']['name']); + $this->assertEquals(0, $response['body']['sum']); + $this->assertIsInt($response['body']['sum']); + $this->assertIsInt($response['body']['dateCreated']); + } } \ No newline at end of file