Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array driver doesn't support eloquent constraints #19

Open
brendanpetty opened this issue Jul 15, 2024 · 4 comments
Open

Array driver doesn't support eloquent constraints #19

brendanpetty opened this issue Jul 15, 2024 · 4 comments

Comments

@brendanpetty
Copy link

Using https://github.com/teamtnt/laravel-scout-tntsearch-driver/?tab=readme-ov-file#constraints e.g.

$constraints = Item::query();
$constraints->where('draft', false);
Item::search($query)->constrain($constraints);

works normally, but fails when testing using this driver.

I'm guessing it's not possible to fix this, but maybe is worth a note / known-issue somewhere in the documentation?

@Sti3bas
Copy link
Owner

Sti3bas commented Oct 9, 2024

@brendanpetty it shouldn't fail since TNTSearch provides a macro for the Builder class and that is out of scope of array driver: https://github.com/teamtnt/laravel-scout-tntsearch-driver/blob/d57e4c92502ceb99154803aa1866cd3cf1a26604/src/TNTSearchScoutServiceProvider.php#L43

Could you please provide more information?

@brendanpetty
Copy link
Author

I mean the test fails... the constraint is not applied if using array driver (as TNTSearch isn't instantiated to use that macro). All results pass through without this 'filtering'/constraining being applied in the testing environment.

@Sti3bas
Copy link
Owner

Sti3bas commented Oct 10, 2024

@brendanpetty yeah, array driver was not meant to implement other drivers specific features.

I'm currently working on a PR which would allow to fake response data and I think it would also be useful in this case.

Here is an example:

Controller method:

public function index(Request $request)
{
    $post = new Post;

    $constraints = $post->where('foo', 'bar');
    $post = Post::search($request->searchTerm)->constrain($constraints);

    return $post->paginate(10);
}

Test:

/** @test */
public function example()
{
    $constrain = null;

    Builder::macro('constrain', function ($constraints) use (&$constrain) {
        $constrain = $constraints;

        return $this;
    });

    Post::factory()->create(['id' => 1]);
    Post::factory()->create(['id' => 2]);
    Post::factory()->create(['id' => 3]);
    Post::factory()->create(['id' => 4]);

    Search::fakeResponseData([
        'hits' => [
            ['objectID' => 2],
            ['objectID' => 3],
        ]
    ])->query('test-query');

    $response = $this->getJson(route('posts.index', [
        'searchTerm' => 'test-query'
    ]));

    $response->assertOk();

    $this->assertNotNull($constrain);

    $fooClause = collect($constrain->getQuery()->wheres)->firstWhere(fn($clause) => $clause['column'] == 'foo');
    $this->assertNotNull($fooClause);
    $this->assertEquals('bar', $fooClause['value']);

    $this->assertCount(2, $response['data']);
    $this->assertEquals(2, $response['data'][0]['id']);
    $this->assertEquals(3, $response['data'][1]['id']);
}

@brendanpetty
Copy link
Author

Thanks, that looks great. Some of my testing is also around the filtering logic, so I'm just going to use the actual search driver for those tests rather than the array driver. A bit more work, unlike the super easy config of your array driver (thanks!).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants