From 570e4fea812a53033e6ed762bf4891df32832be2 Mon Sep 17 00:00:00 2001 From: Mathieu Darse Date: Fri, 3 Jul 2015 16:54:47 +0200 Subject: [PATCH] Test TextNode Make buildConceptQueries() return early when no concepts are available (do not call getFields() uselessly anymore). --- .../Elastic/AST/AbstractTermNode.php | 15 +- .../Phrasea/SearchEngine/AST/TextNodeTest.php | 154 ++++++++++++++++++ 2 files changed, 163 insertions(+), 6 deletions(-) create mode 100644 tests/Alchemy/Tests/Phrasea/SearchEngine/AST/TextNodeTest.php diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/AST/AbstractTermNode.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/AST/AbstractTermNode.php index 0ed6335c98..5b3c34c06c 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/AST/AbstractTermNode.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/AST/AbstractTermNode.php @@ -10,7 +10,7 @@ abstract class AbstractTermNode extends Node implements TermInterface { protected $text; protected $context; - private $concepts = array(); + private $concepts = []; public function __construct($text, Context $context = null) { @@ -25,21 +25,24 @@ abstract class AbstractTermNode extends Node implements TermInterface protected function buildConceptQueries(QueryContext $context) { - $queries = array(); + $queries = []; $concepts = Concept::pruneNarrowConcepts($this->concepts); + if (!$concepts) { + return []; + } $fields = $context->getFields(); if (empty($fields)) { - $fields = array('*'); + $fields = ['*']; } $prefixedFields = array(); foreach ($fields as $field) { $prefixedFields[] = 'concept_path.' . $field; } foreach ($concepts as $concept) { - $queries[]['multi_match'] = array( + $queries[]['multi_match'] = [ 'fields' => $prefixedFields, 'query' => $concept->getPath() - ); + ]; } return $queries; @@ -62,6 +65,6 @@ abstract class AbstractTermNode extends Node implements TermInterface public function getTermNodes() { - return array($this); + return [$this]; } } diff --git a/tests/Alchemy/Tests/Phrasea/SearchEngine/AST/TextNodeTest.php b/tests/Alchemy/Tests/Phrasea/SearchEngine/AST/TextNodeTest.php new file mode 100644 index 0000000000..2f2f172428 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/SearchEngine/AST/TextNodeTest.php @@ -0,0 +1,154 @@ +assertTrue(method_exists(TextNode::class, '__toString'), 'Class does not have method __toString'); + $node = new TextNode('foo'); + $this->assertEquals('', (string) $node); + $node_with_context = new TextNode('foo', new Context('bar')); + $this->assertEquals('', (string) $node_with_context); + } + + public function testMerge() + { + $left = new TextNode('foo', new Context('bar')); + $right = new TextNode('baz', new Context('qux')); + $merged = TextNode::merge($left, $right); + $this->assertEquals(new TextNode('foobaz'), $merged); + } + + public function testContextAdd() + { + $node = new TextNode('foo'); + $node_with_context = $node->withContext(new Context('bar')); + $this->assertEquals(new TextNode('foo', new Context('bar')), $node_with_context); + } + + public function testQueryBuild() + { + $query_context = $this->prophesize(QueryContext::class); + $query_context->getLocalizedFields()->willReturn(['foo.fr', 'foo.en']); + $query_context->getAllowedPrivateFields()->willReturn([]); + + $node = new TextNode('bar', new Context('baz')); + $query = $node->buildQuery($query_context->reveal()); + + $expected = '{ + "multi_match": { + "fields": ["foo.fr", "foo.en"], + "query": "bar", + "operator": "and" + } + }'; + + $this->assertEquals(json_decode($expected, true), $query); + } + + public function testQueryBuildWithPrivateFields() + { + $public_field = new Field('foo', Mapping::TYPE_STRING, ['private' => false]); + $private_field = new Field('bar', Mapping::TYPE_STRING, ['private' => true]); + + $query_context = $this->prophesize(QueryContext::class); + $query_context + ->getLocalizedFields() + ->willReturn(['foo.fr', 'foo.en']); + $query_context + ->getAllowedPrivateFields() + ->willReturn([$private_field]); + $query_context + ->getAllowedCollectionsOnPrivateField($private_field) + ->willReturn([1, 2, 3]); + $query_context + ->localizeField('private_caption.bar') + ->willReturn(['private_caption.bar.fr', 'private_caption.bar.en']); + + $node = new TextNode('baz'); + $query = $node->buildQuery($query_context->reveal()); + + $expected = '{ + "bool": { + "should": [{ + "multi_match": { + "fields": ["foo.fr", "foo.en"], + "query": "baz", + "operator": "and" + } + }, { + "bool": { + "must": [{ + "terms": { + "base_id": [1, 2, 3] + } + }, { + "multi_match": { + "fields": ["private_caption.bar.fr", "private_caption.bar.en"], + "query": "baz", + "operator": "and" + } + }] + } + }] + } + }'; + + $this->assertEquals(json_decode($expected, true), $query); + } + + public function testQueryBuildWithConcepts() + { + $query_context = $this->prophesize(QueryContext::class); + $query_context + ->getLocalizedFields() + ->willReturn(['foo.fr', 'foo.en']); + $query_context + ->getAllowedPrivateFields() + ->willReturn([]); + $query_context + ->getFields() + ->willReturn(['foo']); + + $node = new TextNode('bar'); + $node->setConcepts([ + new Concept('/qux'), + ]); + $query = $node->buildQuery($query_context->reveal()); + + $expected = '{ + "bool": { + "should": [{ + "multi_match": { + "fields": ["foo.fr", "foo.en"], + "query": "bar", + "operator": "and" + } + }, { + "multi_match": { + "fields": [ + "concept_path.foo" + ], + "query": "/qux" + } + }] + } + }'; + + $this->assertEquals(json_decode($expected, true), $query); + } +}