Deploy Ladill Transfer / deploy (push) Successful in 35s
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>
253 lines
8.1 KiB
PHP
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');
|
|
}
|
|
}
|