1+ <?php
2+ declare (strict_types=1 );
3+
4+ namespace Flowpack \ElasticSearch \ContentRepositoryAdaptor \Tests \Functional \Eel ;
5+
6+ /*
7+ * This file is part of the Flowpack.ElasticSearch.ContentRepositoryAdaptor package.
8+ *
9+ * (c) Contributors of the Neos Project - www.neos.io
10+ *
11+ * This package is Open Source Software. For the full copyright and license
12+ * information, please view the LICENSE file which was distributed with this
13+ * source code.
14+ */
15+
16+ use DateTime ;
17+ use DateTimeImmutable ;
18+ use Exception ;
19+ use Flowpack \ElasticSearch \ContentRepositoryAdaptor \Command \NodeIndexCommandController ;
20+ use Flowpack \ElasticSearch \ContentRepositoryAdaptor \Eel \ElasticSearchQueryBuilder ;
21+ use Flowpack \ElasticSearch \ContentRepositoryAdaptor \ElasticSearchClient ;
22+ use Flowpack \ElasticSearch \ContentRepositoryAdaptor \Indexer \NodeIndexer ;
23+ use Flowpack \ElasticSearch \ContentRepositoryAdaptor \Tests \Functional \Traits \ContentRepositoryMultiDimensionNodeCreationTrait ;
24+ use Neos \ContentRepository \Domain \Model \NodeInterface ;
25+
26+ use Neos \Flow \Tests \FunctionalTestCase ;
27+
28+ class ElasticSearchMultiDimensionQueryTest extends FunctionalTestCase
29+ {
30+ use ContentRepositoryMultiDimensionNodeCreationTrait;
31+
32+ const TESTING_INDEX_PREFIX = 'neoscr_testing ' ;
33+
34+ /**
35+ * @var ElasticSearchClient
36+ */
37+ protected $ searchClient ;
38+
39+ /**
40+ * @var NodeIndexCommandController
41+ */
42+ protected $ nodeIndexCommandController ;
43+
44+ /**
45+ * @var boolean
46+ */
47+ protected static $ testablePersistenceEnabled = true ;
48+
49+ /**
50+ * @var NodeIndexer
51+ */
52+ protected $ nodeIndexer ;
53+
54+ /**
55+ * @var NodeInterface
56+ */
57+ protected $ siteNodeDefault ;
58+
59+ /**
60+ * @var NodeInterface
61+ */
62+ protected $ siteNodeDe ;
63+
64+ /**
65+ * @var NodeInterface
66+ */
67+ protected $ siteNodeDk ;
68+
69+ /**
70+ * @var boolean
71+ */
72+ protected static $ indexInitialized = false ;
73+
74+
75+ public function setUp (): void
76+ {
77+ parent ::setUp ();
78+
79+ $ this ->nodeIndexer = $ this ->objectManager ->get (NodeIndexer::class);
80+ $ this ->searchClient = $ this ->objectManager ->get (ElasticSearchClient::class);
81+
82+ if (self ::$ indexInitialized !== true ) {
83+ // clean up any existing indices
84+ $ this ->searchClient ->request ('DELETE ' , '/ ' . self ::TESTING_INDEX_PREFIX . '* ' );
85+ }
86+
87+
88+ $ this ->nodeIndexCommandController = $ this ->objectManager ->get (NodeIndexCommandController::class);
89+ $ this ->setupContentRepository ();
90+ $ this ->createNodesForNodeSearchTest ();
91+ $ this ->indexNodes ();
92+ }
93+
94+ public function tearDown (): void
95+ {
96+ parent ::tearDown ();
97+ $ this ->inject ($ this ->contextFactory , 'contextInstances ' , []);
98+ }
99+
100+ /**
101+ * @test
102+ */
103+ public function countDefaultDimensionNodesTest (): void
104+ {
105+ $ resultDefault = $ this ->getQueryBuilder ()
106+ ->query ($ this ->siteNodeDefault )
107+ ->log ($ this ->getLogMessagePrefix (__METHOD__ ))
108+ ->nodeType ('Flowpack.ElasticSearch.ContentRepositoryAdaptor:Document ' )
109+ ->sortDesc ('title ' )
110+ ->execute ();
111+
112+ // expecting: root, document1, untranslated = 3
113+ static ::assertCount (3 , $ resultDefault );
114+ }
115+
116+ /**
117+ * @test
118+ */
119+ public function countDeDimensionNodesTest (): void
120+ {
121+ $ resultDe = $ this ->getQueryBuilder ()
122+ ->query ($ this ->siteNodeDe )
123+ ->log ($ this ->getLogMessagePrefix (__METHOD__ ))
124+ ->nodeType ('Flowpack.ElasticSearch.ContentRepositoryAdaptor:Document ' )
125+ ->sortDesc ('title ' )
126+ ->execute ();
127+
128+ // expecting: root, document1, document2, document3, document4, untranslated (fallback from en_us) = 6
129+ static ::assertCount (6 , $ resultDe );
130+ }
131+
132+ /**
133+ * @test
134+ */
135+ public function countDkDimensionNodesTest (): void
136+ {
137+ $ resultDk = $ this ->getQueryBuilder ()
138+ ->query ($ this ->siteNodeDk )
139+ ->log ($ this ->getLogMessagePrefix (__METHOD__ ))
140+ ->nodeType ('Flowpack.ElasticSearch.ContentRepositoryAdaptor:Document ' )
141+ ->sortDesc ('title ' )
142+ ->execute ();
143+
144+ // expecting: root, document1, document2, document4 (fallback from de), untranslated (fallback from en_us) = 6
145+ static ::assertCount (5 , $ resultDk );
146+ }
147+
148+
149+ protected function indexNodes (): void
150+ {
151+ if (self ::$ indexInitialized === true ) {
152+ return ;
153+ }
154+
155+ $ this ->nodeIndexCommandController ->buildCommand (null , false , 'live ' );
156+ self ::$ indexInitialized = true ;
157+ }
158+
159+ /**
160+ * @param string $method
161+ * @return string
162+ */
163+ protected function getLogMessagePrefix (string $ method ): string
164+ {
165+ return substr (strrchr ($ method , '\\' ), 1 );
166+ }
167+
168+ /**
169+ * @return ElasticSearchQueryBuilder
170+ */
171+ protected function getQueryBuilder (): ElasticSearchQueryBuilder
172+ {
173+ try {
174+ $ elasticSearchQueryBuilder = $ this ->objectManager ->get (ElasticSearchQueryBuilder::class);
175+ $ this ->inject ($ elasticSearchQueryBuilder , 'now ' , new DateTimeImmutable ('@1735685400 ' )); // Dec. 31, 2024 23:50:00
176+
177+ return $ elasticSearchQueryBuilder ;
178+ } catch (Exception $ exception ) {
179+ static ::fail ('Setting up the QueryBuilder failed: ' . $ exception ->getMessage ());
180+ }
181+ }
182+ }
0 commit comments