4.1-4.3: add PHPUnit feature tests for all endpoints + factories

This commit is contained in:
parsa aghaei 2026-06-23 18:37:14 +03:30
parent afb202f333
commit 9ff5b93157
16 changed files with 504 additions and 37 deletions

View File

@ -0,0 +1,17 @@
<?php
namespace Database\Factories\Website;
use Illuminate\Database\Eloquent\Factories\Factory;
class AboutMeFactory extends Factory
{
protected $model = \App\Models\Website\AboutMe::class;
public function definition(): array
{
return [
'image' => $this->faker->imageUrl(),
];
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace Database\Factories\Website;
use Illuminate\Database\Eloquent\Factories\Factory;
class ProjectCategoryFactory extends Factory
{
protected $model = \App\Models\Website\ProjectCategory::class;
public function definition(): array
{
return [
'image' => $this->faker->imageUrl(),
];
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Database\Factories\Website;
use Illuminate\Database\Eloquent\Factories\Factory;
class ProjectFactory extends Factory
{
protected $model = \App\Models\Website\Project::class;
public function definition(): array
{
return [
'category_id' => \App\Models\Website\ProjectCategory::factory(),
'image1' => $this->faker->imageUrl(),
'image2' => $this->faker->imageUrl(),
];
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace Database\Factories\Website;
use Illuminate\Database\Eloquent\Factories\Factory;
class ServiceFactory extends Factory
{
protected $model = \App\Models\Website\Service::class;
public function definition(): array
{
return [
'imageSrc' => $this->faker->imageUrl(),
];
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Database\Factories\Website;
use Illuminate\Database\Eloquent\Factories\Factory;
class SkillFactory extends Factory
{
protected $model = \App\Models\Website\Skill::class;
public function definition(): array
{
return [
'image' => $this->faker->imageUrl(),
'link' => $this->faker->url(),
'percentage' => $this->faker->numberBetween(10, 100),
'about_me_id' => \App\Models\Website\AboutMe::factory(),
];
}
}

View File

@ -22,8 +22,8 @@
<env name="APP_MAINTENANCE_DRIVER" value="file"/> <env name="APP_MAINTENANCE_DRIVER" value="file"/>
<env name="BCRYPT_ROUNDS" value="4"/> <env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_STORE" value="array"/> <env name="CACHE_STORE" value="array"/>
<!-- <env name="DB_CONNECTION" value="sqlite"/> --> <env name="DB_CONNECTION" value="sqlite"/>
<!-- <env name="DB_DATABASE" value=":memory:"/> --> <env name="DB_DATABASE" value=":memory:"/>
<env name="MAIL_MAILER" value="array"/> <env name="MAIL_MAILER" value="array"/>
<env name="PULSE_ENABLED" value="false"/> <env name="PULSE_ENABLED" value="false"/>
<env name="QUEUE_CONNECTION" value="sync"/> <env name="QUEUE_CONNECTION" value="sync"/>

View File

@ -0,0 +1,61 @@
<?php
namespace Tests\Feature\Blog;
use App\Models\Blog\Category;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class CategoryTest extends TestCase
{
use RefreshDatabase;
public function test_can_list_categories()
{
Category::factory()->count(3)->create();
$response = $this->getJson('/api/blog/categories');
$response->assertStatus(200);
}
public function test_can_get_single_category()
{
$category = Category::factory()->create();
$response = $this->getJson("/api/blog/categories/{$category->id}");
$response->assertStatus(200);
}
public function test_can_get_category_posts()
{
$category = Category::factory()->create();
$response = $this->getJson("/api/blog/categories/{$category->slug}/posts");
$response->assertStatus(200)
->assertJsonStructure(['category', 'posts', 'meta', 'links']);
}
public function test_can_create_category()
{
$response = $this->postJson('/api/blog/categories', [
'name' => 'Tech',
'slug' => 'tech',
]);
$response->assertStatus(201);
$this->assertDatabaseHas('categories', ['slug' => 'tech']);
}
public function test_can_delete_category()
{
$category = Category::factory()->create();
$response = $this->deleteJson("/api/blog/categories/{$category->id}");
$response->assertStatus(200);
$this->assertDatabaseMissing('categories', ['id' => $category->id]);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Tests\Feature\Blog;
use App\Models\Blog\Category;
use App\Models\Blog\Post;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class HomeTest extends TestCase
{
use RefreshDatabase;
public function test_can_get_homepage()
{
Post::factory()->count(5)->create();
Category::factory()->count(3)->create();
$response = $this->getJson('/api/blog/homepage');
$response->assertStatus(200)
->assertJsonStructure([
'latest_posts',
'latest_categories',
'most_viewed_posts',
'random_posts',
]);
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace Tests\Feature\Blog;
use App\Models\Blog\Category;
use App\Models\Blog\Post;
use App\Models\Blog\Tag;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class PostTest extends TestCase
{
use RefreshDatabase;
public function test_can_list_posts()
{
Post::factory()->count(3)->create();
$response = $this->getJson('/api/blog/posts');
$response->assertStatus(200);
}
public function test_can_get_single_post()
{
$post = Post::factory()->create();
$response = $this->getJson("/api/blog/posts/{$post->slug}");
$response->assertStatus(200)
->assertJsonStructure(['post', 'related_posts']);
}
public function test_can_create_post()
{
$category = Category::factory()->create();
$user = User::factory()->create();
$response = $this->postJson('/api/blog/posts', [
'title' => 'Test Post',
'body' => 'Content',
'slug' => 'test-post',
'category_id' => $category->id,
'author_id' => $user->id,
]);
$response->assertStatus(201);
$this->assertDatabaseHas('posts', ['slug' => 'test-post']);
}
public function test_can_update_post()
{
$post = Post::factory()->create();
$response = $this->putJson("/api/blog/posts/{$post->id}", [
'title' => 'Updated',
]);
$response->assertStatus(200);
}
public function test_can_delete_post()
{
$post = Post::factory()->create();
$response = $this->deleteJson("/api/blog/posts/{$post->id}");
$response->assertStatus(200);
$this->assertDatabaseMissing('posts', ['id' => $post->id]);
}
public function test_can_filter_posts()
{
Post::factory()->count(3)->create();
$response = $this->getJson('/api/blog/posts?per_page=2');
$response->assertStatus(200);
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace Tests\Feature\Blog;
use App\Models\Blog\Tag;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class TagTest extends TestCase
{
use RefreshDatabase;
public function test_can_list_tags()
{
Tag::factory()->count(3)->create();
$response = $this->getJson('/api/blog/tags');
$response->assertStatus(200);
}
public function test_can_get_single_tag()
{
$tag = Tag::factory()->create();
$response = $this->getJson("/api/blog/tags/{$tag->id}");
$response->assertStatus(200);
}
public function test_can_create_tag()
{
$response = $this->postJson('/api/blog/tags', [
'name' => 'Laravel',
'slug' => 'laravel',
]);
$response->assertStatus(201);
$this->assertDatabaseHas('tags', ['slug' => 'laravel']);
}
public function test_can_delete_tag()
{
$tag = Tag::factory()->create();
$response = $this->deleteJson("/api/blog/tags/{$tag->id}");
$response->assertStatus(200);
$this->assertDatabaseMissing('tags', ['id' => $tag->id]);
}
}

View File

@ -1,19 +0,0 @@
<?php
namespace Tests\Feature;
// use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*/
public function test_the_application_returns_a_successful_response(): void
{
$response = $this->get('/');
$response->assertStatus(200);
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace Tests\Feature\Website;
use App\Models\Website\AboutMe;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AboutMeTest extends TestCase
{
use RefreshDatabase;
public function test_can_get_about_me()
{
$aboutMe = AboutMe::factory()->create();
$response = $this->getJson('/api/website/about-me');
$response->assertStatus(200);
}
public function test_can_get_about_me_translation()
{
$aboutMe = AboutMe::factory()->create();
$aboutMe->setTranslation('title', 'en', 'Hello');
$aboutMe->setTranslation('description', 'en', 'Description');
$aboutMe->save();
$response = $this->getJson("/api/website/about-me/{$aboutMe->id}/translation/en");
$response->assertStatus(200)
->assertJson(['title' => 'Hello']);
}
public function test_returns_404_for_missing_translation()
{
$aboutMe = AboutMe::factory()->create();
$response = $this->getJson("/api/website/about-me/{$aboutMe->id}/translation/de");
$response->assertStatus(404);
}
public function test_can_create_about_me()
{
$response = $this->postJson('/api/website/about-me', [
'image' => 'test.jpg',
]);
$response->assertStatus(201);
$this->assertDatabaseHas('website_about_me', ['image' => 'test.jpg']);
}
public function test_can_update_about_me()
{
$aboutMe = AboutMe::factory()->create();
$response = $this->putJson("/api/website/about-me/{$aboutMe->id}", [
'image' => 'updated.jpg',
]);
$response->assertStatus(200);
$this->assertDatabaseHas('website_about_me', ['image' => 'updated.jpg']);
}
public function test_can_delete_about_me()
{
$aboutMe = AboutMe::factory()->create();
$response = $this->deleteJson("/api/website/about-me/{$aboutMe->id}");
$response->assertStatus(204);
$this->assertDatabaseMissing('website_about_me', ['id' => $aboutMe->id]);
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace Tests\Feature\Website;
use App\Models\Website\Project;
use App\Models\Website\ProjectCategory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ProjectTest extends TestCase
{
use RefreshDatabase;
public function test_can_list_projects()
{
$category = ProjectCategory::factory()->create();
$category->setTranslation('title', 'fa', 'دسته');
$category->save();
$project = Project::factory()->create(['category_id' => $category->id]);
$project->setTranslation('title', 'fa', 'پروژه');
$project->setTranslation('description', 'fa', 'توضیحات');
$project->save();
$response = $this->getJson('/api/website/projects/translation/fa');
$response->assertStatus(200);
$response->assertJsonStructure(['projects', 'categories']);
}
public function test_can_get_single_project()
{
$category = ProjectCategory::factory()->create();
$project = Project::factory()->create(['category_id' => $category->id]);
$response = $this->getJson("/api/website/projects/{$project->id}/translation/en");
$response->assertStatus(200);
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace Tests\Feature\Website;
use App\Models\Website\Service;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ServiceTest extends TestCase
{
use RefreshDatabase;
public function test_can_list_services()
{
Service::factory()->count(3)->create();
$response = $this->getJson('/api/website/services/en');
$response->assertStatus(200);
$this->assertCount(3, $response->json());
}
public function test_can_get_service_translation()
{
$service = Service::factory()->create();
$service->setTranslation('title', 'fa', 'عنوان');
$service->setTranslation('description', 'fa', 'توضیحات');
$service->save();
$response = $this->getJson("/api/website/services/{$service->id}/translation/fa");
$response->assertStatus(200)
->assertJson(['title' => 'عنوان']);
}
}

View File

@ -1,16 +0,0 @@
<?php
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*/
public function test_that_true_is_true(): void
{
$this->assertTrue(true);
}
}

40
tests/Unit/ModelsTest.php Normal file
View File

@ -0,0 +1,40 @@
<?php
namespace Tests\Unit;
use App\Models\Website\AboutMe;
use App\Models\Website\Skill;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ModelsTest extends TestCase
{
use RefreshDatabase;
public function test_about_me_can_set_and_get_translations()
{
$aboutMe = AboutMe::factory()->create();
$aboutMe->setTranslation('title', 'en', 'Hello');
$aboutMe->setTranslation('title', 'fa', 'سلام');
$aboutMe->save();
$this->assertEquals('Hello', $aboutMe->getTranslation('title', 'en'));
$this->assertEquals('سلام', $aboutMe->getTranslation('title', 'fa'));
}
public function test_about_me_has_skills_relation()
{
$aboutMe = AboutMe::factory()->create();
Skill::factory()->count(2)->create(['about_me_id' => $aboutMe->id]);
$this->assertCount(2, $aboutMe->skills);
}
public function test_about_me_fillable_fields()
{
$aboutMe = AboutMe::factory()->create(['image' => 'photo.jpg']);
$this->assertEquals('photo.jpg', $aboutMe->image);
}
}