From aa324c48954ad97606753b896944ece24f1b76bd Mon Sep 17 00:00:00 2001 From: Chri$ Date: Tue, 8 Oct 2024 15:53:18 +0200 Subject: [PATCH] feat:LAR-8 refactor create article process with action and add features test --- app/Actions/Article/CreateArticleAction.php | 61 +++++++++++++++++++ app/Data/Article/CreateArticleData.php | 23 +++++++ app/Gamify/Points/ArticleCreated.php | 25 ++++++++ app/Livewire/Articles/Create.php | 40 ++---------- .../Article/createArticleActionTest.php | 42 +++++++++++++ 5 files changed, 156 insertions(+), 35 deletions(-) create mode 100644 app/Actions/Article/CreateArticleAction.php create mode 100644 app/Data/Article/CreateArticleData.php create mode 100644 app/Gamify/Points/ArticleCreated.php create mode 100644 tests/Feature/Actions/Article/createArticleActionTest.php diff --git a/app/Actions/Article/CreateArticleAction.php b/app/Actions/Article/CreateArticleAction.php new file mode 100644 index 00000000..72ec360f --- /dev/null +++ b/app/Actions/Article/CreateArticleAction.php @@ -0,0 +1,61 @@ +published_at && !($articleData->published_at instanceof DateTimeInterface)) { + $articleData->published_at = new Carbon( + time: $articleData->published_at, + tz: config('app.timezone') + ); + } + + /** @var Article $article */ + $article = Article::query()->create([ + 'title' => $articleData->title, + 'slug' => $articleData->title, + 'body' => $articleData->body, + 'published_at' => $articleData->published_at, + 'submitted_at' => $articleData->submitted_at, + 'approved_at' => $articleData->approved_at, + 'show_toc' => $articleData->show_toc, + 'canonical_url' => $articleData->canonical_url, + 'user_id' => Auth::id(), + ]); + + if (collect($article->associateTags)->isNotEmpty()) { + $article->syncTags(tags: $article->associateTags); + } + + if ($article->file) { + $article->addMedia($article->file->getRealPath())->toMediaCollection('media'); + } + + if ($article->isAwaitingApproval()) { + // Envoi de la notification sur le channel Telegram pour la validation de l'article. + Auth::user()?->notify(new PostArticleToTelegram($article)); + session()->flash('status', __('Merci d\'avoir soumis votre article. Vous aurez des nouvelles que lorsque nous accepterons votre article.')); + } + + if (Auth::user()?->hasAnyRole(['admin', 'moderator'])) { + givePoint(new ArticleCreated($article)); + } + + + return $article; + } +} diff --git a/app/Data/Article/CreateArticleData.php b/app/Data/Article/CreateArticleData.php new file mode 100644 index 00000000..49a5cf67 --- /dev/null +++ b/app/Data/Article/CreateArticleData.php @@ -0,0 +1,23 @@ +subject = $subject; + } + + public function payee(): User + { + // @phpstan-ignore-next-line + return $this->getSubject()->user; + } +} diff --git a/app/Livewire/Articles/Create.php b/app/Livewire/Articles/Create.php index df3202c5..f7c9cd6a 100644 --- a/app/Livewire/Articles/Create.php +++ b/app/Livewire/Articles/Create.php @@ -4,15 +4,13 @@ namespace App\Livewire\Articles; -use App\Events\ArticleWasSubmittedForApproval; -use App\Gamify\Points\PostCreated; -use App\Models\Article; +use App\Actions\Article\CreateArticleAction; +use App\Data\Article\CreateArticleData; use App\Models\Tag; use App\Models\User; use App\Traits\WithArticleAttributes; use App\Traits\WithTagsAssociation; -use Carbon\Carbon; -use DateTimeInterface; + use Illuminate\Contracts\View\View; use Illuminate\Support\Facades\Auth; use Livewire\Component; @@ -52,15 +50,7 @@ public function store(): void /** @var User $user */ $user = Auth::user(); - if ($this->published_at && ! ($this->published_at instanceof DateTimeInterface)) { - $this->published_at = new Carbon( - time: $this->published_at, - tz: config('app.timezone') - ); - } - - /** @var Article $article */ - $article = Article::create([ + $article = app(CreateArticleAction::class)->execute(CreateArticleData::from([ 'title' => $this->title, 'slug' => $this->slug, 'body' => $this->body, @@ -70,28 +60,8 @@ public function store(): void 'show_toc' => $this->show_toc, 'canonical_url' => $this->canonical_url, 'user_id' => $user->id, - ]); - - if (collect($this->associateTags)->isNotEmpty()) { - $article->syncTags(tags: $this->associateTags); - } - - if ($this->file) { - $article->addMedia($this->file->getRealPath())->toMediaCollection('media'); - } - - if ($article->isAwaitingApproval()) { - if (app()->environment('production')) { - // Envoi de la notification sur le channel Telegram pour la validation de l'article. - event(new ArticleWasSubmittedForApproval($article)); - } - - session()->flash('status', __('Merci d\'avoir soumis votre article. Vous aurez des nouvelles que lorsque nous accepterons votre article.')); - } + ])); - if ($user->hasAnyRole(['admin', 'moderator'])) { - givePoint(new PostCreated($article)); - } $user->hasRole('user') ? $this->redirectRoute('dashboard') : diff --git a/tests/Feature/Actions/Article/createArticleActionTest.php b/tests/Feature/Actions/Article/createArticleActionTest.php new file mode 100644 index 00000000..e2c21f7e --- /dev/null +++ b/tests/Feature/Actions/Article/createArticleActionTest.php @@ -0,0 +1,42 @@ +user = $this->login(); + $this->tagOne = Tag::factory()->create(['name' => 'Tag 1', 'concerns' => ['article']]); + $this->tagTwo = Tag::factory()->create(['name' => 'Tag 2', 'concerns' => ['article', 'post']]); +}); + + +describe(CreateArticleAction::class, function (): void { + it('return the created article', function (): void { + $articleDataWithoutTag = CreateArticleData::from([ + 'title' => 'Article title', + 'slug' => 'Article slug', + 'published_at' => Now(), + 'submitted_at' => null, + 'approved_at' => null, + 'show_toc' => 'Article show_toc', + 'canonical_url' => 'Article canonical_url', + 'body' => 'Article body', + 'associateTags' => [], + ]); + + $article = app(CreateArticleAction::class)->execute($articleDataWithoutTag); + + expect($article) + ->toBeInstanceOf(Article::class) + ->and($article->tags) + ->toHaveCount(0) + ->and($article->user_id) + ->toBe($this->user->id); + }); +})->group('Articles');