Skip to content

Commit

Permalink
v1.0.0-alpha.4
Browse files Browse the repository at this point in the history
- `OpdsEngine` property `xml` is now `content`
    - `getXml()` is now `getContent()`
    - add setter `setContent()` and `setResponse()`
  • Loading branch information
ewilan-riviere committed Aug 31, 2023
1 parent 9551674 commit e0d7455
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 61 deletions.
40 changes: 27 additions & 13 deletions src/Engine/OpdsEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ abstract class OpdsEngine
{
protected function __construct(
protected Opds $opds,
protected array $xml = [],
protected array $content = [],
protected ?string $response = null,
) {
}
Expand Down Expand Up @@ -54,6 +54,20 @@ abstract public function addNavigationEntry(OpdsEntryNavigation $entry): array;
*/
abstract public function addBookEntry(OpdsEntryBook $entry): array;

public function setContent(array $content): self
{
$this->content = $content;

return $this;
}

public function setResponse(string $response): self
{
$this->response = $response;

return $this;
}

/**
* Get OPDS instance.
*/
Expand All @@ -63,15 +77,15 @@ public function getOpds(): Opds
}

/**
* Get XML array.
* Get content array.
*/
public function getXml(): array
public function getContent(): array
{
return $this->xml;
return $this->content;
}

/**
* Get XML response.
* Get response as XML or JSON.
*/
public function getResponse(): string
{
Expand Down Expand Up @@ -214,7 +228,7 @@ protected function handleJsonPagination(): array
/**
* Handle XML pagination.
*/
protected function handleXmlPagination(array &$xml, array &$feeds): void
protected function handleXmlPagination(array &$content, array &$feeds): void
{
$feeds = $this->opds->getFeeds();
$paginate = $this->opds->getConfig()->isUsePagination();
Expand Down Expand Up @@ -270,23 +284,23 @@ protected function handleXmlPagination(array &$xml, array &$feeds): void
]);

if ($queryStartRecord !== 0) {
$xml['__custom:link:4'] = $this->addXmlLink(href: $previousUrl, rel: 'previous', title: 'Previous page');
$content['__custom:link:4'] = $this->addXmlLink(href: $previousUrl, rel: 'previous', title: 'Previous page');
}

if ($queryStartRecord !== $last) {
$xml['__custom:link:5'] = $this->addXmlLink(href: $nextUrl, rel: 'next', title: 'Next page');
$content['__custom:link:5'] = $this->addXmlLink(href: $nextUrl, rel: 'next', title: 'Next page');
}

if ($queryStartRecord !== 0) {
$xml['__custom:link:6'] = $this->addXmlLink(href: $firstUrl, rel: 'first', title: 'First page');
$content['__custom:link:6'] = $this->addXmlLink(href: $firstUrl, rel: 'first', title: 'First page');
}

if ($queryStartRecord !== $last) {
$xml['__custom:link:7'] = $this->addXmlLink(href: $lastUrl, rel: 'last', title: 'Last page');
$content['__custom:link:7'] = $this->addXmlLink(href: $lastUrl, rel: 'last', title: 'Last page');
}

$xml['opensearch:totalResults'] = count($this->opds->getFeeds());
$xml['opensearch:itemsPerPage'] = $perPage;
$xml['opensearch:startIndex'] = $startRecord === 0 ? 1 : $start;
$content['opensearch:totalResults'] = count($this->opds->getFeeds());
$content['opensearch:itemsPerPage'] = $perPage;
$content['opensearch:startIndex'] = $startRecord === 0 ? 1 : $start;
}
}
12 changes: 6 additions & 6 deletions src/Engine/OpdsJsonEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static function make(Opds $opds): self

public function feed(): self
{
$this->xml = [
$this->content = [
'metadata' => [
'title' => $this->getFeedTitle(),
],
Expand All @@ -38,14 +38,14 @@ public function feed(): self

if ($this->opds->getConfig()->getStartUrl()) {
if (! $this->opds->getConfig()->isForceJson()) {
$this->xml['links'][] = $this->addJsonLink(
$this->content['links'][] = $this->addJsonLink(
rel: 'alternate',
href: $this->getVersionUrl(OpdsVersionEnum::v1Dot2),
title: 'OPDS 1.2',
type: 'application/atom+xml',
);
}
$this->xml['links'][] = $this->addJsonLink(
$this->content['links'][] = $this->addJsonLink(
rel: 'alternate',
href: $this->getVersionUrl(OpdsVersionEnum::v2Dot0),
title: 'OPDS 2.0',
Expand All @@ -55,15 +55,15 @@ public function feed(): self

foreach ($this->opds->getFeeds() as $feed) {
if ($feed instanceof OpdsEntryBook) {
$this->xml['publications'][] = $this->addEntry($feed);
$this->content['publications'][] = $this->addEntry($feed);

continue;
}

$this->xml['navigation'][] = $this->addEntry($feed);
$this->content['navigation'][] = $this->addEntry($feed);
}

$this->response = json_encode($this->xml);
$this->response = json_encode($this->content);

return $this;
}
Expand Down
26 changes: 13 additions & 13 deletions src/Engine/OpdsXmlEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,34 @@ public function feed(): self
$title = $this->getFeedTitle();
$updated = $this->opds->getConfig()->getUpdated();

$this->xml = [
$this->content = [
'id' => $id,
'title' => $title,
'updated' => $updated->format(DATE_ATOM),
];

if ($this->opds->getConfig()->getIconUrl()) {
$this->xml['icon'] = $this->opds->getConfig()->getIconUrl();
$this->content['icon'] = $this->opds->getConfig()->getIconUrl();
}

$this->xml['__custom:link:1'] = $this->addXmlLink(href: OpdsEngine::getCurrentUrl(), title: 'self', rel: 'self');
$this->content['__custom:link:1'] = $this->addXmlLink(href: OpdsEngine::getCurrentUrl(), title: 'self', rel: 'self');

if ($this->opds->getConfig()->getStartUrl()) {
$this->xml['__custom:link:2'] = $this->addXmlLink(href: $this->route($this->opds->getConfig()->getStartUrl()), title: 'Home', rel: 'start');
$this->content['__custom:link:2'] = $this->addXmlLink(href: $this->route($this->opds->getConfig()->getStartUrl()), title: 'Home', rel: 'start');
}

if ($this->opds->getConfig()->getSearchUrl()) {
$this->xml['__custom:link:3'] = $this->addXmlLink(href: $this->route($this->opds->getConfig()->getSearchUrl()), title: 'Search here', rel: 'search');
$this->content['__custom:link:3'] = $this->addXmlLink(href: $this->route($this->opds->getConfig()->getSearchUrl()), title: 'Search here', rel: 'search');
}

if ($this->opds->getConfig()->getStartUrl()) {
$this->xml['__custom:link:4'] = $this->addXmlLink(
$this->content['__custom:link:4'] = $this->addXmlLink(
href: $this->getVersionUrl(OpdsVersionEnum::v1Dot2),
title: 'OPDS 1.2',
rel: 'alternate',
type: 'application/atom+xml'
);
$this->xml['__custom:link:5'] = $this->addXmlLink(
$this->content['__custom:link:5'] = $this->addXmlLink(
href: $this->getVersionUrl(OpdsVersionEnum::v2Dot0),
title: 'OPDS 2.0',
rel: 'alternate',
Expand All @@ -65,18 +65,18 @@ public function feed(): self
}

if ($this->opds->getConfig()->getAuthor()) {
$this->xml['author'] = ['name' => $this->opds->getConfig()->getAuthor(), 'uri' => $this->opds->getConfig()->getAuthorUrl()];
$this->content['author'] = ['name' => $this->opds->getConfig()->getAuthor(), 'uri' => $this->opds->getConfig()->getAuthorUrl()];
}

$feeds = $this->opds->getFeeds();
$this->handleXmlPagination($this->xml, $feeds);
$this->handleXmlPagination($this->content, $feeds);

foreach ($feeds as $entry) {
$this->xml['entry'][] = $this->addEntry($entry);
$this->content['entry'][] = $this->addEntry($entry);
}

$this->response = ArrayToXml::convert(
array: $this->xml,
array: $this->content,
rootElement: [
'rootElementName' => 'feed',
'_attributes' => OpdsNamespaces::VERSION_1_2,
Expand All @@ -102,7 +102,7 @@ public function search(): self
return $this;
}

$this->xml = [
$this->content = [
'ShortName' => $this->addXmlNode($app),
'Description' => $this->addXmlNode("OPDS search engine {$app}"),
'InputEncoding' => $this->addXmlNode('UTF-8'),
Expand All @@ -123,7 +123,7 @@ public function search(): self
];

$this->response = ArrayToXml::convert(
array: $this->xml,
array: $this->content,
rootElement: [
'rootElementName' => 'OpenSearchDescription',
'_attributes' => OpdsNamespaces::VERSION_1_2_SEARCH,
Expand Down
40 changes: 40 additions & 0 deletions tests/OpdsConfigTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

use Kiwilan\Opds\OpdsConfig;

it('can use setter', function () {
$config = new OpdsConfig();

$config->setName('Gallica');
$config->setAuthor('Hadrien Gardeur');
$config->setAuthorUrl('https://example.com');
$config->setIconUrl('https://example.com/favicon.ico');
$config->setStartUrl('https://example.com/opds');
$config->setSearchUrl('https://example.com/opds/search');
$config->setSearchQuery('query');
$config->setVersionQuery('v');
$config->setUpdated(new DateTime());
$config->usePagination();
$config->setMaxItemsPerPage(10);
$config->forceJson();

expect($config->getName())->toBe('Gallica');
expect($config->getAuthor())->toBe('Hadrien Gardeur');
expect($config->getAuthorUrl())->toBe('https://example.com');
expect($config->getIconUrl())->toBe('https://example.com/favicon.ico');
expect($config->getStartUrl())->toBe('https://example.com/opds');
expect($config->getSearchUrl())->toBe('https://example.com/opds/search');
expect($config->getSearchQuery())->toBe('query');
expect($config->getVersionQuery())->toBe('v');
expect($config->getUpdated())->toBeInstanceOf(DateTime::class);
expect($config->isUsePagination())->toBeTrue();
expect($config->getMaxItemsPerPage())->toBe(10);
expect($config->isForceJson())->toBeTrue();
});

it('can use slug', function () {
$empty = null;
$slug = OpdsConfig::slug($empty);

expect($slug)->toBeNull();
});
4 changes: 2 additions & 2 deletions tests/OpdsJsonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function getConfigV2(): OpdsConfig
->get();

expect($opds)->toBeInstanceOf(Opds::class);
expect($opds->getEngine()->getXml())->toBeArray();
expect($opds->getEngine()->getContent())->toBeArray();
});

it('can use navigation feeds', function () {
Expand All @@ -57,5 +57,5 @@ function getConfigV2(): OpdsConfig
->get();

expect($opds)->toBeInstanceOf(Opds::class);
expect($opds->getEngine()->getXml())->toBeArray();
expect($opds->getEngine()->getContent())->toBeArray();
});
30 changes: 30 additions & 0 deletions tests/OpdsResponseTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

use Kiwilan\Opds\Engine\OpdsXmlEngine;
use Kiwilan\Opds\Opds;
use Kiwilan\Opds\OpdsResponse;

it('can fail on bad content', function () {
$html = '<!DOCTYPE html>';

$opds = Opds::make();
$engine = OpdsXmlEngine::make($opds);
$engine->setContent([$html]);
$engine->setResponse($html);

expect($engine->getContent())->toBe([$html]);
expect($engine->getResponse())->toBe($html);
expect(fn () => OpdsResponse::make($engine, 500))->toThrow(Exception::class);
expect(fn () => OpdsResponse::make($engine, 500))->toThrow('OPDS Response: invalid content');
});

it('can use response', function () {
$opds = Opds::make()
->get();
$response = $opds->getResponse();

expect($response->getStatus())->toBe(200);
expect($response->isJson())->toBeFalse();
expect($response->isXml())->toBeTrue();
expect($response->getContent())->toBeString();
});
70 changes: 70 additions & 0 deletions tests/OpdsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

use Kiwilan\Opds\Engine\OpdsXmlEngine;
use Kiwilan\Opds\Opds;
use Kiwilan\Opds\OpdsOutputEnum;
use Kiwilan\Opds\OpdsResponse;
use Kiwilan\Opds\OpdsVersionEnum;
use Kiwilan\XmlReader\XmlReader;

it('is string', function () {
$opds = Opds::make()
->get();

$response = $opds->getResponse();
expect($response->getContent())->toBeString();
});

it('is valid xml', function () {
$opds = Opds::make()
->get();

$response = $opds->getResponse();
expect(isValidXml($response->getContent()))->toBeTrue();
});

it('can be parsed', function () {
$opds = Opds::make()
->get();

$response = $opds->getResponse();
$xml = XmlReader::make($response->getContent())->toArray();
expect($xml)->toBeArray();
});

it('can use opds properties', function () {
$opds = Opds::make()
->title('feed');

expect($opds->getTitle())->toBe('feed');
expect($opds->getUrl())->toBe('http://localhost/');
expect($opds->getVersion())->toBe(OpdsVersionEnum::v1Dot2);
expect($opds->getFeeds())->toBeArray();
expect($opds->getEngine())->toBeInstanceOf(OpdsXmlEngine::class);
expect($opds->getOutput())->toBe(OpdsOutputEnum::xml);
expect($opds->getResponse())->toBeInstanceOf(OpdsResponse::class);
expect($opds->getUrlParts())->toBeArray();

});

it('can use output', function () {
$opds = Opds::make()
->title('feed');

expect($opds->getOutput())->toBe(OpdsOutputEnum::xml);
});

it('can use response', function () {
$opds = Opds::make()
->title('feed');

expect($opds->getResponse())->toBeInstanceOf(OpdsResponse::class);
});

it('will throw exception with unspported version', function () {
$opds = Opds::make()
->title('feed');

expect(fn () => $opds->url('http://localhost:8000/opds?version=1.0'))->toThrow(Exception::class);
expect(fn () => $opds->url('http://localhost:8000/opds?version=1.0'))->toThrow('OPDS version 1.0 is not supported.');
});
Loading

0 comments on commit e0d7455

Please sign in to comment.