189 lines
5.7 KiB
PHP
189 lines
5.7 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Tests\Feature\Http\Controllers\Api\V1;
|
||
|
|
|
||
|
|
use App\Models\Feed;
|
||
|
|
use App\Models\Keyword;
|
||
|
|
use App\Models\PlatformChannel;
|
||
|
|
use App\Models\Route;
|
||
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||
|
|
use Tests\TestCase;
|
||
|
|
|
||
|
|
class KeywordsControllerTest extends TestCase
|
||
|
|
{
|
||
|
|
use RefreshDatabase;
|
||
|
|
|
||
|
|
protected Feed $feed;
|
||
|
|
protected PlatformChannel $channel;
|
||
|
|
protected Route $route;
|
||
|
|
|
||
|
|
protected function setUp(): void
|
||
|
|
{
|
||
|
|
parent::setUp();
|
||
|
|
|
||
|
|
$this->feed = Feed::factory()->create();
|
||
|
|
$this->channel = PlatformChannel::factory()->create();
|
||
|
|
|
||
|
|
$this->route = Route::create([
|
||
|
|
'feed_id' => $this->feed->id,
|
||
|
|
'platform_channel_id' => $this->channel->id,
|
||
|
|
'is_active' => true,
|
||
|
|
'priority' => 50
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_get_keywords_for_route(): void
|
||
|
|
{
|
||
|
|
$keyword = Keyword::factory()->create([
|
||
|
|
'feed_id' => $this->feed->id,
|
||
|
|
'platform_channel_id' => $this->channel->id,
|
||
|
|
'keyword' => 'test keyword',
|
||
|
|
'is_active' => true
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response = $this->getJson("/api/v1/routing/{$this->feed->id}/{$this->channel->id}/keywords");
|
||
|
|
|
||
|
|
$response->assertStatus(200)
|
||
|
|
->assertJsonStructure([
|
||
|
|
'success',
|
||
|
|
'data' => [
|
||
|
|
'*' => [
|
||
|
|
'id',
|
||
|
|
'keyword',
|
||
|
|
'is_active',
|
||
|
|
'feed_id',
|
||
|
|
'platform_channel_id'
|
||
|
|
]
|
||
|
|
]
|
||
|
|
])
|
||
|
|
->assertJsonPath('data.0.keyword', 'test keyword');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_create_keyword_for_route(): void
|
||
|
|
{
|
||
|
|
$keywordData = [
|
||
|
|
'keyword' => 'new keyword',
|
||
|
|
'is_active' => true
|
||
|
|
];
|
||
|
|
|
||
|
|
$response = $this->postJson("/api/v1/routing/{$this->feed->id}/{$this->channel->id}/keywords", $keywordData);
|
||
|
|
|
||
|
|
$response->assertStatus(201)
|
||
|
|
->assertJsonStructure([
|
||
|
|
'success',
|
||
|
|
'data' => [
|
||
|
|
'id',
|
||
|
|
'keyword',
|
||
|
|
'is_active',
|
||
|
|
'feed_id',
|
||
|
|
'platform_channel_id'
|
||
|
|
]
|
||
|
|
])
|
||
|
|
->assertJsonPath('data.keyword', 'new keyword')
|
||
|
|
->assertJsonPath('data.is_active', true);
|
||
|
|
|
||
|
|
$this->assertDatabaseHas('keywords', [
|
||
|
|
'keyword' => 'new keyword',
|
||
|
|
'feed_id' => $this->feed->id,
|
||
|
|
'platform_channel_id' => $this->channel->id,
|
||
|
|
'is_active' => true
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_cannot_create_duplicate_keyword_for_route(): void
|
||
|
|
{
|
||
|
|
Keyword::factory()->create([
|
||
|
|
'feed_id' => $this->feed->id,
|
||
|
|
'platform_channel_id' => $this->channel->id,
|
||
|
|
'keyword' => 'duplicate keyword'
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response = $this->postJson("/api/v1/routing/{$this->feed->id}/{$this->channel->id}/keywords", [
|
||
|
|
'keyword' => 'duplicate keyword'
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response->assertStatus(409)
|
||
|
|
->assertJsonPath('success', false)
|
||
|
|
->assertJsonPath('message', 'Keyword already exists for this route.');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_update_keyword(): void
|
||
|
|
{
|
||
|
|
$keyword = Keyword::factory()->create([
|
||
|
|
'feed_id' => $this->feed->id,
|
||
|
|
'platform_channel_id' => $this->channel->id,
|
||
|
|
'is_active' => true
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response = $this->putJson("/api/v1/routing/{$this->feed->id}/{$this->channel->id}/keywords/{$keyword->id}", [
|
||
|
|
'is_active' => false
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response->assertStatus(200)
|
||
|
|
->assertJsonPath('data.is_active', false);
|
||
|
|
|
||
|
|
$this->assertDatabaseHas('keywords', [
|
||
|
|
'id' => $keyword->id,
|
||
|
|
'is_active' => false
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_delete_keyword(): void
|
||
|
|
{
|
||
|
|
$keyword = Keyword::factory()->create([
|
||
|
|
'feed_id' => $this->feed->id,
|
||
|
|
'platform_channel_id' => $this->channel->id
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response = $this->deleteJson("/api/v1/routing/{$this->feed->id}/{$this->channel->id}/keywords/{$keyword->id}");
|
||
|
|
|
||
|
|
$response->assertStatus(200);
|
||
|
|
|
||
|
|
$this->assertDatabaseMissing('keywords', [
|
||
|
|
'id' => $keyword->id
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_can_toggle_keyword(): void
|
||
|
|
{
|
||
|
|
$keyword = Keyword::factory()->create([
|
||
|
|
'feed_id' => $this->feed->id,
|
||
|
|
'platform_channel_id' => $this->channel->id,
|
||
|
|
'is_active' => true
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response = $this->postJson("/api/v1/routing/{$this->feed->id}/{$this->channel->id}/keywords/{$keyword->id}/toggle");
|
||
|
|
|
||
|
|
$response->assertStatus(200)
|
||
|
|
->assertJsonPath('data.is_active', false);
|
||
|
|
|
||
|
|
$this->assertDatabaseHas('keywords', [
|
||
|
|
'id' => $keyword->id,
|
||
|
|
'is_active' => false
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_cannot_access_keyword_from_different_route(): void
|
||
|
|
{
|
||
|
|
$otherFeed = Feed::factory()->create();
|
||
|
|
$otherChannel = PlatformChannel::factory()->create();
|
||
|
|
|
||
|
|
$keyword = Keyword::factory()->create([
|
||
|
|
'feed_id' => $otherFeed->id,
|
||
|
|
'platform_channel_id' => $otherChannel->id
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response = $this->deleteJson("/api/v1/routing/{$this->feed->id}/{$this->channel->id}/keywords/{$keyword->id}");
|
||
|
|
|
||
|
|
$response->assertStatus(404)
|
||
|
|
->assertJsonPath('message', 'Keyword not found for this route.');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_validates_required_fields(): void
|
||
|
|
{
|
||
|
|
$response = $this->postJson("/api/v1/routing/{$this->feed->id}/{$this->channel->id}/keywords", []);
|
||
|
|
|
||
|
|
$response->assertStatus(422)
|
||
|
|
->assertJsonValidationErrors(['keyword']);
|
||
|
|
}
|
||
|
|
}
|