Skip to content

Commit bff6423

Browse files
committed
Edit series
1 parent a9d542f commit bff6423

File tree

11 files changed

+179
-2
lines changed

11 files changed

+179
-2
lines changed

app/Http/Controllers/Articles/SeriesController.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
use App\Http\Middleware\RedirectIfUnconfirmed;
88
use App\Http\Requests\SeriesRequest;
99
use App\Jobs\CreateSeries;
10+
use App\Jobs\UpdateSeries;
11+
use App\Models\Series;
1012
use App\Models\Tag;
13+
use App\Policies\SeriesPolicy;
1114

1215
class SeriesController extends Controller
1316
{
@@ -16,6 +19,11 @@ public function __construct()
1619
$this->middleware([Authenticate::class, RedirectIfUnconfirmed::class], ['except' => ['index', 'show']]);
1720
}
1821

22+
public function show(Series $series)
23+
{
24+
25+
}
26+
1927
public function create()
2028
{
2129
$tags = Tag::all();
@@ -32,4 +40,23 @@ public function store(SeriesRequest $request)
3240

3341
return redirect()->route('series.show', $series->id());
3442
}
43+
44+
public function edit(Series $series)
45+
{
46+
$this->authorize(SeriesPolicy::UPDATE, $series);
47+
$selectedTags = $series->tags()->pluck('id')->toArray();
48+
49+
return view('articles.series.edit', ['series' => $series, 'tags' => Tag::all(), 'selectedTags' => $selectedTags]);
50+
}
51+
52+
public function update(SeriesRequest $request, Series $series)
53+
{
54+
$this->authorize(SeriesPolicy::UPDATE, $series);
55+
56+
$series = $this->dispatchNow(UpdateSeries::fromRequest($series, $request));
57+
58+
$this->success('series.updated');
59+
60+
return redirect()->route('series.show', $series->id());
61+
}
3562
}

app/Jobs/UpdateSeries.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace App\Jobs;
4+
5+
use App\Http\Requests\SeriesRequest;
6+
use App\Models\Series;
7+
use Illuminate\Support\Arr;
8+
9+
final class UpdateSeries
10+
{
11+
private $series;
12+
13+
private $attributes;
14+
15+
public function __construct(Series $series, array $attributes = [])
16+
{
17+
$this->series = $series;
18+
$this->attributes = Arr::only($attributes, ['title', 'tags']);
19+
}
20+
21+
public static function fromRequest(Series $series, SeriesRequest $request): self
22+
{
23+
return new static($series, [
24+
'title' => $request->title(),
25+
'tags' => $request->tags(),
26+
]);
27+
}
28+
29+
public function handle(): Series
30+
{
31+
$this->series->update($this->attributes);
32+
33+
if (Arr::has($this->attributes, 'tags')) {
34+
$this->series->syncTags($this->attributes['tags']);
35+
}
36+
37+
$this->series->save();
38+
39+
return $this->series;
40+
}
41+
}

app/Policies/SeriesPolicy.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace App\Policies;
4+
5+
use App\Models\Series;
6+
use App\User;
7+
8+
final class SeriesPolicy
9+
{
10+
const UPDATE = 'update';
11+
const DELETE = 'delete';
12+
13+
public function update(User $user, Series $series): bool
14+
{
15+
return $series->isAuthoredBy($user) || $user->isModerator() || $user->isAdmin();
16+
}
17+
18+
public function delete(User $user, Series $series): bool
19+
{
20+
return $series->isAuthoredBy($user) || $user->isModerator() || $user->isAdmin();
21+
}
22+
}

app/Providers/AuthServiceProvider.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44

55
use App\Models\Article;
66
use App\Models\Reply;
7+
use App\Models\Series;
78
use App\Models\Thread;
89
use App\Policies\ArticlePolicy;
910
use App\Policies\NotificationPolicy;
1011
use App\Policies\ReplyPolicy;
12+
use App\Policies\SeriesPolicy;
1113
use App\Policies\ThreadPolicy;
1214
use App\Policies\UserPolicy;
1315
use App\User;
@@ -22,6 +24,7 @@ class AuthServiceProvider extends ServiceProvider
2224
Thread::class => ThreadPolicy::class,
2325
User::class => UserPolicy::class,
2426
Article::class => ArticlePolicy::class,
27+
Series::class => SeriesPolicy::class,
2528
];
2629

2730
/**

database/factories/SeriesFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
use App\Series;
3+
use App\Models\Series;
44
use Faker\Generator as Faker;
55

66
$factory->define(Series::class, function (Faker $faker) {

resources/lang/en/series.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
return [
44

55
'created' => 'Series successfully created!',
6+
'updated' => 'Series successfully updated!',
67

78
];
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
@title('Update series')
2+
3+
@extends('layouts.default')
4+
5+
@section('content')
6+
<div class="container mx-auto p-4 flex justify-center">
7+
<div class="w-full md:w-2/3 xl:w-1/2">
8+
<div class="md:p-4 md:border-2 md:rounded md:bg-gray-100">
9+
@include('articles.series._form', [
10+
'route' => ['series.update', $series->id()],
11+
'method' => 'PUT',
12+
])
13+
</div>
14+
</div>
15+
</div>
16+
@endsection

routes/web.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@
8383
Route::prefix('series')->group(function () {
8484
Route::get('/create', 'SeriesController@create')->name('series.create');
8585
Route::post('/', 'SeriesController@store')->name('series.store');
86+
Route::get('{series}', 'SeriesController@show')->name('series.show');
87+
Route::get('{series}/edit', 'SeriesController@edit')->name('series.edit');
88+
Route::put('{series}', 'SeriesController@update')->name('series.update');
8689
});
8790

8891
Route::get('/', 'ArticlesController@index')->name('articles');

tests/Feature/SeriesTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Tests\Feature;
44

55
use App\Models\Article;
6+
use App\Models\Series;
67
use App\Models\Tag;
78
use Illuminate\Foundation\Testing\DatabaseMigrations;
89

@@ -44,4 +45,41 @@ public function users_cannot_create_a_series_with_a_title_that_is_too_long()
4445
$response->assertSessionHas('error', 'Something went wrong. Please review the fields below.');
4546
$response->assertSessionHasErrors(['title' => 'The title may not be greater than 100 characters.']);
4647
}
48+
49+
/** @test */
50+
public function users_can_edit_a_series()
51+
{
52+
$user = $this->createUser();
53+
$tag = factory(Tag::class)->create(['name' => 'Test Tag']);
54+
factory(Series::class)->create([
55+
'author_id' => $user->id(),
56+
]);
57+
58+
$this->loginAs($user);
59+
60+
$this->put('/articles/series/1', [
61+
'title' => 'A developers guide to SVG',
62+
'tags' => [$tag->id()],
63+
])
64+
->assertRedirectedTo('/articles/series/1')
65+
->assertSessionHas('success', 'Series successfully updated!');
66+
}
67+
68+
/** @test */
69+
public function users_cannot_edit_a_series_with_a_title_that_is_too_long()
70+
{
71+
$user = $this->createUser();
72+
factory(Series::class)->create([
73+
'author_id' => $user->id()
74+
]);
75+
76+
$this->loginAs($user);
77+
78+
$response = $this->put('/articles/series/1', [
79+
'title' => 'A developers guide to SVG which is an image format written in XML which is highly customisable and flexible',
80+
]);
81+
82+
$response->assertSessionHas('error', 'Something went wrong. Please review the fields below.');
83+
$response->assertSessionHasErrors(['title' => 'The title may not be greater than 100 characters.']);
84+
}
4785
}

tests/Integration/Jobs/UpdateArticleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class UpdateArticleTest extends TestCase
1212
use DatabaseMigrations;
1313

1414
/** @test */
15-
public function we_can_create_an_article()
15+
public function we_can_update_an_article()
1616
{
1717
$user = $this->createUser();
1818
$article = factory(Article::class)->create(['author_id' => $user->id()]);

0 commit comments

Comments
 (0)