add bookmark back
This commit is contained in:
57
app/Http/Controllers/BookmarkController.php
Normal file
57
app/Http/Controllers/BookmarkController.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\BookmarkRequest;
|
||||
use App\Http\Resources\BookmarkCollection;
|
||||
use App\Models\Bookmark;
|
||||
use App\Http\Resources\Bookmark as BookmarkResource;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BookmarkController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('viewAny', Bookmark::class);
|
||||
|
||||
return new BookmarkCollection(request()->user()->bookmarks);
|
||||
}
|
||||
|
||||
public function store(BookmarkRequest $request)
|
||||
{
|
||||
$this->authorize('create', Bookmark::class);
|
||||
|
||||
$bookmark = request()->user()->bookmarks()->create($request->all());
|
||||
|
||||
return (new BookmarkResource($bookmark))
|
||||
->response()
|
||||
->setStatusCode(201);
|
||||
}
|
||||
|
||||
public function show(Bookmark $bookmark)
|
||||
{
|
||||
$this->authorize('view', $bookmark);
|
||||
|
||||
return new BookmarkResource($bookmark);
|
||||
}
|
||||
|
||||
public function update(BookmarkRequest $request, Bookmark $bookmark)
|
||||
{
|
||||
$this->authorize('update', $bookmark);
|
||||
|
||||
$bookmark->update($request->all());
|
||||
|
||||
return (new BookmarkResource($bookmark))
|
||||
->response()
|
||||
->setStatusCode(200);
|
||||
}
|
||||
|
||||
public function destroy(Bookmark $bookmark)
|
||||
{
|
||||
$this->authorize('delete', $bookmark);
|
||||
|
||||
$bookmark->delete();
|
||||
|
||||
return response([], 204);
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/BookmarkRequest.php
Normal file
31
app/Http/Requests/BookmarkRequest.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class BookmarkRequest extends FormRequest
|
||||
{
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => 'max:65',
|
||||
'url' => ['required', 'url', 'max:255'],
|
||||
'favicon' => ['url', 'max:255'],
|
||||
];
|
||||
}
|
||||
|
||||
public function attributes()
|
||||
{
|
||||
return [
|
||||
'name' => 'Nom du marque-page',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'url.required' => 'Une url est nécessaire',
|
||||
];
|
||||
}
|
||||
}
|
||||
33
app/Http/Resources/Bookmark.php
Normal file
33
app/Http/Resources/Bookmark.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class Bookmark extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'data' => [
|
||||
'type' => 'bookmark',
|
||||
'bookmark_id' => $this->id,
|
||||
'attributes' => [
|
||||
'data' => [
|
||||
'name' => $this->name,
|
||||
'url' => $this->url,
|
||||
'favicon' => $this->favicon,
|
||||
'created_at' => $this->created_at->diffForHumans(),
|
||||
'last_updated' => $this->updated_at->diffForHumans(),
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
25
app/Http/Resources/BookmarkCollection.php
Normal file
25
app/Http/Resources/BookmarkCollection.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class BookmarkCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'data' => $this->collection,
|
||||
'bookmarks_count' => $this->count(),
|
||||
'links' => [
|
||||
'self' => url('/bookmarks'),
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
10
app/Models/Bookmark.php
Normal file
10
app/Models/Bookmark.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Bookmark extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App;
|
||||
|
||||
use App\Models\Bookmark;
|
||||
use App\Models\Image;
|
||||
use App\Models\Memo;
|
||||
use App\Models\ToDoList;
|
||||
@@ -64,6 +65,11 @@ class User extends Authenticatable
|
||||
return $this->hasMany(ToDoList::class);
|
||||
}
|
||||
|
||||
public function bookmarks() : HasMany
|
||||
{
|
||||
return $this->hasMany(Bookmark::class);
|
||||
}
|
||||
|
||||
public function images(): MorphMany
|
||||
{
|
||||
return $this->morphMany(Image::class, 'imageable');
|
||||
|
||||
94
app/Policies/BookmarkPolicy.php
Normal file
94
app/Policies/BookmarkPolicy.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Bookmark;
|
||||
use App\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class BookmarkPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any bookmarks.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function viewAny(User $user)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the bookmark.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\Models\Bookmark $bookmark
|
||||
* @return mixed
|
||||
*/
|
||||
public function view(User $user, Bookmark $bookmark)
|
||||
{
|
||||
return $user->id == $bookmark->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create bookmarks.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function create(User $user)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the bookmark.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\Models\Bookmark $bookmark
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(User $user, Bookmark $bookmark)
|
||||
{
|
||||
return $user->id == $bookmark->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the bookmark.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\Models\Bookmark $bookmark
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete(User $user, Bookmark $bookmark)
|
||||
{
|
||||
return $user->id == $bookmark->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the bookmark.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\Models\Bookmark $bookmark
|
||||
* @return mixed
|
||||
*/
|
||||
public function restore(User $user, Bookmark $bookmark)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the bookmark.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\Models\Bookmark $bookmark
|
||||
* @return mixed
|
||||
*/
|
||||
public function forceDelete(User $user, Bookmark $bookmark)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ class AuthServiceProvider extends ServiceProvider
|
||||
'App\User' => 'App\Policies\UserPolicy',
|
||||
'App\Models\Memo' => 'App\Policies\MemoPolicy',
|
||||
'App\Models\ToDoList' => 'App\Policies\ToDoListPolicy',
|
||||
'App\Models\Bookmark' => 'App\Policies\BookmarkPolicy',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
15
database/factories/BookmarkFactory.php
Normal file
15
database/factories/BookmarkFactory.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
||||
|
||||
use App\Models\Bookmark;
|
||||
use Faker\Generator as Faker;
|
||||
|
||||
$factory->define(Bookmark::class, function (Faker $faker) {
|
||||
return [
|
||||
'user_id' => factory(\App\User::class),
|
||||
'name' => $faker->words(3, [false]),
|
||||
'url' => $faker->url,
|
||||
'favicon' => $faker->imageUrl(),
|
||||
];
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateBookmarksTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('bookmarks', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('user_id');
|
||||
$table->string('name')->nullable();
|
||||
$table->string('url');
|
||||
$table->string('favicon')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('bookmarks');
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ Route::middleware('auth:api')->group(function () {
|
||||
'/meteo' => 'MeteoController',
|
||||
'/to-do-lists' => 'ToDoListController',
|
||||
'/to-do-lists/{toDoList}/to-do' => 'ToDoController',
|
||||
'/bookmarks' => 'BookmarkController',
|
||||
// '/users/{user}/posts' => 'UserPostController',
|
||||
// '/friend-request' => 'FriendRequestController',
|
||||
]);
|
||||
|
||||
212
tests/Feature/BookmarkTest.php
Normal file
212
tests/Feature/BookmarkTest.php
Normal file
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Bookmark;
|
||||
use App\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Foundation\Testing\WithFaker;
|
||||
use Tests\TestCase;
|
||||
|
||||
class BookmarkTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/** @test */
|
||||
public function an_unauthenticated_user_can_add_a_bookmark()
|
||||
{
|
||||
$this->withoutExceptionHandling();
|
||||
|
||||
$this->actingAs($user = factory(\App\User::class)->create(), 'api');
|
||||
|
||||
$response = $this->post('/api/bookmarks', $this->data());
|
||||
|
||||
$bookmark = Bookmark::first();
|
||||
|
||||
$this->assertCount(1, Bookmark::all());
|
||||
$this->assertEquals('Test Name', $bookmark->name);
|
||||
$this->assertEquals('https://portal.bricooli.fr', $bookmark->url);
|
||||
$this->assertEquals('https://portal.bricooli.fr/img/logo.svg', $bookmark->favicon);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJson([
|
||||
'data' => [
|
||||
'type' => 'bookmark',
|
||||
'bookmark_id' => $bookmark->id,
|
||||
'attributes' => [
|
||||
'data' => [
|
||||
'name' => $bookmark->name,
|
||||
'url' => $bookmark->url,
|
||||
'favicon' => $bookmark->favicon,
|
||||
]
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function bookmark_url_are_required()
|
||||
{
|
||||
$this->actingAs($user = factory(\App\User::class)->create(), 'api');
|
||||
$response = $this->post('/api/bookmarks', array_merge($this->data(), ['url' => '']));
|
||||
|
||||
$response->assertSessionHasErrors('url');
|
||||
$this->assertCount(0, Bookmark::all());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function a_bookmark_can_be_retrieved()
|
||||
{
|
||||
$this->actingAs($user = factory(User::class)->create(), 'api');
|
||||
$bookmark = factory(Bookmark::class)->create(['user_id' => $user->id]);
|
||||
|
||||
$response = $this->get('/api/bookmarks/' . $bookmark->id );
|
||||
|
||||
$response->assertJson([
|
||||
'data' => [
|
||||
'bookmark_id' => $bookmark->id,
|
||||
'attributes' => [
|
||||
'data' => [
|
||||
'name' => $bookmark->name,
|
||||
'url' => $bookmark->url,
|
||||
'favicon' => $bookmark->favicon,
|
||||
'last_updated' => $bookmark->updated_at->diffForHumans(),
|
||||
]
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function a_user_can_retrueved_all_this_to_do_lists()
|
||||
{
|
||||
$this->actingAs($user = factory(User::class)->create(), 'api');
|
||||
$bookmarkOne = factory(Bookmark::class)->create(['user_id' => $user->id]);
|
||||
$bookmarkTwo = factory(Bookmark::class)->create(['user_id' => $user->id]);
|
||||
|
||||
$response = $this->get('/api/bookmarks');
|
||||
|
||||
$response->assertJson([
|
||||
'data' => [
|
||||
[
|
||||
'data' => [
|
||||
'bookmark_id' => $bookmarkOne->id,
|
||||
'attributes' => [
|
||||
'data' => [
|
||||
'name' => $bookmarkOne->name,
|
||||
'last_updated' => $bookmarkOne->updated_at->diffForHumans(),
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'data' => [
|
||||
'bookmark_id' => $bookmarkTwo->id,
|
||||
'attributes' => [
|
||||
'data' => [
|
||||
'name' => $bookmarkTwo->name,
|
||||
'last_updated' => $bookmarkTwo->updated_at->diffForHumans(),
|
||||
]
|
||||
],
|
||||
],
|
||||
]
|
||||
],
|
||||
'links' => [
|
||||
'self' => url('/bookmarks'),
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function only_owner_bookmark_can_retrieved_it()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
$bookmark = factory(Bookmark::class)->create(['user_id' => $user->id]);
|
||||
|
||||
$this->actingAs($userAnother = factory(User::class)->create(), 'api');
|
||||
|
||||
$response = $this->get('/api/bookmarks/' . $bookmark->id );
|
||||
|
||||
$response->assertStatus(403);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function a_to_bookmark_can_be_patch()
|
||||
{
|
||||
$this->withoutExceptionHandling();
|
||||
$this->actingAs($user = factory(User::class)->create(), 'api');
|
||||
$bookmark = factory(Bookmark::class)->create(['user_id' => $user->id]);
|
||||
|
||||
$response = $this->patch('/api/bookmarks/' . $bookmark->id, [
|
||||
'name' => 'Bookmark Update',
|
||||
'url' => 'https://portal.bricooli.fr',
|
||||
]);
|
||||
|
||||
$bookmark = $bookmark->fresh();
|
||||
|
||||
$this->assertEquals('Bookmark Update', $bookmark->name);
|
||||
$this->assertEquals('https://portal.bricooli.fr', $bookmark->url);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJson([
|
||||
'data' => [
|
||||
'bookmark_id' => $bookmark->id,
|
||||
'attributes' => [
|
||||
'data' => [
|
||||
'name' => 'Bookmark Update'
|
||||
]
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function only_the_owner_can_patch_the_bookmark()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
$bookmark = factory(Bookmark::class)->create(['id' => 123, 'user_id' => $user->id]);
|
||||
|
||||
$this->actingAs($anotherUser = factory(User::class)->create(), 'api');
|
||||
|
||||
$this->patch('/api/bookmarks/'. $bookmark->id, ['url' => 'https://portal.bricooli.fr'])
|
||||
->assertStatus(403);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function a_bookmark_can_be_delete()
|
||||
{
|
||||
$this->actingAs($user = factory(User::class)->create(), 'api');
|
||||
|
||||
$bookmark = factory(Bookmark::class)->create(['user_id' => $user->id]);
|
||||
|
||||
$response = $this->delete('/api/bookmarks/' . $bookmark->id);
|
||||
|
||||
$toDoList = $bookmark->fresh();
|
||||
|
||||
$this->assertCount(0, Bookmark::all());
|
||||
|
||||
$response->assertStatus(204);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function only_the_owner_can_delete_the_bookmark()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
$bookmark = factory(Bookmark::class)->create();
|
||||
|
||||
$this->actingAs($anotherUser = factory(User::class)->create(), 'api');
|
||||
|
||||
$response = $this->delete('/api/bookmarks/' . $bookmark->id);
|
||||
|
||||
$response->assertStatus(403);
|
||||
}
|
||||
|
||||
private function data()
|
||||
{
|
||||
return [
|
||||
'name' => 'Test Name',
|
||||
'url' => 'https://portal.bricooli.fr',
|
||||
'favicon' => 'https://portal.bricooli.fr/img/logo.svg',
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user