mirror of
https://github.com/torrentpier/torrentpier
synced 2025-08-21 22:03:49 -07:00
refactor(emoji): rename variables for clarity in EmojiAlias and EmojiCategory controllers
Updated variable names in the EmojiAliasController and EmojiCategoryController to improve code readability. Changed instances of `$emojiAlias` and `$emojiCategory` to `$alias` and `$category`, respectively, in the show, update, and destroy methods. Additionally, updated the UpdateEmojiAliasRequest to reflect the new variable naming convention. This enhances consistency and clarity across the codebase.
This commit is contained in:
parent
3957929769
commit
6c491be4e9
6 changed files with 920 additions and 18 deletions
|
@ -53,37 +53,37 @@ class EmojiAliasController extends Controller
|
|||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(EmojiAlias $emojiAlias, Request $request)
|
||||
public function show(EmojiAlias $alias, Request $request)
|
||||
{
|
||||
$emojiAlias->load(['emoji' => function ($query) {
|
||||
$alias->load(['emoji' => function ($query) {
|
||||
$query->with('category');
|
||||
}]);
|
||||
|
||||
return new EmojiAliasResource($emojiAlias);
|
||||
return new EmojiAliasResource($alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(UpdateEmojiAliasRequest $request, EmojiAlias $emojiAlias)
|
||||
public function update(UpdateEmojiAliasRequest $request, EmojiAlias $alias)
|
||||
{
|
||||
$emojiAlias->update($request->validated());
|
||||
$alias->update($request->validated());
|
||||
|
||||
if ($request->get('with_emoji')) {
|
||||
$emojiAlias->load(['emoji' => function ($query) {
|
||||
$alias->load(['emoji' => function ($query) {
|
||||
$query->with('category');
|
||||
}]);
|
||||
}
|
||||
|
||||
return new EmojiAliasResource($emojiAlias);
|
||||
return new EmojiAliasResource($alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(EmojiAlias $emojiAlias)
|
||||
public function destroy(EmojiAlias $alias)
|
||||
{
|
||||
$emojiAlias->delete();
|
||||
$alias->delete();
|
||||
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
|
|
|
@ -44,9 +44,9 @@ class EmojiCategoryController extends Controller
|
|||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(EmojiCategory $emojiCategory, Request $request)
|
||||
public function show(EmojiCategory $category, Request $request)
|
||||
{
|
||||
$emojiCategory->load([
|
||||
$category->load([
|
||||
'emojis' => function ($query) use ($request) {
|
||||
$query->orderBy('display_order');
|
||||
if ($request->get('with_aliases')) {
|
||||
|
@ -55,25 +55,25 @@ class EmojiCategoryController extends Controller
|
|||
},
|
||||
]);
|
||||
|
||||
return new EmojiCategoryResource($emojiCategory);
|
||||
return new EmojiCategoryResource($category);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(UpdateEmojiCategoryRequest $request, EmojiCategory $emojiCategory)
|
||||
public function update(UpdateEmojiCategoryRequest $request, EmojiCategory $category)
|
||||
{
|
||||
$emojiCategory->update($request->validated());
|
||||
$category->update($request->validated());
|
||||
|
||||
return new EmojiCategoryResource($emojiCategory);
|
||||
return new EmojiCategoryResource($category);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(EmojiCategory $emojiCategory)
|
||||
public function destroy(EmojiCategory $category)
|
||||
{
|
||||
$emojiCategory->delete();
|
||||
$category->delete();
|
||||
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ class UpdateEmojiAliasRequest extends FormRequest
|
|||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$aliasId = $this->route('emoji_alias')->id;
|
||||
$aliasId = $this->route('alias')->id;
|
||||
|
||||
return [
|
||||
'emoji_id' => 'sometimes|exists:emojis,id',
|
||||
|
|
347
tests/Feature/Api/EmojiAliasTest.php
Normal file
347
tests/Feature/Api/EmojiAliasTest.php
Normal file
|
@ -0,0 +1,347 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Emoji;
|
||||
use App\Models\EmojiAlias;
|
||||
use App\Models\EmojiCategory;
|
||||
|
||||
describe('Emoji Alias API Endpoints', function () {
|
||||
test('can list aliases', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
EmojiAlias::factory()->count(3)->create(['emoji_id' => $emoji->id]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/aliases');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'alias',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
],
|
||||
'links',
|
||||
'meta',
|
||||
])
|
||||
->assertJsonCount(3, 'data');
|
||||
});
|
||||
|
||||
test('can filter aliases by emoji', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji1 = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
$emoji2 = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
EmojiAlias::factory()->count(2)->create(['emoji_id' => $emoji1->id]);
|
||||
EmojiAlias::factory()->count(3)->create(['emoji_id' => $emoji2->id]);
|
||||
|
||||
$response = $this->getJson("/api/emoji/aliases?emoji_id={$emoji1->id}");
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonCount(2, 'data');
|
||||
});
|
||||
|
||||
test('can search aliases', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
EmojiAlias::factory()->create([
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':happy:',
|
||||
]);
|
||||
EmojiAlias::factory()->create([
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':sad:',
|
||||
]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/aliases?search=happy');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonCount(1, 'data')
|
||||
->assertJsonPath('data.0.alias', ':happy:');
|
||||
});
|
||||
|
||||
test('can include emoji and category with aliases', function () {
|
||||
$category = EmojiCategory::factory()->create(['title' => 'Test Category']);
|
||||
$emoji = Emoji::factory()->create([
|
||||
'emoji_category_id' => $category->id,
|
||||
'title' => 'Test Emoji',
|
||||
]);
|
||||
EmojiAlias::factory()->create(['emoji_id' => $emoji->id]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/aliases?with_emoji=1');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.0.emoji.title', 'Test Emoji')
|
||||
->assertJsonPath('data.0.emoji.category.title', 'Test Category');
|
||||
});
|
||||
|
||||
test('can get specific alias', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
$alias = EmojiAlias::factory()->create([
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':test_alias:',
|
||||
]);
|
||||
|
||||
$response = $this->getJson("/api/emoji/aliases/{$alias->id}");
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.alias', ':test_alias:')
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'id',
|
||||
'alias',
|
||||
'emoji',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('returns 404 for non-existent alias', function () {
|
||||
$response = $this->getJson('/api/emoji/aliases/999');
|
||||
|
||||
$response->assertNotFound();
|
||||
});
|
||||
|
||||
test('can create alias', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
$data = [
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':new_alias:',
|
||||
];
|
||||
|
||||
$response = $this->postJson('/api/emoji/aliases', $data);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonPath('data.alias', ':new_alias:')
|
||||
->assertJsonPath('data.emoji', null); // Not loaded by default
|
||||
|
||||
$this->assertDatabaseHas('emoji_aliases', [
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':new_alias:',
|
||||
]);
|
||||
});
|
||||
|
||||
test('validates required fields when creating alias', function () {
|
||||
$response = $this->postJson('/api/emoji/aliases', []);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['emoji_id', 'alias']);
|
||||
});
|
||||
|
||||
test('validates alias format', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
$response = $this->postJson('/api/emoji/aliases', [
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => 'invalid-format',
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['alias']);
|
||||
});
|
||||
|
||||
test('validates unique alias', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
EmojiAlias::factory()->create([
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':existing:',
|
||||
]);
|
||||
|
||||
$response = $this->postJson('/api/emoji/aliases', [
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':existing:',
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['alias']);
|
||||
});
|
||||
|
||||
test('validates emoji exists', function () {
|
||||
$response = $this->postJson('/api/emoji/aliases', [
|
||||
'emoji_id' => 999,
|
||||
'alias' => ':valid_alias:',
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['emoji_id']);
|
||||
});
|
||||
|
||||
test('prevents alias from conflicting with emoji shortcode', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji1 = Emoji::factory()->create([
|
||||
'emoji_category_id' => $category->id,
|
||||
'emoji_shortcode' => ':existing_emoji:',
|
||||
]);
|
||||
$emoji2 = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
$response = $this->postJson('/api/emoji/aliases', [
|
||||
'emoji_id' => $emoji2->id,
|
||||
'alias' => ':existing_emoji:',
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['alias']);
|
||||
});
|
||||
|
||||
test('can update alias', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji1 = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
$emoji2 = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
$alias = EmojiAlias::factory()->create(['emoji_id' => $emoji1->id]);
|
||||
|
||||
$data = [
|
||||
'emoji_id' => $emoji2->id,
|
||||
'alias' => ':updated_alias:',
|
||||
];
|
||||
|
||||
$response = $this->patchJson("/api/emoji/aliases/{$alias->id}", $data);
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.alias', ':updated_alias:');
|
||||
|
||||
$this->assertDatabaseHas('emoji_aliases', [
|
||||
'id' => $alias->id,
|
||||
'emoji_id' => $emoji2->id,
|
||||
'alias' => ':updated_alias:',
|
||||
]);
|
||||
});
|
||||
|
||||
test('can partially update alias', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
$alias = EmojiAlias::factory()->create([
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':original:',
|
||||
]);
|
||||
|
||||
$response = $this->patchJson("/api/emoji/aliases/{$alias->id}", [
|
||||
'alias' => ':updated:',
|
||||
]);
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.alias', ':updated:');
|
||||
|
||||
// emoji_id should remain unchanged
|
||||
$this->assertDatabaseHas('emoji_aliases', [
|
||||
'id' => $alias->id,
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':updated:',
|
||||
]);
|
||||
});
|
||||
|
||||
test('can delete alias', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
$alias = EmojiAlias::factory()->create(['emoji_id' => $emoji->id]);
|
||||
|
||||
$response = $this->deleteJson("/api/emoji/aliases/{$alias->id}");
|
||||
|
||||
$response->assertNoContent();
|
||||
|
||||
$this->assertDatabaseMissing('emoji_aliases', ['id' => $alias->id]);
|
||||
|
||||
// Emoji should still exist
|
||||
$this->assertDatabaseHas('emojis', ['id' => $emoji->id]);
|
||||
});
|
||||
|
||||
test('supports pagination', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
EmojiAlias::factory()->count(60)->create(['emoji_id' => $emoji->id]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/aliases?per_page=20&page=2');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('meta.current_page', 2)
|
||||
->assertJsonPath('meta.per_page', 20)
|
||||
->assertJsonCount(20, 'data');
|
||||
});
|
||||
|
||||
test('aliases are ordered alphabetically', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
EmojiAlias::factory()->create(['emoji_id' => $emoji->id, 'alias' => ':zebra:']);
|
||||
EmojiAlias::factory()->create(['emoji_id' => $emoji->id, 'alias' => ':apple:']);
|
||||
EmojiAlias::factory()->create(['emoji_id' => $emoji->id, 'alias' => ':banana:']);
|
||||
|
||||
$response = $this->getJson('/api/emoji/aliases');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.0.alias', ':apple:')
|
||||
->assertJsonPath('data.1.alias', ':banana:')
|
||||
->assertJsonPath('data.2.alias', ':zebra:');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Emoji Alias Search API', function () {
|
||||
test('can search aliases using scout', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
EmojiAlias::factory()->create([
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':happy:',
|
||||
]);
|
||||
|
||||
EmojiAlias::factory()->create([
|
||||
'emoji_id' => $emoji->id,
|
||||
'alias' => ':sad:',
|
||||
]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/aliases/search?q=happy');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'alias',
|
||||
'emoji',
|
||||
],
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('validates search query parameter', function () {
|
||||
$response = $this->getJson('/api/emoji/aliases/search');
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['q']);
|
||||
});
|
||||
|
||||
test('validates search limit parameter', function () {
|
||||
$response = $this->getJson('/api/emoji/aliases/search?q=test&limit=150');
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['limit']);
|
||||
});
|
||||
|
||||
test('can include emoji data in search results', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
$alias = EmojiAlias::factory()->create(['emoji_id' => $emoji->id]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/aliases/search?q=test&with_emoji=1');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => [
|
||||
'emoji' => [
|
||||
'id',
|
||||
'title',
|
||||
'emoji_shortcode',
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
});
|
||||
});
|
222
tests/Feature/Api/EmojiCategoryTest.php
Normal file
222
tests/Feature/Api/EmojiCategoryTest.php
Normal file
|
@ -0,0 +1,222 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Emoji;
|
||||
use App\Models\EmojiCategory;
|
||||
|
||||
describe('Emoji Category API Endpoints', function () {
|
||||
test('can list categories', function () {
|
||||
EmojiCategory::factory()->count(3)->create();
|
||||
|
||||
$response = $this->getJson('/api/emoji/categories');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'title',
|
||||
'display_order',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
],
|
||||
])
|
||||
->assertJsonCount(3, 'data');
|
||||
});
|
||||
|
||||
test('can list categories with emoji counts', function () {
|
||||
$category1 = EmojiCategory::factory()->create(['title' => 'Category 1']);
|
||||
$category2 = EmojiCategory::factory()->create(['title' => 'Category 2']);
|
||||
|
||||
Emoji::factory()->count(5)->create(['emoji_category_id' => $category1->id]);
|
||||
Emoji::factory()->count(3)->create(['emoji_category_id' => $category2->id]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/categories?with_emojis=1');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.0.emojis_count', 5)
|
||||
->assertJsonPath('data.1.emojis_count', 3);
|
||||
});
|
||||
|
||||
test('can list categories with full emoji data', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
Emoji::factory()->count(2)->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/categories?include_emojis=1');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonCount(2, 'data.0.emojis')
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => [
|
||||
'emojis' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'title',
|
||||
'emoji_shortcode',
|
||||
'emoji_text',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('can get specific category', function () {
|
||||
$category = EmojiCategory::factory()->create([
|
||||
'title' => 'Test Category',
|
||||
'display_order' => 5,
|
||||
]);
|
||||
|
||||
$response = $this->getJson("/api/emoji/categories/{$category->id}");
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.title', 'Test Category')
|
||||
->assertJsonPath('data.display_order', 5)
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'id',
|
||||
'title',
|
||||
'display_order',
|
||||
'emojis',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('can get category with emoji aliases', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
$response = $this->getJson("/api/emoji/categories/{$category->id}?with_aliases=1");
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'emojis' => [
|
||||
'*' => [
|
||||
'aliases',
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('returns 404 for non-existent category', function () {
|
||||
$response = $this->getJson('/api/emoji/categories/999');
|
||||
|
||||
$response->assertNotFound();
|
||||
});
|
||||
|
||||
test('can create category', function () {
|
||||
$data = [
|
||||
'title' => 'New Category',
|
||||
'display_order' => 10,
|
||||
];
|
||||
|
||||
$response = $this->postJson('/api/emoji/categories', $data);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonPath('data.title', 'New Category')
|
||||
->assertJsonPath('data.display_order', 10);
|
||||
|
||||
$this->assertDatabaseHas('emoji_categories', [
|
||||
'title' => 'New Category',
|
||||
'display_order' => 10,
|
||||
]);
|
||||
});
|
||||
|
||||
test('validates required fields when creating category', function () {
|
||||
$response = $this->postJson('/api/emoji/categories', []);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['title', 'display_order']);
|
||||
});
|
||||
|
||||
test('validates display order is non-negative', function () {
|
||||
$response = $this->postJson('/api/emoji/categories', [
|
||||
'title' => 'Test Category',
|
||||
'display_order' => -1,
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['display_order']);
|
||||
});
|
||||
|
||||
test('validates title length', function () {
|
||||
$response = $this->postJson('/api/emoji/categories', [
|
||||
'title' => str_repeat('a', 256),
|
||||
'display_order' => 1,
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['title']);
|
||||
});
|
||||
|
||||
test('can update category', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
|
||||
$data = [
|
||||
'title' => 'Updated Title',
|
||||
'display_order' => 99,
|
||||
];
|
||||
|
||||
$response = $this->patchJson("/api/emoji/categories/{$category->id}", $data);
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.title', 'Updated Title')
|
||||
->assertJsonPath('data.display_order', 99);
|
||||
|
||||
$this->assertDatabaseHas('emoji_categories', [
|
||||
'id' => $category->id,
|
||||
'title' => 'Updated Title',
|
||||
'display_order' => 99,
|
||||
]);
|
||||
});
|
||||
|
||||
test('can partially update category', function () {
|
||||
$category = EmojiCategory::factory()->create([
|
||||
'title' => 'Original Title',
|
||||
'display_order' => 5,
|
||||
]);
|
||||
|
||||
$response = $this->patchJson("/api/emoji/categories/{$category->id}", [
|
||||
'title' => 'New Title',
|
||||
]);
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.title', 'New Title')
|
||||
->assertJsonPath('data.display_order', 5); // Should remain unchanged
|
||||
});
|
||||
|
||||
test('can delete category', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
$response = $this->deleteJson("/api/emoji/categories/{$category->id}");
|
||||
|
||||
$response->assertNoContent();
|
||||
|
||||
$this->assertDatabaseMissing('emoji_categories', ['id' => $category->id]);
|
||||
|
||||
// Emoji should still exist but with null category_id
|
||||
$this->assertDatabaseHas('emojis', [
|
||||
'id' => $emoji->id,
|
||||
'emoji_category_id' => null,
|
||||
]);
|
||||
});
|
||||
|
||||
test('categories are ordered by display_order', function () {
|
||||
EmojiCategory::factory()->create(['title' => 'Third', 'display_order' => 3]);
|
||||
EmojiCategory::factory()->create(['title' => 'First', 'display_order' => 1]);
|
||||
EmojiCategory::factory()->create(['title' => 'Second', 'display_order' => 2]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/categories');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.0.title', 'First')
|
||||
->assertJsonPath('data.1.title', 'Second')
|
||||
->assertJsonPath('data.2.title', 'Third');
|
||||
});
|
||||
});
|
333
tests/Feature/Api/EmojiTest.php
Normal file
333
tests/Feature/Api/EmojiTest.php
Normal file
|
@ -0,0 +1,333 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Emoji;
|
||||
use App\Models\EmojiAlias;
|
||||
use App\Models\EmojiCategory;
|
||||
|
||||
describe('Emoji API Endpoints', function () {
|
||||
test('can list emojis', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emojis = Emoji::factory()->count(3)->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/emojis');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'title',
|
||||
'emoji_text',
|
||||
'emoji_shortcode',
|
||||
'image_url',
|
||||
'sprite_mode',
|
||||
'sprite_params',
|
||||
'display_order',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
],
|
||||
'links',
|
||||
'meta',
|
||||
])
|
||||
->assertJsonCount(3, 'data');
|
||||
});
|
||||
|
||||
test('can filter emojis by category', function () {
|
||||
$category1 = EmojiCategory::factory()->create();
|
||||
$category2 = EmojiCategory::factory()->create();
|
||||
|
||||
Emoji::factory()->count(2)->create(['emoji_category_id' => $category1->id]);
|
||||
Emoji::factory()->count(3)->create(['emoji_category_id' => $category2->id]);
|
||||
|
||||
$response = $this->getJson("/api/emoji/emojis?category_id={$category1->id}");
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonCount(2, 'data');
|
||||
});
|
||||
|
||||
test('can search emojis', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
Emoji::factory()->create([
|
||||
'title' => 'Happy Face',
|
||||
'emoji_shortcode' => ':happy:',
|
||||
'emoji_category_id' => $category->id,
|
||||
]);
|
||||
Emoji::factory()->create([
|
||||
'title' => 'Sad Face',
|
||||
'emoji_shortcode' => ':sad:',
|
||||
'emoji_category_id' => $category->id,
|
||||
]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/emojis?search=happy');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonCount(1, 'data')
|
||||
->assertJsonPath('data.0.title', 'Happy Face');
|
||||
});
|
||||
|
||||
test('can include category and aliases with emojis', function () {
|
||||
$category = EmojiCategory::factory()->create(['title' => 'Test Category']);
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
EmojiAlias::factory()->count(2)->create(['emoji_id' => $emoji->id]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/emojis?with_category=1&with_aliases=1');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.0.category.title', 'Test Category')
|
||||
->assertJsonCount(2, 'data.0.aliases');
|
||||
});
|
||||
|
||||
test('can get specific emoji', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create([
|
||||
'title' => 'Test Emoji',
|
||||
'emoji_shortcode' => ':test:',
|
||||
'emoji_category_id' => $category->id,
|
||||
]);
|
||||
|
||||
$response = $this->getJson("/api/emoji/emojis/{$emoji->id}");
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.title', 'Test Emoji')
|
||||
->assertJsonPath('data.emoji_shortcode', ':test:')
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'id',
|
||||
'title',
|
||||
'emoji_shortcode',
|
||||
'category',
|
||||
'aliases',
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('returns 404 for non-existent emoji', function () {
|
||||
$response = $this->getJson('/api/emoji/emojis/999');
|
||||
|
||||
$response->assertNotFound();
|
||||
});
|
||||
|
||||
test('can create unicode emoji', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
|
||||
$data = [
|
||||
'title' => 'Happy Face',
|
||||
'emoji_text' => '😊',
|
||||
'emoji_shortcode' => ':happy_face:',
|
||||
'emoji_category_id' => $category->id,
|
||||
'display_order' => 1,
|
||||
];
|
||||
|
||||
$response = $this->postJson('/api/emoji/emojis', $data);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonPath('data.title', 'Happy Face')
|
||||
->assertJsonPath('data.emoji_text', '😊')
|
||||
->assertJsonPath('data.emoji_shortcode', ':happy_face:');
|
||||
|
||||
$this->assertDatabaseHas('emojis', [
|
||||
'title' => 'Happy Face',
|
||||
'emoji_text' => '😊',
|
||||
'emoji_shortcode' => ':happy_face:',
|
||||
]);
|
||||
});
|
||||
|
||||
test('can create custom image emoji', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
|
||||
$data = [
|
||||
'title' => 'Custom Emoji',
|
||||
'emoji_shortcode' => ':custom:',
|
||||
'image_url' => '/emojis/custom/custom.png',
|
||||
'emoji_category_id' => $category->id,
|
||||
'display_order' => 1,
|
||||
];
|
||||
|
||||
$response = $this->postJson('/api/emoji/emojis', $data);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonPath('data.title', 'Custom Emoji')
|
||||
->assertJsonPath('data.image_url', '/emojis/custom/custom.png')
|
||||
->assertJsonPath('data.emoji_text', null);
|
||||
});
|
||||
|
||||
test('can create sprite emoji', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
|
||||
$data = [
|
||||
'title' => 'Sprite Emoji',
|
||||
'emoji_shortcode' => ':sprite:',
|
||||
'sprite_mode' => true,
|
||||
'sprite_params' => [
|
||||
'x' => 32,
|
||||
'y' => 64,
|
||||
'width' => 32,
|
||||
'height' => 32,
|
||||
'sheet' => 'emoji-sheet-1.png',
|
||||
],
|
||||
'emoji_category_id' => $category->id,
|
||||
'display_order' => 1,
|
||||
];
|
||||
|
||||
$response = $this->postJson('/api/emoji/emojis', $data);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonPath('data.sprite_mode', true)
|
||||
->assertJsonPath('data.sprite_params.x', 32)
|
||||
->assertJsonPath('data.sprite_params.sheet', 'emoji-sheet-1.png');
|
||||
});
|
||||
|
||||
test('validates required fields when creating emoji', function () {
|
||||
$response = $this->postJson('/api/emoji/emojis', []);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['title', 'emoji_shortcode', 'display_order']);
|
||||
});
|
||||
|
||||
test('validates emoji shortcode format', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
|
||||
$response = $this->postJson('/api/emoji/emojis', [
|
||||
'title' => 'Test',
|
||||
'emoji_shortcode' => 'invalid-format',
|
||||
'emoji_category_id' => $category->id,
|
||||
'display_order' => 1,
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['emoji_shortcode']);
|
||||
});
|
||||
|
||||
test('validates unique emoji shortcode', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
Emoji::factory()->create(['emoji_shortcode' => ':existing:']);
|
||||
|
||||
$response = $this->postJson('/api/emoji/emojis', [
|
||||
'title' => 'Test',
|
||||
'emoji_shortcode' => ':existing:',
|
||||
'emoji_category_id' => $category->id,
|
||||
'display_order' => 1,
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['emoji_shortcode']);
|
||||
});
|
||||
|
||||
test('validates sprite params when sprite mode is enabled', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
|
||||
$response = $this->postJson('/api/emoji/emojis', [
|
||||
'title' => 'Test',
|
||||
'emoji_shortcode' => ':test:',
|
||||
'sprite_mode' => true,
|
||||
'emoji_category_id' => $category->id,
|
||||
'display_order' => 1,
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors([
|
||||
'sprite_params.x',
|
||||
'sprite_params.y',
|
||||
'sprite_params.width',
|
||||
'sprite_params.height',
|
||||
'sprite_params.sheet',
|
||||
]);
|
||||
});
|
||||
|
||||
test('can update emoji', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
$data = [
|
||||
'title' => 'Updated Title',
|
||||
'display_order' => 99,
|
||||
];
|
||||
|
||||
$response = $this->patchJson("/api/emoji/emojis/{$emoji->id}", $data);
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.title', 'Updated Title')
|
||||
->assertJsonPath('data.display_order', 99);
|
||||
|
||||
$this->assertDatabaseHas('emojis', [
|
||||
'id' => $emoji->id,
|
||||
'title' => 'Updated Title',
|
||||
'display_order' => 99,
|
||||
]);
|
||||
});
|
||||
|
||||
test('can delete emoji', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
$emoji = Emoji::factory()->create(['emoji_category_id' => $category->id]);
|
||||
$alias = EmojiAlias::factory()->create(['emoji_id' => $emoji->id]);
|
||||
|
||||
$response = $this->deleteJson("/api/emoji/emojis/{$emoji->id}");
|
||||
|
||||
$response->assertNoContent();
|
||||
|
||||
$this->assertDatabaseMissing('emojis', ['id' => $emoji->id]);
|
||||
$this->assertDatabaseMissing('emoji_aliases', ['id' => $alias->id]);
|
||||
});
|
||||
|
||||
test('supports pagination', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
Emoji::factory()->count(60)->create(['emoji_category_id' => $category->id]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/emojis?per_page=20&page=2');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('meta.current_page', 2)
|
||||
->assertJsonPath('meta.per_page', 20)
|
||||
->assertJsonCount(20, 'data');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Emoji Search API', function () {
|
||||
test('can search emojis using scout', function () {
|
||||
$category = EmojiCategory::factory()->create();
|
||||
|
||||
// Create emojis with different content
|
||||
Emoji::factory()->create([
|
||||
'title' => 'Happy Face',
|
||||
'emoji_shortcode' => ':happy:',
|
||||
'emoji_text' => '😊',
|
||||
'emoji_category_id' => $category->id,
|
||||
]);
|
||||
|
||||
Emoji::factory()->create([
|
||||
'title' => 'Sad Face',
|
||||
'emoji_shortcode' => ':sad:',
|
||||
'emoji_text' => '😢',
|
||||
'emoji_category_id' => $category->id,
|
||||
]);
|
||||
|
||||
$response = $this->getJson('/api/emoji/emojis/search?q=happy');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'title',
|
||||
'emoji_shortcode',
|
||||
'emoji_text',
|
||||
],
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('validates search query parameter', function () {
|
||||
$response = $this->getJson('/api/emoji/emojis/search');
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['q']);
|
||||
});
|
||||
|
||||
test('validates search limit parameter', function () {
|
||||
$response = $this->getJson('/api/emoji/emojis/search?q=test&limit=150');
|
||||
|
||||
$response->assertUnprocessable()
|
||||
->assertJsonValidationErrors(['limit']);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue