207 lines
6.4 KiB
PHP
207 lines
6.4 KiB
PHP
<?php
|
|
|
|
use Bjanczak\FilamentShortUrl\Jobs\SendWebhookJob;
|
|
use Bjanczak\FilamentShortUrl\Models\ShortUrl;
|
|
use Bjanczak\FilamentShortUrl\Services\ShortUrlSettingsManager;
|
|
use Illuminate\Support\Facades\Queue;
|
|
|
|
beforeEach(function () {
|
|
// Enable REST API and inject mock keys
|
|
app(ShortUrlSettingsManager::class)->set([
|
|
'api_enabled' => true,
|
|
'api_keys' => [
|
|
['name' => 'Active Test Token', 'key' => 'sh_key_active_token', 'is_active' => true],
|
|
['name' => 'Inactive Test Token', 'key' => 'sh_key_inactive_token', 'is_active' => false],
|
|
],
|
|
]);
|
|
});
|
|
|
|
it('rejects API requests without a key', function () {
|
|
$response = $this->getJson('/api/short-url/links');
|
|
|
|
$response->assertStatus(401)
|
|
->assertJsonFragment(['error' => 'Unauthorized. API Key is missing.']);
|
|
});
|
|
|
|
it('returns 503 when the REST API is disabled in settings', function () {
|
|
app(ShortUrlSettingsManager::class)->set(['api_enabled' => false]);
|
|
|
|
$response = $this->getJson('/api/short-url/links', [
|
|
'X-Api-Key' => 'sh_key_active_token',
|
|
]);
|
|
|
|
$response->assertStatus(503)
|
|
->assertJsonPath('error', fn ($v) => str_contains($v, 'disabled'));
|
|
});
|
|
|
|
it('rejects API requests with an invalid key', function () {
|
|
$response = $this->getJson('/api/short-url/links', [
|
|
'X-Api-Key' => 'sh_key_invalid_value',
|
|
]);
|
|
|
|
$response->assertStatus(401)
|
|
->assertJsonFragment(['error' => 'Unauthorized. Invalid or inactive API Key.']);
|
|
});
|
|
|
|
it('rejects API requests with an inactive key', function () {
|
|
$response = $this->getJson('/api/short-url/links', [
|
|
'X-Api-Key' => 'sh_key_inactive_token',
|
|
]);
|
|
|
|
$response->assertStatus(401)
|
|
->assertJsonFragment(['error' => 'Unauthorized. Invalid or inactive API Key.']);
|
|
});
|
|
|
|
it('allows API requests with a valid key', function () {
|
|
// Seed at least one short URL
|
|
ShortUrl::create([
|
|
'destination_url' => 'https://example.com/api-test',
|
|
'url_key' => 'apitest',
|
|
]);
|
|
|
|
$response = $this->getJson('/api/short-url/links', [
|
|
'X-Api-Key' => 'sh_key_active_token',
|
|
]);
|
|
|
|
$response->assertStatus(200)
|
|
->assertJsonStructure([
|
|
'data',
|
|
'meta' => ['current_page', 'last_page', 'per_page', 'total'],
|
|
])
|
|
->assertJsonFragment(['url_key' => 'apitest']);
|
|
});
|
|
|
|
it('allows creating a short link programmatically via POST', function () {
|
|
Queue::fake([SendWebhookJob::class]);
|
|
|
|
$pixel = \Bjanczak\FilamentShortUrl\Models\ShortUrlPixel::create([
|
|
'name' => 'Meta Pixel Test',
|
|
'type' => 'meta',
|
|
'pixel_id' => '12345',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$response = $this->postJson('/api/short-url/links', [
|
|
'destination_url' => 'https://google.com',
|
|
'url_key' => 'googleapi',
|
|
'notes' => 'API Generated link',
|
|
'single_use' => true,
|
|
'pixels' => [$pixel->id],
|
|
'webhook_url' => 'https://webhook.site/test',
|
|
], [
|
|
'X-Api-Key' => 'sh_key_active_token',
|
|
]);
|
|
|
|
$response->assertStatus(201)
|
|
->assertJsonFragment(['url_key' => 'googleapi'])
|
|
->assertJsonFragment(['notes' => 'API Generated link']);
|
|
|
|
$this->assertDatabaseHas('short_urls', [
|
|
'url_key' => 'googleapi',
|
|
'single_use' => true,
|
|
'webhook_url' => 'https://webhook.site/test',
|
|
]);
|
|
|
|
$shortUrl = ShortUrl::where('url_key', 'googleapi')->first();
|
|
$this->assertDatabaseHas('short_url_pixel', [
|
|
'short_url_id' => $shortUrl->id,
|
|
'pixel_id' => $pixel->id,
|
|
]);
|
|
|
|
// SendWebhookJob should be dispatched for 'created' event since custom webhook_url is set
|
|
Queue::assertPushed(SendWebhookJob::class, function ($job) {
|
|
return $job->url === 'https://webhook.site/test' && $job->event === 'created';
|
|
});
|
|
});
|
|
|
|
it('allows deleting a short link via DELETE', function () {
|
|
$link = ShortUrl::create([
|
|
'destination_url' => 'https://delete-me.com',
|
|
'url_key' => 'delkey',
|
|
]);
|
|
|
|
$response = $this->deleteJson("/api/short-url/links/{$link->id}", [], [
|
|
'X-Api-Key' => 'sh_key_active_token',
|
|
]);
|
|
|
|
$response->assertStatus(200)
|
|
->assertJsonFragment(['message' => 'Short URL deleted successfully.']);
|
|
|
|
$this->assertDatabaseMissing('short_urls', [
|
|
'id' => $link->id,
|
|
]);
|
|
});
|
|
|
|
it('allows updating a short link via PUT', function () {
|
|
$link = ShortUrl::create([
|
|
'destination_url' => 'https://initial-destination.com',
|
|
'url_key' => 'initkey',
|
|
'notes' => 'Initial notes',
|
|
]);
|
|
|
|
$response = $this->putJson("/api/short-url/links/{$link->id}", [
|
|
'destination_url' => 'https://updated-destination.com',
|
|
'notes' => 'Updated notes',
|
|
], [
|
|
'X-Api-Key' => 'sh_key_active_token',
|
|
]);
|
|
|
|
$response->assertStatus(200)
|
|
->assertJsonFragment(['destination_url' => 'https://updated-destination.com'])
|
|
->assertJsonFragment(['notes' => 'Updated notes'])
|
|
->assertJsonFragment(['url_key' => 'initkey']);
|
|
|
|
$this->assertDatabaseHas('short_urls', [
|
|
'id' => $link->id,
|
|
'destination_url' => 'https://updated-destination.com',
|
|
'notes' => 'Updated notes',
|
|
'url_key' => 'initkey',
|
|
]);
|
|
});
|
|
|
|
it('allows showing a single short link via GET by ID or key', function () {
|
|
$link = ShortUrl::create([
|
|
'destination_url' => 'https://single-show.com',
|
|
'url_key' => 'showkey',
|
|
]);
|
|
|
|
// Show by ID
|
|
$response = $this->getJson("/api/short-url/links/{$link->id}", [
|
|
'X-Api-Key' => 'sh_key_active_token',
|
|
]);
|
|
|
|
$response->assertStatus(200)
|
|
->assertJsonFragment(['url_key' => 'showkey']);
|
|
|
|
// Show by Key
|
|
$responseKey = $this->getJson("/api/short-url/links/showkey", [
|
|
'X-Api-Key' => 'sh_key_active_token',
|
|
]);
|
|
|
|
$responseKey->assertStatus(200)
|
|
->assertJsonFragment(['id' => $link->id]);
|
|
});
|
|
|
|
it('allows fetching link statistics via GET', function () {
|
|
$link = ShortUrl::create([
|
|
'destination_url' => 'https://stats-test.com',
|
|
'url_key' => 'statskey',
|
|
]);
|
|
|
|
$response = $this->getJson("/api/short-url/links/{$link->id}/stats", [
|
|
'X-Api-Key' => 'sh_key_active_token',
|
|
]);
|
|
|
|
$response->assertStatus(200)
|
|
->assertJsonStructure([
|
|
'data' => [
|
|
'totalVisits',
|
|
'uniqueVisits',
|
|
'visitsToday',
|
|
'visitsByDay',
|
|
],
|
|
]);
|
|
});
|
|
|
|
|