0

I'm having trouble getting a unit test working for file upload, and storing the file using Spatie's medialibrary.

The code works fine in the browser: the file saves correctly.

However, this unit test fails:

        Storage::fake('resource-files');
        $file = UploadedFile::fake()->create('courtform.pdf', 1024);

        $response = $this->ActingAs($this->adminUser())
                        ->json('PATCH', '/forms/' . $dbentry->id, [
            'name' => 'Form 800',
            'state' => 'VT',
            'description' => 'General info form',
            'file' => $file,
        ]);

        // Assert the file was stored...
        Storage::disk('resource-files')->assertExists('1/courtform.pdf');

It fails because the mime type is empty:

Spatie\MediaLibrary\Exceptions\FileCannotBeAdded\FileUnacceptableForCollection^ {#1485
  #message: "The file with properties `name: courtform.pdf, size: 0, mime: inode/x-empty` was not accepted into the collection named `source-pdfs` of model `App\Form` with id `1`"

... and I have required that the files in this collection be PDFs:

    public function registerMediaCollections()
    {
      // Keep only one file per model
      $this
            ->addMediaCollection('source-pdfs')
            ->useDisk('resource-files')
            ->singleFile()
            ->acceptsFile(function (File $file) {
            return $file->mimeType === 'application/pdf';
          });

      $this
            ->addMediaCollection('source-fdfs')
            ->singleFile();

    }

But this empty mimeType is only an issue with the unit test — it's not a problem in the browser.

Does anyone know why the file properties might be size: 0, mime: inode/x-empty when evaluated by registerMediaCollections()?

Thank you!

apokryfos
  • 38,771
  • 9
  • 70
  • 114
Erik
  • 1
  • 1

1 Answers1

1

I'm answering a bit late, but here is a solution in case you're still struggling with PDF file uploading and saving testing with the spatie/laravel-medialibray package.

Just create your fake uploaded file like this :

$fakePdfContent = <<<PDF
%PDF-1.4
1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj
3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj
xref
0 4
0000000000 65535 f
0000000009 00000 n
0000000052 00000 n
0000000101 00000 n
trailer<</Size 4/Root 1 0 R>>
startxref
178
%%EOF
PDF;
$fakePdf = UploadedFile::fake()
    ->createWithContent('fake.pdf', $fakePdfContent)
    ->mimeType('application/pdf')
    ->size(10240);

As the content put is the fake PDF file is a real empty PDF file content, the mimetype is correctly guessed by the spatie/laravel-medialibrary package and will be created without any exception throw.

Hope it'll help !

Okipa
  • 551
  • 4
  • 18
  • How do you exactly populate the `$fakePdfContent` ? you have not wrapped it. – xperator Oct 21 '21 at 17:58
  • Well, just pass $fakePdfContent to spatie/medialibrary like this: $model->addMedia($fakePdfContent)->toMediaCollection('your_collection'). – Okipa Nov 01 '21 at 10:16