mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-16 16:45:07 +00:00
6e47d76ba6
Client file sharing, rebuilt from the ground up: a private area per client, resumable uploads, folders, groups and categories, sharing with expiry dates and download limits, comments, file versions, an activity log, a REST API, and sixteen languages. This repository begins here. ProjectSend 2 was developed privately, and that development history is not published — the previous generation remains available, with its own history, at projectsend/legacy. Free software under the GNU General Public License v2, or (at your option) any later version.
124 lines
4.2 KiB
PHP
124 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\User;
|
|
use App\Modules\Files\Folders\FolderService;
|
|
use App\Modules\Files\Models\File;
|
|
use App\Modules\Files\Models\FileAssignment;
|
|
use Inertia\Testing\AssertableInertia;
|
|
|
|
beforeEach(function () {
|
|
// A staff user must exist or every request 302s to /setup.
|
|
User::factory()->create();
|
|
});
|
|
|
|
function myFilesPaginationFolders(User $client, int $count, string $prefix = 'Folder'): void
|
|
{
|
|
test()->actingAs($client);
|
|
for ($i = 1; $i <= $count; $i++) {
|
|
app(FolderService::class)->create(sprintf('%s %02d', $prefix, $i), null);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return list<int>
|
|
*/
|
|
function myFilesPaginationFiles(User $client, int $count, string $prefix = 'file'): array
|
|
{
|
|
$ids = [];
|
|
for ($i = 1; $i <= $count; $i++) {
|
|
$file = File::factory()->create([
|
|
'uploaded_by' => $client->id,
|
|
'name' => sprintf('%s-%02d', $prefix, $i),
|
|
'original_name' => sprintf('%s-%02d.pdf', $prefix, $i),
|
|
'mime_type' => 'application/pdf',
|
|
'size' => 100,
|
|
]);
|
|
FileAssignment::query()->create([
|
|
'file_id' => $file->id,
|
|
'assignable_type' => (new User)->getMorphClass(),
|
|
'assignable_id' => $client->id,
|
|
]);
|
|
$ids[] = $file->id;
|
|
}
|
|
|
|
return $ids;
|
|
}
|
|
|
|
test('a directory with more folders than the page size splits folders across pages', function () {
|
|
$client = User::factory()->client()->create();
|
|
myFilesPaginationFolders($client, 30);
|
|
|
|
$this->actingAs($client)->get('/my-files')->assertInertia(
|
|
fn (AssertableInertia $page) => $page
|
|
->has('folders', 25)
|
|
->has('files', 0)
|
|
->where('pagination.total', 30)
|
|
->where('pagination.last_page', 2),
|
|
);
|
|
|
|
$this->actingAs($client)->get('/my-files?page=2')->assertInertia(
|
|
fn (AssertableInertia $page) => $page->has('folders', 5)->has('files', 0),
|
|
);
|
|
});
|
|
|
|
test('a transition mid-page splits between folders and files with no gap, overlap, or duplicate', function () {
|
|
$client = User::factory()->client()->create();
|
|
myFilesPaginationFolders($client, 10);
|
|
$fileIds = myFilesPaginationFiles($client, 30);
|
|
|
|
$seenFileIds = [];
|
|
$capture = function ($files) use (&$seenFileIds) {
|
|
foreach ($files as $file) {
|
|
$seenFileIds[] = $file['id'];
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
$this->actingAs($client)->get('/my-files')->assertInertia(
|
|
fn (AssertableInertia $page) => $page->has('folders', 10)->has('files', 15)->where('files', $capture),
|
|
);
|
|
|
|
$this->actingAs($client)->get('/my-files?page=2')->assertInertia(
|
|
fn (AssertableInertia $page) => $page->has('folders', 0)->has('files', 15)->where('files', $capture),
|
|
);
|
|
|
|
expect($seenFileIds)->toHaveCount(30)
|
|
->and(array_unique($seenFileIds))->toHaveCount(30)
|
|
->and(collect($seenFileIds)->sort()->values()->all())->toBe(collect($fileIds)->sort()->values()->all());
|
|
});
|
|
|
|
test('a directory with no folders paginates files exactly as before', function () {
|
|
$client = User::factory()->client()->create();
|
|
myFilesPaginationFiles($client, 30);
|
|
|
|
$this->actingAs($client)->get('/my-files')->assertInertia(
|
|
fn (AssertableInertia $page) => $page->has('folders', 0)->has('files', 25),
|
|
);
|
|
|
|
$this->actingAs($client)->get('/my-files?page=2')->assertInertia(
|
|
fn (AssertableInertia $page) => $page->has('folders', 0)->has('files', 5),
|
|
);
|
|
});
|
|
|
|
test('requesting a page beyond the last one redirects to the real last page, preserving sort/direction', function () {
|
|
$client = User::factory()->client()->create();
|
|
myFilesPaginationFolders($client, 5);
|
|
myFilesPaginationFiles($client, 5);
|
|
|
|
$this->actingAs($client)->get('/my-files?sort=name&direction=asc&page=99')
|
|
->assertRedirect('/my-files?sort=name&direction=asc');
|
|
});
|
|
|
|
test('pagination.total reflects folders plus files, not files alone', function () {
|
|
$client = User::factory()->client()->create();
|
|
myFilesPaginationFolders($client, 3);
|
|
myFilesPaginationFiles($client, 4);
|
|
|
|
$this->actingAs($client)->get('/my-files')->assertInertia(
|
|
fn (AssertableInertia $page) => $page->where('pagination.total', 7),
|
|
);
|
|
});
|