Skip to content

Commit

Permalink
Adds the HttpFacadeDownloader (#3505)
Browse files Browse the repository at this point in the history
* Adds the HttpFacadeDownloader

* Added documentation
  • Loading branch information
peterfox authored Jan 22, 2024
1 parent 69c9afc commit 7db2555
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
45 changes: 45 additions & 0 deletions docs/advanced-usage/using-a-custom-media-downloader.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,48 @@ class CustomDownloader implements Downloader {

}
```

## Using the Laravel Downloader

You may configure the medialibrary config to use a downloader compatible more
with Laravel that makes use of the built-in HTTP client. This is the quickest way
to mock any requests made to external URLs.

```php
// config/media-library.php

/*
* When using the addMediaFromUrl method you may want to replace the default downloader.
* This is particularly useful when the url of the image is behind a firewall and
* need to add additional flags, possibly using curl.
*/
'media_downloader' => Spatie\MediaLibrary\Downloaders\HttpFacadeDownloader::class,
```

This then makes it easier in tests to mock the download of files.

```php
$url = 'http://medialibrary.spatie.be/assets/images/mountain.jpg';
$yourModel
->addMediaFromUrl($url)
->toMediaCollection();
```

with a test like this:

```php
Http::fake([
// Stub a response where the body will be the contents of the file
'http://medialibrary.spatie.be/assets/images/mountain.jpg' => Http::response('::file::'),
]);

// Execute code for the test

// Then check that a request for the file was made
Http::assertSent(function (Request $request) {
return $request->url() == 'http://medialibrary.spatie.be/assets/images/mountain.jpg';
});

// We may also assert that the contents of any files created
// will contain `::file::`
```
21 changes: 21 additions & 0 deletions src/Downloaders/HttpFacadeDownloader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Spatie\MediaLibrary\Downloaders;

use Illuminate\Support\Facades\Http;
use Spatie\MediaLibrary\MediaCollections\Exceptions\UnreachableUrl;

class HttpFacadeDownloader implements Downloader
{
public function getTempFile(string $url): string
{
$temporaryFile = tempnam(sys_get_temp_dir(), 'media-library');

Http::withUserAgent('Spatie MediaLibrary')
->throw(fn () => throw new UnreachableUrl($url))
->sink($temporaryFile)
->get($url);

return $temporaryFile;
}
}
55 changes: 55 additions & 0 deletions tests/Downloader/HttpFacadeDownloaderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;

it('can save a url to a temp location', function () {
$url = 'https://example.com';

\Illuminate\Support\Facades\Http::shouldReceive('withUserAgent')
->with('Spatie MediaLibrary')
->once()
->andReturnSelf()
->getMock()
->shouldReceive('throw')
->once()
->andReturnSelf()
->getMock()
->shouldReceive('sink')
->once()
->andReturnSelf()
->getMock()
->shouldReceive('get')
->with($url)
->once();

$downloader = new \Spatie\MediaLibrary\Downloaders\HttpFacadeDownloader();

$result = $downloader->getTempFile($url);

expect($result)->toBeString();
});

it('can be mocked easily for tests', function () {
$url = 'https://example.com';

Http::fake([
// Stub a JSON response for GitHub endpoints...
'https://example.com' => Http::response('::file::'),
]);

$downloader = new \Spatie\MediaLibrary\Downloaders\HttpFacadeDownloader();

$result = $downloader->getTempFile($url);

expect($result)
->toBeString()
->and($result)
->toBeFile()
->and(\Illuminate\Support\Facades\File::get($result))
->toBe('::file::');

Http::assertSent(function (Request $request) {
return $request->url() == 'https://example.com';
});
});

0 comments on commit 7db2555

Please sign in to comment.