mirror of
https://github.com/Kovah/LinkAce.git
synced 2025-04-21 07:22:20 +02:00
Add a new endpoint for handling the trash (#6)
Also optimizes existing tests for the trash controller with a new trait
This commit is contained in:
parent
aa9ea21140
commit
b75c212b5f
80
app/Http/Controllers/API/TrashController.php
Normal file
80
app/Http/Controllers/API/TrashController.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\TrashClearRequest;
|
||||
use App\Http\Requests\TrashRestoreRequest;
|
||||
use App\Models\Link;
|
||||
use App\Models\LinkList;
|
||||
use App\Models\Note;
|
||||
use App\Models\Tag;
|
||||
use App\Repositories\TrashRepository;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class TrashController extends Controller
|
||||
{
|
||||
public function getLinks(Request $request)
|
||||
{
|
||||
$links = Link::onlyTrashed()
|
||||
->byUser($request->user()->id)
|
||||
->get();
|
||||
|
||||
return response()->json($links->toArray());
|
||||
}
|
||||
|
||||
public function getLists(Request $request)
|
||||
{
|
||||
$lists = LinkList::onlyTrashed()
|
||||
->byUser($request->user()->id)
|
||||
->get();
|
||||
|
||||
return response()->json($lists);
|
||||
}
|
||||
|
||||
public function getTags(Request $request)
|
||||
{
|
||||
$tags = Tag::onlyTrashed()
|
||||
->byUser($request->user()->id)
|
||||
->get();
|
||||
|
||||
return response()->json($tags);
|
||||
}
|
||||
|
||||
public function getNotes(Request $request)
|
||||
{
|
||||
$notes = Note::onlyTrashed()
|
||||
->byUser($request->user()->id)
|
||||
->get();
|
||||
|
||||
return response()->json($notes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Permanently delete entries for a model from the trash.
|
||||
*
|
||||
* @param TrashClearRequest $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function clear(TrashClearRequest $request): JsonResponse
|
||||
{
|
||||
TrashRepository::delete($request->input('model'));
|
||||
|
||||
return response()->json(null, Response::HTTP_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore an entry from the trash.
|
||||
*
|
||||
* @param TrashRestoreRequest $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function restore(TrashRestoreRequest $request): JsonResponse
|
||||
{
|
||||
TrashRepository::restore($request->input('model'), $request->input('id'));
|
||||
|
||||
return response()->json(null, Response::HTTP_OK);
|
||||
}
|
||||
}
|
@ -11,7 +11,6 @@ use App\Models\Note;
|
||||
use App\Models\Tag;
|
||||
use App\Repositories\TrashRepository;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class TrashController extends Controller
|
||||
|
30
app/Http/Requests/TrashClearRequest.php
Normal file
30
app/Http/Requests/TrashClearRequest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class TrashClearRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'model' => 'required|in:links,lists,tags,notes',
|
||||
];
|
||||
}
|
||||
}
|
@ -87,7 +87,10 @@ Route::prefix('v1')->group(function () {
|
||||
->name('api.trash.tags');
|
||||
Route::get('trash/notes', [TrashController::class, 'getNotes'])
|
||||
->name('api.trash.notes');
|
||||
Route::post('trash/delete', [TrashController::class, 'getNotes'])
|
||||
->name('api.trash.notes');
|
||||
|
||||
Route::post('trash/clear', [TrashController::class, 'clear'])
|
||||
->name('api.trash.clear');
|
||||
Route::post('trash/restore', [TrashController::class, 'restore'])
|
||||
->name('api.trash.restore');
|
||||
});
|
||||
});
|
||||
|
241
tests/Controller/API/TrashApiTest.php
Normal file
241
tests/Controller/API/TrashApiTest.php
Normal file
@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Controller\API;
|
||||
|
||||
use App\Models\Link;
|
||||
use App\Models\LinkList;
|
||||
use App\Models\Note;
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\Controller\Traits\PreparesTrash;
|
||||
|
||||
class TrashApiTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
use DatabaseMigrations;
|
||||
use PreparesTrash;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->setupTrashTestData();
|
||||
}
|
||||
|
||||
public function testUnauthorizedRequest(): void
|
||||
{
|
||||
$response = $this->getJson('api/v1/trash/links');
|
||||
|
||||
$response->assertUnauthorized();
|
||||
}
|
||||
|
||||
public function testGetLinks(): void
|
||||
{
|
||||
$response = $this->getJson('api/v1/trash/links', $this->generateHeaders());
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$result = json_decode($response->content());
|
||||
$this->assertEquals('Very special site title', $result[0]->title);
|
||||
}
|
||||
|
||||
public function testGetLists(): void
|
||||
{
|
||||
$response = $this->getJson('api/v1/trash/lists', $this->generateHeaders());
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$result = json_decode($response->content());
|
||||
$this->assertEquals('A Tests List', $result[0]->name);
|
||||
}
|
||||
|
||||
public function testGetTags(): void
|
||||
{
|
||||
$response = $this->getJson('api/v1/trash/tags', $this->generateHeaders());
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$result = json_decode($response->content());
|
||||
$this->assertEquals('Examples', $result[0]->name);
|
||||
}
|
||||
|
||||
public function testGetNotes(): void
|
||||
{
|
||||
$response = $this->getJson('api/v1/trash/notes', $this->generateHeaders());
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$result = json_decode($response->content());
|
||||
$this->assertEquals('Quisque placerat facilisis egestas cillum dolore.', $result[0]->note);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests for clearing the trash
|
||||
*/
|
||||
|
||||
public function testValidTrashClearLinksResponse(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/clear', [
|
||||
'model' => 'links',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertOk();
|
||||
|
||||
$this->assertEquals(0, DB::table('links')->count());
|
||||
}
|
||||
|
||||
public function testValidTrashClearTagsResponse(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/clear', [
|
||||
'model' => 'tags',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertOk();
|
||||
|
||||
$this->assertEquals(0, DB::table('tags')->count());
|
||||
}
|
||||
|
||||
public function testValidTrashClearListsResponse(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/clear', [
|
||||
'model' => 'lists',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertOk();
|
||||
|
||||
$this->assertEquals(0, DB::table('lists')->count());
|
||||
}
|
||||
|
||||
public function testValidTrashClearNotesResponse(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/clear', [
|
||||
'model' => 'notes',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertOk();
|
||||
|
||||
$this->assertEquals(0, DB::table('notes')->count());
|
||||
}
|
||||
|
||||
public function testInvalidTrashClearRequest(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/clear', [
|
||||
//'model' => 'links',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertJsonValidationErrors([
|
||||
'model' => 'The model field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testClearRequestWithInvalidModel(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/clear', [
|
||||
'model' => 'shoes',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertJsonValidationErrors([
|
||||
'model' => 'The selected model is invalid.',
|
||||
]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests for restoring items
|
||||
*/
|
||||
|
||||
public function testValidRestoreLinkResponse(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/restore', [
|
||||
'model' => 'link',
|
||||
'id' => '1',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertOk();
|
||||
|
||||
$this->assertEquals(null, Link::find(1)->deleted_at);
|
||||
}
|
||||
|
||||
public function testValidRestoreTagResponse(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/restore', [
|
||||
'model' => 'tag',
|
||||
'id' => '1',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertOk();
|
||||
|
||||
$this->assertEquals(null, Tag::find(1)->deleted_at);
|
||||
}
|
||||
|
||||
public function testValidRestoreListResponse(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/restore', [
|
||||
'model' => 'list',
|
||||
'id' => '1',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertOk();
|
||||
|
||||
$this->assertEquals(null, LinkList::find(1)->deleted_at);
|
||||
}
|
||||
|
||||
public function testValidRestoreNoteResponse(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/restore', [
|
||||
'model' => 'note',
|
||||
'id' => '1',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertOk();
|
||||
|
||||
$this->assertEquals(null, Note::find(1)->deleted_at);
|
||||
}
|
||||
|
||||
public function testInvalidRestoreResponse(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/restore', [
|
||||
//'model' => 'link',
|
||||
//'id' => '1',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertJsonValidationErrors([
|
||||
'model',
|
||||
'id',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testRestoreWithMissingModel(): void
|
||||
{
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->postJson('api/v1/trash/restore', [
|
||||
'model' => 'link',
|
||||
'id' => '1345235',
|
||||
], $this->generateHeaders());
|
||||
|
||||
$response->assertStatus(404);
|
||||
}
|
||||
}
|
@ -10,21 +10,21 @@ use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\Controller\Traits\PreparesTrash;
|
||||
use Tests\TestCase;
|
||||
|
||||
class TrashControllerTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
use DatabaseMigrations;
|
||||
|
||||
private $user;
|
||||
use PreparesTrash;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->user = factory(User::class)->create();
|
||||
$this->actingAs($this->user);
|
||||
$user = factory(User::class)->create();
|
||||
$this->actingAs($user);
|
||||
}
|
||||
|
||||
public function testValidTrashResponse(): void
|
||||
@ -41,7 +41,7 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
public function testValidTrashClearLinksResponse(): void
|
||||
{
|
||||
$this->setupTestData();
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->post('trash/clear', [
|
||||
'model' => 'links'
|
||||
@ -54,7 +54,7 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
public function testValidTrashClearTagsResponse(): void
|
||||
{
|
||||
$this->setupTestData();
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->post('trash/clear', [
|
||||
'model' => 'tags'
|
||||
@ -67,7 +67,7 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
public function testValidTrashClearListsResponse(): void
|
||||
{
|
||||
$this->setupTestData();
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->post('trash/clear', [
|
||||
'model' => 'lists'
|
||||
@ -80,7 +80,7 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
public function testValidTrashClearNotesResponse(): void
|
||||
{
|
||||
$this->setupTestData();
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->post('trash/clear', [
|
||||
'model' => 'notes'
|
||||
@ -97,7 +97,7 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
public function testValidRestoreLinkResponse(): void
|
||||
{
|
||||
$this->setupTestData();
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->post('trash/restore', [
|
||||
'model' => 'link',
|
||||
@ -110,7 +110,7 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
public function testValidRestoreTagResponse(): void
|
||||
{
|
||||
$this->setupTestData();
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->post('trash/restore', [
|
||||
'model' => 'tag',
|
||||
@ -123,7 +123,7 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
public function testValidRestoreListResponse(): void
|
||||
{
|
||||
$this->setupTestData();
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->post('trash/restore', [
|
||||
'model' => 'list',
|
||||
@ -136,7 +136,7 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
public function testValidRestoreNoteResponse(): void
|
||||
{
|
||||
$this->setupTestData();
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->post('trash/restore', [
|
||||
'model' => 'note',
|
||||
@ -149,7 +149,7 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
public function testInvalidRestoreResponse(): void
|
||||
{
|
||||
$this->setupTestData();
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->post('trash/restore', [
|
||||
//'model' => 'link',
|
||||
@ -164,7 +164,7 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
public function testRestoreWithMissingModel(): void
|
||||
{
|
||||
$this->setupTestData();
|
||||
$this->setupTrashTestData();
|
||||
|
||||
$response = $this->post('trash/restore', [
|
||||
'model' => 'link',
|
||||
@ -173,50 +173,4 @@ class TrashControllerTest extends TestCase
|
||||
|
||||
$response->assertStatus(404);
|
||||
}
|
||||
|
||||
protected function setupTestData(): void
|
||||
{
|
||||
$tagExample = Tag::create([
|
||||
'name' => 'Examples',
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
$listTest = LinkList::create([
|
||||
'name' => 'A Tests List',
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
$linkExample = Link::create([
|
||||
'user_id' => $this->user->id,
|
||||
'url' => 'https://example.com',
|
||||
'title' => 'Very special site title',
|
||||
'description' => 'Some description for this site',
|
||||
'is_private' => true,
|
||||
]);
|
||||
|
||||
$linkExample->tags()->attach($tagExample->id);
|
||||
|
||||
$linkExampleNote = Note::create([
|
||||
'user_id' => $this->user->id,
|
||||
'link_id' => $linkExample->id,
|
||||
'note' => 'Quisque placerat facilisis egestas cillum dolore.',
|
||||
'is_private' => false,
|
||||
]);
|
||||
|
||||
$linkTest = Link::create([
|
||||
'user_id' => $this->user->id,
|
||||
'url' => 'https://test.com',
|
||||
'title' => 'Test Site',
|
||||
'description' => null,
|
||||
'is_private' => false,
|
||||
]);
|
||||
|
||||
$linkTest->lists()->attach($listTest->id);
|
||||
|
||||
$tagExample->delete();
|
||||
$listTest->delete();
|
||||
$linkExample->delete();
|
||||
$linkExampleNote->delete();
|
||||
$linkTest->delete();
|
||||
}
|
||||
}
|
||||
|
57
tests/Controller/Traits/PreparesTrash.php
Normal file
57
tests/Controller/Traits/PreparesTrash.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Controller\Traits;
|
||||
|
||||
use App\Models\Link;
|
||||
use App\Models\LinkList;
|
||||
use App\Models\Note;
|
||||
use App\Models\Tag;
|
||||
|
||||
trait PreparesTrash
|
||||
{
|
||||
protected function setupTrashTestData(): void
|
||||
{
|
||||
$tagExample = Tag::create([
|
||||
'name' => 'Examples',
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
$listTest = LinkList::create([
|
||||
'name' => 'A Tests List',
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
$linkExample = Link::create([
|
||||
'user_id' => $this->user->id,
|
||||
'url' => 'https://example.com',
|
||||
'title' => 'Very special site title',
|
||||
'description' => 'Some description for this site',
|
||||
'is_private' => true,
|
||||
]);
|
||||
|
||||
$linkExample->tags()->attach($tagExample->id);
|
||||
|
||||
$linkExampleNote = Note::create([
|
||||
'user_id' => $this->user->id,
|
||||
'link_id' => $linkExample->id,
|
||||
'note' => 'Quisque placerat facilisis egestas cillum dolore.',
|
||||
'is_private' => false,
|
||||
]);
|
||||
|
||||
$linkTest = Link::create([
|
||||
'user_id' => $this->user->id,
|
||||
'url' => 'https://test.com',
|
||||
'title' => 'Test Site',
|
||||
'description' => null,
|
||||
'is_private' => false,
|
||||
]);
|
||||
|
||||
$linkTest->lists()->attach($listTest->id);
|
||||
|
||||
$tagExample->delete();
|
||||
$listTest->delete();
|
||||
$linkExample->delete();
|
||||
$linkExampleNote->delete();
|
||||
$linkTest->delete();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user