Files
ladill-transfer/tests/Feature/TransferFilesTest.php
T
isaaccladandCursor be3b719437
Deploy Ladill Transfer / deploy (push) Successful in 35s
Make folders selectable and downloadable with item count and sharing status.
Folder rows match the file table layout, support zip download, and participate in bulk selection, share, and copy-link actions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 22:21:39 +00:00

253 lines
8.1 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Transfer;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Tests\Concerns\FakesTransferBilling;
use Tests\TestCase;
class TransferFilesTest extends TestCase
{
use FakesTransferBilling;
use RefreshDatabase;
private function createUser(): User
{
return User::create([
'public_id' => (string) Str::uuid(),
'name' => 'Test User',
'email' => 'transfer+'.uniqid().'@example.com',
]);
}
private function createShareTransfer(User $user, string $title, string $filename): Transfer
{
$this->actingAs($user)->post(route('transfer.transfers.store'), [
'title' => $title,
'files' => [UploadedFile::fake()->create($filename, 50, 'application/pdf')],
])->assertRedirect();
return Transfer::query()->where('title', $title)->firstOrFail();
}
private function createFolder(User $user, string $name): Transfer
{
$this->actingAs($user)->post(route('transfer.files.folders.store'), [
'name' => $name,
])->assertRedirect();
return Transfer::query()->where('title', $name)->where('is_folder', true)->firstOrFail();
}
public function test_owner_can_download_file(): void
{
Storage::fake('qr');
$this->fakeTransferBillingApi();
$user = $this->createUser();
$transfer = $this->createShareTransfer($user, 'Docs', 'brief.pdf');
$file = $transfer->files()->first();
$this->actingAs($user)
->get(route('transfer.files.download', $file))
->assertOk();
}
public function test_owner_can_delete_file(): void
{
Storage::fake('qr');
$this->fakeTransferBillingApi();
$user = $this->createUser();
$transfer = $this->createShareTransfer($user, 'Docs', 'brief.pdf');
$file = $transfer->files()->first();
$this->actingAs($user)
->delete(route('transfer.files.destroy', $file))
->assertRedirect();
$this->assertDatabaseMissing('transfer_files', ['id' => $file->id]);
}
public function test_owner_can_move_file_into_user_folder(): void
{
Storage::fake('qr');
$this->fakeTransferBillingApi();
$user = $this->createUser();
$this->createShareTransfer($user, 'Loose file', 'one.pdf');
$file = Transfer::query()->where('title', 'Loose file')->first()->files()->first();
$folder = $this->createFolder($user, 'Destination folder');
$this->actingAs($user)
->post(route('transfer.files.move'), [
'destination' => $folder->id,
'files' => [$file->id],
])
->assertRedirect(route('transfer.files.index', ['folder' => $folder->id]));
$this->assertSame($folder->id, $file->fresh()->transfer_id);
}
public function test_files_index_shows_user_folder(): void
{
Storage::fake('qr');
$this->fakeTransferBillingApi();
$user = $this->createUser();
$folder = $this->createFolder($user, 'BKC');
$this->actingAs($user)
->get(route('transfer.files.index'))
->assertOk()
->assertSee('BKC');
$this->actingAs($user)
->get(route('transfer.files.index', ['folder' => $folder->id]))
->assertOk()
->assertSee('BKC');
}
public function test_upload_detects_duplicate_filenames(): void
{
Storage::fake('qr');
$this->fakeTransferBillingApi();
$user = $this->createUser();
$this->createShareTransfer($user, 'Docs', 'brief.pdf');
$this->actingAs($user)
->postJson(route('transfer.files.upload.check'), [
'filenames' => ['brief.pdf', 'new.docx'],
])
->assertOk()
->assertJsonPath('conflicts.0.filename', 'brief.pdf');
}
public function test_upload_can_replace_duplicate_file(): void
{
Storage::fake('qr');
$this->fakeTransferBillingApi();
$user = $this->createUser();
$this->createShareTransfer($user, 'Docs', 'brief.pdf');
$this->actingAs($user)
->post(route('transfer.files.upload'), [
'files' => [UploadedFile::fake()->create('brief.pdf', 80, 'application/pdf')],
'resolutions' => ['brief.pdf' => 'replace'],
])
->assertRedirect();
$this->assertSame(1, \App\Models\TransferFile::query()->count());
$this->assertDatabaseHas('transfer_files', ['original_name' => 'brief.pdf']);
}
public function test_upload_keep_both_renames_duplicate(): void
{
Storage::fake('qr');
$this->fakeTransferBillingApi();
$user = $this->createUser();
$this->createShareTransfer($user, 'Docs', 'brief.pdf');
$this->actingAs($user)
->post(route('transfer.files.upload'), [
'files' => [UploadedFile::fake()->create('brief.pdf', 80, 'application/pdf')],
'resolutions' => ['brief.pdf' => 'keep_both'],
])
->assertRedirect();
$this->assertDatabaseHas('transfer_files', ['original_name' => 'brief.pdf']);
$this->assertDatabaseHas('transfer_files', ['original_name' => 'brief (1).pdf']);
}
public function test_upload_stores_basename_when_folder_path_in_filename(): void
{
Storage::fake('qr');
$this->fakeTransferBillingApi();
$user = $this->createUser();
$this->actingAs($user)
->post(route('transfer.files.upload'), [
'files' => [
UploadedFile::fake()->createWithContent(
'red-logo/icon.svg',
'<svg></svg>',
),
],
])
->assertRedirect();
$this->assertDatabaseHas('transfer_files', ['original_name' => 'icon.svg']);
$this->assertDatabaseMissing('transfer_files', ['original_name' => 'red-logo/icon.svg']);
}
public function test_folder_upload_creates_folder_with_files(): void
{
Storage::fake('qr');
$this->fakeTransferBillingApi();
$user = $this->createUser();
$this->actingAs($user)
->postJson(route('transfer.files.upload'), [
'upload_folder_name' => 'Brand assets',
'files' => [
UploadedFile::fake()->create('logo.svg', 10, 'image/svg+xml'),
UploadedFile::fake()->create('cover.png', 10, 'image/png'),
],
])
->assertOk()
->assertJsonPath('count', 2)
->assertJsonPath('folder_id', fn ($id) => is_int($id));
$folder = Transfer::query()
->where('user_id', $user->id)
->where('is_folder', true)
->where('title', 'Brand assets')
->first();
$this->assertNotNull($folder);
$this->assertSame(2, $folder->files()->count());
$this->assertDatabaseHas('transfer_files', [
'transfer_id' => $folder->id,
'original_name' => 'logo.svg',
]);
$this->assertDatabaseHas('transfer_files', [
'transfer_id' => $folder->id,
'original_name' => 'cover.png',
]);
}
public function test_owner_can_download_folder_as_zip(): void
{
Storage::fake('qr');
$this->fakeTransferBillingApi();
$user = $this->createUser();
$folder = $this->createFolder($user, 'Forum');
$this->actingAs($user)
->postJson(route('transfer.files.upload'), [
'folder' => $folder->id,
'files' => [
UploadedFile::fake()->create('notes.txt', 10, 'text/plain'),
UploadedFile::fake()->create('photo.jpg', 10, 'image/jpeg'),
],
])
->assertOk();
$this->actingAs($user)
->get(route('transfer.files.folders.download', $folder))
->assertOk()
->assertHeader('content-type', 'application/zip');
}
}