Add tests
This commit is contained in:
parent
07591ea52b
commit
502bb41e97
|
@ -5,6 +5,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
"Zoomyboy\\MedialibraryHelper\\Tests\\": "tests/",
|
||||||
"Zoomyboy\\MedialibraryHelper\\": "src/"
|
"Zoomyboy\\MedialibraryHelper\\": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -15,6 +16,24 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"spatie/laravel-medialibrary": "^10.7"
|
"spatie/laravel-medialibrary": "^10.7",
|
||||||
|
"laravel/framework": "^9.50",
|
||||||
|
"spatie/laravel-data": "^3.1",
|
||||||
|
"pestphp/pest": "^1.22"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^9.6",
|
||||||
|
"orchestra/testbench": "^7.0",
|
||||||
|
"illuminate/console": "^9.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"post-autoload-dump": [
|
||||||
|
"@php vendor/bin/testbench package:discover --ansi"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"allow-plugins": {
|
||||||
|
"pestphp/pest-plugin": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
|
||||||
|
bootstrap="vendor/autoload.php"
|
||||||
|
colors="true"
|
||||||
|
>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Feature">
|
||||||
|
<directory suffix="Test.php">./tests/Feature</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
<coverage>
|
||||||
|
<include>
|
||||||
|
<directory suffix=".php">./src</directory>
|
||||||
|
</include>
|
||||||
|
</coverage>
|
||||||
|
<php>
|
||||||
|
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF"/>
|
||||||
|
<env name="APP_ENV" value="testing"/>
|
||||||
|
<env name="APP_URL" value="http://localhost:8000"/>
|
||||||
|
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||||
|
<env name="CACHE_DRIVER" value="array"/>
|
||||||
|
<env name="DB_CONNECTION" value="sqlite"/>
|
||||||
|
<env name="DB_DATABASE" value=":memory:"/>
|
||||||
|
<env name="MAIL_MAILER" value="array"/>
|
||||||
|
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||||
|
<env name="SESSION_DRIVER" value="array"/>
|
||||||
|
<env name="TELESCOPE_ENABLED" value="false"/>
|
||||||
|
</php>
|
||||||
|
</phpunit>
|
|
@ -8,6 +8,7 @@ use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
use Spatie\MediaLibrary\HasMedia;
|
use Spatie\MediaLibrary\HasMedia;
|
||||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||||
|
|
||||||
|
@ -15,43 +16,61 @@ class MediaController
|
||||||
{
|
{
|
||||||
use AuthorizesRequests;
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public function store(Request $request): JsonResponse
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'name' => 'nullable|string',
|
'name' => 'string',
|
||||||
'content' => 'required|string',
|
|
||||||
'model' => ['required', 'string', Rule::in(app('media-library-helpers')->keys())],
|
'model' => ['required', 'string', Rule::in(app('media-library-helpers')->keys())],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$model = $this->validateModel($request);
|
$model = $this->validateModel($request);
|
||||||
$this->authorize('storeMedia', $model);
|
$this->authorize('storeMedia', $model);
|
||||||
|
|
||||||
$collection = $model->getMediaCollection($request->input('collection'));
|
$collection = $model->getMediaCollection($request->input('collection'));
|
||||||
$isSingle = 1 === $collection->collectionSizeLimit;
|
$isSingle = 1 === $collection->collectionSizeLimit;
|
||||||
|
|
||||||
if ($collection->forceFileRenamer) {
|
$request->validate($isSingle ? [
|
||||||
$fileRenamer = $collection->forceFileRenamer;
|
'payload' => 'array',
|
||||||
$path = $fileRenamer($model);
|
'payload.name' => 'string|max:255',
|
||||||
} else {
|
'payload.content' => 'string',
|
||||||
$path = $request->input('name', Str::random(32));
|
] : [
|
||||||
}
|
'payload' => 'required|array|min:1',
|
||||||
|
'payload.*' => 'array',
|
||||||
|
'payload.*.name' => 'string',
|
||||||
|
'payload.*.content' => 'string',
|
||||||
|
]);
|
||||||
|
|
||||||
$content = $isSingle ? [$request->input('content')] : $request->input('content');
|
$content = $isSingle ? [$request->input('payload')] : $request->input('payload');
|
||||||
|
|
||||||
$medias = collect([]);
|
$medias = collect([]);
|
||||||
foreach ($content as $c) {
|
foreach ($content as $c) {
|
||||||
Storage::disk('public')->put($path, base64_decode($c));
|
if (property_exists($collection, 'forceFileRenamer')) {
|
||||||
|
$fileRenamer = $collection->forceFileRenamer;
|
||||||
|
$path = $fileRenamer($model, pathinfo($c['name'], PATHINFO_FILENAME)).'.'.pathinfo($c['name'], PATHINFO_EXTENSION);
|
||||||
|
} else {
|
||||||
|
$path = $c['name'];
|
||||||
|
}
|
||||||
|
Storage::disk('public')->put($path, base64_decode($c['content']));
|
||||||
|
|
||||||
$medias->push($model->addMedia(Storage::disk('public')->path($path))->toMediaCollection($collection->name));
|
$adder = $model->addMedia(Storage::disk('public')->path($path));
|
||||||
|
if (property_exists($collection, 'storingCallback')) {
|
||||||
|
$callback = $collection->storingCallback;
|
||||||
|
$adder = $callback($adder, $path);
|
||||||
|
}
|
||||||
|
$media = $adder->toMediaCollection($collection->name);
|
||||||
|
$medias->push($media);
|
||||||
|
|
||||||
|
if ($isSingle) {
|
||||||
|
return MediaData::fromMedia($media);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($isSingle ? $medias->first()->toArray() : $medias->map(fn ($media) => $media->toArray()));
|
return MediaData::collection($medias);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(Request $request, $parentModel, int $parentId, string $collection): JsonResponse
|
public function index(Request $request, $parentModel, int $parentId, string $collection): JsonResponse
|
||||||
{
|
{
|
||||||
$model = app('media-library-helpers')->get($parentModel);
|
$model = app('media-library-helpers')->get($parentModel);
|
||||||
$model = $model::findOrFail($parentId);
|
$model = $model::find($parentId);
|
||||||
$isSingle = $model->getMediaCollection($collection)->collectionSizeLimit;
|
$isSingle = $model->getMediaCollection($collection)->collectionSizeLimit;
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
@ -75,6 +94,10 @@ class MediaController
|
||||||
'collection' => ['required', 'string', Rule::in((new $model())->getRegisteredMediaCollections()->map(fn ($collection) => $collection->name)->toArray())],
|
'collection' => ['required', 'string', Rule::in((new $model())->getRegisteredMediaCollections()->map(fn ($collection) => $collection->name)->toArray())],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $model::findOrFail($request->input('id'));
|
if (!$model::find($request->input('id'))) {
|
||||||
|
throw ValidationException::withMessages(['model' => 'nicht gefunden']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model::find($request->input('id'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\MedialibraryHelper;
|
||||||
|
|
||||||
|
use Spatie\LaravelData\Attributes\MapInputName;
|
||||||
|
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||||
|
use Spatie\LaravelData\Data;
|
||||||
|
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
|
||||||
|
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||||
|
|
||||||
|
#[MapInputName(SnakeCaseMapper::class)]
|
||||||
|
#[MapOutputName(SnakeCaseMapper::class)]
|
||||||
|
class MediaData extends Data {
|
||||||
|
|
||||||
|
public int $id;
|
||||||
|
|
||||||
|
public string $originalUrl;
|
||||||
|
|
||||||
|
public int $size;
|
||||||
|
|
||||||
|
public string $name;
|
||||||
|
|
||||||
|
public string $collectionName;
|
||||||
|
|
||||||
|
public string $fileName;
|
||||||
|
|
||||||
|
public static function fromMedia(Media $media): self
|
||||||
|
{
|
||||||
|
return self::withoutMagicalCreationFrom($media);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ class ServiceProvider extends BaseServiceProvider
|
||||||
|
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
app(Router::class)->group(['middleware' => ['web', 'auth:web']], function ($router) {
|
app(Router::class)->group($this->routeGroup(), function ($router) {
|
||||||
$router->post('mediaupload', [MediaController::class, 'store'])->name('media.store');
|
$router->post('mediaupload', [MediaController::class, 'store'])->name('media.store');
|
||||||
$router->delete('mediaupload/{media}', [MediaController::class, 'destroy'])->name('media.destroy');
|
$router->delete('mediaupload/{media}', [MediaController::class, 'destroy'])->name('media.destroy');
|
||||||
$router->get('mediaupload/{parent_model}/{parent_id}/{collection}', [MediaController::class, 'index'])->name('media.index');
|
$router->get('mediaupload/{parent_model}/{parent_id}/{collection}', [MediaController::class, 'index'])->name('media.index');
|
||||||
|
@ -26,5 +26,21 @@ class ServiceProvider extends BaseServiceProvider
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
MediaCollection::macro('storing', function ($callback) {
|
||||||
|
$this->storingCallback = $callback;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array{middleware: array<int, string>}
|
||||||
|
*/
|
||||||
|
protected function routeGroup(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'middleware' => config('medialibrary-helper.middleware'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\MedialibraryHelper\Tests\Feature;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Zoomyboy\MedialibraryHelper\Tests\TestCase;
|
||||||
|
|
||||||
|
class MiddlewareTest extends TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
public function testItReturns401WhenNotLoggedIn(): void
|
||||||
|
{
|
||||||
|
$this->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
|
||||||
|
$response = $this->postJson('/mediaupload', [
|
||||||
|
'model' => 'post',
|
||||||
|
'id' => $post->id,
|
||||||
|
'collection' => 'defaultSingleFile',
|
||||||
|
'content' => base64_encode($this->pdfFile()->getContent()),
|
||||||
|
'name' => 'beispiel bild.jpg',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItReturns401WhenDestroying(): void
|
||||||
|
{
|
||||||
|
$this->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
$media = $post->addMedia($this->pdfFile()->getPathname())->toMediaCollection('defaultSingleFile');
|
||||||
|
|
||||||
|
$response = $this->deleteJson("/mediaupload/{$media->id}");
|
||||||
|
|
||||||
|
$response->assertStatus(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function defineEnvironment($app)
|
||||||
|
{
|
||||||
|
$app['config']->set('medialibrary-helper.middleware', ['web', 'auth:web']);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,229 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\MedialibraryHelper\Tests\Feature;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
test('it uploads a single file to a single file collection', function() {
|
||||||
|
$this->auth()->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
$content = base64_encode($this->pdfFile()->getContent());
|
||||||
|
|
||||||
|
$response = $this->postJson('/mediaupload', [
|
||||||
|
'model' => 'post',
|
||||||
|
'id' => $post->id,
|
||||||
|
'collection' => 'defaultSingleFile',
|
||||||
|
'payload' => [
|
||||||
|
'content' => $content,
|
||||||
|
'name' => 'beispiel bild.jpg',
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(201);
|
||||||
|
$this->assertCount(1, $post->getMedia('defaultSingleFile'));
|
||||||
|
$media = $post->getFirstMedia('defaultSingleFile');
|
||||||
|
$response->assertJsonPath('id', $media->id);
|
||||||
|
$response->assertJsonPath('original_url', $media->getFullUrl());
|
||||||
|
$response->assertJsonPath('size', 3028);
|
||||||
|
$response->assertJsonPath('name', 'beispiel bild');
|
||||||
|
$response->assertJsonPath('collection_name', 'defaultSingleFile');
|
||||||
|
$response->assertJsonPath('file_name', 'beispiel-bild.jpg');
|
||||||
|
$response->assertJsonMissingPath('model_type');
|
||||||
|
$response->assertJsonMissingPath('model_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it forces a filename for a single collection', function() {
|
||||||
|
Carbon::setTestNow(Carbon::parse('2023-04-04 00:00:00'));
|
||||||
|
$this->auth()->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
$content = base64_encode($this->pdfFile()->getContent());
|
||||||
|
|
||||||
|
$response = $this->postJson('/mediaupload', [
|
||||||
|
'model' => 'post',
|
||||||
|
'id' => $post->id,
|
||||||
|
'collection' => 'singleForced',
|
||||||
|
'payload' => [
|
||||||
|
'content' => $content,
|
||||||
|
'name' => 'beispiel bild.jpg',
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(201);
|
||||||
|
$this->assertEquals('beispiel-bild-2023-04-04.jpg', $post->getFirstMedia('singleForced')->file_name);
|
||||||
|
$response->assertJsonPath('name', "beispiel bild 2023-04-04");
|
||||||
|
$response->assertJsonPath('file_name', "beispiel-bild-2023-04-04.jpg");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it sets custom title when storing', function() {
|
||||||
|
$this->auth()->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
$content = base64_encode($this->pdfFile()->getContent());
|
||||||
|
|
||||||
|
$response = $this->postJson('/mediaupload', [
|
||||||
|
'model' => 'post',
|
||||||
|
'id' => $post->id,
|
||||||
|
'collection' => 'singleStoringHook',
|
||||||
|
'payload' => [
|
||||||
|
'content' => $content,
|
||||||
|
'name' => 'beispiel bild.jpg',
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(201);
|
||||||
|
$media = $post->getFirstMedia('singleStoringHook');
|
||||||
|
|
||||||
|
$this->assertEquals('AAA', $media->getCustomProperty('use'));
|
||||||
|
$this->assertEquals('beispiel bild', $media->getCustomProperty('ttt'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it forces a filename for multiple collections', function() {
|
||||||
|
Carbon::setTestNow(Carbon::parse('2023-04-04 00:00:00'));
|
||||||
|
$this->auth()->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
$content = base64_encode($this->pdfFile()->getContent());
|
||||||
|
|
||||||
|
$response = $this->postJson('/mediaupload', [
|
||||||
|
'model' => 'post',
|
||||||
|
'id' => $post->id,
|
||||||
|
'collection' => 'multipleForced',
|
||||||
|
'payload' => [
|
||||||
|
[
|
||||||
|
'content' => $content,
|
||||||
|
'name' => 'beispiel bild.jpg',
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(201);
|
||||||
|
$this->assertEquals('beispiel-bild-2023-04-04.jpg', $post->getFirstMedia('multipleForced')->file_name);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it uploads multiple files', function() {
|
||||||
|
$this->auth()->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
$file = $this->pdfFile();
|
||||||
|
$post->addMedia($file->getPathname())->preservingOriginal()->toMediaCollection('images');
|
||||||
|
|
||||||
|
$response = $this->postJson('/mediaupload', [
|
||||||
|
'model' => 'post',
|
||||||
|
'id' => $post->id,
|
||||||
|
'collection' => 'images',
|
||||||
|
'payload' => [
|
||||||
|
[
|
||||||
|
'content' => base64_encode($file->getContent()),
|
||||||
|
'name' => 'aaaa.jpg',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'content' => base64_encode($file->getContent()),
|
||||||
|
'name' => 'beispiel bild.jpg',
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(201);
|
||||||
|
$this->assertCount(3, $post->getMedia('images'));
|
||||||
|
$media = $post->getMedia('images')->skip(1)->values();
|
||||||
|
$this->assertCount(2, $response->json());
|
||||||
|
$response->assertJsonPath('0.id', $media->get(0)->id);
|
||||||
|
$response->assertJsonPath('1.id', $media->get(1)->id);
|
||||||
|
$response->assertJsonPath('0.original_url', $media->first()->getFullUrl());
|
||||||
|
$response->assertJsonPath('0.size', 3028);
|
||||||
|
$response->assertJsonPath('0.name', 'aaaa');
|
||||||
|
$response->assertJsonPath('0.collection_name', 'images');
|
||||||
|
$response->assertJsonPath('0.file_name', 'aaaa.jpg');
|
||||||
|
$response->assertJsonMissingPath('0.model_type');
|
||||||
|
$response->assertJsonMissingPath('0.model_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it returns 403 when not authorized', function() {
|
||||||
|
$this->auth(['storeMedia' => false])->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
|
||||||
|
$response = $this->postJson('/mediaupload', [
|
||||||
|
'model' => 'post',
|
||||||
|
'id' => $post->id,
|
||||||
|
'collection' => 'defaultSingleFile',
|
||||||
|
'payload' => [
|
||||||
|
'content' => base64_encode($this->pdfFile()->getContent()),
|
||||||
|
'name' => 'beispiel bild.jpg',
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(403);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it needs validation for single files', function(array $payload, string $invalidFieldName) {
|
||||||
|
$this->auth()->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
|
||||||
|
$response = $this->postJson('/mediaupload', [
|
||||||
|
'model' => 'post',
|
||||||
|
'id' => $post->id,
|
||||||
|
'collection' => 'defaultSingleFile',
|
||||||
|
'payload' => [
|
||||||
|
'content' => base64_encode($this->pdfFile()->getContent()),
|
||||||
|
'name' => 'beispiel bild.jpg',
|
||||||
|
],
|
||||||
|
...$payload
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
$response->assertJsonValidationErrors($invalidFieldName);
|
||||||
|
})->with(function() {
|
||||||
|
yield [ ['model' => 'missingmodel'], 'model' ];
|
||||||
|
yield [ ['id' => -1], 'model' ];
|
||||||
|
yield [ ['collection' => 'missingcollection'], 'collection' ];
|
||||||
|
yield [ ['payload' => ['name' => 'AAA', 'content' => []]], 'payload.content' ];
|
||||||
|
yield [ ['payload' => ['name' => 'AAA', 'content' => ['UU']]], 'payload.content' ];
|
||||||
|
yield [ ['payload' => ['name' => 'AAA', 'content' => null]], 'payload.content' ];
|
||||||
|
yield [ ['payload' => ['name' => 'AAA', 'content' => '']], 'payload.content' ];
|
||||||
|
yield [ ['payload' => ['name' => 'AAA', 'content' => 1]], 'payload.content' ];
|
||||||
|
yield [ ['payload' => ['name' => '', 'content' => 'aaadfdf']], 'payload.name' ];
|
||||||
|
yield [ ['payload' => ['name' => ['U'], 'content' => 'aaadfdf']], 'payload.name' ];
|
||||||
|
yield [ ['payload' => ['name' => 1, 'content' => 'aaadfdf']], 'payload.name' ];
|
||||||
|
yield [ ['payload' => ['name' => null, 'content' => 'aaadfdf']], 'payload.name' ];
|
||||||
|
yield [ ['payload' => 'lalal'], 'payload' ];
|
||||||
|
yield [ ['payload' => 55], 'payload' ];
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('it needs validation for multiple files', function(array $payload, string $invalidFieldName) {
|
||||||
|
$this->auth()->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
|
||||||
|
$response = $this->postJson('/mediaupload', [
|
||||||
|
'model' => 'post',
|
||||||
|
'id' => $post->id,
|
||||||
|
'collection' => 'images',
|
||||||
|
'payload' => [
|
||||||
|
[
|
||||||
|
'content' => base64_encode($this->pdfFile()->getContent()),
|
||||||
|
'name' => 'beispiel bild.jpg',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
...$payload
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
$response->assertJsonValidationErrors($invalidFieldName);
|
||||||
|
})->with(function() {
|
||||||
|
yield [ ['model' => 'missingmodel'], 'model' ];
|
||||||
|
yield [ ['id' => -1], 'model' ];
|
||||||
|
yield [ ['collection' => 'missingcollection'], 'collection' ];
|
||||||
|
yield [ ['payload' => 'lalal'], 'payload' ];
|
||||||
|
yield [ ['payload' => []], 'payload' ];
|
||||||
|
yield [ ['payload' => 1], 'payload' ];
|
||||||
|
|
||||||
|
yield [ ['payload' => [['name' => 'AAA', 'content' => []]]], 'payload.0.content' ];
|
||||||
|
yield [ ['payload' => [['name' => 'AAA', 'content' => ['UU']]]], 'payload.0.content' ];
|
||||||
|
yield [ ['payload' => [['name' => 'AAA', 'content' => null]]], 'payload.0.content' ];
|
||||||
|
yield [ ['payload' => [['name' => 'AAA', 'content' => '']]], 'payload.0.content' ];
|
||||||
|
yield [ ['payload' => [['name' => 'AAA', 'content' => 1]]], 'payload.0.content' ];
|
||||||
|
yield [ ['payload' => [['name' => '', 'content' => 'aaadfdf']]], 'payload.0.name' ];
|
||||||
|
yield [ ['payload' => [['name' => ['U'], 'content' => 'aaadfdf']]], 'payload.0.name' ];
|
||||||
|
yield [ ['payload' => [['name' => 1, 'content' => 'aaadfdf']]], 'payload.0.name' ];
|
||||||
|
yield [ ['payload' => [['name' => null, 'content' => 'aaadfdf']]], 'payload.0.name' ];
|
||||||
|
yield [ ['payload' => ['RRR']], 'payload.0' ];
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\MedialibraryHelper\Tests\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Spatie\MediaLibrary\HasMedia;
|
||||||
|
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||||
|
|
||||||
|
class Post extends Model implements HasMedia
|
||||||
|
{
|
||||||
|
|
||||||
|
use InteractsWithMedia;
|
||||||
|
|
||||||
|
public $guarded = [];
|
||||||
|
|
||||||
|
public function registerMediaCollections(): void
|
||||||
|
{
|
||||||
|
$this->addMediaCollection('defaultSingleFile')->singleFile();
|
||||||
|
|
||||||
|
$this->addMediaCollection('images');
|
||||||
|
|
||||||
|
$this->addMediaCollection('singleForced')->singleFile()->forceFileName(function($adder, $name) {
|
||||||
|
return $name.' '.now()->format('Y-m-d');
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->addMediaCollection('multipleForced')->forceFileName(function($adder, $name) {
|
||||||
|
return $name.' '.now()->format('Y-m-d');
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->addMediaCollection('singleStoringHook')->singleFile()->storing(function($adder, $fileName) {
|
||||||
|
return $adder->withCustomProperties([
|
||||||
|
'use' => 'AAA',
|
||||||
|
'ttt' => pathinfo($fileName, PATHINFO_FILENAME),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
uses(Zoomyboy\MedialibraryHelper\Tests\TestCase::class)->in('Feature');
|
||||||
|
uses(Illuminate\Foundation\Testing\RefreshDatabase::class)->in('Feature');
|
||||||
|
uses()->beforeEach(fn () => Storage::fake('media'))->in('Feature');
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\MedialibraryHelper\Tests;
|
||||||
|
|
||||||
|
use Illuminate\Http\File;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\Gate;
|
||||||
|
use Orchestra\Testbench\TestCase as BaseTestCase;
|
||||||
|
use Spatie\LaravelData\LaravelDataServiceProvider;
|
||||||
|
use Spatie\MediaLibrary\MediaLibraryServiceProvider;
|
||||||
|
use Zoomyboy\MedialibraryHelper\ServiceProvider;
|
||||||
|
use Zoomyboy\MedialibraryHelper\Tests\Models\Post;
|
||||||
|
|
||||||
|
class TestCase extends BaseTestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define database migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function defineDatabaseMigrations(): void
|
||||||
|
{
|
||||||
|
$this->loadMigrationsFrom(__DIR__ . '/migrations');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPackageProviders($app): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
ServiceProvider::class,
|
||||||
|
MediaLibraryServiceProvider::class,
|
||||||
|
LaravelDataServiceProvider::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a pdf file with a filename and get path
|
||||||
|
*/
|
||||||
|
protected function pdfFile(?string $filename = null): File
|
||||||
|
{
|
||||||
|
return $this->getFile('pdf.pdf', $filename ?: 'pdf.pdf');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFile(string $location, string $as): File
|
||||||
|
{
|
||||||
|
$path = __DIR__.'/stubs/'.$location;
|
||||||
|
$to = sys_get_temp_dir().'/'.$as;
|
||||||
|
copy($path, $to);
|
||||||
|
|
||||||
|
return new File($to);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function registerModel(): static
|
||||||
|
{
|
||||||
|
app()->extend('media-library-helpers', fn ($p) => $p->put('post', Post::class));
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newPost(): Post
|
||||||
|
{
|
||||||
|
return Post::create(['title' => 'Lorem', 'content' => 'aafff']);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function auth(array $policies = []): self
|
||||||
|
{
|
||||||
|
$policies = [
|
||||||
|
'storeMedia' => true,
|
||||||
|
'updateMedia' => true,
|
||||||
|
'destroyMedia' => true,
|
||||||
|
...$policies,
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($policies as $ability => $result) {
|
||||||
|
Gate::define($ability, fn (?string $whatever) => $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('media', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
$table->morphs('model');
|
||||||
|
$table->uuid('uuid')->nullable()->unique();
|
||||||
|
$table->string('collection_name');
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('file_name');
|
||||||
|
$table->string('mime_type')->nullable();
|
||||||
|
$table->string('disk');
|
||||||
|
$table->string('conversions_disk')->nullable();
|
||||||
|
$table->unsignedBigInteger('size');
|
||||||
|
$table->json('manipulations');
|
||||||
|
$table->json('custom_properties');
|
||||||
|
$table->json('generated_conversions');
|
||||||
|
$table->json('responsive_images');
|
||||||
|
$table->unsignedInteger('order_column')->nullable()->index();
|
||||||
|
|
||||||
|
$table->nullableTimestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class InitialMigration extends Migration {
|
||||||
|
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('posts', function($table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('title');
|
||||||
|
$table->string('content');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,198 @@
|
||||||
|
%PDF-1.3
|
||||||
|
%âãÏÓ
|
||||||
|
|
||||||
|
1 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Catalog
|
||||||
|
/Outlines 2 0 R
|
||||||
|
/Pages 3 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
2 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Outlines
|
||||||
|
/Count 0
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
3 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Pages
|
||||||
|
/Count 2
|
||||||
|
/Kids [ 4 0 R 6 0 R ]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
4 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Page
|
||||||
|
/Parent 3 0 R
|
||||||
|
/Resources <<
|
||||||
|
/Font <<
|
||||||
|
/F1 9 0 R
|
||||||
|
>>
|
||||||
|
/ProcSet 8 0 R
|
||||||
|
>>
|
||||||
|
/MediaBox [0 0 612.0000 792.0000]
|
||||||
|
/Contents 5 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
5 0 obj
|
||||||
|
<< /Length 1074 >>
|
||||||
|
stream
|
||||||
|
2 J
|
||||||
|
BT
|
||||||
|
0 0 0 rg
|
||||||
|
/F1 0027 Tf
|
||||||
|
57.3750 722.2800 Td
|
||||||
|
( A Simple PDF File ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 688.6080 Td
|
||||||
|
( This is a small demonstration .pdf file - ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 664.7040 Td
|
||||||
|
( just for use in the Virtual Mechanics tutorials. More text. And more ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 652.7520 Td
|
||||||
|
( text. And more text. And more text. And more text. ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 628.8480 Td
|
||||||
|
( And more text. And more text. And more text. And more text. And more ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 616.8960 Td
|
||||||
|
( text. And more text. Boring, zzzzz. And more text. And more text. And ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 604.9440 Td
|
||||||
|
( more text. And more text. And more text. And more text. And more text. ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 592.9920 Td
|
||||||
|
( And more text. And more text. ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 569.0880 Td
|
||||||
|
( And more text. And more text. And more text. And more text. And more ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 557.1360 Td
|
||||||
|
( text. And more text. And more text. Even more. Continued on page 2 ...) Tj
|
||||||
|
ET
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
6 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Page
|
||||||
|
/Parent 3 0 R
|
||||||
|
/Resources <<
|
||||||
|
/Font <<
|
||||||
|
/F1 9 0 R
|
||||||
|
>>
|
||||||
|
/ProcSet 8 0 R
|
||||||
|
>>
|
||||||
|
/MediaBox [0 0 612.0000 792.0000]
|
||||||
|
/Contents 7 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
7 0 obj
|
||||||
|
<< /Length 676 >>
|
||||||
|
stream
|
||||||
|
2 J
|
||||||
|
BT
|
||||||
|
0 0 0 rg
|
||||||
|
/F1 0027 Tf
|
||||||
|
57.3750 722.2800 Td
|
||||||
|
( Simple PDF File 2 ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 688.6080 Td
|
||||||
|
( ...continued from page 1. Yet more text. And more text. And more text. ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 676.6560 Td
|
||||||
|
( And more text. And more text. And more text. And more text. And more ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 664.7040 Td
|
||||||
|
( text. Oh, how boring typing this stuff. But not as boring as watching ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 652.7520 Td
|
||||||
|
( paint dry. And more text. And more text. And more text. And more text. ) Tj
|
||||||
|
ET
|
||||||
|
BT
|
||||||
|
/F1 0010 Tf
|
||||||
|
69.2500 640.8000 Td
|
||||||
|
( Boring. More, a little more text. The end, and just as well. ) Tj
|
||||||
|
ET
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
8 0 obj
|
||||||
|
[/PDF /Text]
|
||||||
|
endobj
|
||||||
|
|
||||||
|
9 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Font
|
||||||
|
/Subtype /Type1
|
||||||
|
/Name /F1
|
||||||
|
/BaseFont /Helvetica
|
||||||
|
/Encoding /WinAnsiEncoding
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
10 0 obj
|
||||||
|
<<
|
||||||
|
/Creator (Rave \(http://www.nevrona.com/rave\))
|
||||||
|
/Producer (Nevrona Designs)
|
||||||
|
/CreationDate (D:20060301072826)
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
xref
|
||||||
|
0 11
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000019 00000 n
|
||||||
|
0000000093 00000 n
|
||||||
|
0000000147 00000 n
|
||||||
|
0000000222 00000 n
|
||||||
|
0000000390 00000 n
|
||||||
|
0000001522 00000 n
|
||||||
|
0000001690 00000 n
|
||||||
|
0000002423 00000 n
|
||||||
|
0000002456 00000 n
|
||||||
|
0000002574 00000 n
|
||||||
|
|
||||||
|
trailer
|
||||||
|
<<
|
||||||
|
/Size 11
|
||||||
|
/Root 1 0 R
|
||||||
|
/Info 10 0 R
|
||||||
|
>>
|
||||||
|
|
||||||
|
startxref
|
||||||
|
2714
|
||||||
|
%%EOF
|
Loading…
Reference in New Issue