init commit
This commit is contained in:
38
tests/Bootstrap.php
Normal file
38
tests/Bootstrap.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2023 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
define('XIBO', true);
|
||||
define('PROJECT_ROOT', realpath(__DIR__ . '/..'));
|
||||
|
||||
require_once PROJECT_ROOT . '/vendor/autoload.php';
|
||||
require_once PROJECT_ROOT . '/tests/LocalWebTestCase.php';
|
||||
require_once PROJECT_ROOT . '/tests/XmdsTestCase.php';
|
||||
|
||||
if (!file_exists(PROJECT_ROOT . '/web/settings.php'))
|
||||
die('Not configured');
|
||||
|
||||
\Xibo\Tests\LocalWebTestCase::setEnvironment();
|
||||
|
||||
\Xibo\Helper\Translate::InitLocale(null, 'en_GB');
|
||||
148
tests/Helper/DisplayHelperTrait.php
Normal file
148
tests/Helper/DisplayHelperTrait.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/*
|
||||
* Spring Signage Ltd - http://www.springsignage.com
|
||||
* Copyright (C) 2017 Spring Signage Ltd
|
||||
* (DisplayHelperTrait.php)
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\Helper;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Exception\XiboApiException;
|
||||
|
||||
/**
|
||||
* Trait DisplayHelperTrait
|
||||
* @package Helper
|
||||
*/
|
||||
trait DisplayHelperTrait
|
||||
{
|
||||
/**
|
||||
* @param int $status
|
||||
* @param string $type
|
||||
* @return XiboDisplay
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function createDisplay($status = null, $type = 'windows')
|
||||
{
|
||||
// Generate names for display and xmr channel
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$xmrChannel = Random::generateString(50);
|
||||
|
||||
$this->getLogger()->debug('Creating Display called ' . $hardwareId);
|
||||
|
||||
// This is a dummy pubKey and isn't used by anything important
|
||||
$xmrPubkey = '-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDmdnXL4gGg3yJfmqVkU1xsGSQI
|
||||
3b6YaeAKtWuuknIF1XAHAHtl3vNhQN+SmqcNPOydhK38OOfrdb09gX7OxyDh4+JZ
|
||||
inxW8YFkqU0zTqWaD+WcOM68wTQ9FCOEqIrbwWxLQzdjSS1euizKy+2GcFXRKoGM
|
||||
pbBhRgkIdydXoZZdjQIDAQAB
|
||||
-----END PUBLIC KEY-----';
|
||||
|
||||
// Register our display
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId,
|
||||
$hardwareId,
|
||||
$type,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
'00:16:D9:C9:AL:69',
|
||||
$xmrChannel,
|
||||
$xmrPubkey
|
||||
);
|
||||
|
||||
// Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get(['hardwareKey' => $hardwareId]);
|
||||
|
||||
if (count($displays) != 1)
|
||||
$this->fail('Display was not added correctly');
|
||||
|
||||
/** @var XiboDisplay $display */
|
||||
$display = $displays[0];
|
||||
|
||||
// Set the initial status
|
||||
if ($status !== null)
|
||||
$this->displaySetStatus($display, $status);
|
||||
|
||||
return $display;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboDisplay $display
|
||||
* @param int $status
|
||||
*/
|
||||
protected function displaySetStatus($display, $status)
|
||||
{
|
||||
$display->mediaInventoryStatus = $status;
|
||||
|
||||
$this->getStore()->update('UPDATE `display` SET MediaInventoryStatus = :status, auditingUntil = :auditingUntil WHERE displayId = :displayId', [
|
||||
'displayId' => $display->displayId,
|
||||
'auditingUntil' => Carbon::now()->addSeconds(86400)->format('U'),
|
||||
'status' => $status
|
||||
]);
|
||||
$this->getStore()->commitIfNecessary();
|
||||
$this->getStore()->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboDisplay $display
|
||||
*/
|
||||
protected function displaySetLicensed($display)
|
||||
{
|
||||
$display->licensed = 1;
|
||||
|
||||
$this->getStore()->update('UPDATE `display` SET licensed = 1, auditingUntil = :auditingUntil WHERE displayId = :displayId', [
|
||||
'displayId' => $display->displayId,
|
||||
'auditingUntil' => Carbon::now()->addSeconds(86400)->format('U')
|
||||
]);
|
||||
$this->getStore()->commitIfNecessary();
|
||||
$this->getStore()->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboDisplay $display
|
||||
* @param string $timeZone
|
||||
*/
|
||||
protected function displaySetTimezone($display, $timeZone)
|
||||
{
|
||||
$this->getStore()->update('UPDATE `display` SET timeZone = :timeZone WHERE displayId = :displayId', [
|
||||
'displayId' => $display->displayId,
|
||||
'timeZone' => $timeZone
|
||||
]);
|
||||
$this->getStore()->commitIfNecessary();
|
||||
$this->getStore()->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboDisplay $display
|
||||
*/
|
||||
protected function deleteDisplay($display)
|
||||
{
|
||||
$display->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboDisplay $display
|
||||
* @param int $status
|
||||
* @return bool
|
||||
*/
|
||||
protected function displayStatusEquals($display, $status)
|
||||
{
|
||||
// Requery the Display
|
||||
try {
|
||||
$check = (new XiboDisplay($this->getEntityProvider()))->getById($display->displayId);
|
||||
|
||||
$this->getLogger()->debug('Tested Display ' . $display->display . '. Status returned is ' . $check->mediaInventoryStatus);
|
||||
|
||||
return $check->mediaInventoryStatus === $status;
|
||||
|
||||
} catch (XiboApiException $xiboApiException) {
|
||||
$this->getLogger()->error('API exception for ' . $display->displayId. ': ' . $xiboApiException->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
287
tests/Helper/LayoutHelperTrait.php
Normal file
287
tests/Helper/LayoutHelperTrait.php
Normal file
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2022 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\Helper;
|
||||
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboResolution;
|
||||
use Xibo\OAuth2\Client\Entity\XiboWidget;
|
||||
use Xibo\OAuth2\Client\Exception\XiboApiException;
|
||||
|
||||
/**
|
||||
* Trait LayoutHelperTrait
|
||||
* @package Helper
|
||||
*/
|
||||
trait LayoutHelperTrait
|
||||
{
|
||||
/**
|
||||
* @param int|null $status
|
||||
* @return XiboLayout
|
||||
*/
|
||||
protected function createLayout($status = null)
|
||||
{
|
||||
// Create a Layout for us to work with.
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))
|
||||
->create(
|
||||
Random::generateString(),
|
||||
'PHPUnit Created Layout for Automated Integration Testing',
|
||||
'',
|
||||
$this->getResolutionId('landscape')
|
||||
);
|
||||
|
||||
$this->getLogger()->debug('Layout created with name ' . $layout->layout);
|
||||
|
||||
if ($status !== null) {
|
||||
// Set the initial status of this Layout to Built
|
||||
$this->setLayoutStatus($layout, $status);
|
||||
}
|
||||
|
||||
return $layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboLayout $layout
|
||||
* @param int $status
|
||||
* @return $this
|
||||
*/
|
||||
protected function setLayoutStatus($layout, $status)
|
||||
{
|
||||
$layout->status = $status;
|
||||
$this->getStore()->update('UPDATE `layout` SET `status` = :status WHERE layoutId = :layoutId', ['layoutId' => $layout->layoutId, 'status' => $status]);
|
||||
$this->getStore()->commitIfNecessary();
|
||||
$this->getStore()->close();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the Layout ready for XMDS
|
||||
* @param XiboLayout $layout
|
||||
* @return $this
|
||||
*/
|
||||
protected function buildLayout($layout)
|
||||
{
|
||||
// Call the status route
|
||||
$this->getEntityProvider()->get('/layout/status/' . $layout->layoutId);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboLayout $layout
|
||||
*/
|
||||
protected function deleteLayout($layout)
|
||||
{
|
||||
$layout->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboLayout $layout
|
||||
* @param int $status
|
||||
* @return bool
|
||||
*/
|
||||
protected function layoutStatusEquals($layout, $status)
|
||||
{
|
||||
// Requery the Display
|
||||
try {
|
||||
$check = (new XiboLayout($this->getEntityProvider()))->getById($layout->layoutId);
|
||||
|
||||
$this->getLogger()->debug('Tested Layout ' . $layout->layout . '. Status returned is ' . $check->status);
|
||||
|
||||
return $check->status === $status;
|
||||
|
||||
} catch (XiboApiException $xiboApiException) {
|
||||
$this->getLogger()->error('API exception for ' . $layout->layoutId . ': ' . $xiboApiException->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @return int
|
||||
*/
|
||||
protected function getResolutionId($type)
|
||||
{
|
||||
if ($type === 'landscape') {
|
||||
$width = 1920;
|
||||
$height = 1080;
|
||||
} else if ($type === 'portrait') {
|
||||
$width = 1080;
|
||||
$height = 1920;
|
||||
} else {
|
||||
return -10;
|
||||
}
|
||||
|
||||
//$this->getLogger()->debug('Querying for ' . $width . ', ' . $height);
|
||||
|
||||
$resolutions = (new XiboResolution($this->getEntityProvider()))->get(['width' => $width, 'height' => $height]);
|
||||
|
||||
if (count($resolutions) <= 0)
|
||||
return -10;
|
||||
|
||||
return $resolutions[0]->resolutionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboLayout $layout
|
||||
* @return XiboLayout
|
||||
*/
|
||||
protected function checkout($layout)
|
||||
{
|
||||
$this->getLogger()->debug('Checkout ' . $layout->layoutId);
|
||||
|
||||
$response = $this->getEntityProvider()->put('/layout/checkout/' . $layout->layoutId);
|
||||
|
||||
// Swap the Layout object to use the one returned.
|
||||
/** @var XiboLayout $layout */
|
||||
$layout = $this->constructLayoutFromResponse($response);
|
||||
|
||||
$this->getLogger()->debug('LayoutId is now: ' . $layout->layoutId);
|
||||
|
||||
return $layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboLayout $layout
|
||||
* @return XiboLayout
|
||||
*/
|
||||
protected function publish($layout)
|
||||
{
|
||||
$this->getLogger()->debug('Publish ' . $layout->layoutId);
|
||||
|
||||
$response = $this->getEntityProvider()->put('/layout/publish/' . $layout->layoutId , [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
// Swap the Layout object to use the one returned.
|
||||
/** @var XiboLayout $layout */
|
||||
$layout = $this->constructLayoutFromResponse($response);
|
||||
|
||||
$this->getLogger()->debug('LayoutId is now: ' . $layout->layoutId);
|
||||
|
||||
return $layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XiboLayout $layout
|
||||
* @return XiboLayout
|
||||
*/
|
||||
protected function discard($layout)
|
||||
{
|
||||
$this->getLogger()->debug('Discard ' . $layout->layoutId);
|
||||
|
||||
$response = $this->getEntityProvider()->put('/layout/discard/' . $layout->layoutId);
|
||||
|
||||
// Swap the Layout object to use the one returned.
|
||||
/** @var XiboLayout $layout */
|
||||
$layout = $this->constructLayoutFromResponse($response);
|
||||
|
||||
$this->getLogger()->debug('LayoutId is now: ' . $layout->layoutId);
|
||||
|
||||
return $layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $layout
|
||||
* @return $this
|
||||
*/
|
||||
protected function addSimpleWidget($layout)
|
||||
{
|
||||
$this->getEntityProvider()->post('/playlist/widget/clock/' . $layout->regions[0]->regionPlaylist->playlistId, [
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $layout
|
||||
* @return $this
|
||||
*/
|
||||
protected function addSimpleTextWidget($layout)
|
||||
{
|
||||
$this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId, [
|
||||
'text' => 'PHPUNIT TEST TEXT',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $response
|
||||
* @return \Xibo\OAuth2\Client\Entity\XiboEntity|XiboLayout
|
||||
*/
|
||||
private function constructLayoutFromResponse($response)
|
||||
{
|
||||
$hydratedRegions = [];
|
||||
$hydratedWidgets = [];
|
||||
/** @var XiboLayout $layout */
|
||||
$layout = new XiboLayout($this->getEntityProvider());
|
||||
$layout = $layout->hydrate($response);
|
||||
|
||||
$this->getLogger()->debug('Constructing Layout from Response: ' . $layout->layoutId);
|
||||
|
||||
if (isset($response['regions'])) {
|
||||
foreach ($response['regions'] as $item) {
|
||||
/** @var XiboRegion $region */
|
||||
$region = new XiboRegion($this->getEntityProvider());
|
||||
$region->hydrate($item);
|
||||
/** @var XiboPlaylist $playlist */
|
||||
$playlist = new XiboPlaylist($this->getEntityProvider());
|
||||
$playlist->hydrate($item['regionPlaylist']);
|
||||
foreach ($playlist->widgets as $widget) {
|
||||
/** @var XiboWidget $widgetObject */
|
||||
$widgetObject = new XiboWidget($this->getEntityProvider());
|
||||
$widgetObject->hydrate($widget);
|
||||
$hydratedWidgets[] = $widgetObject;
|
||||
}
|
||||
$playlist->widgets = $hydratedWidgets;
|
||||
$region->regionPlaylist = $playlist;
|
||||
$hydratedRegions[] = $region;
|
||||
}
|
||||
$layout->regions = $hydratedRegions;
|
||||
} else {
|
||||
$this->getLogger()->debug('No regions returned with Layout object');
|
||||
}
|
||||
|
||||
return $layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $layout
|
||||
* @return XiboLayout
|
||||
*/
|
||||
protected function getDraft($layout)
|
||||
{
|
||||
$draft = (new XiboLayout($this->getEntityProvider()))->get(['parentId' => $layout->layoutId, 'showDrafts' => 1, 'embed' => 'regions,playlists,widgets']);
|
||||
|
||||
return $draft[0];
|
||||
}
|
||||
}
|
||||
78
tests/Helper/MockPlayerActionService.php
Normal file
78
tests/Helper/MockPlayerActionService.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2024 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\Helper;
|
||||
|
||||
use Xibo\Service\ConfigServiceInterface;
|
||||
use Xibo\Service\PlayerActionServiceInterface;
|
||||
|
||||
/**
|
||||
* Class MockPlayerActionService
|
||||
* @package Helper
|
||||
*/
|
||||
class MockPlayerActionService implements PlayerActionServiceInterface
|
||||
{
|
||||
/** @var \Xibo\Service\LogServiceInterface */
|
||||
private $log;
|
||||
|
||||
private $displays = [];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function __construct(ConfigServiceInterface $config, $log, $triggerPlayerActions)
|
||||
{
|
||||
$this->log = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function sendAction($displays, $action): void
|
||||
{
|
||||
$this->log->debug('MockPlayerActionService: sendAction');
|
||||
|
||||
if (!is_array($displays)) {
|
||||
$displays = [$displays];
|
||||
}
|
||||
|
||||
foreach ($displays as $display) {
|
||||
$this->displays[] = $display->displayId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getQueue(): array
|
||||
{
|
||||
$this->log->debug('MockPlayerActionService: getQueue');
|
||||
return $this->displays;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function processQueue(): void
|
||||
{
|
||||
$this->log->debug('MockPlayerActionService: processQueue');
|
||||
}
|
||||
}
|
||||
68
tests/Helper/NullPlayerActionService.php
Normal file
68
tests/Helper/NullPlayerActionService.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2024 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\Helper;
|
||||
|
||||
use Xibo\Service\ConfigServiceInterface;
|
||||
use Xibo\Service\PlayerActionServiceInterface;
|
||||
|
||||
/**
|
||||
* Class NullPlayerActionService
|
||||
* @package Helper
|
||||
*/
|
||||
class NullPlayerActionService implements PlayerActionServiceInterface
|
||||
{
|
||||
/** @var \Xibo\Service\LogServiceInterface */
|
||||
private $log;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function __construct(ConfigServiceInterface $config, $log, $triggerPlayerActions)
|
||||
{
|
||||
$this->log = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function sendAction($displays, $action): void
|
||||
{
|
||||
$this->log->debug('NullPlayerActionService: sendAction');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getQueue(): array
|
||||
{
|
||||
$this->log->debug('NullPlayerActionService: getQueue');
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function processQueue(): void
|
||||
{
|
||||
$this->log->debug('NullPlayerActionService: processQueue');
|
||||
}
|
||||
}
|
||||
570
tests/LocalWebTestCase.php
Normal file
570
tests/LocalWebTestCase.php
Normal file
@@ -0,0 +1,570 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests;
|
||||
use Monolog\Handler\NullHandler;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Logger;
|
||||
use Monolog\Processor\UidProcessor;
|
||||
use Nyholm\Psr7\ServerRequest;
|
||||
use PHPUnit\Framework\TestCase as PHPUnit_TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
use Slim\App;
|
||||
use Slim\Http\ServerRequest as Request;
|
||||
use Slim\Views\TwigMiddleware;
|
||||
use Xibo\Entity\Application;
|
||||
use Xibo\Entity\User;
|
||||
use Xibo\Factory\ContainerFactory;
|
||||
use Xibo\Factory\TaskFactory;
|
||||
use Xibo\Middleware\State;
|
||||
use Xibo\Middleware\Storage;
|
||||
use Xibo\OAuth2\Client\Provider\XiboEntityProvider;
|
||||
use Xibo\Service\DisplayNotifyService;
|
||||
use Xibo\Service\ReportService;
|
||||
use Xibo\Storage\PdoStorageService;
|
||||
use Xibo\Storage\StorageServiceInterface;
|
||||
use Xibo\Support\Exception\NotFoundException;
|
||||
use Xibo\Tests\Helper\MockPlayerActionService;
|
||||
use Xibo\Tests\Middleware\TestAuthMiddleware;
|
||||
use Xibo\Tests\Xmds\XmdsWrapper;
|
||||
use Xibo\XTR\TaskInterface;
|
||||
|
||||
/**
|
||||
* Class LocalWebTestCase
|
||||
* @package Xibo\Tests
|
||||
*/
|
||||
class LocalWebTestCase extends PHPUnit_TestCase
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
public static $container;
|
||||
|
||||
/** @var LoggerInterface */
|
||||
public static $logger;
|
||||
|
||||
/** @var TaskInterface */
|
||||
public static $taskService;
|
||||
|
||||
/** @var XiboEntityProvider */
|
||||
public static $entityProvider;
|
||||
|
||||
/** @var XmdsWrapper */
|
||||
public static $xmds;
|
||||
|
||||
/** @var App */
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* Get Entity Provider
|
||||
* @return XiboEntityProvider
|
||||
*/
|
||||
public function getEntityProvider()
|
||||
{
|
||||
return self::$entityProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Xmds Wrapper
|
||||
* @return XmdsWrapper
|
||||
*/
|
||||
public function getXmdsWrapper()
|
||||
{
|
||||
return self::$xmds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Slim instance configured
|
||||
* @return App
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getSlimInstance()
|
||||
{
|
||||
// Create the container for dependency injection.
|
||||
try {
|
||||
$container = ContainerFactory::create();
|
||||
} catch (\Exception $e) {
|
||||
die($e->getMessage());
|
||||
}
|
||||
|
||||
// Create a Slim application
|
||||
$app = \DI\Bridge\Slim\Bridge::create($container);
|
||||
$twigMiddleware = TwigMiddleware::createFromContainer($app);
|
||||
|
||||
// Create a logger
|
||||
$handlers = [];
|
||||
if (isset($_SERVER['PHPUNIT_LOG_TO_FILE']) && $_SERVER['PHPUNIT_LOG_TO_FILE']) {
|
||||
$handlers[] = new StreamHandler(PROJECT_ROOT . '/library/log.txt', Logger::DEBUG);
|
||||
}
|
||||
|
||||
if (isset($_SERVER['PHPUNIT_LOG_WEB_TO_CONSOLE']) && $_SERVER['PHPUNIT_LOG_WEB_TO_CONSOLE']) {
|
||||
$handlers[] = new StreamHandler(STDERR, Logger::DEBUG);
|
||||
}
|
||||
|
||||
if (count($handlers) <= 0) {
|
||||
$handlers[] = new NullHandler();
|
||||
}
|
||||
|
||||
$container->set('logger', function (ContainerInterface $container) use ($handlers) {
|
||||
$logger = new Logger('PHPUNIT');
|
||||
|
||||
$uidProcessor = new UidProcessor();
|
||||
$logger->pushProcessor($uidProcessor);
|
||||
foreach ($handlers as $handler) {
|
||||
$logger->pushHandler($handler);
|
||||
}
|
||||
|
||||
return $logger;
|
||||
});
|
||||
|
||||
// Config
|
||||
$container->set('name', 'test');
|
||||
$container->get('configService');
|
||||
|
||||
// Set app state
|
||||
\Xibo\Middleware\State::setState($app, $this->createRequest('GET', '/'));
|
||||
|
||||
// Setting Middleware
|
||||
$app->add(new \Xibo\Middleware\ListenersMiddleware($app));
|
||||
$app->add(new TestAuthMiddleware($app));
|
||||
$app->add(new State($app));
|
||||
$app->add($twigMiddleware);
|
||||
$app->add(new Storage($app));
|
||||
$app->add(new Middleware\TestXmr($app));
|
||||
$app->addRoutingMiddleware();
|
||||
|
||||
// Add Error Middleware
|
||||
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
|
||||
$errorMiddleware->setDefaultErrorHandler(\Xibo\Middleware\Handlers::testErrorHandler($container));
|
||||
|
||||
// All routes
|
||||
require PROJECT_ROOT . '/lib/routes-web.php';
|
||||
require PROJECT_ROOT . '/lib/routes.php';
|
||||
|
||||
// Add the route for running a task manually
|
||||
$app->get('/tasks/{id}', ['\Xibo\Controller\Task','run']);
|
||||
|
||||
return $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $path
|
||||
* @param array $headers
|
||||
* @param string $requestAttrVal
|
||||
* @param bool|false $ajaxHeader
|
||||
* @param null $body
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
protected function sendRequest(string $method, string $path, $body = null, array $headers = ['HTTP_ACCEPT'=>'application/json'], $requestAttrVal = 'test', $ajaxHeader = false): ResponseInterface
|
||||
{
|
||||
// Create a request for tests
|
||||
$request = new Request(new ServerRequest($method, $path, $headers));
|
||||
$request = $request->withAttribute('_entryPoint', $requestAttrVal);
|
||||
|
||||
// If we are using POST or PUT method then we expect to have Body provided, add it to the request
|
||||
if (in_array($method, ['POST', 'PUT']) && $body != null) {
|
||||
|
||||
$request = $request->withParsedBody($body);
|
||||
|
||||
// in case we forgot to set Content-Type header for PUT requests
|
||||
if ($method === 'PUT') {
|
||||
$request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
}
|
||||
}
|
||||
|
||||
if ($ajaxHeader === true) {
|
||||
$request = $request->withHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
}
|
||||
|
||||
if ($method == 'GET' && $body != null) {
|
||||
$request = $request->withQueryParams($body);
|
||||
}
|
||||
|
||||
// send the request and return the response
|
||||
return $this->app->handle($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $path
|
||||
* @param null $body
|
||||
* @param array $headers
|
||||
* @param array $serverParams
|
||||
* @return Request
|
||||
*/
|
||||
protected function createRequest(string $method, string $path, $body = null, array $headers = ['HTTP_ACCEPT'=>'application/json'], $serverParams = []): Request
|
||||
{
|
||||
// Create a request for tests
|
||||
$request = new Request(new ServerRequest($method, $path, $headers, $body, '', $serverParams));
|
||||
$request = $request->withAttribute('_entryPoint', 'test');
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a global container for all tests to share.
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
// Configure global test state
|
||||
// We want to ensure there is a
|
||||
// - global DB object
|
||||
// - phpunit user who executes the tests through Slim
|
||||
// - an API application owned by phpunit with client_credentials grant type
|
||||
if (self::$container == null) {
|
||||
self::getLogger()->debug('Creating Container');
|
||||
|
||||
// Create a new container
|
||||
$container = ContainerFactory::create();
|
||||
|
||||
// Create a logger
|
||||
$handlers = [];
|
||||
if (isset($_SERVER['PHPUNIT_LOG_TO_FILE']) && $_SERVER['PHPUNIT_LOG_TO_FILE']) {
|
||||
$handlers[] = new StreamHandler(PROJECT_ROOT . '/library/log.txt', Logger::INFO);
|
||||
} else {
|
||||
$handlers[] = new NullHandler();
|
||||
}
|
||||
|
||||
if (isset($_SERVER['PHPUNIT_LOG_CONTAINER_TO_CONSOLE']) && $_SERVER['PHPUNIT_LOG_CONTAINER_TO_CONSOLE']) {
|
||||
$handlers[] = new StreamHandler(STDERR, Logger::DEBUG);
|
||||
}
|
||||
|
||||
$container->set('logger', function (ContainerInterface $container) use ($handlers) {
|
||||
$logger = new Logger('PHPUNIT');
|
||||
|
||||
$uidProcessor = new UidProcessor();
|
||||
$logger->pushProcessor($uidProcessor);
|
||||
foreach ($handlers as $handler) {
|
||||
$logger->pushHandler($handler);
|
||||
}
|
||||
|
||||
return $logger;
|
||||
});
|
||||
|
||||
// Initialise config
|
||||
$container->get('configService');
|
||||
$container->get('configService')->setDependencies($container->get('store'), '/');
|
||||
|
||||
// This is our helper container.
|
||||
$container->set('name', 'phpunit');
|
||||
|
||||
// Configure the container with Player Action and Display Notify
|
||||
// Player Action Helper
|
||||
$container->set('playerActionService', function (ContainerInterface $c) {
|
||||
return new MockPlayerActionService(
|
||||
$c->get('configService'),
|
||||
$c->get('logService'),
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
// Register the display notify service
|
||||
$container->set('displayNotifyService', function (ContainerInterface $c) {
|
||||
return new DisplayNotifyService(
|
||||
$c->get('configService'),
|
||||
$c->get('logService'),
|
||||
$c->get('store'),
|
||||
$c->get('pool'),
|
||||
$c->get('playerActionService'),
|
||||
$c->get('scheduleFactory')
|
||||
);
|
||||
});
|
||||
|
||||
// Register the report service
|
||||
$container->set('reportService', function (ContainerInterface $c) {
|
||||
return new ReportService(
|
||||
$c,
|
||||
$c->get('store'),
|
||||
$c->get('timeSeriesStore'),
|
||||
$c->get('logService'),
|
||||
$c->get('configService'),
|
||||
$c->get('sanitizerService'),
|
||||
$c->get('savedReportFactory')
|
||||
);
|
||||
});
|
||||
|
||||
// <editor-fold desc="Create PHPUnit container users">
|
||||
// Find the PHPUnit user and if we don't create it
|
||||
try {
|
||||
/** @var User $user */
|
||||
$user = $container->get('userFactory')->getByName('phpunit');
|
||||
$user->setChildAclDependencies($container->get('userGroupFactory'));
|
||||
|
||||
// Load the user
|
||||
$user->load(false);
|
||||
|
||||
} catch (NotFoundException $e) {
|
||||
// Create the phpunit user with a random password
|
||||
/** @var \Xibo\Entity\User $user */
|
||||
$user = $container->get('userFactory')->create();
|
||||
$user->setChildAclDependencies($container->get('userGroupFactory'));
|
||||
$user->userTypeId = 1;
|
||||
$user->userName = 'phpunit';
|
||||
$user->libraryQuota = 0;
|
||||
$user->homePageId = 'statusdashboard.view';
|
||||
$user->homeFolderId = 1;
|
||||
$user->isSystemNotification = 1;
|
||||
$user->setNewPassword(\Xibo\Helper\Random::generateString());
|
||||
$user->save();
|
||||
$container->get('store')->commitIfNecessary();
|
||||
}
|
||||
|
||||
// Set on the container
|
||||
$container->set('user', $user);
|
||||
|
||||
// Find the phpunit user and if we don't, complain
|
||||
try {
|
||||
/** @var User $admin */
|
||||
$admin = $container->get('userFactory')->getByName('phpunit');
|
||||
|
||||
} catch (NotFoundException $e) {
|
||||
die ('Cant proceed without the phpunit user');
|
||||
}
|
||||
|
||||
// Check to see if there is an API application we can use
|
||||
try {
|
||||
/** @var Application $application */
|
||||
$application = $container->get('applicationFactory')->getByName('phpunit');
|
||||
} catch (NotFoundException $e) {
|
||||
// Add it
|
||||
$application = $container->get('applicationFactory')->create();
|
||||
$application->name = ('phpunit');
|
||||
$application->authCode = 0;
|
||||
$application->clientCredentials = 1;
|
||||
$application->userId = $admin->userId;
|
||||
$application->assignScope($container->get('applicationScopeFactory')->getById('all'));
|
||||
$application->save();
|
||||
|
||||
/** @var PdoStorageService $store */
|
||||
$store = $container->get('store');
|
||||
$store->commitIfNecessary();
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
// Register a provider and entity provider to act as our API wrapper
|
||||
$provider = new \Xibo\OAuth2\Client\Provider\Xibo([
|
||||
'clientId' => $application->key,
|
||||
'clientSecret' => $application->secret,
|
||||
'redirectUri' => null,
|
||||
'baseUrl' => 'http://localhost'
|
||||
]);
|
||||
|
||||
// Discover the CMS key for XMDS
|
||||
/** @var PdoStorageService $store */
|
||||
$store = $container->get('store');
|
||||
$key = $store->select('SELECT value FROM `setting` WHERE `setting` = \'SERVER_KEY\'', [])[0]['value'];
|
||||
$store->commitIfNecessary();
|
||||
|
||||
// Create an XMDS wrapper for the tests to use
|
||||
$xmds = new XmdsWrapper('http://localhost/xmds.php', $key);
|
||||
|
||||
// Store our entityProvider
|
||||
self::$entityProvider = new XiboEntityProvider($provider);
|
||||
|
||||
// Store our XmdsWrapper
|
||||
self::$xmds = $xmds;
|
||||
|
||||
// Store our container
|
||||
self::$container = $container;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function to skip a test with a reason and close output buffers nicely.
|
||||
* @param string $reason
|
||||
*/
|
||||
public function skipTest($reason)
|
||||
{
|
||||
$this->markTestSkipped($reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Store
|
||||
* @return StorageServiceInterface
|
||||
*/
|
||||
public function getStore()
|
||||
{
|
||||
return self::$container->get('store');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a task object
|
||||
* @param string $task The path of the task class
|
||||
* @return TaskInterface
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getTask($task)
|
||||
{
|
||||
$c = self::$container;
|
||||
|
||||
/** @var TaskFactory $taskFactory */
|
||||
$taskFactory = $c->get('taskFactory');
|
||||
$task = $taskFactory->getByClass($task);
|
||||
|
||||
/** @var TaskInterface $taskClass */
|
||||
$taskClass = new $task->class();
|
||||
|
||||
return $taskClass
|
||||
->setSanitizer($c->get('sanitizerService'))
|
||||
->setUser($c->get('user'))
|
||||
->setConfig($c->get('configService'))
|
||||
->setLogger($c->get('logService'))
|
||||
->setPool($c->get('pool'))
|
||||
->setStore($c->get('store'))
|
||||
->setTimeSeriesStore($c->get('timeSeriesStore'))
|
||||
->setDispatcher($c->get('dispatcher'))
|
||||
->setFactories($c)
|
||||
->setTask($task);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getLogger()
|
||||
{
|
||||
// Create if necessary
|
||||
if (self::$logger === null) {
|
||||
if (isset($_SERVER['PHPUNIT_LOG_TO_CONSOLE']) && $_SERVER['PHPUNIT_LOG_TO_CONSOLE']) {
|
||||
self::$logger = new Logger('TESTS', [new StreamHandler(STDERR, Logger::DEBUG)]);
|
||||
} else {
|
||||
self::$logger = new NullLogger();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the queue of actions.
|
||||
* @return int[]
|
||||
*/
|
||||
public function getPlayerActionQueue()
|
||||
{
|
||||
/** @var \Xibo\Service\PlayerActionServiceInterface $service */
|
||||
$service = $this->app->getContainer()->get('playerActionService');
|
||||
|
||||
if ($service === null) {
|
||||
$this->fail('Test has not used the client and therefore cannot determine XMR activity');
|
||||
}
|
||||
|
||||
return $service->getQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $class
|
||||
*/
|
||||
protected static function installModuleIfNecessary($name, $class)
|
||||
{
|
||||
// Make sure the HLS widget is installed
|
||||
$res = self::$container->get('store')->select('SELECT * FROM `module` WHERE `module` = :module', ['module' => $name]);
|
||||
|
||||
if (count($res) <= 0) {
|
||||
// Install the module
|
||||
self::$container->get('store')->insert('
|
||||
INSERT INTO `module` (`Module`, `Name`, `Enabled`, `RegionSpecific`, `Description`,
|
||||
`SchemaVersion`, `ValidExtensions`, `PreviewEnabled`, `assignable`, `render_as`, `settings`, `viewPath`, `class`, `defaultDuration`, `installName`)
|
||||
VALUES (:module, :name, :enabled, :region_specific, :description,
|
||||
:schema_version, :valid_extensions, :preview_enabled, :assignable, :render_as, :settings, :viewPath, :class, :defaultDuration, :installName)
|
||||
', [
|
||||
'module' => $name,
|
||||
'name' => $name,
|
||||
'enabled' => 1,
|
||||
'region_specific' => 1,
|
||||
'description' => $name,
|
||||
'schema_version' => 1,
|
||||
'valid_extensions' => null,
|
||||
'preview_enabled' => 1,
|
||||
'assignable' => 1,
|
||||
'render_as' => 'html',
|
||||
'settings' => json_encode([]),
|
||||
'viewPath' => '../modules',
|
||||
'class' => $class,
|
||||
'defaultDuration' => 10,
|
||||
'installName' => $name
|
||||
]);
|
||||
self::$container->get('store')->commitIfNecessary();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
self::getLogger()->debug('LocalWebTestCase: setUp');
|
||||
parent::setUp();
|
||||
|
||||
// Establish a local reference to the Slim app object
|
||||
$this->app = $this->getSlimInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function tearDown(): void
|
||||
{
|
||||
self::getLogger()->debug('LocalWebTestCase: tearDown');
|
||||
|
||||
// Close and tidy up the app
|
||||
$this->app->getContainer()->get('store')->close();
|
||||
$this->app = null;
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the _SERVER vars for the suite
|
||||
* @param array $userSettings
|
||||
*/
|
||||
public static function setEnvironment($userSettings = [])
|
||||
{
|
||||
$defaults = [
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'REQUEST_URI' => '/',
|
||||
'SCRIPT_NAME' => '',
|
||||
'PATH_INFO' => '/',
|
||||
'QUERY_STRING' => '',
|
||||
'SERVER_NAME' => 'local.dev',
|
||||
'SERVER_PORT' => 80,
|
||||
'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'HTTP_ACCEPT_LANGUAGE' => 'en-US,en;q=0.8',
|
||||
'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
|
||||
'USER_AGENT' => 'Slim Framework',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
];
|
||||
|
||||
$environmentSettings = array_merge($userSettings, $defaults);
|
||||
|
||||
foreach ($environmentSettings as $key => $value) {
|
||||
$_SERVER[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
75
tests/Middleware/TestAuthMiddleware.php
Normal file
75
tests/Middleware/TestAuthMiddleware.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\Middleware;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
||||
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
||||
use Slim\App;
|
||||
use Xibo\Entity\User;
|
||||
|
||||
|
||||
/**
|
||||
* Class TestAuthMiddleware
|
||||
* @package Xibo\Tests\Middleware
|
||||
*
|
||||
*/
|
||||
class TestAuthMiddleware implements Middleware
|
||||
{
|
||||
/* @var App $app */
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* Xmr constructor.
|
||||
* @param $app
|
||||
*/
|
||||
public function __construct($app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param RequestHandler $handler
|
||||
* @return Response
|
||||
* @throws \Xibo\Support\Exception\GeneralException
|
||||
*/
|
||||
public function process(Request $request, RequestHandler $handler): Response
|
||||
{
|
||||
$app = $this->app;
|
||||
$container = $app->getContainer();
|
||||
|
||||
/** @var User $user */
|
||||
$user = $container->get('userFactory')->getByName('phpunit');
|
||||
$user->setChildAclDependencies($app->getContainer()->get('userGroupFactory'));
|
||||
|
||||
// Load the user
|
||||
$user->load(false);
|
||||
|
||||
$container->set('user', $user);
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
96
tests/Middleware/TestXmr.php
Normal file
96
tests/Middleware/TestXmr.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/*
|
||||
* Spring Signage Ltd - http://www.springsignage.com
|
||||
* Copyright (C) 2017 Spring Signage Ltd
|
||||
* (TestXmr.php)
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\Middleware;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
||||
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
||||
use Slim\App;
|
||||
use Xibo\Support\Exception\GeneralException;
|
||||
use Xibo\Service\DisplayNotifyService;
|
||||
use Xibo\Service\PlayerActionService;
|
||||
use Xibo\Tests\Helper\MockPlayerActionService;
|
||||
|
||||
/**
|
||||
* Class TestXmr
|
||||
* @package Xibo\Tests\Middleware
|
||||
*/
|
||||
class TestXmr implements Middleware
|
||||
{
|
||||
/* @var App $app */
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* Xmr constructor.
|
||||
* @param $app
|
||||
*/
|
||||
public function __construct($app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process
|
||||
* @param Request $request
|
||||
* @param RequestHandler $handler
|
||||
* @return Response
|
||||
*/
|
||||
public function process(Request $request, RequestHandler $handler): Response
|
||||
{
|
||||
$app = $this->app;
|
||||
|
||||
self::setXmr($app);
|
||||
|
||||
// Pass along the request
|
||||
$response = $handler->handle($request);
|
||||
|
||||
// Handle display notifications
|
||||
if ($app->getContainer()->get('displayNotifyService') != null) {
|
||||
try {
|
||||
$app->getContainer()->get('displayNotifyService')->processQueue();
|
||||
} catch (GeneralException $e) {
|
||||
$app->getContainer()->get('logger')->error('Unable to Process Queue of Display Notifications due to %s', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Re-terminate any DB connections
|
||||
$app->getContainer()->get('store')->close();
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set XMR
|
||||
* @param \Slim\App $app
|
||||
* @param bool $triggerPlayerActions
|
||||
*/
|
||||
public static function setXmr($app, $triggerPlayerActions = true)
|
||||
{
|
||||
// Player Action Helper
|
||||
$app->getContainer()->set('playerActionService', function() use ($app, $triggerPlayerActions) {
|
||||
return new MockPlayerActionService(
|
||||
$app->getContainer()->get('configService'),
|
||||
$app->getContainer()->get('logService'),
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
// Register the display notify service
|
||||
$app->getContainer()->set('displayNotifyService', function () use ($app) {
|
||||
return new DisplayNotifyService(
|
||||
$app->getContainer()->get('configService'),
|
||||
$app->getContainer()->get('logService'),
|
||||
$app->getContainer()->get('store'),
|
||||
$app->getContainer()->get('pool'),
|
||||
$app->getContainer()->get('playerActionService'),
|
||||
$app->getContainer()->get('scheduleFactory')
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
193
tests/XMDS.http
Normal file
193
tests/XMDS.http
Normal file
File diff suppressed because one or more lines are too long
105
tests/Xmds/GetDataTest.php
Normal file
105
tests/Xmds/GetDataTest.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2023 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Xmds;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMXPath;
|
||||
use Xibo\Tests\XmdsTestCase;
|
||||
|
||||
/**
|
||||
* Get data tests for xmds v7
|
||||
* @property string $dataSetXml
|
||||
*/
|
||||
class GetDataTest extends XmdsTestCase
|
||||
{
|
||||
// The widgetId of our expected widget (if we change the default layout this ID will change).
|
||||
const WIDGET_ID = 7;
|
||||
|
||||
use XmdsHelperTrait;
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// to make sure Display is logged in, otherwise WidgetSyncTask will not sync data.
|
||||
$this->sendRequest(
|
||||
'POST',
|
||||
$this->register(
|
||||
'PHPUnit7',
|
||||
'phpunitv7',
|
||||
'android'
|
||||
),
|
||||
7
|
||||
);
|
||||
}
|
||||
public function testGetData()
|
||||
{
|
||||
// Fresh RF
|
||||
$this->sendRequest('POST', $this->getRf(7), 7);
|
||||
|
||||
// Execute Widget Sync task so we can have data for our Widget
|
||||
exec('cd /var/www/cms; php bin/run.php 9');
|
||||
|
||||
// XMDS GetData with our dataSet Widget
|
||||
$response = $this->sendRequest('POST', $this->getWidgetData(7, self::WIDGET_ID));
|
||||
$content = $response->getBody()->getContents();
|
||||
|
||||
// expect GetDataResponse
|
||||
$this->assertStringContainsString(
|
||||
'<ns1:GetDataResponse><data xsi:type="xsd:string">',
|
||||
$content,
|
||||
'GetData received incorrect response'
|
||||
);
|
||||
|
||||
$document = new DOMDocument();
|
||||
$document->loadXML($content);
|
||||
$xpath = new DOMXpath($document);
|
||||
$result = $xpath->evaluate('string(//data)');
|
||||
|
||||
$array = json_decode($result, true);
|
||||
|
||||
// go through GetData response and see what we have
|
||||
foreach ($array as $key => $item) {
|
||||
// data and meta expected to not be empty
|
||||
if ($key === 'data' || $key === 'meta') {
|
||||
$this->assertNotEmpty($item);
|
||||
$this->assertNotEmpty($key);
|
||||
}
|
||||
|
||||
if ($key === 'data') {
|
||||
$i = 0;
|
||||
// go through the expected 2 rows in our dataSet data and see if the column/value matches
|
||||
foreach ($item as $row) {
|
||||
$this->assertNotEmpty($row);
|
||||
if ($i === 0) {
|
||||
$this->assertSame('Example text value', $row['Text']);
|
||||
$this->assertSame(1, $row['Number']);
|
||||
} else if ($i === 1) {
|
||||
$this->assertSame('PHPUnit text', $row['Text']);
|
||||
$this->assertSame(2, $row['Number']);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
235
tests/Xmds/GetDependencyTest.php
Normal file
235
tests/Xmds/GetDependencyTest.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2023 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Xmds;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMXPath;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Xibo\Tests\XmdsTestCase;
|
||||
|
||||
/**
|
||||
* GetDependency tests, fonts, bundle
|
||||
*/
|
||||
class GetDependencyTest extends XmdsTestCase
|
||||
{
|
||||
use XmdsHelperTrait;
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public static function successCasesBundle(): array
|
||||
{
|
||||
return [
|
||||
[7],
|
||||
];
|
||||
}
|
||||
|
||||
public static function successCasesFont(): array
|
||||
{
|
||||
return [
|
||||
[7, 'Aileron-Heavy.otf'],
|
||||
[7, 'fonts.css'],
|
||||
[6, 'Aileron-Heavy.otf'],
|
||||
[6, 'fonts.css'],
|
||||
[5, 'Aileron-Heavy.otf'],
|
||||
[5, 'fonts.css'],
|
||||
[4, 'Aileron-Heavy.otf'],
|
||||
[4, 'fonts.css'],
|
||||
];
|
||||
}
|
||||
|
||||
public static function successCasesBundleOld(): array
|
||||
{
|
||||
return [
|
||||
[6],
|
||||
[5],
|
||||
[4],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('successCasesFont')]
|
||||
public function testGetFont($version, $fileName)
|
||||
{
|
||||
$rf = $this->sendRequest('POST', $this->getRf($version), $version);
|
||||
|
||||
$response = $rf->getBody()->getContents();
|
||||
$path = null;
|
||||
|
||||
$document = new DOMDocument();
|
||||
$document->loadXML($response);
|
||||
$xpath = new DOMXpath($document);
|
||||
$result = $xpath->evaluate('string(//RequiredFilesXml)');
|
||||
$array = json_decode(json_encode(simplexml_load_string($result)), true);
|
||||
|
||||
foreach ($array as $item) {
|
||||
foreach ($item as $file) {
|
||||
if (!empty($file['@attributes'])
|
||||
&& !empty($file['@attributes']['saveAs'])
|
||||
&& $file['@attributes']['saveAs'] === $fileName
|
||||
) {
|
||||
if ($version === 7) {
|
||||
$this->assertSame('dependency', $file['@attributes']['type']);
|
||||
} else {
|
||||
$this->assertSame('media', $file['@attributes']['type']);
|
||||
}
|
||||
|
||||
$path = strstr($file['@attributes']['path'], '?');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertNotEmpty($path);
|
||||
|
||||
// Font dependency is still http download, try to get it here
|
||||
$getFile = $this->getFile($path);
|
||||
$this->assertSame(200, $getFile->getStatusCode());
|
||||
$this->assertNotEmpty($getFile->getBody()->getContents());
|
||||
}
|
||||
|
||||
#[DataProvider('successCasesBundle')]
|
||||
public function testGetBundlev7($version)
|
||||
{
|
||||
$rf = $this->sendRequest('POST', $this->getRf($version), $version);
|
||||
$response = $rf->getBody()->getContents();
|
||||
$size = null;
|
||||
$id = null;
|
||||
$type = null;
|
||||
|
||||
$document = new DOMDocument();
|
||||
$document->loadXML($response);
|
||||
$xpath = new DOMXpath($document);
|
||||
$result = $xpath->evaluate('string(//RequiredFilesXml)');
|
||||
$array = json_decode(json_encode(simplexml_load_string($result)), true);
|
||||
|
||||
foreach ($array as $item) {
|
||||
foreach ($item as $file) {
|
||||
if (!empty($file['@attributes'])
|
||||
&& !empty($file['@attributes']['saveAs'])
|
||||
&& $file['@attributes']['saveAs'] === 'bundle.min.js'
|
||||
) {
|
||||
$size = $file['@attributes']['size'];
|
||||
$type = $file['@attributes']['fileType'];
|
||||
$id = $file['@attributes']['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertNotEmpty($size);
|
||||
$this->assertNotEmpty($type);
|
||||
$this->assertNotEmpty($id);
|
||||
|
||||
// construct the xml for GetDependency wsdl request
|
||||
$bundleXml = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="urn:xmds" xmlns:types="urn:xmds/encodedTypes"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<tns:GetDependency>
|
||||
<serverKey xsi:type="xsd:string">6v4RduQhaw5Q</serverKey>
|
||||
<hardwareKey xsi:type="xsd:string">PHPUnit'.$version.'</hardwareKey>
|
||||
<fileType xsi:type="xsd:string">'. $type .'</fileType>
|
||||
<id xsi:type="xsd:string">'. $id .'</id>
|
||||
<chunkOffset xsi:type="xsd:double">0</chunkOffset>
|
||||
<chunkSize xsi:type="xsd:double">'. $size .'</chunkSize>
|
||||
</tns:GetDependency>
|
||||
</soap:Body>
|
||||
</soap:Envelope>';
|
||||
|
||||
// try to call GetDependency with our xml
|
||||
$getBundle = $this->sendRequest('POST', $bundleXml, $version);
|
||||
$getBundleResponse = $getBundle->getBody()->getContents();
|
||||
// expect success
|
||||
$this->assertSame(200, $getBundle->getStatusCode());
|
||||
// expect not empty body
|
||||
$this->assertNotEmpty($getBundleResponse);
|
||||
// expect response format
|
||||
$this->assertStringContainsString(
|
||||
'<ns1:GetDependencyResponse><file xsi:type="xsd:base64Binary">',
|
||||
$getBundleResponse,
|
||||
'GetDependency getBundle received incorrect response'
|
||||
);
|
||||
}
|
||||
|
||||
#[DataProvider('successCasesBundleOld')]
|
||||
public function testGetBundleOld($version)
|
||||
{
|
||||
$rf = $this->sendRequest('POST', $this->getRf($version), $version);
|
||||
$response = $rf->getBody()->getContents();
|
||||
$size = null;
|
||||
$id = null;
|
||||
$type = null;
|
||||
|
||||
$document = new DOMDocument();
|
||||
$document->loadXML($response);
|
||||
$xpath = new DOMXpath($document);
|
||||
$result = $xpath->evaluate('string(//RequiredFilesXml)');
|
||||
$array = json_decode(json_encode(simplexml_load_string($result)), true);
|
||||
|
||||
foreach ($array as $item) {
|
||||
foreach ($item as $file) {
|
||||
if (!empty($file['@attributes'])
|
||||
&& !empty($file['@attributes']['saveAs'])
|
||||
&& $file['@attributes']['saveAs'] === 'bundle.min.js'
|
||||
) {
|
||||
$size = $file['@attributes']['size'];
|
||||
$type = $file['@attributes']['type'];
|
||||
$id = $file['@attributes']['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertNotEmpty($size);
|
||||
$this->assertNotEmpty($type);
|
||||
$this->assertNotEmpty($id);
|
||||
|
||||
// construct the xml for GetDependency wsdl request
|
||||
$bundleXml = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:xmds" xmlns:types="urn:xmds/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<tns:GetFile>
|
||||
<serverKey xsi:type="xsd:string">6v4RduQhaw5Q</serverKey>
|
||||
<hardwareKey xsi:type="xsd:string">PHPUnit'.$version.'</hardwareKey>
|
||||
<fileId xsi:type="xsd:string">'. $id .'</fileId>
|
||||
<fileType xsi:type="xsd:string">'. $type .'</fileType>
|
||||
<chunkOffset xsi:type="xsd:double">0</chunkOffset>
|
||||
<chuckSize xsi:type="xsd:double">'. $size .'</chuckSize>
|
||||
</tns:GetFile>
|
||||
</soap:Body>
|
||||
</soap:Envelope>';
|
||||
|
||||
// try to call GetFile with our xml
|
||||
$getBundle = $this->sendRequest('POST', $bundleXml, $version);
|
||||
$getBundleResponse = $getBundle->getBody()->getContents();
|
||||
// expect success
|
||||
$this->assertSame(200, $getBundle->getStatusCode());
|
||||
// expect not empty body
|
||||
$this->assertNotEmpty($getBundleResponse);
|
||||
// expect response format
|
||||
$this->assertStringContainsString(
|
||||
'<ns1:GetFileResponse><file xsi:type="xsd:base64Binary">',
|
||||
$getBundleResponse,
|
||||
'GetDependency getBundle received incorrect response'
|
||||
);
|
||||
}
|
||||
}
|
||||
215
tests/Xmds/NotifyStatusTest.php
Normal file
215
tests/Xmds/NotifyStatusTest.php
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2023 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Xmds;
|
||||
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Xibo\Tests\XmdsTestCase;
|
||||
|
||||
/**
|
||||
* Various Notify Status tests
|
||||
*/
|
||||
final class NotifyStatusTest extends XmdsTestCase
|
||||
{
|
||||
use XmdsHelperTrait;
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public static function successCases(): array
|
||||
{
|
||||
return [
|
||||
[7],
|
||||
[6],
|
||||
[5],
|
||||
[4],
|
||||
];
|
||||
}
|
||||
|
||||
public static function failureCases(): array
|
||||
{
|
||||
return [
|
||||
[3],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('successCases')]
|
||||
public function testCurrentLayout(int $version)
|
||||
{
|
||||
$request = $this->sendRequest('POST', $this->notifyStatus($version, '{"currentLayoutId":1}'), $version);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'<ns1:NotifyStatusResponse><success xsi:type="xsd:boolean">true</success></ns1:NotifyStatusResponse>',
|
||||
$request->getBody()->getContents(),
|
||||
'Notify Current Layout received incorrect response'
|
||||
);
|
||||
}
|
||||
|
||||
#[DataProvider('failureCases')]
|
||||
public function testCurrentLayoutFailure(int $version)
|
||||
{
|
||||
// disable exception on http_error in guzzle, so we can still check the response
|
||||
$request = $this->sendRequest(
|
||||
'POST',
|
||||
$this->notifyStatus($version, '{"currentLayoutId":1}'),
|
||||
$version,
|
||||
false
|
||||
);
|
||||
|
||||
$this->assertSame(500, $request->getStatusCode());
|
||||
// check the fault code
|
||||
$this->assertStringContainsString(
|
||||
'<faultcode>SOAP-ENV:Server</faultcode>',
|
||||
$request->getBody(),
|
||||
'Notify Current Layout received incorrect response'
|
||||
);
|
||||
|
||||
// check the fault string
|
||||
$this->assertStringContainsString(
|
||||
'<faultstring>Procedure \'NotifyStatus\' not present</faultstring>',
|
||||
$request->getBody(),
|
||||
'Notify Current Layout received incorrect response'
|
||||
);
|
||||
}
|
||||
|
||||
#[DataProvider('failureCases')]
|
||||
public function testCurrentLayoutExceptionFailure(int $version)
|
||||
{
|
||||
// we are expecting 500 Server Exception here for xmds 3
|
||||
$this->expectException('GuzzleHttp\Exception\ServerException');
|
||||
$this->expectExceptionCode(500);
|
||||
$request = $this->sendRequest('POST', $this->notifyStatus($version, '{"currentLayoutId":1}'), $version);
|
||||
}
|
||||
|
||||
#[DataProvider('successCases')]
|
||||
public function testGeoLocation($version)
|
||||
{
|
||||
$request = $this->sendRequest(
|
||||
'POST',
|
||||
$this->notifyStatus($version, '{"latitude":52.3676, "longitude":4.9041}'),
|
||||
$version
|
||||
);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'<ns1:NotifyStatusResponse><success xsi:type="xsd:boolean">true</success></ns1:NotifyStatusResponse>',
|
||||
$request->getBody()->getContents(),
|
||||
'Notify Geo Location received incorrect response'
|
||||
);
|
||||
}
|
||||
|
||||
#[DataProvider('failureCases')]
|
||||
public function testGeoLocationFailure(int $version)
|
||||
{
|
||||
// disable exception on http_error in guzzle, so we can still check the response
|
||||
$request = $this->sendRequest(
|
||||
'POST',
|
||||
$this->notifyStatus($version, '{"latitude":52.3676, "longitude":4.9041}'),
|
||||
$version,
|
||||
false
|
||||
);
|
||||
|
||||
$this->assertSame(500, $request->getStatusCode());
|
||||
// check the fault code
|
||||
$this->assertStringContainsString(
|
||||
'<faultcode>SOAP-ENV:Server</faultcode>',
|
||||
$request->getBody(),
|
||||
'Notify Geo Location received incorrect response'
|
||||
);
|
||||
|
||||
// check the fault string
|
||||
$this->assertStringContainsString(
|
||||
'<faultstring>Procedure \'NotifyStatus\' not present</faultstring>',
|
||||
$request->getBody(),
|
||||
'Notify Geo Location received incorrect response'
|
||||
);
|
||||
}
|
||||
|
||||
#[DataProvider('failureCases')]
|
||||
public function testGeoLocationExceptionFailure(int $version)
|
||||
{
|
||||
// we are expecting 500 Server Exception here for xmds 3
|
||||
$this->expectException('GuzzleHttp\Exception\ServerException');
|
||||
$this->expectExceptionCode(500);
|
||||
$this->sendRequest(
|
||||
'POST',
|
||||
$this->notifyStatus($version, '{"latitude":52.3676, "longitude":4.9041}'),
|
||||
$version,
|
||||
);
|
||||
}
|
||||
|
||||
#[DataProvider('successCases')]
|
||||
public function testOrientation(int $version)
|
||||
{
|
||||
$request = $this->sendRequest(
|
||||
'POST',
|
||||
$this->notifyStatus($version, '{"width":7680, "height":4320}'),
|
||||
$version,
|
||||
);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'<ns1:NotifyStatusResponse><success xsi:type="xsd:boolean">true</success></ns1:NotifyStatusResponse>',
|
||||
$request->getBody()->getContents(),
|
||||
'Notify Orientation received incorrect response'
|
||||
);
|
||||
}
|
||||
|
||||
#[DataProvider('failureCases')]
|
||||
public function testOrientationFailure(int $version)
|
||||
{
|
||||
// disable exception on http_error in guzzle, so we can still check the response
|
||||
$request = $this->sendRequest(
|
||||
'POST',
|
||||
$this->notifyStatus($version, '{"width":7680, "height":4320}'),
|
||||
$version,
|
||||
false
|
||||
);
|
||||
|
||||
$this->assertSame(500, $request->getStatusCode());
|
||||
// check the fault code
|
||||
$this->assertStringContainsString(
|
||||
'<faultcode>SOAP-ENV:Server</faultcode>',
|
||||
$request->getBody(),
|
||||
'Notify Orientation received incorrect response'
|
||||
);
|
||||
|
||||
// check the fault string
|
||||
$this->assertStringContainsString(
|
||||
'<faultstring>Procedure \'NotifyStatus\' not present</faultstring>',
|
||||
$request->getBody(),
|
||||
'Notify Orientation received incorrect response'
|
||||
);
|
||||
}
|
||||
|
||||
#[DataProvider('failureCases')]
|
||||
public function testOrientationExceptionFailure(int $version)
|
||||
{
|
||||
// we are expecting 500 Server Exception here for xmds 3
|
||||
$this->expectException('GuzzleHttp\Exception\ServerException');
|
||||
$this->expectExceptionCode(500);
|
||||
$this->sendRequest(
|
||||
'POST',
|
||||
$this->notifyStatus($version, '{"width":7680, "height":4320}'),
|
||||
$version,
|
||||
);
|
||||
}
|
||||
}
|
||||
134
tests/Xmds/RegisterDisplayTest.php
Normal file
134
tests/Xmds/RegisterDisplayTest.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2024 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Xmds;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMXPath;
|
||||
use Xibo\Tests\XmdsTestCase;
|
||||
|
||||
/**
|
||||
* Register Displays tests
|
||||
*/
|
||||
class RegisterDisplayTest extends XmdsTestCase
|
||||
{
|
||||
use XmdsHelperTrait;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testRegisterDisplayAuthed()
|
||||
{
|
||||
$request = $this->sendRequest(
|
||||
'POST',
|
||||
$this->register(
|
||||
'PHPUnit7',
|
||||
'phpunitv7',
|
||||
'android'
|
||||
),
|
||||
7
|
||||
);
|
||||
|
||||
$response = $request->getBody()->getContents();
|
||||
|
||||
$document = new DOMDocument();
|
||||
$document->loadXML($response);
|
||||
|
||||
$xpath = new DOMXpath($document);
|
||||
$result = $xpath->evaluate('string(//ActivationMessage)');
|
||||
$innerDocument = new DOMDocument();
|
||||
$innerDocument->loadXML($result);
|
||||
|
||||
$this->assertSame('READY', $innerDocument->documentElement->getAttribute('code'));
|
||||
$this->assertSame(
|
||||
'Display is active and ready to start.',
|
||||
$innerDocument->documentElement->getAttribute('message')
|
||||
);
|
||||
}
|
||||
|
||||
public function testRegisterDisplayNoAuth()
|
||||
{
|
||||
$request = $this->sendRequest(
|
||||
'POST',
|
||||
$this->register(
|
||||
'PHPUnitWaiting',
|
||||
'phpunitwaiting',
|
||||
'android'
|
||||
),
|
||||
7
|
||||
);
|
||||
$response = $request->getBody()->getContents();
|
||||
|
||||
$document = new DOMDocument();
|
||||
$document->loadXML($response);
|
||||
|
||||
$xpath = new DOMXpath($document);
|
||||
$result = $xpath->evaluate('string(//ActivationMessage)');
|
||||
$innerDocument = new DOMDocument();
|
||||
$innerDocument->loadXML($result);
|
||||
|
||||
$this->assertSame('WAITING', $innerDocument->documentElement->getAttribute('code'));
|
||||
$this->assertSame(
|
||||
'Display is Registered and awaiting Authorisation from an Administrator in the CMS',
|
||||
$innerDocument->documentElement->getAttribute('message')
|
||||
);
|
||||
|
||||
$array = json_decode(json_encode(simplexml_load_string($result)), true);
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
if ($key === 'commercialLicence') {
|
||||
$this->assertSame('trial', $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testRegisterNewDisplay()
|
||||
{
|
||||
$request = $this->sendRequest(
|
||||
'POST',
|
||||
$this->register(
|
||||
'PHPUnitAddedTest' . mt_rand(1, 10),
|
||||
'phpunitaddedtest',
|
||||
'android'
|
||||
),
|
||||
7
|
||||
);
|
||||
|
||||
$response = $request->getBody()->getContents();
|
||||
|
||||
$document = new DOMDocument();
|
||||
$document->loadXML($response);
|
||||
|
||||
$xpath = new DOMXpath($document);
|
||||
$result = $xpath->evaluate('string(//ActivationMessage)');
|
||||
$innerDocument = new DOMDocument();
|
||||
$innerDocument->loadXML($result);
|
||||
|
||||
$this->assertSame('ADDED', $innerDocument->documentElement->getAttribute('code'));
|
||||
$this->assertSame(
|
||||
'Display is now Registered and awaiting Authorisation from an Administrator in the CMS',
|
||||
$innerDocument->documentElement->getAttribute('message')
|
||||
);
|
||||
}
|
||||
}
|
||||
98
tests/Xmds/ReportFaultsTest.php
Normal file
98
tests/Xmds/ReportFaultsTest.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2023 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Xmds;
|
||||
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Xibo\Tests\XmdsTestCase;
|
||||
|
||||
/**
|
||||
* Report fault tests
|
||||
*/
|
||||
final class ReportFaultsTest extends XmdsTestCase
|
||||
{
|
||||
use XmdsHelperTrait;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public static function successCases(): array
|
||||
{
|
||||
return [
|
||||
[7],
|
||||
[6],
|
||||
];
|
||||
}
|
||||
|
||||
public static function failureCases(): array
|
||||
{
|
||||
return [
|
||||
[5],
|
||||
[4],
|
||||
[3],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('successCases')]
|
||||
public function testSendFaultSuccess(int $version)
|
||||
{
|
||||
$request = $this->sendRequest('POST', $this->reportFault($version), $version);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'<ns1:ReportFaultsResponse><success xsi:type="xsd:boolean">true</success>',
|
||||
$request->getBody()->getContents(),
|
||||
'Send fault received incorrect response'
|
||||
);
|
||||
}
|
||||
|
||||
#[DataProvider('failureCases')]
|
||||
public function testSendFaultFailure(int $version)
|
||||
{
|
||||
// disable exception on http_error in guzzle, so we can still check the response
|
||||
$request = $this->sendRequest('POST', $this->reportFault($version), $version, false);
|
||||
|
||||
// check the fault code
|
||||
$this->assertStringContainsString(
|
||||
'<faultcode>SOAP-ENV:Server</faultcode>',
|
||||
$request->getBody(),
|
||||
'Send fault received incorrect response'
|
||||
);
|
||||
|
||||
// check the fault string
|
||||
$this->assertStringContainsString(
|
||||
'<faultstring>Procedure \'ReportFaults\' not present</faultstring>',
|
||||
$request->getBody(),
|
||||
'Send fault received incorrect response'
|
||||
);
|
||||
}
|
||||
|
||||
#[DataProvider('failureCases')]
|
||||
public function testSendFaultExceptionFailure(int $version)
|
||||
{
|
||||
// we are expecting 500 Server Exception here for xmds 3,4 and 5
|
||||
$this->expectException('GuzzleHttp\Exception\ServerException');
|
||||
$this->expectExceptionCode(500);
|
||||
$this->sendRequest('POST', $this->reportFault($version), $version);
|
||||
}
|
||||
}
|
||||
56
tests/Xmds/SubmitLogTest.php
Normal file
56
tests/Xmds/SubmitLogTest.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Xmds;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Xibo\Tests\xmdsTestCase;
|
||||
|
||||
class SubmitLogTest extends XmdsTestCase
|
||||
{
|
||||
use XmdsHelperTrait;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit log with category event
|
||||
* @return void
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function testSubmitEventLog()
|
||||
{
|
||||
$request = $this->sendRequest(
|
||||
'POST',
|
||||
$this->submitEventLog('7'),
|
||||
7
|
||||
);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'<ns1:SubmitLogResponse><success xsi:type="xsd:boolean">true</success>',
|
||||
$request->getBody()->getContents(),
|
||||
'Submit Log received incorrect response'
|
||||
);
|
||||
}
|
||||
}
|
||||
124
tests/Xmds/SyncTest.php
Normal file
124
tests/Xmds/SyncTest.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2023 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Xmds;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMXPath;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Xibo\Tests\xmdsTestCase;
|
||||
|
||||
/**
|
||||
* Sync Schedule and Register tests
|
||||
*/
|
||||
class SyncTest extends XmdsTestCase
|
||||
{
|
||||
use XmdsHelperTrait;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public static function registerSuccessCases(): array
|
||||
{
|
||||
return [
|
||||
[7],
|
||||
[6],
|
||||
];
|
||||
}
|
||||
|
||||
public function testScheduleSyncEvent()
|
||||
{
|
||||
$request = $this->sendRequest('POST', $this->getSchedule('PHPUnit7'), 7);
|
||||
|
||||
$response = $request->getBody()->getContents();
|
||||
|
||||
$document = new DOMDocument();
|
||||
$document->loadXML($response);
|
||||
|
||||
$xpath = new DOMXpath($document);
|
||||
$result = $xpath->evaluate('string(//ScheduleXml)');
|
||||
$innerDocument = new DOMDocument();
|
||||
$innerDocument->loadXML($result);
|
||||
$layouts = $innerDocument->documentElement->getElementsByTagName('layout');
|
||||
|
||||
$i = 0;
|
||||
foreach ($layouts as $layout) {
|
||||
if ($i === 0) {
|
||||
$this->assertSame('8', $layout->getAttribute('file'));
|
||||
$this->assertSame('1', $layout->getAttribute('syncEvent'));
|
||||
$this->assertSame('2', $layout->getAttribute('scheduleid'));
|
||||
} else if ($i === 1) {
|
||||
$this->assertSame('6', $layout->getAttribute('file'));
|
||||
$this->assertSame('0', $layout->getAttribute('syncEvent'));
|
||||
$this->assertSame('1', $layout->getAttribute('scheduleid'));
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
#[DataProvider('registerSuccessCases')]
|
||||
public function testRegisterDisplay($version)
|
||||
{
|
||||
if ($version === 7) {
|
||||
$this->sendRequest('POST', $this->notifyStatus($version, '{"lanIpAddress":"192.168.0.3"}'), $version);
|
||||
$xml = $this->register(
|
||||
'PHPUnit7',
|
||||
'phpunitv7',
|
||||
'android'
|
||||
);
|
||||
} else {
|
||||
$xml = $this->register(
|
||||
'PHPUnit6',
|
||||
'phpunitv6',
|
||||
'android'
|
||||
);
|
||||
}
|
||||
|
||||
$request = $this->sendRequest('POST', $xml, $version);
|
||||
$response = $request->getBody()->getContents();
|
||||
|
||||
$document = new DOMDocument();
|
||||
$document->loadXML($response);
|
||||
|
||||
$xpath = new DOMXpath($document);
|
||||
$result = $xpath->evaluate('string(//ActivationMessage)');
|
||||
$innerDocument = new DOMDocument();
|
||||
$innerDocument->loadXML($result);
|
||||
|
||||
$this->assertSame('READY', $innerDocument->documentElement->getAttribute('code'));
|
||||
$this->assertSame(
|
||||
'Display is active and ready to start.',
|
||||
$innerDocument->documentElement->getAttribute('message')
|
||||
);
|
||||
|
||||
$syncNodes = $innerDocument->getElementsByTagName('syncGroup');
|
||||
$this->assertSame(1, count($syncNodes));
|
||||
|
||||
if ($version === 7) {
|
||||
$this->assertSame('lead', $syncNodes->item(0)->textContent);
|
||||
} else {
|
||||
$this->assertSame('192.168.0.3', $syncNodes->item(0)->textContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
136
tests/Xmds/XmdsHelperTrait.php
Normal file
136
tests/Xmds/XmdsHelperTrait.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2024 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Xmds;
|
||||
trait XmdsHelperTrait
|
||||
{
|
||||
public function getRf(string $version)
|
||||
{
|
||||
return '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="urn:xmds" xmlns:types="urn:xmds/encodedTypes"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<tns:RequiredFiles>
|
||||
<serverKey xsi:type="xsd:string">6v4RduQhaw5Q</serverKey>
|
||||
<hardwareKey xsi:type="xsd:string">PHPUnit'.$version.'</hardwareKey>
|
||||
</tns:RequiredFiles>
|
||||
</soap:Body>
|
||||
</soap:Envelope>';
|
||||
}
|
||||
|
||||
public function notifyStatus(string $version, string $status)
|
||||
{
|
||||
return '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:xmds" xmlns:types="urn:xmds/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<tns:NotifyStatus>
|
||||
<serverKey xsi:type="xsd:string">6v4RduQhaw5Q</serverKey>
|
||||
<hardwareKey xsi:type="xsd:string">PHPUnit'.$version.'</hardwareKey>
|
||||
<status xsi:type-="xsd:string">'.$status.'</status>
|
||||
</tns:NotifyStatus>
|
||||
</soap:Body>
|
||||
</soap:Envelope>';
|
||||
}
|
||||
|
||||
public function register(
|
||||
$hardwareKey,
|
||||
$displayName,
|
||||
$clientType,
|
||||
$clientVersion = '4',
|
||||
$clientCode = '400',
|
||||
$macAddress = 'CC:40:D0:46:3C:A8'
|
||||
) {
|
||||
return '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:xmds" xmlns:types="urn:xmds/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<tns:RegisterDisplay>
|
||||
<serverKey xsi:type="xsd:string">6v4RduQhaw5Q</serverKey>
|
||||
<hardwareKey xsi:type="xsd:string">' . $hardwareKey . '</hardwareKey>
|
||||
<displayName xsi:type="xsd:string">' . $displayName . '</displayName>
|
||||
<clientType xsi:type="xsd:string">' . $clientType . '</clientType>
|
||||
<clientVersion xsi:type="xsd:string">' . $clientVersion . '</clientVersion>
|
||||
<clientCode xsi:type="xsd:int">' . $clientCode . '</clientCode>
|
||||
<macAddress xsi:type="xsd:string">' . $macAddress . '</macAddress>
|
||||
</tns:RegisterDisplay>
|
||||
</soap:Body>
|
||||
</soap:Envelope>';
|
||||
}
|
||||
|
||||
public function getSchedule($hardwareKey)
|
||||
{
|
||||
return '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:xmds" xmlns:types="urn:xmds/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<tns:Schedule>
|
||||
<serverKey xsi:type="xsd:string">6v4RduQhaw5Q</serverKey>
|
||||
<hardwareKey xsi:type="xsd:string">' . $hardwareKey . '</hardwareKey>
|
||||
</tns:Schedule>
|
||||
</soap:Body>
|
||||
</soap:Envelope>';
|
||||
}
|
||||
|
||||
public function reportFault($version)
|
||||
{
|
||||
return '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:xmds" xmlns:types="urn:xmds/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<tns:ReportFaults>
|
||||
<serverKey xsi:type="xsd:string">6v4RduQhaw5Q</serverKey>
|
||||
<hardwareKey xsi:type="xsd:string">PHPUnit'.$version.'</hardwareKey>
|
||||
<fault xsi:type="xsd:string">[{"date":"2023-04-20 17:03:52","expires":"2023-04-21 17:03:52","code":"10001","reason":"Test","scheduleId":"0","layoutId":0,"regionId":"0","mediaId":"0","widgetId":"0"}]</fault>
|
||||
</tns:ReportFaults>
|
||||
</soap:Body>
|
||||
</soap:Envelope>';
|
||||
}
|
||||
|
||||
public function getWidgetData($version, $widgetId)
|
||||
{
|
||||
return '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="urn:xmds" xmlns:types="urn:xmds/encodedTypes"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<tns:GetData>
|
||||
<serverKey xsi:type="xsd:string">6v4RduQhaw5Q</serverKey>
|
||||
<hardwareKey xsi:type="xsd:string">PHPUnit'. $version .'</hardwareKey>
|
||||
<widgetId xsi:type="xsd:int">'.$widgetId.'</widgetId>
|
||||
</tns:GetData>
|
||||
</soap:Body>
|
||||
</soap:Envelope>';
|
||||
}
|
||||
|
||||
public function submitEventLog($version): string
|
||||
{
|
||||
return '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="urn:xmds" xmlns:types="urn:xmds/encodedTypes"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<tns:SubmitLog>
|
||||
<serverKey xsi:type="xsd:string">6v4RduQhaw5Q</serverKey>
|
||||
<hardwareKey xsi:type="xsd:string">PHPUnit'. $version .'</hardwareKey>
|
||||
<logXml xsi:type="xsd:string"><log><event date="2024-04-10 12:45:55" category="event"><eventType>App Start</eventType><message>Detailed message about this event</message><alertType>both</alertType><refId></refId></event></log></logXml>
|
||||
</tns:SubmitLog>
|
||||
</soap:Body>
|
||||
</soap:Envelope>';
|
||||
}
|
||||
}
|
||||
189
tests/Xmds/XmdsWrapper.php
Normal file
189
tests/Xmds/XmdsWrapper.php
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Xmds;
|
||||
|
||||
/**
|
||||
* Class XmdsWrapper
|
||||
* @package Xibo\Tests\Xmds
|
||||
*/
|
||||
class XmdsWrapper
|
||||
{
|
||||
private $URL;
|
||||
private $KEY;
|
||||
private $version;
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* XmdsWrapper constructor.
|
||||
* @param string $URL
|
||||
* @param string $KEY
|
||||
* @param string $version
|
||||
* @throws \SoapFault
|
||||
*/
|
||||
public function __construct($URL = 'http://localhost/xmds.php', $KEY = 'test', $version = '7')
|
||||
{
|
||||
$this->URL = $URL;
|
||||
$this->KEY = $KEY;
|
||||
$this->version = $version;
|
||||
|
||||
ini_set('soap.wsdl_cache_enabled', 0);
|
||||
ini_set('soap.wsdl_cache_ttl', 900);
|
||||
ini_set('default_socket_timeout', 15);
|
||||
|
||||
$options = [
|
||||
'uri'=>'http://schemas.xmlsoap.org/soap/envelope/',
|
||||
'style'=>SOAP_RPC,
|
||||
'use'=>SOAP_ENCODED,
|
||||
'soap_version'=>SOAP_1_1,
|
||||
'cache_wsdl'=>WSDL_CACHE_NONE,
|
||||
'connection_timeout'=>15,
|
||||
'trace'=>true,
|
||||
'encoding'=>'UTF-8',
|
||||
'exceptions'=>true,
|
||||
];
|
||||
|
||||
$this->client = new \SoapClient($this->URL . '?wsdl&v=' . $this->version, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $hardwareKey
|
||||
* @param $displayName
|
||||
* @param string $clientType
|
||||
* @param string $clientVersion
|
||||
* @param string $clientCode
|
||||
* @param string $operatingSystem
|
||||
* @param string $macAddress
|
||||
* @param string $xmrChannel
|
||||
* @param string $xmrPubKey
|
||||
* @return mixed
|
||||
* @throws \SoapFault
|
||||
*/
|
||||
function RegisterDisplay($hardwareKey, $displayName, $clientType='windows', $clientVersion='', $clientCode='', $operatingSystem='', $macAddress='', $xmrChannel='', $xmrPubKey='')
|
||||
{
|
||||
return $this->client->RegisterDisplay($this->KEY,
|
||||
$hardwareKey,
|
||||
$displayName,
|
||||
$clientType,
|
||||
$clientVersion,
|
||||
$clientCode,
|
||||
$operatingSystem,
|
||||
$macAddress,
|
||||
$xmrChannel,
|
||||
$xmrPubKey
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request Required Files
|
||||
* @param $hardwareKey
|
||||
* @return mixed
|
||||
* @throws \SoapFault
|
||||
*/
|
||||
function RequiredFiles($hardwareKey)
|
||||
{
|
||||
return $this->client->RequiredFiles($this->KEY, $hardwareKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a file
|
||||
* @param $hardwareKey
|
||||
* @param $fileId
|
||||
* @param $fileType
|
||||
* @param $chunkOffset
|
||||
* @param $chunkSize
|
||||
* @return mixed
|
||||
* @throws \SoapFault
|
||||
*/
|
||||
function GetFile($hardwareKey, $fileId, $fileType, $chunkOffset, $chunkSize)
|
||||
{
|
||||
return $this->client->GetFile($this->KEY,
|
||||
$hardwareKey,
|
||||
$fileId,
|
||||
$fileType,
|
||||
$chunkOffset,
|
||||
$chunkSize
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request Schedule
|
||||
* @param $hardwareKey
|
||||
* @return mixed
|
||||
* @throws \SoapFault
|
||||
*/
|
||||
function Schedule($hardwareKey)
|
||||
{
|
||||
return $this->client->Schedule($this->KEY, $hardwareKey);
|
||||
}
|
||||
|
||||
function BlackList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function SubmitLog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit Stats
|
||||
* @param $hardwareKey
|
||||
* @param $statXml
|
||||
* @return mixed
|
||||
* @throws \SoapFault
|
||||
*/
|
||||
function SubmitStats($hardwareKey, $statXml)
|
||||
{
|
||||
return $this->client->SubmitStats($this->KEY, $hardwareKey, $statXml);
|
||||
|
||||
}
|
||||
|
||||
function MediaInventory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $hardwareKey
|
||||
* @param int $layoutId
|
||||
* @param int $regionId
|
||||
* @param string $mediaId
|
||||
* @return string
|
||||
* @throws \SoapFault
|
||||
*/
|
||||
function GetResource($hardwareKey, $layoutId, $regionId, $mediaId)
|
||||
{
|
||||
return $this->client->GetResource($this->KEY, $hardwareKey, $layoutId, $regionId, $mediaId);
|
||||
}
|
||||
|
||||
function NotifyStatus()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function SubmitScreenShot()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
180
tests/XmdsTestCase.php
Normal file
180
tests/XmdsTestCase.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2023 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Logger;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
|
||||
class xmdsTestCase extends TestCase
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
public static $container;
|
||||
|
||||
/** @var LoggerInterface */
|
||||
public static $logger;
|
||||
|
||||
/** @var Client */
|
||||
public $client;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getGuzzleClient(array $requestOptions = []): Client
|
||||
{
|
||||
if ($this->client === null) {
|
||||
$this->client = new Client($requestOptions);
|
||||
}
|
||||
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $body
|
||||
* @param string $path
|
||||
* @param array $headers
|
||||
* @return ResponseInterface
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
protected function sendRequest(
|
||||
string $method = 'POST',
|
||||
string $body = '',
|
||||
string $version = '7',
|
||||
bool $httpErrors = true,
|
||||
string $path = 'http://localhost/xmds.php?v=',
|
||||
array $headers = ['HTTP_ACCEPT'=>'text/xml']
|
||||
): ResponseInterface {
|
||||
// Create a request for tests
|
||||
return $this->client->request($method, $path . $version, [
|
||||
'headers' => $headers,
|
||||
'body' => $body,
|
||||
'http_errors' => $httpErrors
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getFile(
|
||||
string $fileQuery = '',
|
||||
string $method = 'GET',
|
||||
string $basePath = 'http://localhost/xmds.php',
|
||||
): ResponseInterface {
|
||||
// Create a request for tests
|
||||
return $this->client->request($method, $basePath . $fileQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a global container for all tests to share.
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function to skip a test with a reason and close output buffers nicely.
|
||||
* @param string $reason
|
||||
*/
|
||||
public function skipTest(string $reason): void
|
||||
{
|
||||
$this->markTestSkipped($reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Logger|NullLogger|LoggerInterface
|
||||
*/
|
||||
public static function getLogger(): Logger|NullLogger|LoggerInterface
|
||||
{
|
||||
// Create if necessary
|
||||
if (self::$logger === null) {
|
||||
if (isset($_SERVER['PHPUNIT_LOG_TO_CONSOLE']) && $_SERVER['PHPUNIT_LOG_TO_CONSOLE']) {
|
||||
self::$logger = new Logger('TESTS', [new StreamHandler(STDERR, Logger::DEBUG)]);
|
||||
} else {
|
||||
self::$logger = new NullLogger();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
self::getLogger()->debug('xmdsTestCase: setUp');
|
||||
parent::setUp();
|
||||
|
||||
// Establish a local reference to the Slim app object
|
||||
$this->client = $this->getGuzzleClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function tearDown(): void
|
||||
{
|
||||
self::getLogger()->debug('xmdsTestCase: tearDown');
|
||||
|
||||
// Close and tidy up the app
|
||||
$this->client = null;
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the _SERVER vars for the suite
|
||||
* @param array $userSettings
|
||||
*/
|
||||
public static function setEnvironment(array $userSettings = []): void
|
||||
{
|
||||
$defaults = [
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'REQUEST_URI' => '/',
|
||||
'SCRIPT_NAME' => '',
|
||||
'PATH_INFO' => '/',
|
||||
'QUERY_STRING' => '',
|
||||
'SERVER_NAME' => 'local.dev',
|
||||
'SERVER_PORT' => 80,
|
||||
'HTTP_ACCEPT' => 'text/xml,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'HTTP_ACCEPT_LANGUAGE' => 'en-US,en;q=0.8',
|
||||
'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
|
||||
'USER_AGENT' => 'Slim Framework',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
];
|
||||
|
||||
$environmentSettings = array_merge($userSettings, $defaults);
|
||||
|
||||
foreach ($environmentSettings as $key => $value) {
|
||||
$_SERVER[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
tests/Xmr/playerSub.php
Normal file
74
tests/Xmr/playerSub.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2023 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// This is a simple XMR client which connects to the display added in XMDS.http
|
||||
// performing actions in the CMS which affect the display should be logged here.
|
||||
|
||||
define('PROJECT_ROOT', realpath(__DIR__ . '/../..'));
|
||||
|
||||
require PROJECT_ROOT . '/vendor/autoload.php';
|
||||
|
||||
// RSA key
|
||||
$fp = fopen(PROJECT_ROOT . '/library/certs/private.key', 'r');
|
||||
$privateKey = openssl_get_privatekey(fread($fp, 8192));
|
||||
fclose($fp);
|
||||
|
||||
// Sub
|
||||
$loop = React\EventLoop\Factory::create();
|
||||
|
||||
$context = new React\ZMQ\Context($loop);
|
||||
|
||||
$sub = $context->getSocket(ZMQ::SOCKET_SUB);
|
||||
$sub->connect('tcp://xmr:9505');
|
||||
$sub->subscribe('H');
|
||||
$sub->subscribe('XMR_test_channel');
|
||||
|
||||
$sub->on('messages', function ($msg) use ($privateKey) {
|
||||
try {
|
||||
if ($msg[0] == 'H') {
|
||||
echo '[' . date('Y-m-d H:i:s') . '] Heartbeat...' . PHP_EOL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Expect messages to have a length of 3
|
||||
if (count($msg) != 3) {
|
||||
throw new InvalidArgumentException('Incorrect Message Length');
|
||||
}
|
||||
|
||||
// Message will be: channel, key, message
|
||||
if ($msg[0] != 'XMR_test_channel') {
|
||||
throw new InvalidArgumentException('Channel does not match');
|
||||
}
|
||||
|
||||
// Decrypt
|
||||
$output = null;
|
||||
openssl_open(base64_decode($msg[2]), $output, base64_decode($msg[1]), $privateKey, 'RC4');
|
||||
|
||||
echo '[' . date('Y-m-d H:i:s') . '] Received: ' . $output . PHP_EOL;
|
||||
} catch (InvalidArgumentException $e) {
|
||||
echo '[' . date('Y-m-d H:i:s') . '] E: ' . $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
});
|
||||
|
||||
$loop->run();
|
||||
|
||||
openssl_free_key($privateKey);
|
||||
11
tests/http-client.env.json
Normal file
11
tests/http-client.env.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"dev": {
|
||||
"url": "http://localhost",
|
||||
"serverKey": "test",
|
||||
"hardwareKey": "phpstorm",
|
||||
"displayName": "PHPStorm",
|
||||
"clientType": "windows",
|
||||
"macAddress": "00:00:00:00:00:00",
|
||||
"testWidgetId": "1660"
|
||||
}
|
||||
}
|
||||
95
tests/integration/AboutTest.php
Normal file
95
tests/integration/AboutTest.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
use League\OAuth2\Client\Token\AccessToken;
|
||||
|
||||
/**
|
||||
* Class AboutTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class AboutTest extends \Xibo\Tests\LocalWebTestCase
|
||||
{
|
||||
/**
|
||||
* Shows CMS version
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function testVersion()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/about');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response);
|
||||
|
||||
$body = json_decode($response->getBody());
|
||||
|
||||
$this->assertSame(200, $body->status);
|
||||
$this->assertSame(true, $body->success);
|
||||
$this->assertSame(false, $body->grid);
|
||||
$this->assertNotEmpty($body->data, 'Empty Data');
|
||||
$this->assertNotEmpty($body->data->version, 'Empty Version');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the API is initialised and making authenticated requests.
|
||||
*/
|
||||
public function testApiInitialisedTest()
|
||||
{
|
||||
$this->assertNotNull($this->getEntityProvider(), 'Entity Provider not set');
|
||||
$this->assertNotNull($this->getEntityProvider()->getProvider(), 'Provider not set');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testApiInitialisedTest
|
||||
*/
|
||||
public function testApiAccessTest()
|
||||
{
|
||||
$provider = $this->getEntityProvider()->getProvider();
|
||||
$token = $provider->getAccessToken('client_credentials');
|
||||
|
||||
$this->assertNotNull($token);
|
||||
$this->assertNotTrue($token->hasExpired(), 'Expired Token');
|
||||
$this->assertInstanceOf('League\OAuth2\Client\Token\AccessToken', $token);
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccessToken $token
|
||||
* @depends testApiAccessTest
|
||||
*/
|
||||
public function testApiUserTest(AccessToken $token)
|
||||
{
|
||||
$provider = $this->getEntityProvider()->getProvider();
|
||||
|
||||
try {
|
||||
$me = $provider->getResourceOwner($token);
|
||||
} catch (\Exception $exception) {
|
||||
$this->fail('API connect not successful: ' . $exception->getMessage());
|
||||
}
|
||||
|
||||
$this->assertNotNull($me);
|
||||
$this->assertArrayHasKey('userId', $me->toArray());
|
||||
$this->assertNotEmpty($me->getId());
|
||||
$this->assertNotEquals(0, $me->getId());
|
||||
}
|
||||
}
|
||||
67
tests/integration/AuditLogTest.php
Normal file
67
tests/integration/AuditLogTest.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
|
||||
class AuditLogTest extends \Xibo\Tests\LocalWebTestCase
|
||||
{
|
||||
public function testSearch()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/audit');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object->data, $response->getBody());
|
||||
$this->assertObjectHasAttribute('draw', $object->data, $response->getBody());
|
||||
$this->assertObjectHasAttribute('recordsTotal', $object->data, $response->getBody());
|
||||
$this->assertObjectHasAttribute('recordsFiltered', $object->data, $response->getBody());
|
||||
|
||||
// Make sure the recordsTotal is not greater than 10 (the default paging)
|
||||
$this->assertLessThanOrEqual(10, count($object->data->data));
|
||||
}
|
||||
|
||||
public function testExportForm()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/audit/form/export');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testExport()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/audit/export', [
|
||||
'filterFromDt' => Carbon::now()->subSeconds(86400)->format(DateFormatHelper::getSystemFormat()),
|
||||
'filterToDt' => Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
]);
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
}
|
||||
}
|
||||
147
tests/integration/Cache/CampaignDeleteTest.php
Normal file
147
tests/integration/Cache/CampaignDeleteTest.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCampaign;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class CampaignDeleteTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class CampaignDeleteTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboCampaign */
|
||||
protected $campaign;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboSchedule */
|
||||
protected $event;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a simple widget
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Campaign
|
||||
$this->campaign = (new XiboCampaign($this->getEntityProvider()))->create(Random::generateString());
|
||||
|
||||
// Assign the Layout to the Campaign
|
||||
$this->getEntityProvider()->post('/campaign/layout/assign/' . $this->campaign->campaignId, [
|
||||
'layoutId' => $this->layout->layoutId
|
||||
]);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Date
|
||||
$date = Carbon::now();
|
||||
|
||||
// Schedule the Campaign "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$this->event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
$date->format(DateFormatHelper::getSystemFormat()),
|
||||
$date->addHours(3)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->campaign->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Delete the Campaign
|
||||
$this->sendRequest('DELETE', '/campaign/' . $this->campaign->campaignId);
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
146
tests/integration/Cache/CampaignLayoutAssignTest.php
Normal file
146
tests/integration/Cache/CampaignLayoutAssignTest.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2021 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCampaign;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class CampaignLayoutAssignTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class CampaignLayoutAssignTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboCampaign */
|
||||
protected $campaign;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboSchedule */
|
||||
protected $event;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Campaign Layout Unassign Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a simple widget
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Campaign
|
||||
$this->campaign = (new XiboCampaign($this->getEntityProvider()))->create(Random::generateString());
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Date
|
||||
$date = Carbon::now();
|
||||
|
||||
// Schedule the Campaign "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$this->event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
$date->format(DateFormatHelper::getSystemFormat()),
|
||||
$date->addHours(3)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->campaign->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the Campaign
|
||||
$this->campaign->delete();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt Done as expected');
|
||||
|
||||
// Add the Layout we have prepared to the existing Campaign
|
||||
$this->sendRequest('POST', '/campaign/layout/assign/' . $this->campaign->campaignId, [
|
||||
'layoutId' => $this->layout->layoutId
|
||||
]);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt Pending as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
155
tests/integration/Cache/CampaignLayoutUnassignTest.php
Normal file
155
tests/integration/Cache/CampaignLayoutUnassignTest.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCampaign;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class CampaignLayoutUnassignTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class CampaignLayoutUnassignTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboCampaign */
|
||||
protected $campaign;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboSchedule */
|
||||
protected $event;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a simple widget
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Campaign
|
||||
$this->campaign = (new XiboCampaign($this->getEntityProvider()))->create(Random::generateString());
|
||||
|
||||
// Assign the Layout to the Campaign
|
||||
$this->getEntityProvider()->post('/campaign/layout/assign/' . $this->campaign->campaignId, [
|
||||
'layoutId' => $this->layout->layoutId
|
||||
]);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Date
|
||||
$date = Carbon::now();
|
||||
|
||||
// Schedule the Campaign "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$this->event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
$date->format(DateFormatHelper::getSystemFormat()),
|
||||
$date->addHours(3)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->campaign->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the Campaign
|
||||
$this->campaign->delete();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Unassign requires edit
|
||||
$this->sendRequest('PUT', '/campaign/' . $this->campaign->campaignId, [
|
||||
'name' => $this->campaign->campaign,
|
||||
'manageLayouts' => 1,
|
||||
'layoutIds' => [] // empty list
|
||||
]);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
159
tests/integration/Cache/DataSetDataEditTest.php
Normal file
159
tests/integration/Cache/DataSetDataEditTest.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\DataSetColumn;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSet;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSetColumn;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSetView;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboWidget;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DataSetDataEditTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class DataSetDataEditTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboDataSet */
|
||||
protected $dataSet;
|
||||
|
||||
/** @var DataSetColumn */
|
||||
protected $dataSetColumn;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboWidget */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Add a DataSet
|
||||
$this->dataSet = (new XiboDataSet($this->getEntityProvider()))->create(Random::generateString(), 'Test');
|
||||
|
||||
// Add a Column
|
||||
$this->dataSetColumn = (new XiboDataSetColumn($this->getEntityProvider()))->create($this->dataSet->dataSetId,
|
||||
Random::generateString(),
|
||||
'',
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
'');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a couple of text widgets to the region
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/datasetview/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'step' => 1,
|
||||
'dataSetId' => $this->dataSet->dataSetId
|
||||
]);
|
||||
|
||||
$this->widget = (new XiboDataSetView($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Check in
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Set the Layout status
|
||||
$this->setLayoutStatus($this->layout, 1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the DataSet
|
||||
$this->dataSet->deleteWData();
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Add Data to the DataSet
|
||||
$this->sendRequest('POST','/dataset/data/'. $this->dataSet->dataSetId, [
|
||||
'dataSetColumnId_' . $this->dataSetColumn->dataSetColumnId => '1'
|
||||
]);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Somehow test that we have issued an XMR request
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
145
tests/integration/Cache/DisplayGroupDisplayAssignTest.php
Normal file
145
tests/integration/Cache/DisplayGroupDisplayAssignTest.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayGroup;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DisplayGroupDisplayAssignTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class DisplayGroupDisplayAssignTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplayGroup */
|
||||
protected $displayGroup;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a simple widget
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Display Group
|
||||
$this->displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create(Random::generateString(), 'Cache Test', 0, null);
|
||||
|
||||
// Schedule the Layout "always" onto our display group
|
||||
// deleting the layout will remove this at the end
|
||||
$this->event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->displayGroup->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the Display Group
|
||||
$this->displayGroup->delete();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Add the Layout we have prepared to the Display Group
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $this->displayGroup->displayGroupId . '/display/assign', [
|
||||
'displayId' => [$this->display->displayId]
|
||||
]);
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
147
tests/integration/Cache/DisplayGroupDisplayUnassignTest.php
Normal file
147
tests/integration/Cache/DisplayGroupDisplayUnassignTest.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayGroup;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DisplayGroupDisplayUnassignTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class DisplayGroupDisplayUnassignTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplayGroup */
|
||||
protected $displayGroup;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a simple widget
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Display Group
|
||||
$this->displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create(Random::generateString(), 'Cache Test', 0, null);
|
||||
|
||||
// Schedule the Layout "always" onto our display group
|
||||
// deleting the layout will remove this at the end
|
||||
$this->event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->displayGroup->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Assign my Display to the Group
|
||||
$this->getEntityProvider()->post('/displaygroup/' . $this->displayGroup->displayGroupId . '/display/assign', [
|
||||
'displayId' => [$this->display->displayId]
|
||||
]);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the Display Group
|
||||
$this->displayGroup->delete();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Unassign
|
||||
$this->sendRequest('POST','/displaygroup/' . $this->displayGroup->displayGroupId . '/display/unassign', [
|
||||
'displayId' => [$this->display->displayId]
|
||||
]);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
181
tests/integration/Cache/DisplayGroupDynamicDisplayTest.php
Normal file
181
tests/integration/Cache/DisplayGroupDynamicDisplayTest.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayGroup;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DisplayGroupDynamicDisplayTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class DisplayGroupDynamicDisplayTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplayGroup */
|
||||
protected $displayGroup;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a simple widget
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Create a Display Group
|
||||
// this matches all displays created by the test suite
|
||||
$this->displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create(
|
||||
Random::generateString(),
|
||||
'Cache Test',
|
||||
1,
|
||||
'phpunit');
|
||||
|
||||
$this->getLogger()->debug('DisplayGroup created with ID ' . $this->displayGroup->displayGroupId);
|
||||
|
||||
// Schedule the Layout "always" onto our display group
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->displayGroup->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->getLogger()->debug('Schedule created with ID ' . $event->eventId);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Run regular maintenance to add the new display to our group.
|
||||
$this->runRegularMaintenance();
|
||||
|
||||
$this->getLogger()->debug('Display created with ID ' . $this->display->displayId);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display Group
|
||||
$this->displayGroup->delete();
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
$this->getLogger()->debug('Renaming display');
|
||||
|
||||
// Rename the display
|
||||
$response = $this->sendRequest('PUT','/display/' . $this->display->displayId, [
|
||||
'display' => Random::generateString(10, 'testedited'),
|
||||
'defaultLayoutId' => $this->display->defaultLayoutId,
|
||||
'auditingUntil' => null,
|
||||
'licensed' => $this->display->licensed,
|
||||
'license' => $this->display->license,
|
||||
'incSchedule' => $this->display->incSchedule,
|
||||
'emailAlert' => $this->display->emailAlert,
|
||||
'wakeOnLanEnabled' => $this->display->wakeOnLanEnabled,
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
// There isn't anything directly on the display - so that will NOT trigger anything. The schedule is on the Display Group.
|
||||
$this->getLogger()->debug('Finished renaming display');
|
||||
|
||||
$this->assertLessThan(300, $response->getStatusCode(), 'Non-success status code, body =' . $response->getBody()->getContents());
|
||||
|
||||
// Initially we're expecting no change.
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Run regular maintenance
|
||||
$this->runRegularMaintenance();
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Our player action would have been sent by regular maintenance, not by the edit.
|
||||
// Make sure we don't have one here.
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
|
||||
private function runRegularMaintenance()
|
||||
{
|
||||
$this->getLogger()->debug('Running Regular Maintenance');
|
||||
exec('cd /var/www/cms; php bin/run.php 2');
|
||||
$this->getLogger()->debug('Finished Regular Maintenance');
|
||||
}
|
||||
}
|
||||
115
tests/integration/Cache/DisplayGroupLayoutAssignTest.php
Normal file
115
tests/integration/Cache/DisplayGroupLayoutAssignTest.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DisplayGroupLayoutAssignTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class DisplayGroupLayoutAssignTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a simple widget
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Add the Layout we have prepared to the Display Group
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $this->display->displayGroupId . '/layout/assign', [
|
||||
'layoutId' => [$this->layout->layoutId]
|
||||
]);
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
120
tests/integration/Cache/DisplayGroupLayoutUnssignTest.php
Normal file
120
tests/integration/Cache/DisplayGroupLayoutUnssignTest.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DisplayGroupLayoutUnssignTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class DisplayGroupLayoutUnssignTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a simple widget
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Assign the Layout to the Display
|
||||
$this->getEntityProvider()->post('/displaygroup/' . $this->display->displayGroupId . '/layout/assign', [
|
||||
'layoutId' => [$this->layout->layoutId]
|
||||
]);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Add the Layout we have prepared to the Display Group
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $this->display->displayGroupId . '/layout/unassign', [
|
||||
'layoutId' => [$this->layout->layoutId]
|
||||
]);
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
102
tests/integration/Cache/DisplayGroupMediaAssignTest.php
Normal file
102
tests/integration/Cache/DisplayGroupMediaAssignTest.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DisplayGroupMediaAssignTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class DisplayGroupMediaAssignTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Add a media item
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))
|
||||
->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/HLH264.mp4');
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Add the Layout we have prepared to the Display Group
|
||||
$this->sendRequest('POST','/displaygroup/' . $this->display->displayGroupId . '/media/assign', [
|
||||
'mediaId' => [$this->media->mediaId]
|
||||
]);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
107
tests/integration/Cache/DisplayGroupMediaUnassignTest.php
Normal file
107
tests/integration/Cache/DisplayGroupMediaUnassignTest.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DisplayGroupMediaUnassignTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class DisplayGroupMediaUnassignTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Add a media item
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))
|
||||
->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/HLH264.mp4');
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Assign the mediaId to the display
|
||||
$this->getEntityProvider()->post('/displaygroup/' . $this->display->displayGroupId . '/media/assign', [
|
||||
'mediaId' => [$this->media->mediaId]
|
||||
]);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Add the Layout we have prepared to the Display Group
|
||||
$this->sendRequest('POST','/displaygroup/' . $this->display->displayGroupId . '/media/unassign', [
|
||||
'mediaId' => [$this->media->mediaId]
|
||||
]);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
167
tests/integration/Cache/GetResourceTest.php
Normal file
167
tests/integration/Cache/GetResourceTest.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class GetResourceTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class GetResourceTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a resource heavy module to the Layout (one that will download images)
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/ticker/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'uri' => 'http://ceu.xibo.co.uk/mediarss/feed.xml',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1,
|
||||
'sourceId' => 1,
|
||||
'templateId' => 'media-rss-with-title'
|
||||
]);
|
||||
|
||||
// Edit the Ticker to add the template
|
||||
$this->widget = (new XiboTicker($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Checkin
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Set the Layout status
|
||||
$this->setLayoutStatus($this->layout, 3);
|
||||
|
||||
// Build the Layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Layout is already status 1
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
|
||||
$this->assertContains('file="' . $this->layout->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
$this->assertContains('layoutid="' . $this->layout->layoutId . '"', $rf, 'Layout not in Required Files');
|
||||
|
||||
// Call Get Resource
|
||||
$this->getLogger()->debug('Calling GetResource - for ' . $this->layout->layoutId . ' - ' . $this->layout->regions[0]->regionId . ' - ' . $this->widget->widgetId);
|
||||
|
||||
$this->getXmdsWrapper()->GetResource($this->display->license, $this->layout->layoutId, $this->layout->regions[0]->regionId, $this->widget->widgetId);
|
||||
|
||||
// Check the Layout Status
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
}
|
||||
}
|
||||
151
tests/integration/Cache/LayoutBuildTest.php
Normal file
151
tests/integration/Cache/LayoutBuildTest.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutBuildTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutBuildTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
$this->widget = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Layout is already status 1
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 3), 'Pre-Layout Status isnt as expected');
|
||||
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Pre-Display Status isnt as expected');
|
||||
|
||||
// Publish (which builds)
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layout->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$object = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layout = $this->constructLayoutFromResponse($object['data']);
|
||||
|
||||
// Check the Layout Status
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
99
tests/integration/Cache/LayoutChangeActionTest.php
Normal file
99
tests/integration/Cache/LayoutChangeActionTest.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutChangeActionTest
|
||||
*
|
||||
* Tests whether a Layout Edit updates the Cache Appropriately
|
||||
*
|
||||
* @package integration\Cache
|
||||
*/
|
||||
class LayoutChangeActionTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Layout Edit Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout(1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure we're in good condition to start
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Edit the Layout
|
||||
$this->sendRequest('POST','/displaygroup/' . $this->display->displayGroupId . '/action/changeLayout', [
|
||||
'layoutId' => $this->layout->layoutId
|
||||
]);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Somehow test that we have issued an XMR request
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
121
tests/integration/Cache/LayoutDeleteTest.php
Normal file
121
tests/integration/Cache/LayoutDeleteTest.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Exception\XiboApiException;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutDeleteTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutDeleteTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Layout Edit Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout(1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
if ($this->layout !== null)
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Delete the Layout we've got created for us.
|
||||
$this->sendRequest('DELETE','/layout/' . $this->layout->layoutId);
|
||||
|
||||
// Check its deleted
|
||||
try {
|
||||
$this->layoutStatusEquals($this->layout, 0);
|
||||
} catch (XiboApiException $xiboApiException) {
|
||||
$this->assertEquals(404, $xiboApiException->getCode(), 'Expecting a 404, got ' . $xiboApiException->getCode());
|
||||
}
|
||||
|
||||
$this->layout = null;
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Somehow test that we have issued an XMR request
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
145
tests/integration/Cache/LayoutEditTest.php
Normal file
145
tests/integration/Cache/LayoutEditTest.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutEditTest
|
||||
*
|
||||
* Tests whether a Layout Edit updates the Cache Appropriately
|
||||
*
|
||||
* @package integration\Cache
|
||||
*/
|
||||
class LayoutEditTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Layout Edit Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout(1);
|
||||
|
||||
// We need to add a widget to it, so that the Layout tests out as valid
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure we're in good condition to start
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Checkout this Layout
|
||||
$layout = $this->checkout($this->layout);
|
||||
|
||||
// Validate the display status after we've checked out
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected after checkout');
|
||||
|
||||
// Edit the Layout
|
||||
$response = $this->sendRequest('PUT','/layout/background/' . $layout->layoutId, [
|
||||
'backgroundColor' => $layout->backgroundColor,
|
||||
'backgroundzIndex' => $layout->backgroundzIndex
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode(), 'Transaction Status Incorrect');
|
||||
|
||||
// Check in the Layout
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Validate the layout status afterwards (publish builds the layout)
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected after publish');
|
||||
|
||||
// Somehow test that we have issued an XMR request
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
168
tests/integration/Cache/LayoutInCampaignStatusTest.php
Normal file
168
tests/integration/Cache/LayoutInCampaignStatusTest.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCampaign;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutInCampaignStatusTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutInCampaignStatusTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboCampaign */
|
||||
protected $campaign;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Campaign
|
||||
$this->campaign = (new XiboCampaign($this->getEntityProvider()))->create(Random::generateString());
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
$this->widget = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Assign the layout to our campaign
|
||||
$this->getEntityProvider()->post('/campaign/layout/assign/' . $this->campaign->campaignId, [
|
||||
'layoutId' => $this->layout->layoutId
|
||||
]);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Campaign "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->campaign->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the Campaign
|
||||
$this->campaign->delete();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Layout is already status 1
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 3), 'Pre-Layout Status isnt as expected');
|
||||
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Pre-Display Status isnt as expected');
|
||||
|
||||
// Publish (which builds)
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layout->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getStatusCode() . $response->getBody()->getContents());
|
||||
|
||||
$response = json_decode($response->getBody(), true);
|
||||
$this->layout = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Check the Layout Status
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
99
tests/integration/Cache/LayoutOverlayActionTest.php
Normal file
99
tests/integration/Cache/LayoutOverlayActionTest.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutOverlayActionTest
|
||||
*
|
||||
* Tests whether a Layout Edit updates the Cache Appropriately
|
||||
*
|
||||
* @package integration\Cache
|
||||
*/
|
||||
class LayoutOverlayActionTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Layout Edit Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout(1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure we're in good condition to start
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Edit the Layout
|
||||
$this->sendRequest('POST','/displaygroup/' . $this->display->displayGroupId . '/action/overlayLayout', [
|
||||
'layoutId' => $this->layout->layoutId
|
||||
]);
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Somehow test that we have issued an XMR request
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutProofOfPlayXMLMediaInheritWidgetInheritTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutProofOfPlayXMLMediaInheritWidgetInheritTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOff;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOn;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
protected $widgetId;
|
||||
protected $widgetId2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout with enableStat Off (by default)
|
||||
$this->layoutOff = $this->createLayout();
|
||||
$layoutOff = $this->getDraft($this->layoutOff);
|
||||
|
||||
// Upload some media - enableStat is Inherit (from global media stat setting)
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'API Video'),
|
||||
PROJECT_ROOT . '/tests/resources/HLH264.mp4'
|
||||
);
|
||||
|
||||
// Assign the media we've created to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOff->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId = $playlist->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOff->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
|
||||
// Create a layout with enableStat On
|
||||
$this->layoutOn = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit description',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
$layoutOn = $this->getDraft($this->layoutOn);
|
||||
|
||||
// Assign the media we've created to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist2 = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOn->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId2 = $playlist2->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display2
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Schedule the LayoutOn "always" onto our display
|
||||
// deleting the layoutOn will remove this at the end
|
||||
$event2 = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOn->campaignId,
|
||||
[$this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display2, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the LayoutOff
|
||||
$this->deleteLayout($this->layoutOff);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOn);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display2);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// Logic Table
|
||||
//
|
||||
// Widget With Media
|
||||
// LAYOUT MEDIA WIDGET Media stats collected?
|
||||
// ON ON ON YES Widget takes precedence // Match - 1
|
||||
// ON OFF ON YES Widget takes precedence // Match - 1
|
||||
// ON INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// OFF ON ON YES Widget takes precedence // Match - 1
|
||||
// OFF OFF ON YES Widget takes precedence // Match - 1
|
||||
// OFF INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// ON ON OFF NO Widget takes precedence // Match - 2
|
||||
// ON OFF OFF NO Widget takes precedence // Match - 2
|
||||
// ON INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// OFF ON OFF NO Widget takes precedence // Match - 2
|
||||
// OFF OFF OFF NO Widget takes precedence // Match - 2
|
||||
// OFF INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// ON ON INHERIT YES Media takes precedence // Match - 3
|
||||
// ON OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// ON INHERIT INHERIT YES Media takes precedence and Inherited from Layout // Match - 5
|
||||
//
|
||||
// OFF ON INHERIT YES Media takes precedence // Match - 3
|
||||
// OFF OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// OFF INHERIT INHERIT NO Media takes precedence and Inherited from Layout // Match - 6
|
||||
////
|
||||
|
||||
|
||||
public function testLayoutOff()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOff->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOff = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
$this->assertContains('file="' . $this->layoutOff->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display->license, $this->layoutOff->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 0
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="0">', $xmlString );
|
||||
|
||||
// Layout Off, Media Inherit, Widget Inherit, Output => [0, 'Inherit', 'Inherit', 0]
|
||||
$this->assertContains('<media id="'.$this->widgetId.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="0" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
public function testLayoutOn()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOn->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOn = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
$this->assertContains('file="' . $this->layoutOn->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display2->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display2->license, $this->layoutOn->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 1
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="1">', $xmlString );
|
||||
|
||||
// Layout On, Media Inherit, Widget Inherit, Output => [1, 'Inherit', 'Inherit', 1]
|
||||
$this->assertContains('<media id="'.$this->widgetId2.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="1" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutProofOfPlayXMLMediaInheritWidgetOffTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutProofOfPlayXMLMediaInheritWidgetOffTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOff;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOn;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $mediaOn;
|
||||
|
||||
protected $widgetId;
|
||||
protected $widgetId2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Set global widget enable stat set to Off
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'Off');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
// Create a Layout with enableStat Off (by default)
|
||||
$this->layoutOff = $this->createLayout();
|
||||
$layoutOff = $this->getDraft($this->layoutOff);
|
||||
|
||||
// Upload some media - enableStat is Inherit (from global media stat setting)
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'API Video'),
|
||||
PROJECT_ROOT . '/tests/resources/HLH264.mp4'
|
||||
);
|
||||
|
||||
// Assign the media we've edited to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOff->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId = $playlist->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOff->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Create a layout with enableStat On
|
||||
$this->layoutOn = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit description',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
$layoutOn = $this->getDraft($this->layoutOn);
|
||||
|
||||
// Assign the media we've created to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist2 = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOn->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId2 = $playlist2->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display2
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Schedule the LayoutOn "always" onto our display
|
||||
// deleting the layoutOn will remove this at the end
|
||||
$event2 = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOn->campaignId,
|
||||
[$this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display2, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOff);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOn);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display2);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
// Set global widget enable stat set to Inherit
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'Inherit');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// Logic Table
|
||||
//
|
||||
// Widget With Media
|
||||
// LAYOUT MEDIA WIDGET Media stats collected?
|
||||
// ON ON ON YES Widget takes precedence // Match - 1
|
||||
// ON OFF ON YES Widget takes precedence // Match - 1
|
||||
// ON INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// OFF ON ON YES Widget takes precedence // Match - 1
|
||||
// OFF OFF ON YES Widget takes precedence // Match - 1
|
||||
// OFF INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// ON ON OFF NO Widget takes precedence // Match - 2
|
||||
// ON OFF OFF NO Widget takes precedence // Match - 2
|
||||
// ON INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// OFF ON OFF NO Widget takes precedence // Match - 2
|
||||
// OFF OFF OFF NO Widget takes precedence // Match - 2
|
||||
// OFF INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// ON ON INHERIT YES Media takes precedence // Match - 3
|
||||
// ON OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// ON INHERIT INHERIT YES Media takes precedence and Inherited from Layout // Match - 5
|
||||
//
|
||||
// OFF ON INHERIT YES Media takes precedence // Match - 3
|
||||
// OFF OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// OFF INHERIT INHERIT NO Media takes precedence and Inherited from Layout // Match - 6
|
||||
////
|
||||
|
||||
public function testLayoutOff()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOff->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOff = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
$this->assertContains('file="' . $this->layoutOff->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display->license, $this->layoutOff->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 0
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="0">', $xmlString );
|
||||
|
||||
// Layout Off, Media Inherit, Widget Off, Output => [0, 'Inherit', 'Off', 0],
|
||||
$this->assertContains('<media id="'.$this->widgetId.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="0" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
public function testLayoutOn()
|
||||
{
|
||||
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOn->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOn = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
$this->assertContains('file="' . $this->layoutOn->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display2->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display2->license, $this->layoutOn->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 1
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="1">', $xmlString );
|
||||
|
||||
// Layout On, Media Inherit, Widget Off, Output => [1, 'Off', 'Off', 0],
|
||||
$this->assertContains('<media id="'.$this->widgetId2.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="0" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutProofOfPlayXMLMediaInheritWidgetOnTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutProofOfPlayXMLMediaInheritWidgetOnTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOff;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOn;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $mediaOn;
|
||||
|
||||
protected $widgetId;
|
||||
protected $widgetId2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Set global widget enable stat set to On
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'On');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
// Create a Layout with enableStat Off (by default)
|
||||
$this->layoutOff = $this->createLayout();
|
||||
$layoutOff = $this->getDraft($this->layoutOff);
|
||||
|
||||
// Upload some media - enableStat is Inherit (from global media stat setting)
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'API Video'),
|
||||
PROJECT_ROOT . '/tests/resources/HLH264.mp4'
|
||||
);
|
||||
|
||||
// Assign the media we've edited to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOff->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId = $playlist->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOff->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Create a layout with enableStat On
|
||||
$this->layoutOn = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit description',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
$layoutOn = $this->getDraft($this->layoutOn);
|
||||
|
||||
// Assign the media we've created to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist2 = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOn->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId2 = $playlist2->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display2
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Schedule the LayoutOn "always" onto our display
|
||||
// deleting the layoutOn will remove this at the end
|
||||
$event2 = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOn->campaignId,
|
||||
[$this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display2, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOff);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOn);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display2);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
// Set global widget enable stat set to Inherit
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'Inherit');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
parent::tearDown();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// Logic Table
|
||||
//
|
||||
// Widget With Media
|
||||
// LAYOUT MEDIA WIDGET Media stats collected?
|
||||
// ON ON ON YES Widget takes precedence // Match - 1
|
||||
// ON OFF ON YES Widget takes precedence // Match - 1
|
||||
// ON INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// OFF ON ON YES Widget takes precedence // Match - 1
|
||||
// OFF OFF ON YES Widget takes precedence // Match - 1
|
||||
// OFF INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// ON ON OFF NO Widget takes precedence // Match - 2
|
||||
// ON OFF OFF NO Widget takes precedence // Match - 2
|
||||
// ON INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// OFF ON OFF NO Widget takes precedence // Match - 2
|
||||
// OFF OFF OFF NO Widget takes precedence // Match - 2
|
||||
// OFF INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// ON ON INHERIT YES Media takes precedence // Match - 3
|
||||
// ON OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// ON INHERIT INHERIT YES Media takes precedence and Inherited from Layout // Match - 5
|
||||
//
|
||||
// OFF ON INHERIT YES Media takes precedence // Match - 3
|
||||
// OFF OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// OFF INHERIT INHERIT NO Media takes precedence and Inherited from Layout // Match - 6
|
||||
////
|
||||
|
||||
public function testLayoutOff()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOff->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOff = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
$this->assertContains('file="' . $this->layoutOff->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display->license, $this->layoutOff->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 0
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="0">', $xmlString );
|
||||
|
||||
// Layout Off, Media Inherit, Widget On, Output => [0, 'Inherit', 'On', 1],
|
||||
$this->assertContains('<media id="'.$this->widgetId.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="1" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
public function testLayoutOn()
|
||||
{
|
||||
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOn->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOn = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
$this->assertContains('file="' . $this->layoutOn->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display2->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display2->license, $this->layoutOn->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 1
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="1">', $xmlString );
|
||||
|
||||
// Layout On, Media Inherit, Widget On, Output => [1, 'Inherit', 'On', 1],
|
||||
$this->assertContains('<media id="'.$this->widgetId2.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="1" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutProofOfPlayXMLMediaOffWidgetInheritTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutProofOfPlayXMLMediaOffWidgetInheritTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOff;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOn;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $mediaOn;
|
||||
|
||||
protected $widgetId;
|
||||
protected $widgetId2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout with enableStat Off (by default)
|
||||
$this->layoutOff = $this->createLayout();
|
||||
$layoutOff = $this->getDraft($this->layoutOff);
|
||||
|
||||
// Upload some media - enableStat is Inherit (from global media stat setting)
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'API Video'),
|
||||
PROJECT_ROOT . '/tests/resources/HLH264.mp4'
|
||||
);
|
||||
|
||||
// Edit the media to set enableStat On
|
||||
$this->media->edit(
|
||||
$this->media->name,
|
||||
$this->media->duration,
|
||||
$this->media->retired,
|
||||
$this->media->tags,
|
||||
$this->media->updateInLayouts,
|
||||
'Off'
|
||||
);
|
||||
|
||||
// Assign the media we've edited to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOff->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId = $playlist->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOff->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
|
||||
// Create a layout with enableStat On
|
||||
$this->layoutOn = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit description',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
$layoutOn = $this->getDraft($this->layoutOn);
|
||||
|
||||
// Assign the media we've created to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist2 = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOn->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId2 = $playlist2->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display2
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Schedule the LayoutOn "always" onto our display
|
||||
// deleting the layoutOn will remove this at the end
|
||||
$event2 = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOn->campaignId,
|
||||
[$this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display2, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the LayoutOff
|
||||
$this->deleteLayout($this->layoutOff);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOn);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display2);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// Logic Table
|
||||
//
|
||||
// Widget With Media
|
||||
// LAYOUT MEDIA WIDGET Media stats collected?
|
||||
// ON ON ON YES Widget takes precedence // Match - 1
|
||||
// ON OFF ON YES Widget takes precedence // Match - 1
|
||||
// ON INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// OFF ON ON YES Widget takes precedence // Match - 1
|
||||
// OFF OFF ON YES Widget takes precedence // Match - 1
|
||||
// OFF INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// ON ON OFF NO Widget takes precedence // Match - 2
|
||||
// ON OFF OFF NO Widget takes precedence // Match - 2
|
||||
// ON INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// OFF ON OFF NO Widget takes precedence // Match - 2
|
||||
// OFF OFF OFF NO Widget takes precedence // Match - 2
|
||||
// OFF INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// ON ON INHERIT YES Media takes precedence // Match - 3
|
||||
// ON OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// ON INHERIT INHERIT YES Media takes precedence and Inherited from Layout // Match - 5
|
||||
//
|
||||
// OFF ON INHERIT YES Media takes precedence // Match - 3
|
||||
// OFF OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// OFF INHERIT INHERIT NO Media takes precedence and Inherited from Layout // Match - 6
|
||||
////
|
||||
|
||||
|
||||
public function testLayoutOff()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOff->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOff = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
$this->assertContains('file="' . $this->layoutOff->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display->license, $this->layoutOff->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 0
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="0">', $xmlString );
|
||||
|
||||
// Layout Off, Media Off, Widget Inherit, Output => [0, 'Off', 'Inherit', 0],
|
||||
$this->assertContains('<media id="'.$this->widgetId.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="0" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
public function testLayoutOn()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOn->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOn = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
$this->assertContains('file="' . $this->layoutOn->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display2->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display2->license, $this->layoutOn->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 1
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="1">', $xmlString );
|
||||
|
||||
// Layout On, Media Off, Widget Inherit, Output => [1, 'Off', 'Inherit', 0],
|
||||
$this->assertContains('<media id="'.$this->widgetId2.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="0" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutProofOfPlayXMLMediaOffWidgetOffTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutProofOfPlayXMLMediaOffWidgetOffTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOff;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOn;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $mediaOn;
|
||||
|
||||
protected $widgetId;
|
||||
protected $widgetId2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Set global widget enable stat set to Off
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'Off');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
// Create a Layout with enableStat Off (by default)
|
||||
$this->layoutOff = $this->createLayout();
|
||||
$layoutOff = $this->getDraft($this->layoutOff);
|
||||
|
||||
// Upload some media - enableStat is Inherit (from global media stat setting)
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'API Video'),
|
||||
PROJECT_ROOT . '/tests/resources/HLH264.mp4'
|
||||
);
|
||||
|
||||
// Edit the media to set enableStat On
|
||||
$this->media->edit(
|
||||
$this->media->name,
|
||||
$this->media->duration,
|
||||
$this->media->retired,
|
||||
$this->media->tags,
|
||||
$this->media->updateInLayouts,
|
||||
'Off'
|
||||
);
|
||||
|
||||
// Assign the media we've edited to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOff->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId = $playlist->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOff->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Create a layout with enableStat On
|
||||
$this->layoutOn = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit description',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
$layoutOn = $this->getDraft($this->layoutOn);
|
||||
|
||||
// Assign the media we've created to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist2 = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOn->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId2 = $playlist2->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display2
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Schedule the LayoutOn "always" onto our display
|
||||
// deleting the layoutOn will remove this at the end
|
||||
$event2 = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOn->campaignId,
|
||||
[$this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display2, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOff);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOn);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display2);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
// Set global widget enable stat set to Inherit
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'Inherit');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// Logic Table
|
||||
//
|
||||
// Widget With Media
|
||||
// LAYOUT MEDIA WIDGET Media stats collected?
|
||||
// ON ON ON YES Widget takes precedence // Match - 1
|
||||
// ON OFF ON YES Widget takes precedence // Match - 1
|
||||
// ON INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// OFF ON ON YES Widget takes precedence // Match - 1
|
||||
// OFF OFF ON YES Widget takes precedence // Match - 1
|
||||
// OFF INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// ON ON OFF NO Widget takes precedence // Match - 2
|
||||
// ON OFF OFF NO Widget takes precedence // Match - 2
|
||||
// ON INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// OFF ON OFF NO Widget takes precedence // Match - 2
|
||||
// OFF OFF OFF NO Widget takes precedence // Match - 2
|
||||
// OFF INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// ON ON INHERIT YES Media takes precedence // Match - 3
|
||||
// ON OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// ON INHERIT INHERIT YES Media takes precedence and Inherited from Layout // Match - 5
|
||||
//
|
||||
// OFF ON INHERIT YES Media takes precedence // Match - 3
|
||||
// OFF OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// OFF INHERIT INHERIT NO Media takes precedence and Inherited from Layout // Match - 6
|
||||
////
|
||||
|
||||
public function testLayoutOff()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOff->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOff = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
$this->assertContains('file="' . $this->layoutOff->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display->license, $this->layoutOff->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 0
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="0">', $xmlString );
|
||||
|
||||
// Layout Off, Media Off, Widget Off, Output => [0, 'Off', 'Off', 0],
|
||||
$this->assertContains('<media id="'.$this->widgetId.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="0" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
public function testLayoutOn()
|
||||
{
|
||||
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOn->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOn = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
$this->assertContains('file="' . $this->layoutOn->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display2->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display2->license, $this->layoutOn->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 1
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="1">', $xmlString );
|
||||
|
||||
// Layout On, Media Off, Widget Off, Output => [1, 'Off', 'Off', 0],
|
||||
$this->assertContains('<media id="'.$this->widgetId2.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="0" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutProofOfPlayXMLMediaOffWidgetOnTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutProofOfPlayXMLMediaOffWidgetOnTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOff;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOn;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $mediaOn;
|
||||
|
||||
protected $widgetId;
|
||||
protected $widgetId2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Set global widget enable stat set to On
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'On');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
// Create a Layout with enableStat Off (by default)
|
||||
$this->layoutOff = $this->createLayout();
|
||||
$layoutOff = $this->getDraft($this->layoutOff);
|
||||
|
||||
// Upload some media - enableStat is Inherit (from global media stat setting)
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'API Video'),
|
||||
PROJECT_ROOT . '/tests/resources/HLH264.mp4'
|
||||
);
|
||||
|
||||
// Edit the media to set enableStat On
|
||||
$this->media->edit(
|
||||
$this->media->name,
|
||||
$this->media->duration,
|
||||
$this->media->retired,
|
||||
$this->media->tags,
|
||||
$this->media->updateInLayouts,
|
||||
'Off'
|
||||
);
|
||||
|
||||
// Assign the media we've edited to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOff->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId = $playlist->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOff->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Create a layout with enableStat On
|
||||
$this->layoutOn = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit description',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
$layoutOn = $this->getDraft($this->layoutOn);
|
||||
|
||||
// Assign the media we've created to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist2 = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOn->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId2 = $playlist2->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display2
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Schedule the LayoutOn "always" onto our display
|
||||
// deleting the layoutOn will remove this at the end
|
||||
$event2 = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOn->campaignId,
|
||||
[$this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display2, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOff);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOn);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display2);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
// Set global widget enable stat set to Inherit
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'Inherit');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// Logic Table
|
||||
//
|
||||
// Widget With Media
|
||||
// LAYOUT MEDIA WIDGET Media stats collected?
|
||||
// ON ON ON YES Widget takes precedence // Match - 1
|
||||
// ON OFF ON YES Widget takes precedence // Match - 1
|
||||
// ON INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// OFF ON ON YES Widget takes precedence // Match - 1
|
||||
// OFF OFF ON YES Widget takes precedence // Match - 1
|
||||
// OFF INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// ON ON OFF NO Widget takes precedence // Match - 2
|
||||
// ON OFF OFF NO Widget takes precedence // Match - 2
|
||||
// ON INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// OFF ON OFF NO Widget takes precedence // Match - 2
|
||||
// OFF OFF OFF NO Widget takes precedence // Match - 2
|
||||
// OFF INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// ON ON INHERIT YES Media takes precedence // Match - 3
|
||||
// ON OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// ON INHERIT INHERIT YES Media takes precedence and Inherited from Layout // Match - 5
|
||||
//
|
||||
// OFF ON INHERIT YES Media takes precedence // Match - 3
|
||||
// OFF OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// OFF INHERIT INHERIT NO Media takes precedence and Inherited from Layout // Match - 6
|
||||
////
|
||||
|
||||
public function testLayoutOff()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOff->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOff = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
$this->assertContains('file="' . $this->layoutOff->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display->license, $this->layoutOff->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 0
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="0">', $xmlString );
|
||||
|
||||
// Layout Off, Media Off, Widget On, Output => [0, 'Off', 'On', 1],
|
||||
$this->assertContains('<media id="'.$this->widgetId.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="1" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
public function testLayoutOn()
|
||||
{
|
||||
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOn->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOn = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
$this->assertContains('file="' . $this->layoutOn->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display2->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display2->license, $this->layoutOn->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 1
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="1">', $xmlString );
|
||||
|
||||
// Layout On, Media Off, Widget On, Output => [1, 'Off', 'On', 1],
|
||||
$this->assertContains('<media id="'.$this->widgetId2.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="1" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutProofOfPlayXMLMediaOnWidgetInheritTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutProofOfPlayXMLMediaOnWidgetInheritTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOff;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOn;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $mediaOn;
|
||||
|
||||
protected $widgetId;
|
||||
protected $widgetId2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout with enableStat Off (by default)
|
||||
$this->layoutOff = $this->createLayout();
|
||||
$layoutOff = $this->getDraft($this->layoutOff);
|
||||
|
||||
// Upload some media - enableStat is Inherit (from global media stat setting)
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'API Video'),
|
||||
PROJECT_ROOT . '/tests/resources/HLH264.mp4'
|
||||
);
|
||||
|
||||
// Edit the media to set enableStat On
|
||||
$this->media->edit(
|
||||
$this->media->name,
|
||||
$this->media->duration,
|
||||
$this->media->retired,
|
||||
$this->media->tags,
|
||||
$this->media->updateInLayouts,
|
||||
'On'
|
||||
);
|
||||
|
||||
// Assign the media we've edited to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOff->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId = $playlist->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOff->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
|
||||
// Create a layout with enableStat On
|
||||
$this->layoutOn = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit description',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
$layoutOn = $this->getDraft($this->layoutOn);
|
||||
|
||||
// Assign the media we've created to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist2 = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOn->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId2 = $playlist2->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display2
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Schedule the LayoutOn "always" onto our display
|
||||
// deleting the layoutOn will remove this at the end
|
||||
$event2 = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOn->campaignId,
|
||||
[$this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display2, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the LayoutOff
|
||||
$this->deleteLayout($this->layoutOff);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOn);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display2);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
parent::tearDown();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// Logic Table
|
||||
//
|
||||
// Widget With Media
|
||||
// LAYOUT MEDIA WIDGET Media stats collected?
|
||||
// ON ON ON YES Widget takes precedence // Match - 1
|
||||
// ON OFF ON YES Widget takes precedence // Match - 1
|
||||
// ON INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// OFF ON ON YES Widget takes precedence // Match - 1
|
||||
// OFF OFF ON YES Widget takes precedence // Match - 1
|
||||
// OFF INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// ON ON OFF NO Widget takes precedence // Match - 2
|
||||
// ON OFF OFF NO Widget takes precedence // Match - 2
|
||||
// ON INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// OFF ON OFF NO Widget takes precedence // Match - 2
|
||||
// OFF OFF OFF NO Widget takes precedence // Match - 2
|
||||
// OFF INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// ON ON INHERIT YES Media takes precedence // Match - 3
|
||||
// ON OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// ON INHERIT INHERIT YES Media takes precedence and Inherited from Layout // Match - 5
|
||||
//
|
||||
// OFF ON INHERIT YES Media takes precedence // Match - 3
|
||||
// OFF OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// OFF INHERIT INHERIT NO Media takes precedence and Inherited from Layout // Match - 6
|
||||
////
|
||||
|
||||
|
||||
public function testLayoutOff()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOff->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOff = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
$this->assertContains('file="' . $this->layoutOff->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display->license, $this->layoutOff->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 0
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="0">', $xmlString );
|
||||
|
||||
// Layout Off, Media On, Widget Inherit, Output => [0, 'On', 'Inherit', 1],
|
||||
$this->assertContains('<media id="'.$this->widgetId.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="1" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
public function testLayoutOn()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOn->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOn = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
$this->assertContains('file="' . $this->layoutOn->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display2->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display2->license, $this->layoutOn->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 1
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="1">', $xmlString );
|
||||
|
||||
// Layout On, Media On, Widget Inherit, Output => [1, 'On', 'Inherit', 1],
|
||||
$this->assertContains('<media id="'.$this->widgetId2.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="1" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutProofOfPlayXMLMediaOnWidgetOffTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutProofOfPlayXMLMediaOnWidgetOffTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOff;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOn;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $mediaOn;
|
||||
|
||||
protected $widgetId;
|
||||
protected $widgetId2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Set global widget enable stat set to Off
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'Off');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
// Create a Layout with enableStat Off (by default)
|
||||
$this->layoutOff = $this->createLayout();
|
||||
$layoutOff = $this->getDraft($this->layoutOff);
|
||||
|
||||
// Upload some media - enableStat is Inherit (from global media stat setting)
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'API Video'),
|
||||
PROJECT_ROOT . '/tests/resources/HLH264.mp4'
|
||||
);
|
||||
|
||||
// Edit the media to set enableStat On
|
||||
$this->media->edit(
|
||||
$this->media->name,
|
||||
$this->media->duration,
|
||||
$this->media->retired,
|
||||
$this->media->tags,
|
||||
$this->media->updateInLayouts,
|
||||
'On'
|
||||
);
|
||||
|
||||
// Assign the media we've edited to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOff->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId = $playlist->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOff->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Create a layout with enableStat On
|
||||
$this->layoutOn = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit description',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
$layoutOn = $this->getDraft($this->layoutOn);
|
||||
|
||||
// Assign the media we've created to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist2 = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOn->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId2 = $playlist2->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display2
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Schedule the LayoutOn "always" onto our display
|
||||
// deleting the layoutOn will remove this at the end
|
||||
$event2 = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOn->campaignId,
|
||||
[$this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display2, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOff);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOn);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display2);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
// Set global widget enable stat set to Inherit
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'Inherit');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// Logic Table
|
||||
//
|
||||
// Widget With Media
|
||||
// LAYOUT MEDIA WIDGET Media stats collected?
|
||||
// ON ON ON YES Widget takes precedence // Match - 1
|
||||
// ON OFF ON YES Widget takes precedence // Match - 1
|
||||
// ON INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// OFF ON ON YES Widget takes precedence // Match - 1
|
||||
// OFF OFF ON YES Widget takes precedence // Match - 1
|
||||
// OFF INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// ON ON OFF NO Widget takes precedence // Match - 2
|
||||
// ON OFF OFF NO Widget takes precedence // Match - 2
|
||||
// ON INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// OFF ON OFF NO Widget takes precedence // Match - 2
|
||||
// OFF OFF OFF NO Widget takes precedence // Match - 2
|
||||
// OFF INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// ON ON INHERIT YES Media takes precedence // Match - 3
|
||||
// ON OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// ON INHERIT INHERIT YES Media takes precedence and Inherited from Layout // Match - 5
|
||||
//
|
||||
// OFF ON INHERIT YES Media takes precedence // Match - 3
|
||||
// OFF OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// OFF INHERIT INHERIT NO Media takes precedence and Inherited from Layout // Match - 6
|
||||
////
|
||||
|
||||
public function testLayoutOff()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOff->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOff = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
$this->assertContains('file="' . $this->layoutOff->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display->license, $this->layoutOff->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 0
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="0">', $xmlString );
|
||||
|
||||
// Layout Off, Media On, Widget Off, Output => [0, 'On', 'Off', 0],
|
||||
$this->assertContains('<media id="'.$this->widgetId.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="0" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
public function testLayoutOn()
|
||||
{
|
||||
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOn->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOn = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
$this->assertContains('file="' . $this->layoutOn->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display2->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display2->license, $this->layoutOn->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 1
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="1">', $xmlString );
|
||||
|
||||
// Layout On, Media On, Widget Off, Output => [1, 'On', 'Off', 0],
|
||||
$this->assertContains('<media id="'.$this->widgetId2.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="0" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutProofOfPlayXMLMediaOnWidgetOnTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutProofOfPlayXMLMediaOnWidgetOnTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOff;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOn;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $mediaOn;
|
||||
|
||||
protected $widgetId;
|
||||
protected $widgetId2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Set global widget enable stat set to On
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'On');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
// Create a Layout with enableStat Off (by default)
|
||||
$this->layoutOff = $this->createLayout();
|
||||
$layoutOff = $this->getDraft($this->layoutOff);
|
||||
|
||||
// Upload some media - enableStat is Inherit (from global media stat setting)
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'API Video'),
|
||||
PROJECT_ROOT . '/tests/resources/HLH264.mp4'
|
||||
);
|
||||
|
||||
// Edit the media to set enableStat On
|
||||
$this->media->edit(
|
||||
$this->media->name,
|
||||
$this->media->duration,
|
||||
$this->media->retired,
|
||||
$this->media->tags,
|
||||
$this->media->updateInLayouts,
|
||||
'On'
|
||||
);
|
||||
|
||||
// Assign the media we've edited to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOff->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId = $playlist->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOff->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Create a layout with enableStat On
|
||||
$this->layoutOn = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit description',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
$layoutOn = $this->getDraft($this->layoutOn);
|
||||
|
||||
// Assign the media we've created to our regions playlist- widget with Inherit (from global widget stat setting)
|
||||
$playlist2 = (new XiboPlaylist($this->getEntityProvider()))
|
||||
->assign([$this->media->mediaId], 10, $layoutOn->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId2 = $playlist2->widgets[0]->widgetId;
|
||||
|
||||
// Create a Display2
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Schedule the LayoutOn "always" onto our display
|
||||
// deleting the layoutOn will remove this at the end
|
||||
$event2 = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOn->campaignId,
|
||||
[$this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display2, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOff);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOn);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display2);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
// Set global widget enable stat set to Inherit
|
||||
self::$container->get('configService')->changeSetting('WIDGET_STATS_ENABLED_DEFAULT', 'Inherit');
|
||||
$this->getStore()->commitIfNecessary();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// Logic Table
|
||||
//
|
||||
// Widget With Media
|
||||
// LAYOUT MEDIA WIDGET Media stats collected?
|
||||
// ON ON ON YES Widget takes precedence // Match - 1
|
||||
// ON OFF ON YES Widget takes precedence // Match - 1
|
||||
// ON INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// OFF ON ON YES Widget takes precedence // Match - 1
|
||||
// OFF OFF ON YES Widget takes precedence // Match - 1
|
||||
// OFF INHERIT ON YES Widget takes precedence // Match - 1
|
||||
//
|
||||
// ON ON OFF NO Widget takes precedence // Match - 2
|
||||
// ON OFF OFF NO Widget takes precedence // Match - 2
|
||||
// ON INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// OFF ON OFF NO Widget takes precedence // Match - 2
|
||||
// OFF OFF OFF NO Widget takes precedence // Match - 2
|
||||
// OFF INHERIT OFF NO Widget takes precedence // Match - 2
|
||||
//
|
||||
// ON ON INHERIT YES Media takes precedence // Match - 3
|
||||
// ON OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// ON INHERIT INHERIT YES Media takes precedence and Inherited from Layout // Match - 5
|
||||
//
|
||||
// OFF ON INHERIT YES Media takes precedence // Match - 3
|
||||
// OFF OFF INHERIT NO Media takes precedence // Match - 4
|
||||
// OFF INHERIT INHERIT NO Media takes precedence and Inherited from Layout // Match - 6
|
||||
////
|
||||
|
||||
public function testLayoutOff()
|
||||
{
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOff->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOff = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
$this->assertContains('file="' . $this->layoutOff->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display->license, $this->layoutOff->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 0
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="0">', $xmlString );
|
||||
|
||||
// Layout Off, Media On, Widget On, Output => [0, 'On', 'On', 1],
|
||||
$this->assertContains('<media id="'.$this->widgetId.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="1" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
public function testLayoutOn()
|
||||
{
|
||||
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOn->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOn = $this->constructLayoutFromResponse($response['data']);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
$this->assertContains('file="' . $this->layoutOn->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display2->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display2->license, $this->layoutOn->layoutId, 'layout', 0, 0);
|
||||
|
||||
// Layout enable stat 1
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="1">', $xmlString );
|
||||
|
||||
// Layout On, Media On, Widget On, Output => [1, 'On', 'On', 1],
|
||||
$this->assertContains('<media id="'.$this->widgetId2.'" type="video" render="native" duration="10" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="1" fileId="'.$this->media->mediaId.'">', $xmlString );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
280
tests/integration/Cache/LayoutProofOfPlayXMLWithoutMediaTest.php
Normal file
280
tests/integration/Cache/LayoutProofOfPlayXMLWithoutMediaTest.php
Normal file
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutProofOfPlayXMLWithoutMediaTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class LayoutProofOfPlayXMLWithoutMediaTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOff;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layoutOn;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
protected $media;
|
||||
|
||||
protected $widgetId2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout with enableStat Off (by default)
|
||||
$this->layoutOff = $this->createLayout();
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layoutOff will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOff->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Create a layout with enableStat On
|
||||
$this->layoutOn = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit description',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
|
||||
// Create a Display2
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Schedule the LayoutOn "always" onto our display
|
||||
// deleting the layoutOn will remove this at the end
|
||||
$event2 = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->addSeconds(3600)->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layoutOn->campaignId,
|
||||
[$this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display2, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the LayoutOff
|
||||
$this->deleteLayout($this->layoutOff);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the LayoutOn
|
||||
$this->deleteLayout($this->layoutOn);
|
||||
|
||||
// Delete the Display2
|
||||
$this->deleteDisplay($this->display2);
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// Logic Table
|
||||
//
|
||||
// Widget Without Media
|
||||
// LAYOUT WIDGET Widget stats collected?
|
||||
// ON ON YES Widget takes precedence // Match - 1
|
||||
// ON OFF NO Widget takes precedence // Match - 2
|
||||
// ON INHERIT YES Inherited from Layout // Match - 7
|
||||
// OFF ON YES Widget takes precedence // Match - 1
|
||||
// OFF OFF NO Widget takes precedence // Match - 2
|
||||
// OFF INHERIT NO Inherited from Layout // Match - 8
|
||||
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (enableStat)
|
||||
* @return array
|
||||
*/
|
||||
public function layoutEnableStatOffCases()
|
||||
{
|
||||
return [
|
||||
// Layout enableStat Off options - for layout and widget and their expected result (Widget stats collected?) in enableStat (media node attribute)
|
||||
'Layout Off Media On' => [0, 'On', 1],
|
||||
'Layout Off Media Off' => [0, 'Off', 0],
|
||||
'Layout Off Media Inherit' => [0, 'Inherit', 0]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (enableStat)
|
||||
* @return array
|
||||
*/
|
||||
public function layoutEnableStatOnCases()
|
||||
{
|
||||
return [
|
||||
// Layout enableStat On options - for layout and widget and their expected result (Widget stats collected?) in enableStat (media node attribute)
|
||||
'Layout On Media On' => [1, 'On', 1],
|
||||
'Layout On Media Off' => [1, 'Off', 0],
|
||||
'Layout On Media Inherit' => [1, 'Inherit', 1]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit
|
||||
* @dataProvider layoutEnableStatOffCases
|
||||
*/
|
||||
public function testLayoutOff($layoutEnableStat, $widgetEnableStat, $outputEnableStat)
|
||||
{
|
||||
// Checkout
|
||||
$layoutOff = $this->getDraft($this->layoutOff);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layoutOff->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'] , [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1,
|
||||
'enableStat' => $widgetEnableStat
|
||||
]);
|
||||
|
||||
$this->widget = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOff->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOff = $this->constructLayoutFromResponse($response['data']);
|
||||
$this->getLogger()->debug($this->layoutOff->enableStat);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display->license);
|
||||
$this->assertContains('file="' . $this->layoutOff->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display->license, $this->layoutOff->layoutId, 'layout', 0, 0);
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="'.$layoutEnableStat.'">', $xmlString );
|
||||
$this->assertContains('<media id="'.$this->widget->widgetId.'" type="text" render="native" duration="100" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="'.$outputEnableStat.'">', $xmlString );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit
|
||||
* @dataProvider layoutEnableStatOnCases
|
||||
*/
|
||||
public function testLayoutOn($layoutEnableStat, $widgetEnableStat, $outputEnableStat)
|
||||
{
|
||||
// Checkout
|
||||
$layoutOn = $this->getDraft($this->layoutOn);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layoutOn->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'] , [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1,
|
||||
'enableStat' => $widgetEnableStat
|
||||
]);
|
||||
|
||||
$this->widget = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Publish layout
|
||||
$response = $this->sendRequest('PUT','/layout/publish/' . $this->layoutOn->layoutId, [
|
||||
'publishNow' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$response = json_decode($response->getBody(), true);
|
||||
|
||||
$this->layoutOn = $this->constructLayoutFromResponse($response['data']);
|
||||
$this->getLogger()->debug($this->layoutOn->enableStat);
|
||||
|
||||
// Confirm our Layout is in the Schedule
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
$this->assertContains('file="' . $this->layoutOn->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($this->display2->license);
|
||||
|
||||
// Get XML string for player
|
||||
$xmlString = $this->getXmdsWrapper()->GetFile($this->display2->license, $this->layoutOn->layoutId, 'layout', 0, 0);
|
||||
$this->assertContains('<layout width="1920" height="1080" bgcolor="#000" schemaVersion="3" enableStat="'.$layoutEnableStat.'">', $xmlString );
|
||||
$this->assertContains('<media id="'.$this->widget->widgetId.'" type="text" render="native" duration="100" useDuration="1" fromDt="1970-01-01 01:00:00" toDt="2038-01-19 03:14:07" enableStat="'.$outputEnableStat.'">', $xmlString );
|
||||
}
|
||||
|
||||
}
|
||||
109
tests/integration/Cache/LayoutRetireTest.php
Normal file
109
tests/integration/Cache/LayoutRetireTest.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class LayoutRetireTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Layout Retire Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout(1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Retire the Layout we've got created for us.
|
||||
$this->sendRequest('PUT','/layout/retire/' . $this->layout->layoutId, [], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
// Validate the layout status
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Somehow test that we have issued an XMR request
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
146
tests/integration/Cache/LibraryReviseTest.php
Normal file
146
tests/integration/Cache/LibraryReviseTest.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LibraryReviseTest
|
||||
*
|
||||
* Tests whether a Layout Edit updates the Cache Appropriately
|
||||
*
|
||||
* @package integration\Cache
|
||||
*/
|
||||
class LibraryReviseTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Layout Edit Test');
|
||||
|
||||
// Upload some media
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))
|
||||
->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/xts-flowers-001.jpg');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout(1);
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add it to the Layout
|
||||
(new XiboPlaylist($this->getEntityProvider()))->assign([$this->media->mediaId], 10, $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Publish
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Set the Layout status (force it)
|
||||
$this->setLayoutStatus($this->layout, 1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
|
||||
$this->getLogger()->debug('Finished setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure we're in good condition to start
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout status is not as expected');
|
||||
|
||||
// Replace the Media
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))
|
||||
->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/xts-flowers-002.jpg', $this->media->mediaId, 1, 1);
|
||||
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 3), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
}
|
||||
}
|
||||
157
tests/integration/Cache/PlaylistReorderTest.php
Normal file
157
tests/integration/Cache/PlaylistReorderTest.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class PlaylistReorderTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class PlaylistReorderTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
protected $widget1;
|
||||
protected $widget2;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Region Edit Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a couple of text widgets to the region
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
$this->widget1 = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget B',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
$this->widget2 = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Publish
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Set the Layout status
|
||||
$this->setLayoutStatus($this->layout, 1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Checkout
|
||||
$layout = $this->checkout($this->layout);
|
||||
|
||||
// Edit region
|
||||
$this->sendRequest('POST','/playlist/order/' . $layout->regions[0]->regionPlaylist->playlistId, [
|
||||
'widgets' => [
|
||||
$this->widget1->widgetId => 2,
|
||||
$this->widget2->widgetId => 1
|
||||
]
|
||||
]);
|
||||
|
||||
// This shouldn't effect the display
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Publish
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Check the Layout Status
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
}
|
||||
}
|
||||
141
tests/integration/Cache/RegionDeleteTest.php
Normal file
141
tests/integration/Cache/RegionDeleteTest.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class RegionDeleteTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class RegionDeleteTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Region Delete Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a widget to the existing region
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
// Add a region to the Layout
|
||||
$this->region = (new XiboRegion($this->getEntityProvider()))->create($layout->layoutId, 200,300,75,125);
|
||||
|
||||
// Set the Layout status
|
||||
$this->setLayoutStatus($this->layout, 1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Edit region
|
||||
$this->sendRequest('DELETE','/region/' . $this->region->regionId);
|
||||
|
||||
// This shouldn't effect the display
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Checkin
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Check the Layout Status
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Somehow test that we have issued an XMR request
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
144
tests/integration/Cache/RegionEditTest.php
Normal file
144
tests/integration/Cache/RegionEditTest.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class RegionEditTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class RegionEditTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboRegion */
|
||||
protected $region;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Region Edit Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add a widget to the existing region
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
// Set the Layout status
|
||||
$this->setLayoutStatus($this->layout, 1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Edit region
|
||||
$this->sendRequest('PUT','/region/' . $this->layout->regions[0]->regionId, [
|
||||
'width' => 700,
|
||||
'height' => 500,
|
||||
'top' => 400,
|
||||
'left' => 400,
|
||||
'loop' => 0,
|
||||
'zIndex' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Checkin
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Check the Layout Status
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Somehow test that we have issued an XMR request
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
159
tests/integration/Cache/ScheduleChangeInsideRfTest.php
Normal file
159
tests/integration/Cache/ScheduleChangeInsideRfTest.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ScheduleChangeInsideRfTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class ScheduleChangeInsideRfTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboSchedule */
|
||||
protected $event;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
$this->widget = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$this->event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Layout is already status 1
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Change the Schedule
|
||||
$response = $this->sendRequest('PUT','/schedule/' . $this->event->eventId, [
|
||||
'fromDt' => Carbon::createFromTimestamp($this->event->fromDt)->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => Carbon::createFromTimestamp($this->event->toDt)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $this->event->campaignId,
|
||||
'displayGroupIds' => [$this->display->displayGroupId],
|
||||
'displayOrder' => 1,
|
||||
'isPriority' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
// Check the Layout Status
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertTrue(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
161
tests/integration/Cache/ScheduleChangeOutsideRfTest.php
Normal file
161
tests/integration/Cache/ScheduleChangeOutsideRfTest.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ScheduleChangeOutsideRfTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class ScheduleChangeOutsideRfTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboTicker */
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboSchedule */
|
||||
protected $event;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
$this->widget = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Dates outside of RF
|
||||
$date = Carbon::now()->addMonth();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$this->event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
$date->format(DateFormatHelper::getSystemFormat()),
|
||||
$date->addHour()->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Make sure our Layout is already status 1
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Change the Schedule
|
||||
$this->sendRequest('PUT','/schedule/' . $this->event->eventId, [
|
||||
'fromDt' => date(DateFormatHelper::getSystemFormat(), $this->event->fromDt),
|
||||
'toDt' => date(DateFormatHelper::getSystemFormat(), $this->event->toDt),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $this->event->campaignId,
|
||||
'displayGroupIds' => [$this->display->displayGroupId],
|
||||
'displayOrder' => 1,
|
||||
'isPriority' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
// Check the Layout Status
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Validate that XMR has been called.
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
145
tests/integration/Cache/WidgetDeleteTest.php
Normal file
145
tests/integration/Cache/WidgetDeleteTest.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class WidgetDeleteTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class WidgetDeleteTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Region Delete Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget B',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
$this->widget = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Set the Layout status
|
||||
$this->setLayoutStatus($this->layout, 1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Edit region
|
||||
$response = $this->sendRequest('DELETE','/playlist/widget/' . $this->widget->widgetId);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode(), 'Transaction Status Incorrect');
|
||||
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Publish
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Check the Layout Status
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Somehow test that we have issued an XMR request
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
142
tests/integration/Cache/WidgetEditTest.php
Normal file
142
tests/integration/Cache/WidgetEditTest.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Xibo\Tests\integration\Cache;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class WidgetEditTest
|
||||
* @package Xibo\Tests\integration\Cache
|
||||
*/
|
||||
class WidgetEditTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
protected $widget;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache Region Edit Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId, [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
$this->widget = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Set the Layout status
|
||||
$this->setLayoutStatus($this->layout, 1);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
// Schedule the Layout "always" onto our display
|
||||
// deleting the layout will remove this at the end
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* @group cacheInvalidateTests
|
||||
*/
|
||||
public function testInvalidateCache()
|
||||
{
|
||||
// Edit region
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widget->widgetId, [
|
||||
'text' => 'Edited Text',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode(), 'Transaction Status Incorrect');
|
||||
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Check the Layout Status
|
||||
// Validate the layout status afterwards
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Validate the display status afterwards
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_PENDING), 'Display Status isnt as expected');
|
||||
|
||||
// Somehow test that we have issued an XMR request
|
||||
$this->assertFalse(in_array($this->display->displayId, $this->getPlayerActionQueue()), 'Player action not present');
|
||||
}
|
||||
}
|
||||
142
tests/integration/CampaignLayoutManagementTest.php
Normal file
142
tests/integration/CampaignLayoutManagementTest.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2021 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCampaign;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\Support\Exception\InvalidArgumentException;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class CampaignLayoutManagementTest
|
||||
* @package Xibo\Tests\integration
|
||||
*/
|
||||
class CampaignLayoutManagementTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var XiboCampaign */
|
||||
protected $campaign;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
// Create a Campaign and Layout
|
||||
$this->campaign = (new XiboCampaign($this->getEntityProvider()))->create(Random::generateString());
|
||||
$this->layout = $this->createLayout();
|
||||
$this->layout = $this->publish($this->layout);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Campaign
|
||||
$this->campaign->delete();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign Layout
|
||||
*/
|
||||
public function testAssignOneLayout()
|
||||
{
|
||||
// Assign one layout
|
||||
$response = $this->sendRequest('POST', '/campaign/layout/assign/' . $this->campaign->campaignId, [
|
||||
'layoutId' => $this->layout->layoutId
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Request failed: ' . $response->getBody()->getContents());
|
||||
|
||||
// Get this campaign and check it has 1 layout assigned
|
||||
$campaignCheck = (new XiboCampaign($this->getEntityProvider()))->getById($this->campaign->campaignId);
|
||||
$this->assertSame($this->campaign->campaignId, $campaignCheck->campaignId, $response->getBody());
|
||||
$this->assertSame(1, $campaignCheck->numberLayouts, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign Layout
|
||||
*/
|
||||
public function testAssignTwoLayouts()
|
||||
{
|
||||
$response = $this->sendRequest('PUT', '/campaign/' . $this->campaign->campaignId, [
|
||||
'name' => $this->campaign->campaign,
|
||||
'manageLayouts' => 1,
|
||||
'layoutIds' => [$this->layout->layoutId, $this->layout->layoutId]
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Request failed');
|
||||
|
||||
// Get this campaign and check it has 2 layouts assigned
|
||||
$campaignCheck = (new XiboCampaign($this->getEntityProvider()))->getById($this->campaign->campaignId);
|
||||
$this->assertSame($this->campaign->campaignId, $campaignCheck->campaignId, $response->getBody());
|
||||
$this->assertSame(2, $campaignCheck->numberLayouts, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign Layout
|
||||
*/
|
||||
public function testUnassignLayout()
|
||||
{
|
||||
$this->getEntityProvider()->post('/campaign/layout/assign/' . $this->campaign->campaignId, [
|
||||
'layoutId' => $this->layout->layoutId
|
||||
]);
|
||||
|
||||
$response = $this->sendRequest('PUT', '/campaign/' . $this->campaign->campaignId, [
|
||||
'name' => $this->campaign->campaign,
|
||||
'manageLayouts' => 1,
|
||||
'layoutIds' => []
|
||||
]);
|
||||
|
||||
$campaignCheck = (new XiboCampaign($this->getEntityProvider()))->getById($this->campaign->campaignId);
|
||||
$this->assertSame($this->campaign->campaignId, $campaignCheck->campaignId, $response->getBody());
|
||||
$this->assertSame(0, $campaignCheck->numberLayouts, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign Layout to layout specific campaignId - expect failure
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function testAssignLayoutFailure()
|
||||
{
|
||||
// Call assign on the layout specific campaignId
|
||||
$request = $this->createRequest('POST', '/campaign/layout/assign/' . $this->layout->campaignId);
|
||||
$request = $request->withParsedBody([
|
||||
'layoutId' => $this->layout->layoutId
|
||||
]);
|
||||
|
||||
try {
|
||||
$this->app->handle($request);
|
||||
} catch (InvalidArgumentException $exception) {
|
||||
$this->assertSame(422, $exception->getCode(), 'Expecting failure, received ' . $exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
216
tests/integration/CampaignTest.php
Normal file
216
tests/integration/CampaignTest.php
Normal file
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCampaign;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboResolution;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class CampaignTest
|
||||
* @package Xibo\Tests
|
||||
*/
|
||||
class CampaignTest extends LocalWebTestCase
|
||||
{
|
||||
|
||||
protected $startCampaigns;
|
||||
protected $startLayouts;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startCampaigns = (new XiboCampaign($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->startLayouts = (new XiboLayout($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all campaigns that weren't there initially
|
||||
$finalCamapigns = (new XiboCampaign($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining campaigns and nuke them
|
||||
foreach ($finalCamapigns as $campaign) {
|
||||
/** @var XiboCampaign $campaign */
|
||||
$flag = true;
|
||||
foreach ($this->startCampaigns as $startCampaign) {
|
||||
if ($startCampaign->campaignId == $campaign->campaignId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$campaign->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $campaign->campaignId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
// tearDown all layouts that weren't there initially
|
||||
$finalLayouts = (new XiboLayout($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining layouts and nuke them
|
||||
foreach ($finalLayouts as $layout) {
|
||||
/** @var XiboLayout $layout */
|
||||
$flag = true;
|
||||
foreach ($this->startLayouts as $startLayout) {
|
||||
if ($startLayout->layoutId == $layout->layoutId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$layout->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $layout->layoutId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @return int
|
||||
*/
|
||||
private function getResolutionId($type)
|
||||
{
|
||||
if ($type === 'landscape') {
|
||||
$width = 1920;
|
||||
$height = 1080;
|
||||
} else if ($type === 'portrait') {
|
||||
$width = 1080;
|
||||
$height = 1920;
|
||||
} else {
|
||||
return -10;
|
||||
}
|
||||
|
||||
//$this->getLogger()->debug('Querying for ' . $width . ', ' . $height);
|
||||
|
||||
$resolutions = (new XiboResolution($this->getEntityProvider()))->get(['width' => $width, 'height' => $height]);
|
||||
|
||||
if (count($resolutions) <= 0)
|
||||
return -10;
|
||||
|
||||
return $resolutions[0]->resolutionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Campaigns
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
# Get list of all campaigns
|
||||
$response = $this->sendRequest('GET', '/campaign');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response);
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
# Check if call was successful
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertNotEmpty($object->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Campaign
|
||||
*/
|
||||
public function testAdd()
|
||||
{
|
||||
# Generate random name
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
# Add campaign
|
||||
$response = $this->sendRequest('POST', '/campaign', ['name' => $name]);
|
||||
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Check if campaign has he name we want it to have
|
||||
$this->assertSame($name, $object->data->campaign);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test edit
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
# Generate name and add campaign
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$campaign = (new XiboCampaign($this->getEntityProvider()))->create($name);
|
||||
# Generate new random name
|
||||
$newName = Random::generateString(8, 'phpunit');
|
||||
# Edit the campaign we added and change the name
|
||||
$response = $this->sendRequest('PUT', '/campaign/' . $campaign->campaignId, ['name' => $newName]);
|
||||
|
||||
# check if cal was successful
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
# Check if campaign has the new name now
|
||||
$this->assertSame($newName, $object->data->campaign);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Delete
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
# generate two random names
|
||||
$name1 = Random::generateString(8, 'phpunit');
|
||||
$name2 = Random::generateString(8, 'phpunit');
|
||||
# Load in a couple of known campaigns
|
||||
$camp1 = (new XiboCampaign($this->getEntityProvider()))->create($name1);
|
||||
$camp2 = (new XiboCampaign($this->getEntityProvider()))->create($name2);
|
||||
# Delete the one we created last
|
||||
$response = $this->sendRequest('DELETE', '/campaign/' . $camp2->campaignId);
|
||||
# This should return 204 for success
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
|
||||
# Check only one remains
|
||||
$campaigns = (new XiboCampaign($this->getEntityProvider()))->get();
|
||||
$this->assertEquals(count($this->startCampaigns) + 1, count($campaigns));
|
||||
$flag = false;
|
||||
foreach ($campaigns as $campaign) {
|
||||
if ($campaign->campaignId == $camp1->campaignId) {
|
||||
$flag = true;
|
||||
}
|
||||
}
|
||||
# Check if everything is in order
|
||||
$this->assertTrue($flag, 'Campaign ID ' . $camp1->campaignId . ' was not found after deleting a different campaign');
|
||||
# Cleanup
|
||||
$camp1->delete();
|
||||
}
|
||||
}
|
||||
38
tests/integration/ClockTest.php
Normal file
38
tests/integration/ClockTest.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
|
||||
class ClockTest extends \Xibo\Tests\LocalWebTestCase
|
||||
{
|
||||
public function testView()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/clock');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response);
|
||||
$response = json_decode($response->getBody());
|
||||
$this->assertNotEmpty($response->data);
|
||||
|
||||
}
|
||||
}
|
||||
276
tests/integration/CommandTest.php
Normal file
276
tests/integration/CommandTest.php
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCommand;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
|
||||
class CommandTest extends LocalWebTestCase
|
||||
{
|
||||
protected $startCommands;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startCommands = (new XiboCommand($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all commands that weren't there initially
|
||||
$finalCommands = (new XiboCommand($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining commands and nuke them
|
||||
foreach ($finalCommands as $command) {
|
||||
/** @var XiboCommand $command */
|
||||
$flag = true;
|
||||
foreach ($this->startCommands as $startCom) {
|
||||
if ($startCom->commandId == $command->commandId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$command->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $command->commandId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows this user commands
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
# Get the list of all commands
|
||||
$response = $this->sendRequest('GET','/command');
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddSuccess - test adding various commands that should be valid
|
||||
* @dataProvider provideSuccessCases
|
||||
* @group minimal
|
||||
*/
|
||||
public function testAddSuccess($commandName, $commandDescription, $commandCode)
|
||||
{
|
||||
|
||||
// Loop through any pre-existing commands to make sure we're not
|
||||
// going to get a clash
|
||||
foreach ($this->startCommands as $tmpCom) {
|
||||
if ($tmpCom->command == $commandName) {
|
||||
$this->skipTest("There is a pre-existing command with this name");
|
||||
return;
|
||||
}
|
||||
}
|
||||
# Add new comands with arguments from provideSuccessCases
|
||||
$response = $this->sendRequest('POST','/command', [
|
||||
'command' => $commandName,
|
||||
'description' => $commandDescription,
|
||||
'code' => $commandCode
|
||||
]);
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
# Check if commands were added successfully and have correct parameters
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($commandName, $object->data->command);
|
||||
$this->assertSame($commandDescription, $object->data->description);
|
||||
$this->assertSame($commandCode, $object->data->code);
|
||||
|
||||
# Check again that the command was added correctly
|
||||
$command = (new XiboCommand($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($commandName, $command->command);
|
||||
$this->assertSame($commandDescription, $command->description);
|
||||
$this->assertSame($commandCode, $command->code);
|
||||
# Clean up the commands as we no longer need it
|
||||
$this->assertTrue($command->delete(), 'Unable to delete ' . $command->commandId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (command name, description, code)
|
||||
* @return array
|
||||
*/
|
||||
|
||||
public function provideSuccessCases()
|
||||
{
|
||||
# Cases we provide to testAddSuccess, you can extend it by simply adding new case here
|
||||
return [
|
||||
'reboot' => ['test command', 'test description', 'reboot'],
|
||||
'binary' => ['test command 2', '|01100100|01100001|01101110|00001101', 'binary'],
|
||||
'sleep' => ['test command 3', 'test description', 'sleep'],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* testAddFailure - test adding various commands that should be invalid
|
||||
* @dataProvider provideFailureCases
|
||||
*/
|
||||
public function testAddFailure($commandName, $commandDescription, $commandCode)
|
||||
{
|
||||
# Add new commands with arguments from provideFailureCases
|
||||
$response = $this->sendRequest('POST','/command', [
|
||||
'command' => $commandName,
|
||||
'description' => $commandDescription,
|
||||
'code' => $commandCode
|
||||
]);
|
||||
# Check if commands are failing as expected
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (command name, description, code)
|
||||
* @return array
|
||||
*/
|
||||
|
||||
public function provideFailureCases()
|
||||
{
|
||||
# Cases we provide to testAddFailure, you can extend it by simply adding new case here
|
||||
return [
|
||||
'No code' => ['No code', 'aa', NULL],
|
||||
'Code with space' => ['Code with space', 'Code with space', 'Code with space'],
|
||||
'Code with symbol' => ['Code with symbol', 'Code with symbol', 'Codewithsymbol$$'],
|
||||
'No description' => ['no description', NULL, 'code'],
|
||||
'No Name' => [NULL, 'Bienvenue à la suite de tests Xibo', 'beep'],
|
||||
'Only Name' => ['Deutsch Prüfung 1', NULL, NULL],
|
||||
'Empty' => [NULL, NULL, NULL]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* List all commands known set
|
||||
* @group minimal
|
||||
* @depends testAddSuccess
|
||||
*/
|
||||
public function testListKnown()
|
||||
{
|
||||
$cases = $this->provideSuccessCases();
|
||||
$commands = [];
|
||||
// Check each possible case to ensure it's not pre-existing
|
||||
// If it is, skip over it
|
||||
foreach ($cases as $case) {
|
||||
$flag = true;
|
||||
foreach ($this->startCommands as $tmpCom) {
|
||||
if ($case[0] == $tmpCom->command) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
$commands[] = (new XiboCommand($this->getEntityProvider()))->create($case[0],$case[1],$case[2]);
|
||||
}
|
||||
}
|
||||
|
||||
$response = $this->sendRequest('GET','/command');
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
# There should be as many commands as we created plus the number we started with in the system
|
||||
$this->assertEquals(count($commands) + count($this->startCommands), $object->data->recordsTotal);
|
||||
# Clean up the groups we created
|
||||
foreach ($commands as $com) {
|
||||
$com->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing command
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
# Load in a known command
|
||||
/** @var XiboCommand $command */
|
||||
$command = (new XiboCommand($this->getEntityProvider()))->create('phpunit command', 'phpunit description', 'phpunitcode');
|
||||
# Generate new name and description
|
||||
$name = Random::generateString(8, 'command');
|
||||
$description = Random::generateString(8, 'description');
|
||||
# Change name and description of earlier created command
|
||||
$response = $this->sendRequest('PUT','/command/' . $command->commandId, [
|
||||
'command' => $name,
|
||||
'description' => $description,
|
||||
'code' => $command->code
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
# Examine the returned object and check that it's what we expect
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->command);
|
||||
$this->assertSame($description, $object->data->description);
|
||||
# Check that the command name and description were actually renamed
|
||||
$command = (new XiboCommand($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($name, $command->command);
|
||||
$this->assertSame($description, $command->description);
|
||||
# Clean up the Layout as we no longer need it
|
||||
$command->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete
|
||||
* @group minimal
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
# Generate random names
|
||||
$name1 = Random::generateString(8, 'phpunit');
|
||||
$name2 = Random::generateString(8, 'phpunit');
|
||||
# Load in a couple of known commands
|
||||
$command1 = (new XiboCommand($this->getEntityProvider()))->create($name1, 'phpunit description', 'code');
|
||||
$command2 = (new XiboCommand($this->getEntityProvider()))->create($name2, 'phpunit description', 'codetwo');
|
||||
# Delete the one we created last
|
||||
$response = $this->sendRequest('DELETE','/command/' . $command2->commandId);
|
||||
# This should return 204 for success
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Check only one remains
|
||||
$commands = (new XiboCommand($this->getEntityProvider()))->get();
|
||||
$this->assertEquals(count($this->startCommands) + 1, count($commands));
|
||||
$flag = false;
|
||||
foreach ($commands as $command) {
|
||||
if ($command->commandId == $command1->commandId) {
|
||||
$flag = true;
|
||||
}
|
||||
}
|
||||
$this->assertTrue($flag, 'Command ID ' . $command1->commandId . ' was not found after deleting a different command');
|
||||
# Clean up the first command as we no longer need it
|
||||
$command1->delete();
|
||||
}
|
||||
}
|
||||
161
tests/integration/DataSetRemoteTest.php
Normal file
161
tests/integration/DataSetRemoteTest.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2022 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSet;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Test remote datasets
|
||||
*/
|
||||
class DataSetRemoteTest extends LocalWebTestCase
|
||||
{
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboDataSet */
|
||||
private $dataSet;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
// copy json file to /web folder
|
||||
shell_exec('cp -r ' . PROJECT_ROOT . '/tests/resources/RemoteDataSet.json ' . PROJECT_ROOT . '/web');
|
||||
|
||||
$this->dataSet = (new XiboDataSet($this->getEntityProvider()))
|
||||
->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'',
|
||||
'remote',
|
||||
1,
|
||||
'GET',
|
||||
'http://localhost/RemoteDataSet.json',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
1,
|
||||
0,
|
||||
null,
|
||||
'data'
|
||||
);
|
||||
|
||||
// Add columns
|
||||
$this->dataSet->createColumn(
|
||||
'title',
|
||||
null,
|
||||
1,
|
||||
1,
|
||||
3,
|
||||
null,
|
||||
'title'
|
||||
);
|
||||
$this->dataSet->createColumn(
|
||||
'identifier',
|
||||
null,
|
||||
2,
|
||||
2,
|
||||
3,
|
||||
null,
|
||||
'id'
|
||||
);
|
||||
$this->dataSet->createColumn(
|
||||
'date',
|
||||
null,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
null,
|
||||
'Date'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the dataset
|
||||
$this->dataSet->deleteWData();
|
||||
|
||||
// remove json file from /web folder
|
||||
shell_exec('rm -r ' . PROJECT_ROOT . '/web/RemoteDataSet.json');
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testRemoteDataSetData()
|
||||
{
|
||||
// call the remote dataSet test
|
||||
$response = $this->sendRequest('POST', '/dataset/remote/test', [
|
||||
'testDataSetId' => $this->dataSet->dataSetId,
|
||||
'dataSet' => $this->dataSet->dataSet,
|
||||
'code' => 'remote',
|
||||
'isRemote' => 1,
|
||||
'method' => 'GET',
|
||||
'uri' => 'http://localhost/RemoteDataSet.json',
|
||||
'dataRoot' => 'data',
|
||||
'refreshRate' => 0,
|
||||
'clearRate' => 1,
|
||||
'sourceId' => 1,
|
||||
'limitPolicy' => 'stop'
|
||||
]);
|
||||
|
||||
// HTTP response code
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
// Expect a JSON body
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
// Data and ID parameters
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
// Make sure we have the same dataset back
|
||||
$this->assertSame($object->id, $this->dataSet->dataSetId);
|
||||
|
||||
// Make sure we parsed out some entries.
|
||||
$this->assertNotEmpty($object->data->entries);
|
||||
$this->assertNotEmpty($object->data->processed);
|
||||
|
||||
// The entries should match our sample file.
|
||||
$this->assertSame(3, $object->data->number);
|
||||
|
||||
// First record
|
||||
$this->assertSame(1, $object->data->processed[0][0]->identifier);
|
||||
$this->assertSame('Title 1', $object->data->processed[0][0]->title);
|
||||
$this->assertSame('2019-07-29 13:11:00', $object->data->processed[0][0]->date);
|
||||
|
||||
// Second record
|
||||
$this->assertSame(2, $object->data->processed[0][1]->identifier);
|
||||
$this->assertFalse(property_exists($object->data->processed[0][1], 'title'));
|
||||
$this->assertSame('2019-07-30 03:04:00', $object->data->processed[0][1]->date);
|
||||
|
||||
// Third record
|
||||
$this->assertSame(3, $object->data->processed[0][2]->identifier);
|
||||
$this->assertSame('1', $object->data->processed[0][2]->title);
|
||||
$this->assertFalse(property_exists($object->data->processed[0][2], 'date'));
|
||||
}
|
||||
}
|
||||
546
tests/integration/DataSetTest.php
Normal file
546
tests/integration/DataSetTest.php
Normal file
@@ -0,0 +1,546 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSet;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSetColumn;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSetRow;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class DataSetTest extends LocalWebTestCase
|
||||
{
|
||||
protected $startDataSets;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startDataSets = (new XiboDataSet($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all datasets that weren't there initially
|
||||
$finalDataSets = (new XiboDataSet($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
|
||||
$difference = array_udiff($finalDataSets, $this->startDataSets, function ($a, $b) {
|
||||
/** @var XiboDataSet $a */
|
||||
/** @var XiboDataSet $b */
|
||||
return $a->dataSetId - $b->dataSetId;
|
||||
});
|
||||
|
||||
# Loop over any remaining datasets and nuke them
|
||||
foreach ($difference as $dataSet) {
|
||||
/** @var XiboDataSet $dataSet */
|
||||
try {
|
||||
$dataSet->deleteWData();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $dataSet->dataSetId . '. E: ' . $e->getMessage() . PHP_EOL);
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/*
|
||||
* List all datasets
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/dataset');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group add
|
||||
*/
|
||||
public function testAdd()
|
||||
{
|
||||
# Generate random name
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
# Add dataset
|
||||
$response = $this->sendRequest('POST','/dataset', [
|
||||
'dataSet' => $name,
|
||||
'description' => 'PHP Unit Test'
|
||||
]);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Check if dataset has the correct name
|
||||
$this->assertSame($name, $object->data->dataSet);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test edit
|
||||
* @depends testAdd
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
# Create a new dataset
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create('phpunit dataset', 'phpunit description');
|
||||
# Generate new name and description
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = 'New description';
|
||||
# Edit the name and description
|
||||
$response = $this->sendRequest('PUT','/dataset/' . $dataSet->dataSetId, [
|
||||
'dataSet' => $name,
|
||||
'description' => $description
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
# Check if name and description were correctly changed
|
||||
$this->assertSame($name, $object->data->dataSet);
|
||||
$this->assertSame($description, $object->data->description);
|
||||
# Deeper check by querying for dataset again
|
||||
$dataSetCheck = (new XiboDataSet($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($name, $dataSetCheck->dataSet);
|
||||
$this->assertSame($description, $dataSetCheck->description);
|
||||
# Clean up the dataset as we no longer need it
|
||||
$dataSet->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testEdit
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
# Generate new random names
|
||||
$name1 = Random::generateString(8, 'phpunit');
|
||||
$name2 = Random::generateString(8, 'phpunit');
|
||||
# Load in a couple of known dataSets
|
||||
$data1 = (new XiboDataSet($this->getEntityProvider()))->create($name1, 'phpunit description');
|
||||
$data2 = (new XiboDataSet($this->getEntityProvider()))->create($name2, 'phpunit description');
|
||||
# Delete the one we created last
|
||||
$response = $this->sendRequest('DELETE','/dataset/' . $data2->dataSetId);
|
||||
# This should return 204 for success
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Check only one remains
|
||||
$dataSets = (new XiboDataSet($this->getEntityProvider()))->get();
|
||||
$this->assertEquals(count($this->startDataSets) + 1, count($dataSets));
|
||||
$flag = false;
|
||||
foreach ($dataSets as $dataSet) {
|
||||
if ($dataSet->dataSetId == $data1->dataSetId) {
|
||||
$flag = true;
|
||||
}
|
||||
}
|
||||
$this->assertTrue($flag, 'dataSet ID ' . $data1->dataSetId . ' was not found after deleting a different dataset');
|
||||
}
|
||||
|
||||
# TO DO /dataset/import/
|
||||
|
||||
/**
|
||||
* @dataProvider provideSuccessCases
|
||||
*/
|
||||
public function testAddColumnSuccess($columnName, $columnListContent, $columnOrd, $columnDataTypeId, $columnDataSetColumnTypeId, $columnFormula)
|
||||
{
|
||||
# Create radom name and description
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = 'PHP Unit column add';
|
||||
# Create new dataset
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create($name, $description);
|
||||
# Create new columns with arguments from provideSuccessCases
|
||||
$response = $this->sendRequest('POST','/dataset/' . $dataSet->dataSetId . '/column', [
|
||||
'heading' => $columnName,
|
||||
'listContent' => $columnListContent,
|
||||
'columnOrder' => $columnOrd,
|
||||
'dataTypeId' => $columnDataTypeId,
|
||||
'dataSetColumnTypeId' => $columnDataSetColumnTypeId,
|
||||
'formula' => $columnFormula
|
||||
]);
|
||||
# Check that call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
# Check that columns have correct parameters
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($columnName, $object->data->heading);
|
||||
$this->assertSame($columnListContent, $object->data->listContent);
|
||||
$this->assertSame($columnOrd, $object->data->columnOrder);
|
||||
$this->assertSame($columnDataTypeId, $object->data->dataTypeId);
|
||||
$this->assertSame($columnDataSetColumnTypeId, $object->data->dataSetColumnTypeId);
|
||||
$this->assertSame($columnFormula, $object->data->formula);
|
||||
# Check that column was correctly added
|
||||
$column = (new XiboDataSetColumn($this->getEntityProvider()))->getById($dataSet->dataSetId, $object->id);
|
||||
$this->assertSame($columnName, $column->heading);
|
||||
# Clean up the dataset as we no longer need it
|
||||
$this->assertTrue($dataSet->delete(), 'Unable to delete ' . $dataSet->dataSetId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($columnName, $columnListContent, $columnOrd, $columnDataTypeId, $columnDataSetColumnTypeId, $columnFormula)
|
||||
* @return array
|
||||
*/
|
||||
|
||||
public function provideSuccessCases()
|
||||
{
|
||||
# Cases we provide to testAddColumnSucess, you can extend it by simply adding new case here
|
||||
return [
|
||||
# Value
|
||||
'Value String' => ['Test Column Value String', NULL, 2, 1, 1, NULL],
|
||||
'List Content' => ['Test Column list content', 'one,two,three', 2, 1, 1, NULL],
|
||||
'Value Number' => ['Test Column Value Number', NULL, 2, 2, 1, NULL],
|
||||
'Value Date' => ['Test Column Value Date', NULL, 2, 3, 1, NULL],
|
||||
'External Image' => ['Test Column Value External Image', NULL, 2, 4, 1, NULL],
|
||||
'Library Image' => ['Test Column Value Internal Image', NULL, 2, 5, 1, NULL],
|
||||
# Formula
|
||||
'Formula' => ['Test Column Formula', NULL, 2, 5, 1, 'Where Name = Dan'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFailureCases
|
||||
*/
|
||||
public function testAddColumnFailure($columnName, $columnListContent, $columnOrd, $columnDataTypeId, $columnDataSetColumnTypeId, $columnFormula)
|
||||
{
|
||||
# Create random name and description
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = 'PHP Unit column add failure';
|
||||
# Create new columns that we expect to fail with arguments from provideFailureCases
|
||||
/** @var XiboDataSet $dataSet */
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create($name, $description);
|
||||
$response = $this->sendRequest('POST','/dataset/' . $dataSet->dataSetId . '/column', [
|
||||
'heading' => $columnName,
|
||||
'listContent' => $columnListContent,
|
||||
'columnOrder' => $columnOrd,
|
||||
'dataTypeId' => $columnDataTypeId,
|
||||
'dataSetColumnTypeId' => $columnDataSetColumnTypeId,
|
||||
'formula' => $columnFormula
|
||||
]);
|
||||
# Check if cases are failing as expected
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($columnName, $columnListContent, $columnOrd, $columnDataTypeId, $columnDataSetColumnTypeId, $columnFormula)
|
||||
* @return array
|
||||
*/
|
||||
|
||||
public function provideFailureCases()
|
||||
{
|
||||
# Cases we provide to testAddColumnFailure, you can extend it by simply adding new case here
|
||||
return [
|
||||
// Value
|
||||
'Incorrect dataType' => ['incorrect data type', NULL, 2, 12, 1, NULL],
|
||||
'Incorrect columnType' => ['incorrect column type', NULL, 2, 19, 1, NULL],
|
||||
'Empty Name' => [NULL, NULL, 2, 3, 1, NULL],
|
||||
'Symbol Name' => ['a.b.c', NULL, 2, 3, 1, NULL],
|
||||
'Symbol Name 2' => ['$£"', NULL, 2, 3, 1, NULL]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Search columns for DataSet
|
||||
*/
|
||||
public function testListAllColumns()
|
||||
{
|
||||
# Create new dataSet
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = 'PHP Unit column list';
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create($name, $description);
|
||||
# Add a new column to our dataset
|
||||
$nameCol = Random::generateString(8, 'phpunit');
|
||||
$dataSet->createColumn($nameCol,'', 2, 1, 1, '');
|
||||
# Search for columns
|
||||
$response = $this->sendRequest('GET','/dataset/' . $dataSet->dataSetId . '/column');
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
# Clean up as we no longer need it
|
||||
$dataSet->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test edit column
|
||||
*/
|
||||
public function testColumnEdit()
|
||||
{
|
||||
# Create dataSet
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = 'PHP Unit column edit';
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create($name, $description);
|
||||
# Add new column to our dataset
|
||||
$nameCol = Random::generateString(8, 'phpunit');
|
||||
$column = (new XiboDataSetColumn($this->getEntityProvider()))->create($dataSet->dataSetId, $nameCol,'', 2, 1, 1, '');
|
||||
# Generate new random name
|
||||
$nameNew = Random::generateString(8, 'phpunit');
|
||||
# Edit our column and change the name
|
||||
$response = $this->sendRequest('PUT','/dataset/' . $dataSet->dataSetId . '/column/' . $column->dataSetColumnId, [
|
||||
'heading' => $nameNew,
|
||||
'listContent' => '',
|
||||
'columnOrder' => $column->columnOrder,
|
||||
'dataTypeId' => $column->dataTypeId,
|
||||
'dataSetColumnTypeId' => $column->dataSetColumnTypeId,
|
||||
'formula' => ''
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Check if our column has updated name
|
||||
$this->assertSame($nameNew, $object->data->heading);
|
||||
# Clean up as we no longer need it
|
||||
$dataSet->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $dataSetId
|
||||
* @depends testAddColumnSuccess
|
||||
*/
|
||||
public function testDeleteColumn()
|
||||
{
|
||||
# Create dataSet
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = 'PHP Unit column delete';
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create($name, $description);
|
||||
# Add new column to our dataset
|
||||
$nameCol = Random::generateString(8, 'phpunit');
|
||||
$column = (new XiboDataSetColumn($this->getEntityProvider()))->create($dataSet->dataSetId, $nameCol,'', 2, 1, 1, '');
|
||||
# delete column
|
||||
$response = $this->sendRequest('DELETE','/dataset/' . $dataSet->dataSetId . '/column/' . $column->dataSetColumnId);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
}
|
||||
|
||||
/*
|
||||
* GET data
|
||||
*/
|
||||
|
||||
public function testGetData()
|
||||
{
|
||||
# Create dataSet
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = 'PHP Unit';
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create($name, $description);
|
||||
# Call get data
|
||||
$response = $this->sendRequest('GET','/dataset/data/' . $dataSet->dataSetId);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
# Clean up
|
||||
$dataSet->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add row
|
||||
*/
|
||||
public function testRowAdd()
|
||||
{
|
||||
# Create a new dataset to use
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = 'PHP Unit row add';
|
||||
/** @var XiboDataSet $dataSet */
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create($name, $description);
|
||||
# Create column and add it to our dataset
|
||||
$nameCol = Random::generateString(8, 'phpunit');
|
||||
$column = (new XiboDataSetColumn($this->getEntityProvider()))->create($dataSet->dataSetId, $nameCol,'', 2, 1, 1, '');
|
||||
# Add new row to our dataset and column
|
||||
$response = $this->sendRequest('POST','/dataset/data/' . $dataSet->dataSetId, [
|
||||
'dataSetColumnId_' . $column->dataSetColumnId => 'test',
|
||||
]);
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Get the row id
|
||||
$row = $dataSet->getData();
|
||||
$this->getLogger()->debug(json_encode($row));
|
||||
# Check if data was correctly added to the row
|
||||
$this->assertArrayHasKey($nameCol, $row[0]);
|
||||
$this->assertSame($row[0][$nameCol], 'test');
|
||||
# Clean up as we no longer need it, deleteWData will delete dataset even if it has data assigned to it
|
||||
$dataSet->deleteWData();
|
||||
}
|
||||
/**
|
||||
* Test edit row
|
||||
* @dataProvider provideSuccessCasesRow
|
||||
*/
|
||||
public function testRowEdit($data)
|
||||
{
|
||||
# Create a new dataset to use
|
||||
/** @var XiboDataSet $dataSet */
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = 'PHP Unit row edit';
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create($name, $description);
|
||||
# Generate a new name for the new column
|
||||
$nameCol = Random::generateString(8, 'phpunit');
|
||||
# Create new column and add it to our dataset
|
||||
$column = (new XiboDataSetColumn($this->getEntityProvider()))->create($dataSet->dataSetId, $nameCol,'', 2, 1, 1, '');
|
||||
# Add new row with data to our dataset
|
||||
$rowD = 'test';
|
||||
$row = (new XiboDataSetRow($this->getEntityProvider()))->create($dataSet->dataSetId, $column->dataSetColumnId, $rowD);
|
||||
# Edit row data
|
||||
$response = $this->sendRequest('PUT','/dataset/data/' . $dataSet->dataSetId . '/' . $row['id'], [
|
||||
'dataSetColumnId_' . $column->dataSetColumnId => $data
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# get the row id
|
||||
$rowCheck = $dataSet->getData();
|
||||
# Check if data was correctly added to the row
|
||||
$this->assertArrayHasKey($nameCol, $rowCheck[0]);
|
||||
if ($data == Null){
|
||||
$this->assertSame($rowCheck[0][$nameCol], $rowD);
|
||||
}
|
||||
else {
|
||||
$this->assertSame($rowCheck[0][$nameCol], $data);
|
||||
}
|
||||
|
||||
# Clean up as we no longer need it, deleteWData will delete dataset even if it has data assigned to it
|
||||
$dataSet->deleteWData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($data)
|
||||
* @return array
|
||||
*/
|
||||
|
||||
public function provideSuccessCasesRow()
|
||||
{
|
||||
# Cases we provide to testRowEdit, you can extend it by simply adding new case here
|
||||
return [
|
||||
# Value
|
||||
'String' => ['API EDITED ROW'],
|
||||
'Null' => [NULL],
|
||||
'number as string' => ['1212']
|
||||
];
|
||||
}
|
||||
|
||||
/*
|
||||
* delete row data
|
||||
*/
|
||||
public function testRowDelete()
|
||||
{
|
||||
# Create a new dataset to use
|
||||
/** @var XiboDataSet $dataSet */
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = 'PHP Unit row delete';
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create($name, $description);
|
||||
# Generate a new name for the new column
|
||||
$nameCol = Random::generateString(8, 'phpunit');
|
||||
# Create new column and add it to our dataset
|
||||
$column = (new XiboDataSetColumn($this->getEntityProvider()))->create($dataSet->dataSetId, $nameCol,'', 2, 1, 1, '');
|
||||
# Add new row data
|
||||
$row = (new XiboDataSetRow($this->getEntityProvider()))->create($dataSet->dataSetId, $column->dataSetColumnId, 'Row Data');
|
||||
# Delete row
|
||||
$response = $this->sendRequest('DELETE','/dataset/data/' . $dataSet->dataSetId . '/' . $row['id']);
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up as we no longer need it, deleteWData will delete dataset even if it has data assigned to it
|
||||
$dataSet->deleteWData();
|
||||
}
|
||||
|
||||
public function testAddRemoteDataSet()
|
||||
{
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
# Add dataset
|
||||
$response = $this->sendRequest('POST','/dataset', [
|
||||
'dataSet' => $name,
|
||||
'code' => 'remote',
|
||||
'isRemote' => 1,
|
||||
'method' => 'GET',
|
||||
'uri' => 'http://localhost/resources/RemoteDataSet.json',
|
||||
'dataRoot' => 'data',
|
||||
'refreshRate' => 0,
|
||||
'clearRate' => 1,
|
||||
'sourceId' => 1,
|
||||
'limitPolicy' => 'stop'
|
||||
]);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
# Check dataSet object
|
||||
$this->assertSame($name, $object->data->dataSet);
|
||||
$this->assertSame(1, $object->data->isRemote);
|
||||
$this->assertSame('http://localhost/resources/RemoteDataSet.json', $object->data->uri);
|
||||
$this->assertSame(1, $object->data->clearRate);
|
||||
$this->assertSame(0, $object->data->refreshRate);
|
||||
$this->assertSame(0, $object->data->lastClear);
|
||||
$this->assertSame(1, $object->data->sourceId);
|
||||
}
|
||||
|
||||
public function testEditRemoteDataSet()
|
||||
{
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$name2 = Random::generateString(8, 'phpunit');
|
||||
|
||||
// add DataSet with wrapper
|
||||
$dataSet = (new XiboDataSet($this->getEntityProvider()))->create($name, '', 'remote', 1, 'GET', 'http://localhost/resources/RemoteDataSet.json', '', '', '', '', 1, 0, null, 'data');
|
||||
|
||||
// Edit DataSet
|
||||
$response = $this->sendRequest('PUT','/dataset/' . $dataSet->dataSetId, [
|
||||
'dataSet' => $name2,
|
||||
'code' => 'remote',
|
||||
'isRemote' => 1,
|
||||
'method' => 'GET',
|
||||
'uri' => 'http://localhost/resources/RemoteDataSet.json',
|
||||
'dataRoot' => 'data',
|
||||
'clearRate' => 3600,
|
||||
'refreshRate' => 1,
|
||||
'sourceId' => 1,
|
||||
'limitPolicy' => 'stop'
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
# Check dataSet object
|
||||
$this->assertSame($name2, $object->data->dataSet);
|
||||
$this->assertSame(1, $object->data->isRemote);
|
||||
$this->assertSame('http://localhost/resources/RemoteDataSet.json', $object->data->uri);
|
||||
$this->assertSame(3600, $object->data->clearRate);
|
||||
$this->assertSame(1, $object->data->refreshRate);
|
||||
$this->assertSame(1, $object->data->sourceId);
|
||||
}
|
||||
}
|
||||
223
tests/integration/DaypartTest.php
Normal file
223
tests/integration/DaypartTest.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDaypart;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DaypartTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
|
||||
class DaypartTest extends LocalWebTestCase
|
||||
{
|
||||
/** @var XiboDaypart[] */
|
||||
protected $startDayparts;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startDayparts = (new XiboDaypart($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
|
||||
$this->getLogger()->debug('There are ' . count($this->startDayparts) . ' dayparts at the start of the test');
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all dayparts that weren't there initially
|
||||
$finalDayparts = (new XiboDaypart($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining dayparts and nuke them
|
||||
foreach ($finalDayparts as $daypart) {
|
||||
/** @var XiboDaypart $daypart */
|
||||
$flag = true;
|
||||
foreach ($this->startDayparts as $startDaypart) {
|
||||
if ($startDaypart->dayPartId == $daypart->dayPartId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$daypart->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $daypart->dayPartId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddSuccess - test adding various daypart that should be valid
|
||||
* @dataProvider provideSuccessCases
|
||||
*/
|
||||
public function testAddSuccess($name, $description, $startTime, $endTime, $exceptionDays, $exceptionStartTimes, $exceptionEndTimes)
|
||||
{
|
||||
# Create daypart with arguments from provideSuccessCases
|
||||
$response = $this->sendRequest('POST','/daypart', [
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'startTime' => $startTime,
|
||||
'endTime' => $endTime,
|
||||
'exceptionDays' => $exceptionDays,
|
||||
'exceptionStartTimes' => $exceptionStartTimes,
|
||||
'exceptionEndTimes' => $exceptionEndTimes
|
||||
]);
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
$this->assertSame($description, $object->data->description);
|
||||
# Check that the daypart was really added
|
||||
$dayparts = (new XiboDaypart($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->assertEquals(count($this->startDayparts) + 1, count($dayparts));
|
||||
# Check that the daypart was added correctly
|
||||
$daypart = (new XiboDaypart($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($name, $daypart->name);
|
||||
$this->assertSame($description, $daypart->description);
|
||||
# Clean up the daypart as we no longer need it
|
||||
$this->assertTrue($daypart->delete(), 'Unable to delete ' . $daypart->dayPartId);
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddFailure - test adding various daypart that should be invalid
|
||||
* @dataProvider provideFailureCases
|
||||
*/
|
||||
public function testAddFailure($name, $description, $startTime, $endTime, $exceptionDays, $exceptionStartTimes, $exceptionEndTimes)
|
||||
{
|
||||
# Create daypart with arguments from provideFailureCases
|
||||
$response = $this->sendRequest('POST','/daypart', [
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'startTime' => $startTime,
|
||||
'endTime' => $endTime,
|
||||
'exceptionDays' => $exceptionDays,
|
||||
'exceptionStartTimes' => $exceptionStartTimes,
|
||||
'exceptionEndTimes' => $exceptionEndTimes
|
||||
]);
|
||||
# check if they fail as expected
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($name, $description, $startTime, $endTime, $exceptionDays, $exceptionStartTimes, $exceptionEndTimes)
|
||||
* @return array
|
||||
*/
|
||||
public function provideSuccessCases()
|
||||
{
|
||||
# Data for testAddSuccess, easily expandable - just add another set of data below
|
||||
return [
|
||||
'No exceptions' => ['phpunit daypart', 'API', '02:00', '06:00', NULL, NULL, NULL],
|
||||
'Except Monday' => ['phpunit daypart exception', NULL, '02:00', '06:00', ['Monday'], ['00:01'], ['23:59']]
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($name, $description, $startTime, $endTime, $exceptionDays, $exceptionStartTimes, $exceptionEndTimes)
|
||||
* @return array
|
||||
*/
|
||||
public function provideFailureCases()
|
||||
{
|
||||
# Data for testAddfailure, easily expandable - just add another set of data below
|
||||
// TODO we should probably validate description and day names in daypart Controller.
|
||||
return [
|
||||
'Empty title' => [NULL, 'should be invalid', '07:00', '10:00', NULL, NULL, NULL],
|
||||
//'Description over 254 characters' => ['Too long description', Random::generateString(258), '07:00', '10:00', NULL, NULL, NULL],
|
||||
'Wrong time data type' => ['Time as integer','should be incorrect', 21, 22, NULL, NULL, NULL],
|
||||
//'Wrong day name' => ['phpunit daypart exception', NULL, '02:00', '06:00', ['Cabbage'], ['00:01'], ['23:59']]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing daypart
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
#Create new daypart
|
||||
$daypart = (new XiboDaypart($this->getEntityProvider()))->create('phpunit daypart', 'API', '02:00', '06:00', NULL, NULL, NULL);
|
||||
# Change the daypart name and description
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = Random::generateString(8, 'description');
|
||||
$response = $this->sendRequest('PUT','/daypart/' . $daypart->dayPartId, [
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'startTime' => '02:00',
|
||||
'endTime' => '06:00',
|
||||
'exceptionDays' => $daypart->exceptionDays,
|
||||
'exceptionStartTimes' => $daypart->exceptionStartTimes,
|
||||
'exceptionEndTimes' => $daypart->exceptionEndTimes
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
# Examine the returned object and check that it's what we expect
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
$this->assertSame($description, $object->data->description);
|
||||
# Check that the daypart was actually renamed
|
||||
$daypart = (new XiboDaypart($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($name, $daypart->name);
|
||||
$this->assertSame($description, $daypart->description);
|
||||
# Clean up the Daypart as we no longer need it
|
||||
$daypart->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete
|
||||
* @group minimal
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
$name1 = Random::generateString(8, 'phpunit');
|
||||
$name2 = Random::generateString(8, 'phpunit');
|
||||
# Load in a couple of known Dayparts
|
||||
$daypart1 = (new XiboDaypart($this->getEntityProvider()))->create($name1, 'API', '02:00', '06:00', NULL, NULL, NULL);
|
||||
$daypart2 = (new XiboDaypart($this->getEntityProvider()))->create($name2, 'API', '12:00', '16:00', NULL, NULL, NULL);
|
||||
# Delete the one we created last
|
||||
$response = $this->sendRequest('DELETE','/daypart/' . $daypart2->dayPartId);
|
||||
# This should return 204 for success
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Check only one remains
|
||||
$dayparts = (new XiboDaypart($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->assertEquals(count($this->startDayparts) + 1, count($dayparts));
|
||||
$flag = false;
|
||||
foreach ($dayparts as $daypart) {
|
||||
if ($daypart->dayPartId == $daypart1->dayPartId) {
|
||||
$flag = true;
|
||||
}
|
||||
}
|
||||
$this->assertTrue($flag, 'Daypart ID ' . $daypart1->dayPartId . ' was not found after deleting a different daypart');
|
||||
$daypart1->delete();
|
||||
}
|
||||
}
|
||||
138
tests/integration/DisplayGroupCopyTest.php
Normal file
138
tests/integration/DisplayGroupCopyTest.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayGroup;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Tests copying a display group.
|
||||
*/
|
||||
class DisplayGroupCopyTest extends LocalWebTestCase
|
||||
{
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboDisplayGroup */
|
||||
protected $displayGroup;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for Cache ' . get_class($this) . ' Test');
|
||||
|
||||
// Create a couple of displays to use in the test
|
||||
$this->display = $this->createDisplay();
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// Create a display group and assign both displays
|
||||
$this->displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create(
|
||||
'phpunit_' . bin2hex(random_bytes(4)),
|
||||
'',
|
||||
0,
|
||||
null
|
||||
);
|
||||
|
||||
// Assign our two displays
|
||||
$this->displayGroup->assignDisplay($this->display->displayId);
|
||||
$this->displayGroup->assignDisplay($this->display2->displayId);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
$this->deleteDisplay($this->display2);
|
||||
$this->displayGroup->delete();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
public function testCopyPlain()
|
||||
{
|
||||
$response = $this->sendRequest('POST', '/displaygroup/' . $this->displayGroup->displayGroupId . '/copy', [
|
||||
'displayGroup' => 'phpunit_' . bin2hex(random_bytes(4)),
|
||||
'description' => 'copied',
|
||||
'copyMembers' => 0,
|
||||
'copyAssignments' => 0,
|
||||
'copyTags' => 0,
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame('copied', $object->data->description);
|
||||
|
||||
// Check there aren't any displays assigned.
|
||||
$results = $this->getStore()->select('SELECT COUNT(*) AS cnt FROM lkdisplaydg WHERE displayGroupId = :displayGroupId', [
|
||||
'displayGroupId' => $object->id
|
||||
]);
|
||||
|
||||
$this->assertEquals(0, intval($results[0]['cnt']));
|
||||
|
||||
(new XiboDisplayGroup($this->getEntityProvider()))->getById($object->id)->delete();
|
||||
}
|
||||
|
||||
public function testCopyMembers()
|
||||
{
|
||||
$response = $this->sendRequest('POST', '/displaygroup/' . $this->displayGroup->displayGroupId . '/copy', [
|
||||
'displayGroup' => 'phpunit_' . bin2hex(random_bytes(4)),
|
||||
'description' => 'copied',
|
||||
'copyMembers' => 1,
|
||||
'copyAssignments' => 0,
|
||||
'copyTags' => 0,
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame('copied', $object->data->description);
|
||||
|
||||
// Check there aren't any displays assigned.
|
||||
$results = $this->getStore()->select('SELECT COUNT(*) AS cnt FROM lkdisplaydg WHERE displayGroupId = :displayGroupId', [
|
||||
'displayGroupId' => $object->id
|
||||
]);
|
||||
|
||||
$this->assertEquals(2, intval($results[0]['cnt']));
|
||||
|
||||
(new XiboDisplayGroup($this->getEntityProvider()))->getById($object->id)->delete();
|
||||
}
|
||||
}
|
||||
899
tests/integration/DisplayGroupTest.php
Normal file
899
tests/integration/DisplayGroupTest.php
Normal file
@@ -0,0 +1,899 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCommand;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayGroup;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DisplayGroupTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class DisplayGroupTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
protected $startDisplayGroups;
|
||||
protected $startDisplays;
|
||||
protected $startLayouts;
|
||||
protected $startCommands;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startDisplayGroups = (new XiboDisplayGroup($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->startDisplays = (new XiboDisplay($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->startLayouts = (new XiboLayout($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->startCommands = (new XiboCommand($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all display groups that weren't there initially
|
||||
$finalDisplayGroups = (new XiboDisplayGroup($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
|
||||
# Loop over any remaining display groups and nuke them
|
||||
foreach ($finalDisplayGroups as $displayGroup) {
|
||||
/** @var XiboDisplayGroup $displayGroup */
|
||||
|
||||
$flag = true;
|
||||
|
||||
foreach ($this->startDisplayGroups as $startGroup) {
|
||||
if ($startGroup->displayGroupId == $displayGroup->displayGroupId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($flag) {
|
||||
try {
|
||||
$displayGroup->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $displayGroup->displayGroupId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tear down any displays that weren't there before
|
||||
$finalDisplays = (new XiboDisplay($this->getEntityProvider()))->get();
|
||||
|
||||
# Loop over any remaining displays and nuke them
|
||||
foreach ($finalDisplays as $display) {
|
||||
/** @var XiboDisplay $display */
|
||||
|
||||
$flag = true;
|
||||
|
||||
foreach ($this->startDisplays as $startDisplay) {
|
||||
if ($startDisplay->displayId == $display->displayId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($flag) {
|
||||
try {
|
||||
$display->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $display->displayId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tearDown all layouts that weren't there initially
|
||||
$finalLayouts = (new XiboLayout($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining layouts and nuke them
|
||||
foreach ($finalLayouts as $layout) {
|
||||
/** @var XiboLayout $layout */
|
||||
$flag = true;
|
||||
foreach ($this->startLayouts as $startLayout) {
|
||||
if ($startLayout->layoutId == $layout->layoutId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$layout->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $layout->layoutId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tearDown all commands that weren't there initially
|
||||
$finalCommands = (new XiboCommand($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining commands and nuke them
|
||||
foreach ($finalCommands as $command) {
|
||||
/** @var XiboCommand $command */
|
||||
$flag = true;
|
||||
foreach ($this->startCommands as $startCom) {
|
||||
if ($startCom->commandId == $command->commandId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$command->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $command->commandId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* List all display groups known empty
|
||||
* @group minimal
|
||||
* @group destructive
|
||||
*/
|
||||
public function testListEmpty()
|
||||
{
|
||||
if (count($this->startDisplayGroups) > 0) {
|
||||
$this->skipTest("There are pre-existing DisplayGroups");
|
||||
return;
|
||||
}
|
||||
$response = $this->sendRequest('GET','/displaygroup');
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
# There should be no DisplayGroups in the system
|
||||
$this->assertEquals(0, $object->data->recordsTotal);
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddSuccess - test adding various Display Groups that should be valid
|
||||
* @dataProvider provideSuccessCases
|
||||
* @group minimal
|
||||
*/
|
||||
public function testAddSuccess($groupName, $groupDescription, $isDynamic, $expectedDynamic, $dynamicCriteria, $expectedDynamicCriteria)
|
||||
{
|
||||
// Loop through any pre-existing DisplayGroups to make sure we're not
|
||||
// going to get a clash
|
||||
|
||||
foreach ($this->startDisplayGroups as $tmpGroup) {
|
||||
if ($tmpGroup->displayGroup == $groupName) {
|
||||
$this->skipTest("There is a pre-existing DisplayGroup with this name");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$response = $this->sendRequest('POST','/displaygroup', [
|
||||
'displayGroup' => $groupName,
|
||||
'description' => $groupDescription,
|
||||
'isDynamic' => $isDynamic,
|
||||
'dynamicCriteria' => $dynamicCriteria
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($groupName, $object->data->displayGroup);
|
||||
$this->assertSame($groupDescription, $object->data->description);
|
||||
$this->assertSame($expectedDynamic, $object->data->isDynamic);
|
||||
$this->assertSame($expectedDynamicCriteria, $object->data->dynamicCriteria);
|
||||
# Check that the group was really added
|
||||
$displayGroups = (new XiboDisplayGroup($this->getEntityProvider()))->get(['length' => 1000]);
|
||||
$this->assertEquals(count($this->startDisplayGroups) + 1, count($displayGroups));
|
||||
# Check that the group was added correctly
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($groupName, $displayGroup->displayGroup);
|
||||
$this->assertSame($groupDescription, $displayGroup->description);
|
||||
$this->assertSame($expectedDynamic, $displayGroup->isDynamic);
|
||||
$this->assertSame($expectedDynamicCriteria, $displayGroup->dynamicCriteria);
|
||||
# Clean up the DisplayGroup as we no longer need it
|
||||
$this->assertTrue($displayGroup->delete(), 'Unable to delete ' . $displayGroup->displayGroupId);
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddFailure - test adding various Display Groups that should be invalid
|
||||
* @dataProvider provideFailureCases
|
||||
* @group minimal
|
||||
*/
|
||||
public function testAddFailure($groupName, $groupDescription, $isDynamic, $dynamicCriteria)
|
||||
{
|
||||
$response = $this->sendRequest('POST','/displaygroup', [
|
||||
'displayGroup' => $groupName,
|
||||
'description' => $groupDescription,
|
||||
'isDynamic' => $isDynamic,
|
||||
'dynamicCriteria' => $dynamicCriteria
|
||||
]);
|
||||
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* List all display groups known set
|
||||
* @group minimal
|
||||
* @depends testAddSuccess
|
||||
*/
|
||||
public function testListKnown()
|
||||
{
|
||||
# Load in a known set of display groups
|
||||
# We can assume this works since we depend upon the test which
|
||||
# has previously added and removed these without issue:
|
||||
$cases = $this->provideSuccessCases();
|
||||
$displayGroups = [];
|
||||
// Check each possible case to ensure it's not pre-existing
|
||||
// If it is, skip over it
|
||||
foreach ($cases as $case) {
|
||||
$flag = true;
|
||||
|
||||
foreach ($this->startDisplayGroups as $tmpGroup) {
|
||||
if ($case[0] == $tmpGroup->displayGroup) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($flag) {
|
||||
$displayGroups[] = (new XiboDisplayGroup($this->getEntityProvider()))->create($case[0],$case[1],$case[2],$case[3]);
|
||||
}
|
||||
}
|
||||
|
||||
$response = $this->sendRequest('GET','/displaygroup');
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
# There should be as many groups as we created plus the number we started with in the system
|
||||
$this->assertEquals(count($displayGroups) + count($this->startDisplayGroups), $object->data->recordsTotal);
|
||||
# Clean up the groups we created
|
||||
foreach ($displayGroups as $group) {
|
||||
$group->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List specific display groups
|
||||
* @group minimal
|
||||
* @group destructive
|
||||
* @depends testListKnown
|
||||
* @depends testAddSuccess
|
||||
* @dataProvider provideSuccessCases
|
||||
*/
|
||||
public function testListFilter($groupName, $groupDescription, $isDynamic, $expectedDynamic, $dynamicCriteria, $expectedDynamicCriteria)
|
||||
{
|
||||
if (count($this->startDisplayGroups) > 0) {
|
||||
$this->skipTest("There are pre-existing DisplayGroups");
|
||||
return;
|
||||
}
|
||||
# Load in a known set of display groups
|
||||
# We can assume this works since we depend upon the test which
|
||||
# has previously added and removed these without issue:
|
||||
$cases = $this->provideSuccessCases();
|
||||
$displayGroups = [];
|
||||
foreach ($cases as $case) {
|
||||
$displayGroups[] = (new XiboDisplayGroup($this->getEntityProvider()))->create($case[0], $case[1], $case[2], $case[3]);
|
||||
}
|
||||
$response = $this->sendRequest('GET','/displaygroup', [
|
||||
'displayGroup' => $groupName
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
# There should be at least one match
|
||||
$this->assertGreaterThanOrEqual(1, $object->data->recordsTotal);
|
||||
$flag = false;
|
||||
# Check that for the records returned, $groupName is in the groups names
|
||||
foreach ($object->data->data as $group) {
|
||||
if (strpos($groupName, $group->displayGroup) == 0) {
|
||||
$flag = true;
|
||||
}
|
||||
else {
|
||||
// The object we got wasn't the exact one we searched for
|
||||
// Make sure all the words we searched for are in the result
|
||||
foreach (array_map('trim',explode(",",$groupName)) as $word) {
|
||||
assertTrue((strpos($word, $group->displayGroup) !== false), 'Group returned did not match the query string: ' . $group->displayGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertTrue($flag, 'Search term not found');
|
||||
|
||||
foreach ($displayGroups as $group) {
|
||||
$group->delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format
|
||||
* (Group Name, Group Description, isDynamic, Returned isDynamic (0 or 1),
|
||||
* Criteria for Dynamic group, Returned Criteria for Dynamic group)
|
||||
* For example, if you set isDynamic to 0 and send criteria, it will come back
|
||||
* with criteria = null
|
||||
* These are reused in other tests so please ensure Group Name is unique
|
||||
* through the dataset
|
||||
* @return array
|
||||
*/
|
||||
public function provideSuccessCases()
|
||||
{
|
||||
|
||||
return [
|
||||
// Multi-language non-dynamic groups
|
||||
'English 1' => ['phpunit test group', 'Api', 0, 0, null, null],
|
||||
'English 2' => ['another phpunit test group', 'Api', 0, 0, null, null],
|
||||
'French 1' => ['Test de Français 1', 'Bienvenue à la suite de tests Xibo', 0, 0, null, null],
|
||||
'German 1' => ['Deutsch Prüfung 1', 'Weiß mit schwarzem Text', 0, 0, null, null],
|
||||
'Simplified Chinese 1' => ['试验组', '测试组描述', 0, 0, null, null],
|
||||
// Multi-language dynamic groups
|
||||
'English Dynamic 1' => ['phpunit test dynamic group', 'Api', 1, 1, 'test', 'test'],
|
||||
'French Dynamic 1' => ['Test de Français 2', 'Bienvenue à la suite de tests Xibo', 1, 1, 'test', 'test'],
|
||||
'German Dynamic 1' => ['Deutsch Prüfung 2', 'Weiß mit schwarzem Text', 1, 1, 'test', 'test'],
|
||||
// Tests for the various allowed values for isDynamic = 1
|
||||
'isDynamic on' => ['phpunit group dynamic is on', 'Api', 'on', 1, 'test', 'test'],
|
||||
'isDynamic true' => ['phpunit group dynamic is true', 'Api', 'true', 1, 'test', 'test'],
|
||||
// Invalid isDynamic flag (the CMS sanitises these for us to false)
|
||||
'isDynamic is 7 null criteria' => ['Invalid isDynamic flag 1', 'Invalid isDynamic flag', 7, 0, null, null],
|
||||
'isDynamic is 7 with criteria' => ['Invalid isDynamic flag 2 ', 'Invalid isDynamic flag', 7, 0, 'criteria', 'criteria'],
|
||||
'isDynamic is invalid null criteria' => ['Invalid isDynamic flag alpha 1', 'Invalid isDynamic flag alpha', 'invalid', 0, null, null],
|
||||
'isDynamic is invalid with criteria' => ['Invalid isDynamic flag alpha 2', 'Invalid isDynamic flag alpha', 'invalid', 0, 'criteria', 'criteria']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format
|
||||
* (Group Name, Group Description, isDynamic, Criteria for Dynamic group)
|
||||
* @return array
|
||||
*/
|
||||
public function provideFailureCases()
|
||||
{
|
||||
|
||||
return [
|
||||
// Description is limited to 255 characters
|
||||
'Description over 254 characters' => ['Too long description', Random::generateString(255), 0, null],
|
||||
// If isDynamic = 1 then criteria must be set
|
||||
'No dynamicCriteria on dynamic group' => ['No dynamic criteria', 'No dynamic criteria', 1, null],
|
||||
// Missing group names
|
||||
'Group name empty' => ['', 'Group name is empty', 0, null],
|
||||
'Group name null' => [null, 'Group name is null', 0, null]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Try and add two display groups with the same name
|
||||
* @group minimal
|
||||
* @depends testAddSuccess
|
||||
*/
|
||||
public function testAddDuplicate()
|
||||
{
|
||||
$flag = true;
|
||||
foreach ($this->startDisplayGroups as $group) {
|
||||
if ($group->displayGroup == 'phpunit displaygroup') {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
# Load in a known display group if it's not there already
|
||||
if ($flag) {
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create('phpunit displaygroup', 'phpunit displaygroup', 0, '');
|
||||
}
|
||||
|
||||
$response = $this->sendRequest('POST','/displaygroup', [
|
||||
'displayGroup' => 'phpunit displaygroup',
|
||||
'description' => 'phpunit displaygroup',
|
||||
'isDynamic' => 0,
|
||||
'dynamicCriteria' => ''
|
||||
]);
|
||||
|
||||
$this->assertSame(409, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode());
|
||||
$displayGroup->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing display group
|
||||
* @depends testAddSuccess
|
||||
* @group minimal
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
foreach ($this->startDisplayGroups as $group) {
|
||||
if ($group->displayGroup == 'phpunit displaygroup') {
|
||||
$this->skipTest('displayGroup already exists with that name');
|
||||
return;
|
||||
}
|
||||
}
|
||||
# Load in a known display group
|
||||
/** @var XiboDisplayGroup $displayGroup */
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create('phpunit displaygroup', 'phpunit displaygroup', 0, '');
|
||||
# Change the group name and description
|
||||
# Change it to a dynamic group with a fixed criteria
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = Random::generateString(8, 'description');
|
||||
$criteria = 'test';
|
||||
|
||||
$response = $this->sendRequest('PUT','/displaygroup/' . $displayGroup->displayGroupId, [
|
||||
'displayGroup' => $name,
|
||||
'description' => $description,
|
||||
'isDynamic' => 1,
|
||||
'dynamicCriteria' => $criteria
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
# Examine the returned object and check that it's what we expect
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->displayGroup);
|
||||
$this->assertSame($description, $object->data->description);
|
||||
$this->assertSame(1, $object->data->isDynamic);
|
||||
$this->assertSame($criteria, $object->data->dynamicCriteria);
|
||||
# Check that the group was actually renamed
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($name, $displayGroup->displayGroup);
|
||||
$this->assertSame($description, $displayGroup->description);
|
||||
$this->assertSame(1, $displayGroup->isDynamic);
|
||||
$this->assertSame($criteria, $displayGroup->dynamicCriteria);
|
||||
# Clean up the DisplayGroup as we no longer need it
|
||||
$displayGroup->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete
|
||||
* @depends testAddSuccess
|
||||
* @group minimal
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
$name1 = Random::generateString(8, 'phpunit');
|
||||
$name2 = Random::generateString(8, 'phpunit');
|
||||
# Load in a couple of known display groups
|
||||
$displayGroup1 = (new XiboDisplayGroup($this->getEntityProvider()))->create($name1, 'phpunit description', 0, '');
|
||||
$displayGroup2 = (new XiboDisplayGroup($this->getEntityProvider()))->create($name2, 'phpunit description', 0, '');
|
||||
# Delete the one we created last
|
||||
$response = $this->sendRequest('DELETE','/displaygroup/' . $displayGroup2->displayGroupId);
|
||||
# This should return 204 for success
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Check only one remains
|
||||
$groups = (new XiboDisplayGroup($this->getEntityProvider()))->get();
|
||||
$this->assertEquals(count($this->startDisplayGroups) + 1, count($groups));
|
||||
|
||||
$flag = false;
|
||||
foreach ($groups as $group) {
|
||||
if ($group->displayGroupId == $displayGroup1->displayGroupId) {
|
||||
$flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertTrue($flag, 'DisplayGroup ID ' . $displayGroup1->displayGroupId . ' was not found after deleting a different DisplayGroup');
|
||||
# Clean up
|
||||
$displayGroup1->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign new displays Test
|
||||
*/
|
||||
public function testAssignDisplay()
|
||||
{
|
||||
# Create a Display in the system
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId, 'PHPUnit Test Display');
|
||||
# Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get();
|
||||
$display = null;
|
||||
|
||||
foreach ($displays as $disp) {
|
||||
if ($disp->license == $hardwareId) {
|
||||
$display = $disp;
|
||||
}
|
||||
}
|
||||
|
||||
if ($display === null) {
|
||||
$this->fail('Display was not added correctly');
|
||||
}
|
||||
# Create a DisplayGroup to add the display to
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
# Call assign display to display group
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/display/assign', [
|
||||
'displayId' => [$display->displayId]
|
||||
]);
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Get a list of all Displays in the group
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get(['displayGroupId' => $displayGroup->displayGroupId]);
|
||||
# Check that there's only us in that group
|
||||
$this->assertEquals(1, count($displays));
|
||||
$this->assertEquals($display->displayId, $displays[0]->displayId);
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$display->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to assign display to isDisplaySpecific displayGroupId
|
||||
*/
|
||||
public function testAssignDisplayFailure()
|
||||
{
|
||||
# Create a Display in the system
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId, 'PHPUnit Test Display');
|
||||
# Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get();
|
||||
$display = null;
|
||||
|
||||
foreach ($displays as $disp) {
|
||||
if ($disp->license == $hardwareId) {
|
||||
$display = $disp;
|
||||
}
|
||||
}
|
||||
|
||||
if ($display === null) {
|
||||
$this->fail('Display was not added correctly');
|
||||
}
|
||||
|
||||
# Call assign display to display specific display group
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $display->displayGroupId . '/display/assign', [
|
||||
'displayId' => [$display->displayId]
|
||||
]);
|
||||
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign displays Test
|
||||
*/
|
||||
public function testUnassignDisplay()
|
||||
{
|
||||
# Create a Display in the system
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId, 'PHPUnit Test Display');
|
||||
# Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get();
|
||||
$display = null;
|
||||
|
||||
foreach ($displays as $disp) {
|
||||
if ($disp->license == $hardwareId) {
|
||||
$display = $disp;
|
||||
}
|
||||
}
|
||||
|
||||
if ($display === null) {
|
||||
$this->fail('Display was not added correctly');
|
||||
}
|
||||
|
||||
# Create display group
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
# Assign display to display group
|
||||
$displayGroup->assignDisplay([$display->displayId]);
|
||||
# Unassign display from display group
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/display/unassign', [
|
||||
'displayId' => [$display->displayId]
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$display->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to unassign display from isDisplaySpecific displayGroupId
|
||||
*/
|
||||
public function testUnassignDisplayFailure()
|
||||
{
|
||||
# Create a Display in the system
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId, 'PHPUnit Test Display');
|
||||
# Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get();
|
||||
$display = null;
|
||||
|
||||
foreach ($displays as $disp) {
|
||||
if ($disp->license == $hardwareId) {
|
||||
$display = $disp;
|
||||
}
|
||||
}
|
||||
|
||||
if ($display === null) {
|
||||
$this->fail('Display was not added correctly');
|
||||
}
|
||||
|
||||
# Create display group
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
# Assign display to display group - should be successful
|
||||
$displayGroup->assignDisplay([$display->displayId]);
|
||||
# Unassign display from isDisplaySpecific display group - should fail
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $display->displayGroupId . '/display/unassign', [
|
||||
'displayId' => [$display->displayId]
|
||||
]);
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign new display group Test
|
||||
*/
|
||||
public function testAssignGroup()
|
||||
{
|
||||
# Generate new random names
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$name2 = Random::generateString(8, 'phpunit');
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
$displayGroup2 = (new XiboDisplayGroup($this->getEntityProvider()))->create($name2, 'phpunit description', 0, '');
|
||||
# Assign second display group to the first one
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/displayGroup/assign', [
|
||||
'displayGroupId' => [$displayGroup2->displayGroupId]
|
||||
]);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$displayGroup2->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign displays group Test
|
||||
*/
|
||||
public function testUnassignGroup()
|
||||
{
|
||||
# Generate new random names
|
||||
$name = Random::generateString(8, 'PARENT');
|
||||
$name2 = Random::generateString(8, 'CHILD');
|
||||
# Create new display groups
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
$displayGroup2 = (new XiboDisplayGroup($this->getEntityProvider()))->create($name2, 'phpunit description', 0, '');
|
||||
# Assign second display group to the first one
|
||||
|
||||
$displayGroup->assignDisplayGroup([$displayGroup2->displayGroupId]);
|
||||
# Unassign second display group from the first one
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/displayGroup/unassign', [
|
||||
'displayGroupId' => [$displayGroup2->displayGroupId]
|
||||
]);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$displayGroup2->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign new media file to a group Test
|
||||
*/
|
||||
public function testAssignMedia()
|
||||
{
|
||||
# Generate new random name
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
# Upload a known files
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create('API video 12', PROJECT_ROOT . '/tests/resources/HLH264.mp4');
|
||||
$media2 = (new XiboLibrary($this->getEntityProvider()))->create('API image 12', PROJECT_ROOT . '/tests/resources/xts-night-001.jpg');
|
||||
# Assign two files o the display group and unassign one of them
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/media/assign', [
|
||||
'mediaId' => [$media->mediaId, $media2->mediaId],
|
||||
'unassignMediaId' => [$media2->mediaId]
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$media->delete();
|
||||
$media2->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign media files from a group Test
|
||||
*/
|
||||
public function testUnassignMedia()
|
||||
{
|
||||
# Generate new random name
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
# Upload a known file
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create('API image 29', PROJECT_ROOT . '/tests/resources/xts-night-001.jpg');
|
||||
# Assign media to display Group
|
||||
$displayGroup->assignMedia([$media->mediaId]);
|
||||
# Unassign the media from the display group
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/media/unassign', [
|
||||
'mediaId' => [$media->mediaId]
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$media->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign new layouts to a group Test
|
||||
*/
|
||||
public function testAssignLayout()
|
||||
{
|
||||
# Create new random name
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
|
||||
# Create new layouts
|
||||
$layout = $this->createLayout();
|
||||
$layout2 = $this->createLayout();
|
||||
|
||||
# Assign both layouts to display group then unassign the second layout from it
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/layout/assign', [
|
||||
'layoutId' => [$layout->layoutId, $layout2->layoutId],
|
||||
'unassignLayoutsId' => [$layout2->layoutId]
|
||||
]);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$layout->delete();
|
||||
$layout2->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign layouts from a group Test
|
||||
*/
|
||||
public function testUnassignLayout()
|
||||
{
|
||||
# Create new random name
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
|
||||
# Create new layout
|
||||
$layout = $this->createLayout();
|
||||
|
||||
# assign layout to display group
|
||||
$displayGroup->assignLayout([$layout->layoutId]);
|
||||
# unassign layout from display group
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/layout/unassign', [
|
||||
'layoutId' => [$layout->layoutId]
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$layout->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect now action test
|
||||
*/
|
||||
public function testCollectNow()
|
||||
{
|
||||
# Generate random name
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
# Call callectNow
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/action/collectNow');
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change Layout action test
|
||||
*/
|
||||
public function testChangeLayout()
|
||||
{
|
||||
# Generate random name
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
|
||||
# Create new layout
|
||||
$layout = $this->createLayout();
|
||||
|
||||
# Call changeLayout
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/action/changeLayout', [
|
||||
'layoutId' => $layout->layoutId,
|
||||
'duration' => 900,
|
||||
'downloadRequired' => 1,
|
||||
'changeMode' => 'queue'
|
||||
]);
|
||||
# Check if successful
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$layout->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert to Schedule action test
|
||||
*/
|
||||
public function testRevertToSchedule()
|
||||
{
|
||||
# Generate random name and create new display group
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
# Call RevertToSchedule
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/action/revertToSchedule');
|
||||
# Check if successful
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send command action test
|
||||
*/
|
||||
public function testCommand()
|
||||
{
|
||||
# Generate random name and create new display group
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create($name, 'phpunit description', 0, '');
|
||||
# Create new command
|
||||
$command = (new XiboCommand($this->getEntityProvider()))->create('phpunit command', 'phpunit description', 'phpunitcode');
|
||||
# Send command to display group
|
||||
$response = $this->sendRequest('POST','/displaygroup/' . $displayGroup->displayGroupId . '/action/command' , [
|
||||
'commandId' => $command->commandId
|
||||
]);
|
||||
# Check if successful
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$command->delete();
|
||||
}
|
||||
}
|
||||
171
tests/integration/DisplayProfileTest.php
Normal file
171
tests/integration/DisplayProfileTest.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayProfile;
|
||||
|
||||
/**
|
||||
* Class DisplayProfileTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class DisplayProfileTest extends \Xibo\Tests\LocalWebTestCase
|
||||
{
|
||||
|
||||
protected $startProfiles;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startProfiles = (new XiboDisplayProfile($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all profiles that weren't there initially
|
||||
$finalProfiles = (new XiboDisplayProfile($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
|
||||
// Loop over any remaining profiles and nuke them
|
||||
foreach ($finalProfiles as $displayProfile) {
|
||||
/** @var XiboDisplayProfile $displayProfile */
|
||||
$flag = true;
|
||||
foreach ($this->startProfiles as $startProfile) {
|
||||
if ($startProfile->displayProfileId == $displayProfile->displayProfileId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$displayProfile->delete();
|
||||
} catch (\Exception $e) {
|
||||
$this->getLogger()->error('Unable to delete ' . $displayProfile->displayProfileId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
/**
|
||||
* Shows all display profiles
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
# Get list of all display profiles
|
||||
$response = $this->sendRequest('GET','/displayprofile');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* testAddSuccess - test adding various display profiles that should be valid
|
||||
* @dataProvider provideSuccessCases
|
||||
* @group minimal
|
||||
*/
|
||||
public function testAddSuccess($profileName, $profileType, $profileIsDefault)
|
||||
{
|
||||
// Loop through any pre-existing profiles to make sure we're not
|
||||
// going to get a clash
|
||||
foreach ($this->startProfiles as $tmpProfile) {
|
||||
if ($tmpProfile->name == $profileName) {
|
||||
$this->skipTest("There is a pre-existing profiles with this name");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$response = $this->sendRequest('POST','/displayprofile', [
|
||||
'name' => $profileName,
|
||||
'type' => $profileType,
|
||||
'isDefault' => $profileIsDefault
|
||||
]);
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($profileName, $object->data->name);
|
||||
$this->assertSame($profileType, $object->data->type);
|
||||
$this->assertSame($profileIsDefault, $object->data->isDefault);
|
||||
# Check that the profile was added correctly
|
||||
$profile = (new XiboDisplayProfile($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($profileName, $profile->name);
|
||||
$this->assertSame($profileType, $profile->type);
|
||||
# Clean up the Profiles as we no longer need it
|
||||
$this->assertTrue($profile->delete(), 'Unable to delete ' . $profile->displayProfileId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (profile name, type(windows/android), isDefault flag)
|
||||
* @return array
|
||||
*/
|
||||
public function provideSuccessCases()
|
||||
{
|
||||
// Cases we provide to testAddSuccess, you can extend it by simply adding new case here
|
||||
return [
|
||||
'Android notDefault' => ['test profile', 'android', 0],
|
||||
'Windows notDefault' => ['different test profile', 'windows', 0],
|
||||
'French Android' => ['Test de Français 1', 'android', 0],
|
||||
'Linux' => ['Test de Français 1', 'linux', 0],
|
||||
'Tizen' => ['Test de Français 1', 'sssp', 0],
|
||||
'webOS' => ['Test de Français 1', 'lg', 0]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddFailure - test adding various profiles that should be invalid
|
||||
* @dataProvider provideFailureCases
|
||||
*/
|
||||
public function testAddFailure($profileName, $profileType, $profileIsDefault)
|
||||
{
|
||||
# Add new display profile with arguments from provideFailureCases
|
||||
$response = $this->sendRequest('POST','/displayprofile', [
|
||||
'name' => $profileName,
|
||||
'type' => $profileType,
|
||||
'isDefault' => $profileIsDefault
|
||||
]);
|
||||
# Check if it fails as expected
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (profile name, type(windows/android), isDefault flag)
|
||||
* @return array
|
||||
*/
|
||||
|
||||
public function provideFailureCases()
|
||||
{
|
||||
# Cases we provide to testAddFailure, you can extend it by simply adding new case here
|
||||
return [
|
||||
'NULL Type' => ['no type', NULL, 0],
|
||||
'NULL name' => [NULL, 'android', 1],
|
||||
'is Default 1' => ['TEST PHP', 'android', 1]
|
||||
];
|
||||
}
|
||||
}
|
||||
75
tests/integration/DisplayProfileTestDelete.php
Normal file
75
tests/integration/DisplayProfileTestDelete.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2019 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayProfile;
|
||||
use Xibo\OAuth2\Client\Exception\XiboApiException;
|
||||
|
||||
/**
|
||||
* Class DisplayProfileTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class DisplayProfileTestDelete extends \Xibo\Tests\LocalWebTestCase
|
||||
{
|
||||
/** @var XiboDisplayProfile */
|
||||
private $displayProfile;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->displayProfile = (new XiboDisplayProfile($this->getEntityProvider()))->create(Random::generateString(), 'android', 0);
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
if ($this->displayProfile !== null) {
|
||||
$this->displayProfile->delete();
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
// Delete the one we created last
|
||||
$response = $this->sendRequest('DELETE','/displayprofile/' . $this->displayProfile->displayProfileId);
|
||||
|
||||
// This should return 204 for success
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
|
||||
// Check only one remains
|
||||
try {
|
||||
$displayProfile = (new XiboDisplayProfile($this->getEntityProvider()))->getById($this->displayProfile->displayProfileId);
|
||||
|
||||
$this->fail('Display profile ID ' . $this->displayProfile->displayProfileId . ' was not found after deleting a different Display Profile');
|
||||
} catch (XiboApiException $exception) {
|
||||
// We know we've deleted it, so no clear for tearDown
|
||||
$this->displayProfile = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
112
tests/integration/DisplayProfileTestEdit.php
Normal file
112
tests/integration/DisplayProfileTestEdit.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayProfile;
|
||||
|
||||
/**
|
||||
* Class DisplayProfileTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class DisplayProfileTestEdit extends \Xibo\Tests\LocalWebTestCase
|
||||
{
|
||||
/** @var XiboDisplayProfile */
|
||||
private $displayProfile;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->displayProfile = (new XiboDisplayProfile($this->getEntityProvider()))->create(Random::generateString(), 'android', 0);
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->displayProfile->delete();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing profile
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
// Call edit on the profile.
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$response = $this->sendRequest('PUT','/displayprofile/' . $this->displayProfile->displayProfileId, [
|
||||
'name' => $name,
|
||||
'type' => $this->displayProfile->type,
|
||||
'isDefault' => $this->displayProfile->isDefault
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
// Examine the returned object and check that it's what we expect
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
$this->assertSame('android', $object->data->type);
|
||||
|
||||
// Check that the profile was actually renamed
|
||||
$displayProfile = (new XiboDisplayProfile($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($name, $displayProfile->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing profile
|
||||
*/
|
||||
public function testEditConfig()
|
||||
{
|
||||
// Call edit on the profile.
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$response = $this->sendRequest('PUT','/displayprofile/' . $this->displayProfile->displayProfileId, [
|
||||
'name' => $name,
|
||||
'type' => $this->displayProfile->type,
|
||||
'isDefault' => $this->displayProfile->isDefault,
|
||||
'emailAddress' => 'phpunit@xibo.org.uk'
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getStatusCode());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
// Examine the returned object and check that it's what we expect
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
$this->assertSame('android', $object->data->type);
|
||||
|
||||
foreach ($object->data->config as $config) {
|
||||
if ($config->name === 'emailAddress') {
|
||||
$this->assertSame('phpunit@xibo.org.uk', $config->value, json_encode($object->data->config));
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the profile was actually renamed
|
||||
$displayProfile = (new XiboDisplayProfile($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($name, $displayProfile->name);
|
||||
}
|
||||
}
|
||||
293
tests/integration/DisplayTest.php
Normal file
293
tests/integration/DisplayTest.php
Normal file
@@ -0,0 +1,293 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\Integration;
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
|
||||
class DisplayTest extends \Xibo\Tests\LocalWebTestCase
|
||||
{
|
||||
protected $startDisplays;
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startDisplays = (new XiboDisplay($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Tear down any displays that weren't there before
|
||||
$finalDisplays = (new XiboDisplay($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
|
||||
# Loop over any remaining displays and nuke them
|
||||
foreach ($finalDisplays as $display) {
|
||||
/** @var XiboDisplay $display */
|
||||
$flag = true;
|
||||
foreach ($this->startDisplays as $startDisplay) {
|
||||
if ($startDisplay->displayId == $display->displayId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$display->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $display->displayId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows list of all displays Test
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
# Get all displays
|
||||
$response = $this->sendRequest('GET','/display');
|
||||
# Check if successful
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Display Test
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
# Create a Display in the system
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId, 'PHPUnit Test Display');
|
||||
# Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get(['hardwareKey' => $hardwareId]);
|
||||
if (count($displays) != 1)
|
||||
$this->fail('Display was not added correctly');
|
||||
/** @var XiboDisplay $display */
|
||||
$display = $displays[0];
|
||||
$response = $this->sendRequest('DELETE','/display/' . $display->displayId);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Display test, expecting success
|
||||
*/
|
||||
public function testEditSuccess()
|
||||
{
|
||||
# Create a Display in the system
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId, 'PHPUnit Test Display');
|
||||
# Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get(['hardwareKey' => $hardwareId]);
|
||||
|
||||
if (count($displays) != 1) {
|
||||
$this->fail('Display was not added correctly');
|
||||
}
|
||||
|
||||
/** @var XiboDisplay $display */
|
||||
$display = $displays[0];
|
||||
$auditingTime = time()+3600;
|
||||
# Edit display and change its name
|
||||
$response = $this->sendRequest('PUT','/display/' . $display->displayId, [
|
||||
'display' => 'API EDITED',
|
||||
'defaultLayoutId' => $display->defaultLayoutId,
|
||||
'auditingUntil' => Carbon::createFromTimestamp($auditingTime)->format(DateFormatHelper::getSystemFormat()),
|
||||
'licensed' => $display->licensed,
|
||||
'license' => $display->license,
|
||||
'incSchedule' => $display->incSchedule,
|
||||
'emailAlert' => $display->emailAlert,
|
||||
'wakeOnLanEnabled' => $display->wakeOnLanEnabled,
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
# Check if display has new edited name
|
||||
$this->assertSame('API EDITED', $object->data->display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Display Type and reference, expecting success
|
||||
*/
|
||||
public function testEditDisplayType()
|
||||
{
|
||||
# Create a Display in the system
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId, 'PHPUnit Test Display Type');
|
||||
# Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get(['hardwareKey' => $hardwareId]);
|
||||
|
||||
if (count($displays) != 1) {
|
||||
$this->fail('Display was not added correctly');
|
||||
}
|
||||
|
||||
/** @var XiboDisplay $display */
|
||||
$display = $displays[0];
|
||||
$auditingTime = time()+3600;
|
||||
# Edit display and change its name
|
||||
$response = $this->sendRequest('PUT', '/display/' . $display->displayId, [
|
||||
'display' => 'PHPUnit Test Display Type - EDITED',
|
||||
'defaultLayoutId' => $display->defaultLayoutId,
|
||||
'auditingUntil' => Carbon::createFromTimestamp($auditingTime)->format(DateFormatHelper::getSystemFormat()),
|
||||
'licensed' => $display->licensed,
|
||||
'license' => $display->license,
|
||||
'incSchedule' => $display->incSchedule,
|
||||
'emailAlert' => $display->emailAlert,
|
||||
'wakeOnLanEnabled' => $display->wakeOnLanEnabled,
|
||||
'displayTypeId' => 1,
|
||||
'ref1' => 'Lorem ipsum',
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
# Check if display has new edited name
|
||||
$this->assertSame(1, $object->data->displayTypeId);
|
||||
$this->assertSame('Lorem ipsum', $object->data->ref1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Display test, expecting failure
|
||||
*/
|
||||
public function testEditFailure()
|
||||
{
|
||||
# Create a Display in the system
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId, 'PHPUnit Test Display');
|
||||
# Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get(['hardwareKey' => $hardwareId]);
|
||||
if (count($displays) != 1)
|
||||
$this->fail('Display was not added correctly');
|
||||
/** @var XiboDisplay $display */
|
||||
$display = $displays[0];
|
||||
# Edit display and change its hardwareKey
|
||||
$response = $this->sendRequest('PUT','/display/' . $display->displayId, [
|
||||
'display' => 'API EDITED',
|
||||
'defaultLayoutId' => $display->defaultLayoutId,
|
||||
'licensed' => $display->licensed,
|
||||
'license' => null,
|
||||
'incSchedule' => $display->incSchedule,
|
||||
'emailAlert' => $display->emailAlert,
|
||||
'wakeOnLanEnabled' => $display->wakeOnLanEnabled,
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
# Check if call failed as expected (license cannot be null)
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Request screenshot Test
|
||||
*/
|
||||
public function testScreenshot()
|
||||
{
|
||||
# Generate names for display and xmr channel
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$xmrChannel = Random::generateString(50);
|
||||
# This is a dummy pubKey and isn't used by anything important
|
||||
$xmrPubkey = '-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDmdnXL4gGg3yJfmqVkU1xsGSQI
|
||||
3b6YaeAKtWuuknIF1XAHAHtl3vNhQN+SmqcNPOydhK38OOfrdb09gX7OxyDh4+JZ
|
||||
inxW8YFkqU0zTqWaD+WcOM68wTQ9FCOEqIrbwWxLQzdjSS1euizKy+2GcFXRKoGM
|
||||
pbBhRgkIdydXoZZdjQIDAQAB
|
||||
-----END PUBLIC KEY-----';
|
||||
# Register our display
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId,
|
||||
'PHPUnit Test Display',
|
||||
'windows',
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
'00:16:D9:C9:AL:69',
|
||||
$xmrChannel,
|
||||
$xmrPubkey
|
||||
);
|
||||
|
||||
# Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get(['hardwareKey' => $hardwareId]);
|
||||
if (count($displays) != 1)
|
||||
$this->fail('Display was not added correctly');
|
||||
/** @var XiboDisplay $display */
|
||||
$display = $displays[0];
|
||||
# Check if xmr channel and pubkey were registered correctly
|
||||
$this->assertSame($xmrChannel, $display->xmrChannel, 'XMR Channel not set correctly by XMDS Register Display');
|
||||
$this->assertSame($xmrPubkey, $display->xmrPubKey, 'XMR PubKey not set correctly by XMDS Register Display');
|
||||
# Call request screenshot
|
||||
$response = $this->sendRequest('PUT','/display/requestscreenshot/' . $display->displayId);
|
||||
# Check if successful
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Wake On Lan Test
|
||||
*/
|
||||
public function testWoL()
|
||||
{
|
||||
# Create dummy hardware key and mac address
|
||||
$hardwareId = Random::generateString(12, 'phpunit');
|
||||
$macAddress = '00-16-D9-C9-AE-69';
|
||||
# Register our display
|
||||
$this->getXmdsWrapper()->RegisterDisplay($hardwareId,
|
||||
'PHPUnit Test Display',
|
||||
'windows',
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$macAddress,
|
||||
Random::generateString(50),
|
||||
Random::generateString(50)
|
||||
);
|
||||
# Now find the Id of that Display
|
||||
$displays = (new XiboDisplay($this->getEntityProvider()))->get(['hardwareKey' => $hardwareId]);
|
||||
if (count($displays) != 1)
|
||||
$this->fail('Display was not added correctly');
|
||||
/** @var XiboDisplay $display */
|
||||
$display = $displays[0];
|
||||
# Check if mac address was added correctly
|
||||
$this->assertSame($macAddress, $display->macAddress, 'Mac Address not set correctly by XMDS Register Display');
|
||||
$auditingTime = time()+3600;
|
||||
# Edit display and add broadcast channel
|
||||
$display->edit(
|
||||
$display->display,
|
||||
$display->description,
|
||||
$display->tags,
|
||||
Carbon::createFromTimestamp($auditingTime)->format(DateFormatHelper::getSystemFormat()),
|
||||
$display->defaultLayoutId,
|
||||
$display->licensed,
|
||||
$display->license,
|
||||
$display->incSchedule,
|
||||
$display->emailAlert,
|
||||
$display->alertTimeout,
|
||||
$display->wakeOnLanEnabled,
|
||||
null,
|
||||
'127.0.0.1');
|
||||
# Call WOL
|
||||
$response = $this->sendRequest('POST','/display/wol/' . $display->displayId);
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
}
|
||||
}
|
||||
60
tests/integration/FaultTest.php
Normal file
60
tests/integration/FaultTest.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
/**
|
||||
* Class FaultTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class FaultTest extends \Xibo\Tests\LocalWebTestCase
|
||||
{
|
||||
/**
|
||||
* Collect data
|
||||
* This test modifies headers and we therefore need to run in a separate process
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testCollect()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/fault/collect', ['outputLog' => 'on']);
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* test turning debug on
|
||||
*/
|
||||
public function testDebugOn()
|
||||
{
|
||||
$response = $this->sendRequest('PUT','/fault/debug/on');
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* test turning debug off
|
||||
*/
|
||||
public function testDebugOff()
|
||||
{
|
||||
$response = $this->sendRequest('PUT','/fault/debug/off');
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
}
|
||||
}
|
||||
169
tests/integration/FontTest.php
Normal file
169
tests/integration/FontTest.php
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2022 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class FontTest extends LocalWebTestCase
|
||||
{
|
||||
use DisplayHelperTrait;
|
||||
|
||||
private $testFileName = 'PHPUNIT FONT TEST';
|
||||
private $testFilePath = PROJECT_ROOT . '/tests/resources/UglyTypist.ttf';
|
||||
protected $startFonts;
|
||||
// TODO create api wrapper for fonts :)
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startFonts = $this->getEntityProvider()->get('/fonts', ['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all media files that weren't there initially
|
||||
$finalFonts = $this->getEntityProvider()->get('/fonts', ['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining font files and nuke them
|
||||
foreach ($finalFonts as $font) {
|
||||
$flag = true;
|
||||
foreach ($this->startFonts as $startFont) {
|
||||
if ($startFont['id'] == $font['id']) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$this->getEntityProvider()->delete('/fonts/'.$font['id'].'/delete');
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete font ' . $font['id'] . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* List all file in library
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
# Get all library items
|
||||
$response = $this->sendRequest('GET', '/fonts');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
// we expect fonts distributed with CMS to be there.
|
||||
$this->assertNotEmpty($object->data->data);
|
||||
}
|
||||
|
||||
public function testUpload()
|
||||
{
|
||||
$uploadResponse = $this->uploadFontFile();
|
||||
$uploadedFileObject = $uploadResponse['files'][0];
|
||||
$this->assertNotEmpty($uploadedFileObject);
|
||||
$this->assertSame(filesize($this->testFilePath), $uploadedFileObject['size']);
|
||||
$this->assertSame(basename($this->testFilePath), $uploadedFileObject['fileName']);
|
||||
|
||||
$this->getLogger()->debug(
|
||||
'Uploaded font ' . $uploadedFileObject['name'] .
|
||||
' with ID ' . $uploadedFileObject['id'] .
|
||||
' Stored as ' . $uploadedFileObject['fileName']
|
||||
);
|
||||
|
||||
$fontRecord = $this->getEntityProvider()->get('/fonts', ['name' => $this->testFileName])[0];
|
||||
$this->assertNotEmpty($fontRecord);
|
||||
$this->assertSame(filesize($this->testFilePath), $fontRecord['size']);
|
||||
$this->assertSame(basename($this->testFilePath), $fontRecord['fileName']);
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$upload = $this->uploadFontFile();
|
||||
|
||||
$response = $this->sendRequest('DELETE', '/fonts/' . $upload['files'][0]['id']. '/delete');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
}
|
||||
|
||||
public function testFontDependencies()
|
||||
{
|
||||
$upload = $this->uploadFontFile();
|
||||
$size = $upload['files'][0]['size'];
|
||||
$md5 = $upload['files'][0]['md5'];
|
||||
|
||||
// Create a Display
|
||||
$display = $this->createDisplay();
|
||||
$this->displaySetStatus($display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($display);
|
||||
|
||||
// Call Required Files
|
||||
$rf = $this->getXmdsWrapper()->RequiredFiles($display->license);
|
||||
|
||||
$this->assertContains('file download="http" size="'.$size.'" md5="'.$md5.'" saveAs="'.basename($this->testFilePath).'" type="dependency" fileType="font" ', $rf, 'Font not in Required Files');
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($display);
|
||||
}
|
||||
|
||||
public function testFontCss()
|
||||
{
|
||||
$fontCssPath = PROJECT_ROOT . '/library/fonts/fonts.css';
|
||||
|
||||
// upload file, this should also update fonts.css file
|
||||
$this->uploadFontFile();
|
||||
// read css file
|
||||
$fontsCss = file_get_contents($fontCssPath);
|
||||
|
||||
// get the record
|
||||
$fontRecord = $this->getEntityProvider()->get('/fonts', ['name' => $this->testFileName])[0];
|
||||
|
||||
// check if the uploaded font was added to player fonts.css file.
|
||||
$this->assertContains('font-family: \''.$fontRecord['familyName'].'\';', $fontsCss, 'Font not in fonts.css');
|
||||
$this->assertContains('src: url(\''.basename($this->testFilePath).'\');', $fontsCss, 'Font not in fonts.css');
|
||||
}
|
||||
|
||||
private function uploadFontFile()
|
||||
{
|
||||
$payload = [
|
||||
[
|
||||
'name' => 'name',
|
||||
'contents' => $this->testFileName
|
||||
],
|
||||
[
|
||||
'name' => 'files',
|
||||
'contents' => fopen($this->testFilePath, 'r')
|
||||
]
|
||||
];
|
||||
|
||||
return $this->getEntityProvider()->post('/fonts', ['multipart' => $payload]);
|
||||
}
|
||||
}
|
||||
434
tests/integration/InteractiveFeaturesTest.php
Normal file
434
tests/integration/InteractiveFeaturesTest.php
Normal file
@@ -0,0 +1,434 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
|
||||
/**
|
||||
* Class AboutTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class InteractiveFeaturesTest extends \Xibo\Tests\LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this));
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Get Draft
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$this->addSimpleTextWidget($layout);
|
||||
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Set the Layout status
|
||||
$this->setLayoutStatus($this->layout, 1);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* Test Add Region Drawer
|
||||
*/
|
||||
public function testAddDrawer()
|
||||
{
|
||||
$layout = $this->checkout($this->layout);
|
||||
// add Drawer Region
|
||||
$response = $this->sendRequest('POST', '/region/drawer/' . $layout->layoutId);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response);
|
||||
|
||||
$body = json_decode($response->getBody());
|
||||
|
||||
$this->assertSame(201, $body->status);
|
||||
$this->assertSame(true, $body->success);
|
||||
$this->assertSame(false, $body->grid);
|
||||
$this->assertNotEmpty($body->data, 'Empty Data');
|
||||
|
||||
$this->assertSame(1, $body->data->isDrawer);
|
||||
$this->assertContains('drawer', $body->data->name);
|
||||
|
||||
// get the layout
|
||||
$layout = $this->getEntityProvider()->get('/layout', ['layoutId' => $layout->layoutId, 'embed' => 'regions'])[0];
|
||||
// check if regions and drawers arrays are not empty
|
||||
$this->assertNotEmpty($layout['drawers']);
|
||||
$this->assertNotEmpty($layout['regions']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Add Region Drawer
|
||||
*/
|
||||
public function testDeleteDrawer()
|
||||
{
|
||||
$layout = $this->checkout($this->layout);
|
||||
// add Drawer Region
|
||||
$drawer = $this->getEntityProvider()->post('/region/drawer/' . $layout->layoutId);
|
||||
|
||||
// delete Drawer Region
|
||||
$response = $this->sendRequest('DELETE', '/region/' . $drawer['regionId']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response);
|
||||
$body = json_decode($response->getBody());
|
||||
$this->assertSame(204, $body->status);
|
||||
$this->assertSame(true, $body->success);
|
||||
}
|
||||
|
||||
public function testListAll()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/action');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Action
|
||||
* @dataProvider AddActionSuccessCases
|
||||
* @param string $source
|
||||
* @param string $triggerType
|
||||
* @param string|null $triggerCode
|
||||
* @param string $actionType
|
||||
* @param string $target
|
||||
* @param string|null $layoutCode
|
||||
*/
|
||||
public function testAddActionSuccess(?string $source, ?string $triggerType, ?string $triggerCode, string $actionType, string $target, ?string $layoutCode)
|
||||
{
|
||||
$layout = $this->checkout($this->layout);
|
||||
$sourceId = null;
|
||||
$targetId = null;
|
||||
$widgetId = null;
|
||||
|
||||
// Add a couple of text widgets to the region
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
$widget = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget B',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
$widget2 = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// depending on the source from AddActionsCases, the sourceId will be different
|
||||
if ($source === 'layout') {
|
||||
$sourceId = $layout->layoutId;
|
||||
} elseif ($source === 'region') {
|
||||
$sourceId = $layout->regions[0]->regionId;
|
||||
} else {
|
||||
$sourceId = $widget->widgetId;
|
||||
}
|
||||
|
||||
// depending on the target screen|region we may need targetId
|
||||
if ($target === 'region') {
|
||||
$targetId = $layout->regions[0]->regionId;
|
||||
}
|
||||
|
||||
if ($actionType == 'navWidget') {
|
||||
$widgetId = $widget2->widgetId;
|
||||
}
|
||||
|
||||
$response = $this->sendRequest('POST', '/action', [
|
||||
'triggerType' => $triggerType,
|
||||
'triggerCode' => $triggerCode,
|
||||
'actionType' => $actionType,
|
||||
'target' => $target,
|
||||
'targetId' => $targetId,
|
||||
'widgetId' => $widgetId,
|
||||
'layoutCode' => $layoutCode,
|
||||
'source' => $source,
|
||||
'sourceId' => $sourceId,
|
||||
'layoutId' => $layout->layoutId
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response);
|
||||
|
||||
$body = json_decode($response->getBody());
|
||||
$this->assertSame(201, $body->status);
|
||||
$this->assertSame(true, $body->success);
|
||||
$this->assertSame(false, $body->grid);
|
||||
|
||||
$this->assertNotEmpty($body->data, 'Empty Data');
|
||||
$this->assertSame($layout->layoutId, $body->data->layoutId);
|
||||
$this->assertSame($sourceId, $body->data->sourceId);
|
||||
$this->assertSame($triggerType, $body->data->triggerType);
|
||||
$this->assertSame($triggerCode, $body->data->triggerCode);
|
||||
$this->assertSame($actionType, $body->data->actionType);
|
||||
$this->assertSame($target, $body->data->target);
|
||||
$this->assertSame($targetId, $body->data->targetId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (string $source, string $triggerType, string|null $triggerCode, string $actionType, string $target, string LayoutCode)
|
||||
* @return array
|
||||
*/
|
||||
public function AddActionSuccessCases()
|
||||
{
|
||||
return [
|
||||
'Layout' => ['layout', 'touch', 'trigger code', 'next', 'screen', null],
|
||||
'Layout with region target' => ['layout', 'touch', null, 'previous', 'region', null],
|
||||
'Region' => ['region', 'webhook', 'test', 'previous', 'screen', null],
|
||||
'Region with region target' => ['region', 'touch', null, 'previous', 'region', null],
|
||||
'Widget' => ['widget', 'touch', null, 'next', 'screen', null],
|
||||
'Widget with region target' => ['widget', 'touch', null, 'next', 'region', null],
|
||||
'Navigate to Widget' => ['layout', 'touch', null, 'navWidget', 'screen', null],
|
||||
'Navigate to Layout with code' => ['layout', 'touch', null, 'navLayout', 'screen', 'CodeIdentifier'],
|
||||
'Web UI' => [null, null, null, 'next', 'screen', null]
|
||||
];
|
||||
}
|
||||
|
||||
public function testEditAction()
|
||||
{
|
||||
$layout = $this->checkout($this->layout);
|
||||
$action = $this->getEntityProvider()->post('/action', [
|
||||
'actionType' => 'previous',
|
||||
'target' => 'screen',
|
||||
'layoutId' => $layout->layoutId
|
||||
]);
|
||||
|
||||
$response = $this->sendRequest('PUT', '/action/' . $action['actionId'], [
|
||||
'source' => 'layout',
|
||||
'sourceId' => $layout->layoutId,
|
||||
'triggerType' => 'webhook',
|
||||
'triggerCode' => 'new code',
|
||||
'actionType' => 'next',
|
||||
'target' => 'region',
|
||||
'targetId' => $layout->regions[0]->regionId
|
||||
], ['Content-Type' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response);
|
||||
|
||||
$body = json_decode($response->getBody());
|
||||
$this->assertSame(200, $body->status);
|
||||
$this->assertSame(true, $body->success);
|
||||
$this->assertSame(false, $body->grid);
|
||||
|
||||
$this->assertNotEmpty($body->data, 'Empty Data');
|
||||
$this->assertSame($layout->layoutId, $body->data->sourceId);
|
||||
$this->assertSame($layout->layoutId, $body->data->layoutId);
|
||||
$this->assertSame('webhook', $body->data->triggerType);
|
||||
$this->assertSame('new code', $body->data->triggerCode);
|
||||
$this->assertSame('next', $body->data->actionType);
|
||||
$this->assertSame('region', $body->data->target);
|
||||
$this->assertSame($layout->regions[0]->regionId, $body->data->targetId);
|
||||
}
|
||||
|
||||
public function testDeleteAction()
|
||||
{
|
||||
$layout = $this->checkout($this->layout);
|
||||
|
||||
$action = $this->getEntityProvider()->post('/action', [
|
||||
'triggerType' => 'webhook',
|
||||
'triggerCode' => 'test',
|
||||
'actionType' => 'previous',
|
||||
'target' => 'screen',
|
||||
'layoutId' => $layout->layoutId
|
||||
]);
|
||||
|
||||
$response = $this->sendRequest('DELETE', '/action/' . $action['actionId']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response);
|
||||
|
||||
$body = json_decode($response->getBody());
|
||||
$this->assertSame(204, $body->status);
|
||||
$this->assertSame(true, $body->success);
|
||||
$this->assertSame(false, $body->grid);
|
||||
|
||||
// check if one action remains with our Layout Id.
|
||||
$actions = $this->getEntityProvider()->get('/action', ['sourceId' => $layout->layoutId]);
|
||||
$this->assertSame(0, count($actions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Action
|
||||
* @dataProvider editActionFailureCases
|
||||
* @param string $source
|
||||
* @param string $triggerType
|
||||
* @param string|null $triggerCode
|
||||
* @param string $actionType
|
||||
* @param string $target
|
||||
*/
|
||||
public function testEditActionFailure(string $source, string $triggerType, ?string $triggerCode, string $actionType, string $target)
|
||||
{
|
||||
$layout = $this->checkout($this->layout);
|
||||
$action = $this->getEntityProvider()->post('/action', [
|
||||
'actionType' => 'previous',
|
||||
'target' => 'screen',
|
||||
'layoutId' => $layout->layoutId
|
||||
]);
|
||||
|
||||
$targetId = null;
|
||||
$widgetId = null;
|
||||
$layoutCode = null;
|
||||
|
||||
if ($source === 'layout') {
|
||||
$sourceId = $layout->layoutId;
|
||||
} elseif ($source === 'region') {
|
||||
$sourceId = $layout->regions[0]->regionId;
|
||||
} else {
|
||||
$sourceId = null;
|
||||
}
|
||||
|
||||
$response = $this->sendRequest('PUT', '/action/' . $action['actionId'], [
|
||||
'triggerType' => $triggerType,
|
||||
'triggerCode' => $triggerCode,
|
||||
'actionType' => $actionType,
|
||||
'target' => $target,
|
||||
'targetId' => $targetId,
|
||||
'source' => $source,
|
||||
'sourceId' => $sourceId
|
||||
]);
|
||||
|
||||
$body = json_decode($response->getBody());
|
||||
|
||||
// in other failure cases, we expect to get invalidArgument exception.
|
||||
$this->assertSame(422, $response->getStatusCode());
|
||||
|
||||
// get the error message for cases and make sure we return correct one.
|
||||
if ($source === 'playlist') {
|
||||
$this->assertSame('Invalid source', $body->error);
|
||||
}
|
||||
|
||||
// wrong trigger type case
|
||||
if ($triggerType === 'notExistingType') {
|
||||
$this->assertSame('Invalid trigger type', $body->error);
|
||||
}
|
||||
|
||||
// wrong trigger type case
|
||||
if ($actionType === 'wrongAction') {
|
||||
$this->assertSame('Invalid action type', $body->error);
|
||||
}
|
||||
|
||||
// wrong target case
|
||||
if ($target === 'world') {
|
||||
$this->assertSame('Invalid target', $body->error);
|
||||
}
|
||||
|
||||
// test case when we have target set to region, but we don't set targetId to any regionId
|
||||
if ($target === 'region') {
|
||||
$this->assertSame('Please select a Region', $body->error);
|
||||
}
|
||||
|
||||
// trigger code in non layout
|
||||
if ($triggerType === 'webhook' && $triggerCode === null) {
|
||||
$this->assertSame('Please provide trigger code', $body->error);
|
||||
}
|
||||
|
||||
// navWidget without widgetId
|
||||
if ($actionType === 'navWidget' && $widgetId == null) {
|
||||
$this->assertSame('Please select a Widget', $body->error);
|
||||
}
|
||||
|
||||
// navLayout without layoutCode
|
||||
if ($actionType === 'navLayout' && $layoutCode == null) {
|
||||
$this->assertSame('Please enter Layout code', $body->error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (string $source, string $triggerType, string|null $triggerCode, string $actionType, string $target)
|
||||
* @return array
|
||||
*/
|
||||
public function editActionFailureCases()
|
||||
{
|
||||
return [
|
||||
'Wrong source' => ['playlist', 'touch', null, 'next', 'screen'],
|
||||
'Wrong trigger type' => ['layout', 'notExistingType', null, 'previous', 'screen'],
|
||||
'Wrong action type' => ['layout', 'touch', null, 'wrongAction', 'screen'],
|
||||
'Wrong target' => ['layout', 'touch', null, 'next', 'world'],
|
||||
'Target region without targetId' => ['layout', 'touch', 'trigger code', 'next', 'region'],
|
||||
'Missing trigger code for webhook' => ['region', 'webhook', null, 'next', 'screen'],
|
||||
'Navigate to Widget without widgetId' => ['layout', 'touch', null, 'navWidget', 'screen'],
|
||||
'Navigate to Layout without layoutCode' => ['layout', 'touch', null, 'navLayout', 'screen']
|
||||
];
|
||||
}
|
||||
|
||||
public function testCopyLayoutWithActions()
|
||||
{
|
||||
$layout = $this->checkout($this->layout);
|
||||
|
||||
$this->getEntityProvider()->post('/action', [
|
||||
'triggerType' => 'touch',
|
||||
'actionType' => 'previous',
|
||||
'target' => 'screen',
|
||||
'layout' => $layout->layoutId
|
||||
]);
|
||||
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
$response = $this->sendRequest('POST', '/layout/copy/' . $this->layout->layoutId, ['copyMediaFiles' => 0, 'name' => Random::generateString()]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response);
|
||||
|
||||
$body = json_decode($response->getBody());
|
||||
$this->assertSame(201, $body->status);
|
||||
|
||||
$newLayoutId = $body->id;
|
||||
$newLayout = $this->getEntityProvider()->get('/layout', ['layoutId' => $newLayoutId, 'embed' => 'regions,actions'])[0];
|
||||
$this->assertNotEmpty($newLayout['actions']);
|
||||
// delete the copied layout
|
||||
(new XiboLayout($this->getEntityProvider()))->getById($newLayoutId)->delete();
|
||||
}
|
||||
}
|
||||
88
tests/integration/LayoutDraftTest.php
Normal file
88
tests/integration/LayoutDraftTest.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\integration;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutDraftTest
|
||||
* @package Xibo\Tests\integration
|
||||
*/
|
||||
class LayoutDraftTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
private $layout;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->layout = $this->createLayout();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
// This should always be the original, regardless of whether we checkout/discard/etc
|
||||
$this->layout->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding a region to a Layout that has been checked out, but use the parent
|
||||
*/
|
||||
public function testAddRegionCheckoutParent()
|
||||
{
|
||||
// Add region to our layout with data from regionSuccessCases
|
||||
$response = $this->sendRequest('POST','/region/' . $this->layout->layoutId, [
|
||||
'width' => 100,
|
||||
'height' => 100,
|
||||
'top' => 10,
|
||||
'left' => 10
|
||||
]);
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Status Incorrect');
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(false, $object->success);
|
||||
$this->assertSame(422, $object->httpStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding a region to a Layout that has been checked out, using the draft
|
||||
*/
|
||||
public function testAddRegionCheckout()
|
||||
{
|
||||
// Checkout the Parent, but add a Region to the Original
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add region to our layout with data from regionSuccessCases
|
||||
$response = $this->sendRequest('POST','/region/' . $layout->layoutId, [
|
||||
'width' => 100,
|
||||
'height' => 100,
|
||||
'top' => 10,
|
||||
'left' => 10
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
}
|
||||
}
|
||||
120
tests/integration/LayoutLockTest.php
Normal file
120
tests/integration/LayoutLockTest.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Exception\XiboApiException;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class LayoutLockTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
private $layout;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Get Draft
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Set the Layout status
|
||||
$this->setLayoutStatus($this->layout, 1);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testIsLockedObject()
|
||||
{
|
||||
// draft
|
||||
$layout = $this->checkout($this->layout);
|
||||
|
||||
// add simple Widget via API
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
// Get the Layout object via web request
|
||||
$response = $this->sendRequest('GET', '/layout', ['layoutId' => $layout->layoutId], [], 'layoutLock');
|
||||
$body = json_decode($response->getBody());
|
||||
$layoutObject = $body[0];
|
||||
|
||||
// check if the isLocked dynamic object is there and is not empty, then check the values inside of it.
|
||||
// we expect it to be locked with our LayoutId and API entryPoint
|
||||
$this->assertNotEmpty($layoutObject->isLocked);
|
||||
$this->assertSame($layout->layoutId, $layoutObject->isLocked->layoutId);
|
||||
$this->assertSame('API', $layoutObject->isLocked->entryPoint);
|
||||
}
|
||||
|
||||
public function testApiToWeb()
|
||||
{
|
||||
// draft
|
||||
$layout = $this->checkout($this->layout);
|
||||
|
||||
// add simple Widget via API
|
||||
$this->addSimpleWidget($layout);
|
||||
|
||||
// layout should be locked for our User with API entry point for 5 min.
|
||||
// attempt to add another Widget via web request
|
||||
$response = $this->sendRequest('POST', '/playlist/widget/clock/' . $layout->regions[0]->regionPlaylist->playlistId, [
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
], [], 'layoutLock');
|
||||
|
||||
$this->assertSame(403, $response->getStatusCode());
|
||||
$body = json_decode($response->getBody());
|
||||
$this->assertSame(403, $body->httpStatus);
|
||||
$this->assertContains('Layout ID ' . $layout->layoutId . ' is locked by another User! Lock expires on:', $body->error);
|
||||
}
|
||||
|
||||
public function testWebToApi()
|
||||
{
|
||||
// draft
|
||||
$layout = $this->checkout($this->layout);
|
||||
|
||||
// call Layout status via web request, this will trigger the Layout Lock Middleware as well
|
||||
$this->sendRequest('GET', '/layout/status/' . $layout->layoutId, [], [], 'layoutLock');
|
||||
|
||||
// attempt to add Widget via API
|
||||
try {
|
||||
$this->addSimpleWidget($layout);
|
||||
} catch (XiboApiException $exception) {
|
||||
$this->assertContains('Layout ID ' . $layout->layoutId . ' is locked by another User! Lock expires on:', $exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
903
tests/integration/LayoutTest.php
Normal file
903
tests/integration/LayoutTest.php
Normal file
@@ -0,0 +1,903 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCampaign;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboRegion;
|
||||
use Xibo\OAuth2\Client\Entity\XiboResolution;
|
||||
use Xibo\Support\Exception\InvalidArgumentException;
|
||||
use Xibo\Support\Exception\NotFoundException;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LayoutTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class LayoutTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var XiboLayout[] */
|
||||
protected $startLayouts;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startLayouts = (new XiboLayout($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all layouts that weren't there initially
|
||||
$finalLayouts = (new XiboLayout($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
|
||||
// Loop over any remaining layouts and nuke them
|
||||
foreach ($finalLayouts as $layout) {
|
||||
/** @var XiboLayout $layout */
|
||||
$flag = true;
|
||||
foreach ($this->startLayouts as $startLayout) {
|
||||
if ($startLayout->layoutId == $layout->layoutId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$layout->delete();
|
||||
} catch (\Exception $e) {
|
||||
$this->getLogger()->error('Unable to delete ' . $layout->layoutId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @return int
|
||||
*/
|
||||
private function getResolutionId($type)
|
||||
{
|
||||
if ($type === 'landscape') {
|
||||
$width = 1920;
|
||||
$height = 1080;
|
||||
} else if ($type === 'portrait') {
|
||||
$width = 1080;
|
||||
$height = 1920;
|
||||
} else {
|
||||
return -10;
|
||||
}
|
||||
|
||||
//$this->getLogger()->debug('Querying for ' . $width . ', ' . $height);
|
||||
|
||||
$resolutions = (new XiboResolution($this->getEntityProvider()))->get(['width' => $width, 'height' => $height]);
|
||||
|
||||
if (count($resolutions) <= 0)
|
||||
return -10;
|
||||
|
||||
return $resolutions[0]->resolutionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all layouts known empty
|
||||
*/
|
||||
public function testListEmpty()
|
||||
{
|
||||
# Check that there is one layout in the database (the 'default layout')
|
||||
if (count($this->startLayouts) > 1) {
|
||||
$this->skipTest("There are pre-existing Layouts");
|
||||
return;
|
||||
}
|
||||
|
||||
$response = $this->sendRequest('GET','/layout');
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
# There should be one default layout in the system
|
||||
$this->assertEquals(1, $object->data->recordsTotal);
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddSuccess - test adding various Layouts that should be valid
|
||||
* @dataProvider provideSuccessCases
|
||||
*/
|
||||
public function testAddSuccess($layoutName, $layoutDescription, $layoutTemplateId, $layoutResolutionType)
|
||||
{
|
||||
$layoutResolutionId = $this->getResolutionId($layoutResolutionType);
|
||||
|
||||
# Create layouts with arguments from provideSuccessCases
|
||||
$response = $this->sendRequest('POST','/layout', [
|
||||
'name' => $layoutName,
|
||||
'description' => $layoutDescription,
|
||||
'layoutId' => $layoutTemplateId,
|
||||
'resolutionId' => $layoutResolutionId
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
$this->assertSame($layoutName, $object->data->layout);
|
||||
$this->assertSame($layoutDescription, $object->data->description);
|
||||
|
||||
# Check that the layout was really added
|
||||
$layouts = (new XiboLayout($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->assertEquals(count($this->startLayouts) + 1, count($layouts));
|
||||
|
||||
# Check that the layout was added correctly
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($layoutName, $layout->layout);
|
||||
$this->assertSame($layoutDescription, $layout->description);
|
||||
|
||||
# Clean up the Layout as we no longer need it
|
||||
$this->assertTrue($layout->delete(), 'Unable to delete ' . $layout->layoutId);
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddFailure - test adding various Layouts that should be invalid
|
||||
* @dataProvider provideFailureCases
|
||||
*/
|
||||
public function testAddFailure($layoutName, $layoutDescription, $layoutTemplateId, $layoutResolutionType)
|
||||
{
|
||||
$layoutResolutionId = $this->getResolutionId($layoutResolutionType);
|
||||
|
||||
# Create layouts with arguments from provideFailureCases
|
||||
$request = $this->createRequest('POST','/layout');
|
||||
$request->withParsedBody([
|
||||
'name' => $layoutName,
|
||||
'description' => $layoutDescription,
|
||||
'layoutId' => $layoutTemplateId,
|
||||
'resolutionId' => $layoutResolutionId
|
||||
]);
|
||||
|
||||
try {
|
||||
$this->app->handle($request);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
# check if they fail as expected
|
||||
$this->assertSame(422, $e->getCode(), 'Expecting failure, received ' . $e->getMessage());
|
||||
} catch (NotFoundException $e ) {
|
||||
$this->assertSame(404, $e->getCode(), 'Expecting failure, received ' . $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* List all layouts known set
|
||||
* @group minimal
|
||||
*/
|
||||
public function testListKnown()
|
||||
{
|
||||
$cases = $this->provideSuccessCases();
|
||||
$layouts = [];
|
||||
|
||||
// Check each possible case to ensure it's not pre-existing
|
||||
// If it is, skip over it
|
||||
foreach ($cases as $case) {
|
||||
$flag = true;
|
||||
foreach ($this->startLayouts as $tmpLayout) {
|
||||
if ($case[0] == $tmpLayout->layout) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
$layouts[] = (new XiboLayout($this->getEntityProvider()))->create($case[0],$case[1],$case[2],$this->getResolutionId($case[3]));
|
||||
}
|
||||
}
|
||||
|
||||
$response = $this->sendRequest('GET','/layout');
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
|
||||
# There should be as many layouts as we created plus the number we started with in the system
|
||||
$this->assertEquals(count($layouts) + count($this->startLayouts), $object->data->recordsTotal);
|
||||
|
||||
# Clean up the Layouts we created
|
||||
foreach ($layouts as $lay) {
|
||||
$lay->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List specific layouts
|
||||
* @group minimal
|
||||
* @group destructive
|
||||
* @depends testListKnown
|
||||
* @depends testAddSuccess
|
||||
* @dataProvider provideSuccessCases
|
||||
*/
|
||||
public function testListFilter($layoutName, $layoutDescription, $layoutTemplateId, $layoutResolutionType)
|
||||
{
|
||||
if (count($this->startLayouts) > 1) {
|
||||
$this->skipTest("There are pre-existing Layouts");
|
||||
return;
|
||||
}
|
||||
|
||||
# Load in a known set of layouts
|
||||
# We can assume this works since we depend upon the test which
|
||||
# has previously added and removed these without issue:
|
||||
$cases = $this->provideSuccessCases();
|
||||
$layouts = [];
|
||||
foreach ($cases as $case) {
|
||||
$layouts[] = (new XiboLayout($this->getEntityProvider()))->create($case[0], $case[1], $case[2], $this->getResolutionId($case[3]));
|
||||
}
|
||||
|
||||
// Fitler for our specific layout
|
||||
$response = $this->sendRequest('GET','/layout', ['name' => $layoutName]);
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
|
||||
# There should be at least one match
|
||||
$this->assertGreaterThanOrEqual(1, $object->data->recordsTotal);
|
||||
|
||||
$flag = false;
|
||||
# Check that for the records returned, $layoutName is in the groups names
|
||||
foreach ($object->data->data as $lay) {
|
||||
if (strpos($layoutName, $lay->layout) == 0) {
|
||||
$flag = true;
|
||||
}
|
||||
else {
|
||||
// The object we got wasn't the exact one we searched for
|
||||
// Make sure all the words we searched for are in the result
|
||||
foreach (array_map('trim',explode(",",$layoutName)) as $word) {
|
||||
assertTrue((strpos($word, $lay->layout) !== false), 'Layout returned did not match the query string: ' . $lay->layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertTrue($flag, 'Search term not found');
|
||||
|
||||
// Remove the Layouts we've created
|
||||
foreach ($layouts as $lay) {
|
||||
$lay->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (LayoutName, description, layoutID (template), resolution ID)
|
||||
* @return array
|
||||
*/
|
||||
public function provideSuccessCases()
|
||||
{
|
||||
# Data for testAddSuccess, easily expandable - just add another set of data below
|
||||
return [
|
||||
// Multi-language layouts
|
||||
'English 1' => ['phpunit test Layout', 'Api', NULL, 'landscape'],
|
||||
'French 1' => ['Test de Français 1', 'Bienvenue à la suite de tests Xibo', NULL, 'landscape'],
|
||||
'German 1' => ['Deutsch Prüfung 1', 'Weiß mit schwarzem Text', NULL, 'landscape'],
|
||||
'Simplified Chinese 1' => ['试验组', '测试组描述', NULL, 'landscape'],
|
||||
'Portrait layout' => ['Portrait layout', '1080x1920', '', 'portrait'],
|
||||
'No Description' => ['Just the title and resolution', NULL, '', 'portrait'],
|
||||
'Just title' => ['Just the name', NULL, NULL, 'portrait']
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (LayoutName, description, layoutID (template), resolution ID)
|
||||
* @return array
|
||||
*/
|
||||
public function provideFailureCases()
|
||||
{
|
||||
# Data for testAddfailure, easily expandable - just add another set of data below
|
||||
return [
|
||||
// Description is limited to 255 characters
|
||||
'Description over 254 characters' => ['Too long description', Random::generateString(255), '', 'landscape'],
|
||||
// Missing layout names
|
||||
'layout name empty' => ['', 'Layout name is empty', '', 'landscape'],
|
||||
'Layout name null' => [null, 'Layout name is null', '', 'landscape'],
|
||||
'Wrong resolution ID' => ['id not found', 'not found exception', '', 'invalid']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Try and add two layouts with the same name
|
||||
*/
|
||||
public function testAddDuplicate()
|
||||
{
|
||||
# Check if there are layouts with that name already in the system
|
||||
$flag = true;
|
||||
foreach ($this->startLayouts as $layout) {
|
||||
if ($layout->layout == 'phpunit layout') {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
# Load in a known layout if it's not there already
|
||||
$landscapeId = $this->getResolutionId('landscape');
|
||||
|
||||
if ($flag) {
|
||||
(new XiboLayout($this->getEntityProvider()))->create(
|
||||
'phpunit layout',
|
||||
'phpunit layout',
|
||||
'',
|
||||
$landscapeId
|
||||
);
|
||||
}
|
||||
|
||||
$response = $this->sendRequest('POST','/layout', [
|
||||
'name' => 'phpunit layout',
|
||||
'description' => 'phpunit layout',
|
||||
'resolutionId' => $landscapeId
|
||||
]);
|
||||
$this->assertSame(409, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode() . '. Body = ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(false, $object->success);
|
||||
$this->assertContains('You already own a Layout called ', $object->error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing layout
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
// Create a known layout with a random name for us to work with.
|
||||
// it will automatically get deleted in tearDown()
|
||||
$layout = $this->createLayout();
|
||||
|
||||
// We do not need to checkout the Layout to perform an edit of its top level data.
|
||||
// Change the layout name and description
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = Random::generateString(8, 'description');
|
||||
$response = $this->sendRequest('PUT','/layout/' . $layout->layoutId, [
|
||||
'name' => $name,
|
||||
'description' => $description
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
# Examine the returned object and check that it's what we expect
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->layout);
|
||||
$this->assertSame($description, $object->data->description);
|
||||
# Check that the layout was actually renamed
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($name, $layout->layout);
|
||||
$this->assertSame($description, $layout->description);
|
||||
# Clean up the Layout as we no longer need it
|
||||
$layout->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing layout that should fail because of negative value in the backgroundzIndex
|
||||
*/
|
||||
public function testEditFailure()
|
||||
{
|
||||
// Create a known layout with a random name for us to work with.
|
||||
// it will automatically get deleted in tearDown()
|
||||
$layout = $this->createLayout();
|
||||
|
||||
// Set a background z-index that is outside parameters
|
||||
$response = $this->sendRequest('PUT','/layout/' . $layout->layoutId, [
|
||||
'backgroundColor' => $layout->backgroundColor,
|
||||
'backgroundzIndex' => -1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete
|
||||
* @group minimal
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
$name1 = Random::generateString(8, 'phpunit');
|
||||
$name2 = Random::generateString(8, 'phpunit');
|
||||
# Load in a couple of known layouts
|
||||
$layout1 = (new XiboLayout($this->getEntityProvider()))->create($name1, 'phpunit description', '', $this->getResolutionId('landscape'));
|
||||
$layout2 = (new XiboLayout($this->getEntityProvider()))->create($name2, 'phpunit description', '', $this->getResolutionId('landscape'));
|
||||
# Delete the one we created last
|
||||
$response = $this->sendRequest('DELETE','/layout/' . $layout2->layoutId);
|
||||
# This should return 204 for success
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Check only one remains
|
||||
$layouts = (new XiboLayout($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->assertEquals(count($this->startLayouts) + 1, count($layouts));
|
||||
$flag = false;
|
||||
foreach ($layouts as $layout) {
|
||||
if ($layout->layoutId == $layout1->layoutId) {
|
||||
$flag = true;
|
||||
}
|
||||
}
|
||||
$this->assertTrue($flag, 'Layout ID ' . $layout1->layoutId . ' was not found after deleting a different layout');
|
||||
$layout1->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to delete a layout that is assigned to a campaign
|
||||
*/
|
||||
public function testDeleteAssigned()
|
||||
{
|
||||
# Load in a known layout
|
||||
/** @var XiboLayout $layout */
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->create('phpunit layout assigned', 'phpunit layout', '', $this->getResolutionId('landscape'));
|
||||
// Make a campaign with a known name
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$campaign = (new XiboCampaign($this->getEntityProvider()))->create($name);
|
||||
|
||||
// Assign layout to campaign
|
||||
$this->getEntityProvider()->post('/campaign/layout/assign/' . $campaign->campaignId, [
|
||||
'layoutId' => $layout->layoutId
|
||||
]);
|
||||
|
||||
# Check if it's assigned
|
||||
$campaignCheck = (new XiboCampaign($this->getEntityProvider()))->getById($campaign->campaignId);
|
||||
$this->assertSame(1, $campaignCheck->numberLayouts);
|
||||
# Try to Delete the layout assigned to the campaign
|
||||
$response = $this->sendRequest('DELETE','/layout/' . $layout->layoutId);
|
||||
# This should return 204 for success
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Layout Retire
|
||||
*/
|
||||
public function testRetire()
|
||||
{
|
||||
// Get known layout
|
||||
$layout = $this->createLayout();
|
||||
|
||||
// Call retire
|
||||
$response = $this->sendRequest('PUT','/layout/retire/' . $layout->layoutId, [], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
|
||||
// Get the same layout again and make sure its retired = 1
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->getById($layout->layoutId);
|
||||
$this->assertSame(1, $layout->retired, 'Retired flag not updated');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Unretire
|
||||
*/
|
||||
public function testUnretire()
|
||||
{
|
||||
// Get known layout
|
||||
/** @var XiboLayout $layout */
|
||||
$layout = $this->createLayout();
|
||||
|
||||
// Retire it
|
||||
$this->getEntityProvider()->put('/layout/retire/' . $layout->layoutId);
|
||||
|
||||
// Call layout edit with this Layout
|
||||
$response = $this->sendRequest('PUT','/layout/unretire/' . $layout->layoutId, [], [
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded'
|
||||
]);
|
||||
|
||||
// Make sure that was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
|
||||
// Get the same layout again and make sure its retired = 0
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->getById($layout->layoutId);
|
||||
|
||||
$this->assertSame(0, $layout->retired, 'Retired flag not updated. ' . $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new region to a specific layout
|
||||
* @dataProvider regionSuccessCases
|
||||
*/
|
||||
public function testAddRegionSuccess($regionWidth, $regionHeight, $regionTop, $regionLeft)
|
||||
{
|
||||
// Create a Layout and Checkout
|
||||
$layout = $this->createLayout();
|
||||
$layout = $this->getDraft($layout);
|
||||
|
||||
// Add region to our layout with data from regionSuccessCases
|
||||
$response = $this->sendRequest('POST','/region/' . $layout->layoutId, [
|
||||
'width' => $regionWidth,
|
||||
'height' => $regionHeight,
|
||||
'top' => $regionTop,
|
||||
'left' => $regionLeft
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Check if region has intended values
|
||||
$this->assertSame($regionWidth, $object->data->width);
|
||||
$this->assertSame($regionHeight, $object->data->height);
|
||||
$this->assertSame($regionTop, $object->data->top);
|
||||
$this->assertSame($regionLeft, $object->data->left);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (width, height, top, left)
|
||||
* @return array
|
||||
*/
|
||||
public function regionSuccessCases()
|
||||
{
|
||||
return [
|
||||
// various correct regions
|
||||
'region 1' => [500, 350, 100, 150],
|
||||
'region 2' => [350, 200, 50, 50],
|
||||
'region 3' => [69, 69, 20, 420],
|
||||
'region 4 no offsets' => [69, 69, 0, 0]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddFailure - test adding various regions that should be invalid
|
||||
* @dataProvider regionFailureCases
|
||||
*/
|
||||
public function testAddRegionFailure($regionWidth, $regionHeight, $regionTop, $regionLeft, $expectedHttpCode, $expectedWidth, $expectedHeight)
|
||||
{
|
||||
// Create a Layout and Checkout
|
||||
$layout = $this->createLayout();
|
||||
$layout = $this->getDraft($layout);
|
||||
|
||||
# Add region to our layout with datafrom regionFailureCases
|
||||
$response = $this->sendRequest('POST','/region/' . $layout->layoutId, [
|
||||
'width' => $regionWidth,
|
||||
'height' => $regionHeight,
|
||||
'top' => $regionTop,
|
||||
'left' => $regionLeft
|
||||
]);
|
||||
|
||||
# Check if we receive failure as expected
|
||||
$this->assertSame($expectedHttpCode, $response->getStatusCode(), 'Expecting failure, received ' . $response->getBody());
|
||||
if ($expectedHttpCode == 200) {
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($expectedWidth, $object->data->width);
|
||||
$this->assertSame($expectedHeight, $object->data->height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (width, height, top, left)
|
||||
* @return array
|
||||
*/
|
||||
public function regionFailureCases()
|
||||
{
|
||||
return [
|
||||
// various incorrect regions
|
||||
'region no size' => [NULL, NULL, 20, 420, 200, 250, 250],
|
||||
'region negative dimensions' => [-69, -420, 20, 420, 422, null, null]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit known region
|
||||
*/
|
||||
public function testEditRegion()
|
||||
{
|
||||
// Create a Layout and Checkout
|
||||
$layout = $this->createLayout();
|
||||
$layout = $this->getDraft($layout);
|
||||
|
||||
# Add region to our layout
|
||||
$region = (new XiboRegion($this->getEntityProvider()))->create($layout->layoutId, 200,300,75,125);
|
||||
|
||||
# Edit region
|
||||
$response = $this->sendRequest('PUT','/region/' . $region->regionId, [
|
||||
'name' => $layout->layout . ' edited',
|
||||
'width' => 700,
|
||||
'height' => 500,
|
||||
'top' => 400,
|
||||
'left' => 400,
|
||||
'loop' => 0,
|
||||
'zIndex' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
# Check if successful
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Check if region has updated values
|
||||
$this->assertSame(700, $object->data->width);
|
||||
$this->assertSame(500, $object->data->height);
|
||||
$this->assertSame(400, $object->data->top);
|
||||
$this->assertSame(400, $object->data->left);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit known region that should fail because of negative z-index value
|
||||
*/
|
||||
public function testEditRegionFailure()
|
||||
{
|
||||
// Create a Layout and Checkout
|
||||
$layout = $this->createLayout();
|
||||
$layout = $this->getDraft($layout);
|
||||
|
||||
# Add region to our layout
|
||||
$region = (new XiboRegion($this->getEntityProvider()))->create($layout->layoutId, 200,300,75,125);
|
||||
# Edit region
|
||||
$response = $this->sendRequest('PUT','/region/' . $region->regionId, [
|
||||
'width' => 700,
|
||||
'height' => 500,
|
||||
'top' => 400,
|
||||
'left' => 400,
|
||||
'loop' => 0,
|
||||
'zIndex' => -1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
# Check if it failed
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* delete region test
|
||||
*/
|
||||
public function testDeleteRegion()
|
||||
{
|
||||
// Create a Layout and Checkout
|
||||
$layout = $this->createLayout();
|
||||
$layout = $this->getDraft($layout);
|
||||
|
||||
$region = (new XiboRegion($this->getEntityProvider()))->create($layout->layoutId, 200, 670, 100, 100);
|
||||
|
||||
# Delete region
|
||||
$response = $this->sendRequest('DELETE','/region/' . $region->regionId);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tag to a layout
|
||||
*/
|
||||
public function testAddTag()
|
||||
{
|
||||
# Create layout
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->create($name, 'phpunit description', '', $this->getResolutionId('landscape'));
|
||||
# Assign new tag to our layout
|
||||
$response = $this->sendRequest('POST','/layout/' . $layout->layoutId . '/tag' , [
|
||||
'tag' => ['API']
|
||||
]);
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->getById($layout->layoutId);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
foreach ($layout->tags as $tag) {
|
||||
$this->assertSame('API', $tag['tag']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete tags from layout
|
||||
*/
|
||||
public function testDeleteTag()
|
||||
{
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->create($name, 'phpunit description', '', $this->getResolutionId('landscape'));
|
||||
$tag = 'API';
|
||||
$layout->addTag($tag);
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->getById($layout->layoutId);
|
||||
|
||||
$response = $this->sendRequest('POST','/layout/' . $layout->layoutId . '/untag', [
|
||||
'tag' => [$tag]
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$layout->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate layout status
|
||||
*/
|
||||
public function testStatus()
|
||||
{
|
||||
# Create layout
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->create($name, 'phpunit description', '', $this->getResolutionId('landscape'));
|
||||
# Calculate layouts status
|
||||
$response = $this->sendRequest('GET','/layout/status/' . $layout->layoutId);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy Layout Test
|
||||
*/
|
||||
public function testCopy()
|
||||
{
|
||||
# Load in a known layout
|
||||
/** @var XiboLayout $layout */
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit layout',
|
||||
'',
|
||||
$this->getResolutionId('landscape')
|
||||
);
|
||||
|
||||
// Generate new random name
|
||||
$nameCopy = Random::generateString(8, 'phpunit');
|
||||
|
||||
// Call copy
|
||||
$response = $this->sendRequest('POST','/layout/copy/' . $layout->layoutId, [
|
||||
'name' => $nameCopy,
|
||||
'description' => 'Copy',
|
||||
'copyMediaFiles' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
# Check if copied layout has correct name
|
||||
$this->assertSame($nameCopy, $object->data->layout);
|
||||
|
||||
# Clean up the Layout as we no longer need it
|
||||
$this->assertTrue($layout->delete(), 'Unable to delete ' . $layout->layoutId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Position Test
|
||||
*/
|
||||
public function testPosition()
|
||||
{
|
||||
// Create a Layout and Checkout
|
||||
$layout = $this->createLayout();
|
||||
$layout = $this->getDraft($layout);
|
||||
|
||||
# Create Two known regions and add them to that layout
|
||||
$region1 = (new XiboRegion($this->getEntityProvider()))->create($layout->layoutId, 200,670,75,125);
|
||||
$region2 = (new XiboRegion($this->getEntityProvider()))->create($layout->layoutId, 200,300,475,625);
|
||||
|
||||
# Reposition regions on that layout
|
||||
$regionJson = json_encode([
|
||||
[
|
||||
'regionid' => $region1->regionId,
|
||||
'width' => 700,
|
||||
'height' => 500,
|
||||
'top' => 400,
|
||||
'left' => 400
|
||||
],
|
||||
[
|
||||
'regionid' => $region2->regionId,
|
||||
'width' => 100,
|
||||
'height' => 100,
|
||||
'top' => 40,
|
||||
'left' => 40
|
||||
]
|
||||
]);
|
||||
|
||||
$response = $this->sendRequest('PUT','/region/position/all/' . $layout->layoutId, [
|
||||
'regions' => $regionJson
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
# Check if successful
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(true, $object->success);
|
||||
$this->assertSame(200, $object->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Position Test with incorrect parameters (missing height and incorrect spelling)
|
||||
*/
|
||||
public function testPositionFailure()
|
||||
{
|
||||
// Create a Layout and Checkout
|
||||
$layout = $this->createLayout();
|
||||
$layout = $this->getDraft($layout);
|
||||
|
||||
# Create Two known regions and add them to that layout
|
||||
$region1 = (new XiboRegion($this->getEntityProvider()))->create($layout->layoutId, 200,670,75,125);
|
||||
$region2 = (new XiboRegion($this->getEntityProvider()))->create($layout->layoutId, 200,300,475,625);
|
||||
|
||||
# Reposition regions on that layout with incorrect/missing parameters
|
||||
$regionJson = json_encode([
|
||||
[
|
||||
'regionid' => $region1->regionId,
|
||||
'width' => 700,
|
||||
'top' => 400,
|
||||
'left' => 400
|
||||
],
|
||||
[
|
||||
'regionid' => $region2->regionId,
|
||||
'heigTH' => 100,
|
||||
'top' => 40,
|
||||
'left' => 40
|
||||
]
|
||||
]);
|
||||
|
||||
$response = $this->sendRequest('PUT','/region/position/all/' . $layout->layoutId, [
|
||||
'regions' => $regionJson
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
# Check if it fails as expected
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(false, $object->success);
|
||||
$this->assertSame(422, $object->httpStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Drawer to the Layout
|
||||
*/
|
||||
public function testAddDrawer()
|
||||
{
|
||||
// Create a Layout and Checkout
|
||||
$layout = $this->createLayout();
|
||||
$layout = $this->getDraft($layout);
|
||||
|
||||
// Add Drawer
|
||||
$response = $this->sendRequest('POST', '/region/drawer/' . $layout->layoutId);
|
||||
|
||||
// Check if successful
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
// Check if drawer has the right values
|
||||
$this->assertSame($layout->width, $object->data->width);
|
||||
$this->assertSame($layout->height, $object->data->height);
|
||||
$this->assertSame(0, $object->data->top);
|
||||
$this->assertSame(0, $object->data->left);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a Drawer to the Layout
|
||||
*/
|
||||
public function testSaveDrawer()
|
||||
{
|
||||
// Create a Layout and Checkout
|
||||
$layout = $this->createLayout();
|
||||
$layout = $this->getDraft($layout);
|
||||
|
||||
// Add Drawer
|
||||
$drawer = $this->getEntityProvider()->post('/region/drawer/' . $layout->layoutId);
|
||||
|
||||
// Save drawer
|
||||
$response = $this->sendRequest('PUT', '/region/drawer/' . $drawer['regionId'], [
|
||||
'width' => 1280,
|
||||
'height' => 720
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
// Check if successful
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
// Check if drawer has the right values
|
||||
$this->assertSame(1280, $object->data->width);
|
||||
$this->assertSame(720, $object->data->height);
|
||||
$this->assertSame(0, $object->data->top);
|
||||
$this->assertSame(0, $object->data->left);
|
||||
}
|
||||
}
|
||||
280
tests/integration/LibraryTest.php
Normal file
280
tests/integration/LibraryTest.php
Normal file
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class LibraryTest extends LocalWebTestCase
|
||||
{
|
||||
protected $startMedias;
|
||||
protected $mediaName;
|
||||
protected $mediaType;
|
||||
protected $mediaId;
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startMedias = (new XiboLibrary($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all media files that weren't there initially
|
||||
$finalMedias = (new XiboLibrary($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining media files and nuke them
|
||||
foreach ($finalMedias as $media) {
|
||||
/** @var XiboLibrary $media */
|
||||
$flag = true;
|
||||
foreach ($this->startMedias as $startMedia) {
|
||||
if ($startMedia->mediaId == $media->mediaId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$media->deleteAssigned();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $media->mediaId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* List all file in library
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
# Get all library items
|
||||
$response = $this->sendRequest('GET','/library');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new file to library
|
||||
*/
|
||||
public function testAdd()
|
||||
{
|
||||
# Using XiboLibrary wrapper to upload new file to the CMS, need to provide (name, file location)
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create('API video test', PROJECT_ROOT . '/tests/resources/HLH264.mp4');
|
||||
|
||||
$media->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new file to library and replace old one in all layouts
|
||||
*/
|
||||
public function testReplace()
|
||||
{
|
||||
# Using XiboLibrary wrapper to upload new file to the CMS, need to provide (name, file location)
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create('flowers', PROJECT_ROOT . '/tests/resources/xts-flowers-001.jpg');
|
||||
# Replace the image and update it in all layouts (name, file location, old media id, replace in all layouts flag, delete old revision flag)
|
||||
$media2 = (new XiboLibrary($this->getEntityProvider()))->create('API replace image', PROJECT_ROOT . '/tests/resources/xts-flowers-002.jpg', $media->mediaId, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* try to add not allowed filetype
|
||||
*/
|
||||
public function testAddEmpty()
|
||||
{
|
||||
# Using XiboLibrary wrapper to upload new file to the CMS, need to provide (name, file location)
|
||||
$this->expectException('\Xibo\OAuth2\Client\Exception\XiboApiException');
|
||||
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create('API incorrect file 2', PROJECT_ROOT . '/tests/resources/empty.txt');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tags to media
|
||||
*/
|
||||
public function testAddTag()
|
||||
{
|
||||
# Using XiboLibrary wrapper to upload new file to the CMS, need to provide (name, file location)
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create('flowers 2', PROJECT_ROOT . '/tests/resources/xts-flowers-001.jpg');
|
||||
|
||||
$response = $this->sendRequest('POST','/library/' . $media->mediaId . '/tag', [
|
||||
'tag' => ['API']
|
||||
]);
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->getById($media->mediaId);
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
foreach ($media->tags as $tag) {
|
||||
$this->assertSame('API', $tag['tag']);
|
||||
}
|
||||
$media->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete tags from media
|
||||
* @group broken
|
||||
*/
|
||||
public function testDeleteTag()
|
||||
{
|
||||
# Using XiboLibrary wrapper to upload new file to the CMS, need to provide (name, file location)
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create('flowers', PROJECT_ROOT . '/tests/resources/xts-flowers-001.jpg');
|
||||
$media->AddTag('API');
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->getById($media->mediaId);
|
||||
$this->assertSame('API', $media->tags);
|
||||
|
||||
$response = $this->sendRequest('POST','/library/' . $media->mediaId . '/untag', [
|
||||
'tag' => ['API']
|
||||
]);
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->getById($media->mediaId);
|
||||
print_r($media->tags);
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$media->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit media file
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
# Using XiboLibrary wrapper to upload new file to the CMS, need to provide (name, file location)
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create('API video 4', PROJECT_ROOT . '/tests/resources/HLH264.mp4');
|
||||
# Generate new random name
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
# Edit media file, change the name
|
||||
$response = $this->sendRequest('PUT','/library/' . $media->mediaId, [
|
||||
'name' => $name,
|
||||
'duration' => 50,
|
||||
'retired' => $media->retired,
|
||||
'tags' => $media->tags,
|
||||
'updateInLayouts' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->getById($media->mediaId);
|
||||
$this->assertSame($name, $media->name);
|
||||
$media->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete added media
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
# Using XiboLibrary wrapper to upload new file to the CMS, need to provide (name, file location)
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create('API video 4', PROJECT_ROOT . '/tests/resources/HLH264.mp4');
|
||||
# Delete added media file
|
||||
$response = $this->sendRequest('DELETE','/library/' . $media->mediaId);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Library tidy
|
||||
*/
|
||||
public function testTidy()
|
||||
{
|
||||
$response = $this->sendRequest('DELETE','/library/tidy');
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
}
|
||||
|
||||
public function testUploadFromUrl()
|
||||
{
|
||||
shell_exec('cp -r ' . PROJECT_ROOT . '/tests/resources/rss/image1.jpg ' . PROJECT_ROOT . '/web');
|
||||
|
||||
$response = $this->sendRequest('POST','/library/uploadUrl', [
|
||||
'url' => 'http://localhost/image1.jpg'
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertNotEmpty($object->data, 'Empty Response');
|
||||
$this->assertSame('image', $object->data->mediaType);
|
||||
$this->assertSame(0, $object->data->expires);
|
||||
$this->assertSame('image1', $object->data->name);
|
||||
$this->assertNotEmpty($object->data->mediaId, 'Not successful, MediaId is empty');
|
||||
|
||||
$module = $this->getEntityProvider()->get('/module', ['name' => 'Image']);
|
||||
$moduleDefaultDuration = $module[0]['defaultDuration'];
|
||||
|
||||
$this->assertSame($object->data->duration, $moduleDefaultDuration);
|
||||
|
||||
shell_exec('rm -r ' . PROJECT_ROOT . '/web/image1.jpg');
|
||||
}
|
||||
|
||||
public function testUploadFromUrlWithType()
|
||||
{
|
||||
shell_exec('cp -r ' . PROJECT_ROOT . '/tests/resources/rss/image2.jpg ' . PROJECT_ROOT . '/web');
|
||||
|
||||
$response = $this->getEntityProvider()->post('/library/uploadUrl?envelope=1', [
|
||||
'url' => 'http://localhost/image2.jpg',
|
||||
'type' => 'image'
|
||||
]);
|
||||
|
||||
$this->assertSame(201, $response['status'], json_encode($response));
|
||||
$this->assertNotEmpty($response['data'], 'Empty Response');
|
||||
$this->assertSame('image', $response['data']['mediaType']);
|
||||
$this->assertSame(0, $response['data']['expires']);
|
||||
$this->assertSame('image2', $response['data']['name']);
|
||||
$this->assertNotEmpty($response['data']['mediaId'], 'Not successful, MediaId is empty');
|
||||
|
||||
$module = $this->getEntityProvider()->get('/module', ['name' => 'Image']);
|
||||
$moduleDefaultDuration = $module[0]['defaultDuration'];
|
||||
|
||||
$this->assertSame($response['data']['duration'], $moduleDefaultDuration);
|
||||
|
||||
shell_exec('rm -r ' . PROJECT_ROOT . '/web/image2.jpg');
|
||||
}
|
||||
|
||||
public function testUploadFromUrlWithTypeAndName()
|
||||
{
|
||||
shell_exec('cp -r ' . PROJECT_ROOT . '/tests/resources/HLH264.mp4 ' . PROJECT_ROOT . '/web');
|
||||
|
||||
$response = $this->getEntityProvider()->post('/library/uploadUrl?envelope=1', [
|
||||
'url' => 'http://localhost/HLH264.mp4',
|
||||
'type' => 'video',
|
||||
'optionalName' => 'PHPUNIT URL upload video'
|
||||
]);
|
||||
|
||||
$this->assertSame(201, $response['status'], json_encode($response));
|
||||
$this->assertNotEmpty($response['data'], 'Empty Response');
|
||||
$this->assertSame('video', $response['data']['mediaType']);
|
||||
$this->assertSame(0, $response['data']['expires']);
|
||||
$this->assertSame('PHPUNIT URL upload video', $response['data']['name']);
|
||||
$this->assertNotEmpty($response['data']['mediaId'], 'Not successful, MediaId is empty');
|
||||
|
||||
// for videos we expect the Media duration to be the actual video duration.
|
||||
$this->assertSame($response['data']['duration'], 78);
|
||||
|
||||
shell_exec('rm -r ' . PROJECT_ROOT . '/web/HLH264.mp4');
|
||||
}
|
||||
}
|
||||
118
tests/integration/MenuBoardCategoryTest.php
Normal file
118
tests/integration/MenuBoardCategoryTest.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2021 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class MenuBoardCategoryTest extends LocalWebTestCase
|
||||
{
|
||||
private $menuBoard;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->menuBoard = $this->getEntityProvider()->post('/menuboard', [
|
||||
'name' => Random::generateString(10, 'phpunit'),
|
||||
'description' => 'Description for test Menu Board'
|
||||
]);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
if ($this->menuBoard['menuId'] !== null) {
|
||||
$this->getEntityProvider()->delete('/menuboard/' . $this->menuBoard['menuId']);
|
||||
}
|
||||
}
|
||||
|
||||
public function testListEmpty()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/menuboard/' . $this->menuBoard['menuId'] . '/categories');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertEquals(0, $object->data->recordsTotal);
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create(Random::generateString(10, 'API Image'), PROJECT_ROOT . '/tests/resources/xts-night-001.jpg');
|
||||
$name = Random::generateString(10, 'Category Add');
|
||||
|
||||
$response = $this->sendRequest('POST', '/menuboard/' . $this->menuBoard['menuId'] . '/category', [
|
||||
'name' => $name,
|
||||
'mediaId' => $media->mediaId
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
$this->assertSame($media->mediaId, $object->data->mediaId);
|
||||
|
||||
$media->delete();
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$menuBoardCategory = $this->getEntityProvider()->post('/menuboard/' . $this->menuBoard['menuId'] . '/category', [
|
||||
'name' => 'Test Menu Board Category Edit'
|
||||
]);
|
||||
$name = Random::generateString(10, 'Category Edit');
|
||||
|
||||
$response = $this->sendRequest('PUT', '/menuboard/' . $menuBoardCategory['menuCategoryId'] . '/category', [
|
||||
'name' => $name,
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$menuBoardCategory = $this->getEntityProvider()->post('/menuboard/' . $this->menuBoard['menuId'] . '/category', [
|
||||
'name' => 'Test Menu Board Category Delete'
|
||||
]);
|
||||
|
||||
$response = $this->sendRequest('DELETE', '/menuboard/' . $menuBoardCategory['menuCategoryId'] . '/category');
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status);
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
}
|
||||
}
|
||||
198
tests/integration/MenuBoardProductTest.php
Normal file
198
tests/integration/MenuBoardProductTest.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2021 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class MenuBoardProductTest extends LocalWebTestCase
|
||||
{
|
||||
private $menuBoard;
|
||||
private $menuBoardCategory;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->menuBoard = $this->getEntityProvider()->post('/menuboard', [
|
||||
'name' => Random::generateString(10, 'phpunit'),
|
||||
'description' => 'Description for test Menu Board'
|
||||
]);
|
||||
|
||||
$this->menuBoardCategory = $this->getEntityProvider()->post('/menuboard/' . $this->menuBoard['menuId'] . '/category', [
|
||||
'name' => 'Test Menu Board Category Edit'
|
||||
]);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
if ($this->menuBoard['menuId'] !== null) {
|
||||
$this->getEntityProvider()->delete('/menuboard/' . $this->menuBoard['menuId']);
|
||||
}
|
||||
}
|
||||
|
||||
public function testListEmpty()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/menuboard/' . $this->menuBoardCategory['menuCategoryId'] . '/products');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertEquals(0, $object->data->recordsTotal);
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->create(Random::generateString(10, 'API Image'), PROJECT_ROOT . '/tests/resources/xts-night-001.jpg');
|
||||
$name = Random::generateString(10, 'Product Add');
|
||||
|
||||
$response = $this->sendRequest('POST', '/menuboard/' . $this->menuBoardCategory['menuCategoryId'] . '/product', [
|
||||
'name' => $name,
|
||||
'mediaId' => $media->mediaId,
|
||||
'price' => '$12.40',
|
||||
'description' => 'Product Description',
|
||||
'allergyInfo' => 'N/A',
|
||||
'availability' => 1,
|
||||
'productOptions' => ['small', 'medium', 'large'],
|
||||
'productValues' => ['$10.40', '$15.40', '$20.20']
|
||||
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
$this->assertSame($media->mediaId, $object->data->mediaId);
|
||||
$this->assertSame('$12.40', $object->data->price);
|
||||
$this->assertSame('Product Description', $object->data->description);
|
||||
$this->assertSame('N/A', $object->data->allergyInfo);
|
||||
$this->assertSame(1, $object->data->availability);
|
||||
|
||||
// product options are ordered by option name
|
||||
$this->assertSame($object->id, $object->data->productOptions[2]->menuProductId);
|
||||
$this->assertSame('small', $object->data->productOptions[2]->option);
|
||||
$this->assertSame('$10.40', $object->data->productOptions[2]->value);
|
||||
$this->assertSame($object->id, $object->data->productOptions[1]->menuProductId);
|
||||
$this->assertSame('medium', $object->data->productOptions[1]->option);
|
||||
$this->assertSame('$15.40', $object->data->productOptions[1]->value);
|
||||
$this->assertSame($object->id, $object->data->productOptions[0]->menuProductId);
|
||||
$this->assertSame('large', $object->data->productOptions[0]->option);
|
||||
$this->assertSame('$20.20', $object->data->productOptions[0]->value);
|
||||
|
||||
$media->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFailureCases
|
||||
*/
|
||||
public function testAddFailure($name, $price)
|
||||
{
|
||||
$response = $this->sendRequest('POST', '/menuboard/' . $this->menuBoardCategory['menuCategoryId'] . '/product', [
|
||||
'name' => $name,
|
||||
'price' => $price
|
||||
]);
|
||||
|
||||
# check if they fail as expected
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (name, price, productOptions, productValues)
|
||||
* @return array
|
||||
*/
|
||||
public function provideFailureCases()
|
||||
{
|
||||
return [
|
||||
'empty name' => ['', '$11', [], []],
|
||||
'empty price' => ['Test Product', null, [], []]
|
||||
];
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$menuBoardProduct = $this->getEntityProvider()->post('/menuboard/' . $this->menuBoardCategory['menuCategoryId'] . '/product', [
|
||||
'name' => 'Test Menu Board Product Edit',
|
||||
'price' => '$11.11',
|
||||
'productOptions' => ['small', 'medium', 'large'],
|
||||
'productValues' => ['$10.40', '$15.40', '$20.20']
|
||||
]);
|
||||
$name = Random::generateString(10, 'Product Edit');
|
||||
|
||||
$response = $this->sendRequest('PUT', '/menuboard/' . $menuBoardProduct['menuProductId'] . '/product', [
|
||||
'name' => $name,
|
||||
'price' => '$9.99',
|
||||
'description' => 'Product Description Edited',
|
||||
'allergyInfo' => '',
|
||||
'availability' => 1,
|
||||
'productOptions' => ['small', 'medium', 'large'],
|
||||
'productValues' => ['$8.40', '$12.40', '$15.20']
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
$this->assertSame('$9.99', $object->data->price);
|
||||
$this->assertSame('Product Description Edited', $object->data->description);
|
||||
$this->assertSame('', $object->data->allergyInfo);
|
||||
$this->assertSame(1, $object->data->availability);
|
||||
|
||||
// product options are ordered by option name
|
||||
$this->assertSame($object->id, $object->data->productOptions[2]->menuProductId);
|
||||
$this->assertSame('small', $object->data->productOptions[2]->option);
|
||||
$this->assertSame('$8.40', $object->data->productOptions[2]->value);
|
||||
$this->assertSame($object->id, $object->data->productOptions[1]->menuProductId);
|
||||
$this->assertSame('medium', $object->data->productOptions[1]->option);
|
||||
$this->assertSame('$12.40', $object->data->productOptions[1]->value);
|
||||
$this->assertSame($object->id, $object->data->productOptions[0]->menuProductId);
|
||||
$this->assertSame('large', $object->data->productOptions[0]->option);
|
||||
$this->assertSame('$15.20', $object->data->productOptions[0]->value);
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$menuBoardProduct = $this->getEntityProvider()->post('/menuboard/' . $this->menuBoardCategory['menuCategoryId'] . '/product', [
|
||||
'name' => 'Test Menu Board Category Delete',
|
||||
'price' => '$11.11'
|
||||
]);
|
||||
|
||||
$response = $this->sendRequest('DELETE', '/menuboard/' . $menuBoardProduct['menuProductId'] . '/product');
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status);
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
}
|
||||
}
|
||||
114
tests/integration/MenuBoardTest.php
Normal file
114
tests/integration/MenuBoardTest.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2021 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class MenuBoardTest extends LocalWebTestCase
|
||||
{
|
||||
private $menuBoardId;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
if ($this->menuBoardId !== null) {
|
||||
$this->getEntityProvider()->delete('/menuboard/' . $this->menuBoardId);
|
||||
}
|
||||
}
|
||||
|
||||
public function testListAll()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/menuboards');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$name = Random::generateString(10, 'MenuBoard Add');
|
||||
$response = $this->sendRequest('POST', '/menuboard', [
|
||||
'name' => $name,
|
||||
'description' => 'Description for test Menu Board Add'
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
$this->assertSame('Description for test Menu Board Add', $object->data->description);
|
||||
|
||||
$this->menuBoardId = $object->id;
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$menuBoard = $this->getEntityProvider()->post('/menuboard', [
|
||||
'name' => 'Test Menu Board Edit',
|
||||
'description' => 'Description for test Menu Board Edit'
|
||||
]);
|
||||
$name = Random::generateString(10, 'MenuBoard Edit');
|
||||
$response = $this->sendRequest('PUT', '/menuboard/' . $menuBoard['menuId'], [
|
||||
'name' => $name,
|
||||
'description' => 'Test Menu Board Edited description'
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->name);
|
||||
$this->assertSame('Test Menu Board Edited description', $object->data->description);
|
||||
|
||||
$this->menuBoardId = $object->id;
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$menuBoard = $this->getEntityProvider()->post('/menuboard', [
|
||||
'name' => 'Test Menu Board Delete',
|
||||
'description' => 'Description for test Menu Board Delete'
|
||||
]);
|
||||
|
||||
$response = $this->sendRequest('DELETE', '/menuboard/' . $menuBoard['menuId']);
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status);
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
}
|
||||
}
|
||||
196
tests/integration/NotificationTest.php
Normal file
196
tests/integration/NotificationTest.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayGroup;
|
||||
use Xibo\OAuth2\Client\Entity\XiboNotification;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class NotificationTest extends LocalWebTestCase
|
||||
{
|
||||
/** @var XiboDisplayGroup[] */
|
||||
protected $startDisplayGroups;
|
||||
|
||||
/** @var XiboNotification[] */
|
||||
protected $startNotifications;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startDisplayGroups = (new XiboDisplayGroup($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->startNotifications = (new XiboNotification($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all display groups that weren't there initially
|
||||
$finalDisplayGroups = (new XiboDisplayGroup($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
|
||||
# Loop over any remaining display groups and nuke them
|
||||
foreach ($finalDisplayGroups as $displayGroup) {
|
||||
/** @var XiboDisplayGroup $displayGroup */
|
||||
|
||||
$flag = true;
|
||||
|
||||
foreach ($this->startDisplayGroups as $startGroup) {
|
||||
if ($startGroup->displayGroupId == $displayGroup->displayGroupId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($flag) {
|
||||
try {
|
||||
$displayGroup->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $displayGroup->displayGroupId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tearDown all notifications that weren't there initially
|
||||
$finalNotifications = (new XiboNotification($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
|
||||
# Loop over any remaining notifications and nuke them
|
||||
foreach ($finalNotifications as $notification) {
|
||||
/** @var XiboNotification $notification */
|
||||
|
||||
$flag = true;
|
||||
|
||||
foreach ($this->startNotifications as $startNotf) {
|
||||
if ($startNotf->notificationId == $notification->notificationId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($flag) {
|
||||
try {
|
||||
$notification->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $notification->notificationId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* List notifications
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
# Get all notifications
|
||||
$response = $this->sendRequest('GET','/notification');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new Notification
|
||||
*/
|
||||
public function testAdd()
|
||||
{
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create('phpunit group', 'notification description', 0, '');
|
||||
# Add new notification and assign it to our display group
|
||||
$subject = 'API Notification';
|
||||
$response = $this->sendRequest('POST','/notification', [
|
||||
'subject' => $subject,
|
||||
'body' => 'Notification body text',
|
||||
'releaseDt' => '2016-09-01 00:00:00',
|
||||
'isEmail' => 0,
|
||||
'isInterrupt' => 0,
|
||||
'displayGroupIds' => [$displayGroup->displayGroupId]
|
||||
// 'userGroupId' =>
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
# Check if the subject is correctly set
|
||||
$this->assertSame($subject, $object->data->subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete notification
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create('phpunit group', 'phpunit description', 0, '');
|
||||
# Create new notification
|
||||
$notification = (new XiboNotification($this->getEntityProvider()))->create('API subject', 'API body', '2016-09-01 00:00:00', 0, 0, [$displayGroup->displayGroupId]);
|
||||
# Delete notification
|
||||
$response = $this->sendRequest('DELETE','/notification/' . $notification->notificationId);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status);
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit notification
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create('phpunit group', 'phpunit description', 0, '');
|
||||
# Create new notification
|
||||
$notification = (new XiboNotification($this->getEntityProvider()))->create('API subject', 'API body', '2016-09-01 00:00:00', 0, 0, [$displayGroup->displayGroupId]);
|
||||
$notification->releaseDt = Carbon::createFromTimestamp($notification->releaseDt)->format(DateFormatHelper::getSystemFormat());
|
||||
# Create new subject
|
||||
$subjectNew = 'Subject edited via API';
|
||||
# Edit our notification
|
||||
$response = $this->sendRequest('PUT','/notification/' . $notification->notificationId, [
|
||||
'subject' => $subjectNew,
|
||||
'body' => $notification->body,
|
||||
'releaseDt' => $notification->releaseDt,
|
||||
'isEmail' => $notification->isEmail,
|
||||
'isInterrupt' => $notification->isInterrupt,
|
||||
'displayGroupIds' => [$displayGroup->displayGroupId]
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
# Examine the returned object and check that it's what we expect
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($subjectNew, $object->data->subject);
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$notification->delete();
|
||||
}
|
||||
}
|
||||
204
tests/integration/PlayerSoftwareTest.php
Normal file
204
tests/integration/PlayerSoftwareTest.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayProfile;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class PlayerSoftwareTest
|
||||
* @package Xibo\Tests\integration
|
||||
*/
|
||||
class PlayerSoftwareTest extends LocalWebTestCase
|
||||
{
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media2;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplayProfile */
|
||||
protected $displayProfile;
|
||||
|
||||
protected $version;
|
||||
protected $version2;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) . ' Test');
|
||||
|
||||
// Upload version files
|
||||
$uploadVersion = $this->uploadVersionFile(Random::generateString(), PROJECT_ROOT . '/tests/resources/Xibo_for_Android_v1.7_R61.apk');
|
||||
$this->version = $uploadVersion['files'][0];
|
||||
$uploadVersion2 = $this->uploadVersionFile(Random::generateString(), PROJECT_ROOT . '/tests/resources/Xibo_for_Android_v1.8_R108.apk');
|
||||
$this->version2 = $uploadVersion2['files'][0];
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay(null, 'android');
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Create a display profile
|
||||
$this->displayProfile = (new XiboDisplayProfile($this->getEntityProvider()))->create(Random::generateString(), 'android', 0);
|
||||
|
||||
// Edit display profile to add the uploaded apk to the config
|
||||
$this->getEntityProvider()->put('/displayprofile/' . $this->displayProfile->displayProfileId, [
|
||||
'name' => $this->displayProfile->name,
|
||||
'type' => $this->displayProfile->type,
|
||||
'isDefault' => $this->displayProfile->isDefault,
|
||||
'versionMediaId' => $this->version['id']
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
// Delete the version files we've been working with
|
||||
$this->getEntityProvider()->delete('/playersoftware/' . $this->version['id']);
|
||||
$this->getEntityProvider()->delete('/playersoftware/' . $this->version2['id']);
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
// Delete the Display profile
|
||||
$this->displayProfile->delete();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
public function testVersionFromProfile()
|
||||
{
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Edit display, assign it to the created display profile
|
||||
$response = $this->sendRequest('PUT','/display/' . $this->display->displayId, [
|
||||
'display' => $this->display->display,
|
||||
'licensed' => $this->display->licensed,
|
||||
'license' => $this->display->license,
|
||||
'defaultLayoutId' => $this->display->defaultLayoutId,
|
||||
'displayProfileId' => $this->displayProfile->displayProfileId,
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded'] );
|
||||
|
||||
// Check response
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertSame($this->displayProfile->displayProfileId, $object->data->displayProfileId, $response->getBody());
|
||||
|
||||
// Ensure the Version Instructions are present on the Register Display call and that
|
||||
// Register our display
|
||||
$register = $this->getXmdsWrapper()->RegisterDisplay($this->display->license,
|
||||
$this->display->license,
|
||||
'android',
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
'00:16:D9:C9:AL:69',
|
||||
$this->display->xmrChannel,
|
||||
$this->display->xmrPubKey
|
||||
);
|
||||
|
||||
$this->getLogger()->debug($register);
|
||||
|
||||
$this->assertContains($this->version['fileName'], $register, 'Version information not in Register');
|
||||
$this->assertContains('61', $register, 'Version information Code not in Register');
|
||||
}
|
||||
|
||||
public function testVersionOverride()
|
||||
{
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Edit display, set the versionMediaId
|
||||
$response = $this->sendRequest('PUT','/display/' . $this->display->displayId, [
|
||||
'display' => $this->display->display,
|
||||
'licensed' => $this->display->licensed,
|
||||
'license' => $this->display->license,
|
||||
'versionMediaId' => $this->version2['id'],
|
||||
'defaultLayoutId' => $this->display->defaultLayoutId,
|
||||
'displayProfileId' => $this->displayProfile->displayProfileId
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded'] );
|
||||
|
||||
// Check response
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertSame($this->displayProfile->displayProfileId, $object->data->displayProfileId, $response->getBody());
|
||||
$this->assertNotEmpty($object->data->overrideConfig);
|
||||
|
||||
foreach ($object->data->overrideConfig as $override) {
|
||||
if ($override->name === 'versionMediaId') {
|
||||
$this->assertSame($this->version2['id'], $override->value, json_encode($object->data->overrideConfig));
|
||||
}
|
||||
}
|
||||
|
||||
// call register
|
||||
$register = $this->getXmdsWrapper()->RegisterDisplay($this->display->license,
|
||||
$this->display->license,
|
||||
'android',
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
'00:16:D9:C9:AL:69',
|
||||
$this->display->xmrChannel,
|
||||
$this->display->xmrPubKey
|
||||
);
|
||||
// make sure the media ID set on the display itself is in the register
|
||||
$this->getLogger()->debug($register);
|
||||
$this->assertContains($this->version2['fileName'], $register, 'Version information not in Register');
|
||||
$this->assertContains('108', $register, 'Version information Code not in Register');
|
||||
}
|
||||
|
||||
private function uploadVersionFile($fileName, $filePath)
|
||||
{
|
||||
$payload = [
|
||||
[
|
||||
'name' => 'name',
|
||||
'contents' => $fileName
|
||||
],
|
||||
[
|
||||
'name' => 'files',
|
||||
'contents' => fopen($filePath, 'r')
|
||||
]
|
||||
];
|
||||
|
||||
return $this->getEntityProvider()->post('/playersoftware', ['multipart' => $payload]);
|
||||
}
|
||||
}
|
||||
169
tests/integration/PlaylistTest.php
Normal file
169
tests/integration/PlaylistTest.php
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class PlaylistTest
|
||||
* @package Xibo\Tests\integration
|
||||
*/
|
||||
class PlaylistTest extends LocalWebTestCase
|
||||
{
|
||||
/** @var XiboPlaylist[] */
|
||||
private $playlists;
|
||||
|
||||
/** @var XiboPlaylist */
|
||||
private $duplicateName;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->duplicateName = (new XiboPlaylist($this->getEntityProvider()))->hydrate($this->getEntityProvider()->post('/playlist', [
|
||||
'name' => Random::generateString(5, 'playlist')
|
||||
]));
|
||||
|
||||
// Add a Playlist to use for the duplicate name test
|
||||
$this->playlists[] = $this->duplicateName;
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tearing down, removing ' . count($this->playlists));
|
||||
|
||||
// Delete any Playlists we've added
|
||||
foreach ($this->playlists as $playlist) {
|
||||
$this->getEntityProvider()->delete('/playlist/' . $playlist->playlistId);
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function addPlaylistCases()
|
||||
{
|
||||
return [
|
||||
'Normal add' => [200, Random::generateString(5, 'playlist'), null, 0, null, null],
|
||||
'Tags add' => [200, Random::generateString(5, 'playlist'), 'test', 0, null, null],
|
||||
'Dynamic add' => [200, Random::generateString(5, 'playlist'), null, 1, 'test', null]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function addPlaylistFailureCases()
|
||||
{
|
||||
return [
|
||||
'Dynamic without filter' => [422, Random::generateString(5, 'playlist'), null, 1, null, null],
|
||||
'Without a name' => [422, null, null, 1, null, null]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider addPlaylistCases
|
||||
*/
|
||||
public function testAddPlaylist($statusCode, $name, $tags, $isDynamic, $nameFilter, $tagFilter)
|
||||
{
|
||||
// Add this Playlist
|
||||
$response = $this->sendRequest('POST', '/playlist', [
|
||||
'name' => $name,
|
||||
'tags' => $tags,
|
||||
'isDynamic' => $isDynamic,
|
||||
'filterMediaName' => $nameFilter,
|
||||
'filterMediaTag' => $tagFilter
|
||||
]);
|
||||
|
||||
// Check the response headers
|
||||
$this->assertSame($statusCode, $response->getStatusCode(), 'Not successful: ' . $response->getStatusCode() . $response->getBody());
|
||||
|
||||
// Make sure we have a useful body
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, 'Missing data');
|
||||
$this->assertObjectHasAttribute('id', $object, 'Missing id');
|
||||
|
||||
// Add to the list of playlists to clean up
|
||||
if ($response->getStatusCode() >= 200 && $response->getStatusCode() < 300) {
|
||||
$this->playlists[] = (new XiboPlaylist($this->getEntityProvider()))->hydrate((array)$object->data);
|
||||
}
|
||||
|
||||
// Get the Playlists back out from the API, to double check it has been created as we expected
|
||||
/** @var XiboPlaylist $playlistCheck */
|
||||
$playlistCheck = (new XiboPlaylist($this->getEntityProvider()))->hydrate($this->getEntityProvider()->get('/playlist', ['playlistId' => $object->id])[0]);
|
||||
|
||||
$this->assertEquals($name, $playlistCheck->name, 'Names are not identical');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider addPlaylistFailureCases
|
||||
*/
|
||||
public function testAddPlaylistFailure($statusCode, $name, $tags, $isDynamic, $nameFilter, $tagFilter)
|
||||
{
|
||||
$response = $this->sendRequest('POST', '/playlist', [
|
||||
'name' => $name,
|
||||
'tags' => $tags,
|
||||
'isDynamic' => $isDynamic,
|
||||
'filterMediaName' => $nameFilter,
|
||||
'filterMediaTag' => $tagFilter
|
||||
]);
|
||||
|
||||
// Check the response headers
|
||||
$this->assertSame($statusCode, $response->getStatusCode(), 'Not successful: ' . $response->getStatusCode() . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, 'Missing data');
|
||||
$this->assertSame([], $object->data);
|
||||
$this->assertObjectHasAttribute('error', $object, 'Missing error');
|
||||
$this->assertObjectNotHasAttribute('id', $object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit test
|
||||
*/
|
||||
public function testEditPlaylist()
|
||||
{
|
||||
// New name
|
||||
$newName = Random::generateString(5, 'playlist');
|
||||
|
||||
// Take the duplicate name playlist, and edit it
|
||||
$response = $this->sendRequest('PUT','/playlist/' . $this->duplicateName->playlistId, [
|
||||
'name' => $newName,
|
||||
'tags' => null,
|
||||
'isDynamic' => 0,
|
||||
'nameFilter' => null,
|
||||
'tagFilter' => null
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
// Check the response headers
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getStatusCode() . $response->getBody());
|
||||
|
||||
/** @var XiboPlaylist $playlistCheck */
|
||||
$playlistCheck = (new XiboPlaylist($this->getEntityProvider()))->hydrate($this->getEntityProvider()->get('/playlist', ['playlistId' => $this->duplicateName->playlistId])[0]);
|
||||
|
||||
$this->assertEquals($newName, $playlistCheck->name, 'Names are not identical');
|
||||
}
|
||||
}
|
||||
89
tests/integration/PlaylistWidgetListTest.php
Normal file
89
tests/integration/PlaylistWidgetListTest.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class PlaylistTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class PlaylistWidgetListTest extends LocalWebTestCase
|
||||
{
|
||||
/** @var XiboPlaylist */
|
||||
private $playlist;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
// Create a Playlist
|
||||
$this->playlist = (new XiboPlaylist($this->getEntityProvider()))->hydrate($this->getEntityProvider()->post('/playlist', [
|
||||
'name' => Random::generateString(5, 'playlist')
|
||||
]));
|
||||
|
||||
// Assign some Widgets
|
||||
$this->getEntityProvider()->post('/playlist/widget/clock/' . $this->playlist->playlistId, [
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
$text = $this->getEntityProvider()->post('/playlist/widget/text/' . $this->playlist->playlistId);
|
||||
$this->getEntityProvider()->put('/playlist/widget/' . $text['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Playlist
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* List all items in playlist
|
||||
*/
|
||||
public function testGetWidget()
|
||||
{
|
||||
// Search widgets on our playlist
|
||||
$response = $this->sendRequest('GET','/playlist/widget', [
|
||||
'playlistId' => $this->playlist->playlistId
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertSame(2, $object->data->recordsTotal);
|
||||
}
|
||||
}
|
||||
295
tests/integration/ProofOfPlayOnOff.php
Normal file
295
tests/integration/ProofOfPlayOnOff.php
Normal file
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboImage;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ProofOfPlayOnOff
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class ProofOfPlayOnOff extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout2;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// get draft Layout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Create another Layout with stat enabled
|
||||
$this->layout2 = (new XiboLayout($this->getEntityProvider()))->create(
|
||||
Random::generateString(8, 'phpunit'),
|
||||
'phpunit layout',
|
||||
'',
|
||||
$this->getResolutionId('landscape'),
|
||||
1
|
||||
);
|
||||
|
||||
// Upload some media
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create('API video '.rand(1,400), PROJECT_ROOT . '/tests/resources/HLH264.mp4');
|
||||
|
||||
// Assign the media we've created to our regions playlist.
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))->assign([$this->media->mediaId], 10, $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Store the widgetId
|
||||
$this->widgetId = $playlist->widgets[0]->widgetId;
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) . ' Test');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the second Layout we've been working with
|
||||
$this->deleteLayout($this->layout2);
|
||||
|
||||
// Delete the media record
|
||||
$this->media->deleteAssigned();
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (enableStat)
|
||||
* @return array
|
||||
*/
|
||||
public function enableStatLayoutCases()
|
||||
{
|
||||
return [
|
||||
// various correct enableStat flag
|
||||
'Layout enableStat Off' => [0],
|
||||
'Layout enableStat On' => [1]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (enableStat)
|
||||
* @return array
|
||||
*/
|
||||
public function enableStatMediaAndWidgetCases()
|
||||
{
|
||||
return [
|
||||
// various correct enableStat options - for both media and widget are same
|
||||
'enableStat Off' => ['Off'],
|
||||
'enableStat On' => ['On'],
|
||||
'enableStat Inherit' => ['Inherit']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add enableStat flag was set to 0 when creating the layout
|
||||
*/
|
||||
public function testAddLayoutEnableStatOff()
|
||||
{
|
||||
// Check that the layout enable stat sets to off
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->getById($this->layout->layoutId);
|
||||
$this->assertSame(0, $layout->enableStat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add enableStat flag was set to 1 when creating the layout
|
||||
*/
|
||||
public function testAddLayoutEnableStatOn()
|
||||
{
|
||||
// Check that the layout enable stat sets to on
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->getById($this->layout2->layoutId);
|
||||
$this->assertSame(1, $layout->enableStat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit enableStat flag of an existing layout
|
||||
* @dataProvider enableStatLayoutCases
|
||||
*/
|
||||
public function testEditLayoutEnableStat($enableStat)
|
||||
{
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
$description = Random::generateString(8, 'description');
|
||||
|
||||
$response = $this->sendRequest('PUT','/layout/' . $this->layout->layoutId, [
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'enableStat' => $enableStat
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame($enableStat, $object->data->enableStat);
|
||||
|
||||
// Check that the layout enable stat sets to on/off
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($enableStat, $layout->enableStat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit enableStat flag of an existing media file
|
||||
* @dataProvider enableStatMediaAndWidgetCases
|
||||
*/
|
||||
public function testEditMediaEnableStat($enableStat)
|
||||
{
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
|
||||
// Edit media file
|
||||
$response = $this->sendRequest('PUT','/library/' . $this->media->mediaId, [
|
||||
'name' => $name,
|
||||
'duration' => 50,
|
||||
'updateInLayouts' => 1,
|
||||
'enableStat' => $enableStat
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame($enableStat, $object->data->enableStat);
|
||||
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->getById($this->media->mediaId);
|
||||
$this->assertSame($enableStat, $media->enableStat);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Xibo\OAuth2\Client\Exception\XiboApiException
|
||||
* @dataProvider enableStatMediaAndWidgetCases
|
||||
*/
|
||||
public function testEditWidgetEnableStat($enableStat)
|
||||
{
|
||||
// Now try to edit our assigned Media Item.
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'enableStat' => $enableStat,
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']
|
||||
);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
|
||||
/** @var XiboImage $widgetOptions */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$widgetOptions = (new XiboImage($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
foreach ($widgetOptions->widgetOptions as $option) {
|
||||
if ($option['option'] == 'enableStat') {
|
||||
$this->assertSame($enableStat, $option['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy Layout - enableStat flag copied from an existing layout
|
||||
*/
|
||||
public function testCopyLayoutCheckEnableStat()
|
||||
{
|
||||
// Generate new random name
|
||||
$nameCopy = Random::generateString(8, 'phpunit');
|
||||
|
||||
// Call copy
|
||||
$response = $this->sendRequest('POST','/layout/copy/' . $this->layout2->layoutId, [
|
||||
'name' => $nameCopy,
|
||||
'description' => 'Copy',
|
||||
'copyMediaFiles' => 1
|
||||
], [
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded'
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
|
||||
// Check if copied layout has enableStat flag of copying layout
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame($this->layout2->enableStat, $object->data->enableStat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk On/Off Layout enableStat
|
||||
* @dataProvider enableStatLayoutCases
|
||||
*/
|
||||
public function testLayoutBulkEnableStat($enableStat)
|
||||
{
|
||||
// Call Set enable stat
|
||||
$response = $this->sendRequest('PUT','/layout/setenablestat/' . $this->layout->layoutId, [
|
||||
'enableStat' => $enableStat
|
||||
], [
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded'
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
|
||||
$layout = (new XiboLayout($this->getEntityProvider()))->getById($this->layout->layoutId);
|
||||
$this->assertSame($enableStat, $layout->enableStat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk On/Off/Inherit Media enableStat
|
||||
* @dataProvider enableStatMediaAndWidgetCases
|
||||
*/
|
||||
public function testMediaBulkEnableStat($enableStat)
|
||||
{
|
||||
// Call Set enable stat
|
||||
$response = $this->sendRequest('PUT','/library/setenablestat/' . $this->media->mediaId, [
|
||||
'enableStat' => $enableStat
|
||||
], [
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded'
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
|
||||
$media = (new XiboLibrary($this->getEntityProvider()))->getById($this->media->mediaId);
|
||||
$this->assertSame($enableStat, $media->enableStat);
|
||||
}
|
||||
}
|
||||
188
tests/integration/ReportScheduleDataTest.php
Normal file
188
tests/integration/ReportScheduleDataTest.php
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2023 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ReportScheduleDataTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class ReportScheduleDataTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait, DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
// Stat type
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->type = 'layout';
|
||||
$hardwareId = $this->display->license;
|
||||
|
||||
// Record some stats
|
||||
$this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(4)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(3)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$this->type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'" />
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(3)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$this->type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"/>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays()->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$this->type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"/>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays()->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$this->type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'" />
|
||||
</stats>'
|
||||
);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete stat records
|
||||
self::$container->get('timeSeriesStore')
|
||||
->deleteStats(Carbon::now(), Carbon::now()->startOfDay()->subDays(10));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if proof of play statistics are correct
|
||||
*/
|
||||
public function testProofOfPlayReportYesterday()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/report/data/proofofplayReport', [
|
||||
'reportFilter'=> 'yesterday',
|
||||
'groupByFilter' => 'byday',
|
||||
'displayId' => $this->display->displayId,
|
||||
'layoutId' => [$this->layout->layoutId],
|
||||
'type' => $this->type
|
||||
], ['HTTP_ACCEPT'=>'application/json'], 'web', true);
|
||||
|
||||
$this->getLogger()->debug('Response code is: ' . $response->getStatusCode());
|
||||
|
||||
$body = $response->getBody();
|
||||
|
||||
$this->getLogger()->debug($body);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($body);
|
||||
$object = json_decode($body);
|
||||
$this->assertObjectHasAttribute('table', $object, $body);
|
||||
$this->assertSame(1, $object->table[0]->numberPlays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if proof of play statistics are correct for Proof of play Report
|
||||
*/
|
||||
public function testProofOfPlayReport()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/report/data/proofofplayReport', [
|
||||
'statsFromDt' => Carbon::now()->startOfDay()->subDays(3)->format(DateFormatHelper::getSystemFormat()),
|
||||
'statsToDt' => Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()),
|
||||
'groupByFilter' => 'byday',
|
||||
'displayId' => $this->display->displayId,
|
||||
'layoutId' => [$this->layout->layoutId],
|
||||
'type' => $this->type
|
||||
], ['HTTP_ACCEPT'=>'application/json'], 'web', true);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$body = $response->getBody();
|
||||
$this->getLogger()->debug($body);
|
||||
$this->assertNotEmpty($body);
|
||||
$object = json_decode($body);
|
||||
$this->assertObjectHasAttribute('table', $object, $response->getBody());
|
||||
$this->assertSame(1, $object->table[0]->numberPlays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if proof of play statistics are correct for Summary Report
|
||||
*/
|
||||
public function testSummaryReport()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/report/data/summaryReport', [
|
||||
'statsFromDt' => Carbon::now()->startOfDay()->subDays(4)->format(DateFormatHelper::getSystemFormat()),
|
||||
'statsToDt' => Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()),
|
||||
'groupByFilter' => 'byday',
|
||||
'displayId' => $this->display->displayId,
|
||||
'layoutId' => $this->layout->layoutId,
|
||||
'type' => $this->type
|
||||
], ['HTTP_ACCEPT'=>'application/json'], 'web', true);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('chart', $object, $response->getBody());
|
||||
$expectedSeconds = Carbon::now()->startOfDay()->subDays(3)->format('U') -
|
||||
Carbon::now()->startOfDay()->subDays(4)->format('U');
|
||||
$this->assertSame($expectedSeconds, $object->chart->data->datasets[0]->data[0]);
|
||||
}
|
||||
}
|
||||
208
tests/integration/ReportScheduleTest.php
Normal file
208
tests/integration/ReportScheduleTest.php
Normal file
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboReportSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ReportScheduleTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class ReportScheduleTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait, DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (filter, reportName)
|
||||
* @return array
|
||||
*/
|
||||
public function filterCreateCases()
|
||||
{
|
||||
return [
|
||||
'proofofplayReport Daily' => ['daily', 'proofofplayReport'],
|
||||
'proofofplayReport Weekly' => ['weekly', 'proofofplayReport'],
|
||||
'proofofplayReport Monthly' => ['monthly', 'proofofplayReport'],
|
||||
'proofofplayReport Yearly' => ['yearly', 'proofofplayReport'],
|
||||
'summaryReport Daily' => ['daily', 'summaryReport'],
|
||||
'summaryReport Weekly' => ['weekly', 'summaryReport'],
|
||||
'summaryReport Monthly' => ['monthly', 'summaryReport'],
|
||||
'summaryReport Yearly' => ['yearly', 'summaryReport'],
|
||||
'distributionReport Daily' => ['daily', 'distributionReport'],
|
||||
'distributionReport Weekly' => ['weekly', 'distributionReport'],
|
||||
'distributionReport Monthly' => ['monthly', 'distributionReport'],
|
||||
'distributionReport Yearly' => ['yearly', 'distributionReport'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Report Schedule
|
||||
* @dataProvider filterCreateCases
|
||||
*/
|
||||
public function testCreateReportSchedule($filter, $report)
|
||||
{
|
||||
$reportSchedule = (new XiboReportSchedule($this->getEntityProvider()))
|
||||
->create('Report Schedule', $report, $filter, 'byhour', null,
|
||||
$this->display->displayId, '{"type":"layout","selectedId":'.$this->layout->layoutId.',"eventTag":null}');
|
||||
|
||||
$this->assertSame($report, $reportSchedule->reportName);
|
||||
|
||||
// Delete Report Schedule
|
||||
$reportSchedule->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Report Schedule Delete All Saved Report
|
||||
* @throws \Xibo\Support\Exception\NotFoundException
|
||||
*/
|
||||
public function testReportScheduleDeleteAllSavedReport()
|
||||
{
|
||||
$reportSchedule = (new XiboReportSchedule($this->getEntityProvider()))
|
||||
->create('Report Schedule', 'proofofplayReport', 'daily');
|
||||
|
||||
$reportScheduleId = $reportSchedule->reportScheduleId;
|
||||
|
||||
$task = $this->getTask('\Xibo\XTR\ReportScheduleTask');
|
||||
$task->run();
|
||||
self::$container->get('store')->commitIfNecessary();
|
||||
|
||||
// Delete All Saved Report
|
||||
$resDelete = $this->sendRequest('POST', '/report/reportschedule/' .
|
||||
$reportScheduleId. '/deletesavedreport');
|
||||
$this->assertSame(200, $resDelete->getStatusCode(), $resDelete->getBody());
|
||||
|
||||
// Delete Report Schedule
|
||||
$reportSchedule->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Report Schedule Toggle Active
|
||||
*/
|
||||
public function testReportScheduleToggleActive()
|
||||
{
|
||||
$reportSchedule = (new XiboReportSchedule($this->getEntityProvider()))
|
||||
->create('Report Schedule', 'proofofplayReport', 'daily');
|
||||
|
||||
// Toggle Active
|
||||
$response = $this->sendRequest('POST', '/report/reportschedule/'.
|
||||
$reportSchedule->reportScheduleId.'/toggleactive');
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame('Paused Report Schedule', $object->message);
|
||||
|
||||
// Delete Report Schedule
|
||||
$reportSchedule->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Report Schedule Reset
|
||||
*/
|
||||
public function testReportScheduleReset()
|
||||
{
|
||||
|
||||
$reportSchedule = (new XiboReportSchedule($this->getEntityProvider()))
|
||||
->create('Report Schedule', 'proofofplayReport', 'daily');
|
||||
|
||||
// Reset
|
||||
$response = $this->sendRequest('POST', '/report/reportschedule/'.
|
||||
$reportSchedule->reportScheduleId.'/reset');
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame('Success', $object->message);
|
||||
|
||||
// Delete Report Schedule
|
||||
$reportSchedule->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Saved Report
|
||||
* @throws \Xibo\OAuth2\Client\Exception\XiboApiException|\Xibo\Support\Exception\NotFoundException
|
||||
*/
|
||||
public function testDeleteSavedReport()
|
||||
{
|
||||
$reportSchedule = (new XiboReportSchedule($this->getEntityProvider()))
|
||||
->create('Report Schedule', 'proofofplayReport', 'daily');
|
||||
|
||||
// Create a saved report
|
||||
$task = $this->getTask('\Xibo\XTR\ReportScheduleTask');
|
||||
$task->run();
|
||||
self::$container->get('store')->commitIfNecessary();
|
||||
|
||||
// Get updated report schedule's last saved report Id
|
||||
$rs = (new XiboReportSchedule($this->getEntityProvider()))
|
||||
->getById($reportSchedule->reportScheduleId);
|
||||
|
||||
// Delete Saved Report
|
||||
$response = $this->sendRequest('DELETE', '/report/savedreport/'.
|
||||
$rs->lastSavedReportId);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
|
||||
// Delete Report Schedule
|
||||
$rs->delete();
|
||||
}
|
||||
}
|
||||
232
tests/integration/ResolutionTest.php
Normal file
232
tests/integration/ResolutionTest.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboResolution;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ResolutionTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class ResolutionTest extends LocalWebTestCase
|
||||
{
|
||||
|
||||
protected $startResolutions;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startResolutions = (new XiboResolution($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
}
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all resolutions that weren't there initially
|
||||
$finalResolutions = (new XiboResolution($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining resolutions and nuke them
|
||||
foreach ($finalResolutions as $resolution) {
|
||||
/** @var XiboResolution $resolution */
|
||||
$flag = true;
|
||||
foreach ($this->startResolutions as $startRes) {
|
||||
if ($startRes->resolutionId == $resolution->resolutionId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$resolution->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $resolution->resolutionId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testListAll()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/resolution');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddSuccess - test adding various Resolutions that should be valid
|
||||
* @dataProvider provideSuccessCases
|
||||
* @group minimal
|
||||
*/
|
||||
public function testAddSuccess($resolutionName, $resolutionWidth, $resolutionHeight)
|
||||
{
|
||||
|
||||
# Loop through any pre-existing resolutions to make sure we're not
|
||||
# going to get a clash
|
||||
foreach ($this->startResolutions as $tmpRes) {
|
||||
if ($tmpRes->resolution == $resolutionName) {
|
||||
$this->skipTest("There is a pre-existing resolution with this name");
|
||||
return;
|
||||
}
|
||||
}
|
||||
# Create new resolutions with data from provideSuccessCases
|
||||
$response = $this->sendRequest('POST','/resolution', [
|
||||
'resolution' => $resolutionName,
|
||||
'width' => $resolutionWidth,
|
||||
'height' => $resolutionHeight
|
||||
]);
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($resolutionName, $object->data->resolution);
|
||||
$this->assertSame($resolutionWidth, $object->data->width);
|
||||
$this->assertSame($resolutionHeight, $object->data->height);
|
||||
# Check that the resolution was added correctly
|
||||
$resolution = (new XiboResolution($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($resolutionName, $resolution->resolution);
|
||||
$this->assertSame($resolutionWidth, $resolution->width);
|
||||
$this->assertSame($resolutionHeight, $resolution->height);
|
||||
# Clean up the Resolutions as we no longer need it
|
||||
$this->assertTrue($resolution->delete(), 'Unable to delete ' . $resolution->resolutionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (resolution name, width, height)
|
||||
* @return array
|
||||
*/
|
||||
|
||||
public function provideSuccessCases()
|
||||
{
|
||||
# Sets of correct data, which should be successfully added
|
||||
return [
|
||||
'resolution 1' => ['test resolution', 800, 200],
|
||||
'resolution 2' => ['different test resolution', 1069, 1699]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* testAddFailure - test adding various resolutions that should be invalid
|
||||
* @dataProvider provideFailureCases
|
||||
*/
|
||||
public function testAddFailure($resolutionName, $resolutionWidth, $resolutionHeight)
|
||||
{
|
||||
# create new resolution with data from provideFailureCases
|
||||
$response = $this->sendRequest('POST','/resolution', [
|
||||
'resolution' => $resolutionName,
|
||||
'width' => $resolutionWidth,
|
||||
'height' => $resolutionHeight
|
||||
]);
|
||||
# Check if it fails as expected
|
||||
$this->assertSame(422, $response->getStatusCode(), 'Expecting failure, received ' . $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format (resolution name, width, height)
|
||||
* @return array
|
||||
*/
|
||||
public function provideFailureCases()
|
||||
{
|
||||
# Sets of incorrect data, which should lead to a failure
|
||||
return [
|
||||
'incorrect width and height' => ['wrong parameters', 'abc', NULL],
|
||||
'incorrect width' => [12, 'width', 1699]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing resolution
|
||||
* @group minimal
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
# Load in a known resolution
|
||||
/** @var XiboResolution $resolution */
|
||||
$resolution = (new XiboResolution($this->getEntityProvider()))->create('phpunit resolution', 1200, 860);
|
||||
$newWidth = 2400;
|
||||
# Change the resolution name, width and enable flag
|
||||
$name = Random::generateString(8, 'phpunit');
|
||||
|
||||
$response = $this->sendRequest('PUT','/resolution/' . $resolution->resolutionId, [
|
||||
'resolution' => $name,
|
||||
'width' => $newWidth,
|
||||
'height' => $resolution->height,
|
||||
'enabled' => 0
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
# Examine the returned object and check that it's what we expect
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
$this->assertSame($name, $object->data->resolution);
|
||||
$this->assertSame($newWidth, $object->data->width);
|
||||
$this->assertSame(0, $object->data->enabled);
|
||||
# Check that the resolution was actually renamed
|
||||
$resolution = (new XiboResolution($this->getEntityProvider()))->getById($object->id);
|
||||
$this->assertSame($name, $resolution->resolution);
|
||||
$this->assertSame($newWidth, $resolution->width);
|
||||
# Clean up the resolution as we no longer need it
|
||||
$resolution->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete
|
||||
* @group minimal
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
# Generate two random names
|
||||
$name1 = Random::generateString(8, 'phpunit');
|
||||
$name2 = Random::generateString(8, 'phpunit');
|
||||
# Load in a couple of known resolutions
|
||||
$res1 = (new XiboResolution($this->getEntityProvider()))->create($name1, 1000, 500);
|
||||
$res2 = (new XiboResolution($this->getEntityProvider()))->create($name2, 2000, 760);
|
||||
# Delete the one we created last
|
||||
$response = $this->sendRequest('DELETE','/resolution/' . $res2->resolutionId);
|
||||
# This should return 204 for success
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertSame(204, $object->status, $response->getBody());
|
||||
# Check only one remains
|
||||
$resolutions = (new XiboResolution($this->getEntityProvider()))->get();
|
||||
$this->assertEquals(count($this->startResolutions) + 1, count($resolutions));
|
||||
$flag = false;
|
||||
foreach ($resolutions as $res) {
|
||||
if ($res->resolutionId == $res1->resolutionId) {
|
||||
$flag = true;
|
||||
}
|
||||
}
|
||||
$this->assertTrue($flag, 'Resolution ID ' . $res1->resolutionId . ' was not found after deleting a different Resolution');
|
||||
# Clean up
|
||||
$res1->delete();
|
||||
}
|
||||
}
|
||||
188
tests/integration/ScheduleDayPartTest.php
Normal file
188
tests/integration/ScheduleDayPartTest.php
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDaypart;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class ScheduleDayPartTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboSchedule */
|
||||
protected $event;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboDaypart */
|
||||
protected $dayPart;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Make sure the Layout Status is as we expect
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Create a Day Part
|
||||
// calculate a few hours either side of now
|
||||
// must be tomorrow
|
||||
// must not cross the day boundary
|
||||
$now = Carbon::now()->startOfDay()->addDay()->addHour();
|
||||
|
||||
$this->dayPart = (new XiboDaypart($this->getEntityProvider()))->create(
|
||||
Random::generateString(5),
|
||||
'',
|
||||
$now->format('H:i'),
|
||||
$now->copy()->addHours(5)->format('H:i')
|
||||
);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
|
||||
// Delete the DayPart
|
||||
$this->dayPart->delete();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
public function testSchedule()
|
||||
{
|
||||
// Our CMS is in GMT
|
||||
// Create a schedule one hours time in my player timezone
|
||||
$date = Carbon::now()->addDay()->setTime(0,0,0);
|
||||
|
||||
$this->getLogger()->debug('Event start will be at: ' . $date->format(DateFormatHelper::getSystemFormat()));
|
||||
|
||||
$response = $this->sendRequest('POST','/schedule', [
|
||||
'fromDt' => $date->format(DateFormatHelper::getSystemFormat()),
|
||||
'dayPartId' => $this->dayPart->dayPartId,
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $this->layout->campaignId,
|
||||
'displayGroupIds' => [$this->display->displayGroupId],
|
||||
'displayOrder' => 1,
|
||||
'isPriority' => 0,
|
||||
'scheduleRecurrenceType' => null,
|
||||
'scheduleRecurrenceDetail' => null,
|
||||
'scheduleRecurrenceRange' => null,
|
||||
'syncTimezone' => 0
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML($this->getXmdsWrapper()->Schedule($this->display->license));
|
||||
//$this->getLogger()->debug($xml->saveXML());
|
||||
|
||||
// Check our event is present.
|
||||
$layouts = $xml->getElementsByTagName('layout');
|
||||
|
||||
$this->assertTrue(count($layouts) == 1, 'Unexpected number of events');
|
||||
|
||||
foreach ($layouts as $layout) {
|
||||
$xmlFromDt = $layout->getAttribute('fromdt');
|
||||
$xmlToDt = $layout->getAttribute('todt');
|
||||
$this->assertEquals($date->format('Y-m-d') . ' ' . $this->dayPart->startTime . ':00', $xmlFromDt, 'From date doesnt match: ' . $xmlFromDt);
|
||||
$this->assertEquals($date->format('Y-m-d') . ' ' . $this->dayPart->endTime . ':00', $xmlToDt, 'To date doesnt match: ' . $xmlToDt);
|
||||
}
|
||||
|
||||
// Also check this layout is in required files.
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML($this->getXmdsWrapper()->RequiredFiles($this->display->license));
|
||||
//$this->getLogger()->debug($xml->saveXML());
|
||||
|
||||
// Find using XPATH
|
||||
$xpath = new \DOMXPath($xml);
|
||||
$nodes =$xpath->query('//file[@type="layout"]');
|
||||
|
||||
$this->assertGreaterThanOrEqual(1, $nodes->count(), 'Layout not in required files');
|
||||
|
||||
$found = false;
|
||||
foreach ($nodes as $node) {
|
||||
/** @var \DOMNode $node */
|
||||
if ($this->layout->layoutId == $node->attributes->getNamedItem('id')->nodeValue) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$this->fail('Layout not found in Required Files XML');
|
||||
}
|
||||
}
|
||||
}
|
||||
114
tests/integration/ScheduleDisplayDeleteTest.php
Normal file
114
tests/integration/ScheduleDisplayDeleteTest.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ScheduleDisplayDeleteTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class ScheduleDisplayDeleteTest extends LocalWebTestCase
|
||||
{
|
||||
use DisplayHelperTrait;
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display2;
|
||||
|
||||
/** @var XiboSchedule */
|
||||
protected $event;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
// We need 2 displays
|
||||
$this->display = $this->createDisplay();
|
||||
$this->display2 = $this->createDisplay();
|
||||
|
||||
// This is the remaining display we will test for the schedule
|
||||
$this->displaySetLicensed($this->display2);
|
||||
|
||||
// 1 Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// 1 Schedule
|
||||
$this->event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$this->layout->campaignId,
|
||||
[$this->display->displayGroupId, $this->display2->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout and Remaining Display
|
||||
$this->deleteDisplay($this->display2);
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
/**
|
||||
* Do the test
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
// Delete 1 display
|
||||
$this->sendRequest('DELETE','/display/' . $this->display->displayId);
|
||||
|
||||
// Test to ensure the schedule remains
|
||||
$schedule = $this->getXmdsWrapper()->Schedule($this->display2->license);
|
||||
|
||||
$this->assertContains('file="' . $this->layout->layoutId . '"', $schedule, 'Layout not scheduled');
|
||||
}
|
||||
}
|
||||
246
tests/integration/ScheduleNotificationTest.php
Normal file
246
tests/integration/ScheduleNotificationTest.php
Normal file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ScheduleNotificationTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class ScheduleNotificationTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboSchedule */
|
||||
protected $event;
|
||||
|
||||
protected $timeZone = 'Asia/Hong_Kong';
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
$this->displaySetTimezone($this->display, $this->timeZone);
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Make sure the Layout Status is as we expect
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Check our timzone is set correctly
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML($this->getXmdsWrapper()->RegisterDisplay($this->display->license, $this->timeZone));
|
||||
$this->assertEquals($this->timeZone, $xml->documentElement->getAttribute('localTimezone'), 'Timezone not correct');
|
||||
$xml = null;
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
public function testSchedule()
|
||||
{
|
||||
// Our CMS is in GMT
|
||||
// Create a schedule one hours time in my player timezone
|
||||
$localNow = Carbon::now()->setTimezone($this->timeZone);
|
||||
$date = $localNow->copy()->addHour()->startOfHour();
|
||||
|
||||
$this->getLogger()->debug('Event start will be at: ' . $date->format(DateFormatHelper::getSystemFormat()));
|
||||
|
||||
$response = $this->sendRequest('POST','/schedule', [
|
||||
'fromDt' => $date->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => $date->copy()->addMinutes(30)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $this->layout->campaignId,
|
||||
'displayGroupIds' => [$this->display->displayGroupId],
|
||||
'displayOrder' => 1,
|
||||
'isPriority' => 0,
|
||||
'recurrenceType' => null,
|
||||
'recurrenceDetail' => null,
|
||||
'recurrenceRange' => null,
|
||||
'syncTimezone' => 0,
|
||||
'scheduleReminders' => [
|
||||
[
|
||||
'reminder_value' => 1,
|
||||
'reminder_type' => 1,
|
||||
'reminder_option' => 1,
|
||||
'reminder_isEmailHidden' => 1
|
||||
],
|
||||
[
|
||||
'reminder_value' => 1,
|
||||
'reminder_type' => 1,
|
||||
'reminder_option' => 2,
|
||||
'reminder_isEmailHidden' => 1
|
||||
]
|
||||
],
|
||||
'embed' => 'scheduleReminders'
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
# Check if two reminders are created
|
||||
$this->assertSame(2, count($object->data->scheduleReminders));
|
||||
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML($this->getXmdsWrapper()->Schedule($this->display->license));
|
||||
//$this->getLogger()->debug($xml->saveXML());
|
||||
|
||||
// Check the filter from and to dates are correct
|
||||
$this->assertEquals($localNow->startOfHour()->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterFrom'), 'Filter from date incorrect');
|
||||
$this->assertEquals($localNow->addDays(2)->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterTo'), 'Filter to date incorrect');
|
||||
|
||||
// Check our event is present.
|
||||
$layouts = $xml->getElementsByTagName('layout');
|
||||
|
||||
$this->assertTrue(count($layouts) == 1, 'Unexpected number of events');
|
||||
|
||||
foreach ($layouts as $layout) {
|
||||
$xmlFromDt = $layout->getAttribute('fromdt');
|
||||
$this->assertEquals($date->format(DateFormatHelper::getSystemFormat()), $xmlFromDt, 'From date doesnt match: ' . $xmlFromDt);
|
||||
}
|
||||
}
|
||||
|
||||
public function testRecurringSchedule()
|
||||
{
|
||||
// Our CMS is in GMT
|
||||
// Create a schedule one hours time in my player timezone
|
||||
// we start this schedule the day before
|
||||
$localNow = Carbon::now()->setTimezone($this->timeZone);
|
||||
$date = $localNow->copy()->subDay()->addHour()->startOfHour();
|
||||
|
||||
$this->getLogger()->debug('Event start will be at: ' . $date->format(DateFormatHelper::getSystemFormat()));
|
||||
|
||||
$response = $this->sendRequest('POST','/schedule', [
|
||||
'fromDt' => $date->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => $date->copy()->addMinutes(30)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $this->layout->campaignId,
|
||||
'displayGroupIds' => [$this->display->displayGroupId],
|
||||
'displayOrder' => 1,
|
||||
'isPriority' => 0,
|
||||
'recurrenceType' => 'Day',
|
||||
'recurrenceDetail' => 1,
|
||||
'recurrenceRange' => null,
|
||||
'syncTimezone' => 0,
|
||||
'scheduleReminders' => [
|
||||
[
|
||||
'reminder_value' => 1,
|
||||
'reminder_type' => 1,
|
||||
'reminder_option' => 1,
|
||||
'reminder_isEmailHidden' => 1
|
||||
],
|
||||
[
|
||||
'reminder_value' => 1,
|
||||
'reminder_type' => 1,
|
||||
'reminder_option' => 2,
|
||||
'reminder_isEmailHidden' => 1
|
||||
]
|
||||
],
|
||||
'embed' => 'scheduleReminders'
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
# Check if two reminders are created
|
||||
$this->assertSame(2, count($object->data->scheduleReminders));
|
||||
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML($this->getXmdsWrapper()->Schedule($this->display->license));
|
||||
//$this->getLogger()->debug($xml->saveXML());
|
||||
|
||||
// Check the filter from and to dates are correct
|
||||
$this->assertEquals($localNow->startOfHour()->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterFrom'), 'Filter from date incorrect');
|
||||
$this->assertEquals($localNow->addDays(2)->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterTo'), 'Filter to date incorrect');
|
||||
|
||||
// Check our event is present.
|
||||
$layouts = $xml->getElementsByTagName('layout');
|
||||
|
||||
foreach ($layouts as $layout) {
|
||||
// Move our day on (we know we're recurring by day), and that we started a day behind
|
||||
$date->addDay();
|
||||
|
||||
$xmlFromDt = $layout->getAttribute('fromdt');
|
||||
$this->assertEquals($date->format(DateFormatHelper::getSystemFormat()), $xmlFromDt, 'From date doesnt match: ' . $xmlFromDt);
|
||||
}
|
||||
}
|
||||
}
|
||||
404
tests/integration/ScheduleTest.php
Normal file
404
tests/integration/ScheduleTest.php
Normal file
@@ -0,0 +1,404 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2020 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\Integration;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCampaign;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCommand;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplayGroup;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboSchedule;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ScheduleTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class ScheduleTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
protected $route = '/schedule';
|
||||
|
||||
protected $startCommands;
|
||||
protected $startDisplayGroups;
|
||||
protected $startEvents;
|
||||
protected $startLayouts;
|
||||
protected $startCampaigns;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
$this->startDisplayGroups = (new XiboDisplayGroup($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->startLayouts = (new XiboLayout($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->startCampaigns = (new XiboCampaign($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
$this->startCommands = (new XiboCommand($this->getEntityProvider()))->get(['start' => 0, 'length' => 1000]);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// tearDown all display groups that weren't there initially
|
||||
$finalDisplayGroups = (new XiboDisplayGroup($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining display groups and nuke them
|
||||
foreach ($finalDisplayGroups as $displayGroup) {
|
||||
/** @var XiboDisplayGroup $displayGroup */
|
||||
$flag = true;
|
||||
foreach ($this->startDisplayGroups as $startGroup) {
|
||||
if ($startGroup->displayGroupId == $displayGroup->displayGroupId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$displayGroup->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Unable to delete ' . $displayGroup->displayGroupId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
// tearDown all layouts that weren't there initially
|
||||
$finalLayouts = (new XiboLayout($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining layouts and nuke them
|
||||
foreach ($finalLayouts as $layout) {
|
||||
/** @var XiboLayout $layout */
|
||||
$flag = true;
|
||||
foreach ($this->startLayouts as $startLayout) {
|
||||
if ($startLayout->layoutId == $layout->layoutId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$layout->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Layout: Unable to delete ' . $layout->layoutId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tearDown all campaigns that weren't there initially
|
||||
$finalCamapigns = (new XiboCampaign($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining campaigns and nuke them
|
||||
foreach ($finalCamapigns as $campaign) {
|
||||
/** @var XiboCampaign $campaign */
|
||||
$flag = true;
|
||||
foreach ($this->startCampaigns as $startCampaign) {
|
||||
if ($startCampaign->campaignId == $campaign->campaignId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$campaign->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Campaign: Unable to delete ' . $campaign->campaignId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
// tearDown all commands that weren't there initially
|
||||
$finalCommands = (new XiboCommand($this->getEntityProvider()))->get(['start' => 0, 'length' => 10000]);
|
||||
# Loop over any remaining commands and nuke them
|
||||
foreach ($finalCommands as $command) {
|
||||
/** @var XiboCommand $command */
|
||||
$flag = true;
|
||||
foreach ($this->startCommands as $startCom) {
|
||||
if ($startCom->commandId == $command->commandId) {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
try {
|
||||
$command->delete();
|
||||
} catch (\Exception $e) {
|
||||
fwrite(STDERR, 'Command: Unable to delete ' . $command->commandId . '. E:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* testListAll
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
# list all scheduled events
|
||||
$response = $this->sendRequest('GET','/schedule/data/events');
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('result', $object, $response->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group add
|
||||
* @dataProvider provideSuccessCasesCampaign
|
||||
*/
|
||||
public function testAddEventCampaign($isCampaign, $scheduleFrom, $scheduleTo, $scheduledayPartId, $scheduleRecurrenceType, $scheduleRecurrenceDetail, $scheduleRecurrenceRange, $scheduleOrder, $scheduleIsPriority)
|
||||
{
|
||||
# Create new display group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create('phpunit group', 'phpunit description', 0, '');
|
||||
$layout = null;
|
||||
$campaign = null;
|
||||
# isCampaign checks if we want to add campaign or layout to our event
|
||||
if ($isCampaign) {
|
||||
# Create Campaign
|
||||
/* @var XiboCampaign $campaign */
|
||||
$campaign = (new XiboCampaign($this->getEntityProvider()))->create('phpunit');
|
||||
# Create new event with data from provideSuccessCasesCampaign where isCampaign is set to true
|
||||
$response = $this->sendRequest('POST', $this->route, [
|
||||
'fromDt' => Carbon::createFromTimestamp($scheduleFrom)->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => Carbon::createFromTimestamp($scheduleTo)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $campaign->campaignId,
|
||||
'displayGroupIds' => [$displayGroup->displayGroupId],
|
||||
'displayOrder' => $scheduleOrder,
|
||||
'isPriority' => $scheduleIsPriority,
|
||||
'scheduleRecurrenceType' => $scheduleRecurrenceType,
|
||||
'scheduleRecurrenceDetail' => $scheduleRecurrenceDetail,
|
||||
'scheduleRecurrenceRange' => $scheduleRecurrenceRange
|
||||
]);
|
||||
} else {
|
||||
# Create layout
|
||||
$layout = $this->createLayout();
|
||||
|
||||
# Create new event with data from provideSuccessCasesCampaign where isCampaign is set to false
|
||||
$response = $this->sendRequest('POST', $this->route, [
|
||||
'fromDt' => Carbon::createFromTimestamp($scheduleFrom)->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => Carbon::createFromTimestamp($scheduleTo)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $layout->campaignId,
|
||||
'displayGroupIds' => [$displayGroup->displayGroupId],
|
||||
'displayOrder' => $scheduleOrder,
|
||||
'isPriority' => $scheduleIsPriority,
|
||||
'scheduleRecurrenceType' => $scheduleRecurrenceType,
|
||||
'scheduleRecurrenceDetail' => $scheduleRecurrenceDetail,
|
||||
'scheduleRecurrenceRange' => $scheduleRecurrenceRange
|
||||
]);
|
||||
}
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
if ($campaign != null)
|
||||
$campaign->delete();
|
||||
if ($layout != null)
|
||||
$layout->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($isCampaign, $scheduleFrom, $scheduleTo, $scheduledayPartId, $scheduleRecurrenceType, $scheduleRecurrenceDetail, $scheduleRecurrenceRange, $scheduleOrder, $scheduleIsPriority)
|
||||
* @return array
|
||||
*/
|
||||
public function provideSuccessCasesCampaign()
|
||||
{
|
||||
# Sets of data used in testAddEventCampaign, first argument (isCampaign) controls if it's layout or campaign
|
||||
return [
|
||||
'Campaign no priority, no recurrence' => [true, time()+3600, time()+7200, 0, NULL, NULL, NULL, 0, 0],
|
||||
'Layout no priority, no recurrence' => [false, time()+3600, time()+7200, 0, NULL, NULL, NULL, 0, 0]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @group add
|
||||
* @dataProvider provideSuccessCasesCommand
|
||||
*/
|
||||
public function testAddEventCommand($scheduleFrom, $scheduledayPartId, $scheduleRecurrenceType, $scheduleRecurrenceDetail, $scheduleRecurrenceRange, $scheduleOrder, $scheduleIsPriority)
|
||||
{
|
||||
# Create command
|
||||
$command = (new XiboCommand($this->getEntityProvider()))->create('phpunit command', 'phpunit command desc', 'code');
|
||||
# Create Display Group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create('phpunit group', 'phpunit description', 0, '');
|
||||
# Create new event with scheduled command and data from provideSuccessCasesCommand
|
||||
$response = $this->sendRequest('POST', $this->route, [
|
||||
'fromDt' => Carbon::createFromTimestamp($scheduleFrom)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 2,
|
||||
'commandId' => $command->commandId,
|
||||
'displayGroupIds' => [$displayGroup->displayGroupId],
|
||||
'displayOrder' => $scheduleOrder,
|
||||
'isPriority' => $scheduleIsPriority,
|
||||
'scheduleRecurrenceType' => $scheduleRecurrenceType,
|
||||
'scheduleRecurrenceDetail' => $scheduleRecurrenceDetail,
|
||||
'scheduleRecurrenceRange' => $scheduleRecurrenceRange
|
||||
]);
|
||||
# Check if successful
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$command->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($scheduleFrom, $scheduleDisplays, $scheduledayPartId, $scheduleRecurrenceType, $scheduleRecurrenceDetail, $scheduleRecurrenceRange, $scheduleOrder, $scheduleIsPriority)
|
||||
* @return array
|
||||
*/
|
||||
public function provideSuccessCasesCommand()
|
||||
{
|
||||
return [
|
||||
'Command no priority, no recurrence' => [time()+3600, 0, NULL, NULL, NULL, 0, 0],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @group add
|
||||
* @dataProvider provideSuccessCasesOverlay
|
||||
*/
|
||||
public function testAddEventOverlay($scheduleFrom, $scheduleTo, $scheduleCampaignId, $scheduleDisplays, $scheduledayPartId, $scheduleRecurrenceType, $scheduleRecurrenceDetail, $scheduleRecurrenceRange, $scheduleOrder, $scheduleIsPriority)
|
||||
{
|
||||
# Create new dispay group
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create('phpunit group', 'phpunit description', 0, '');
|
||||
|
||||
# Create layout
|
||||
$layout = $this->createLayout();
|
||||
|
||||
# Create new event with data from provideSuccessCasesOverlay
|
||||
$response = $this->sendRequest('POST', $this->route, [
|
||||
'fromDt' => Carbon::createFromTimestamp($scheduleFrom)->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => Carbon::createFromTimestamp($scheduleTo)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 3,
|
||||
'campaignId' => $layout->campaignId,
|
||||
'displayGroupIds' => [$displayGroup->displayGroupId],
|
||||
'displayOrder' => $scheduleOrder,
|
||||
'isPriority' => $scheduleIsPriority,
|
||||
'scheduleRecurrenceType' => $scheduleRecurrenceType,
|
||||
'scheduleRecurrenceDetail' => $scheduleRecurrenceDetail,
|
||||
'scheduleRecurrenceRange' => $scheduleRecurrenceRange
|
||||
]);
|
||||
# Check if call was successful
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
if ($layout != null)
|
||||
$layout->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($scheduleFrom, $scheduleTo, $scheduledayPartId, $scheduleRecurrenceType, $scheduleRecurrenceDetail, $scheduleRecurrenceRange, $scheduleOrder, $scheduleIsPriority)
|
||||
* @return array
|
||||
*/
|
||||
public function provideSuccessCasesOverlay()
|
||||
{
|
||||
return [
|
||||
'Overlay, no recurrence' => [time()+3600, time()+7200, 0, NULL, NULL, NULL, 0, 0, 0, 0],
|
||||
];
|
||||
}
|
||||
/**
|
||||
* @group minimal
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
// Get a Display Group Id
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create('phpunit group', 'phpunit description', 0, '');
|
||||
// Create Campaign
|
||||
/* @var XiboCampaign $campaign */
|
||||
$campaign = (new XiboCampaign($this->getEntityProvider()))->create('phpunit');
|
||||
# Create new event
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$campaign->campaignId,
|
||||
[$displayGroup->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
$fromDt = time() + 3600;
|
||||
$toDt = time() + 86400;
|
||||
# Edit event
|
||||
$response = $this->sendRequest('PUT',$this->route . '/' . $event->eventId, [
|
||||
'fromDt' => Carbon::createFromTimestamp($fromDt)->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => Carbon::createFromTimestamp($toDt)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $event->campaignId,
|
||||
'displayGroupIds' => [$displayGroup->displayGroupId],
|
||||
'displayOrder' => 1,
|
||||
'isPriority' => 1
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
$this->assertSame(200, $response->getStatusCode(), "Not successful: " . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
# Check if edit was successful
|
||||
$this->assertSame($toDt, intval($object->data->toDt));
|
||||
$this->assertSame($fromDt, intval($object->data->fromDt));
|
||||
# Tidy up
|
||||
$displayGroup->delete();
|
||||
$campaign->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $eventId
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
|
||||
# Get a Display Group Id
|
||||
$displayGroup = (new XiboDisplayGroup($this->getEntityProvider()))->create('phpunit group', 'phpunit description', 0, '');
|
||||
# Create Campaign
|
||||
/* @var XiboCampaign $campaign */
|
||||
$campaign = (new XiboCampaign($this->getEntityProvider()))->create('phpunit');
|
||||
# Create event
|
||||
$event = (new XiboSchedule($this->getEntityProvider()))->createEventLayout(
|
||||
Carbon::now()->format(DateFormatHelper::getSystemFormat()),
|
||||
Carbon::now()->addSeconds(7200)->format(DateFormatHelper::getSystemFormat()),
|
||||
$campaign->campaignId,
|
||||
[$displayGroup->displayGroupId],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
# Delete event
|
||||
$response = $this->sendRequest('DELETE',$this->route . '/' . $event->eventId);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
# Clean up
|
||||
$displayGroup->delete();
|
||||
$campaign->delete();
|
||||
}
|
||||
}
|
||||
311
tests/integration/ScheduleTimezoneBaseCase.php
Normal file
311
tests/integration/ScheduleTimezoneBaseCase.php
Normal file
@@ -0,0 +1,311 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Xibo\Entity\Display;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ScheduleTimezoneTest
|
||||
* @package Xibo\Tests\integration
|
||||
*/
|
||||
class ScheduleTimezoneBaseCase extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
use DisplayHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboSchedule */
|
||||
protected $event;
|
||||
|
||||
protected $timeZone = 'Asia/Hong_Kong';
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->layout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/text/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'text' => 'Widget A',
|
||||
'duration' => 100,
|
||||
'useDuration' => 1
|
||||
]);
|
||||
|
||||
// Check us in again
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
// Build the layout
|
||||
$this->buildLayout($this->layout);
|
||||
|
||||
// Create a Display
|
||||
$this->display = $this->createDisplay();
|
||||
|
||||
$this->displaySetTimezone($this->display, $this->timeZone);
|
||||
$this->displaySetStatus($this->display, Display::$STATUS_DONE);
|
||||
$this->displaySetLicensed($this->display);
|
||||
|
||||
// Make sure the Layout Status is as we expect
|
||||
$this->assertTrue($this->layoutStatusEquals($this->layout, 1), 'Layout Status isnt as expected');
|
||||
|
||||
// Make sure our Display is already DONE
|
||||
$this->assertTrue($this->displayStatusEquals($this->display, Display::$STATUS_DONE), 'Display Status isnt as expected');
|
||||
|
||||
// Check our timzone is set correctly
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML($this->getXmdsWrapper()->RegisterDisplay($this->display->license, $this->timeZone));
|
||||
$this->assertEquals($this->timeZone, $xml->documentElement->getAttribute('localTimezone'), 'Timezone not correct');
|
||||
$xml = null;
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->layout);
|
||||
|
||||
// Delete the Display
|
||||
$this->deleteDisplay($this->display);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
public function testSchedule()
|
||||
{
|
||||
// Our CMS is in GMT
|
||||
// Create a schedule one hours time in my player timezone
|
||||
$localNow = Carbon::now()->setTimezone($this->timeZone);
|
||||
$date = $localNow->copy()->addHour()->startOfHour();
|
||||
|
||||
$this->getLogger()->debug('Event start will be at: ' . $date->format(DateFormatHelper::getSystemFormat()));
|
||||
|
||||
$response = $this->sendRequest('POST','/schedule', [
|
||||
'fromDt' => $date->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => $date->copy()->addMinutes(30)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $this->layout->campaignId,
|
||||
'displayGroupIds' => [$this->display->displayGroupId],
|
||||
'displayOrder' => 1,
|
||||
'isPriority' => 0,
|
||||
'scheduleRecurrenceType' => null,
|
||||
'scheduleRecurrenceDetail' => null,
|
||||
'scheduleRecurrenceRange' => null,
|
||||
'syncTimezone' => 0
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML($this->getXmdsWrapper()->Schedule($this->display->license));
|
||||
//$this->getLogger()->debug($xml->saveXML());
|
||||
|
||||
// Check the filter from and to dates are correct
|
||||
$this->assertEquals($localNow->startOfHour()->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterFrom'), 'Filter from date incorrect');
|
||||
$this->assertEquals($localNow->addDays(2)->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterTo'), 'Filter to date incorrect');
|
||||
|
||||
// Check our event is present.
|
||||
$layouts = $xml->getElementsByTagName('layout');
|
||||
|
||||
$this->assertTrue(count($layouts) == 1, 'Unexpected number of events');
|
||||
|
||||
foreach ($layouts as $layout) {
|
||||
$xmlFromDt = $layout->getAttribute('fromdt');
|
||||
$this->assertEquals($date->format(DateFormatHelper::getSystemFormat()), $xmlFromDt, 'From date doesnt match: ' . $xmlFromDt);
|
||||
}
|
||||
}
|
||||
|
||||
public function testRecurringSchedule()
|
||||
{
|
||||
// Our CMS is in GMT
|
||||
// Create a schedule one hours time in my player timezone
|
||||
// we start this schedule the day before
|
||||
$localNow = Carbon::now()->setTimezone($this->timeZone);
|
||||
$date = $localNow->copy()->subDay()->addHour()->startOfHour();
|
||||
|
||||
$this->getLogger()->debug('Event start will be at: ' . $date->format(DateFormatHelper::getSystemFormat()));
|
||||
|
||||
$response = $this->sendRequest('POST','/schedule', [
|
||||
'fromDt' => $date->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => $date->copy()->addMinutes(30)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $this->layout->campaignId,
|
||||
'displayGroupIds' => [$this->display->displayGroupId],
|
||||
'displayOrder' => 1,
|
||||
'isPriority' => 0,
|
||||
'recurrenceType' => 'Day',
|
||||
'recurrenceDetail' => 1,
|
||||
'recurrenceRange' => null,
|
||||
'syncTimezone' => 0
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML($this->getXmdsWrapper()->Schedule($this->display->license));
|
||||
//$this->getLogger()->debug($xml->saveXML());
|
||||
|
||||
// Check the filter from and to dates are correct
|
||||
$this->assertEquals($localNow->startOfHour()->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterFrom'), 'Filter from date incorrect');
|
||||
$this->assertEquals($localNow->addDays(2)->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterTo'), 'Filter to date incorrect');
|
||||
|
||||
// Check our event is present.
|
||||
$layouts = $xml->getElementsByTagName('layout');
|
||||
|
||||
foreach ($layouts as $layout) {
|
||||
// Move our day on (we know we're recurring by day), and that we started a day behind
|
||||
$date->addDay();
|
||||
|
||||
$xmlFromDt = $layout->getAttribute('fromdt');
|
||||
$this->assertEquals($date->format(DateFormatHelper::getSystemFormat()), $xmlFromDt, 'From date doesnt match: ' . $xmlFromDt);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSyncedSchedule()
|
||||
{
|
||||
// Our CMS is in GMT
|
||||
// Create a schedule one hours time in my CMS timezone
|
||||
$localNow = Carbon::now()->setTimezone($this->timeZone);
|
||||
|
||||
// If this was 8AM local CMS time, we would expect the resulting date/times in the XML to have the equivilent
|
||||
// timezone specific date/times
|
||||
$date = Carbon::now()->copy()->addHour()->startOfHour();
|
||||
$localDate = $date->copy()->timezone($this->timeZone);
|
||||
|
||||
$this->getLogger()->debug('Event start will be at: ' . $date->format(DateFormatHelper::getSystemFormat()) . ' which is ' . $localDate->format(DateFormatHelper::getSystemFormat()) . ' local time.');
|
||||
|
||||
$response = $this->sendRequest('POST','/schedule', [
|
||||
'fromDt' => $date->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => $date->copy()->addMinutes(30)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $this->layout->campaignId,
|
||||
'displayGroupIds' => [$this->display->displayGroupId],
|
||||
'displayOrder' => 1,
|
||||
'isPriority' => 0,
|
||||
'recurrenceType' => null,
|
||||
'recurrenceDetail' => null,
|
||||
'recurrenceRange' => null,
|
||||
'syncTimezone' => 1
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML($this->getXmdsWrapper()->Schedule($this->display->license));
|
||||
//$this->getLogger()->debug($xml->saveXML());
|
||||
|
||||
// Check the filter from and to dates are correct
|
||||
$this->assertEquals($localNow->startOfHour()->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterFrom'), 'Filter from date incorrect');
|
||||
$this->assertEquals($localNow->addDays(2)->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterTo'), 'Filter to date incorrect');
|
||||
|
||||
// Check our event is present.
|
||||
$layouts = $xml->getElementsByTagName('layout');
|
||||
|
||||
foreach ($layouts as $layout) {
|
||||
$xmlFromDt = $layout->getAttribute('fromdt');
|
||||
$this->assertEquals($localDate->format(DateFormatHelper::getSystemFormat()), $xmlFromDt, 'From date doesnt match: ' . $xmlFromDt);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSyncedRecurringSchedule()
|
||||
{
|
||||
// Our CMS is in GMT
|
||||
// Create a schedule one hours time in my CMS timezone
|
||||
$localNow = Carbon::now()->setTimezone($this->timeZone);
|
||||
|
||||
// If this was 8AM local CMS time, we would expect the resulting date/times in the XML to have the equivilent
|
||||
// timezone specific date/times
|
||||
$date = Carbon::now()->copy()->subDay()->addHour()->startOfHour();
|
||||
$localDate = $date->copy()->timezone($this->timeZone);
|
||||
|
||||
$this->getLogger()->debug('Event start will be at: ' . $date->format(DateFormatHelper::getSystemFormat()) . ' which is ' . $localDate->format(DateFormatHelper::getSystemFormat()) . ' local time.');
|
||||
|
||||
$response = $this->sendRequest('POST','/schedule', [
|
||||
'fromDt' => $date->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => $date->copy()->addMinutes(30)->format(DateFormatHelper::getSystemFormat()),
|
||||
'eventTypeId' => 1,
|
||||
'campaignId' => $this->layout->campaignId,
|
||||
'displayGroupIds' => [$this->display->displayGroupId],
|
||||
'displayOrder' => 1,
|
||||
'isPriority' => 0,
|
||||
'recurrenceType' => 'Day',
|
||||
'recurrenceDetail' => 1,
|
||||
'recurrenceRange' => null,
|
||||
'syncTimezone' => 1
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Not successful: ' . $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertObjectHasAttribute('id', $object);
|
||||
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML($this->getXmdsWrapper()->Schedule($this->display->license));
|
||||
//$this->getLogger()->debug($xml->saveXML());
|
||||
|
||||
// Check the filter from and to dates are correct
|
||||
$this->assertEquals($localNow->startOfHour()->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterFrom'), 'Filter from date incorrect');
|
||||
$this->assertEquals($localNow->addDays(2)->format(DateFormatHelper::getSystemFormat()), $xml->documentElement->getAttribute('filterTo'), 'Filter to date incorrect');
|
||||
|
||||
// Check our event is present.
|
||||
$layouts = $xml->getElementsByTagName('layout');
|
||||
|
||||
foreach ($layouts as $layout) {
|
||||
// Move our day on (we know we're recurring by day), and that we started a day behind
|
||||
// we use addRealDay because our synced calendar entry _should_ change its time over a DST switch
|
||||
$localDate->addRealDay();
|
||||
|
||||
$xmlFromDt = $layout->getAttribute('fromdt');
|
||||
$this->assertEquals($localDate->format(DateFormatHelper::getSystemFormat()), $xmlFromDt, 'From date doesnt match: ' . $xmlFromDt);
|
||||
}
|
||||
}
|
||||
}
|
||||
29
tests/integration/ScheduleTimezoneHongKongTest.php
Normal file
29
tests/integration/ScheduleTimezoneHongKongTest.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2019 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
|
||||
class ScheduleTimezoneHongKongTest extends ScheduleTimezoneBaseCase
|
||||
{
|
||||
protected $timeZone = 'Asia/Hong_Kong';
|
||||
}
|
||||
29
tests/integration/ScheduleTimezoneLATest.php
Normal file
29
tests/integration/ScheduleTimezoneLATest.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2019 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
|
||||
class ScheduleTimezoneLATest extends ScheduleTimezoneBaseCase
|
||||
{
|
||||
protected $timeZone = 'America/Los_Angeles';
|
||||
}
|
||||
29
tests/integration/ScheduleTimezoneLondonTest.php
Normal file
29
tests/integration/ScheduleTimezoneLondonTest.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2019 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
|
||||
class ScheduleTimezoneLondonTest extends ScheduleTimezoneBaseCase
|
||||
{
|
||||
protected $timeZone = 'Europe/London';
|
||||
}
|
||||
232
tests/integration/SearchFilterTest.php
Normal file
232
tests/integration/SearchFilterTest.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 Xibo Signage Ltd
|
||||
*
|
||||
* Xibo - Digital Signage - https://xibosignage.com
|
||||
*
|
||||
* This file is part of Xibo.
|
||||
*
|
||||
* Xibo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Xibo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Xibo\Tests\integration;
|
||||
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class SearchFilterTest
|
||||
* @package Xibo\Tests\integration
|
||||
*/
|
||||
class SearchFilterTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout2;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout3;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout4;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout5;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout6;
|
||||
|
||||
// <editor-fold desc="Init">
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup test for ' . get_class($this) . ' Test');
|
||||
|
||||
// Create 6 layouts to test with
|
||||
$this->layout = (new XiboLayout($this->getEntityProvider()))
|
||||
->create(
|
||||
'integration layout 1',
|
||||
'PHPUnit Created Layout for Automated Integration Testing',
|
||||
'',
|
||||
$this->getResolutionId('landscape')
|
||||
);
|
||||
|
||||
$this->layout2 = (new XiboLayout($this->getEntityProvider()))
|
||||
->create(
|
||||
'integration example layout 2',
|
||||
'PHPUnit Created Layout for Automated Integration Testing',
|
||||
'',
|
||||
$this->getResolutionId('landscape')
|
||||
);
|
||||
|
||||
$this->layout3 = (new XiboLayout($this->getEntityProvider()))
|
||||
->create(
|
||||
'integration layout 3',
|
||||
'PHPUnit Created Layout for Automated Integration Testing',
|
||||
'',
|
||||
$this->getResolutionId('landscape')
|
||||
);
|
||||
|
||||
$this->layout4 = (new XiboLayout($this->getEntityProvider()))
|
||||
->create(
|
||||
'integration example 4',
|
||||
'PHPUnit Created Layout for Automated Integration Testing',
|
||||
'',
|
||||
$this->getResolutionId('landscape')
|
||||
);
|
||||
|
||||
$this->layout5 = (new XiboLayout($this->getEntityProvider()))
|
||||
->create(
|
||||
'example layout 5',
|
||||
'PHPUnit Created Layout for Automated Integration Testing',
|
||||
'',
|
||||
$this->getResolutionId('landscape')
|
||||
);
|
||||
|
||||
$this->layout6 = (new XiboLayout($this->getEntityProvider()))
|
||||
->create(
|
||||
'display different name',
|
||||
'PHPUnit Created Layout for Automated Integration Testing',
|
||||
'',
|
||||
$this->getResolutionId('landscape')
|
||||
);
|
||||
|
||||
$this->getLogger()->debug('Finished Setup');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->getLogger()->debug('Tear Down');
|
||||
|
||||
$this->deleteLayout($this->layout);
|
||||
$this->deleteLayout($this->layout2);
|
||||
$this->deleteLayout($this->layout3);
|
||||
$this->deleteLayout($this->layout4);
|
||||
$this->deleteLayout($this->layout5);
|
||||
$this->deleteLayout($this->layout6);
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* Search filter test.
|
||||
*
|
||||
* Single keyword
|
||||
*/
|
||||
public function testSearch()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/layout', ['layout' => 'integration']);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertSame(4, $object->data->recordsFiltered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search filter test
|
||||
*
|
||||
* Comma separated
|
||||
*/
|
||||
public function testSearchCommaSeparated()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/layout', ['layout' => 'integration,example']);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertSame(5, $object->data->recordsFiltered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search filter test
|
||||
*
|
||||
* Comma separated with not RLIKE filter
|
||||
*/
|
||||
public function testSearchCommaSeparatedWithNotRlike()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/layout', ['layout' => 'integration layout, -example']);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertSame(4, $object->data->recordsFiltered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search filter test
|
||||
*
|
||||
* Comma separated with not RLIKE filter
|
||||
*/
|
||||
public function testSearchCommaSeparatedWithNotRlike2()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/layout', ['layout' => 'example, -layout']);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertSame(4, $object->data->recordsFiltered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search filter test.
|
||||
*
|
||||
* partial match filter
|
||||
*/
|
||||
public function testSearchPartialMatch()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/layout', ['layout' => 'inte, exa']);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertSame(5, $object->data->recordsFiltered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search filter test.
|
||||
*
|
||||
* using regexp
|
||||
*/
|
||||
public function testSearchWithRegEx()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/layout', ['layout' => 'name$', 'useRegexForName' => 1]);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertSame(1, $object->data->recordsFiltered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search filter test.
|
||||
*
|
||||
* using regexp
|
||||
*/
|
||||
public function testSearchWithRegEx2()
|
||||
{
|
||||
$response = $this->sendRequest('GET', '/layout', ['layout' => '^example, ^disp', 'useRegexForName' => 1]);
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertSame(2, $object->data->recordsFiltered);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user