2
votes

I'm using laravel 5.6 and Dusk for this specific test.

I'm trying to assert a file upload in my dropzone. But my Dropzone is created in a way that I don't have a file input element. So I can't use the attach() method.

So I tried the following

$file = new \Symfony\Component\HttpFoundation\File\UploadedFile(base_path() . '/tests/samples/Cylinder.stl', 'Cylinder.stl');

$response = $this->actingAs( $this->user )
                ->from( 'my-url' )
                ->post( route('attachments.store' ) , [
                    'file' => $file
                ]);

But the error bag is containing this error

"errors" => Illuminate\Support\ViewErrorBag {#1194             
  #bags: array:1 [                                             
    "default" => Illuminate\Support\MessageBag {#1189          
      #messages: array:1 [                                     
        "file" => array:1 [                                    
          0 => "The file failed to upload."                    
        ]                                                      
      ]                                                        
      #format: ":message"                                      
    }                                                          
  ]                                                            
}      

And of course this is working when I do it manually.

2
Can you create a minimal example on jsfiddle.net? - Jonas Staudenmeir

2 Answers

6
votes

Dropzonejs adds an input field with a specific 'dz-hidden-input' class. You can find it at the bottom of your html page, likely just before the </body> tag:

<input type="file" multiple="multiple" class="dz-hidden-input">

So you can tell Dusk to match that exact selector through the attach method:

$browser->attach('input.dz-hidden-input', storage_path('app/public/testing/test-file.jpg'));

If you have a dropzone preview showing the file name and a 'Remove file' button, you can then chain some assertions like this to make sure the file can also be removed:

$browser->attach('input.dz-hidden-input', storage_path('app/public/testing/test-file.jpg'))
 ->assertSee('test-file.jpg')
 ->assertSeeLink('Remove file')
 ->clickLink('Remove file')
 ->assertDontSee('test-file.jpg');
1
votes

As mentioned in another answer, the approach lies in the dummy input field that dropzone.js creates. However, if you have multiple, separate dropzones, this is not a viable solution, since there's no way to tell which input field is the right one to attach a file to.

The best solution lies in the hiddenInputContainer configuration value for the dropzone. Specify a value you can use to distinguish the dropzones, such as the div containing the dropzone you're configuring.

Then, you can attach a file to it (using Faker as a shortcut for generating the file):

$image = $faker->image('/tmp', 640, 480);
$browser->attach('#dropzone-image1 input.dz-hidden-input', $image);
$browser->attach('#dropzone-image2 input.dz-hidden-input', $image);