nimuli/tests/Feature/Livewire/LinksModalsTest.php

169 lines
5.2 KiB
PHP

<?php
use App\Domains\Link\Models\Link;
use App\Domains\Workspace\Models\Workspace;
use App\Domains\Workspace\Models\WorkspaceMember;
use App\Livewire\Modals\CreateLink;
use App\Livewire\Modals\DeleteLink;
use App\Livewire\Modals\EditLink;
use App\Models\User;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Livewire\Livewire;
function makeUserWithWs(): array
{
$user = User::factory()->create();
$ws = Workspace::factory()->create(['owner_id' => $user->id]);
WorkspaceMember::create([
'workspace_id' => $ws->id,
'user_id' => $user->id,
'role' => 'owner',
'joined_at' => now(),
]);
return [$user, $ws];
}
// CreateLink
it('renders create link modal', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
Livewire::actingAs($user)->test(CreateLink::class)
->assertOk()
->assertSee('Create Short Link');
});
it('validates required url on create link', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
Livewire::actingAs($user)->test(CreateLink::class)
->call('save')
->assertHasErrors(['targetUrl' => 'required']);
});
it('validates url format on create link', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
Livewire::actingAs($user)->test(CreateLink::class)
->set('targetUrl', 'not-a-url')
->call('save')
->assertHasErrors(['targetUrl']);
});
it('creates link and dispatches linkCreated', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
Livewire::actingAs($user)->test(CreateLink::class)
->set('targetUrl', 'https://example.com/page')
->call('save')
->assertDispatched('linkCreated');
expect(Link::where('workspace_id', $ws->id)->where('target_url', 'https://example.com/page')->exists())->toBeTrue();
});
it('generate slug fills slug field when empty', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
$component = Livewire::actingAs($user)->test(CreateLink::class)
->call('generateSlug');
expect($component->get('slug'))->not->toBeEmpty();
});
// EditLink
it('renders edit link modal with prefilled data', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
$link = Link::factory()->create([
'workspace_id' => $ws->id,
'title' => 'My Link',
'slug' => 'mylink',
'target_url' => 'https://old.example.com',
]);
Livewire::actingAs($user)->test(EditLink::class, ['linkUlid' => $link->ulid])
->assertOk()
->assertSet('targetUrl', 'https://old.example.com')
->assertSet('slug', 'mylink');
});
it('updates link on save', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
$link = Link::factory()->create([
'workspace_id' => $ws->id,
'slug' => 'oldslug',
'target_url' => 'https://old.example.com',
]);
Livewire::actingAs($user)->test(EditLink::class, ['linkUlid' => $link->ulid])
->set('targetUrl', 'https://new.example.com')
->set('slug', 'newslug')
->call('save')
->assertDispatched('linkUpdated');
expect($link->fresh()->target_url)->toBe('https://new.example.com');
expect($link->fresh()->slug)->toBe('newslug');
});
it('rejects edit for link in different workspace', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
$otherOwner = User::factory()->create();
$otherWs = Workspace::factory()->create(['owner_id' => $otherOwner->id]);
$link = Link::factory()->create(['workspace_id' => $otherWs->id]);
expect(fn () => Livewire::actingAs($user)->test(EditLink::class, ['linkUlid' => $link->ulid]))
->toThrow(ModelNotFoundException::class);
});
// DeleteLink
it('renders delete link modal', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
$link = Link::factory()->create([
'workspace_id' => $ws->id,
'title' => 'My Link',
]);
Livewire::actingAs($user)->test(DeleteLink::class, ['linkUlid' => $link->ulid])
->assertOk()
->assertSee('Delete Link');
});
it('soft-deletes link and dispatches linkDeleted', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
$link = Link::factory()->create(['workspace_id' => $ws->id]);
Livewire::actingAs($user)->test(DeleteLink::class, ['linkUlid' => $link->ulid])
->call('delete')
->assertDispatched('linkDeleted');
expect(Link::withTrashed()->find($link->id)->deleted_at)->not->toBeNull();
});
it('rejects delete for link in different workspace', function () {
[$user, $ws] = makeUserWithWs();
app()->instance('current_workspace', $ws);
$otherOwner = User::factory()->create();
$otherWs = Workspace::factory()->create(['owner_id' => $otherOwner->id]);
$link = Link::factory()->create(['workspace_id' => $otherWs->id]);
expect(fn () => Livewire::actingAs($user)->test(DeleteLink::class, ['linkUlid' => $link->ulid]))
->toThrow(ModelNotFoundException::class);
});