Skip to content

Commit

Permalink
Fix fulltext search tests
Browse files Browse the repository at this point in the history
Under InnoDB, database entries created in transactions are not processed by fulltext indexes until the transaction is committed. To work around this, cases that test fulltext search have been split off into a separate class that adds and removes seed discussions/posts outside of transactions during setUp/tearDown.
  • Loading branch information
askvortsov1 committed Jan 7, 2021
1 parent 93aa227 commit 793e9ed
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 92 deletions.
92 changes: 0 additions & 92 deletions tests/integration/api/discussions/ListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,96 +67,4 @@ public function can_search_for_author()

$this->assertEquals(200, $response->getStatusCode());
}

/**
* @test
*/
public function can_search_for_word_in_post()
{
$this->database()->table('discussions')->insert([
['id' => 2, 'title' => 'lightsail in title', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'comment_count' => 1],
['id' => 3, 'title' => 'not in title', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'comment_count' => 1],
]);

$this->database()->table('posts')->insert([
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'type' => 'comment', 'content' => '<t><p>not in text</p></t>'],
['id' => 3, 'discussion_id' => 3, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'type' => 'comment', 'content' => '<t><p>lightsail in text</p></t>'],
]);

$response = $this->send(
$this->request('GET', '/api/discussions')
->withQueryParams([
'filter' => ['q' => 'lightsail'],
'include' => 'mostRelevantPost',
])
);

$data = json_decode($response->getBody()->getContents(), true);
$ids = array_map(function ($row) {
return $row['id'];
}, $data['data']);

// Order-independent comparison
$this->assertEquals(['3'], $ids, 'IDs do not match', 0.0, 10, true);
}

/**
* @test
*/
public function ignores_non_word_characters_when_searching()
{
$this->database()->table('discussions')->insert([
['id' => 2, 'title' => 'lightsail in title', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'comment_count' => 1],
['id' => 3, 'title' => 'not in title', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'comment_count' => 1],
]);

$this->database()->table('posts')->insert([
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'type' => 'comment', 'content' => '<t><p>not in text</p></t>'],
['id' => 3, 'discussion_id' => 3, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'type' => 'comment', 'content' => '<t><p>lightsail in text</p></t>'],
]);

$response = $this->send(
$this->request('GET', '/api/discussions')
->withQueryParams([
'filter' => ['q' => 'lightsail+'],
'include' => 'mostRelevantPost',
])
);

$data = json_decode($response->getBody()->getContents(), true);
$ids = array_map(function ($row) {
return $row['id'];
}, $data['data']);

// Order-independent comparison
$this->assertEquals(['3'], $ids, 'IDs do not match', 0.0, 10, true);
}

/**
* @test
*/
public function search_for_special_characters_gives_empty_result()
{
$response = $this->send(
$this->request('GET', '/api/discussions')
->withQueryParams([
'filter' => ['q' => '*'],
'include' => 'mostRelevantPost',
])
);

$data = json_decode($response->getBody()->getContents(), true);
$this->assertEquals([], $data['data']);

$response = $this->send(
$this->request('GET', '/api/discussions')
->withQueryParams([
'filter' => ['q' => '@'],
'include' => 'mostRelevantPost',
])
);

$data = json_decode($response->getBody()->getContents(), true);
$this->assertEquals([], $data['data']);
}
}
161 changes: 161 additions & 0 deletions tests/integration/api/discussions/ListTestWithFulltextSearch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?php

/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/

namespace Flarum\Tests\integration\api\discussions;

use Carbon\Carbon;
use Flarum\Tests\integration\RetrievesAuthorizedUsers;
use Flarum\Tests\integration\TestCase;

class ListTest extends TestCase
{
use RetrievesAuthorizedUsers;

/**
* @inheritDoc
*/
protected function setUp(): void
{
parent::setUp();

$this->database()->rollBack();

// We need to insert these outside of a transaction, because FULLTEXT indexing,
// which is needed for search, doesn't happen in transactions.
// We clean it up explcitly at the end.
$this->database()->table('discussions')->insert([
['id' => 1, 'title' => 'lightsail in title', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
['id' => 2, 'title' => 'not in title', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
]);

$this->database()->table('posts')->insert([
['id' => 1, 'discussion_id' => 1, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>not in text</p></t>'],
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>lightsail in text</p></t>'],
]);

// We need to call these again, since we rolled back the transaction started by `::app()`.
$this->database()->beginTransaction();

$this->populateDatabase();
}

/**
* @inheritDoc
*/
protected function tearDown(): void
{
parent::tearDown();

$this->database()->table('discussions')->whereIn('id', [1,2])->delete();
$this->database()->table('posts')->whereIn('id', [1, 2])->delete();
}

/**
* @test
*/
public function shows_index_for_guest()
{
$response = $this->send(
$this->request('GET', '/api/discussions')
);

$this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody()->getContents(), true);

$this->assertEquals(1, count($data['data']));
}

/**
* @test
*/
public function can_search_for_author()
{
$response = $this->send(
$this->request('GET', '/api/discussions')
->withQueryParams([
'filter' => ['q' => 'author:normal foo'],
'include' => 'mostRelevantPost',
])
);

$this->assertEquals(200, $response->getStatusCode());
}

/**
* @test
*/
public function can_search_for_word_in_post()
{
$response = $this->send(
$this->request('GET', '/api/discussions')
->withQueryParams([
'filter' => ['q' => 'lightsail'],
'include' => 'mostRelevantPost',
])
);

$data = json_decode($response->getBody()->getContents(), true);
$ids = array_map(function ($row) {
return $row['id'];
}, $data['data']);

// Order-independent comparison
$this->assertEquals(['3'], $ids, 'IDs do not match', 0.0, 10, true);
}

/**
* @test
*/
public function ignores_non_word_characters_when_searching()
{
$response = $this->send(
$this->request('GET', '/api/discussions')
->withQueryParams([
'filter' => ['q' => 'lightsail+'],
'include' => 'mostRelevantPost',
])
);

$data = json_decode($response->getBody()->getContents(), true);
$ids = array_map(function ($row) {
return $row['id'];
}, $data['data']);

// Order-independent comparison
$this->assertEquals(['3'], $ids, 'IDs do not match', 0.0, 10, true);
}

/**
* @test
*/
public function search_for_special_characters_gives_empty_result()
{
$response = $this->send(
$this->request('GET', '/api/discussions')
->withQueryParams([
'filter' => ['q' => '*'],
'include' => 'mostRelevantPost',
])
);

$data = json_decode($response->getBody()->getContents(), true);
$this->assertEquals([], $data['data']);

$response = $this->send(
$this->request('GET', '/api/discussions')
->withQueryParams([
'filter' => ['q' => '@'],
'include' => 'mostRelevantPost',
])
);

$data = json_decode($response->getBody()->getContents(), true);
$this->assertEquals([], $data['data']);
}
}

0 comments on commit 793e9ed

Please sign in to comment.