init commit
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
158
tests/integration/StatisticsEventTest.php
Normal file
158
tests/integration/StatisticsEventTest.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?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 Carbon\Carbon;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\Helper\Random;
|
||||
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 StatisticsEventTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class StatisticsEventTest 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);
|
||||
|
||||
// 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 testProof()
|
||||
{
|
||||
$type = 'event';
|
||||
|
||||
// Checkout layout
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
$hardwareId = $this->display->license;
|
||||
|
||||
// One word name for the event
|
||||
$eventName = Random::generateString(10, 'event');
|
||||
|
||||
// First insert
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(5)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="0"
|
||||
tag="'.$eventName.'"/>
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Second insert
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(1)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="0"
|
||||
tag="'.$eventName.'"/>
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Third insert
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(1)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="0"
|
||||
tag="'.$eventName.'"/>
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Get stats and see if they match with what we expect
|
||||
$response = $this->sendRequest('GET', '/stats', [
|
||||
'fromDt' => Carbon::now()->startOfDay()->subDays(5)->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()),
|
||||
'displayId' => $this->display->displayId,
|
||||
'type' => $type
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertEquals(3, $object->data->recordsTotal);
|
||||
$this->assertCount(3, $object->data->data);
|
||||
}
|
||||
}
|
||||
184
tests/integration/StatisticsLayoutTest.php
Normal file
184
tests/integration/StatisticsLayoutTest.php
Normal file
@@ -0,0 +1,184 @@
|
||||
<?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 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 StatisticsLayoutTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class StatisticsLayoutTest 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);
|
||||
|
||||
// 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 testProof()
|
||||
{
|
||||
$type = 'layout';
|
||||
|
||||
$hardwareId = $this->display->license;
|
||||
|
||||
// Set start and date time
|
||||
//
|
||||
// $fromDt = '2018-02-12 00:00:00';
|
||||
// $toDt = '2018-02-15 00:00:00';
|
||||
//
|
||||
// $fromDt2 = '2018-02-15 00:00:00';
|
||||
// $toDt2 = '2018-02-16 00:00:00';
|
||||
//
|
||||
// $fromDt3 = '2018-02-16 00:00:00';
|
||||
// $toDt3 = '2018-02-17 00:00:00';
|
||||
|
||||
// Add stats to the DB - known set
|
||||
//
|
||||
// 1 layout
|
||||
// type,start,end,layout,media
|
||||
// layout,2016-02-12 00:00:00, 2016-02-15 00:00:00, L1, NULL
|
||||
//
|
||||
// Result
|
||||
// L1 72 hours
|
||||
//
|
||||
// 1 layout
|
||||
// type,start,end,layout,media
|
||||
// layout,2016-02-15 00:00:00, 2016-02-16 00:00:00, L1, NULL
|
||||
//
|
||||
// Result
|
||||
// L1 24 hours
|
||||
//
|
||||
// 1 layout
|
||||
// type,start,end,layout,media
|
||||
// layout,2016-02-16 00:00:00, 2016-02-17 00:00:00, L1, NULL
|
||||
//
|
||||
// Result
|
||||
// L1 24 hours
|
||||
|
||||
// First insert
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(5)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'" />
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Second insert
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(1)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"/>
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Third insert
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(1)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"/>
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Get stats and see if they match with what we expect
|
||||
$response = $this->sendRequest('GET', '/stats', [
|
||||
'fromDt' => Carbon::now()->startOfDay()->subDays(5)->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()),
|
||||
'displayId' => $this->display->displayId,
|
||||
'layoutId' => [$this->layout->layoutId],
|
||||
'type' => $type
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertEquals(3, $object->data->recordsTotal);
|
||||
$this->assertCount(3, $object->data->data);
|
||||
}
|
||||
}
|
||||
214
tests/integration/StatisticsMediaTest.php
Normal file
214
tests/integration/StatisticsMediaTest.php
Normal file
@@ -0,0 +1,214 @@
|
||||
<?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 Carbon\Carbon;
|
||||
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\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class StatisticsMediaTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class StatisticsMediaTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait, DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media2;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboWidget */
|
||||
private $widget;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboWidget */
|
||||
private $widget2;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
// Upload some media
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))
|
||||
->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/xts-night-001.jpg');
|
||||
|
||||
$this->media2 = (new XiboLibrary($this->getEntityProvider()))
|
||||
->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/xts-layout-003-background.jpg');
|
||||
|
||||
// Checkout our Layout and add some Widgets to it.
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Add another region
|
||||
// Assign media to the layouts default region.
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))->assign([$this->media->mediaId, $this->media2->mediaId], 10, $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Get Widget Ids
|
||||
$this->widget = $playlist->widgets[0];
|
||||
$this->widget2 = $playlist->widgets[1];
|
||||
|
||||
// Publish the Layout
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
$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 the media records
|
||||
$this->media->deleteAssigned();
|
||||
$this->media2->deleteAssigned();
|
||||
|
||||
// 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 testProof()
|
||||
{
|
||||
$type = 'media';
|
||||
|
||||
$hardwareId = $this->display->license;
|
||||
|
||||
// Set start and date time
|
||||
//
|
||||
// $fromDt = '2018-02-12 00:00:00';
|
||||
// $toDt = '2018-02-17 00:00:00';
|
||||
|
||||
// Add stats to the DB - known set
|
||||
//
|
||||
// 1 layout, 2 region, 2 medias (1 per region)
|
||||
// type,start,end,layout,media
|
||||
// media,2018-02-12 00:00:00, 2018-02-13 00:00:00, L1, M1
|
||||
// media,2018-02-13 00:00:00, 2018-02-14 00:00:00, L1, M1
|
||||
// media,2018-02-16 00:00:00, 2018-02-17 12:00:00, L1, M1
|
||||
// media,2018-02-14 00:00:00, 2018-02-15 00:00:00, L1, M2
|
||||
// media,2018-02-15 00:00:00, 2018-02-16 00:00:00, L1, M2
|
||||
// media,2018-02-16 00:00:00, 2018-02-16 12:00:00, L1, M2
|
||||
//
|
||||
// Result
|
||||
// M1 60 hours
|
||||
// M2 60 hours
|
||||
|
||||
// Insert all stats in one call to SubmitStats
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(5)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(4)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"
|
||||
mediaid="'.$this->widget->widgetId.'"/>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(4)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(3)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"
|
||||
mediaid="'.$this->widget->widgetId.'"/>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subHours(12)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"
|
||||
mediaid="'.$this->widget->widgetId.'"/>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(3)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"
|
||||
mediaid="'.$this->widget2->widgetId.'"/>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(1)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"
|
||||
mediaid="'.$this->widget2->widgetId.'"/>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(1)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subHours(12)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"
|
||||
mediaid="'.$this->widget2->widgetId.'"/>
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Get stats and see if they match with what we expect
|
||||
$response = $this->sendRequest('GET', '/stats', [
|
||||
'fromDt' => Carbon::now()->startOfDay()->subDays(5)->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()),
|
||||
'displayId' => $this->display->displayId,
|
||||
'layoutId' => [$this->layout->layoutId],
|
||||
'type' => $type
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertEquals(6, $object->data->recordsTotal);
|
||||
$this->assertCount(6, $object->data->data);
|
||||
}
|
||||
}
|
||||
246
tests/integration/StatisticsTest.php
Normal file
246
tests/integration/StatisticsTest.php
Normal file
@@ -0,0 +1,246 @@
|
||||
<?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 Carbon\Carbon;
|
||||
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\XiboStats;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class StatisticsTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class StatisticsTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait, DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media2;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboWidget */
|
||||
private $widget;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboWidget */
|
||||
private $widget2;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboWidget */
|
||||
private $textWidget;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
// Upload some media
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))
|
||||
->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/xts-night-001.jpg');
|
||||
|
||||
$this->media2 = (new XiboLibrary($this->getEntityProvider()))
|
||||
->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/xts-layout-003-background.jpg');
|
||||
|
||||
// Checkout our Layout and add some Widgets to it.
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Create and assign new text widget
|
||||
$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->textWidget = (new XiboText($this->getEntityProvider()))->hydrate($response);
|
||||
|
||||
// Add another region
|
||||
// Assign media to the layouts default region.
|
||||
$playlist = (new XiboPlaylist($this->getEntityProvider()))->assign([$this->media->mediaId, $this->media2->mediaId], 10, $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Get Widget Ids
|
||||
$this->widget = $playlist->widgets[0];
|
||||
$this->widget2 = $playlist->widgets[1];
|
||||
|
||||
// Publish the Layout
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
$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 the media records
|
||||
$this->media->deleteAssigned();
|
||||
$this->media2->deleteAssigned();
|
||||
|
||||
// Delete stat records
|
||||
self::$container->get('timeSeriesStore')
|
||||
->deleteStats(Carbon::now(), Carbon::now()->startOfDay()->subDays(10));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the method call with default values
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
$this->getXmdsWrapper()->SubmitStats($this->display->license, '
|
||||
<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subHours(12)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="layout"
|
||||
scheduleid="0"
|
||||
layoutid="' . $this->layout->layoutId . '" />
|
||||
</stats>');
|
||||
|
||||
$response = $this->sendRequest('GET', '/stats');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertEquals(1, $object->data->recordsTotal);
|
||||
$this->assertCount(1, $object->data->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if proof of play statistics can be exported
|
||||
*/
|
||||
public function testExport()
|
||||
{
|
||||
$this->getXmdsWrapper()->SubmitStats($this->display->license, '
|
||||
<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(4)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(3)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="layout"
|
||||
scheduleid="0"
|
||||
layoutid="' . $this->layout->layoutId . '" />
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(4)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(3)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="media"
|
||||
scheduleid="0"
|
||||
layoutid="' . $this->layout->layoutId . '"
|
||||
mediaid="' . $this->widget->widgetId . '"/>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(4)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(3)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="widget"
|
||||
scheduleid="0"
|
||||
layoutid="' . $this->layout->layoutId . '"
|
||||
mediaid="' . $this->textWidget->widgetId . '"/>
|
||||
</stats>');
|
||||
|
||||
|
||||
$response = $this->sendRequest('GET', '/stats/export', [
|
||||
'fromDt' => Carbon::now()->startOfDay()->subDays(5)->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat())
|
||||
]);
|
||||
|
||||
// Check 200
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
|
||||
// We're expecting a send file header as we're testing within Docker
|
||||
$this->assertTrue($response->hasHeader('X-Sendfile'));
|
||||
$this->assertSame('text/csv', $response->getHeader('Content-Type')[0] ?? '');
|
||||
$this->assertGreaterThan(0, $response->getHeader('Content-Length')[0] ?? 0);
|
||||
|
||||
// We can't test the body, because there isn't any web server involved with this request.
|
||||
}
|
||||
|
||||
public function testProofOldStats()
|
||||
{
|
||||
$hardwareId = $this->display->license;
|
||||
|
||||
// Attempt to insert stat data older than 30 days
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(35)->format('Y-m-d H:i:s') . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(31)->format('Y-m-d H:i:s') .'"
|
||||
type="layout"
|
||||
scheduleid="0"
|
||||
layoutid="' . $this->layout->layoutId . '" />
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(40)->format('Y-m-d H:i:s') . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(38)->format('Y-m-d H:i:s') .'"
|
||||
type="layout"
|
||||
scheduleid="0"
|
||||
layoutid="' . $this->layout->layoutId . '" />
|
||||
</stats>'
|
||||
);
|
||||
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Default max stat age is 30 days, therefore we expect to get no results after the attempted inserts.
|
||||
$stats = (new XiboStats($this->getEntityProvider()))->get([
|
||||
'fromDt' => Carbon::now()->startOfDay()->subDays(41)->format('Y-m-d H:i:s'),
|
||||
'toDt' => Carbon::now()->startOfDay()->subDays(31)->format('Y-m-d H:i:s'),
|
||||
'layoutId' => [$this->layout->layoutId],
|
||||
'type' => 'layout'
|
||||
]);
|
||||
$this->assertEquals(0, count($stats));
|
||||
}
|
||||
}
|
||||
173
tests/integration/StatisticsWidgetTest.php
Normal file
173
tests/integration/StatisticsWidgetTest.php
Normal file
@@ -0,0 +1,173 @@
|
||||
<?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 Carbon\Carbon;
|
||||
use Xibo\Helper\DateFormatHelper;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDisplay;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLayout;
|
||||
use Xibo\OAuth2\Client\Entity\XiboText;
|
||||
use Xibo\Tests\Helper\DisplayHelperTrait;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class StatisticsWidgetTest
|
||||
* @package Xibo\Tests\Integration
|
||||
*/
|
||||
class StatisticsWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait, DisplayHelperTrait;
|
||||
|
||||
/** @var XiboLayout */
|
||||
protected $layout;
|
||||
|
||||
/** @var XiboDisplay */
|
||||
protected $display;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboWidget */
|
||||
private $widget;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
// Checkout our Layout and add some Widgets to it.
|
||||
$layout = $this->getDraft($this->layout);
|
||||
|
||||
// Create and assign new text widget
|
||||
$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);
|
||||
|
||||
// Publish the Layout
|
||||
$this->layout = $this->publish($this->layout);
|
||||
|
||||
$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 testProof()
|
||||
{
|
||||
$type = 'widget';
|
||||
|
||||
$hardwareId = $this->display->license;
|
||||
|
||||
// First insert
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(5)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"
|
||||
mediaid="'.$this->widget->widgetId.'"/>
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Second insert
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(2)->format(DateFormatHelper::getSystemFormat()) . '"
|
||||
todt="'.Carbon::now()->startOfDay()->subDays(1)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"
|
||||
mediaid="'.$this->widget->widgetId.'"/>
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Third insert
|
||||
$response = $this->getXmdsWrapper()->SubmitStats(
|
||||
$hardwareId,
|
||||
'<stats>
|
||||
<stat fromdt="'. Carbon::now()->startOfDay()->subDays(1)->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
todt="'. Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()) .'"
|
||||
type="'.$type.'"
|
||||
scheduleid="0"
|
||||
layoutid="'.$this->layout->layoutId.'"
|
||||
mediaid="'.$this->widget->widgetId.'"/>
|
||||
</stats>'
|
||||
);
|
||||
$this->assertSame(true, $response);
|
||||
|
||||
// Get stats and see if they match with what we expect
|
||||
$response = $this->sendRequest('GET', '/stats', [
|
||||
'fromDt' => Carbon::now()->startOfDay()->subDays(5)->format(DateFormatHelper::getSystemFormat()),
|
||||
'toDt' => Carbon::now()->startOfDay()->format(DateFormatHelper::getSystemFormat()),
|
||||
'displayId' => $this->display->displayId,
|
||||
'layoutId' => [$this->layout->layoutId],
|
||||
'type' => $type
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertEquals(3, $object->data->recordsTotal);
|
||||
$this->assertCount(3, $object->data->data);
|
||||
}
|
||||
}
|
||||
89
tests/integration/TemplateTest.php
Normal file
89
tests/integration/TemplateTest.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/*
|
||||
* Xibo - Digital Signage - http://www.xibo.org.uk
|
||||
* Copyright (C) 2015-2018 Spring Signage Ltd
|
||||
*
|
||||
* 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\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class TemplateTest
|
||||
* @package Xibo\Tests
|
||||
*/
|
||||
class TemplateTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/**
|
||||
* Show Templates
|
||||
*/
|
||||
public function testListAll()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/template');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Template
|
||||
*/
|
||||
public function testAdd()
|
||||
{
|
||||
# Create random name and new layout
|
||||
$layout = $this->createLayout();
|
||||
|
||||
# Generate second random name
|
||||
$name2 = Random::generateString(8, 'phpunit');
|
||||
|
||||
# Create template using our layout and new name
|
||||
$response = $this->sendRequest('POST','/template/' . $layout->layoutId, [
|
||||
'name' => $name2,
|
||||
'includeWidgets' => 1,
|
||||
'tags' => 'phpunit',
|
||||
'description' => $layout->description
|
||||
]);
|
||||
|
||||
# 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 it has edited name
|
||||
$this->assertSame($name2, $object->data->layout);
|
||||
// Expect 2 tags phpunit added in this request and template tag.
|
||||
$this->assertSame(2,count($object->data->tags));
|
||||
|
||||
$templateId = $object->id;
|
||||
|
||||
# delete template as we no longer need it
|
||||
$template = (new XiboLayout($this->getEntityProvider()))->getByTemplateId($templateId);
|
||||
$template->delete();
|
||||
|
||||
# delete layout as we no longer need it
|
||||
$layout->delete();
|
||||
}
|
||||
}
|
||||
63
tests/integration/UserGroupTest.php
Normal file
63
tests/integration/UserGroupTest.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?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\Exception\XiboApiException;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class UserGroupTest
|
||||
* @package Xibo\Tests\integration
|
||||
*/
|
||||
class UserGroupTest extends LocalWebTestCase
|
||||
{
|
||||
/**
|
||||
* Add a new group and then check it was added correctly.
|
||||
*/
|
||||
public function testAdd()
|
||||
{
|
||||
$params = [
|
||||
'group' => Random::generateString(),
|
||||
'description' => Random::generateString()
|
||||
];
|
||||
$response = $this->sendRequest('POST', '/group', $params);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertObjectHasAttribute('id', $object, $response->getBody());
|
||||
|
||||
// Use the API to get it out again
|
||||
try {
|
||||
//$group = (new XiboUserGroup($this->getEntityProvider()))->getById($object->id);
|
||||
$group = $this->getEntityProvider()->get('/group', ['userGroupId' => $object->id])[0];
|
||||
|
||||
// Check our key parts match.
|
||||
$this->assertSame($params['group'], $group['group'], 'Name does not match');
|
||||
$this->assertSame($params['description'], $group['description'], 'Description does not match');
|
||||
} catch (XiboApiException $e) {
|
||||
$this->fail('Group not found. e = ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
114
tests/integration/UserTest.php
Normal file
114
tests/integration/UserTest.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?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\XiboUser;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class UserTest
|
||||
* @package Xibo\Tests
|
||||
*/
|
||||
class UserTest extends LocalWebTestCase
|
||||
{
|
||||
/**
|
||||
* Show me
|
||||
*/
|
||||
public function testGetMe()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/user/me');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
$this->assertSame('phpunit', $object->data->userName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show all users
|
||||
*/
|
||||
public function testGetUsers()
|
||||
{
|
||||
$response = $this->sendRequest('GET','/user');
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new user
|
||||
*/
|
||||
public function testAdd()
|
||||
{
|
||||
$group = $this->getEntityProvider()->get('/group', ['userGroup' => 'Users'])[0];
|
||||
$userName = Random::generateString();
|
||||
|
||||
$response = $this->sendRequest('POST','/user', [
|
||||
'userName' => $userName,
|
||||
'userTypeId' => 3,
|
||||
'homePageId' => 'icondashboard.view',
|
||||
'homeFolderId' => 1,
|
||||
'password' => 'newUserPassword',
|
||||
'groupId' => $group['groupId'],
|
||||
'libraryQuota' => 0
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), $response->getBody());
|
||||
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
$this->assertObjectHasAttribute('id', $object, $response->getBody());
|
||||
|
||||
$this->assertSame($userName, $object->data->userName);
|
||||
$this->assertSame(3, $object->data->userTypeId);
|
||||
$this->assertSame('icondashboard.view', $object->data->homePageId);
|
||||
|
||||
$userCheck = (new XiboUser($this->getEntityProvider()))->getById($object->id);
|
||||
$userCheck->delete();
|
||||
}
|
||||
|
||||
public function testAddEmptyPassword()
|
||||
{
|
||||
$group = $this->getEntityProvider()->get('/group', ['userGroup' => 'Users'])[0];
|
||||
|
||||
$response = $this->sendRequest('POST', '/user', [
|
||||
'userName' => Random::generateString(),
|
||||
'userTypeId' => 3,
|
||||
'homePageId' => 'icondashboard.view',
|
||||
'homeFolderId' => 1,
|
||||
'password' => null,
|
||||
'groupId' => $group['groupId'],
|
||||
'libraryQuota' => 0
|
||||
]);
|
||||
|
||||
$this->assertSame(422, $response->getStatusCode(), $response->getBody());
|
||||
}
|
||||
}
|
||||
182
tests/integration/Widget/AudioWidgetTest.php
Normal file
182
tests/integration/Widget/AudioWidgetTest.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboImage;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class AudioWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class AudioWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $audio;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create some media to upload
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/cc0_f1_gp_cars_pass_crash.mp3');
|
||||
$this->audio = (new XiboLibrary($this->getEntityProvider()))->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/cc0_f1_gp_cars_pass_crash.mp3');
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
// Tidy up the media
|
||||
$this->media->delete();
|
||||
$this->audio->delete();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Xibo\OAuth2\Client\Exception\XiboApiException
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
$this->getLogger()->debug('testEdit ' . get_class($this) .' Test');
|
||||
|
||||
// Now try to edit our assigned Media Item.
|
||||
$name = 'Edited Name ' . Random::generateString(5);
|
||||
$duration = 80;
|
||||
$useDuration = 1;
|
||||
$mute = 0;
|
||||
$loop = 0;
|
||||
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'name' => $name,
|
||||
'duration' => $duration,
|
||||
'useDuration' => $useDuration,
|
||||
'mute' => $mute,
|
||||
'loop' => $loop,
|
||||
], ['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]);
|
||||
|
||||
$this->assertSame($name, $widgetOptions->name);
|
||||
$this->assertSame($duration, $widgetOptions->duration);
|
||||
|
||||
foreach ($widgetOptions->widgetOptions as $option) {
|
||||
if ($option['option'] == 'mute') {
|
||||
$this->assertSame($mute, intval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'loop') {
|
||||
$this->assertSame($loop, intval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'useDuration') {
|
||||
$this->assertSame($useDuration, intval($option['value']));
|
||||
}
|
||||
}
|
||||
|
||||
$this->getLogger()->debug('testEdit finished');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to edit and assign an auto item to a widget
|
||||
*/
|
||||
public function testAssign()
|
||||
{
|
||||
$this->getLogger()->debug('testAssign');
|
||||
|
||||
$volume = 80;
|
||||
$loop = 1;
|
||||
|
||||
// Add audio to image assigned to a playlist
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId . '/audio', [
|
||||
'mediaId' => $this->audio->mediaId,
|
||||
'volume' => $volume,
|
||||
'loop' => $loop,
|
||||
], ['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());
|
||||
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
|
||||
/** @var XiboImage $widgetOptions */
|
||||
$widgetOptions = (new XiboImage($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
$this->assertSame($this->media->name, $widgetOptions->name);
|
||||
$this->assertSame($this->media->mediaId, intval($widgetOptions->mediaIds[0]));
|
||||
$this->assertSame($this->audio->mediaId, intval($widgetOptions->mediaIds[1]));
|
||||
$this->assertSame($volume, intval($widgetOptions->audio[0]['volume']));
|
||||
$this->assertSame($loop, intval($widgetOptions->audio[0]['loop']));
|
||||
|
||||
$this->getLogger()->debug('testAssign finished');
|
||||
}
|
||||
}
|
||||
138
tests/integration/Widget/ClockWidgetTest.php
Normal file
138
tests/integration/Widget/ClockWidgetTest.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\Widget;
|
||||
|
||||
use Xibo\OAuth2\Client\Entity\XiboClock;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ClockWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class ClockWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create a Widget for us to edit.
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/clock/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
$this->widgetId = $response['widgetId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($name, $duration, $useDuration, $theme, $clockTypeId, $offset, $format, $showSeconds, $clockFace)
|
||||
* @return array
|
||||
*/
|
||||
public function provideSuccessCases()
|
||||
{
|
||||
# Sets of data used in testAdd
|
||||
return [
|
||||
'Analogue' => ['Api Analogue clock', 20, 1, 1, 1, null, null, 0, 'TwentyFourHourClock'],
|
||||
'Digital' => ['API digital clock', 20, 1, 0, 2, null, '[HH:mm]', 0, 'TwentyFourHourClock'],
|
||||
'Flip 24h' => ['API Flip clock 24h', 5, 1, 0, 3, null, null, 1, 'TwentyFourHourClock'],
|
||||
'Flip counter' => ['API Flip clock Minute counter', 50, 1, 0, 3, null, null, 1, 'MinuteCounter']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $duration
|
||||
* @param $useDuration
|
||||
* @param $theme
|
||||
* @param $clockTypeId
|
||||
* @param $offset
|
||||
* @param $format
|
||||
* @param $showSeconds
|
||||
* @param $clockFace
|
||||
* @dataProvider provideSuccessCases
|
||||
*/
|
||||
public function testEdit($name, $duration, $useDuration, $theme, $clockTypeId, $offset, $format, $showSeconds, $clockFace)
|
||||
{
|
||||
$response = $this->sendRequest('PUT', '/playlist/widget/' . $this->widgetId, [
|
||||
'name' => $name,
|
||||
'useDuration' => $useDuration,
|
||||
'duration' => $duration,
|
||||
'themeId' => $theme,
|
||||
'clockTypeId' => $clockTypeId,
|
||||
'offset' => $offset,
|
||||
'format' => $format,
|
||||
'showSeconds' => $showSeconds,
|
||||
'clockFace' => $clockFace
|
||||
], ['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 XiboClock $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboClock($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
foreach ($checkWidget->widgetOptions as $option) {
|
||||
if ($option['option'] == 'clockTypeId') {
|
||||
$this->assertSame($clockTypeId, intval($option['value']));
|
||||
} else {
|
||||
if ($option['option'] == 'name') {
|
||||
$this->assertSame($name, $option['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
144
tests/integration/Widget/CurrenciesWidgetTest.php
Normal file
144
tests/integration/Widget/CurrenciesWidgetTest.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\OAuth2\Client\Entity\XiboCurrencies;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class CurrenciesWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class CurrenciesWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create a Widget for us to edit.
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/currencies/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
$this->widgetId = $response['widgetId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($overrideTemplate, $templateId, $name, $duration, $useDuration, $base, $items, $reverseConversion, $effect, $speed, $backgroundColor, $noRecordsMessage, $dateFormat, $updateInterval, $durationIsPerItem, $widgetOriginalWidth, $widgetOriginalHeight, $itemsPerPage, $mainTemplate, $itemTemplate, $styleSheet, $javaScript)
|
||||
* @return array
|
||||
*/
|
||||
public function provideSuccessCases()
|
||||
{
|
||||
# Sets of data used in testAdd
|
||||
return [
|
||||
'No override template 1' => [false, 'currencies1', 'template 1', 6, 1, 'GBP', 'PLN', 0, NULL, NULL, NULL, 'No messages', NULL, 12, 1, null, null, 5, null, null, null, null],
|
||||
'No override template 2 reverse' => [false, 'currencies2', 'template 2', 120, 1, 'GBP', 'EUR', 1, NULL, NULL, NULL, 'No messages', NULL, 120, 0, null, null, 2, null, null, null, null],
|
||||
'Override' => [true, 'currencies1', 'override template', 12, 1, 'GBP', 'EUR', 0, NULL, NULL, NULL, 'No messages', NULL, 60, 1, 1000, 800, 5, '<div class="container-main"><div class="container "><div class="row row-header"><div class="col-2 offset-xs-7 text-center value">BUY</div><div class="col-2 offset-xs-1 value text-center">SELL</div></div><div id="cycle-container">[itemsTemplate]</div></div></div>', '<div class="row row-finance"><div class="col-1 flags"><img class="img-circle center-block " src="[CurrencyFlag]"></div><div class="col-1 value ">[NameShort]</div><div class="col-2 offset-xs-5 text-center value">[Bid]</div><div class="col-2 offset-xs-1 value text-center">[Ask]</div> </div>','body { font-family: "Helvetica", "Arial", sans-serif; line-height: 1; } .container-main {height: 420px !important;width: 820px !important; } .container { height: 420px !important; width: 820px !important; float: left; margin-top: 20px; } .row-finance { height: 60px; background: rgba(0, 0, 0, 0.87); margin-bottom: 20px; } .row {margin-right: 0; margin-left: 0; } .row-header { margin-right: -15px; margin-left: -15px; margin-bottom: 20px; } #cycle-container { margin-left: -15px; margin-right: -15px; } .value { font-size: 20px; padding-top: 20px; font-weight: bold; color: #fff; } .down-arrow { font-size: 20px; color: red; padding-top: 17px; } .up-arrow { font-size: 20px;color: green; padding-top: 17px; } .variant { font-size: 20px; padding-top: 17px; } .flags { padding-top: 4px; } .center-block { width: 50px; height: 50px; }', NULL]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* This test works correctly, it's marked as broken because we don't have this widget installed by default
|
||||
* @group broken
|
||||
* @dataProvider provideSuccessCases
|
||||
*/
|
||||
public function testEdit($isOverride, $templateId, $name, $duration, $useDuration, $base, $items, $reverseConversion, $effect, $speed, $backgroundColor, $noRecordsMessage, $dateFormat, $updateInterval, $durationIsPerItem, $widgetOriginalWidth, $widgetOriginalHeight, $itemsPerPage, $mainTemplate, $itemTemplate, $styleSheet, $javaScript)
|
||||
{
|
||||
# Edit currency widget and change name, duration, template, reverseConversion and items
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'templateId' => $templateId,
|
||||
'name' => $name,
|
||||
'duration' => $duration,
|
||||
'useDuration' => $useDuration,
|
||||
'base' => $base,
|
||||
'items' => $items,
|
||||
'reverseConversion' => $reverseConversion,
|
||||
'effect' => $effect,
|
||||
'speed' => $speed,
|
||||
'backgroundColor' => $backgroundColor,
|
||||
'noRecordsMessage' => $noRecordsMessage,
|
||||
'dateFormat' => $dateFormat,
|
||||
'updateInterval' => $updateInterval,
|
||||
'durationIsPerItem' => $durationIsPerItem,
|
||||
], ['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 XiboCurrencies $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboCurrencies($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
# check if changes were correctly saved
|
||||
$this->assertSame($name, $checkWidget->name);
|
||||
$this->assertSame($duration, $checkWidget->duration);
|
||||
|
||||
foreach ($checkWidget->widgetOptions as $option) {
|
||||
if ($option['option'] == 'templateId') {
|
||||
$this->assertSame($templateId, $option['value']);
|
||||
}
|
||||
if ($option['option'] == 'items') {
|
||||
$this->assertSame($items, $option['value']);
|
||||
}
|
||||
if ($option['option'] == 'reverseConversion') {
|
||||
$this->assertSame($reverseConversion, intval($option['value']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
168
tests/integration/Widget/DataSetTickerWidgetTest.php
Normal file
168
tests/integration/Widget/DataSetTickerWidgetTest.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\Widget;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSet;
|
||||
use Xibo\OAuth2\Client\Entity\XiboTicker;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class DataSetTickerWidgetTest
|
||||
* @package Xibo\Tests\integration\Widget
|
||||
*/
|
||||
class DataSetTickerWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/** @var XiboDataSet */
|
||||
protected $dataSet;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Add a DataSet
|
||||
$this->dataSet = (new XiboDataSet($this->getEntityProvider()))->create(Random::generateString(), 'Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create a Widget for us to edit.
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/datasetticker/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
$response = $this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'step' => 1,
|
||||
'dataSetId' => $this->dataSet->dataSetId
|
||||
]);
|
||||
|
||||
$this->widgetId = $response['widgetId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
// Delete the DataSet
|
||||
$this->dataSet->deleteWData();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit dataSet ticker
|
||||
*/
|
||||
public function testEditDataset()
|
||||
{
|
||||
$this->getLogger()->debug('testEdit ' . get_class($this) .' Test');
|
||||
|
||||
// Edit ticker
|
||||
$noDataMessage = 'no records found';
|
||||
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'name' => 'Edited widget',
|
||||
'duration' => 90,
|
||||
'useDuration' => 1,
|
||||
'updateInterval' => 100,
|
||||
'effect' => 'fadeout',
|
||||
'speed' => 500,
|
||||
'template' => '[Col1]',
|
||||
'durationIsPerItem' => 1,
|
||||
'itemsSideBySide' => 1,
|
||||
'upperLimit' => 0,
|
||||
'lowerLimit' => 0,
|
||||
'itemsPerPage' => 5,
|
||||
'noDataMessage' => $noDataMessage
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode(), 'Incorrect status: ' . $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
|
||||
$this->getLogger()->debug('Request successful, double check contents.');
|
||||
|
||||
/** @var XiboTicker $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboTicker($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
// check if changes were correctly saved
|
||||
$this->assertSame('Edited widget', $checkWidget->name);
|
||||
$this->assertSame(90, $checkWidget->duration);
|
||||
|
||||
foreach ($checkWidget->widgetOptions as $option) {
|
||||
if ($option['option'] == 'updateInterval') {
|
||||
$this->assertSame(100, intval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'effect') {
|
||||
$this->assertSame('fadeout', $option['value']);
|
||||
}
|
||||
if ($option['option'] == 'speed') {
|
||||
$this->assertSame(500, intval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'template') {
|
||||
$this->assertSame('[Col1]', $option['value']);
|
||||
}
|
||||
if ($option['option'] == 'durationIsPerItem') {
|
||||
$this->assertSame(1, intval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'itemsSideBySide') {
|
||||
$this->assertSame(1, intval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'upperLimit') {
|
||||
$this->assertSame(0, intval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'lowerLimit') {
|
||||
$this->assertSame(0, intval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'itemsPerPage') {
|
||||
$this->assertSame(5, intval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'noDataMessage') {
|
||||
$this->assertSame($noDataMessage, $option['value']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->getLogger()->debug('testEdit finished');
|
||||
}
|
||||
}
|
||||
139
tests/integration/Widget/DataSetViewWidgetTest.php
Normal file
139
tests/integration/Widget/DataSetViewWidgetTest.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSet;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSetColumn;
|
||||
use Xibo\OAuth2\Client\Entity\XiboDataSetView;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
class DataSetViewWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/** @var XiboDataSet */
|
||||
protected $dataSet;
|
||||
|
||||
/** @var XiboDataSetColumn */
|
||||
protected $dataSetColumn;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Add a DataSet
|
||||
$this->dataSet = (new XiboDataSet($this->getEntityProvider()))->create(Random::generateString(), 'Test');
|
||||
|
||||
// Create a Column for our DataSet
|
||||
$this->dataSetColumn = (new XiboDataSetColumn($this->getEntityProvider()))->create($this->dataSet->dataSetId, Random::generateString(8, 'phpunit'),'', 2, 1, 1, '');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create a Widget for us to edit.
|
||||
$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->widgetId = $response['widgetId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
// Delete the DataSet
|
||||
$this->dataSet->deleteWData();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$nameNew = 'Edited Name';
|
||||
$durationNew = 80;
|
||||
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'dataSetColumnId' => [$this->dataSetColumn->dataSetColumnId],
|
||||
'name' => $nameNew,
|
||||
'duration' => $durationNew,
|
||||
'updateInterval' => 100,
|
||||
'rowsPerPage' => 2,
|
||||
'showHeadings' => 0,
|
||||
'upperLimit' => 0,
|
||||
'lowerLimit' => 0,
|
||||
'filter' => null,
|
||||
'ordering' => null,
|
||||
'templateId' => 'light-green',
|
||||
'overrideTemplate' => 0,
|
||||
'useOrderingClause' => 0,
|
||||
'useFilteringClause' => 0,
|
||||
'noDataMessage' => 'No Data returned',
|
||||
], ['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 XiboDataSetView $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboDataSetView($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
$this->assertSame($nameNew, $checkWidget->name);
|
||||
$this->assertSame($durationNew, $checkWidget->duration);
|
||||
|
||||
foreach ($checkWidget->widgetOptions as $option) {
|
||||
if ($option['option'] == 'templateId') {
|
||||
$this->assertSame('light-green', $option['value']);
|
||||
} else if ($option['option'] == 'updateInterval') {
|
||||
$this->assertSame(100, intval($option['value']));
|
||||
} else if ($option['option'] == 'name') {
|
||||
$this->assertSame($nameNew, $option['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
108
tests/integration/Widget/EmbeddedWidgetTest.php
Normal file
108
tests/integration/Widget/EmbeddedWidgetTest.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboEmbedded;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class EmbeddedWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class EmbeddedWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create a Widget for us to edit.
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/embedded/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
$this->widgetId = $response['widgetId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Xibo\OAuth2\Client\Exception\XiboApiException
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
$name = Random::generateString();
|
||||
$durationNew = 80;
|
||||
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'name' => $name,
|
||||
'duration' => $durationNew,
|
||||
'transparency' => 1,
|
||||
'scaleContent' => 1,
|
||||
'embedHtml' => null,
|
||||
'embedScript' => null,
|
||||
'embedStyle' => '<style type="text/css"> </style>'
|
||||
], ['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 XiboEmbedded $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboEmbedded($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
$this->assertSame($name, $checkWidget->name);
|
||||
$this->assertSame($durationNew, $checkWidget->duration);
|
||||
}
|
||||
}
|
||||
149
tests/integration/Widget/GoogleTrafficWidgetTest.php
Normal file
149
tests/integration/Widget/GoogleTrafficWidgetTest.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\OAuth2\Client\Entity\XiboGoogleTraffic;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class GoogleTrafficWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class GoogleTrafficWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
parent::installModuleIfNecessary('googletraffic', '\Xibo\Widget\GoogleTraffic');
|
||||
}
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create a Widget for us to edit.
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/googletraffic/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
$this->widgetId = $response['widgetId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($name, $duration, $useDisplayLocation, $longitude, $latitude, $zoom)
|
||||
* @return array
|
||||
*/
|
||||
public function provideEditCases()
|
||||
{
|
||||
# Sets of data used in testAdd
|
||||
return [
|
||||
'Use Display location' => [200, 'Traffic with display location', 2000, 1, null, null, 100],
|
||||
'Custom location 1' => [200, 'Traffic with custom location - Italy', 4500, 0, 7.640974, 45.109612, 80],
|
||||
'Custom location 2' => [200, 'Traffic with custom location - Japan', 4500, 0, 35.7105, 139.7336, 50],
|
||||
'No zoom provided' => [422, 'no zoom', 2000, 1, null, null, null],
|
||||
'no lat/long' => [422, 'no lat/long provided with useDisplayLocation 0', 3000, 0, null, null, 20],
|
||||
'low min duration' => [422, 'Traffic with display location', 20, 1, null, null, 100],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit
|
||||
* @dataProvider provideEditCases
|
||||
* This test works correctly, it's marked as broken because we don't have this widget installed by default
|
||||
* @group broken
|
||||
*/
|
||||
public function testEdit($statusCode, $name, $duration, $useDisplayLocation, $lat, $long, $zoom)
|
||||
{
|
||||
$this->getLogger()->debug('testEdit ' . get_class($this) .' Test');
|
||||
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'name' => $name,
|
||||
'duration' => $duration,
|
||||
'useDuration' => 1,
|
||||
'useDisplayLocation' => $useDisplayLocation,
|
||||
'longitude' => $long,
|
||||
'latitude' => $lat,
|
||||
'zoom' => $zoom,
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame($statusCode, $response->getStatusCode(), 'Incorrect status code.', var_export($response, true));
|
||||
|
||||
if ($statusCode == 422)
|
||||
return;
|
||||
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
|
||||
/** @var XiboGoogleTraffic $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboGoogleTraffic($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
$this->assertSame($name, $checkWidget->name);
|
||||
$this->assertSame($duration, $checkWidget->duration);
|
||||
|
||||
foreach ($checkWidget->widgetOptions as $option) {
|
||||
if ($option['option'] == 'longitude' && $long !== null) {
|
||||
$this->assertSame($long, floatval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'latitude' && $lat !== null) {
|
||||
$this->assertSame($lat, floatval($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'zoom') {
|
||||
$this->assertSame($zoom, intval($option['value']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
139
tests/integration/Widget/HlsWidgetTest.php
Normal file
139
tests/integration/Widget/HlsWidgetTest.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\OAuth2\Client\Entity\XiboHls;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class HlsWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class HlsWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
parent::installModuleIfNecessary('hls', '\Xibo\Widget\Hls');
|
||||
}
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create a Widget for us to edit.
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/hls/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
$this->widgetId = $response['widgetId'];
|
||||
|
||||
$this->getLogger()->debug('Setup Finished');
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($name, $useDuration, $duration, $uri, $mute, $transparency)
|
||||
* @return array
|
||||
*/
|
||||
public function provideEditCases()
|
||||
{
|
||||
# Sets of data used in testAdd
|
||||
return [
|
||||
'HLS stream' => [200, 'HLS stream', 1, 20, 'http://ceu.xibo.co.uk/hls/big_buck_bunny_adaptive_master.m3u8', 0, 0],
|
||||
'HLS stream 512' => [200, 'HLS stream with transparency', 1, 20, 'http://ceu.xibo.co.uk/hls/big_buck_bunny_adaptive_512.m3u8', 0, 1],
|
||||
'No url provided' => [422, 'no uri', 1, 10, '', 0, 0],
|
||||
'No duration provided' => [422, 'no duration with useDuration 1', 1, 0, 'http://ceu.xibo.co.uk/hls/big_buck_bunny_adaptive_512.m3u8', 0, 0],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit
|
||||
* @dataProvider provideEditCases
|
||||
*/
|
||||
public function testEdit($statusCode, $name, $useDuration, $duration, $uri, $mute, $transparency)
|
||||
{
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'name' => $name,
|
||||
'useDuration' => $useDuration,
|
||||
'duration' => $duration,
|
||||
'uri' => $uri,
|
||||
'mute' => $mute,
|
||||
'transparency' => $transparency,
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->assertSame($statusCode, $response->getStatusCode());
|
||||
|
||||
if ($statusCode == 422)
|
||||
return;
|
||||
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
|
||||
/** @var XiboHls $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboHls($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
$this->assertSame($name, $checkWidget->name);
|
||||
$this->assertSame($duration, $checkWidget->duration);
|
||||
|
||||
foreach ($checkWidget->widgetOptions as $option) {
|
||||
if ($option['option'] == 'uri') {
|
||||
$this->assertSame($uri, urldecode(($option['value'])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
135
tests/integration/Widget/ImageWidgetTest.php
Normal file
135
tests/integration/Widget/ImageWidgetTest.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboImage;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ImageWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class ImageWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create some media to upload
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/xts-night-001.jpg');
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
// Tidy up the media
|
||||
$this->media->delete();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$this->getLogger()->debug('testEdit ' . get_class($this) .' Test');
|
||||
|
||||
// Edit properties
|
||||
$nameNew = 'Edited Name: ' . Random::generateString(5);
|
||||
$durationNew = 80;
|
||||
$scaleTypeIdNew = 'stretch';
|
||||
$alignIdNew = 'center';
|
||||
$valignIdNew = 'top';
|
||||
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'name' => $nameNew,
|
||||
'duration' => $durationNew,
|
||||
'useDuration' => 1,
|
||||
'scaleTypeId' => $scaleTypeIdNew,
|
||||
'alignId' => $alignIdNew,
|
||||
'valignId' => $valignIdNew,
|
||||
], ['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 $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboImage($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
$this->assertSame($nameNew, $checkWidget->name);
|
||||
$this->assertSame($durationNew, $checkWidget->duration);
|
||||
$this->assertSame($this->media->mediaId, intval($checkWidget->mediaIds[0]));
|
||||
|
||||
foreach ($checkWidget->widgetOptions as $option) {
|
||||
if ($option['option'] == 'scaleTypeId') {
|
||||
$this->assertSame($scaleTypeIdNew, $option['value']);
|
||||
}
|
||||
if ($option['option'] == 'alignId') {
|
||||
$this->assertSame($alignIdNew, $option['value']);
|
||||
}
|
||||
if ($option['option'] == 'valignId') {
|
||||
$this->assertSame($valignIdNew, $option['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
128
tests/integration/Widget/LocalVideoWidgetTest.php
Normal file
128
tests/integration/Widget/LocalVideoWidgetTest.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\OAuth2\Client\Entity\XiboLocalVideo;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LocalVideoWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class LocalVideoWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create a Widget for us to edit.
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/localvideo/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
$this->widgetId = $response['widgetId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($name, $duration, $theme, $clockTypeId, $offset, $format, $showSeconds, $clockFace)
|
||||
* @return array
|
||||
*/
|
||||
public function provideEditCases()
|
||||
{
|
||||
# Sets of data used in testAdd
|
||||
return [
|
||||
'Aspect' => ['rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov', 30, 1, 'aspect', 0],
|
||||
'Stretch muted' => ['rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov', 100, 1, ' stretch', 1],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Xibo\OAuth2\Client\Exception\XiboApiException
|
||||
* @dataProvider provideEditCases
|
||||
*/
|
||||
public function testEdit($uri, $duration, $useDuration, $scaleTypeId, $mute)
|
||||
{
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'uri' => $uri,
|
||||
'duration' => $duration,
|
||||
'useDuration' => $useDuration,
|
||||
'scaleTypeId' => $scaleTypeId,
|
||||
'mute' => $mute,
|
||||
], ['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 XiboLocalVideo $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboLocalVideo($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
$this->assertSame($duration, $checkWidget->duration);
|
||||
|
||||
foreach ($checkWidget->widgetOptions as $option) {
|
||||
if ($option['option'] == 'uri') {
|
||||
$this->assertSame($uri, urldecode($option['value']));
|
||||
}
|
||||
if ($option['option'] == 'scaleTypeId') {
|
||||
$this->assertSame($scaleTypeId, $option['value']);
|
||||
}
|
||||
if ($option['option'] == 'mute') {
|
||||
$this->assertSame($mute, intval($option['value']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
137
tests/integration/Widget/MenuBoardWidgetTest.php
Normal file
137
tests/integration/Widget/MenuBoardWidgetTest.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class LocalVideoWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class MenuBoardWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
private $menuBoard;
|
||||
private $menuBoardCategory;
|
||||
private $menuBoardProduct;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create a Widget for us to edit.
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/menuboard/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
$this->menuBoard = $this->getEntityProvider()->post('/menuboard', [
|
||||
'name' => 'phpunit Menu board',
|
||||
'description' => 'Description for test Menu Board'
|
||||
]);
|
||||
|
||||
$this->menuBoardCategory = $this->getEntityProvider()->post('/menuboard/' . $this->menuBoard['menuId'] . '/category', [
|
||||
'name' => 'phpunit Menu Board Category'
|
||||
]);
|
||||
|
||||
$this->menuBoardProduct = $this->getEntityProvider()->post('/menuboard/' . $this->menuBoardCategory['menuCategoryId'] . '/product', [
|
||||
'name' => 'phpunit Menu Board Product',
|
||||
'price' => '$11.11'
|
||||
]);
|
||||
|
||||
$this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'step' => 1,
|
||||
'menuId' => $this->menuBoard['menuId'],
|
||||
'templateId' => 'menuboard1'
|
||||
]);
|
||||
|
||||
$this->getEntityProvider()->put('/playlist/widget/' . $response['widgetId'], [
|
||||
'step' => 2,
|
||||
'menuBoardCategories_1' => [$this->menuBoardCategory['menuCategoryId']]
|
||||
]);
|
||||
|
||||
$this->widgetId = $response['widgetId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
if ($this->menuBoard['menuId'] !== null) {
|
||||
$this->getEntityProvider()->delete('/menuboard/' . $this->menuBoard['menuId']);
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$response = $this->sendRequest('PUT', '/playlist/widget/' . $this->widgetId, [
|
||||
'name' => 'Test Menu Board Widget',
|
||||
'duration' => 60,
|
||||
'useDuration' => 1,
|
||||
'showUnavailable' => 0,
|
||||
'productsHighlight' => [$this->menuBoardProduct['menuProductId']]
|
||||
], ['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());
|
||||
|
||||
$widget = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId])[0];
|
||||
|
||||
$this->assertSame(60, $widget['duration']);
|
||||
foreach ($widget['widgetOptions'] as $option) {
|
||||
if ($option['option'] == 'showUnavailable') {
|
||||
$this->assertSame(0, intval($option['value']));
|
||||
} elseif ($option['option'] == 'name') {
|
||||
$this->assertSame('Test Menu Board Widget', $option['value']);
|
||||
} elseif ($option['option'] == 'productsHighlight') {
|
||||
$this->assertSame([$this->menuBoardProduct['menuBoardProductId']], $option['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
122
tests/integration/Widget/PdfWidgetTest.php
Normal file
122
tests/integration/Widget/PdfWidgetTest.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboLibrary;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPdf;
|
||||
use Xibo\OAuth2\Client\Entity\XiboPlaylist;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class PdfWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class PdfWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var XiboLibrary */
|
||||
protected $media;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create some media to upload
|
||||
$this->media = (new XiboLibrary($this->getEntityProvider()))->create(Random::generateString(), PROJECT_ROOT . '/tests/resources/sampleDocument.pdf');
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
// Tidy up the media
|
||||
$this->media->delete();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Edit
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
$this->getLogger()->debug('testEdit ' . get_class($this) .' Test');
|
||||
|
||||
$name = 'Edited Name: ' . Random::generateString(5);
|
||||
$duration = 80;
|
||||
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'name' => $name,
|
||||
'duration' => $duration,
|
||||
], ['CONTENT_TYPE' => 'application/x-www-form-urlencoded']);
|
||||
|
||||
$this->getLogger()->debug('testEdit Finished');
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertNotEmpty($response->getBody());
|
||||
$object = json_decode($response->getBody());
|
||||
|
||||
$this->assertObjectHasAttribute('data', $object, $response->getBody());
|
||||
|
||||
/** @var XiboPdf $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboPdf($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
$this->assertSame($name, $checkWidget->name);
|
||||
$this->assertSame($duration, $checkWidget->duration);
|
||||
$this->assertSame($this->media->mediaId, intval($checkWidget->mediaIds[0]));
|
||||
|
||||
$this->getLogger()->debug('testEdit Finished');
|
||||
}
|
||||
}
|
||||
139
tests/integration/Widget/ShellCommandWidgetTest.php
Normal file
139
tests/integration/Widget/ShellCommandWidgetTest.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?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\Widget;
|
||||
|
||||
use Xibo\Helper\Random;
|
||||
use Xibo\OAuth2\Client\Entity\XiboCommand;
|
||||
use Xibo\OAuth2\Client\Entity\XiboShellCommand;
|
||||
use Xibo\Tests\Helper\LayoutHelperTrait;
|
||||
use Xibo\Tests\LocalWebTestCase;
|
||||
|
||||
/**
|
||||
* Class ShellCommandWidgetTest
|
||||
* @package Xibo\Tests\Integration\Widget
|
||||
*/
|
||||
class ShellCommandWidgetTest extends LocalWebTestCase
|
||||
{
|
||||
use LayoutHelperTrait;
|
||||
|
||||
/** @var \Xibo\OAuth2\Client\Entity\XiboLayout */
|
||||
protected $publishedLayout;
|
||||
|
||||
/** @var XiboCommand */
|
||||
protected $command;
|
||||
|
||||
/** @var int */
|
||||
protected $widgetId;
|
||||
|
||||
/**
|
||||
* setUp - called before every test automatically
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->getLogger()->debug('Setup for ' . get_class($this) .' Test');
|
||||
|
||||
// Create a Layout
|
||||
$this->publishedLayout = $this->createLayout();
|
||||
|
||||
// Checkout
|
||||
$layout = $this->getDraft($this->publishedLayout);
|
||||
|
||||
// Create a Widget for us to edit.
|
||||
$response = $this->getEntityProvider()->post('/playlist/widget/shellcommand/' . $layout->regions[0]->regionPlaylist->playlistId);
|
||||
|
||||
// Create a command
|
||||
$this->command = (new XiboCommand($this->getEntityProvider()))->create(Random::generateString(), 'phpunit description', 'phpunitcode');
|
||||
|
||||
$this->widgetId = $response['widgetId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown - called after every test automatically
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
// Delete the Layout we've been working with
|
||||
$this->deleteLayout($this->publishedLayout);
|
||||
|
||||
// Delete the commant
|
||||
$this->command->delete();
|
||||
|
||||
parent::tearDown();
|
||||
|
||||
$this->getLogger()->debug('Tear down for ' . get_class($this) .' Test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Each array is a test run
|
||||
* Format ($name, $duration, $windowsCommand, $linuxCommand, $launchThroughCmd, $terminateCommand, $useTaskkill, $commandCode)
|
||||
* @return array
|
||||
*/
|
||||
public function provideSuccessCases()
|
||||
{
|
||||
# Sets of data used in testAdd
|
||||
return [
|
||||
'Windows new command' => ['Api Windows command', 20, 1,'reboot', NULL, 1, null, 1, null],
|
||||
'Android new command' => ['Api Android command', 30, 1, null, 'reboot', null, 1, null, null],
|
||||
'Previously created command' => ['Api shell command', 50, 1, null, null, 1, 1, 1, 'phpunit code']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Xibo\OAuth2\Client\Exception\XiboApiException
|
||||
* @dataProvider provideSuccessCases
|
||||
*/
|
||||
public function testEdit($name, $duration, $useDuration, $windowsCommand, $linuxCommand, $launchThroughCmd, $terminateCommand, $useTaskkill, $commandCode)
|
||||
{
|
||||
$response = $this->sendRequest('PUT','/playlist/widget/' . $this->widgetId, [
|
||||
'name' => $name,
|
||||
'duration' => $duration,
|
||||
'useDuration' => $useDuration,
|
||||
'windowsCommand' => $windowsCommand,
|
||||
'linuxCommand' => $linuxCommand,
|
||||
'launchThroughCmd' => $launchThroughCmd,
|
||||
'terminateCommand' => $terminateCommand,
|
||||
'useTaskkill' => $useTaskkill,
|
||||
'commandCode' => $commandCode,
|
||||
], ['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 XiboShellCommand $checkWidget */
|
||||
$response = $this->getEntityProvider()->get('/playlist/widget', ['widgetId' => $this->widgetId]);
|
||||
$checkWidget = (new XiboShellCommand($this->getEntityProvider()))->hydrate($response[0]);
|
||||
|
||||
$this->assertSame($name, $checkWidget->name);
|
||||
$this->assertSame($duration, $checkWidget->duration);
|
||||
|
||||
foreach ($checkWidget->widgetOptions as $option) {
|
||||
if ($option['option'] == 'commandCode') {
|
||||
$this->assertSame($commandCode, $option['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user