From 053fc74a7e2e9d2128c8c4d28cbdc148f1bc4c1c Mon Sep 17 00:00:00 2001 From: Groups Date: Tue, 16 Jan 2018 19:57:11 -0800 Subject: [PATCH] passing tests --- src/Pho/Kernel/Foundation/AbstractActor.php | 1 + src/Pho/Kernel/Foundation/AbstractGraph.php | 1 + src/Pho/Kernel/Foundation/AbstractObject.php | 1 + src/Pho/Kernel/Foundation/Handlers/Set.php | 58 +++++++++++++++ src/Pho/Kernel/Foundation/ParticleTrait.php | 8 ++ .../Kernel/Services/Index/IndexInterface.php | 15 ++++ src/Pho/Kernel/defaults.php | 3 +- tests/Pho/Kernel/CustomFounderTestCase.php | 1 + tests/Pho/Kernel/TestCase.php | 1 + tests/Pho/Kernel/UniqueFieldsTest.php | 74 +++++++++++++++++++ tests/assets/compiled/User.php | 13 ++-- .../compiled/UserWithUniqueFeatures.php | 53 +++++++++++++ 12 files changed, 223 insertions(+), 6 deletions(-) create mode 100644 src/Pho/Kernel/Foundation/Handlers/Set.php create mode 100644 tests/Pho/Kernel/UniqueFieldsTest.php create mode 100644 tests/assets/compiled/UserWithUniqueFeatures.php diff --git a/src/Pho/Kernel/Foundation/AbstractActor.php b/src/Pho/Kernel/Foundation/AbstractActor.php index 97cc440..1b32bc7 100644 --- a/src/Pho/Kernel/Foundation/AbstractActor.php +++ b/src/Pho/Kernel/Foundation/AbstractActor.php @@ -29,6 +29,7 @@ abstract class AbstractActor extends Framework\Actor implements ParticleInterfac public function __construct(Kernel $kernel, Framework\ContextInterface $graph) { parent::__construct($graph); + $this->registerSetHandler(); $this->registerHandler( "form", \Pho\Kernel\Foundation\Handlers\Form::class diff --git a/src/Pho/Kernel/Foundation/AbstractGraph.php b/src/Pho/Kernel/Foundation/AbstractGraph.php index ba66138..3ff0d6f 100644 --- a/src/Pho/Kernel/Foundation/AbstractGraph.php +++ b/src/Pho/Kernel/Foundation/AbstractGraph.php @@ -13,6 +13,7 @@ abstract class AbstractGraph extends Framework\Graph implements ParticleInterfac public function __construct(Kernel $kernel, AbstractActor $actor, Framework\ContextInterface $graph) { parent::__construct($actor, $graph); + $this->registerSetHandler(); $this->hydrate($kernel, $graph); $this->kernel->space()->emit("particle.added", [$this]); } diff --git a/src/Pho/Kernel/Foundation/AbstractObject.php b/src/Pho/Kernel/Foundation/AbstractObject.php index ad6b2a8..9892db4 100644 --- a/src/Pho/Kernel/Foundation/AbstractObject.php +++ b/src/Pho/Kernel/Foundation/AbstractObject.php @@ -13,6 +13,7 @@ abstract class AbstractObject extends Framework\Object implements ParticleInterf public function __construct(Kernel $kernel, AbstractActor $actor, Framework\ContextInterface $graph) { parent::__construct($actor, $graph); + $this->registerSetHandler(); $this->hydrate($kernel, $graph); $this->kernel->space()->emit("particle.added", [$this]); diff --git a/src/Pho/Kernel/Foundation/Handlers/Set.php b/src/Pho/Kernel/Foundation/Handlers/Set.php new file mode 100644 index 0000000..e776ae1 --- /dev/null +++ b/src/Pho/Kernel/Foundation/Handlers/Set.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Pho\Kernel\Foundation\Handlers; + +use Pho\Framework\ParticleInterface; +use Pho\Framework\FieldHelper; + +/** + * Kernel adapter of the Set Handler class. + * + * + * @author Emre Sokullu + */ +class Set extends \Pho\Framework\Handlers\Set { + + /** + * {@inheritDoc} + * + * @todo Find a better way of accessing kernel than calling $GLOBALS + */ + protected static function saveField( + ParticleInterface $particle, + string $field_name, + /*mixed*/ $field_value, + bool $defer_persist, + FieldHelper $helper): void + { + $kernel = $GLOBALS["kernel"]; + if($helper->isUnique()) { + // check if it is unique via index + //eval(\Psy\sh()); + if($kernel->live() && !$kernel->index()->checkNodeUniqueness($field_name, $field_value, $particle->label())) { + throw new \InvalidArgumentException("Given field is not unique"); + } + } + elseif($helper->withIndex()) { + // check if there is an index + } + parent::saveField($particle, $field_name, $field_value, $defer_persist, $helper); + + /*if(!$defer_persist) { + $particle->attributes()->$field_name = $field_value; + return; + } + $particle->attributes()->quietSet($field_name, $field_value); + */ + } + +} diff --git a/src/Pho/Kernel/Foundation/ParticleTrait.php b/src/Pho/Kernel/Foundation/ParticleTrait.php index e16e81b..d5d9ad5 100644 --- a/src/Pho/Kernel/Foundation/ParticleTrait.php +++ b/src/Pho/Kernel/Foundation/ParticleTrait.php @@ -23,6 +23,14 @@ trait ParticleTrait protected $deferred_persistence = false; protected $rewired = false; + protected function registerSetHandler(): void + { + $this->registerHandler( + "set", + \Pho\Kernel\Foundation\Handlers\Set::class + ); + } + protected function hydrate( Kernel $kernel, Framework\ContextInterface $graph): void diff --git a/src/Pho/Kernel/Services/Index/IndexInterface.php b/src/Pho/Kernel/Services/Index/IndexInterface.php index 5c67d2b..a61333b 100644 --- a/src/Pho/Kernel/Services/Index/IndexInterface.php +++ b/src/Pho/Kernel/Services/Index/IndexInterface.php @@ -89,4 +89,19 @@ public function edgeDeleted(string $id): void; */ public function flush(): void; + /** + * Checks whether the given node exists in the database or not. + * + * @param string $field_name Field Name + * @param mixed $field_value Field Value + * @param string $label The label of the node in question + * + * @return bool + */ + public function checkNodeUniqueness( + string $field_name, + /*mixed*/ $field_value, + string $label = "" + ): bool; + } diff --git a/src/Pho/Kernel/defaults.php b/src/Pho/Kernel/defaults.php index 45bca57..493828d 100644 --- a/src/Pho/Kernel/defaults.php +++ b/src/Pho/Kernel/defaults.php @@ -24,7 +24,8 @@ "database" => ["type"=>"apcu", "uri"=> "" ], "logger" => ["type"=>"stdout", "uri"=> "" ], "storage" => ["type"=>"filesystem", "uri"=> "" ], - "events" => ["type"=>"local", "uri"=> "" ] + "events" => ["type"=>"local", "uri"=> "" ], + "index" => ["type"=>"neo4j", "uri"=> ""] ), "tmp_path" => sys_get_temp_dir(), // Temporary folder to store files. For example uploaded files may go there. "root_path" => __DIR__, diff --git a/tests/Pho/Kernel/CustomFounderTestCase.php b/tests/Pho/Kernel/CustomFounderTestCase.php index 7ddd455..8959b2a 100644 --- a/tests/Pho/Kernel/CustomFounderTestCase.php +++ b/tests/Pho/Kernel/CustomFounderTestCase.php @@ -31,5 +31,6 @@ protected function startKernel($founder=null): void $founder = new \PhoNetworksAutogenerated\User($this->kernel, $this->kernel->space(), "123456"); $this->kernel->boot($founder); $this->graph = $this->kernel->graph(); + //eval(\Psy\sh()); } } diff --git a/tests/Pho/Kernel/TestCase.php b/tests/Pho/Kernel/TestCase.php index 1c306db..ab7596c 100644 --- a/tests/Pho/Kernel/TestCase.php +++ b/tests/Pho/Kernel/TestCase.php @@ -14,6 +14,7 @@ include("tests/assets/compiled/Graph.php"); include("tests/assets/compiled/User.php"); + include("tests/assets/compiled/UserWithUniqueFeatures.php"); include("tests/assets/compiled/Status.php"); include("tests/assets/compiled/StatusOut/Mention.php"); include("tests/assets/compiled/UserOut/Follow.php"); diff --git a/tests/Pho/Kernel/UniqueFieldsTest.php b/tests/Pho/Kernel/UniqueFieldsTest.php new file mode 100644 index 0000000..99f1d7d --- /dev/null +++ b/tests/Pho/Kernel/UniqueFieldsTest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Pho\Kernel; + +class UniqueFieldsTest extends TestCase +{ + + protected function getKernelConfig() + { + $configs = parent::getKernelConfig(); + $configs["default_objects"] = [ + "graph" => \PhoNetworksAutogenerated\Graph::class, + "founder" => \PhoNetworksAutogenerated\UserWithUniqueFeatures::class, + ]; + return $configs; + } + + protected function startKernel($founder=null): void + { + $this->configs = $this->getKernelConfig(); + $this->kernel = new Kernel($this->configs); + $founder = new \PhoNetworksAutogenerated\UserWithUniqueFeatures($this->kernel, $this->kernel->space(), "esokullu", "123456"); + $this->kernel->boot($founder); + + } + + + public function testSucceed() { + $this->flushDBandRestart(); + $u = new \PhoNetworksAutogenerated\UserWithUniqueFeatures($this->kernel, $this->kernel->graph(), "another_username", "123456"); + $this->created[] = $u->id(); + $this->kernel->founder()->setBirthday("12/21/1983"); + $u->setBirthday("12/21/1983"); + $this->assertEquals($this->kernel->founder()->getBirthday(), $u->getBirthday()); + //eval(\Psy\sh()); + $this->assertTrue(true); // if it has come to this point with no exception, we're good + } + + public function testFailDueToDuplicate() { + $this->flushDBandRestart(); + $this->expectException(\InvalidArgumentException::class); + $u = new \PhoNetworksAutogenerated\UserWithUniqueFeatures($this->kernel, $this->kernel->graph(), "esokullu", "123456"); + $this->created[] = $u->id(); + } + + public function testAnotherFieldWithSameValueSucceed() { + $this->flushDBandRestart(); + $u = new \PhoNetworksAutogenerated\UserWithUniqueFeatures($this->kernel, $this->kernel->graph(), "another_username", "123456"); + $this->created[] = $u->id(); + $u->setAbout("esokullu"); + $this->assertEquals($this->kernel->founder()->getUsername(), $u->getAbout()); + //eval(\Psy\sh()); + $this->assertTrue(true); // if it has come to this point with no exception, we're good + } + + + /* + // @todo + public function testUniquenesswithDistinctLabel() { + // ? + } + */ + + +} \ No newline at end of file diff --git a/tests/assets/compiled/User.php b/tests/assets/compiled/User.php index c3294b9..8b0bfe6 100644 --- a/tests/assets/compiled/User.php +++ b/tests/assets/compiled/User.php @@ -25,7 +25,7 @@ class User extends Foundation\AbstractActorDP { const DEFAULT_MOD = 0x07554; const DEFAULT_MASK = 0xfffff; - const FIELDS = "{\"password\":{\"constraints\":{\"minLength\":null,\"maxLength\":null,\"uuid\":null,\"regex\":\"^[a-zA-Z0-9_]{4,12}$\",\"greaterThan\":null,\"lessThan\":null},\"directives\":{\"md5\":true,\"now\":false,\"default\":\"|_~_~NO!-!VALUE!-!SET~_~_|\"}},\"join_time\":{\"constraints\":{\"minLength\":null,\"maxLength\":null,\"uuid\":null,\"regex\":null,\"greaterThan\":null,\"lessThan\":null},\"directives\":{\"md5\":false,\"now\":true,\"default\":\"|_~_~NO!-!VALUE!-!SET~_~_|\"}},\"birthday\":{\"constraints\":{\"minLength\":null,\"maxLength\":null,\"uuid\":null,\"regex\":null,\"greaterThan\":null,\"lessThan\":null},\"directives\":{\"md5\":false,\"now\":false,\"default\":411436800}},\"about\":{\"constraints\":{\"minLength\":null,\"maxLength\":\"255\",\"uuid\":null,\"regex\":null,\"greaterThan\":null,\"lessThan\":null},\"directives\":{\"md5\":false,\"now\":false,\"default\":\"\"}}}"; + const FIELDS = "{\"password\":{\"constraints\":{\"minLength\":null,\"maxLength\":null,\"uuid\":null,\"regex\":\"^[a-zA-Z0-9_]{4,12}$\",\"greaterThan\":null,\"lessThan\":null},\"directives\":{\"md5\":true,\"now\":false,\"default\":\"|_~_~NO!-!VALUE!-!SET~_~_|\"}},\"join_time\":{\"constraints\":{\"minLength\":null,\"maxLength\":null,\"uuid\":null,\"regex\":null,\"greaterThan\":null,\"lessThan\":null},\"directives\":{\"md5\":false,\"now\":true,\"default\":\"|_~_~NO!-!VALUE!-!SET~_~_|\"}},\"birthday\":{\"constraints\":{\"minLength\":null,\"maxLength\":null,\"uuid\":null,\"regex\":null,\"greaterThan\":null,\"lessThan\":null},\"directives\":{\"md5\":false,\"now\":false,\"default\":411436800}},\"about\":{\"constraints\":{\"minLength\":null,\"maxLength\":\"255\",\"uuid\":null,\"regex\":null,\"greaterThan\":null,\"lessThan\":null},\"directives\":{ \"md5\":false,\"now\":false,\"default\":\"\"}}}"; public function __construct(\Pho\Kernel\Kernel $kernel, \Pho\Lib\Graph\GraphInterface $graph , string $password, ?int $birthday = 411436800, ?string $about = "") { @@ -34,10 +34,13 @@ public function __construct(\Pho\Kernel\Kernel $kernel, \Pho\Lib\Graph\GraphInte $this->registerIncomingEdges(UserOut\Consume::class); parent::__construct($kernel, $graph); $this->setPassword($password, true); - $this->setJoinTime(time(), true); - $this->setBirthday($birthday, true); - $this->setAbout($about, true); - + + $this->setJoinTime(time(), true); + + $this->setBirthday($birthday, true); + + $this->setAbout($about, true); + $this->persist(); } diff --git a/tests/assets/compiled/UserWithUniqueFeatures.php b/tests/assets/compiled/UserWithUniqueFeatures.php new file mode 100644 index 0000000..0d0074c --- /dev/null +++ b/tests/assets/compiled/UserWithUniqueFeatures.php @@ -0,0 +1,53 @@ +setUsername($username, true); + + + $this->persist(); + } + +} + +/***************************************************** + * Timestamp: 1501461738 + * Size (in bytes): 2346 + * Compilation Time: 3434 + * e64cf8335098e7a03ebd665e7c424c27 + ******************************************************/ \ No newline at end of file