fix(api): use DeleteLink action for cache invalidation, fix validation, add delete tests
parent
1375519cdb
commit
3568e67ca0
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
namespace App\Domains\Api\Resources;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class LinkResource extends JsonResource
|
||||
{
|
||||
public function toArray($request): array
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->ulid,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api\V1;
|
|||
|
||||
use App\Domains\Api\Resources\LinkResource;
|
||||
use App\Domains\Link\Actions\CreateLink;
|
||||
use App\Domains\Link\Actions\DeleteLink;
|
||||
use App\Domains\Link\Models\Link;
|
||||
use App\Domains\Workspace\Models\Workspace;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -28,10 +29,11 @@ class LinkController extends Controller
|
|||
$this->authorize('update', $workspace);
|
||||
|
||||
$validated = $request->validate([
|
||||
'target_url' => 'required|url|max:2048',
|
||||
'target_url' => 'required|url:http,https|max:2048',
|
||||
'slug' => 'nullable|string|max:64|alpha_dash',
|
||||
'title' => 'nullable|string|max:255',
|
||||
'tags' => 'nullable|array',
|
||||
'tags.*' => 'string|max:64',
|
||||
]);
|
||||
|
||||
$link = $action->handle($workspace, $request->user(), $validated);
|
||||
|
|
@ -41,7 +43,7 @@ class LinkController extends Controller
|
|||
->setStatusCode(201);
|
||||
}
|
||||
|
||||
public function destroy(string $workspaceUlid, string $linkUlid): \Illuminate\Http\Response
|
||||
public function destroy(Request $request, string $workspaceUlid, string $linkUlid, DeleteLink $action): \Illuminate\Http\Response
|
||||
{
|
||||
$workspace = Workspace::where('ulid', $workspaceUlid)->firstOrFail();
|
||||
$this->authorize('update', $workspace);
|
||||
|
|
@ -50,7 +52,7 @@ class LinkController extends Controller
|
|||
->where('workspace_id', $workspace->id)
|
||||
->firstOrFail();
|
||||
|
||||
$link->delete();
|
||||
$action->handle($link);
|
||||
|
||||
return response()->noContent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ class WorkspaceController extends Controller
|
|||
{
|
||||
$workspaces = $request->user()
|
||||
->workspaces()
|
||||
->get(['id', 'ulid', 'name', 'slug']);
|
||||
->select(['ulid', 'name', 'slug'])
|
||||
->paginate(50);
|
||||
|
||||
return response()->json(['data' => $workspaces]);
|
||||
return response()->json($workspaces);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,3 +31,34 @@ it('creates link via API', function () {
|
|||
$response->assertCreated()
|
||||
->assertJsonPath('data.target_url', 'https://example.com');
|
||||
});
|
||||
|
||||
it('deletes a link via API', function () {
|
||||
$user = User::factory()->create();
|
||||
$workspace = (new \App\Domains\Workspace\Actions\CreateWorkspace)->handle($user, ['name' => 'Test']);
|
||||
$link = Link::factory()->create(['workspace_id' => $workspace->id]);
|
||||
$token = $user->createToken('api-test')->plainTextToken;
|
||||
|
||||
$response = $this->withToken($token)
|
||||
->deleteJson("/api/v1/workspaces/{$workspace->ulid}/links/{$link->ulid}");
|
||||
|
||||
$response->assertNoContent();
|
||||
$this->assertSoftDeleted($link);
|
||||
});
|
||||
|
||||
it('rejects delete from non-member', function () {
|
||||
$owner = User::factory()->create();
|
||||
$outsider = User::factory()->create();
|
||||
$workspace = (new \App\Domains\Workspace\Actions\CreateWorkspace)->handle($owner, ['name' => 'Test']);
|
||||
$link = Link::factory()->create(['workspace_id' => $workspace->id]);
|
||||
$token = $outsider->createToken('api-test')->plainTextToken;
|
||||
|
||||
$response = $this->withToken($token)
|
||||
->deleteJson("/api/v1/workspaces/{$workspace->ulid}/links/{$link->ulid}");
|
||||
|
||||
$response->assertForbidden();
|
||||
});
|
||||
|
||||
it('rejects unauthenticated requests', function () {
|
||||
$response = $this->getJson('/api/v1/workspaces/ULID/links');
|
||||
$response->assertUnauthorized();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue