Skip to content

Commit

Permalink
feat: add optional ClientInterface parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
phanan committed May 31, 2024
1 parent 9c0e629 commit 8dd1f10
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 9 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,22 @@ composer require phanan/poddle

## Usage

To parse a podcast feed, call the `fromUrl` method with the feed URL:
### Parse from a URL

To parse a podcast feed from its URL, call the `fromUrl` method with the feed URL:

```php
$poddle = \PhanAn\Poddle::fromUrl('https://example.com/feed.xml');
```

It is possible to configure the timeout value for the request by passing an integer as the second parameter for `Poddle::fromUrl`.
This method also accepts two additional parameters:

* `timeoutInSeconds`: The number of seconds to wait while trying to connect. Defaults to 30. Note that the `max_execution_time` value in your PHP configuration may still limit the maximum timeout value.
* `client`: A PSR-7-compliant client to make the request. If not provided, Poddle will use a default client. This parameter may come in handy during testing or if you need to heavily customize the request.

### Parse from XML

For total control, you can make the request yourself (for example using an HTTP client) and pass the response body to `Poddle::fromXml` instead:
If you already have the XML string, you can parse it using `Poddle::fromXml` instead:

```php
use Illuminate\Support\Facades\Http;
Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@
"illuminate/collections": "^10.48",
"illuminate/http": "^10.48",
"illuminate/support": "^10.48",
"guzzlehttp/guzzle": "^7.8"
"guzzlehttp/guzzle": "^7.8",
"psr/http-client": "^1.0"
},
"require-dev": {
"phpunit/phpunit": ">=10.5",
"laravel/pint": "^1.15",
"larastan/larastan": "^2.9",
"orchestra/testbench": "*",
"laravel/tinker": "^2.9"
"laravel/tinker": "^2.9",
"mockery/mockery": "^1.6"
},
"scripts": {
"test": "phpunit tests",
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions src/Poddle.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace PhanAn\Poddle;

use Generator;
use GuzzleHttp\Psr7\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use PhanAn\Poddle\Enums\PodcastType;
Expand All @@ -13,6 +14,7 @@
use PhanAn\Poddle\Values\EpisodeCollection;
use PhanAn\Poddle\Values\FundingCollection;
use PhanAn\Poddle\Values\TxtCollection;
use Psr\Http\Client\ClientInterface;
use Saloon\XmlWrangler\Exceptions\QueryAlreadyReadException;
use Saloon\XmlWrangler\Exceptions\XmlReaderException;
use Saloon\XmlWrangler\XmlReader;
Expand All @@ -28,9 +30,13 @@ public function __construct(public readonly string $xml)
$this->xmlReader = XmlReader::fromString($xml);
}

public static function fromUrl(string $url, int $timeoutInSeconds = 30): self
public static function fromUrl(string $url, int $timeoutInSeconds = 30, ClientInterface $client = null): self
{
return new self(Http::timeout($timeoutInSeconds)->get($url)->body());
$xml = $client
? $client->sendRequest(new Request('GET', $url, ['connect_timeout' => $timeoutInSeconds]))->getBody()
: Http::timeout($timeoutInSeconds)->get($url)->body();

return new self((string) $xml);
}

public static function fromXml(string $xml): self
Expand Down
36 changes: 35 additions & 1 deletion tests/PoddleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@

namespace Tests;

use GuzzleHttp\Psr7\Stream;
use GuzzleHttp\Psr7\Utils;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\LazyCollection;
use Mockery;
use PhanAn\Poddle\Poddle;
use PhanAn\Poddle\Values\Channel;
use PhanAn\Poddle\Values\Episode;
use PhanAn\Poddle\Values\EpisodeCollection;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

class PoddleTest extends TestCase
{
Expand Down Expand Up @@ -35,6 +41,34 @@ public function testParseUrl(): void
self::assertEpisodes($parser->getEpisodes());
}

public function testParseUrlUsingClientInterface(): void
{
$clientMock = Mockery::mock(ClientInterface::class);

$responseMock = Mockery::mock(ResponseInterface::class, [
'getBody' => Utils::streamFor(file_get_contents(__DIR__ . '/fixtures/sample.xml')),
]);

$clientMock->shouldReceive('sendRequest')->with(
Mockery::on(static function (RequestInterface $request): bool {
self::assertSame('GET', $request->getMethod());
self::assertSame('https://mypodcast.com/feed', (string) $request->getUri());
self::assertSame('45', $request->getHeader('connect_timeout')[0]);

return true;
})
)->andReturn($responseMock);

$parser = Poddle::fromUrl(
url: 'https://mypodcast.com/feed',
timeoutInSeconds: 45,
client: $clientMock
);

self::assertChannel($parser->getChannel());
self::assertEpisodes($parser->getEpisodes());
}

private static function assertChannel(Channel $channel): void
{
self::assertEquals([
Expand Down Expand Up @@ -85,7 +119,7 @@ private static function assertChannel(Channel $channel): void
], $channel->toArray());
}

public function assertEpisodes(EpisodeCollection $episodes): void
private function assertEpisodes(EpisodeCollection $episodes): void
{
self::assertInstanceOf(LazyCollection::class, $episodes);
self::assertSame(8, $episodes->count());
Expand Down

0 comments on commit 8dd1f10

Please sign in to comment.