Skip to content

Commit

Permalink
Reflect changes in the search service for OC 16. (#22)
Browse files Browse the repository at this point in the history
* update tests for oc16

* param to toogle search behaviour, update sort params for oc >= 16, fix tests

* change test if lucene is disabled

* improvements

---------

Co-authored-by: ferishili <zamanifarbod2@gmail.com>
  • Loading branch information
tgloeggl and ferishili committed Jun 13, 2024
1 parent 5621e07 commit 662afa8
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 64 deletions.
5 changes: 5 additions & 0 deletions src/OpencastApi/Opencast.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class Opencast
'connect_timeout' => 0 // The API connection timeout. In seconds (default 0 to wait indefinitely) (optional)
'version' => null // The API Version. (Default null). (optional)
'handler' => null // The callable Handler or HandlerStack. (Default null). (optional)
'features' => null // A set of additional features [e.g. lucene search]. (Default null). (optional)
]
$engageConfig = [
Expand All @@ -91,6 +92,7 @@ class Opencast
'connect_timeout' => 0 // The API connection timeout. In seconds (default 0 to wait indefinitely) (optional)
'version' => null // The API Version. (Default null). (optional)
'handler' => null // The callable Handler or HandlerStack. (Default null). (optional)
'features' => null // A set of additional features [e.g. lucene search]. (Default null). (optional)
]
*/
/**
Expand Down Expand Up @@ -171,6 +173,9 @@ private function setEngageRestClient($config, $engageConfig)
if (!isset($engageConfig['handler']) && isset($config['handler'])) {
$engageConfig['handler'] = $config['handler'];
}
if (!isset($engageConfig['features']) && isset($config['features'])) {
$engageConfig['features'] = $config['features'];
}
$this->engageRestClient = new OcRestClient($engageConfig);
}

Expand Down
22 changes: 20 additions & 2 deletions src/OpencastApi/Rest/OcRestClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ class OcRestClient extends Client
private $additionalHeaders = [];
private $noHeader = false;
private $origin;
private $features = [];
/*
$config = [
'url' => 'https://develop.opencast.org/', // The API url of the opencast instance (required)
'username' => 'admin', // The API username. (required)
'password' => 'opencast', // The API password. (required)
'timeout' => 0, // The API timeout. In seconds (default 0 to wait indefinitely). (optional)
'connect_timeout' => 0, // The API connection timeout. In seconds (default 0 to wait indefinitely) (optional)
'version' => null // The API Version. (Default null). (optional)
'handler' => null // The callable Handler or HandlerStack. (Default null). (optional)
'version' => null, // The API Version. (Default null). (optional)
'handler' => null, // The callable Handler or HandlerStack. (Default null). (optional)
'features' => null // A set of additional features [e.g. lucene search]. (Default null). (optional)
]
*/
public function __construct($config)
Expand All @@ -51,9 +53,25 @@ public function __construct($config)
if (isset($config['handler']) && is_callable($config['handler'])) {
$parentConstructorConfig['handler'] = $config['handler'];
}

if (isset($config['features'])) {
$this->features = $config['features'];
}

parent::__construct($parentConstructorConfig);
}

public function readFeatures($key = null) {
if (empty($key)) {
return $this->features;
}

if (isset($this->features[$key])) {
return $this->features[$key];
}
return false;
}

public function registerHeaderException($header, $path) {
$path = ltrim($path, '/');
if (!isset($this->headerExceptions[$header]) || !in_array($path, $this->headerExceptions[$header])) {
Expand Down
144 changes: 102 additions & 42 deletions src/OpencastApi/Rest/OcSearch.php
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
<?php
<?php
namespace OpencastApi\Rest;

class OcSearch extends OcRest
{
const URI = '/search';
public $lucene = false; // By default false, main support for OC 16.

public function __construct($restClient)
{
$restClient->registerHeaderException('Accept', self::URI);
parent::__construct($restClient);
if ($restClient->readFeatures('lucene')) {
$this->lucene = true;
}
}


/**
* Search for episodes matching the query parameters as object (JSON) by default or XML (text) on demand.
*
* @param array $params the params to pass to the call: it must cointain the following:
*
* @param array $params the params to pass to the call: it must cointain the following:
* $params = [
* 'id' => '{The ID of the single episode to be returned, if it exists}',
* 'q' => '{Any episode that matches this free-text query.}',
Expand All @@ -28,7 +32,7 @@ public function __construct($restClient)
* 'sign' => '{If results are to be signed (Default value=true)}',
* ]
* @param string $format The output format (json or xml) of the response body. (Default value = 'json')
*
*
* @return array the response result ['code' => 200, 'body' => '{The search results, formatted as xml or json}']
*/
public function getEpisodes($params = [], $format = '')
Expand Down Expand Up @@ -64,30 +68,58 @@ public function getEpisodes($params = [], $format = '')
$query['sign'] = $params['sign'];
}

$sortsASC = [
'DATE_CREATED', 'DATE_MODIFIED', 'TITLE', 'SERIES_ID',
'MEDIA_PACKAGE_ID', 'CREATOR', 'CONTRIBUTOR', 'LANGUAGE',
'LICENSE','SUBJECT','DESCRIPTION','PUBLISHER',
];
$sortsDESC = array_map(function ($sort) {
return "{$sort}_DESC";
}, $sortsASC);

$sorts = array_merge($sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array($params['sort'], $sorts)) {
$query['sort'] = $params['sort'];
// OC <= 15
if ($this->lucene) {
$sortsASC = [
'DATE_CREATED', 'DATE_MODIFIED', 'TITLE', 'SERIES_ID',
'MEDIA_PACKAGE_ID', 'CREATOR', 'CONTRIBUTOR', 'LANGUAGE',
'LICENSE','SUBJECT','DESCRIPTION','PUBLISHER',
];
$sortsDESC = array_map(function ($sort) {
return "{$sort}_DESC";
}, $sortsASC);

$sorts = array_merge($sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array($params['sort'], $sorts)) {
$query['sort'] = $params['sort'];
}

// OC >= 16
} else {
$sorts = [
'modified', 'title', 'creator', 'contributor'
];

$sortsASC = array_map(function ($sort) {
return "{$sort} asc";
}, $sorts);

$sortsDESC = array_map(function ($sort) {
return "{$sort} desc";
}, $sorts);

$sorts_list = array_merge($sorts, $sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array(strtolower($params['sort']), $sorts_list)) {
$query['sort'] = strtolower($params['sort']);
}
}

$options = $this->restClient->getQueryParams($query);
return $this->restClient->performGet($uri, $options);
}


/**
* Search a lucene query as object (JSON) by default or XML (text) on demand.
*
* @param array $params the params to pass to the call: it must cointain the following:
*
* INFO: This endpoint is removed in Opencast 16.
*
* @param array $params the params to pass to the call: it must cointain the following:
* $params = [
* 'q' => '{ The lucene query. }',
* 'series' => '{ Include series in the search result. (Default value=false)}',
Expand All @@ -98,11 +130,15 @@ public function getEpisodes($params = [], $format = '')
* 'sign' => '{If results are to be signed (Default value=true)}',
* ]
* @param string $format The output format (json or xml) of the response body. (Default value = 'json')
*
*
* @return array the response result ['code' => 200, 'body' => '{The search results, formatted as xml or json}']
*/
public function getLucene($params = [], $format = '')
{
if (!$this->lucene) {
return ['code' => 410, 'reason' => 'Lucene search endpoint is not available!'];
}

$uri = self::URI . "/lucene.json";
if (!empty($format) && strtolower($format) == 'xml') {
$uri = str_replace('json', 'xml', $uri);
Expand Down Expand Up @@ -138,20 +174,20 @@ public function getLucene($params = [], $format = '')
}, $sortsASC);

$sorts = array_merge($sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array($params['sort'], $sorts)) {
$query['sort'] = $params['sort'];
}

$options = $this->restClient->getQueryParams($query);
return $this->restClient->performGet($uri, $options);
}

/**
* Search for series matching the query parameters and returns JSON (object) by default or XML (text) on demand
*
* @param array $params the params to pass to the call: it must cointain the following:
*
* @param array $params the params to pass to the call: it must cointain the following:
* $params = [
* 'id' = '{The series ID. If the additional boolean parameter "episodes" is "true", the result set will include this series episodes.}'
* 'q' => '{Any series that matches this free-text query. If the additional boolean parameter "episodes" is "true", the result set will include this series episodes.}',
Expand All @@ -163,7 +199,7 @@ public function getLucene($params = [], $format = '')
* 'sign' => '{If results are to be signed (Default value=true)}',
* ]
* @param string $format The output format (json or xml) of the response body. (Default value = 'json')
*
*
* @return array the response result ['code' => 200, 'body' => '{The search results, formatted as xml or json}']
*/
public function getSeries($params = [], $format = '')
Expand Down Expand Up @@ -196,24 +232,48 @@ public function getSeries($params = [], $format = '')
$query['sign'] = $params['sign'];
}

$sortsASC = [
'DATE_CREATED', 'DATE_MODIFIED', 'TITLE', 'SERIES_ID',
'MEDIA_PACKAGE_ID', 'CREATOR', 'CONTRIBUTOR', 'LANGUAGE',
'LICENSE','SUBJECT','DESCRIPTION','PUBLISHER',
];
$sortsDESC = array_map(function ($sort) {
return "{$sort}_DESC";
}, $sortsASC);
// OC <= 15
if ($this->lucene) {
$sortsASC = [
'DATE_CREATED', 'DATE_MODIFIED', 'TITLE', 'SERIES_ID',
'MEDIA_PACKAGE_ID', 'CREATOR', 'CONTRIBUTOR', 'LANGUAGE',
'LICENSE','SUBJECT','DESCRIPTION','PUBLISHER',
];
$sortsDESC = array_map(function ($sort) {
return "{$sort}_DESC";
}, $sortsASC);

$sorts = array_merge($sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array($params['sort'], $sorts)) {
$query['sort'] = $params['sort'];
$sorts = array_merge($sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array($params['sort'], $sorts)) {
$query['sort'] = $params['sort'];
}

// OC >= 16
} else {
$sorts = [
'modified', 'title', 'creator', 'contributor'
];

$sortsASC = array_map(function ($sort) {
return "{$sort} asc";
}, $sorts);

$sortsDESC = array_map(function ($sort) {
return "{$sort} desc";
}, $sorts);

$sorts_list = array_merge($sorts, $sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array(strtolower($params['sort']), $sorts_list)) {
$query['sort'] = strtolower($params['sort']);
}
}

$options = $this->restClient->getQueryParams($query);
return $this->restClient->performGet($uri, $options);
}
}
?>
?>
12 changes: 4 additions & 8 deletions tests/DataProvider/SearchDataProvider.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
<?php
<?php
namespace Tests\DataProvider;

class SearchDataProvider {

public static function getEpisodeQueryCases(): array
{
return [
[[], 'json'],
[[], 'xml'],
[[], 'XML'],
[['id' => 'fe0b45b0-7ed5-4944-8b0a-a0a283331791'], ''],
[['sid' => '8010876e-1dce-4d38-ab8d-24b956e3d8b7'], ''],
[['sname' => 'HUB_LOCAL_TEST'], ''],
[['sort' => 'DATE_CREATED_DESC'], ''],
[['sort' => 'modified asc'], ''],
[['offset' => 1], ''],
[['limit' => 1], ''],
[['admin' => true], ''],
Expand All @@ -39,11 +37,9 @@ public static function getSeriesQueryCases(): array
{
return [
[[], 'json'],
[[], 'xml'],
[[], 'XML'],
[['id' => '8010876e-1dce-4d38-ab8d-24b956e3d8b7'], ''],
[['episodes' => true], ''],
[['sort' => 'DATE_CREATED_DESC'], ''],
[['sort' => 'modified desc'], ''],
[['offset' => 1], ''],
[['limit' => 1], ''],
[['admin' => true], ''],
Expand Down
7 changes: 5 additions & 2 deletions tests/DataProvider/SetupDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ public static function getConfig($version = ''): array
'username' => $username,
'password' => $password,
'timeout' => $timeout,
'version' => '1.9.0',
'connect_timeout' => $connectTimeout
'version' => '1.11.0',
'connect_timeout' => $connectTimeout,
'features' => [
'lucene' => false
]
];
if (!empty($version)) {
$config['version'] = $version;
Expand Down
16 changes: 8 additions & 8 deletions tests/Unit/OcSearchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,22 @@ public function get_eposides($params, $format): void

/**
* @test
* @dataProvider \Tests\DataProvider\SearchDataProvider::getLuceneQueryCases()
* @dataProvider \Tests\DataProvider\SearchDataProvider::getSeriesQueryCases()
*/
public function get_lucenes($params, $format): void
public function get_series($params, $format): void
{
$response = $this->ocSearch->getLucene($params, $format);
$this->assertSame(200, $response['code'], 'Failure to search lucene');
$response = $this->ocSearch->getSeries($params, $format);
$this->assertSame(200, $response['code'], 'Failure to search series');
}

/**
* @test
* @dataProvider \Tests\DataProvider\SearchDataProvider::getSeriesQueryCases()
* @dataProvider \Tests\DataProvider\SearchDataProvider::getLuceneQueryCases()
*/
public function get_series($params, $format): void
public function get_lucenes($params, $format): void
{
$response = $this->ocSearch->getSeries($params, $format);
$this->assertSame(200, $response['code'], 'Failure to search series');
$response = $this->ocSearch->getLucene($params, $format);
$this->assertContains($response['code'], [200, 410], 'Failure to create an event');
}
}
?>
4 changes: 2 additions & 2 deletions tests/UnitMock/OcSearchTestMock.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ public function get_eposides(): void
* @test
*/
public function get_lucenes(): void
{
{
$params = ['series' => true];
$response = $this->ocSearch->getLucene($params);
$this->assertSame(200, $response['code'], 'Failure to search lucene');
$this->assertContains($response['code'], [200, 410], 'Failure to create an event');
}

/**
Expand Down

0 comments on commit 662afa8

Please sign in to comment.