Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions tests/Integration/Aggregation/ContainerAggregationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace Bonu\ElasticsearchBuilder\Tests\Integration\Aggregation;

use PHPUnit\Framework\Attributes\Test;
use Bonu\ElasticsearchBuilder\QueryBuilder;
use Bonu\ElasticsearchBuilder\Query\TermQuery;
use Bonu\ElasticsearchBuilder\Tests\IntegrationTestCase;
use Bonu\ElasticsearchBuilder\Aggregation\StatsAggregation;
use Bonu\ElasticsearchBuilder\Aggregation\TermsAggregation;
use Bonu\ElasticsearchBuilder\Aggregation\ContainerAggregation;

/**
* @internal
*/
final class ContainerAggregationTest extends IntegrationTestCase
{
#[Test]
public function itGroupsSubAggregationsWithFilter(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->aggregation(
new ContainerAggregation('filtered_container')
->query(new TermQuery('album_type', 'album'))
->aggregation(new TermsAggregation('by_explicit', 'explicit'))
)
->size(1)
->build()
)->asArray();

$this->assertArrayHasKey('aggregations', $response);
$this->assertArrayHasKey('filtered_container', $response['aggregations']);
$this->assertArrayHasKey('doc_count', $response['aggregations']['filtered_container']);
$this->assertGreaterThan(0, $response['aggregations']['filtered_container']['doc_count']);
$this->assertNotEmpty($response['aggregations']['filtered_container']['by_explicit']['buckets']);
}

#[Test]
public function itGroupsSubAggregationsAsGlobal(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->query(new TermQuery('album_type', 'single'))
->aggregation(
new ContainerAggregation('global_container')
->asGlobal()
->aggregation(new StatsAggregation('popularity_stats', 'track_popularity'))
)
->size(1)
->build()
)->asArray();

$this->assertArrayHasKey('aggregations', $response);
$this->assertArrayHasKey('global_container', $response['aggregations']);
$this->assertArrayHasKey('doc_count', $response['aggregations']['global_container']);
$this->assertGreaterThan(
$response['hits']['total']['value'],
$response['aggregations']['global_container']['doc_count'],
);
$this->assertArrayHasKey('popularity_stats', $response['aggregations']['global_container']);
}
}
50 changes: 50 additions & 0 deletions tests/Integration/Aggregation/HistogramAggregationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Bonu\ElasticsearchBuilder\Tests\Integration\Aggregation;

use PHPUnit\Framework\Attributes\Test;
use Bonu\ElasticsearchBuilder\QueryBuilder;
use Bonu\ElasticsearchBuilder\Tests\IntegrationTestCase;
use Bonu\ElasticsearchBuilder\Aggregation\HistogramAggregation;

/**
* @internal
*/
final class HistogramAggregationTest extends IntegrationTestCase
{
#[Test]
public function itCreatesHistogramBuckets(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->aggregation(new HistogramAggregation('popularity_histogram', 'track_popularity', 10))
->size(1)
->build()
)->asArray();

$this->assertArrayHasKey('aggregations', $response);
$this->assertNotEmpty($response['aggregations']['popularity_histogram']['buckets']);

foreach ($response['aggregations']['popularity_histogram']['buckets'] as $bucket) {
$this->assertArrayHasKey('key', $bucket);
$this->assertArrayHasKey('doc_count', $bucket);
}
}

#[Test]
public function itCreatesHistogramWithMinDocCount(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->aggregation(new HistogramAggregation('popularity_histogram', 'track_popularity', 10, 1))
->size(1)
->build()
)->asArray();

foreach ($response['aggregations']['popularity_histogram']['buckets'] as $bucket) {
$this->assertGreaterThanOrEqual(1, $bucket['doc_count']);
}
}
}
37 changes: 37 additions & 0 deletions tests/Integration/Aggregation/MultiTermsAggregationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Bonu\ElasticsearchBuilder\Tests\Integration\Aggregation;

use PHPUnit\Framework\Attributes\Test;
use Bonu\ElasticsearchBuilder\QueryBuilder;
use Bonu\ElasticsearchBuilder\Tests\IntegrationTestCase;
use Bonu\ElasticsearchBuilder\Aggregation\MultiTermsAggregation;

/**
* @internal
*/
final class MultiTermsAggregationTest extends IntegrationTestCase
{
#[Test]
public function itAggregatesByMultipleFields(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->aggregation(new MultiTermsAggregation('by_type_and_explicit', ['album_type', 'explicit']))
->size(1)
->build()
)->asArray();

$this->assertArrayHasKey('aggregations', $response);
$this->assertNotEmpty($response['aggregations']['by_type_and_explicit']['buckets']);

foreach ($response['aggregations']['by_type_and_explicit']['buckets'] as $bucket) {
$this->assertArrayHasKey('key', $bucket);
$this->assertArrayHasKey('doc_count', $bucket);
$this->assertCount(2, $bucket['key']);
$this->assertGreaterThan(0, $bucket['doc_count']);
}
}
}
39 changes: 39 additions & 0 deletions tests/Integration/Aggregation/StatsAggregationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Bonu\ElasticsearchBuilder\Tests\Integration\Aggregation;

use PHPUnit\Framework\Attributes\Test;
use Bonu\ElasticsearchBuilder\QueryBuilder;
use Bonu\ElasticsearchBuilder\Tests\IntegrationTestCase;
use Bonu\ElasticsearchBuilder\Aggregation\StatsAggregation;

/**
* @internal
*/
final class StatsAggregationTest extends IntegrationTestCase
{
#[Test]
public function itCalculatesFieldStatistics(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->aggregation(new StatsAggregation('popularity_stats', 'track_popularity'))
->size(1)
->build()
)->asArray();

$this->assertArrayHasKey('aggregations', $response);

$stats = $response['aggregations']['popularity_stats'];
$this->assertArrayHasKey('min', $stats);
$this->assertArrayHasKey('max', $stats);
$this->assertArrayHasKey('avg', $stats);
$this->assertArrayHasKey('sum', $stats);
$this->assertArrayHasKey('count', $stats);
$this->assertGreaterThanOrEqual(0, $stats['min']);
$this->assertLessThanOrEqual(100, $stats['max']);
$this->assertGreaterThan(0, $stats['count']);
}
}
49 changes: 49 additions & 0 deletions tests/Integration/Aggregation/TermsAggregationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace Bonu\ElasticsearchBuilder\Tests\Integration\Aggregation;

use PHPUnit\Framework\Attributes\Test;
use Bonu\ElasticsearchBuilder\QueryBuilder;
use Bonu\ElasticsearchBuilder\Tests\IntegrationTestCase;
use Bonu\ElasticsearchBuilder\Aggregation\TermsAggregation;

/**
* @internal
*/
final class TermsAggregationTest extends IntegrationTestCase
{
#[Test]
public function itAggregatesTermsBuckets(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->aggregation(new TermsAggregation('by_album_type', 'album_type'))
->size(1)
->build()
)->asArray();

$this->assertArrayHasKey('aggregations', $response);
$this->assertNotEmpty($response['aggregations']['by_album_type']['buckets']);

foreach ($response['aggregations']['by_album_type']['buckets'] as $bucket) {
$this->assertArrayHasKey('key', $bucket);
$this->assertArrayHasKey('doc_count', $bucket);
$this->assertGreaterThan(0, $bucket['doc_count']);
}
}

#[Test]
public function itAggregatesTermsWithSize(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->aggregation(new TermsAggregation('by_album_type', 'album_type')->size(1))
->size(1)
->build()
)->asArray();

$this->assertCount(1, $response['aggregations']['by_album_type']['buckets']);
}
}
59 changes: 59 additions & 0 deletions tests/Integration/Query/BoolQueryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace Bonu\ElasticsearchBuilder\Tests\Integration\Query;

use PHPUnit\Framework\Attributes\Test;
use Bonu\ElasticsearchBuilder\QueryBuilder;
use Bonu\ElasticsearchBuilder\Query\BoolQuery;
use Bonu\ElasticsearchBuilder\Query\TermQuery;
use Bonu\ElasticsearchBuilder\Query\MatchQuery;
use Bonu\ElasticsearchBuilder\Tests\IntegrationTestCase;

/**
* @internal
*/
final class BoolQueryTest extends IntegrationTestCase
{
#[Test]
public function itCombinesFilterAndMustNot(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->query(
new BoolQuery()
->filter(new TermQuery('album_type', 'album'))
->mustNot(new TermQuery('explicit', true))
)
->build()
)->asArray();

$this->assertGreaterThan(0, $response['hits']['total']['value']);

foreach ($response['hits']['hits'] as $hit) {
$this->assertSame('album', $hit['_source']['album_type']);
$this->assertFalse($hit['_source']['explicit']);
}
}

#[Test]
public function itCombinesFilterAndShould(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->query(
new BoolQuery()
->filter(new TermQuery('album_type', 'single'))
->should(new MatchQuery('artist_name', 'Diplo'))
)
->build()
)->asArray();

$this->assertGreaterThan(0, $response['hits']['total']['value']);

foreach ($response['hits']['hits'] as $hit) {
$this->assertSame('single', $hit['_source']['album_type']);
}
}
}
44 changes: 44 additions & 0 deletions tests/Integration/Query/DatetimeRangeQueryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace Bonu\ElasticsearchBuilder\Tests\Integration\Query;

use PHPUnit\Framework\Attributes\Test;
use Bonu\ElasticsearchBuilder\QueryBuilder;
use Bonu\ElasticsearchBuilder\Query\DatetimeRangeQuery;
use Bonu\ElasticsearchBuilder\Tests\IntegrationTestCase;

/**
* @internal
*/
final class DatetimeRangeQueryTest extends IntegrationTestCase
{
#[Test]
public function itFiltersRecordsByDateRange(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->query(new DatetimeRangeQuery('album_release_date', lte: '2025-12-31', gte: '2025-01-01', format: 'yyyy-MM-dd'))
->build()
)->asArray();

$this->assertGreaterThan(0, $response['hits']['total']['value']);

foreach ($response['hits']['hits'] as $hit) {
$this->assertStringStartsWith('2025-', $hit['_source']['album_release_date']);
}
}

#[Test]
public function itFiltersRecordsWithLowerBoundOnly(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->query(new DatetimeRangeQuery('album_release_date', gte: '2020-01-01', format: 'yyyy-MM-dd'))
->build()
)->asArray();

$this->assertGreaterThan(0, $response['hits']['total']['value']);
}
}
49 changes: 49 additions & 0 deletions tests/Integration/Query/MatchPhraseQueryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace Bonu\ElasticsearchBuilder\Tests\Integration\Query;

use PHPUnit\Framework\Attributes\Test;
use Bonu\ElasticsearchBuilder\QueryBuilder;
use Bonu\ElasticsearchBuilder\Query\MatchPhraseQuery;
use Bonu\ElasticsearchBuilder\Tests\IntegrationTestCase;

/**
* @internal
*/
final class MatchPhraseQueryTest extends IntegrationTestCase
{
#[Test]
public function itMatchesExactPhrase(): void
{
$response = $this->client?->search(
new QueryBuilder(self::INDEX)
->query(new MatchPhraseQuery('track_name', 'Trippy Mane'))
->build()
)->asArray();

$this->assertGreaterThan(0, $response['hits']['total']['value']);
}

#[Test]
public function itMatchesPhraseWithSlop(): void
{
$exactResponse = $this->client?->search(
new QueryBuilder(self::INDEX)
->query(new MatchPhraseQuery('track_name', 'Trippy Mane'))
->build()
)->asArray();

$slopResponse = $this->client?->search(
new QueryBuilder(self::INDEX)
->query(new MatchPhraseQuery('track_name', 'Trippy Mane', 1))
->build()
)->asArray();

$this->assertGreaterThanOrEqual(
$exactResponse['hits']['total']['value'],
$slopResponse['hits']['total']['value'],
);
}
}
Loading