14 Commits

Author SHA1 Message Date
Vassyli 03fc114775 Revert "Fixs a weird bug causing the deletion of scens to NOT cascade, despite passing tests."
This reverts commit 848e6b022c.
2017-03-13 14:13:50 +01:00
Vassyli 848e6b022c Fixs a weird bug causing the deletion of scens to NOT cascade, despite passing tests. 2017-03-12 19:39:44 +01:00
Vassyli 5c3fd4714d Adds fixes and tests for cascade=persist, remove for scene entities.
It still looks like doctrine doesn't "know" about the column names in a cascade=remove relationship and assumes the property name to be also the column name - which is usually not true (by default, it's propertyname_id).

This update changes the column name so that doctrine's assumptions are correct again and adds tests so any changes which invalidates this relationship can be gecocnized easily.
2017-03-11 12:51:25 +01:00
Vassyli 498f4965e6 Adds tests and support for Unidirectional connections.
Also fixes travis config.
2017-03-02 20:04:27 +01:00
Vassyli 2970bd09d7 Changed the scene parent<=>child relationship to connections.
The parent<=>child relationship of scenes was removed. Instead, this commit introduces the concept of a connection.

A connection is used to connect two scenes. Depending on which entity the connect-method is called, one is defined as the "outgoing" scene, the other as the ingoing scene:

```
$a->connect($b);
```

In this case, $a will be the outgoing part of the connection, $b the incoming.

Furthermore, in order to support action groups, this commit introduces SceneConnectionGroups which can be created in scenes and checked wether they exist or not. Using these, it is possible to specifiy to which part of the scenes are connected to each other.

```
$a->getConnectionGroup("scene-A/marketsquare")->connect($b);
```

In this case, $a will have the action to access $b under the ActionGroup of scene-A/marketsquare. On the other hand, $b, which doesn't have a connection group specified, will have the connection back to $a in the default group.

Connect also accepts the return value of getConnectionGroup as the argument, thus allowing the connection _to_ a certain part of $b as well:

```
$a->connect($b->getConnectionGroup("scene-B/back"));
```

The tests for scenes were updates in order to reflect this change.
2017-03-02 17:19:46 +01:00
Vassyli e82e72a183 Abstract actor model has more straightforward API
The implicit API requirements via class properties has been changed to relay now on abstract methods that the extending class must implement.
2017-01-19 10:18:27 +01:00
Vassyli 9ecd0ddc58 Applied suggested changes 2017-01-19 10:02:31 +01:00
Vassyli 64cb22d3c0 Replaced Permissionable/-Interface with an abstract Actor class. 2017-01-19 10:02:31 +01:00
Vassyli f8057077bc Adds logging to permission manager and requires an actor to return an actor name. 2017-01-19 10:02:31 +01:00
Vassyli 1c89d8f204 Adds removal of exceptions as well as error handling. 2017-01-19 10:02:31 +01:00
Vassyli 3b8537fab6 Adds methods to read and check permissions. 2017-01-19 10:02:31 +01:00
Vassyli 3bf23f3ac7 Adds Permission model and framework for testing permission manager. 2017-01-19 10:02:31 +01:00
Basilius Sauter 94e18b8d11 Increases windows compability by removing microtime from tests 2017-01-04 08:26:10 +01:00
Basilius Sauter b8f47c6d53 Fixed composer creation to account completely for cwd
Also added tests that fail if not.
2017-01-04 08:23:32 +01:00
39 changed files with 2529 additions and 505 deletions
+1
View File
@@ -1,5 +1,6 @@
### Project related
vendor/
.idea/
logs/*
+1 -1
View File
@@ -1,7 +1,7 @@
sudo: false
language: php
php:
- '7.0'
- '7.1'
install:
- composer install
script:
+3 -3
View File
@@ -12,7 +12,7 @@
"bin/daenerys"
],
"require": {
"php": "^7.0.0",
"php": "^7.1.0",
"composer/composer": "*",
"gedmo/doctrine-extensions": "*",
"doctrine/orm": "^2.5",
@@ -29,8 +29,8 @@
],
"require-dev": {
"phpunit/phpunit": "*",
"phpunit/dbunit": "*",
"phpunit/phpunit": "^5.0",
"phpunit/dbunit": "^2.0",
"block8/php-docblock-checker": "2.0.0"
}
}
Generated
+415 -328
View File
File diff suppressed because it is too large Load Diff
+9
View File
@@ -76,4 +76,13 @@ class ActionGroup
{
$this->actions = $actions;
}
/**
* Adds a single action to the list of actions.
* @param Action $action
*/
public function addAction(Action $action)
{
$this->actions[] = $action;
}
}
+8 -7
View File
@@ -6,7 +6,8 @@ namespace LotGD\Core;
use Composer\{
Composer,
Factory,
IO\NullIO
IO\NullIO,
Package\CompletePackageInterface
};
use Monolog\Logger;
@@ -41,13 +42,13 @@ class ComposerManager
{
if ($this->composer === null) {
// Verify location of composer.json.
$path = $this->cwd . DIRECTORY_SEPARATOR . "composer.json";
if (!file_exists($path)) {
throw new InvalidConfigurationException("composer.json cannot be found at {$path}.");
$composerConfigPath = $this->cwd . DIRECTORY_SEPARATOR . "composer.json";
if (!file_exists($composerConfigPath)) {
throw new InvalidConfigurationException("composer.json cannot be found at {$composerConfigPath}.");
}
$io = new NullIO();
$this->composer = Factory::create($io, $path);
$factory = new Factory();
$this->composer = $factory->createComposer(new NullIO(), $composerConfigPath, false, $this->cwd);
}
return $this->composer;
@@ -58,7 +59,7 @@ class ComposerManager
* @return PackageInterface Package corresponding to this library.
* @throws LibraryDoesNotExistException
*/
public function getPackageForLibrary(string $library): PackageInterface
public function getPackageForLibrary(string $library): CompletePackageInterface
{
// TODO: should probably do something better than O(n) here.
$packages = $this->getComposer()->getRepositoryManager()->getLocalRepository()->getPackages();
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if an existing entity is tried to create again.
*/
class EntityAlreadyExistsException extends EntityException
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if a non-existing entity is requested.
*/
class EntityDoesNotExistException extends EntityException
{
}
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* A basic entity exception
*/
class EntityException extends CoreException
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if an existing entity is tried to create again.
*/
class PermissionAlreadyExistsException extends EntityAlreadyExistsException
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if an existing entity is tried to create again.
*/
class PermissionDoesNotExistException extends EntityDoesNotExistException
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if a requested permission id has not been found.
*/
class PermissionIdNotFoundException extends EntityDoesNotExistException
{
}
+62 -22
View File
@@ -6,16 +6,11 @@ namespace LotGD\Core;
use Doctrine\ORM\EntityManagerInterface;
use Monolog\Logger;
use LotGD\Core\Models\ {
Character,
Viewpoint,
Scene
use LotGD\Core\Models\{
Character, SceneConnectable, Viewpoint, Scene, SceneConnection
};
use LotGD\Core\Exceptions\ {
ActionNotFoundException,
CharacterNotFoundException,
InvalidConfigurationException,
SceneNotFoundException
ActionNotFoundException, CharacterNotFoundException, InvalidConfigurationException, SceneNotFoundException
};
/**
@@ -36,6 +31,10 @@ class Game
/**
* Construct a game. You probably want to use Bootstrap to do this.
* @param Configuration $configuration
* @param Logger $logger
* @param EntityManagerInterface $entityManager
* @param string $cwd
*/
public function __construct(
Configuration $configuration,
@@ -136,9 +135,9 @@ class Game
/**
* Returns the logger instance to write logs.
* @return \Monolog\Logger
* @return Logger
*/
public function getLogger(): \Monolog\Logger
public function getLogger(): Logger
{
return $this->logger;
}
@@ -161,6 +160,7 @@ class Game
/**
* Returns the currently configured user character.
* @return Character
* @throws CharacterNotFoundException
*/
public function getCharacter(): Character
{
@@ -182,6 +182,7 @@ class Game
/**
* Return the viewpoint for the current user.
* @return Viewpoint
* @throws InvalidConfigurationException
*/
public function getViewpoint(): Viewpoint
{
@@ -236,19 +237,56 @@ class Game
// Generate the default set of actions: the default group with
// all children.
$this->getLogger()->addDebug("Building default action group...");
$defaultGroup = new ActionGroup(ActionGroup::DefaultGroup, '', 0);
$as = array_map(function ($c) {
$id = $c->getId();
$this->getLogger()->addDebug(" Adding navigation action for child sceneId={$id}");
return new Action($c->getId());
}, $scene->getChildren()->toArray());
$defaultGroup->setActions($as);
$count = count($as);
$this->getLogger()->addDebug("Total actions: {$count}");
$actionGroups = [
ActionGroup::DefaultGroup => new ActionGroup(ActionGroup::DefaultGroup, '', 0),
];
$hiddenGroup = new ActionGroup(ActionGroup::HiddenGroup, '', 100);
// Iterates through all connections and adds an action to the connected scene to the action group. If the connection
// belongs to a new connection Group, it creates a new ActionGroup.
$scene->getConnections()->map(function(SceneConnection $connection) use ($scene, &$actionGroups) {
if ($connection->getOutgoingScene() === $scene) {
// current scene is outgoing, use incoming.
$connectedScene = $connection->getIncomingScene();
$connectionGroupName = $connection->getOutgoingConnectionGroupName();
} else {
// current scene is not outgoing, thus incoming, use outgoing.
$connectedScene = $connection->getOutgoingScene();
$connectionGroupName = $connection->getIncomingConnectionGroupName();
$viewpoint->setActionGroups([$defaultGroup, $hiddenGroup]);
// Check if the connection is unidirectional - if yes, the current scene (incoming in this branch) cannot
// connect to the outgoing scene.
if ($connection->isDirectionality(SceneConnectable::Unidirectional)) {
return;
}
}
$this->getLogger()->addDebug(" Adding navigation action for child sceneId={$connectedScene->getId()}");
$action = new Action($connectedScene->getId());
if ($connectionGroupName === null) {
$actionGroups[ActionGroup::DefaultGroup]->addAction($action);
} else {
if (isset($actionGroups[$connectionGroupName])) {
$actionGroups[$connectionGroupName]->addAction($action);
} else {
$connectionGroup = $scene->getConnectionGroup($connectionGroupName);
$actionGroup = new ActionGroup($connectionGroupName, $connectionGroup->getTitle(), 0);
$actionGroup->addAction($action);
$actionGroups[$connectionGroupName] = $actionGroup;
}
}
});
// Logging
$counts = implode(", ", array_map(function($k, $v) {
return $k .count($v);
}, array_keys($actionGroups), array_values($actionGroups)));
$this->getLogger()->addDebug("Total actions: {$counts}");
$actionGroups[ActionGroup::HiddenGroup] = new ActionGroup(ActionGroup::HiddenGroup, '', 100);
$viewpoint->setActionGroups(array_values($actionGroups));
// Let and installed listeners (ie modules) make modifications to the
// new viewpoint, including the ability to redirect the user to
@@ -275,7 +313,9 @@ class Game
* Take the specified navigation action for the currently configured
* user. This action must be present in the current user's viewpoint.
* @param string $actionId The identifier of the action to take.
* @param array $paramters
* @param array $parameters
* @throws ActionNotFoundException
* @throws SceneNotFoundException
*/
public function takeAction(string $actionId, array $parameters = [])
{
+134
View File
@@ -0,0 +1,134 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
use Generator;
use LotGD\Core\Exceptions\PermissionAlreadyExistsException;
use LotGD\Core\Exceptions\PermissionDoesNotExistException;
use LotGD\Core\Models\Permission;
use LotGD\Core\Models\PermissionAssociationInterface;
/**
* This abtract class provides functionality for user entities that crates might
* want to implement, such as permissions.
*/
abstract class Actor
{
/** @var array Associations between permission-id and PermissionAssociation entity. */
private $permissionIdToAssociation = [];
/**
* Needs to return a generator which iterates through all permission associations.
* @return Generator List of PermissionAssociations.
*/
abstract protected function getPermissionAssociations(): Generator;
/**
* Returns the class of the permission associations used for the entity
* implementing this class.
* @return string fully qualified class name of the permission association entity.
*/
abstract protected function getPermissionAssociationClass(): string;
/**
* Loads all associated permissions for this actor.
* @throws PermissionAssociationEntityMissingException
*/
protected function loadPermissions()
{
if (class_exists($this->getPermissionAssociationClass()) === false) {
throw new PermissionAssociationEntityMissingException(
"The method getPermissionAssociationClass does not return a valid class name."
);
}
if (empty($this->permissionIdToAssociation)) {
foreach ($this->getPermissionAssociations() as $permission) {
$this->permissionIdToAssociation[$permission->getId()] = $permission;
}
}
}
/**
* Checks if the actor is associated with a given permission. For permission
* checking, use only the PermissionManager class.
* @param string $permissionId
* @return bool
*/
public function hasPermissionSet(string $permissionId): bool
{
$this->loadPermissions();
return isset($this->permissionIdToAssociation[$permissionId]);
}
/**
* Returns the associated permission given by an id. For permission
* checking, use only the PermissionManager class.
* @param string $permissionId
* @return PermissionAssociationInterface
*/
public function getPermission(string $permissionId): PermissionAssociationInterface
{
$this->loadPermissions();
return $this->permissionIdToAssociation[$permissionId];
}
/**
* Returns the raw permission given by the id. For permission
* checking, use only the PermissionManager class.
* @param string $permissionId
* @return Permission
*/
public function getRawPermission(string $permissionId): Permission
{
$this->loadPermissions();
return $this->permissionIdToAssociation[$permissionId]->getPermission();
}
/**
* Associates a permission with this actor in a given state. For permission
* manipulation, use only the PermissionManager class.
* @param Permission $permission
* @param int $state
* @throws PermissionAlreadyExistsException
*/
public function addPermission(Permission $permission, int $state)
{
$this->loadPermissions();
if ($this->hasPermissionSet($permission->getId())) {
$permissionId = $permission->getId();
throw new PermissionAlreadyExistsException("The permission with the id {$permissionId} has already been set on this actor.");
} else {
$associationEntity = $this->getPermissionAssociationClass();
$permissionAssoc = new $associationEntity($this, $permission, $state);
$this->permissions->add($permissionAssoc);
$this->permissionIdToAssociation[$permissionAssoc->getId()] = $permissionAssoc;
}
}
/**
* Removes an associated permission from this actor by a given id. For permission
* manipulation, use only the PermissionManager class.
* @param string $permissionId
* @throws PermissionDoesNotExistException
*/
public function removePermission(string $permissionId)
{
$this->loadPermissions();
if ($this->hasPermissionSet($permissionId)) {
$permissionAssoc = $this->getPermission($permissionId);
$this->permissions->removeElement($permissionAssoc);
unset($this->permissionIdToAssociation[$permissionId]);
} else {
throw new PermissionDoesNotExistException("The permission with the id {$permissionId} has not been set on this actor.");
}
}
}
+95
View File
@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Tools\Model\Creator;
use LotGD\Core\Tools\Model\Deletor;
/**
* Represents a permission.
*
* @Entity()
* @Table(name="permissions")
*/
class Permission implements CreateableInterface
{
use Creator;
use Deletor;
/** @Id @Column(type="string"); */
private $id;
/** @Column(type="string") */
private $library;
/** @Column(type="string") */
private $name;
static $fillable = [
"id",
"library",
"name"
];
/**
* Returns the id of this entity.
* @return string
*/
public function getId(): string
{
return $this->id;
}
/**
* Sets this entity's id if it's not set yet.
* @param string $id
*/
public function setId(string $id)
{
if (empty($this->id)) {
$this->id = $id;
}
else {
throw new ArgumentException("Cannot reset id.");
}
}
/**
* Returns the library this permission belongs to.
* @return string
*/
public function getLibrary(): string
{
return $this->library;
}
/**
* Sets the library this permission belongs to.
* @param string $library
*/
public function setLibrary(string $library)
{
$this->library = $library;
}
/**
* Gets this entity's human readable name.
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* Sets this entity's human readable name.
* @param string $name
*/
public function setName(string $name)
{
$this->name = $name;
}
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
/**
* Extend this class to provide an association between an entity and a permission.
*/
interface PermissionAssociationInterface
{
}
+210 -77
View File
@@ -7,8 +7,8 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Column;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Tools\Model\Creator;
use LotGD\Core\Tools\Model\Deletor;
use LotGD\Core\Tools\Model\SceneBasics;
@@ -20,7 +20,7 @@ use LotGD\Core\Tools\Model\SceneBasics;
* @Entity
* @Table(name="scenes")
*/
class Scene implements CreateableInterface
class Scene implements CreateableInterface, SceneConnectable
{
use Creator;
use Deletor;
@@ -30,18 +30,19 @@ class Scene implements CreateableInterface
private $id;
/**
* @ManyToMany(targetEntity="Scene", mappedBy="children", cascade={"persist"})
* @OneToMany(targetEntity="SceneConnectionGroup", mappedBy="scene", cascade={"persist", "remove"})
*/
private $parents = null;
private $connectionGroups = null;
/**
* @ManyToMany(targetEntity="Scene", inversedBy="parents", cascade={"persist", "remove"})
* @JoinTable(name="paths",
* joinColumns={@JoinColumn(name="scene_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="child_scene_id", referencedColumnName="id")}
* )
* @OneToMany(targetEntity="SceneConnection", mappedBy="outgoingScene", cascade={"persist", "remove"})
*/
private $children = [];
private $outgoingConnections = null;
/**
* @OneToMany(targetEntity="SceneConnection", mappedBy="incomingScene", cascade={"persist", "remove"})
*/
private $incomingConnections = null;
/**
* @var array
@@ -49,17 +50,20 @@ class Scene implements CreateableInterface
private static $fillable = [
"title",
"description",
"parents",
"template"
];
/* @var ?ArrayCollection */
private $connectedScenes = null;
/**
* Constructor for a scene.
*/
public function __construct()
{
$this->children = new ArrayCollection();
$this->parents = new ArrayCollection();
$this->connectionGroups = new ArrayCollection();
$this->outgoingConnections = new ArrayCollection();
$this->incomingConnections = new ArrayCollection();
}
/**
@@ -72,88 +76,217 @@ class Scene implements CreateableInterface
}
/**
* Set the parents to the given Collection.
* @param Collection $parents
*/
public function setParents(Collection $parents)
{
// Super slow, but presumably these are short collections :)
// We should probably move to a set collection at some point.
$oldParents = $this->parents;
$additions = $parents->filter(function($element) use ($oldParents) {
return !$oldParents->contains($element);
});
$removals = $this->parents->filter(function($element) use ($parents) {
return !$parents->contains($element);
});
foreach ($additions as $a) {
$this->addParent($a);
}
foreach ($removals as $r) {
$this->removeParent($r);
}
$this->parents = $parents;
}
/**
* Adds a parent to this scene.
* @param \LotGD\Core\Models\Scene $parent
*/
public function addParent(Scene $parent)
{
if (!$this->parents->contains($parent)) {
$this->parents->add($parent);
$parent->addChild($this);
}
}
/**
* Removes a parent from this scene.
* @param Scene $parent
*/
public function removeParent(Scene $parent)
{
$this->parents->removeElement($parent);
$parent->removeChild($this);
}
/**
* Returns all the possible parents of this scene.
* Filters all connection groups for a specific name.
* @param string $name
* @return Collection
*/
public function getParents(): Collection
private function filterConnectionGroupCollectionByName(string $name): Collection
{
return $this->parents;
return $this->connectionGroups->filter(function(SceneConnectionGroup $group) use ($name) {
if ($group->getName() === $name) {
return true;
} else {
return false;
}
});
}
/**
* Returns a list of all children registered for this scene.
* @return Collection
* Returns true if this scene has a connection group with a given name associated.
* @param string $name
* @return bool
*/
public function getChildren(): Collection
public function hasConnectionGroup(string $name): bool
{
return $this->children;
return count($this->filterConnectionGroupCollectionByName($name)) === 1 ? true : false;
}
/**
* Registers a child for this scene.
* @param \LotGD\Core\Models\Scene $child
* Returns a connection group entity associated with this scene by a given name.
* @param string $name
* @return \LotGD\Core\Models\SceneConnectionGroup
*/
protected function addChild(Scene $child)
public function getConnectionGroup(string $name): SceneConnectionGroup
{
if (!$this->children->contains($child)) {
$this->children->add($child);
return $this->filterConnectionGroupCollectionByName($name)->first();
}
/**
* Adds a connection group to this scene.
* @param SceneConnectionGroup $group
* @throws ArgumentException
*/
public function addConnectionGroup(SceneConnectionGroup $group): void
{
if ($this->connectionGroups->contains($group) === true) {
throw new ArgumentException("This entity already owns the given connection group.");
}
if ($group->getScene()) {
throw new ArgumentException("The given connection group is already owned by another scene entity.");
}
$group->setScene($this);
$this->connectionGroups->add($group);
}
/**
* Removes a connection group from this scene.
* @param \LotGD\Core\Models\SceneConnectionGroup $group
* @throws ArgumentException
*/
public function dropConnectionGroup(SceneConnectionGroup $group): void
{
if ($this->connectionGroups->contains($group) === false) {
throw new ArgumentException("This entity does not own the given connection group.");
}
$this->connectionGroups->removeElement($group);
}
/**
* Lazy loading helper function - loads all scenes that are connected to this scene.
*/
private function loadConnectedScenes(): void
{
if ($this->connectedScenes === null) {
$connectedScenes = new ArrayCollection();
foreach ($this->outgoingConnections as $connection) {
$incomingScene = $connection->getIncomingScene();
if ($connectedScenes->contains($incomingScene) === false) {
$connectedScenes->add($incomingScene);
}
}
foreach ($this->incomingConnections as $connection) {
$outgoingScenes = $connection->getOutgoingScene();
if ($connectedScenes->contains($outgoingScenes) === false) {
$connectedScenes->add($outgoingScenes);
}
}
$this->connectedScenes = $connectedScenes;
}
}
/**
* Removes a child from this scene.
* @param \LotGD\Core\Models\Scene $child
* Returns a list of scenes that are connected to this scene.
*
* This procedure can get slow, especially if there are a lot of scenes connected
* to one. Use this method only for the installation and removal of modules,
* or for administrative purposes (like a scene graph).
* @return ArrayCollection
*/
protected function removeChild(Scene $child)
public function getConnectedScenes(): ArrayCollection
{
$this->children->removeElement($child);
$this->loadConnectedScenes();
return $this->connectedScenes;
}
/**
* Checks if the given scene is connected to this entity.
* @param \LotGD\Core\Models\Scene $scene
* @return bool True if yes.
*/
public function isConnectedTo(Scene $scene): bool
{
$this->loadConnectedScenes();
if ($this->connectedScenes->contains($scene)) {
return true;
} else {
return false;
}
}
/**
* Returns all collections of this entity.
* @return Collection
*/
public function getConnections(): Collection
{
return new ArrayCollection(
array_merge(
$this->outgoingConnections->toArray(),
$this->incomingConnections->toArray()
)
);
}
/**
* Adds a connection to the outgoing connections.
* @param \LotGD\Core\Models\SceneConnection $connection
*/
public function addOutgoingConnection(SceneConnection $connection): void
{
$this->outgoingConnections->add($connection);
// If we already have loaded all connected scenes, we need to add the entry manually.
if ($this->connectedScenes !== null) {
$this->connectedScenes->add($connection->getIncomingScene());
}
}
/**
* Adds a connection to the incoming connections.
* @param \LotGD\Core\Models\SceneConnection $connection
*/
public function addIncomingConnection(SceneConnection $connection): void
{
$this->incomingConnections->add($connection);
// If we already have loaded all connected scenes, we need to add the entry manually.
if ($this->connectedScenes !== null) {
$this->connectedScenes->add($connection->getOutgoingScene());
}
}
/**
* @inheritDoc
*/
public function connect(
SceneConnectable $connectable,
int $directionality = self::Bidirectional
): SceneConnection {
if ($connectable instanceof self) {
if ($this === $connectable) {
throw new ArgumentException("Cannot connect a scene to itself.");
}
if ($this->isConnectedTo($connectable)) {
throw new ArgumentException(
"The given scene (ID {$connectable->getId()}) is already connected to this (ID {$this->getId()}) one."
);
}
$connection = new SceneConnection($this, $connectable, $directionality);
$outgoingScene = $this;
$incomingScene = $connectable;
} else {
if ($this === $connectable->getScene()) {
throw new ArgumentException("Cannot connect a scene to itself.");
}
if ($this->isConnectedTo($connectable->getScene())) {
throw new ArgumentException(
"The given scene (ID {$connectable->getId()}) is already connected to this (ID {$this->getId()}) one."
);
}
$connection = new SceneConnection($this, $connectable->getScene(), $directionality);
$connection->setIncomingConnectionGroupName($connectable->getName());
$outgoingScene = $this;
$incomingScene = $connectable->getScene();
}
$outgoingScene->addOutgoingConnection($connection);
$incomingScene->addIncomingConnection($connection);
return $connection;
}
}
+19
View File
@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
interface SceneConnectable
{
public const Bidirectional = 0;
public const Unidirectional = 1;
public const Xordirectional = 2;
/**
* Creates an outgoing connection for this scene to the given connectable.
* @param SceneConnectable $connectable
* @param int $directionality
* @return SceneConnection
*/
public function connect(SceneConnectable $connectable, int $directionality): SceneConnection;
}
+128
View File
@@ -0,0 +1,128 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
/**
*
* @Entity
* @Table(name="scene_connections")
*/
class SceneConnection
{
/**
* @Id
* @ManyToOne(targetEntity="Scene")
* @JoinColumn(name="outgoingScene", referencedColumnName="id")
*/
private $outgoingScene;
/**
* @Id
* @ManyToOne(targetEntity="Scene")
* @JoinColumn(name="incomingScene", referencedColumnName="id")
*/
private $incomingScene;
/**
* @Column(type="integer", options={"default":0})
*/
private $directionality = 0;
/**
* @Column(type="string", nullable=True)
*/
private $outgoingConnectionGroupName;
/**
* @Column(type="string", nullable=True)
*/
private $incomingConnectionGroupName;
/**
*
* @param \LotGD\Core\Models\Scene $outgoing
* @param \LotGD\Core\Models\Scene $incoming
* @param int $directionality
*/
public function __construct(
Scene $outgoing,
Scene $incoming,
int $directionality
) {
$this->outgoingScene = $outgoing;
$this->incomingScene = $incoming;
$this->directionality = $directionality;
}
/**
* Sets the connection group name identifier of the outgoing connection.
* @param null|string $name The identifier name of the outgoing connection group.
*/
public function setOutgoingConnectionGroupName(?string $name): void
{
$this->outgoingConnectionGroupName = $name;
}
/**
* Returns the connection from name identifier of the outgoing connection.
* @return null|string
*/
public function getOutgoingConnectionGroupName(): ?string
{
return $this->outgoingConnectionGroupName;
}
/**
* Returns the outgoing Scene of this connection.
* @return Scene
*/
public function getOutgoingScene(): Scene
{
return $this->outgoingScene;
}
/**
* Sets the connection group name identifier of the incoming connection.
* @param null|string $name The identifier name of the incoming connection group.
*/
public function setIncomingConnectionGroupName(?string $name)
{
$this->incomingConnectionGroupName = $name;
}
/**
* Returns the connection group name identifier of the incoming connection.
* @return null|string
*/
public function getIncomingConnectionGroupName(): ?string
{
return $this->incomingConnectionGroupName;
}
/**
* Returns the incoming Scene of this connection.
* @return Scene
*/
public function getIncomingScene(): Scene
{
return $this->incomingScene;
}
/**
* Returns if the directionality of this entity is as given as the first parameter.
* @param int $directionality
* @return bool
*/
public function isDirectionality(int $directionality): bool
{
if ($this->directionality === $directionality) {
return true;
} else {
return false;
}
}
}
+99
View File
@@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Tools\Model\Creator;
use LotGD\Core\Tools\Model\Deletor;
/**
*
* @Entity
* @Table(name="scene_connection_groups")
*/
class SceneConnectionGroup implements SceneConnectable
{
/**
* @Id
* @ManyToOne(targetEntity="Scene", inversedBy="outgoingConnections", cascade={"persist"})
* @JoinColumn(name="scene", referencedColumnName="id")
*/
private $scene;
/**
* @Id
* @Column(type="string")
*/
private $name;
/**
* @Column(type="string", length=255)
*/
private $title;
/**
* SceneConnectionGroup constructor.
* @param string $name Soft-identifier of the connection group, e.g. lotgd/core
* @param string $title
*/
public function __construct(string $name, string $title)
{
$this->name = $name;
$this->title = $title;
}
/**
* Returns the scene associated with this connection group.
* @return \LotGD\Core\Models\Scene
*/
public function getScene(): ?Scene
{
return $this->scene;
}
/**
* Sets the scene associated with this connection group.
* @param \LotGD\Core\Models\Scene $scene
*/
public function setScene(Scene $scene): void
{
$this->scene = $scene;
}
/**
* Returns the name-identifier of this connection group.
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* Returns the title of this connection group.
* @return string
*/
public function getTitle(): string
{
return $this->title;
}
/**
* @inheritDoc
*/
public function connect(SceneConnectable $connectable, int $directionality = null): SceneConnection
{
if ($directionality === null) {
$connection = $this->scene->connect($connectable);
} else {
$connection = $this->scene->connect($connectable, $directionality);
}
$connection->setOutgoingConnectionGroupName($this->name);
return $connection;
}
}
+196
View File
@@ -0,0 +1,196 @@
<?php
declare(strict_types=1);
namespace LotGD\Core;
use LotGD\Core\Exceptions\PermissionIdNotFoundException;
use LotGD\Core\Models\Actor;
use LotGD\Core\Models\PermissionableInterface;
use LotGD\Core\Models\Permission;
/**
* The PermissionManager manages (checks and manipulates) permissions of actors.
*
* The PermissionManager class provides methods to work with permissions and is
* the only way to check and manipulate permissions. It can be used to create or
* delete permissions, to remove, allow or deny permissions to actors and to
* check whether an actor has a certain permission or if it is explicitly
* denied to him.
*
* The wording used in this class is:
* - allowed, the actor has a certain permission in the allowed state.
* - denied, the actor has a certain permission in the denied state.
*
* To make this more clear, the following table summarizes how different methods
* react.
*
* Method
* State: | Unset | Allowed | Denied
* -------------------+-------+---------+---------
* isAllowed | False | True | False
* isDenied | False | False | True
* hasPermissionSet | False | True | True
*/
class PermissionManager
{
const Allowed = 1;
const Denied = -1;
const Superuser = "lotgd/core/superuser";
const AddScenes = "lotgd/core/scene/add";
const EditScenes = "lotgd/core/scene/edit";
const DeleteScenes = "lotgd/core/scene/delete";
const AddCharacters = "lotgd/core/characters/add";
const EditCharacters = "lotgd/core/characters/edit";
const DeleteCharacters = "lotgd/core/characters/delete";
private $game;
/**
* Construct a permission manager.
* @param Game $g The game.
*/
public function __construct(Game $game)
{
$this->game = $game;
}
/**
* Checks if an actor has a permission set. No assumption can be made if it's allowed or denied.
* @param \LotGD\Core\PermissionableInterface $actor
* @param string $permissionId
* @return bool True if the permission has been set, be it allowed or denied.
*/
public function hasPermissionSet(
Actor $actor,
string $permissionId
): bool {
if ($actor->hasPermissionSet($permissionId)) {
return true;
} else {
return false;
}
}
/**
* Checks if an actor is allowed a given permission.
* @param \LotGD\Core\PermissionableInterface $actor
* @param string $permissionId
* @return bool True if the actor has the permission set and it's state is allowed.
*/
public function isAllowed(
Actor $actor,
string $permissionId
): bool {
if ($actor->hasPermissionSet($permissionId)) {
return $actor->getPermission($permissionId)->checkState(static::Allowed);
} else {
return false;
}
}
/**
* Checks if an actor is denied a given permission.
* @param \LotGD\Core\PermissionableInterface $actor
* @param string $permissionId
* @return bool True if the actor has the permission set and it's state is denied.
*/
public function isDenied(
Actor $actor,
string $permissionId
): bool {
if ($actor->hasPermissionSet($permissionId)) {
return $actor->getPermission($permissionId)->checkState(static::Denied);
} else {
return false;
}
}
/**
* Retrieves a permission entity from the database by a permission id.
* @param string $permissionId
* @return Permission
* @throws PermissionIdNotFoundException
*/
private function findPermission(string $permissionId): Permission
{
$em = $this->game->getEntityManager();
$result = $em->getRepository(Permission::class)->find($permissionId);
if ($result) {
return $result;
} else {
throw new PermissionIdNotFoundException("Permission {$permissionId} was not found.");
}
}
/**
* Allows an actor a permission given by the permission id.
* @param PermissionableInterface $actor
* @param string $permissionId
*/
public function allow(
Actor $actor,
string $permissionId
) {
if ($actor->hasPermissionSet($permissionId)) {
if ($this->isAllowed($actor, $permissionId) == false) {
$permission = $actor->getPermission($permissionId);
$permission->setState(static::Allowed);
$name = $actor->getActorName();
$this->game->getLogger()->debug("Granting permission {$permissionId} to {$name} (from denied).");
}
} else {
$permission = $this->findPermission($permissionId);
$actor->addPermission($permission, static::Allowed);
$name = $actor->getActorName();
$this->game->getLogger()->debug("Granting permission {$permissionId} to {$name} (from nothing).");
}
}
/**
* Denies an actor a permission given by the permission id.
* @param PermissionableInterface $actor
* @param string $permissionId
*/
public function deny(
Actor $actor,
string $permissionId
) {
if ($actor->hasPermissionSet($permissionId)) {
if ($this->isDenied($actor, $permissionId) == false) {
$permission = $actor->getPermission($permissionId);
$permission->setState(static::Denied);
$name = $actor->getActorName();
$this->game->getLogger()->debug("Denying permission {$permissionId} from {$name} (from allowed).");
}
} else {
$permission = $this->findPermission($permissionId);
$actor->addPermission($permission, static::Denied);
$name = $actor->getActorName();
$this->game->getLogger()->debug("Denying permission {$permissionId} from {$name} (from nothing).");
}
}
/**
* Removes a permission from an actor.
* @param PermissionableInterface $actor
* @param string $permissionId
*/
public function remove(
Actor $actor,
string $permissionId
) {
if ($actor->hasPermissionSet($permissionId)) {
$permissionAssoc = $actor->getPermission($permissionId);
$actor->removePermission($permissionId);
$name = $actor->getActorName();
$this->game->getLogger()->debug("Removing permission {$permissionId} from {$name}).");
}
}
}
@@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tools\Model;
use LotGD\Core\Models\Actor;
use LotGD\Core\Models\Permission;
use LotGD\Core\Models\PermissionableInterface;
/**
* Tools to work with a permission type field.
*/
trait PermissionAssociationable
{
/**
* @Id @ManyToOne(targetEntity="LotGD\Core\Models\Permission", inversedBy="permission")
* @JoinColumn(name="permission", referencedColumnName="id")
*/
protected $permission;
/** @Column(type="integer") */
protected $permissionState;
public function __construct(Actor $owner, Permission $permission, int $state) {
$this->owner = $owner;
$this->permission = $permission;
$this->permissionState = $state;
}
/**
* Returns the current state of the permission.
* @return int
*/
public function getState(): int
{
return $this->permissionState;
}
/**
* Sets the current state of the permission.
* @param int $state
*/
public function setState(int $state)
{
$this->permissionState = $state;
}
/**
* Checks if this permission is set to a given state.
* @param int $state
* @return bool
*/
public function checkState(int $state): bool
{
return $this->permissionState == $state ? true : false;
}
/**
* Returns the permission id.
* @see Permission->getId()
* @return string
*/
public function getId(): string
{
return $this->permission->getId();
}
/**
* Returns the permission library.
* @see Permission->getLibrary()
* @return string
*/
public function getLibrary(): string
{
return $this->permission->getLibrary();
}
/**
* Returns the Permission entity.
* @return Permission
*/
public function getPermission(): Permission
{
return $this->permission;
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/bash -ex
phpunit
phpunit --stop-on-failure
./vendor/bin/phpdoccheck -d src --no-ansi
+1
View File
@@ -0,0 +1 @@
CMD /C phpunit --stop-on-failure
+46
View File
@@ -40,4 +40,50 @@ class ComposerManagerTest extends \PHPUnit_Framework_TestCase
$namespace = 'LotGD\\NotFound';
$this->assertNull($manager->translateNamespaceToPath($namespace));
}
public function testListPackageWithRootCwd()
{
$manager = new ComposerManager(implode(DIRECTORY_SEPARATOR, [__DIR__, '..']));
$packageCount = count($manager->getPackages());
$this->assertGreaterThan(1, $packageCount);
}
public function testListPackageWithDifferentThanRootCwd()
{
$oldcwd = getcwd();
chdir($oldcwd . DIRECTORY_SEPARATOR . "tests");
$manager = new ComposerManager(implode(DIRECTORY_SEPARATOR, [__DIR__, '..']));
$packageCount = count($manager->getPackages());
$this->assertGreaterThan(1, $packageCount);
chdir($oldcwd);
}
public function testGetPackageByLibraryNameWithRootCwd()
{
$manager = new ComposerManager(implode(DIRECTORY_SEPARATOR, [__DIR__, '..']));
$package = $manager->getPackageForLibrary("composer/composer");
$this->assertSame("composer/composer", $package->getName());
}
public function testGetPackageByLibraryNameWithDifferentThanRootCwd()
{
$oldcwd = getcwd();
chdir($oldcwd . DIRECTORY_SEPARATOR . "tests");
$manager = new ComposerManager(implode(DIRECTORY_SEPARATOR, [__DIR__, '..']));
$package = $manager->getPackageForLibrary("composer/composer");
$this->assertSame("composer/composer", $package->getName());
chdir($oldcwd);
}
}
+1 -1
View File
@@ -100,7 +100,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
list($dsn, $user, $password) = $configuration->getDatabaseConnectionDetails("/home/web/sqlite");
$this->assertNotSame($rawDSN, $dsn);
$this->assertSame("sqlite:/home/web/sqlite/db.db3", $dsn);
$this->assertSame("sqlite:/home/web/sqlite" . DIRECTORY_SEPARATOR . "db.db3", $dsn);
}
public function testIfInvalidConfigurationExceptionIsThrownIfDatabaseDSNIsMissing()
+59
View File
@@ -190,4 +190,63 @@ class GameTest extends CoreModelTestCase
$v = $this->g->getViewpoint();
$this->assertSame($s->getTemplate(), $v->getTemplate());
}
public function testIfActionsAreAddedAsExpected()
{
$viewpointToArray = function(Viewpoint $v) {
$returnTree = [];
foreach ($v->getActionGroups() as $actionGroup) {
$returnTree[$actionGroup->getId()] = [];
foreach ($actionGroup->getActions() as $action) {
$returnTree[$actionGroup->getId()][] = $action->getDestinationSceneId();
}
}
return [$v->getTitle(), $returnTree];
};
$sortedValues = function(array $array) {
$values = array_values($array);
sort($values);
return $values;
};
$c = $this->getEntityManager()->getRepository(Character::class)->find(3);
$this->g->setCharacter($c);
$v0 = $this->g->getViewpoint();
$this->g->takeAction($v0->getActionGroups()[0]->getActions()[2]->getId());
$v1 = $this->g->getViewpoint();
$this->assertSame([
"Parent Scene",
[
ActionGroup::DefaultGroup => [1],
"lotgd/tests/none/child1" => [5],
"lotgd/tests/none/child2" => [6],
ActionGroup::HiddenGroup => [],
]
], $viewpointToArray($v1));
$this->g->takeAction($v1->getActionGroups()[1]->getActions()[0]->getId());
$v2 = $this->g->getviewpoint();
$this->assertSame([
"Child Scene 1",
[
ActionGroup::DefaultGroup => [6, 4],
ActionGroup::HiddenGroup => [],
]
], $viewpointToArray($v2));
$this->g->takeAction($v1->getActionGroups()[0]->getActions()[0]->getId());
$v3 = $this->g->getviewpoint();
$this->assertSame([
"Child Scene 2",
[
ActionGroup::DefaultGroup => [4],
ActionGroup::HiddenGroup => [],
]
], $viewpointToArray($v3));
}
}
+290
View File
@@ -0,0 +1,290 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tests\Managers;
use Doctrine\ORM\EntityManagerInterface;
use LotGD\Core\Game;
use LotGD\Core\PermissionManager;
use LotGD\Core\Exceptions\PermissionAlreadyExistsException;
use LotGD\Core\Exceptions\PermissionDoesNotExistException;
use LotGD\Core\Exceptions\PermissionIdNotFoundException;
use LotGD\Core\Models\Permission;
use LotGD\Core\Models\PermissionableInterface;
use LotGD\Core\Models\PermissionAssociationInterface;
use LotGD\Core\Tools\Model\Permissionable;
use LotGD\Core\Tests\CoreModelTestCase;
use LotGD\Core\Tests\Ressources\TestModels\User;
use LotGD\Core\Tests\Ressources\TestModels\UserPermissionAssociation;
/**
* Description of PermissionManagerTest
*/
class PermissionManagerTest extends CoreModelTestCase
{
protected $dataset = "permission-manager";
public function getPermissionManager(EntityManagerInterface $em): PermissionManager
{
$this->game = $this->getMockBuilder(Game::class)
->disableOriginalConstructor()
->getMock();
$this->game->method('getEntityManager')->willReturn($em);
return new PermissionManager($this->game);
}
public function testUserHasPermission()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($user->hasPermissionSet("test/permission_one"));
$this->assertTrue($user->hasPermissionSet("test/permission_two"));
}
public function testUserReturnsPermission()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permission = $user->getRawPermission("test/permission_one");
$this->assertInstanceOf(Permission::class, $permission);
}
public function testUserReturnsPermissionAssociation()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permission = $user->getPermission("test/permission_one");
$this->assertInstanceOf(UserPermissionAssociation::class, $permission);
}
public function testIfAddingAnAlreadySetPermissionToAnUserResultsInException()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permission = $em->getRepository(Permission::class)->find("test/permission_two");
$this->expectException(PermissionAlreadyExistsException::class);
$user->addPermission($permission, PermissionManager::Denied);
}
public function testIfRemovingANotSetPermissionFromAnUserResultsInException()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permission = $em->getRepository(Permission::class)->find("test/permission_tri");
$this->expectException(PermissionDoesNotExistException::class);
$user->removePermission("test/permission_tri");
}
public function testIfHasPermissionSetWorksAsExpected()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->hasPermissionSet($user, "test/permission_one"));
$this->assertTrue($permissionManager->hasPermissionSet($user, "test/permission_two"));
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_none"));
}
public function testIfIsAllowedSetWorksAsExpected()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_one"));
$this->assertFalse($permissionManager->isAllowed($user, "test/permission_two"));
$this->assertFalse($permissionManager->isAllowed($user, "test/permission_tri"));
$this->assertFalse($permissionManager->isAllowed($user, "test/permission_none"));
}
public function testIfIsDeniedSetWorksAsExpected()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertFalse($permissionManager->isDenied($user, "test/permission_one"));
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
$this->assertFalse($permissionManager->isDenied($user, "test/permission_tri"));
$this->assertFalse($permissionManager->isDenied($user, "test/permission_none"));
}
public function testIfAllowingAnAllowedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$permissionManager->allow($user, "test/permission_one");
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_one"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_one"));
}
public function testIfAllowingAnDeniedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
$permissionManager->allow($user, "test/permission_two");
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_two"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_two"));
}
public function testIfAllowingANonExistingPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$permissionManager->allow($user, "test/permission_tri");
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_tri"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_tri"));
}
public function testIfDenyingAnAllowedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_one"));
$permissionManager->deny($user, "test/permission_one");
$this->assertTrue($permissionManager->isDenied($user, "test/permission_one"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_one"));
}
public function testIfDenyingAnDeniedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
$permissionManager->deny($user, "test/permission_two");
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
}
public function testIfDenyingANonExistingPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$permissionManager->deny($user, "test/permission_tri");
$this->assertTrue($permissionManager->isDenied($user, "test/permission_tri"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_tri"));
}
public function testIfRemovingAnAllowedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_one"));
$permissionManager->remove($user, "test/permission_one");
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_one"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_one"));
}
public function testIfRemovingADeniedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
$permissionManager->remove($user, "test/permission_two");
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_two"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_two"));
}
public function testIfRemovingANonExistingPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$permissionManager->remove($user, "test/permission_tri");
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
}
public function testIfRequestingANonExistingPermissionThrowsAnException()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->expectException(PermissionIdNotFoundException::class);
$permissionManager->allow($user, "test/non_existing_permission");
}
public function testSomething()
{
$this->assertTrue(True);
}
}
+7
View File
@@ -47,6 +47,7 @@ abstract class ModelTestCase extends \PHPUnit_Extensions_Database_TestCase
$libraryConfigurationManager = new LibraryConfigurationManager($composerManager, getcwd());
$directories = $libraryConfigurationManager->getEntityDirectories();
$directories[] = implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'src', 'Models']);
$directories[] = implode(DIRECTORY_SEPARATOR, [__DIR__, 'Resources', 'TestModels']);
// Read db annotations from model files
$configuration = Setup::createAnnotationMetadataConfiguration($directories, true);
@@ -81,4 +82,10 @@ abstract class ModelTestCase extends \PHPUnit_Extensions_Database_TestCase
// Clear out the cache so tests don't get confused.
$this->getEntityManager()->clear();
}
protected function flushAndClear()
{
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
}
}
+1 -2
View File
@@ -52,7 +52,6 @@ class MotDModelTest extends CoreModelTestCase
$time4->setTimezone(new \DateTimeZone("America/Los_Angeles"));
$this->assertSame($time1->getTimestamp(), $time2->getTimestamp());
$this->assertEquals($time1, $time2);
$this->assertSame($time2, $time3);
$this->assertEquals($time2->getTimezone(), $time3->getTimezone());
$this->assertNotEquals($time1->getTimezone(), $time2->getTimezone());
@@ -100,7 +99,7 @@ class MotDModelTest extends CoreModelTestCase
$this->assertSame($motdCreationArguments["author"]->getName(), $checkMotd->getAuthor()->getName());
$this->assertSame($motdCreationArguments["title"], $checkMotd->getTitle());
$this->assertSame($motdCreationArguments["body"], $checkMotd->getBody());
$this->assertEquals($motd->getCreationTime(), $checkMotd->getCreationTime());
$this->assertEquals($motd->getCreationTime()->format("Ymd-His"), $checkMotd->getCreationTime()->format("Ymd-His"));
if ($motdCreationArguments["systemMessage"] === true) {
$this->assertNotSame($motdCreationArguments["author"]->getName(), $checkMotd->getApparantAuthor()->getName());
+60
View File
@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tests\Models;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Models\Permission;
use LotGD\Core\Tests\CoreModelTestCase;
/**
* Tests the Permission model.
*/
class PermissionModelTest extends CoreModelTestCase
{
/** @var string default data set */
protected $dataset = "permission";
public function testIfPermissionsCanBeFetched()
{
$em = $this->getEntityManager();
$permission = $em->getRepository(Permission::class)->find("lotgd/core/superuser");
$this->assertInstanceOf(Permission::class, $permission);
$this->assertEquals("lotgd/core/superuser", $permission->getId());
$this->assertEquals("lotgd/core", $permission->getLibrary());
$this->assertEquals("Superuser. Superseeds all flags.", $permission->getName());
}
public function testIfPermissionsCanBeCreated()
{
$permission = Permission::create([
"id" => "test/core/testpermission",
"library" => "test/core",
"name"=> "A permission for testing."
]);
$this->assertInstanceOf(Permission::class, $permission);
$em = $this->getEntityManager();
$permission->save($em);
$em->clear();
$permission = $em->getRepository(Permission::class)->find("test/core/testpermission");
$this->assertInstanceOf(Permission::class, $permission);
$this->assertEquals("test/core/testpermission", $permission->getId());
$this->assertEquals("test/core", $permission->getLibrary());
$this->assertEquals("A permission for testing.", $permission->getName());
}
public function testIfIdCannotBeChanged()
{
$em = $this->getEntityManager();
$permission = $em->getRepository(Permission::class)->find("lotgd/core/superuser");
$this->expectException(ArgumentException::class);
$permission->setId("another id.");
}
}
+312 -48
View File
@@ -5,7 +5,8 @@ namespace LotGD\Core\Tests\Models;
use Doctrine\Common\Collections\ArrayCollection;
use LotGD\Core\Models\Scene;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Models\{Scene, SceneConnection, SceneConnectionGroup};
use LotGD\Core\Tests\CoreModelTestCase;
/**
@@ -16,9 +17,125 @@ class SceneModelTest extends CoreModelTestCase
/** @var string default data set */
protected $dataset = "scene";
public function testCreate()
protected function getNumberOfScenes(): int
{
$scene = new Scene();
$results = $this->getEntityManager()->getRepository(Scene::class)->findAll();
return count($results);
}
protected function getNumberOfSceneConnections(): int
{
$results = $this->getEntityManager()->getRepository(SceneConnection::class)->findAll();
return count($results);
}
protected function getNumberOfSceneGroups(): int
{
$results = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findAll();
return count($results);
}
protected function getTestSceneData(): array
{
return [
"title" => "A new scene",
"description" => "This is a new scene",
"template" => "lotgd/test/new-scene"
];
}
public function testIfSceneCanGetCreatedAndDeleted()
{
$em = $this->getEntityManager();
// Count number of scenes
$n1 = $this->getNumberOfScenes();
$this->assertGreaterThan(0, $n1);
// create new scene, flush and clear. Number of scenes in db should be +1
$newScene = Scene::create($this->getTestSceneData());
$newScene->save($em);
$this->flushAndClear();
unset($newScene);
// recount and assert that n1 + 1 === n2
$n2 = $this->getNumberOfScenes();
$this->assertSame($n1 + 1, $n2);
// fetch new scene, delete, flush and clear.
$newScene = $em->getRepository(Scene::class)->findOneBy($this->getTestSceneData());
$newScene->delete($em);
$this->flushAndClear();
// recount and assert that n3 == n1
$n3 = $this->getNumberOfScenes();
$this->assertSame($n1, $n3);
}
public function testIfSceneWithConnectionsCanGetCreatedAndDeleted()
{
$em = $this->getEntityManager();
// Count number of scenes
$n1 = $this->getNumberOfScenes();
$this->assertGreaterThan(0, $n1);
// Count number of connections
$c1 = $this->getNumberOfSceneConnections();
$this->assertGreaterTHan(0, $c1);
// create new scene, connect to another one. Number of scenes must be +1, number of connections must be +1
// this tests for cascade=persist
$scene = Scene::create($this->getTestSceneData());
$scene->connect($em->getRepository(Scene::class)->find(1));
$scene->save($em);
$this->flushAndClear();
unset($scene);
// recount and assert that this is the case
$this->assertSame($n1 + 1, $this->getNumberOfScenes());
$this->assertSame($c1 + 1, $this->getNumberOfSceneConnections());
// delete scene again. Number of scenes and number of connections must be what it was at the beginning
// this tests for cascade=remove
$scene = $em->getRepository(Scene::class)->findOneBy($this->getTestSceneData());
$scene->delete($em);
$this->flushAndClear();
unset($scene);
// recount and assert that this is the case
$this->assertSame($n1, $this->getNumberOfScenes());
$this->assertSame($c1, $this->getNumberOfSceneConnections());
}
public function testIfSceneWithConnectionGroupsCanGetCreatedAndDeleted()
{
$em = $this->getEntityManager();
// count number of scenes
$n1 = $this->getNumberOfScenes();
$g1 = $this->getNumberOfSceneGroups();
// create new scene, add scene group. Number of scenes must be +1, number of scene connection groups must be +1
// this tests for cascade=persist
$scene = Scene::create($this->getTestSceneData());
$scene->addConnectionGroup(new SceneConnectionGroup("test", "test"));
$scene->save($em);
$this->flushAndClear();
// recount and assert that this is the case
$this->assertSame($n1 + 1, $this->getNumberOfScenes());
$this->assertSame($g1 + 1, $this->getNumberOfSceneGroups());
// delete scene again. Number of scenes and number of connection groups must be what it was at the beginning
$scene = $em->getRepository(Scene::class)->findOneBy($this->getTestSceneData());
$scene->delete($em);
$this->flushAndClear();
unset($scene);
// recount and assert that this is the case
$this->assertSame($n1, $this->getNumberOfScenes());
$this->assertSame($g1, $this->getNumberOfSceneGroups());
}
/**
@@ -31,68 +148,215 @@ class SceneModelTest extends CoreModelTestCase
$this->assertEquals("The Forest", $scene->getTitle());
$this->assertEquals("This is a very dangerous and dark forest", $scene->getDescription());
$this->assertInstanceOf(Scene::class, $scene->getParents()[0]);
$this->assertCount(1, $scene->getParents());
$this->assertCount(0, $scene->getChildren());
$em->flush();
}
/**
* Test if parent<=>child relationship is working.
*/
public function testChildParentRelationships()
public function testIfHasConnectionGroupReturnsTrueIfConnectionGroupExists()
{
$em = $this->getEntityManager();
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$parentScene = $em->getRepository(Scene::class)->find(1);
$childScene = $em->getRepository(Scene::class)->find(2);
$this->assertContains($parentScene, $childScene->getParents());
$this->assertContains($childScene, $parentScene->getChildren());
$em->flush();
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/outside"));
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/market"));
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/empty"));
}
/**
* Test if the scene can be removed.
*/
public function testMoveScene()
public function testIfHasConnectionGroupReturnsFalseIfConnectionGroupDoesNotExist()
{
$em = $this->getEntityManager();
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$parentScene1 = $em->getRepository(Scene::class)->find(1);
$parentScene2 = $em->getRepository(Scene::class)->find(4);
$this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/outside"));
$this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/market"));
$this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/empty"));
$orphanScene = $em->getRepository(scene::class)->find(5);
$this->assertCount(0, $orphanScene->getParents());
$this->assertCount(0, $orphanScene->getChildren());
// Assign orphanScene to parentScene1 and check relationships
$orphanScene->addParent($parentScene1);
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$this->assertCount(1, $orphanScene->getParents());
$this->assertCount(3, $parentScene1->getChildren());
$this->assertContains($parentScene1, $orphanScene->getParents());
$this->assertContains($orphanScene, $parentScene1->getChildren());
$this->assertFalse($scene1->hasConnectionGroup("lotgd/tests/village/23426"));
}
// Add the scene now to parentScene2 and check relationships
$orphanScene->addParent($parentScene2);
public function testIfAddConnectionGroupWorks()
{
$connectionGroup = new SceneConnectionGroup("lotgd/tests/village/new", "New Street");
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$this->assertCount(3, $parentScene1->getChildren());
$this->assertCount(1, $parentScene2->getChildren());
$this->assertContains($parentScene2, $orphanScene->getParents());
$this->assertContains($orphanScene, $parentScene2->getChildren());
$this->assertFalse($scene->hasConnectionGroup("lotgd/tests/village/new"));
// Make an orphan out of it again
$orphanScene->setParents(new ArrayCollection());
$scene->addConnectionGroup($connectionGroup);
$this->assertCount(2, $parentScene1->getChildren());
$this->assertCount(0, $parentScene2->getChildren());
$this->assertCount(0, $orphanScene->getParents());
$this->assertNotContains($orphanScene, $parentScene1->getChildren());
$this->assertNotContains($orphanScene, $parentScene2->getChildren());
$this->getEntityManager()->flush();
$em->flush();
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/new"));
}
public function testIfAddConnectionGroupThrowsArgumentExceptionIfGroupIsAlreadyAssignedToItself()
{
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]);
$this->expectException(ArgumentException::class);
$scene->addConnectionGroup($connectionGroup);
}
public function testIfAddConnectionGroupThrowsArgumentExceptionIfGroupIsAlreadyAssignedToSomwhereElse()
{
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]);
$this->expectException(ArgumentException::class);
$scene->addConnectionGroup($connectionGroup);
}
public function testifDropConnectionGroupWorks()
{
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]);
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/outside"));
$scene->dropConnectionGroup($connectionGroup);
$this->getEntityManager()->flush();
$this->assertFalse($scene->hasConnectionGroup("lotgd/tests/village/outside"));
}
public function testIfDropConnectionGroupThrowsArgumentExceptionIfEntityIsRemovedFromNonOwningScene()
{
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]);
$this->expectException(ArgumentException::class);
$scene->dropConnectionGroup($connectionGroup);
}
public function testIfGetConnectedScenesReturnsConnectedScenes()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$this->assertCount(3, $scene1->getConnectedScenes());
$this->assertCount(1, $scene2->getConnectedScenes());
$this->assertTrue($scene1->getConnectedScenes()->contains($scene2));
$this->assertTrue($scene2->getConnectedScenes()->contains($scene1));
$this->assertFalse($scene1->getConnectedScenes()->contains($scene1));
$this->assertFalse($scene2->getConnectedScenes()->contains($scene2));
}
public function testIfIsConnectedToReturnsExpectedReturnValue()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$scene5 = $this->getEntityManager()->getRepository(Scene::class)->find(5);
$this->assertTrue($scene1->isConnectedTo($scene2));
$this->assertTrue($scene2->isConnectedTo($scene1));
$this->assertFalse($scene1->isConnectedTo($scene5));
$this->assertFalse($scene2->isConnectedTo($scene5));
$this->assertFalse($scene5->isConnectedTo($scene1));
$this->assertFalse($scene5->isConnectedTo($scene2));
}
public function testIfTwoScenesCanGetConnected()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5);
$scene1->connect($scene2);
$this->assertTrue($scene1->getConnectedScenes()->contains($scene2));
$this->assertTrue($scene2->getConnectedScenes()->contains($scene1));
$this->assertFalse($scene1->getConnectedScenes()->contains($scene1));
$this->assertFalse($scene2->getConnectedScenes()->contains($scene2));
$this->getEntityManager()->flush();
}
public function testIfASceneConnectionGroupCanGetConnectedToAScene()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5);
$scene1->getConnectionGroup("lotgd/tests/village/outside")->connect($scene2);
$this->assertTrue($scene1->isConnectedTo($scene2));
$this->assertTrue($scene2->isConnectedTo($scene1));
$this->assertFalse($scene1->isConnectedTo($scene1));
$this->assertFalse($scene2->isConnectedTo($scene2));
$this->getEntityManager()->flush();
}
public function testIfASceneCanGetConnectedToASceneConnectionGroup()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5);
$scene2->connect($scene1->getConnectionGroup("lotgd/tests/village/outside"));
$this->assertTrue($scene1->isConnectedTo($scene2));
$this->assertTrue($scene2->isConnectedTo($scene1));
$this->assertFalse($scene1->isConnectedTo($scene1));
$this->assertFalse($scene2->isConnectedTo($scene2));
$this->getEntityManager()->flush();
}
public function testIfASceneConnectionGroupCanGetConnectedToAnotherSceneConnectionGroup()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5);
$scene2->addConnectionGroup(new SceneConnectionGroup("test/orphaned", "Orphan group"));
$scene1
->getConnectionGroup("lotgd/tests/village/outside")
->connect(
$scene2->getConnectionGroup("test/orphaned")
);
$this->assertTrue($scene1->isConnectedTo($scene2));
$this->assertTrue($scene2->isConnectedTo($scene1));
$this->assertFalse($scene1->isConnectedTo($scene1));
$this->assertFalse($scene2->isConnectedTo($scene2));
$this->getEntityManager()->flush();
}
public function testIfConnectingASceneToItselfThrowsAnException()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$this->expectException(ArgumentException::class);
$scene1->connect($scene1);
$this->expectException(ArgumentException::class);
$scene1->connect($scene1->getConnectionGroup("lotgd/tests/village/outside"));
$this->expectException(ArgumentException::class);
$scene1->getConnectionGroup("lotgd/tests/village/outside")->connect($scene1);
$this->expectException(ArgumentException::class);
$scene1->getConnectionGroup("lotgd/tests/village/outside")->connect($scene1->getConnectionGroup("lotgd/tests/village/outside"));
$this->assertFalse($scene1->isConnectedTo($scene1));
}
public function testIfConnectingASceneToAnotherAlreadyConnectedSceneThrowsAnException()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$this->expectException(ArgumentException::class);
$scene1->connect($scene2);
$this->expectException(ArgumentException::class);
$scene1->getConnectionGroup("lotgd/tests/village/hidden")->connect($scene2);
$this->expectException(ArgumentException::class);
$scene1->connect($scene2->getConnectionGroup("lotgd/tests/forest/category"));
$this->expectException(ArgumentException::class);
$scene1->getConnectionGroup("lotgd/tests/village/hidden")->connect($scene2->getConnectionGroup("lotgd/tests/forest/category"));
}
}
+64
View File
@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tests\Ressources\TestModels;
use Generator;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Lotgd\Core\Models\Actor;
/**
* @Entity
* @Table("TestUsers")
*/
class User extends Actor #implements PermissionableInterface {
{
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @Column(type="string", length=50); */
private $name;
/** @OneToMany(targetEntity="UserPermissionAssociation", mappedBy="owner", cascade={"persist", "remove"}, orphanRemoval=true) */
protected $permissions;
public function __construct()
{
$this->permissions = new ArrayCollection();
}
public function getId(): int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name)
{
$this->name = $name;
}
public function getActorName(): string
{
return "User #".$this->id." (".$this->name.")";
}
protected function getPermissionAssociationClass(): string
{
return UserPermissionAssociation::class;
}
protected function getPermissionAssociations(): Generator
{
foreach ($this->permissions as $permission) {
yield $permission;
}
}
}
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tests\Ressources\TestModels;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Models\PermissionAssociationInterface;
use LotGD\Core\Tools\Model\PermissionAssociationable;
/**
* @Entity
* @Table("TestUserAssociations")
*/
class UserPermissionAssociation implements PermissionAssociationInterface {
use PermissionAssociationable;
/**
* @Id @ManyToOne(targetEntity="User", inversedBy="permissions")
* @JoinColumn(name="owner", referencedColumnName="id")
*/
private $owner;
}
+50 -5
View File
@@ -36,10 +36,55 @@ scenes:
title: "The Weaponry"
description: "This is the place where you can buy awesome weapons"
template: "lotgd/tests/weaponry"
paths:
-
scene_id: 1
child_scene_id: 2
id: 4
title: "Parent Scene"
description: "This is a parent scene that connects to two children."
template: "lotgd/tests/none"
-
scene_id: 1
child_scene_id: 3
id: 5
title: "Child Scene 1"
description: "This is a parent scene that connects to two children."
template: "lotgd/tests/none"
-
id: 6
title: "Child Scene 2"
description: "This is a parent scene that connects to two children."
template: "lotgd/tests/none"
scene_connection_groups:
-
scene: 4
name: "lotgd/tests/none/child1"
title: "Child 1"
-
scene: 4
name: "lotgd/tests/none/child2"
title: "Child 2"
scene_connections:
-
outgoingScene: 1
incomingScene: 2
directionality: 0
-
outgoingScene: 1
incomingScene: 3
directionality: 0
-
outgoingScene: 1
incomingScene: 4
directionality: 0
-
outgoingScene: 4
incomingScene: 5
outgoingConnectionGroupName: "lotgd/tests/none/child1"
directionality: 0
-
outgoingScene: 4
incomingScene: 6
outgoingConnectionGroupName: "lotgd/tests/none/child2"
directionality: 0
-
outgoingScene: 5
incomingScene: 6
directionality: 1
+28
View File
@@ -0,0 +1,28 @@
## YAML Template.
testUsers:
-
id: 1
name: "Test User 1"
testUserAssociations:
-
owner: 1
permission: "test/permission_one"
permissionState: 1
-
owner: 1
permission: "test/permission_two"
permissionState: -1
permissions:
-
id: "test/permission_one"
library: "lotgd/core"
name: "Test permission."
-
id: "test/permission_two"
library: "lotgd/core"
name: "Test permission."
-
id: "test/permission_tri"
library: "lotgd/core"
name: "Test permission."
+6
View File
@@ -0,0 +1,6 @@
## YAML Template.
permissions:
-
id: "lotgd/core/superuser"
library: "lotgd/core"
name: "Superuser. Superseeds all flags."
+25 -5
View File
@@ -24,10 +24,30 @@ scenes:
title: "Orphan"
description: "This is an orphan scene"
template: "lotgd/tests/orphan"
paths:
scene_connection_groups:
-
scene_id: 1
child_scene_id: 2
scene: 1
name: "lotgd/tests/village/outside"
title: "Outside"
-
scene_id: 1
child_scene_id: 3
scene: 1
name: "lotgd/tests/village/market"
title: "Market"
-
scene: 1
name: "lotgd/tests/village/empty"
title: "Empty"
-
scene: 2
name: "lotgd/tests/forest/category"
title: "Empty"
scene_connections:
-
outgoingScene: 1
incomingScene: 2
-
outgoingScene: 1
incomingScene: 3
-
outgoingScene: 1
incomingScene: 4
+5 -5
View File
@@ -32,10 +32,10 @@ scenes:
title: "The Weaponry"
description: "This is the place where you can buy awesome weapons"
template: "lotgd/tests/weaponry"
paths:
scene_connections:
-
scene_id: 1
child_scene_id: 2
outgoingScene: 1
incomingScene: 2
-
scene_id: 1
child_scene_id: 3
outgoingScene: 1
incomingScene: 3