|
| 1 | +<?php |
| 2 | + |
| 3 | +declare(strict_types=1); |
| 4 | + |
| 5 | +namespace Syndesi\CypherEntityManager\Tests\EventListener\OpenCypher; |
| 6 | + |
| 7 | +use Laudis\Neo4j\Databags\Statement; |
| 8 | +use Monolog\Handler\TestHandler; |
| 9 | +use Monolog\Logger; |
| 10 | +use Psr\Log\LoggerInterface; |
| 11 | +use Syndesi\CypherDataStructures\Contract\NodeInterface; |
| 12 | +use Syndesi\CypherDataStructures\Type\Node; |
| 13 | +use Syndesi\CypherDataStructures\Type\NodeLabel; |
| 14 | +use Syndesi\CypherDataStructures\Type\PropertyName; |
| 15 | +use Syndesi\CypherDataStructures\Type\Relation; |
| 16 | +use Syndesi\CypherDataStructures\Type\RelationType; |
| 17 | +use Syndesi\CypherEntityManager\Event\ActionCypherElementToStatementEvent; |
| 18 | +use Syndesi\CypherEntityManager\EventListener\OpenCypher\SimilarRelationQueueCreateToStatementEventListener; |
| 19 | +use Syndesi\CypherEntityManager\Exception\InvalidArgumentException; |
| 20 | +use Syndesi\CypherEntityManager\Tests\ProphesizeTestCase; |
| 21 | +use Syndesi\CypherEntityManager\Type\ActionCypherElement; |
| 22 | +use Syndesi\CypherEntityManager\Type\ActionType; |
| 23 | +use Syndesi\CypherEntityManager\Type\SimilarRelationQueue; |
| 24 | + |
| 25 | +class SimilarRelationQueueCreateToStatementEventListenerTest extends ProphesizeTestCase |
| 26 | +{ |
| 27 | + public function createNode(int $id): Node |
| 28 | + { |
| 29 | + return (new Node()) |
| 30 | + ->addNodeLabel(new NodeLabel('Node')) |
| 31 | + ->addProperty(new PropertyName('id'), $id) |
| 32 | + ->addIdentifier(new PropertyName('id')); |
| 33 | + } |
| 34 | + |
| 35 | + public function createRelation(int $id, ?NodeInterface $startNode, ?NodeInterface $endNode): Relation |
| 36 | + { |
| 37 | + return (new Relation()) |
| 38 | + ->setStartNode($startNode) |
| 39 | + ->setEndNode($endNode) |
| 40 | + ->setRelationType(new RelationType('RELATION')) |
| 41 | + ->addProperty(new PropertyName('id'), $id) |
| 42 | + ->addIdentifier(new PropertyName('id')); |
| 43 | + } |
| 44 | + |
| 45 | + public function testOnActionCypherElementToStatementEvent(): void |
| 46 | + { |
| 47 | + $nodeA = $this->createNode(1000); |
| 48 | + $nodeB = $this->createNode(1001); |
| 49 | + $nodeC = $this->createNode(1002); |
| 50 | + $relationAB = $this->createRelation(2000, $nodeA, $nodeB); |
| 51 | + $relationBC = $this->createRelation(2001, $nodeB, $nodeC); |
| 52 | + $relationCA = $this->createRelation(2002, $nodeC, $nodeA); |
| 53 | + |
| 54 | + $similarRelationQueue = (new SimilarRelationQueue()) |
| 55 | + ->enqueue($relationAB) |
| 56 | + ->enqueue($relationBC) |
| 57 | + ->enqueue($relationCA); |
| 58 | + |
| 59 | + $actionCypherElement = new ActionCypherElement(ActionType::CREATE, $similarRelationQueue); |
| 60 | + $event = new ActionCypherElementToStatementEvent($actionCypherElement); |
| 61 | + $loggerHandler = new TestHandler(); |
| 62 | + $logger = (new Logger('logger')) |
| 63 | + ->pushHandler($loggerHandler); |
| 64 | + |
| 65 | + $eventListener = new SimilarRelationQueueCreateToStatementEventListener($logger); |
| 66 | + $eventListener->onActionCypherElementToStatementEvent($event); |
| 67 | + |
| 68 | + $this->assertTrue($event->isPropagationStopped()); |
| 69 | + $this->assertInstanceOf(Statement::class, $event->getStatement()); |
| 70 | + $this->assertCount(1, $loggerHandler->getRecords()); |
| 71 | + $logMessage = $loggerHandler->getRecords()[0]; |
| 72 | + $this->assertSame('Acting on ActionCypherElementToStatementEvent: Created similar-relation-queue-create-statement and stopped propagation.', $logMessage->message); |
| 73 | + $this->assertArrayHasKey('element', $logMessage->context); |
| 74 | + $this->assertArrayHasKey('statement', $logMessage->context); |
| 75 | + } |
| 76 | + |
| 77 | + public function testOnActionCypherElementToStatementEventWithWrongAction(): void |
| 78 | + { |
| 79 | + $similarRelationQueue = new SimilarRelationQueue(); |
| 80 | + |
| 81 | + $actionCypherElement = new ActionCypherElement(ActionType::MERGE, $similarRelationQueue); |
| 82 | + $event = new ActionCypherElementToStatementEvent($actionCypherElement); |
| 83 | + |
| 84 | + $eventListener = new SimilarRelationQueueCreateToStatementEventListener($this->prophet->prophesize(LoggerInterface::class)->reveal()); |
| 85 | + $eventListener->onActionCypherElementToStatementEvent($event); |
| 86 | + |
| 87 | + $this->assertFalse($event->isPropagationStopped()); |
| 88 | + $this->assertNull($event->getStatement()); |
| 89 | + } |
| 90 | + |
| 91 | + public function testOnActionCypherElementToStatementEventWithWrongType(): void |
| 92 | + { |
| 93 | + $node = new Node(); |
| 94 | + $actionCypherElement = new ActionCypherElement(ActionType::CREATE, $node); |
| 95 | + $event = new ActionCypherElementToStatementEvent($actionCypherElement); |
| 96 | + |
| 97 | + $eventListener = new SimilarRelationQueueCreateToStatementEventListener($this->prophet->prophesize(LoggerInterface::class)->reveal()); |
| 98 | + $eventListener->onActionCypherElementToStatementEvent($event); |
| 99 | + |
| 100 | + $this->assertFalse($event->isPropagationStopped()); |
| 101 | + $this->assertNull($event->getStatement()); |
| 102 | + } |
| 103 | + |
| 104 | + public function testOnActionCypherElementToStatementEventWithEmptyQueue(): void |
| 105 | + { |
| 106 | + $similarRelationQueue = new SimilarRelationQueue(); |
| 107 | + $actionCypherElement = new ActionCypherElement(ActionType::CREATE, $similarRelationQueue); |
| 108 | + $event = new ActionCypherElementToStatementEvent($actionCypherElement); |
| 109 | + |
| 110 | + $eventListener = new SimilarRelationQueueCreateToStatementEventListener($this->prophet->prophesize(LoggerInterface::class)->reveal()); |
| 111 | + $eventListener->onActionCypherElementToStatementEvent($event); |
| 112 | + |
| 113 | + $this->assertTrue($event->isPropagationStopped()); |
| 114 | + $this->assertSame('MATCH (n) LIMIT 0', $event->getStatement()->getText()); |
| 115 | + } |
| 116 | + |
| 117 | +// todo :) |
| 118 | +// public function testOnActionCypherElementToStatementEventWithNoStartNode(): void |
| 119 | +// { |
| 120 | +// $node = $this->createNode(1000); |
| 121 | +// $relation = $this->createRelation(2000, null, $node); |
| 122 | +// $similarRelationQueue = (new SimilarRelationQueue()) |
| 123 | +// ->enqueue($relation); |
| 124 | +// |
| 125 | +// $actionCypherElement = new ActionCypherElement(ActionType::CREATE, $similarRelationQueue); |
| 126 | +// $event = new ActionCypherElementToStatementEvent($actionCypherElement); |
| 127 | +// |
| 128 | +// $this->expectException(InvalidArgumentException::class); |
| 129 | +// $this->expectExceptionMessage('---'); |
| 130 | +// |
| 131 | +// $eventListener = new SimilarRelationQueueCreateToStatementEventListener($this->prophet->prophesize(LoggerInterface::class)->reveal()); |
| 132 | +// $eventListener->onActionCypherElementToStatementEvent($event); |
| 133 | +// } |
| 134 | + |
| 135 | + public function testNodeStatement(): void |
| 136 | + { |
| 137 | + $nodeA = $this->createNode(1000); |
| 138 | + $nodeB = $this->createNode(1001); |
| 139 | + $nodeC = $this->createNode(1002); |
| 140 | + $relationAB = $this->createRelation(2000, $nodeA, $nodeB); |
| 141 | + $relationBC = $this->createRelation(2001, $nodeB, $nodeC); |
| 142 | + $relationCA = $this->createRelation(2002, $nodeC, $nodeA); |
| 143 | + |
| 144 | + $similarRelationQueue = (new SimilarRelationQueue()) |
| 145 | + ->enqueue($relationAB) |
| 146 | + ->enqueue($relationBC) |
| 147 | + ->enqueue($relationCA); |
| 148 | + |
| 149 | + $statement = SimilarRelationQueueCreateToStatementEventListener::similarRelationQueueStatement($similarRelationQueue); |
| 150 | + |
| 151 | + $this->assertSame( |
| 152 | + "UNWIND \$batch as row\n". |
| 153 | + "MATCH\n". |
| 154 | + " (startNode:Node {id: row.startNode.id}),\n". |
| 155 | + " (endNode:Node {id: row.endNode.id})\n". |
| 156 | + "CREATE (startNode)-[relation:RELATION {id: row.identifier.id}]->(endNode)\n". |
| 157 | + "SET relation += row.property", |
| 158 | + $statement->getText() |
| 159 | + ); |
| 160 | + $this->assertCount(1, $statement->getParameters()); |
| 161 | + foreach ($statement->getParameters()['batch'] as $row) { |
| 162 | + $this->assertArrayHasKey('startNode', $row); |
| 163 | + $this->assertArrayHasKey('endNode', $row); |
| 164 | + $this->assertArrayHasKey('identifier', $row); |
| 165 | + $this->assertArrayHasKey('property', $row); |
| 166 | + } |
| 167 | + } |
| 168 | +} |
0 commit comments