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' => 'lightsail in title too', 'created_at' => Carbon::createFromDate(2020, 01, 01)->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1], ['id' => 3, 'title' => 'not in title either', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1], ['id' => 4, 'title' => 'not in title or text', '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' => 'not in text'], ['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => 'lightsail in text'], ['id' => 3, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => 'another lightsail for discussion 2!'], ['id' => 4, 'discussion_id' => 3, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => 'just one lightsail for discussion 3.'], ['id' => 5, 'discussion_id' => 4, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => 'not in title or text'], ]); // 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')->delete(); $this->database()->table('posts')->delete(); } /** * @test */ public function can_search_for_word_or_title_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']); $this->assertEquals(['2', '1', '3'], $ids, 'IDs do not match'); } /** * @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']); $this->assertEquals(['2', '1', '3'], $ids, 'IDs do not match'); } /** * @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']); } }
not in text
lightsail in text
another lightsail for discussion 2!
just one lightsail for discussion 3.
not in title or text