192 lines
5.1 KiB
PHP
192 lines
5.1 KiB
PHP
<?php
|
|
|
|
use App\Models\User;
|
|
use App\Uploads\Jobs\VirusScanJob;
|
|
use Illuminate\Support\Facades\Bus;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
function makeValidArchiveUpload(): UploadedFile
|
|
{
|
|
$path = tempnam(sys_get_temp_dir(), 'sb_preload_zip_');
|
|
if ($path === false) {
|
|
throw new \RuntimeException('Unable to allocate temporary zip path.');
|
|
}
|
|
|
|
$zip = new \ZipArchive();
|
|
if ($zip->open($path, \ZipArchive::OVERWRITE | \ZipArchive::CREATE) !== true) {
|
|
throw new \RuntimeException('Unable to create temporary zip file.');
|
|
}
|
|
|
|
$zip->addFromString('skins/theme/readme.txt', 'safe');
|
|
$zip->addFromString('skins/theme/colors.ini', 'accent=blue');
|
|
$zip->close();
|
|
|
|
return new UploadedFile($path, 'pack.zip', 'application/zip', null, true);
|
|
}
|
|
|
|
it('authenticated user can preload image', function () {
|
|
Storage::fake('local');
|
|
$user = User::factory()->create();
|
|
|
|
$main = UploadedFile::fake()->image('main.jpg', 1200, 800);
|
|
|
|
$response = $this
|
|
->actingAs($user)
|
|
->postJson('/api/uploads/preload', [
|
|
'main' => $main,
|
|
]);
|
|
|
|
$response->assertOk()->assertJsonStructure([
|
|
'upload_id',
|
|
'status',
|
|
'expires_at',
|
|
]);
|
|
|
|
$uploadId = $response->json('upload_id');
|
|
|
|
$this->assertDatabaseHas('uploads', [
|
|
'id' => $uploadId,
|
|
'user_id' => $user->id,
|
|
'type' => 'image',
|
|
'status' => 'draft',
|
|
]);
|
|
|
|
$this->assertDatabaseHas('upload_files', [
|
|
'upload_id' => $uploadId,
|
|
'type' => 'main',
|
|
]);
|
|
|
|
Storage::disk('local')->assertExists("tmp/drafts/{$uploadId}/meta.json");
|
|
expect(Storage::disk('local')->allFiles("tmp/drafts/{$uploadId}"))->not->toBeEmpty();
|
|
});
|
|
|
|
it('authenticated user can preload archive with screenshot', function () {
|
|
Storage::fake('local');
|
|
$user = User::factory()->create();
|
|
|
|
$main = makeValidArchiveUpload();
|
|
$screenshot = UploadedFile::fake()->image('screen1.jpg', 800, 600);
|
|
|
|
$response = $this
|
|
->actingAs($user)
|
|
->postJson('/api/uploads/preload', [
|
|
'main' => $main,
|
|
'screenshots' => [$screenshot],
|
|
]);
|
|
|
|
$response->assertOk()->assertJsonStructure([
|
|
'upload_id',
|
|
'status',
|
|
'expires_at',
|
|
]);
|
|
|
|
$uploadId = $response->json('upload_id');
|
|
|
|
$this->assertDatabaseHas('uploads', [
|
|
'id' => $uploadId,
|
|
'user_id' => $user->id,
|
|
'type' => 'archive',
|
|
'status' => 'draft',
|
|
]);
|
|
|
|
$this->assertDatabaseHas('upload_files', [
|
|
'upload_id' => $uploadId,
|
|
'type' => 'main',
|
|
]);
|
|
|
|
$this->assertDatabaseHas('upload_files', [
|
|
'upload_id' => $uploadId,
|
|
'type' => 'screenshot',
|
|
]);
|
|
|
|
Storage::disk('local')->assertExists("tmp/drafts/{$uploadId}/meta.json");
|
|
expect(Storage::disk('local')->allFiles("tmp/drafts/{$uploadId}"))->not->toBeEmpty();
|
|
});
|
|
|
|
it('guest is rejected', function () {
|
|
Storage::fake('local');
|
|
|
|
$main = UploadedFile::fake()->image('main.jpg', 1200, 800);
|
|
|
|
$response = $this->postJson('/api/uploads/preload', [
|
|
'main' => $main,
|
|
]);
|
|
|
|
expect(in_array($response->getStatusCode(), [401, 403]))->toBeTrue();
|
|
});
|
|
|
|
it('missing main file fails', function () {
|
|
Storage::fake('local');
|
|
$user = User::factory()->create();
|
|
|
|
$response = $this
|
|
->actingAs($user)
|
|
->postJson('/api/uploads/preload', []);
|
|
|
|
$response->assertStatus(422)->assertJsonValidationErrors(['main']);
|
|
});
|
|
|
|
it('archive without screenshot fails', function () {
|
|
Storage::fake('local');
|
|
$user = User::factory()->create();
|
|
|
|
$main = UploadedFile::fake()->create('pack.zip', 1024, 'application/zip');
|
|
|
|
$response = $this
|
|
->actingAs($user)
|
|
->postJson('/api/uploads/preload', [
|
|
'main' => $main,
|
|
]);
|
|
|
|
$response->assertStatus(422)->assertJsonValidationErrors(['screenshots']);
|
|
});
|
|
|
|
it('invalid file type is rejected', function () {
|
|
Storage::fake('local');
|
|
$user = User::factory()->create();
|
|
|
|
$main = UploadedFile::fake()->create('notes.txt', 4, 'text/plain');
|
|
|
|
$response = $this
|
|
->actingAs($user)
|
|
->postJson('/api/uploads/preload', [
|
|
'main' => $main,
|
|
]);
|
|
|
|
$response->assertStatus(422)->assertJsonValidationErrors(['main']);
|
|
});
|
|
|
|
it('preload dispatches VirusScanJob', function () {
|
|
Storage::fake('local');
|
|
Bus::fake();
|
|
|
|
$user = User::factory()->create();
|
|
$main = UploadedFile::fake()->image('main.jpg', 1200, 800);
|
|
|
|
$response = $this
|
|
->actingAs($user)
|
|
->postJson('/api/uploads/preload', [
|
|
'main' => $main,
|
|
]);
|
|
|
|
$response->assertOk()->assertJsonStructure([
|
|
'upload_id',
|
|
'status',
|
|
'expires_at',
|
|
]);
|
|
|
|
$uploadId = $response->json('upload_id');
|
|
|
|
Bus::assertDispatched(VirusScanJob::class, function (VirusScanJob $job) use ($uploadId) {
|
|
$reflect = new \ReflectionClass($job);
|
|
$property = $reflect->getProperty('uploadId');
|
|
$property->setAccessible(true);
|
|
|
|
return $property->getValue($job) === $uploadId;
|
|
});
|
|
});
|