170 lines
5.2 KiB
PHP
170 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('link-created');
|
|
|
|
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('link-updated');
|
|
|
|
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('link-deleted');
|
|
|
|
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);
|
|
});
|