Skip to content

Commit

Permalink
#183: Test written for article form and index
Browse files Browse the repository at this point in the history
  • Loading branch information
alimranahmed committed Aug 1, 2024
1 parent 143eff4 commit 0e6088c
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 5 deletions.
8 changes: 4 additions & 4 deletions app/Livewire/Backend/Article/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ class Form extends Component
'articleData.meta.image_url' => 'nullable|url',
];

public function mount(?Article $article = null): void
public function mount($article = null): void
{
if ($article->id) {
if ($article?->id) {
$this->originalArticle = $article;
$this->articleData = $article->toArray();
$this->articleData['keywords'] = $article->keywords->pluck('name')->implode(' ');
$this->articleData['meta'] = $article->meta ?: [];
}

$this->method = $article->id ? 'put' : 'post';
$this->method = $article?->id ? 'put' : 'post';
}

public function render(): View
Expand Down Expand Up @@ -75,7 +75,7 @@ protected function store(array $articleData): void
$newArticle = Article::query()->create($articleData);

//add keywords
$keywordsToAttach = array_unique(explode(' ', Arr::get($this->article, 'keywords')));
$keywordsToAttach = array_unique(explode(' ', Arr::get($this->articleData, 'keywords')));

foreach ($keywordsToAttach as $keywordToAttach) {
if (empty($keywordToAttach)) {
Expand Down
3 changes: 2 additions & 1 deletion database/factories/ArticleFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Database\Factories;

use App\Models\Article;
use App\Models\Category;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

Expand All @@ -26,7 +27,7 @@ public function definition(): array
'user_id' => null,
'language' => $language = $this->faker->randomElement(['ben', 'eng']),
'slug' => Str::slug($heading, '-', $language),
'category_id' => null,
'category_id' => Category::factory()->create()->id,
];
}

Expand Down
135 changes: 135 additions & 0 deletions tests/Feature/Livewire/Backend/Article/FormTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

namespace Tests\Feature\Livewire\Backend\Article;

use App\Livewire\Backend\Article\Form;
use App\Livewire\Backend\Config\Index;
use App\Mail\NotifySubscriberForNewArticle;
use App\Models\Article;
use App\Models\Category;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use Livewire\Livewire;
use Symfony\Component\HttpFoundation\Response;
use Tests\TestCase;

class FormTest extends TestCase
{

public function testRender(): void
{
Livewire::test(Form::class)
->assertStatus(Response::HTTP_OK)
->assertViewIs('livewire.backend.article.form')
->assertViewHas('categories');
}

public function test_initializes_correctly_without_article()
{
Livewire::test(Form::class)
->assertSet('method', 'post')
->assertSet('articleData', []);
}

public function test_initializes_correctly_with_article()
{
$article = Article::factory()->create();
Livewire::test(Form::class, ['article' => $article])
->assertSet('method', 'put')
->assertSet('articleData.heading', $article->heading)
->assertSet('articleData.slug', $article->slug)
->assertSet('articleData.category_id', $article->category_id);
}

public function test_generates_slug_when_heading_changes()
{
Livewire::test(Form::class)
->set('articleData.heading', 'New Article')
->set('articleData.language', 'en')
->assertSet('articleData.slug', Str::slug('New Article'));
}

public function test_validates_article_data_correctly()
{
Livewire::test(Form::class)
->set('articleData.heading', '')
->set('articleData.slug', '')
->set('articleData.category_id', null)
->set('articleData.content', '')
->set('articleData.language', '')
->call('submit')
->assertHasErrors([
'articleData.heading' => 'required',
'articleData.slug' => 'required',
'articleData.category_id' => 'required',
'articleData.content' => 'required',
'articleData.language' => 'required',
]);
}

public function test_stores_a_new_article_correctly()
{
Mail::fake();
Auth::loginUsingId(User::factory()->create()->id);

$category = Category::factory()->create();
$data = [
'heading' => 'Test Article',
'slug' => 'test-article',
'category_id' => $category->id,
'content' => 'This is a test article.',
'language' => 'en',
'is_comment_enabled' => true,
'meta' => [
'description' => 'Test description',
'image_url' => 'http://example.com/image.jpg',
],
'keywords' => 'test article',
];

Livewire::test(Form::class, ['article' => null])
->set('articleData', $data)
->call('submit')
->assertSessionHas('success', 'Article published successfully!');

$this->assertDatabaseHas('articles', ['heading' => 'Test Article']);
$this->assertDatabaseHas('keywords', ['name' => 'test']);
$this->assertDatabaseHas('keywords', ['name' => 'article']);
Mail::assertQueued(NotifySubscriberForNewArticle::class);
}

public function test_updates_an_existing_article_correctly()
{
Mail::fake();
Auth::loginUsingId(User::factory()->create()->id);

$article = Article::factory()->create();
$data = [
'heading' => 'Updated Article',
'slug' => 'updated-article',
'category_id' => $article->category_id,
'content' => 'This is an updated article.',
'language' => 'en',
'is_comment_enabled' => true,
'meta' => [
'description' => 'Updated description',
'image_url' => 'http://example.com/updated-image.jpg',
],
'keywords' => 'updated article',
];

Livewire::test(Form::class, ['article' => $article])
->set('articleData', $data)
->call('submit')
->assertSessionHas('successMsg', 'Article updated successfully!');

$this->assertDatabaseHas('articles', [
'id' => $article->id,
'heading' => 'Updated Article'
]);
$this->assertDatabaseHas('keywords', ['name' => 'updated']);
$this->assertDatabaseHas('keywords', ['name' => 'article']);
}
}
76 changes: 76 additions & 0 deletions tests/Feature/Livewire/Backend/Article/IndexTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace Tests\Feature\Livewire\Backend\Article;

use App\Livewire\Backend\Article\Index;
use App\Models\Article;
use App\Models\Category;
use App\Models\Keyword;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Livewire\Livewire;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

class IndexTest extends TestCase
{
public function setUp(): void
{
parent::setUp();
$user = User::factory()->create();
$author = Role::findOrCreate('author');
$user->assignRole($author);
Auth::loginUsingId($user->id);
}
public function testItRendersCorrectly()
{
Auth::loginUsingId(User::factory()->create()->id);

Livewire::test(Index::class)
->assertStatus(200)
->assertViewIs('livewire.backend.article.index');
}

public function testItFiltersArticlesBasedOnCategory()
{
$category = Category::factory()->create();
Article::factory()->count(3)->create(['category_id' => $category->id]);
Article::factory()->count(2)->create(); // Articles in different categories

Livewire::test(Index::class)
->set('category', $category->id)
->assertSeeInOrder([$category->name], 'category')
->assertViewHas('articles', function ($articles) use ($category) {
return $articles->every(fn($article) => $article->category_id === $category->id);
});
}

public function testItFiltersArticlesBasedOnKeyword()
{
$keyword = Keyword::factory()->create();
$articleWithKeyword = Article::factory()->create();
$articleWithKeyword->keywords()->attach($keyword);

Article::factory()->count(2)->create(); // Articles without the keyword

Livewire::test(Index::class)
->set('keyword', $keyword->name)
->assertSeeInOrder([$keyword->name], 'keywords')
->assertViewHas('articles', function ($articles) use ($keyword) {
return $articles->every(fn($article) => $article->keywords->contains($keyword));
});
}

public function testItFiltersArticlesBasedOnSearchQuery()
{
$query = 'Unique Title';
Article::factory()->create(['heading' => $query]);
Article::factory()->count(2)->create(['heading' => 'Other Title']);

Livewire::test(Index::class)
->set('query', $query)
->assertViewHas('articles', function ($articles) use ($query) {
return $articles->every(fn($article) => stripos($article->heading, $query) !== false);
});
}
}

0 comments on commit 0e6088c

Please sign in to comment.