diff --git a/app/Http/Controllers/Api/V2/CollectionController.php b/app/Http/Controllers/Api/V2/CollectionController.php index cd135d913..ec1ddef00 100644 --- a/app/Http/Controllers/Api/V2/CollectionController.php +++ b/app/Http/Controllers/Api/V2/CollectionController.php @@ -504,17 +504,13 @@ public function update(UpdateCollection $request, int $id): JsonResponse $this->checkAccessCollaborators($input, array_column($collHasUsers, 'user_id')); try { - $initCollection = Collection::withTrashed()->where('id', $id)->first(); + $initCollection = Collection::where('id', $id)->first(); // Don't allow us to edit a team-owned Collection via this endpoint if ($initCollection['team_id'] !== null) { throw new UnauthorizedException('Cannot update a team-owned Collection via the individual Collection endpoint'); } - if ($initCollection['status'] === Collection::STATUS_ARCHIVED && !array_key_exists('status', $input)) { - throw new Exception('Cannot update current collection! Status already "ARCHIVED"'); - } - $arrayKeys = [ 'name', 'description', @@ -528,7 +524,7 @@ public function update(UpdateCollection $request, int $id): JsonResponse ]; $array = $this->checkEditArray($input, $arrayKeys); - Collection::where('id', $id)->update($array); + Collection::where('id', $id)->first()->update($array); $datasets = $input['datasets'] ?? []; $this->checkDatasets($id, $datasets, (int)$jwtUser['id']); @@ -551,7 +547,7 @@ public function update(UpdateCollection $request, int $id): JsonResponse // updated_on if (array_key_exists('updated_on', $input)) { - Collection::where('id', $id)->update(['updated_on' => $input['updated_on']]); + Collection::where('id', $id)->first()->update(['updated_on' => $input['updated_on']]); } Auditor::log([ @@ -589,15 +585,6 @@ public function update(UpdateCollection $request, int $id): JsonResponse * description="Edit a collection", * security={{"bearerAuth":{}}}, * @OA\Parameter( - * name="unarchive", - * in="query", - * description="Unarchive a collection", - * @OA\Schema( - * type="string", - * description="instruction to unarchive collection", - * ), - * ), - * @OA\Parameter( * name="id", * in="path", * description="collection id", @@ -685,130 +672,87 @@ public function edit(EditCollection $request, int $id): JsonResponse $this->checkAccessCollaborators($input, array_column($collHasUsers, 'user_id')); try { - if ($request->has('unarchive')) { - $collectionModel = Collection::withTrashed() - ->find($id); + // get initial colleciton + $initCollection = Collection::where('id', $id)->first(); - // Don't allow us to edit a team-owned Collection via this endpoint - if ($collectionModel['team_id'] !== null) { - throw new UnauthorizedException('Cannot update a team-owned Collection via the individual Collection endpoint'); - } - if ($request['status'] !== Collection::STATUS_ARCHIVED) { - if (in_array($request['status'], [ - Collection::STATUS_ACTIVE, Collection::STATUS_DRAFT - ])) { - $collectionModel->status = $request['status']; - $collectionModel->deleted_at = null; - $collectionModel->save(); - - CollectionHasDatasetVersion::withTrashed()->where('collection_id', $id)->restore(); - CollectionHasTool::withTrashed()->where('collection_id', $id)->restore(); - CollectionHasDur::withTrashed()->where('collection_id', $id)->restore(); - CollectionHasPublication::withTrashed()->where('collection_id', $id)->restore(); - - Auditor::log([ - 'user_id' => (int)$jwtUser['id'], - 'action_type' => 'UPDATE', - 'action_name' => class_basename($this) . '@' . __FUNCTION__, - 'description' => 'Personal Collection ' . $id . ' unarchived and marked as ' . strtoupper($request['status']), - ]); - } - } - - return response()->json([ - 'message' => 'success', - 'data' => $this->getCollectionById($id), - ], Config::get('statuscodes.STATUS_OK.code')); - } else { - $arrayKeys = [ - 'name', - 'description', - 'image_link', - 'enabled', - 'public', - 'counter', - 'mongo_object_id', - 'mongo_id', - 'team_id', - 'status', - ]; - $array = $this->checkEditArray($input, $arrayKeys); - - if (array_key_exists('name', $input)) { - $array['name'] = formatCleanInput($input['name']); - } - - // Handle the 'deleted_at' field based on 'status' - if (isset($input['status']) && ($input['status'] === Collection::STATUS_ARCHIVED)) { - $array['deleted_at'] = Carbon::now(); + // Don't allow us to edit a team-owned Collection via this endpoint + if ($initCollection['team_id'] !== null) { + throw new UnauthorizedException('Cannot edit a team-owned Collection via the individual Collection endpoint'); + } - } else { - $array['deleted_at'] = null; - } + $arrayKeys = [ + 'name', + 'description', + 'image_link', + 'enabled', + 'public', + 'counter', + 'mongo_object_id', + 'mongo_id', + 'team_id', + 'status', + ]; + $array = $this->checkEditArray($input, $arrayKeys); - // get initial colleciton - $initCollection = Collection::withTrashed()->where('id', $id)->first(); + if (array_key_exists('name', $input)) { + $array['name'] = formatCleanInput($input['name']); + } - // Don't allow us to edit a team-owned Collection via this endpoint - if ($initCollection['team_id'] !== null) { - throw new UnauthorizedException('Cannot edit a team-owned Collection via the individual Collection endpoint'); - } + //update it + $initCollection->update($array); - //update it - Collection::withTrashed()->where('id', $id)->update($array); - // get updated collection - $updatedCollection = Collection::withTrashed()->where('id', $id)->first(); - // Check and update related datasets and tools etc if the collection is active + // get updated collection + $updatedCollection = Collection::where('id', $id)->first(); + // Check and update related datasets and tools etc if the collection is active - // collaborators - if (array_key_exists('collaborators', $input)) { - $collaborators = (array_key_exists('collaborators', $input)) ? $input['collaborators'] : []; - $this->updateCollectionUsers((int)$id, $collaborators); - } + // collaborators + if (array_key_exists('collaborators', $input)) { + $collaborators = (array_key_exists('collaborators', $input)) ? $input['collaborators'] : []; + $this->updateCollectionUsers((int)$id, $collaborators); + } - if (array_key_exists('datasets', $input)) { - $datasets = $input['datasets']; - $this->checkDatasets($id, $datasets, (int)$jwtUser['id']); - } + if (array_key_exists('datasets', $input)) { + $datasets = $input['datasets']; + $this->checkDatasets($id, $datasets, (int)$jwtUser['id']); + } - if (array_key_exists('tools', $input)) { - $tools = $input['tools']; - $this->checkTools($id, $tools, (int)$jwtUser['id']); - } + if (array_key_exists('tools', $input)) { + $tools = $input['tools']; + $this->checkTools($id, $tools, (int)$jwtUser['id']); + } - if (array_key_exists('dur', $input)) { - $dur = $input['dur']; - $this->checkDurs($id, $dur, (int)$jwtUser['id']); - } + if (array_key_exists('dur', $input)) { + $dur = $input['dur']; + $this->checkDurs($id, $dur, (int)$jwtUser['id']); + } - if (array_key_exists('publications', $input)) { - $publications = $input['publications']; - $this->checkPublications($id, $publications, (int)$jwtUser['id']); - } + if (array_key_exists('publications', $input)) { + $publications = $input['publications']; + $this->checkPublications($id, $publications, (int)$jwtUser['id']); + } - if (array_key_exists('keywords', $input)) { - $keywords = $input['keywords']; - $this->checkKeywords($id, $keywords); - } + if (array_key_exists('keywords', $input)) { + $keywords = $input['keywords']; + $this->checkKeywords($id, $keywords); + } - // add in a team - if (array_key_exists('team_id', $input)) { - Collection::where('id', $id)->update(['team_id' => $input['team_id']]); - } + // add in a team + if (array_key_exists('team_id', $input)) { + $updatedCollection->update(['team_id' => $input['team_id']]); + } - Auditor::log([ - 'user_id' => (int)$jwtUser['id'], - 'action_type' => 'UPDATE', - 'action_name' => class_basename($this) . '@' . __FUNCTION__, - 'description' => 'Personal Collection ' . $id . ' updated', - ]); + Auditor::log([ + 'user_id' => (int)$jwtUser['id'], + 'action_type' => 'UPDATE', + 'action_name' => class_basename($this) . '@' . __FUNCTION__, + 'description' => 'Personal Collection ' . $id . ' updated', + ]); - return response()->json([ - 'message' => 'success', - 'data' => $this->getCollectionById($id), - ], 200); - } + return response()->json([ + 'message' => 'success', + 'data' => $this->getCollectionById($id), + ], 200); } catch (UnauthorizedException $e) { return response()->json([ 'message' => $e->getMessage(), @@ -829,8 +773,8 @@ public function edit(EditCollection $request, int $id): JsonResponse * @OA\Delete( * path="/api/v2/collections/{id}", * tags={"Collections"}, - * summary="Delete a collection", - * description="Delete a collection", + * summary="Soft-delete a collection", + * description="Soft-delete a collection", * security={{"bearerAuth":{}}}, * @OA\Parameter( * name="id", @@ -877,21 +821,13 @@ public function destroy(DeleteCollection $request, int $id): JsonResponse try { $collection = Collection::where(['id' => $id])->first(); - - // Don't allow us to edit a team-owned Collection via this endpoint - if ($collection['team_id'] !== null) { - throw new UnauthorizedException('Cannot delete a team-owned Collection via the individual Collection endpoint'); - } - $initialStatus = $collection->status; if ($collection) { - CollectionHasDatasetVersion::where(['collection_id' => $id])->delete(); - CollectionHasTool::where(['collection_id' => $id])->delete(); - CollectionHasDur::where(['collection_id' => $id])->delete(); - CollectionHasKeyword::where(['collection_id' => $id])->delete(); - CollectionHasPublication::where(['collection_id' => $id])->delete(); - CollectionHasUser::where(['collection_id' => $id])->delete(); - Collection::where(['id' => $id])->update(['status' => Collection::STATUS_ARCHIVED]); - Collection::where(['id' => $id])->delete(); + // Don't allow us to edit a team-owned Collection via this endpoint + if ($collection['team_id'] !== null) { + throw new UnauthorizedException('Cannot delete a team-owned Collection via the individual Collection endpoint'); + } + + $collection->delete(); Auditor::log([ 'user_id' => (int)$jwtUser['id'], @@ -985,7 +921,6 @@ private function getCollectionById(int $collectionId, bool $trimmed = false) */ 'team', ]) - ->withTrashed() ->where(['id' => $collectionId]) ->first(); diff --git a/app/Http/Controllers/Api/V2/UserCollectionController.php b/app/Http/Controllers/Api/V2/UserCollectionController.php index c008c0566..0515eaa00 100644 --- a/app/Http/Controllers/Api/V2/UserCollectionController.php +++ b/app/Http/Controllers/Api/V2/UserCollectionController.php @@ -6,32 +6,23 @@ use Auditor; use Exception; use App\Models\Collection; -use App\Models\Application; -use App\Models\Dur; +use App\Models\CollectionHasUser; use App\Http\Traits\CheckAccess; use App\Http\Traits\CollectionsV2Helpers; -use App\Models\CollectionHasDur; -use App\Http\Traits\IndexElastic; -use App\Models\CollectionHasTool; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use App\Exceptions\NotFoundException; -use App\Models\CollectionHasKeyword; -use App\Models\CollectionHasPublication; use App\Exceptions\UnauthorizedException; use App\Http\Traits\RequestTransformation; -use App\Models\CollectionHasDatasetVersion; use App\Http\Requests\V2\Collection\CreateCollection; use App\Http\Requests\V2\Collection\DeleteCollection; use App\Http\Requests\V2\Collection\EditCollection; use App\Http\Requests\V2\Collection\GetCollection; use App\Http\Requests\V2\Collection\UpdateCollection; -use App\Models\CollectionHasUser; class UserCollectionController extends Controller { - use IndexElastic; use RequestTransformation; use CheckAccess; use CollectionsV2Helpers; @@ -485,10 +476,6 @@ public function store(CreateCollection $request): JsonResponse $collection->update(['updated_on' => $input['updated_on']]); } - if ($collection->status === Collection::STATUS_ACTIVE) { - $this->indexElasticCollections((int) $collection->id); - } - Auditor::log([ 'user_id' => (int)$jwtUser['id'], 'action_type' => 'CREATE', @@ -608,17 +595,13 @@ public function update(UpdateCollection $request, int $userId, int $id): JsonRes $this->checkAccessCollaborators($input, array_column($collHasUsers, 'user_id')); try { - $initCollection = Collection::withTrashed()->where('id', $id)->first(); + $initCollection = Collection::where('id', $id)->first(); // Don't allow us to edit a team-owned Collection via this endpoint if ($initCollection['team_id'] !== null) { throw new UnauthorizedException('Cannot update a team-owned Collection via the individual Collection endpoint'); } - // if ($initCollection['status'] === Collection::STATUS_ARCHIVED && !array_key_exists('status', $input)) { - // throw new Exception('Cannot update current collection! Status already "ARCHIVED"'); - // } - $arrayKeys = [ 'name', 'description', @@ -658,13 +641,6 @@ public function update(UpdateCollection $request, int $userId, int $id): JsonRes Collection::where('id', $id)->update(['updated_on' => $input['updated_on']]); } - $currentCollection = Collection::where('id', $id)->first(); - if ($currentCollection->status === Collection::STATUS_ACTIVE) { - $this->indexElasticCollections((int) $id); - } else { - $this->deleteCollectionFromElastic((int) $id); - } - Auditor::log([ 'user_id' => (int)$jwtUser['id'], 'action_type' => 'UPDATE', @@ -815,7 +791,7 @@ public function edit(EditCollection $request, int $userId, int $id): JsonRespons } //update it - Collection::where('id', $id)->update($array); + $initCollection->update($array); // get updated collection $updatedCollection = Collection::where('id', $id)->first(); // Check and update related datasets and tools etc if the collection is active @@ -853,12 +829,7 @@ public function edit(EditCollection $request, int $userId, int $id): JsonRespons // add in a team if (array_key_exists('team_id', $input)) { - Collection::where('id', $id)->update(['team_id' => $input['team_id']]); - } - if ($updatedCollection->status === Collection::STATUS_ACTIVE) { - $this->indexElasticCollections((int) $id); - } elseif ($initCollection->status === Collection::STATUS_ACTIVE) { - $this->deleteCollectionFromElastic((int) $id); + $updatedCollection->update(['team_id' => $input['team_id']]); } Auditor::log([ @@ -944,21 +915,12 @@ public function destroy(DeleteCollection $request, int $userId, int $id): JsonRe try { $collection = Collection::where(['id' => $id])->first(); - - // Don't allow us to edit a team-owned Collection via this endpoint - if ($collection['team_id'] !== null) { - throw new UnauthorizedException('Cannot delete a team-owned Collection via the individual Collection endpoint'); - } if ($collection) { - CollectionHasDatasetVersion::where(['collection_id' => $id])->delete(); - CollectionHasTool::where(['collection_id' => $id])->delete(); - CollectionHasDur::where(['collection_id' => $id])->delete(); - CollectionHasKeyword::where(['collection_id' => $id])->delete(); - CollectionHasPublication::where(['collection_id' => $id])->delete(); - CollectionHasUser::where(['collection_id' => $id])->delete(); - Collection::where(['id' => $id])->delete(); - - $this->deleteCollectionFromElastic($id); + // Don't allow us to edit a team-owned Collection via this endpoint + if ($collection['team_id'] !== null) { + throw new UnauthorizedException('Cannot delete a team-owned Collection via the individual Collection endpoint'); + } + $collection->delete(); Auditor::log([ 'user_id' => (int)$jwtUser['id'], diff --git a/app/Http/Traits/CollectionsV2Helpers.php b/app/Http/Traits/CollectionsV2Helpers.php index 752431afd..d523ad08d 100644 --- a/app/Http/Traits/CollectionsV2Helpers.php +++ b/app/Http/Traits/CollectionsV2Helpers.php @@ -121,8 +121,7 @@ private function getCollectionActiveById(int $collectionId, bool $trimmed = fals // datasets private function checkDatasets(int $collectionId, array $inDatasets, int $userId = null) { - $collectionHasDatasetVersions = CollectionHasDatasetVersion::withTrashed() - ->where('collection_id', $collectionId) + $collectionHasDatasetVersions = CollectionHasDatasetVersion::where('collection_id', $collectionId) ->select('dataset_version_id') ->get() ->toArray(); @@ -160,35 +159,10 @@ private function checkDatasets(int $collectionId, array $inDatasets, int $userId continue; } - // else if the latest version is already linked, then delete any links to older versions, and for the latest version, if it's been deleted previously, then re-add it + // else if the latest version is already linked, then delete any links to older versions if (in_array($datasetVersionLatestId, $commonDatasetVersionIds)) { foreach ($commonDatasetVersionIds as $commonDatasetVersionId) { - if ((int) $datasetVersionLatestId === (int) $commonDatasetVersionId) { - $checkCollectionWithLatestDatasetVersionActive = CollectionHasDatasetVersion::where([ - 'collection_id' => $collectionId, - 'dataset_version_id' => $commonDatasetVersionId, - ])->first(); - - if (!is_null($checkCollectionWithLatestDatasetVersionActive)) { - continue; - } - - $checkCollectionWithLatestDatasetVersionDeleted = CollectionHasDatasetVersion::onlyTrashed() - ->where([ - 'collection_id' => $collectionId, - 'dataset_version_id' => $commonDatasetVersionId, - ])->first(); - - if (!is_null($checkCollectionWithLatestDatasetVersionDeleted)) { - CollectionHasDatasetVersion::withTrashed()->where([ - 'collection_id' => $collectionId, - 'dataset_version_id' => $commonDatasetVersionId, - ]) - ->limit(1) - ->update(['deleted_at' => null]); - continue; - } - } else { + if ((int) $datasetVersionLatestId !== (int) $commonDatasetVersionId) { CollectionHasDatasetVersion::where([ 'collection_id' => $collectionId, 'dataset_version_id' => $commonDatasetVersionId, @@ -249,7 +223,7 @@ private function addCollectionHasDatasetVersion(int $collectionId, array $datase $arrCreate['created_at'] = $dataset['updated_at']; $arrCreate['updated_at'] = $dataset['updated_at']; } - + //TODO: this whole function may now be unnecessary or at least convoluted - we never have a soft-deleted CHDV so it's a simple UpdateOrCreate? $checkRow = CollectionHasDatasetVersion::where($searchArray)->first(); if (is_null($checkRow)) { return CollectionHasDatasetVersion::create($arrCreate); @@ -271,7 +245,7 @@ private function addCollectionHasDatasetVersion(int $collectionId, array $datase private function checkInCollectionHasDatasetVersions(int $collectionId, int $datasetVersionId) { try { - return CollectionHasDatasetVersion::withTrashed()->where([ + return CollectionHasDatasetVersion::where([ 'collection_id' => $collectionId, 'dataset_version_id' => $datasetVersionId, ])->first(); diff --git a/app/Models/Team.php b/app/Models/Team.php index 06dd9c273..59daab9c0 100644 --- a/app/Models/Team.php +++ b/app/Models/Team.php @@ -218,7 +218,7 @@ protected function validateFields() $mediaUrl = Config::get('services.media.base_url'); $escapedMediaUrl = preg_quote($mediaUrl, '/'); $allowedExtensions = 'jpeg|jpg|png|gif|bmp|webp'; - $customPattern = "/^(" . $escapedMediaUrl . ")?\/teams\/[a-zA-Z0-9 _-]+\.(?:$allowedExtensions)$/"; + $customPattern = "/^(" . $escapedMediaUrl . ")?\/teams\/[a-zA-Z0-9\(\) _-]+\.(?:$allowedExtensions)$/"; $validator = Validator::make($this->attributes, [ 'team_logo' => [ diff --git a/config/routes_v2.php b/config/routes_v2.php index 2f9370b47..4c954bb71 100644 --- a/config/routes_v2.php +++ b/config/routes_v2.php @@ -277,6 +277,7 @@ 'middleware' => [ 'jwt.verify', 'sanitize.input', + 'check.access:permissions,collections.create', ], 'constraint' => [ 'teamId' => '[0-9]+', @@ -291,6 +292,7 @@ 'middleware' => [ 'jwt.verify', 'sanitize.input', + 'check.access:permissions,collections.update', ], 'constraint' => [ 'id' => '[0-9]+', @@ -306,6 +308,7 @@ 'middleware' => [ 'jwt.verify', 'sanitize.input', + 'check.access:permissions,collections.update', ], 'constraint' => [ 'id' => '[0-9]+', @@ -320,6 +323,7 @@ 'namespaceController' => 'App\Http\Controllers\Api\V2', 'middleware' => [ 'jwt.verify', + 'check.access:permissions,collections.delete', ], 'constraint' => [ 'id' => '[0-9]+', diff --git a/tests/Feature/V2/CollectionTest.php b/tests/Feature/V2/CollectionTest.php index 29bce5e0b..499166ea1 100644 --- a/tests/Feature/V2/CollectionTest.php +++ b/tests/Feature/V2/CollectionTest.php @@ -35,6 +35,7 @@ use Database\Seeders\CollectionHasPublicationSeeder; use Database\Seeders\CollectionHasDatasetVersionSeeder; use Database\Seeders\PublicationHasDatasetVersionSeeder; +use Illuminate\Testing\TestResponse; class CollectionTest extends TestCase { @@ -161,7 +162,7 @@ public function test_get_all_collections_with_success(): void */ public function test_get_collections_count_with_success(): void { - // Ensure we have at least one active and one draft collection + // Ensure we have at least one active, draft and archived collection $mockData = [ "name" => "covid", "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", @@ -183,6 +184,7 @@ public function test_get_collections_count_with_success(): void $mockData, $this->headerNonAdmin ); + $response->assertStatus(201); $mockData = [ "name" => "covid", @@ -206,12 +208,35 @@ public function test_get_collections_count_with_success(): void $this->headerNonAdmin ); + $mockData = [ + "name" => "covid", + "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", + "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), + "enabled" => true, + "public" => true, + "counter" => 123, + "datasets" => $this->generateDatasets(), + "tools" => $this->generateTools(), + "keywords" => $this->generateKeywords(), + "dur" => $this->generateDurs(), + "publications" => $this->generatePublications(), + "status" => "ARCHIVED" + ]; + + $response = $this->json( + 'POST', + self::TEST_URL_V2, + $mockData, + $this->headerNonAdmin + ); + $response = $this->json('GET', self::TEST_URL_V2 . '/count/status', [], $this->header); $response->assertJsonStructure([ 'data' => [ 'ACTIVE', - 'DRAFT' + 'DRAFT', + 'ARCHIVED' ], ]); $response->assertStatus(200); @@ -261,9 +286,6 @@ public function test_get_collection_by_id_with_success(): void public function test_add_new_active_collection_with_success(): void { $datasets = $this->generateDatasets(); - $nActive = Dataset::whereIn("id", array_column($datasets, 'id')) - ->where('status', Dataset::STATUS_ACTIVE) - ->count(); $countBefore = Collection::count(); $mockData = [ @@ -293,15 +315,11 @@ public function test_add_new_active_collection_with_success(): void $this->assertTrue((bool) $countNewRow, 'Response was successfully'); $response->assertStatus(201); - } public function test_add_new_draft_collection_with_success(): void { $datasets = $this->generateDatasets(); - $nActive = Dataset::whereIn("id", array_column($datasets, 'id')) - ->where('status', Dataset::STATUS_ACTIVE) - ->count(); $mockData = [ "name" => "covid", @@ -436,59 +454,23 @@ public function test_update_collection_with_success(): void */ public function test_update_collection_without_success(): void { - $datasets = $this->generateDatasets(); - - // create new collection - $mockDataIn = [ - "name" => "covid", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 123, - "datasets" => $datasets, - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "ACTIVE", - "collaborators" => [], - ]; - $responseIn = $this->json( - 'POST', - self::TEST_URL_V2, - $mockDataIn, - $this->headerNonAdmin - ); - - $responseIn->assertStatus(201); - $idIn = (int) $responseIn['data']; - - // fail to update collection by non-COLLABORATOR - $mockDataUpdate = [ - "name" => "covid update", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero. update", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 1, - "datasets" => $datasets, - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "ACTIVE", - "collaborators" => [$this->nonAdmin2User['id']] - ]; - - $responseUpdate = $this->json( + $this->checkOperationPerms( + [ + "status" => "ACTIVE", + ], + $this->headerNonAdmin, 'PUT', - self::TEST_URL_V2 . '/' . $idIn, - $mockDataUpdate, - $this->headerNonAdmin2 + [ + "name" => "covid update", + "description" => "Dolorem voluptas consequatur nihil illum et sunt libero. update", + "enabled" => true, + "public" => true, + "status" => "DRAFT" + ], + $this->headerNonAdmin2, // This user is not owner nor in the collaborators + 401, // Unauthorized + 1 ); - - $responseUpdate->assertStatus(401); // Unauthorized } /** @@ -498,55 +480,24 @@ public function test_update_collection_without_success(): void */ public function test_update_collection_to_draft_with_success(): void { - // create new collection - $mockDataIns = [ - "name" => "covid", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 123, - "datasets" => $this->generateDatasets(), - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "ACTIVE", - "collaborators" => [$this->nonAdmin2User['id']], - ]; - $responseIns = $this->json( - 'POST', - self::TEST_URL_V2, - $mockDataIns, - $this->headerNonAdmin - ); - - $responseIns->assertStatus(201); - $idIns = (int) $responseIns['data']; - - // update collection - $mockDataUpdate = [ - "name" => "covid update", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero. update", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 1, - "datasets" => $this->generateDatasets(), - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "DRAFT", - 'collaborators' => [$this->nonAdmin2User['id']], - ]; - $responseUpdate = $this->json( + $this->checkOperationPerms( + [ + "status" => "ACTIVE", + "collaborators" => [$this->nonAdmin2User['id']] + ], + $this->headerNonAdmin, 'PUT', - self::TEST_URL_V2 . '/' . $idIns, - $mockDataUpdate, - $this->headerNonAdmin2 + [ + "name" => "covid update", + "description" => "Dolorem voluptas consequatur nihil illum et sunt libero. update", + "enabled" => true, + "public" => true, + "status" => "DRAFT" + ], + $this->headerNonAdmin2, + 200, + 1 ); - $responseUpdate->assertStatus(200); } /** @@ -698,13 +649,13 @@ public function test_edit_collection_without_success(): void "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), "enabled" => true, "public" => true, - "counter" => 1, + "counter" => 3, "datasets" => $this->generateDatasets(), "tools" => $this->generateTools(), "keywords" => $this->generateKeywords(), "dur" => $this->generateDurs(), "status" => "DRAFT", - 'collaborators' => [$this->nonAdmin2User['id']], + 'collaborators' => [], ]; $responseUpdate = $this->json( 'PUT', @@ -733,19 +684,19 @@ public function test_edit_collection_without_success(): void $this->headerNonAdmin2 // Not a COLLABORATOR ); - $responseEdit1->assertStatus(200); // Unauthorized + $responseEdit1->assertStatus(401); // Unauthorized } /** - * SoftDelete Collection by Id with success + * Archive and unarchive Collection by Id with success * * @return void */ - public function test_soft_delete_and_unarchive_collection_with_success(): void + public function test_archive_and_unarchive_collection_with_success(): void { $countBefore = Collection::count(); - $countTrashedBefore = Collection::onlyTrashed()->count(); + // create new collection $mockDataIn = [ "name" => "covid", @@ -772,9 +723,9 @@ public function test_soft_delete_and_unarchive_collection_with_success(): void $idIn = (int) $responseIn['data']; $countAfter = Collection::count(); - $this->assertEquals($countAfter, $countBefore + 1); + $this->assertEquals($countBefore + 1, $countAfter); - // delete collection + // archive collection $response = $this->json( 'PATCH', self::TEST_URL_V2 . '/' . $idIn, @@ -784,39 +735,35 @@ public function test_soft_delete_and_unarchive_collection_with_success(): void $this->headerNonAdmin ); $response->assertStatus(200); - $countAfter = Collection::count(); - $countTrashedAfter = Collection::onlyTrashed()->count(); - $this->assertEquals($countAfter, $countBefore); - $this->assertEquals($countTrashedAfter, 1); + $this->assertEquals($countBefore + 1, $countAfter); $response = $this->json( 'PATCH', - self::TEST_URL_V2 . '/' . $idIn . '?unarchive', + self::TEST_URL_V2 . '/' . $idIn, ['status' => 'ACTIVE'], $this->headerNonAdmin2 ); $response->assertStatus(200); - $countTrashedAfterUnarchiving = Collection::onlyTrashed()->count(); $countAfterUnarchiving = Collection::count(); - $this->assertEquals($countTrashedAfterUnarchiving, 0); - $this->assertTrue($countAfter < $countAfterUnarchiving); $this->assertEquals($countBefore + 1, $countAfterUnarchiving); } - - /** - * SoftDelete Collection by Id with success - index not deleted for draft + /** + * Archive and unarchive Collection by Id without success * * @return void */ - public function test_does_not_delete_index_on_draft_archived_collection(): void + public function test_archive_and_unarchive_collection_without_success(): void { - // create new draft collection + $countBefore = Collection::count(); + $countArchivedBefore = Collection::where(['status' => 'ARCHIVED'])->count(); + + // create new collection $mockDataIn = [ "name" => "covid", "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", @@ -829,8 +776,7 @@ public function test_does_not_delete_index_on_draft_archived_collection(): void "keywords" => $this->generateKeywords(), "dur" => $this->generateDurs(), "publications" => $this->generatePublications(), - "status" => "DRAFT", - "collaborators" => [$this->nonAdmin2User['id']] + "status" => "ACTIVE", ]; $responseIn = $this->json( 'POST', @@ -841,15 +787,59 @@ public function test_does_not_delete_index_on_draft_archived_collection(): void $responseIn->assertStatus(201); $idIn = (int) $responseIn['data']; + $countAfter = Collection::count(); + $this->assertEquals($countBefore + 1, $countAfter); + + // fail to archive collection $response = $this->json( - 'DELETE', + 'PATCH', self::TEST_URL_V2 . '/' . $idIn, - [], - $this->header + [ + 'status' => 'ARCHIVED', + ], + $this->headerNonAdmin2 + ); + $response->assertStatus(401); + $countAfter = Collection::count(); + + $this->assertEquals($countBefore + 1, $countAfter); + + $countArchivedAfter = Collection::where(['status' => 'ARCHIVED'])->count(); + $this->assertEquals($countArchivedBefore, $countArchivedAfter); + + // archive collection + $response = $this->json( + 'PATCH', + self::TEST_URL_V2 . '/' . $idIn, + [ + 'status' => 'ARCHIVED', + ], + $this->headerNonAdmin ); $response->assertStatus(200); - } + $countAfter = Collection::count(); + + $this->assertEquals($countBefore + 1, $countAfter); + + $countArchivedAfter = Collection::where(['status' => 'ARCHIVED'])->count(); + $this->assertEquals($countArchivedBefore + 1, $countArchivedAfter); + $response = $this->json( + 'PATCH', + self::TEST_URL_V2 . '/' . $idIn, + ['status' => 'ACTIVE'], + $this->headerNonAdmin2 + ); + + $response->assertStatus(401); + + $countAfterUnarchiving = Collection::count(); + + $this->assertEquals($countBefore + 1, $countAfterUnarchiving); + + $countArchivedAfter = Collection::where(['status' => 'ARCHIVED'])->count(); + $this->assertEquals($countArchivedBefore + 1, $countArchivedAfter); + } /** * SoftDelete Collection by Id without success @@ -858,9 +848,13 @@ public function test_does_not_delete_index_on_draft_archived_collection(): void */ public function test_soft_delete_collection_without_success(): void { - $countBefore = Collection::count(); + $this->checkOperationPerms([], $this->headerNonAdmin, 'DELETE', [], $this->headerNonAdmin2, 401, 1); + } - // create new collection + private function checkOperationPerms(array $firstDataIn, array $firstUserHeader, string $method, array $secondData, array $secondUserHeader, int $expectedStatus, int $expectedCountChange): TestResponse + { + $countBefore = Collection::count(); + // create a Collection with any supplied data, with first supplied user $mockDataIn = [ "name" => "covid", "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", @@ -874,27 +868,132 @@ public function test_soft_delete_collection_without_success(): void "dur" => $this->generateDurs(), "publications" => $this->generatePublications(), "collaborators" => [], + 'status' => 'ACTIVE', ]; - $responseIn = $this->json( + + $mockDataIn = array_merge($mockDataIn, $firstDataIn); + + $createResponse = $this->json( 'POST', self::TEST_URL_V2, $mockDataIn, - $this->headerNonAdmin + $firstUserHeader, ); - $responseIn->assertStatus(201); - $idIn = (int) $responseIn['data']; - $countAfter = Collection::count(); - $this->assertEquals($countAfter, $countBefore + 1); + // check creation gives 201 + $createResponse->assertStatus(201); + $idIn = (int) $createResponse['data']; - // delete collection with user who is not a collaborator + // run requested method with supplied values, with second supplied user $response = $this->json( - 'DELETE', + $method, self::TEST_URL_V2 . '/' . $idIn, - [], - $this->headerNonAdmin2 + $secondData, + $secondUserHeader, ); - $response->assertStatus(401); + + $response->assertStatus($expectedStatus); + + $countAfter = Collection::count(); + $this->assertEquals($countBefore + $expectedCountChange, $countAfter); + + return $response; + } + + private function checkOperationPermsUser(int $ownerId, array $firstDataIn, array $firstUserHeader, string $method, array $secondData, array $secondUserHeader, int $expectedStatus, int $expectedCountChange): TestResponse + { + $countBefore = Collection::count(); + // create a Collection with any supplied data, with first supplied user + $mockDataIn = [ + "name" => "covid", + "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", + "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), + "enabled" => true, + "public" => true, + "counter" => 123, + "datasets" => $this->generateDatasets(), + "tools" => $this->generateTools(), + "keywords" => $this->generateKeywords(), + "dur" => $this->generateDurs(), + "publications" => $this->generatePublications(), + "collaborators" => [], + ]; + + $mockDataIn = array_merge($mockDataIn, $firstDataIn); + + $createResponse = $this->json( + 'POST', + 'api/v2/users/' . $ownerId . '/collections/', + $mockDataIn, + $firstUserHeader, + ); + + // check creation gives 201 + $createResponse->assertStatus(201); + $idIn = (int) $createResponse['data']; + + // run requested method with supplied values, with second supplied user + $response = $this->json( + $method, + 'api/v2/users/' . $ownerId . '/collections/' . $idIn, + $secondData, + $secondUserHeader, + ); + + $response->assertStatus($expectedStatus); + + $countAfter = Collection::count(); + $this->assertEquals($countBefore + $expectedCountChange, $countAfter); + + return $response; + } + + private function checkOperationPermsTeam(int $teamId, array $firstDataIn, array $firstUserHeader, string $method, array $secondData, array $secondUserHeader, int $expectedStatus, int $expectedCountChange): TestResponse + { + $countBefore = Collection::count(); + // create a Collection with any supplied data, with first supplied user + $mockDataIn = [ + "name" => "covid", + "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", + "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), + "enabled" => true, + "public" => true, + "counter" => 123, + "datasets" => $this->generateDatasets(), + "tools" => $this->generateTools(), + "keywords" => $this->generateKeywords(), + "dur" => $this->generateDurs(), + "publications" => $this->generatePublications(), + "collaborators" => [], + ]; + + $mockDataIn = array_merge($mockDataIn, $firstDataIn); + + $createResponse = $this->json( + 'POST', + 'api/v2/teams/' . $teamId . '/collections/', + $mockDataIn, + $firstUserHeader, + ); + + // check creation gives 201 + $createResponse->assertStatus(201); + $idIn = (int) $createResponse['data']; + + // run requested method with supplied values, with second supplied user + $response = $this->json( + $method, + 'api/v2/teams/' . $teamId . '/collections/' . $idIn, + $secondData, + $secondUserHeader, + ); + + $response->assertStatus($expectedStatus); + + $countAfter = Collection::count(); + $this->assertEquals($countBefore + $expectedCountChange, $countAfter); + + return $response; } /** @@ -905,9 +1004,6 @@ public function test_soft_delete_collection_without_success(): void public function test_add_new_users_collection_with_success(): void { $datasets = $this->generateDatasets(); - $nActive = Dataset::whereIn("id", array_column($datasets, 'id')) - ->where('status', Dataset::STATUS_ACTIVE) - ->count(); $countBefore = Collection::count(); @@ -1065,43 +1161,21 @@ public function test_get_users_collection_with_success(): void * * @return void */ - public function test_get_users_collection_by_id_with_success(): void + public function test_get_users_collection_by_id(): void { - $countBefore = Collection::count(); - $collectionOwner = $this->createCollectionOwner(); $ownerHeader = $collectionOwner['ownerHeader']; $ownerId = $collectionOwner['userId']; - $mockData = [ - "name" => "covid", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 123, - "datasets" => $this->generateDatasets(), - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "ACTIVE" - ]; - - $response = $this->json( - 'POST', - 'api/v2/users/' . $ownerId . '/collections', - $mockData, - $ownerHeader - ); - $collectionId = $response->decodeResponseJson()['data']; - - // Test get collection by id - $response = $this->json( + $response = $this->checkOperationPermsUser( + $ownerId, + ["status" => "ACTIVE"], + $ownerHeader, 'GET', - 'api/v2/users/' . $ownerId . '/collections/' . $collectionId, [], - $ownerHeader + $ownerHeader, + 200, + 1 ); $response->assertJsonStructure([ 'data' => [ @@ -1129,13 +1203,20 @@ public function test_get_users_collection_by_id_with_success(): void $response->assertStatus(200); // Try to get collection through incorrect user endpoint - $response = $this->json( + $otherUser = $this->createCollectionOwner(); + $otherUserHeader = $otherUser['ownerHeader']; + $otherUserId = $otherUser['userId']; + + $response = $this->checkOperationPermsUser( + $otherUserId, // incorrect owner + ["status" => "ACTIVE"], + $ownerHeader, 'GET', - 'api/v2/users/' . $ownerId + 1 . '/collections/' . $collectionId, [], - $ownerHeader + $ownerHeader, + 401, + 1 ); - $response->assertStatus(401); } /** @@ -1149,56 +1230,23 @@ public function test_update_users_collection_with_success(): void $ownerHeader = $collectionOwner['ownerHeader']; $ownerId = $collectionOwner['userId']; - $mockData = [ - "name" => "covid", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 123, - "datasets" => $this->generateDatasets(), - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "ACTIVE" - ]; - - $response = $this->json( - 'POST', - 'api/v2/users/' . $ownerId . '/collections', - $mockData, - $ownerHeader - ); - - $response->assertStatus(201); - $collectionId = $response->decodeResponseJson()['data']; - - $updateData = [ - "name" => "updated name", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 123, - "datasets" => $this->generateDatasets(), - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "DRAFT" - ]; - - $response = $this->json( + $response = $this->checkOperationPermsUser( + $ownerId, + ["status" => "ACTIVE"], + $ownerHeader, 'PUT', - 'api/v2/users/' . $ownerId . '/collections/' . $collectionId, - $updateData, - $ownerHeader + [ + "name" => "updated name", + "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", + "enabled" => true, + "public" => true, + "status" => "DRAFT" + ], + $ownerHeader, + 200, + 1 ); - - $response->assertStatus(200); $content = $response->decodeResponseJson(); - $this->assertEquals('updated name', $content['data']['name']); $this->assertEquals('DRAFT', $content['data']['status']); @@ -1206,13 +1254,22 @@ public function test_update_users_collection_with_success(): void $otherUser = $this->createCollectionOwner(); $otherUserHeader = $otherUser['ownerHeader']; - $response = $this->json( + $response = $this->checkOperationPermsUser( + $ownerId, + ["status" => "ACTIVE"], + $ownerHeader, 'PUT', - 'api/v2/users/' . $ownerId . '/collections/' . $collectionId, - $updateData, - $otherUserHeader + [ + "name" => "updated name", + "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", + "enabled" => true, + "public" => true, + "status" => "DRAFT" + ], + $otherUserHeader, + 401, + 1 ); - $response->assertStatus(401); } /** @@ -1226,46 +1283,22 @@ public function test_edit_users_collection_with_success(): void $ownerHeader = $collectionOwner['ownerHeader']; $ownerId = $collectionOwner['userId']; - $mockData = [ - "name" => "covid", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 123, - "datasets" => $this->generateDatasets(), - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "ACTIVE" - ]; - - $response = $this->json( - 'POST', - 'api/v2/users/' . $ownerId . '/collections', - $mockData, - $ownerHeader - ); - - $response->assertStatus(201); - $collectionId = $response->decodeResponseJson()['data']; - $editData = [ "name" => "edited name", "status" => "DRAFT" ]; - $response = $this->json( + $response = $this->checkOperationPermsUser( + $ownerId, + ["status" => "ACTIVE"], + $ownerHeader, 'PATCH', - 'api/v2/users/' . $ownerId . '/collections/' . $collectionId, $editData, - $ownerHeader + $ownerHeader, + 200, + 1 ); - - $response->assertStatus(200); $content = $response->decodeResponseJson(); - $this->assertEquals('edited name', $content['data']['name']); $this->assertEquals('DRAFT', $content['data']['status']); @@ -1273,13 +1306,16 @@ public function test_edit_users_collection_with_success(): void $otherUser = $this->createCollectionOwner(); $otherUserHeader = $otherUser['ownerHeader']; - $response = $this->json( + $response = $this->checkOperationPermsUser( + $ownerId, + ["status" => "ACTIVE"], + $ownerHeader, 'PATCH', - 'api/v2/users/' . $ownerId . '/collections/' . $collectionId, $editData, - $otherUserHeader + $otherUserHeader, + 401, + 1 ); - $response->assertStatus(401); } /** @@ -1293,39 +1329,16 @@ public function test_delete_users_collection_with_success(): void $ownerHeader = $collectionOwner['ownerHeader']; $ownerId = $collectionOwner['userId']; - $mockData = [ - "name" => "covid", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 123, - "datasets" => $this->generateDatasets(), - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "ACTIVE" - ]; - - $response = $this->json( - 'POST', - 'api/v2/users/' . $ownerId . '/collections', - $mockData, - $ownerHeader - ); - - $response->assertStatus(201); - $collectionId = $response->decodeResponseJson()['data']; - - $response = $this->json( + $response = $this->checkOperationPermsUser( + $ownerId, + ["status" => "ACTIVE"], + $ownerHeader, 'DELETE', - 'api/v2/users/' . $ownerId . '/collections/' . $collectionId, [], - $ownerHeader + $ownerHeader, + 200, + 0 ); - - $response->assertStatus(200); } /** @@ -1339,41 +1352,19 @@ public function test_delete_users_collection_without_success(): void $ownerHeader = $collectionOwner['ownerHeader']; $ownerId = $collectionOwner['userId']; - $mockData = [ - "name" => "covid", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 123, - "datasets" => $this->generateDatasets(), - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "ACTIVE" - ]; - - $response = $this->json( - 'POST', - 'api/v2/users/' . $ownerId . '/collections', - $mockData, - $ownerHeader - ); - - $response->assertStatus(201); - $collectionId = $response->decodeResponseJson()['data']; - $otherUser = $this->createCollectionOwner(); $otherUserHeader = $otherUser['ownerHeader']; - $response = $this->json( + $response = $this->checkOperationPermsUser( + $ownerId, + ["status" => "ACTIVE"], + $ownerHeader, 'DELETE', - 'api/v2/users/' . $ownerId . '/collections/' . $collectionId, [], - $otherUserHeader + $otherUserHeader, + 401, + 1 ); - $response->assertStatus(401); } @@ -1387,9 +1378,6 @@ public function test_delete_users_collection_without_success(): void public function test_add_new_teams_collection_with_success(): void { $datasets = $this->generateDatasets(); - $nActive = Dataset::whereIn("id", array_column($datasets, 'id')) - ->where('status', Dataset::STATUS_ACTIVE) - ->count(); $countBefore = Collection::count(); @@ -1555,37 +1543,17 @@ public function test_get_teams_collection_by_id_with_success(): void $memberHeader = $collectionTeam['memberHeader']; $teamId = $collectionTeam['teamId']; - // Create a collection with each status - $mockData = [ - "name" => "covid", - "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", - "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), - "enabled" => true, - "public" => true, - "counter" => 123, - "datasets" => $this->generateDatasets(), - "tools" => $this->generateTools(), - "keywords" => $this->generateKeywords(), - "dur" => $this->generateDurs(), - "publications" => $this->generatePublications(), - "status" => "ACTIVE" - ]; - - $response = $this->json( - 'POST', - 'api/v2/teams/' . $teamId . '/collections', - $mockData, - $memberHeader - ); - $collectionId = $response->decodeResponseJson()['data']; - - // Test get active collections - $response = $this->json( + $response = $this->checkOperationPermsTeam( + $teamId, + ["status" => "ACTIVE"], + $memberHeader, 'GET', - 'api/v2/teams/' . $teamId . '/collections/' . $collectionId, [], - $memberHeader + $memberHeader, + 200, + 1 ); + $response->assertJsonStructure([ 'data' => [ 'id', @@ -1609,29 +1577,23 @@ public function test_get_teams_collection_by_id_with_success(): void 'team', ], ]); - $response->assertStatus(200); - - // Try to get collection through incorrect team - $response = $this->json( - 'GET', - 'api/v2/teams/' . $teamId + 1 . '/collections/' . $collectionId, - [], - $memberHeader - ); - $response->assertStatus(401); } /** - * Update teams Collection with success + * Get teams Collection by id without success (wrong team id) * * @return void */ - public function test_update_teams_collection_with_success(): void + public function test_get_teams_collection_by_id_without_success(): void { $collectionTeam = $this->createCollectionTeam(); $memberHeader = $collectionTeam['memberHeader']; $teamId = $collectionTeam['teamId']; + $secondCollectionTeam = $this->createCollectionTeam(); + $secondTeamHeader = $secondCollectionTeam['memberHeader']; + $secondTeamId = $secondCollectionTeam['teamId']; + $mockData = [ "name" => "covid", "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", @@ -1653,10 +1615,47 @@ public function test_update_teams_collection_with_success(): void $mockData, $memberHeader ); - - $response->assertStatus(201); $collectionId = $response->decodeResponseJson()['data']; + // Try to get collection through incorrect team + $response = $this->json( + 'GET', + 'api/v2/teams/' . $secondTeamId . '/collections/' . $collectionId, + [], + $memberHeader + ); + $response->assertStatus(401); + + // Try to get collection through member of incorrect team + $response = $this->json( + 'GET', + 'api/v2/teams/' . $teamId . '/collections/' . $collectionId, + [], + $secondTeamHeader + ); + $response->assertStatus(401); + + // Try to get collection through member of incorrect team via incorrect team + $response = $this->json( + 'GET', + 'api/v2/teams/' . $secondTeamId . '/collections/' . $collectionId, + [], + $secondTeamHeader + ); + $response->assertStatus(401); + } + + /** + * Update teams Collection with success + * + * @return void + */ + public function test_update_teams_collection_with_success(): void + { + $collectionTeam = $this->createCollectionTeam(); + $memberHeader = $collectionTeam['memberHeader']; + $teamId = $collectionTeam['teamId']; + $updateData = [ "name" => "updated name", "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", @@ -1672,43 +1671,38 @@ public function test_update_teams_collection_with_success(): void "status" => "DRAFT" ]; - $response = $this->json( + $response = $this->checkOperationPermsTeam( + $teamId, + ["status" => "ACTIVE"], + $memberHeader, 'PUT', - 'api/v2/teams/' . $teamId . '/collections/' . $collectionId, $updateData, - $memberHeader + $memberHeader, + 200, + 1 ); - $response->assertStatus(200); $content = $response->decodeResponseJson(); $this->assertEquals('updated name', $content['data']['name']); $this->assertEquals('DRAFT', $content['data']['status']); - - // Test a different team cannot update - $otherTeam = $this->createCollectionTeam(); - $otherTeamHeader = $otherTeam['memberHeader']; - - $response = $this->json( - 'PUT', - 'api/v2/teams/' . $teamId . '/collections/' . $collectionId, - $updateData, - $otherTeamHeader - ); - $response->assertStatus(401); } /** - * Edit teams Collection with success + * Update teams Collection with success * * @return void */ - public function test_edit_teams_collection_with_success(): void + public function test_update_teams_collection_without_success(): void { $collectionTeam = $this->createCollectionTeam(); $memberHeader = $collectionTeam['memberHeader']; $teamId = $collectionTeam['teamId']; + $secondCollectionTeam = $this->createCollectionTeam(); + $secondTeamHeader = $secondCollectionTeam['memberHeader']; + $secondTeamId = $secondCollectionTeam['teamId']; + $mockData = [ "name" => "covid", "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", @@ -1730,52 +1724,96 @@ public function test_edit_teams_collection_with_success(): void $mockData, $memberHeader ); - - $response->assertStatus(201); $collectionId = $response->decodeResponseJson()['data']; - $editData = [ - "name" => "edited name", + $updateData = [ + "name" => "updated name", + "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", + "image_link" => Config::get('services.media.base_url') . '/collections/' . fake()->lexify('????_????_????.') . fake()->randomElement(['jpg', 'jpeg', 'png', 'gif']), + "enabled" => true, + "public" => true, + "counter" => 123, + "datasets" => $this->generateDatasets(), + "tools" => $this->generateTools(), + "keywords" => $this->generateKeywords(), + "dur" => $this->generateDurs(), + "publications" => $this->generatePublications(), "status" => "DRAFT" ]; $response = $this->json( - 'PATCH', + 'PUT', 'api/v2/teams/' . $teamId . '/collections/' . $collectionId, - $editData, + $updateData, + $secondTeamHeader + ); + $response->assertStatus(401); + + $response = $this->json( + 'PUT', + 'api/v2/teams/' . $secondTeamId . '/collections/' . $collectionId, + $updateData, $memberHeader ); + $response->assertStatus(401); - $response->assertStatus(200); - $content = $response->decodeResponseJson(); + $response = $this->json( + 'PUT', + 'api/v2/teams/' . $secondTeamId . '/collections/' . $collectionId, + $updateData, + $secondTeamHeader + ); + $response->assertStatus(401); + } - $this->assertEquals('edited name', $content['data']['name']); - $this->assertEquals('DRAFT', $content['data']['status']); + /** + * Edit teams Collection with success + * + * @return void + */ + public function test_edit_teams_collection_with_success(): void + { + $collectionTeam = $this->createCollectionTeam(); + $memberHeader = $collectionTeam['memberHeader']; + $teamId = $collectionTeam['teamId']; - // Test a different team cannot edit - $otherTeam = $this->createCollectionTeam(); - $otherTeamHeader = $otherTeam['memberHeader']; + $editData = [ + "name" => "edited name", + "status" => "DRAFT" + ]; - $response = $this->json( + $response = $this->checkOperationPermsTeam( + $teamId, + ["status" => "ACTIVE"], + $memberHeader, 'PATCH', - 'api/v2/teams/' . $teamId . '/collections/' . $collectionId, $editData, - $otherTeamHeader + $memberHeader, + 200, + 1 ); - $response->assertStatus(401); + + $content = $response->decodeResponseJson(); + + $this->assertEquals('edited name', $content['data']['name']); + $this->assertEquals('DRAFT', $content['data']['status']); } /** - * Delete teams Collection with success + * Edit teams Collection without success * * @return void */ - public function test_delete_teams_collection_with_success(): void + public function test_edit_teams_collection_without_success(): void { $collectionTeam = $this->createCollectionTeam(); $memberHeader = $collectionTeam['memberHeader']; $teamId = $collectionTeam['teamId']; + $secondCollectionTeam = $this->createCollectionTeam(); + $secondTeamHeader = $secondCollectionTeam['memberHeader']; + $secondTeamId = $secondCollectionTeam['teamId']; + $mockData = [ "name" => "covid", "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", @@ -1797,18 +1835,60 @@ public function test_delete_teams_collection_with_success(): void $mockData, $memberHeader ); - - $response->assertStatus(201); $collectionId = $response->decodeResponseJson()['data']; + $editData = [ + "name" => "edited name", + "status" => "DRAFT" + ]; + $response = $this->json( - 'DELETE', + 'PATCH', 'api/v2/teams/' . $teamId . '/collections/' . $collectionId, - [], + $editData, + $secondTeamHeader + ); + $response->assertStatus(401); + + $response = $this->json( + 'PATCH', + 'api/v2/teams/' . $secondTeamId . '/collections/' . $collectionId, + $editData, $memberHeader ); + $response->assertStatus(401); - $response->assertStatus(200); + $response = $this->json( + 'PATCH', + 'api/v2/teams/' . $secondTeamId . '/collections/' . $collectionId, + $editData, + $secondTeamHeader + ); + $response->assertStatus(401); + } + + /** + * Delete teams Collection with success + * + * @return void + */ + public function test_delete_teams_collection_with_success(): void + { + $countBefore = Collection::count(); + $collectionTeam = $this->createCollectionTeam(); + $memberHeader = $collectionTeam['memberHeader']; + $teamId = $collectionTeam['teamId']; + + $response = $this->checkOperationPermsTeam( + $teamId, + ["status" => "ACTIVE"], + $memberHeader, + 'DELETE', + [], + $memberHeader, + 200, + 0 + ); } /** @@ -1822,6 +1902,10 @@ public function test_delete_teams_collection_without_success(): void $memberHeader = $collectionTeam['memberHeader']; $teamId = $collectionTeam['teamId']; + $secondCollectionTeam = $this->createCollectionTeam(); + $secondTeamHeader = $secondCollectionTeam['memberHeader']; + $secondTeamId = $secondCollectionTeam['teamId']; + $mockData = [ "name" => "covid", "description" => "Dolorem voluptas consequatur nihil illum et sunt libero.", @@ -1843,20 +1927,30 @@ public function test_delete_teams_collection_without_success(): void $mockData, $memberHeader ); - - $response->assertStatus(201); $collectionId = $response->decodeResponseJson()['data']; - $otherTeam = $this->createCollectionTeam(); - $otherTeamHeader = $otherTeam['memberHeader']; - $response = $this->json( 'DELETE', 'api/v2/teams/' . $teamId . '/collections/' . $collectionId, [], - $otherTeamHeader + $secondTeamHeader ); + $response->assertStatus(401); + + $response = $this->json( + 'DELETE', + 'api/v2/teams/' . $secondTeamId . '/collections/' . $collectionId, + [], + $memberHeader + ); + $response->assertStatus(401); + $response = $this->json( + 'DELETE', + 'api/v2/teams/' . $secondTeamId . '/collections/' . $collectionId, + [], + $secondTeamHeader + ); $response->assertStatus(401); }